feat(idnot): statuts précis auth — 401 email manquant, 403 non-rattachement office
Some checks failed
build-and-push-ext / build_push (push) Failing after 4s

This commit is contained in:
dev4 2025-09-17 15:48:08 +00:00
parent 7541bce346
commit d1075d3f3b

View File

@ -4,14 +4,14 @@ import { IdNotService } from '../services/idnot';
import { authTokens } from '../utils/auth-tokens'; import { authTokens } from '../utils/auth-tokens';
import { IdNotUser, AuthToken } from '../types'; import { IdNotUser, AuthToken } from '../types';
import { Logger } from '../utils/logger'; import { Logger } from '../utils/logger';
import { NotFoundError, ExternalServiceError, BusinessRuleError } from '../types/errors'; import { NotFoundError, ExternalServiceError, BusinessRuleError, UnauthorizedError, ForbiddenError } from '../types/errors';
/** /**
* Pure controller methods that handle business logic * Pure controller methods that handle business logic
* without depending on Express Request/Response objects * without depending on Express Request/Response objects
*/ */
export class IdNotController { export class IdNotController {
/** /**
* Get user rattachements by idNot * Get user rattachements by idNot
*/ */
@ -51,9 +51,9 @@ export class IdNotController {
} }
})); }));
Logger.info('Successfully retrieved user rattachements', { Logger.info('Successfully retrieved user rattachements', {
idNot, idNot,
count: officeData.length count: officeData.length
}); });
return officeData; return officeData;
@ -67,12 +67,12 @@ export class IdNotController {
try { try {
const result = await IdNotService.getOfficeRattachements(idNot); const result = await IdNotService.getOfficeRattachements(idNot);
Logger.info('Successfully retrieved office rattachements', { Logger.info('Successfully retrieved office rattachements', {
idNot, idNot,
count: result.result?.length || 0 count: result.result?.length || 0
}); });
return result; return result;
} catch (error) { } catch (error) {
Logger.error('Failed to get office rattachements', { Logger.error('Failed to get office rattachements', {
@ -103,14 +103,14 @@ export class IdNotController {
// Get user data // Get user data
const userData = await IdNotService.getUserData(payload.profile_idn); const userData = await IdNotService.getUserData(payload.profile_idn);
if (!userData || !userData.statutDuRattachement || userData.entite.typeEntite.name !== 'office') { if (!userData || !userData.statutDuRattachement || userData.entite.typeEntite.name !== 'office') {
throw new BusinessRuleError('User not attached to an office'); throw new ForbiddenError('User not attached to an office');
} }
// Get office location data // Get office location data
const officeLocationData = await IdNotService.getOfficeLocationData(userData.entite.locationsUrl); const officeLocationData = await IdNotService.getOfficeLocationData(userData.entite.locationsUrl);
if (!officeLocationData || !officeLocationData.result || officeLocationData.result.length === 0) { if (!officeLocationData || !officeLocationData.result || officeLocationData.result.length === 0) {
throw new BusinessRuleError('Office location data not found'); throw new BusinessRuleError('Office location data not found');
} }
@ -143,7 +143,7 @@ export class IdNotController {
}; };
if (!idNotUser.contact.email) { if (!idNotUser.contact.email) {
throw new BusinessRuleError('User professional email is empty'); throw new UnauthorizedError('Email not found');
} }
// Generate auth token // Generate auth token
@ -157,10 +157,10 @@ export class IdNotController {
createdAt: Date.now(), createdAt: Date.now(),
expiresAt: Date.now() + (24 * 60 * 60 * 1000) // 24 hours expiresAt: Date.now() + (24 * 60 * 60 * 1000) // 24 hours
}; };
authTokens.push(tokenData); authTokens.push(tokenData);
Logger.info('IdNot authentication successful', { Logger.info('IdNot authentication successful', {
idNot: idNotUser.idNot, idNot: idNotUser.idNot,
office: idNotUser.office.name office: idNotUser.office.name
}); });
@ -172,11 +172,11 @@ export class IdNotController {
codePrefix: code.substring(0, 8) + '...', codePrefix: code.substring(0, 8) + '...',
error: error instanceof Error ? error.message : 'Unknown error' error: error instanceof Error ? error.message : 'Unknown error'
}); });
if (error instanceof BusinessRuleError || error instanceof ExternalServiceError) { if (error instanceof BusinessRuleError || error instanceof ExternalServiceError) {
throw error; throw error;
} }
throw new ExternalServiceError('IdNot', `Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`); throw new ExternalServiceError('IdNot', `Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
} }
} }
@ -189,12 +189,12 @@ export class IdNotController {
// Find the full token data // Find the full token data
const userAuth = authTokens.find(auth => auth.authToken === authToken); const userAuth = authTokens.find(auth => auth.authToken === authToken);
if (!userAuth || !userAuth.idNotUser) { if (!userAuth || !userAuth.idNotUser) {
throw new NotFoundError('User data not found. Please log in again.'); throw new NotFoundError('User data not found. Please log in again.');
} }
Logger.info('Current user data retrieved', { Logger.info('Current user data retrieved', {
idNot, idNot,
office: userAuth.idNotUser.office.name office: userAuth.idNotUser.office.name
}); });
@ -213,16 +213,16 @@ export class IdNotController {
// Remove the auth token from the array // Remove the auth token from the array
const tokenIndex = authTokens.findIndex(auth => auth.authToken === authToken); const tokenIndex = authTokens.findIndex(auth => auth.authToken === authToken);
if (tokenIndex > -1) { if (tokenIndex > -1) {
const removedToken = authTokens.splice(tokenIndex, 1)[0]; const removedToken = authTokens.splice(tokenIndex, 1)[0];
Logger.info('User logout successful', { Logger.info('User logout successful', {
idNot: removedToken.idNot idNot: removedToken.idNot
}); });
} else { } else {
Logger.warn('Logout attempted with invalid token'); Logger.warn('Logout attempted with invalid token');
} }
return { return {
success: true, success: true,
message: 'Déconnexion réussie' message: 'Déconnexion réussie'