feat(auth): add profile and QR card identification endpoints
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { AppError } from '../errors/app-error';
|
||||
import { getProfil, identifierParCarte } from '../services/utilisateur.service';
|
||||
|
||||
export async function getMe(req: Request, res: Response): Promise<void> {
|
||||
const user = req.user;
|
||||
if (!user) {
|
||||
throw new AppError(401, 'Authentification requise');
|
||||
}
|
||||
|
||||
const profil = await getProfil(user.id);
|
||||
res.json({ data: profil });
|
||||
}
|
||||
|
||||
export async function identifier(req: Request, res: Response): Promise<void> {
|
||||
const qr = req.params.qr;
|
||||
if (typeof qr !== 'string') {
|
||||
throw new AppError(400, 'QR code invalide');
|
||||
}
|
||||
|
||||
const profil = await identifierParCarte(qr);
|
||||
res.json({ data: profil });
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { prisma } from '../db/prisma';
|
||||
|
||||
export type CarteAvecUtilisateur = Prisma.CarteEtudianteGetPayload<{
|
||||
include: { utilisateur: { include: { role: true; campus: true } } };
|
||||
}>;
|
||||
|
||||
export function findByQrCode(qrCode: string): Promise<CarteAvecUtilisateur | null> {
|
||||
return prisma.carteEtudiante.findFirst({
|
||||
where: { qrCode },
|
||||
include: { utilisateur: { include: { role: true, campus: true } } },
|
||||
});
|
||||
}
|
||||
@@ -3,9 +3,20 @@ import { prisma } from '../db/prisma';
|
||||
|
||||
export type UtilisateurAvecRole = Prisma.UtilisateurGetPayload<{ include: { role: true } }>;
|
||||
|
||||
export type UtilisateurProfil = Prisma.UtilisateurGetPayload<{
|
||||
include: { role: true; campus: true };
|
||||
}>;
|
||||
|
||||
export function findByEmail(email: string): Promise<UtilisateurAvecRole | null> {
|
||||
return prisma.utilisateur.findUnique({
|
||||
where: { email },
|
||||
include: { role: true },
|
||||
});
|
||||
}
|
||||
|
||||
export function findById(id: number): Promise<UtilisateurProfil | null> {
|
||||
return prisma.utilisateur.findUnique({
|
||||
where: { id },
|
||||
include: { role: true, campus: true },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Router } from 'express';
|
||||
import { currentUser } from '../middlewares/current-user';
|
||||
import { getMe, identifier } from '../controllers/auth.controller';
|
||||
|
||||
export const authRoutes: Router = Router();
|
||||
|
||||
// Identification par QR code : point d'entrée du parcours, donc public.
|
||||
authRoutes.get('/carte/:qr', identifier);
|
||||
|
||||
// Profil de l'utilisateur déjà identifié : protégé.
|
||||
authRoutes.get('/me', currentUser, getMe);
|
||||
@@ -1,10 +1,14 @@
|
||||
import { Router } from 'express';
|
||||
import { currentUser } from '../middlewares/current-user';
|
||||
import { authRoutes } from './auth.routes';
|
||||
import { materielRoutes } from './materiel.routes';
|
||||
import { empruntRoutes } from './emprunt.routes';
|
||||
|
||||
export const apiRouter: Router = Router();
|
||||
|
||||
apiRouter.use(currentUser);
|
||||
apiRouter.use('/materiels', materielRoutes);
|
||||
apiRouter.use('/mes-emprunts', empruntRoutes);
|
||||
// /auth gère lui-même ses routes publiques/protégées.
|
||||
apiRouter.use('/auth', authRoutes);
|
||||
|
||||
// Le reste exige un utilisateur identifié.
|
||||
apiRouter.use('/materiels', currentUser, materielRoutes);
|
||||
apiRouter.use('/mes-emprunts', currentUser, empruntRoutes);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { AppError } from '../errors/app-error';
|
||||
import { findById, UtilisateurProfil } from '../repositories/utilisateur.repository';
|
||||
import { findByQrCode } from '../repositories/carte-etudiante.repository';
|
||||
|
||||
export async function getProfil(utilisateurId: number): Promise<UtilisateurProfil> {
|
||||
const profil = await findById(utilisateurId);
|
||||
if (!profil) {
|
||||
throw new AppError(404, 'Utilisateur introuvable');
|
||||
}
|
||||
|
||||
return profil;
|
||||
}
|
||||
|
||||
/* RG02 : identification de l'étudiant par le QR code de sa carte. La carte doit
|
||||
exister, être active et non expirée, et le compte doit être actif. */
|
||||
export async function identifierParCarte(qrCode: string): Promise<UtilisateurProfil> {
|
||||
const carte = await findByQrCode(qrCode);
|
||||
if (!carte || !carte.actif) {
|
||||
throw new AppError(404, 'Carte non reconnue');
|
||||
}
|
||||
|
||||
if (carte.dateExpiration.getTime() < Date.now()) {
|
||||
throw new AppError(401, 'Carte expiree');
|
||||
}
|
||||
|
||||
if (!carte.utilisateur.actif) {
|
||||
throw new AppError(401, 'Compte inactif');
|
||||
}
|
||||
|
||||
return carte.utilisateur;
|
||||
}
|
||||
Reference in New Issue
Block a user