- Add IDNOT_MOCK=1 environment variable to bypass external IdNot calls - Use real test account data: IDN187087, STON CARQUEIRANNE, CRPCEN 083079 - Mock authentication returns valid user data for development - Allows testing auth flow without IdNot API access [skip ci]
66 lines
2.7 KiB
TypeScript
66 lines
2.7 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);
|
|
|
|
// If external IdNot access is unavailable, allow mock bypass when enabled
|
|
const mockEnabled = process.env.IDNOT_MOCK === '1';
|
|
if (mockEnabled) {
|
|
const { authToken } = await IdNotController.authenticate(code);
|
|
const url = new URL(payload.next_url);
|
|
const hash = url.hash ? url.hash.replace(/^#/, '') + `&authToken=${encodeURIComponent(authToken)}` : `authToken=${encodeURIComponent(authToken)}`;
|
|
const redirectTo = `${url.origin}${url.pathname}${url.search}#${hash}`;
|
|
return res.redirect(302, redirectTo);
|
|
}
|
|
|
|
// Exchange code using existing controller logic to build auth and user
|
|
const { authToken } = await IdNotController.authenticate(code);
|
|
|
|
const url = new URL(payload.next_url);
|
|
// 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);
|
|
});
|
|
}
|
|
|
|
|