lecoffre-back-mini/src/handlers/idnot-callback.handlers.ts
NicolasCantu ba2c36c014
All checks were successful
Build and Push to Registry / build-and-push (push) Successful in 47s
docs: add test data for login; feat: ID.Not dev flow tweaks; chore: nginx dev host adjustments
2025-09-26 15:12:34 +02:00

62 lines
2.5 KiB
TypeScript

import { Request, Response } from 'express';
import { asyncHandler } from '../middleware/error-handler';
import { StateService } from '../services/state.service';
import { IdNotController } from '../controllers/idnot.controller';
import { ExternalServiceError, ValidationError } from '../types/errors';
export class IdNotCallbackHandlers {
static callback = asyncHandler(async (req: Request, res: Response): Promise<void> => {
const code = req.query.code as string | undefined;
const state = req.query.state as string | undefined;
// Debug logging to inspect what reaches the backend via Nginx
// Note: keep logs concise to avoid leaking sensitive data in production
try {
// Only log presence/length of params to avoid full values in logs
const safeQuery = {
code_present: typeof code === 'string',
code_length: typeof code === 'string' ? code.length : undefined,
state_present: typeof state === 'string',
state_length: typeof state === 'string' ? state.length : undefined
};
console.info('[IdNotCallback] incoming request', {
originalUrl: req.originalUrl,
method: req.method,
query: safeQuery,
headers: {
host: req.headers.host,
'x-forwarded-for': req.headers['x-forwarded-for'],
'x-forwarded-proto': req.headers['x-forwarded-proto']
}
});
} catch {}
if (!code || !state) {
throw new ValidationError('Missing code or state', [
{ field: 'code', value: code, constraints: ['required'] },
{ field: 'state', value: state, constraints: ['required'] }
]);
}
const payload = StateService.verifyState(state);
// Mock désactivé: suppression du bypass IDNOT_MOCK
// Exchange code using existing controller logic to build auth and user
const { authToken } = await IdNotController.authenticate(code);
const url = new URL(payload.next_url);
// Normalisation du chemin pour dev4: forcer le préfixe /lecoffre si absent
try {
if (url.hostname === 'dev4.4nkweb.com' && url.pathname === '/authorized-client') {
url.pathname = '/lecoffre/authorized-client';
}
} catch {}
// Prefer fragment to avoid leaking in server logs
const hash = url.hash ? url.hash.replace(/^#/, '') + `&authToken=${encodeURIComponent(authToken)}` : `authToken=${encodeURIComponent(authToken)}`;
const redirectTo = `${url.origin}${url.pathname}${url.search}#${hash}`;
res.redirect(302, redirectTo);
});
}