emilsoftware-utilities 2.0.0-dev.77 → 2.0.0-dev.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/accessi/resource-server/token.js +2 -0
  2. package/dist/accessi/resource-server/token.js.map +1 -1
  3. package/dist/accessi/server/standalone.js +2 -1
  4. package/dist/accessi/server/standalone.js.map +1 -1
  5. package/dist/accessi-module/AccessiModule.d.ts +3 -0
  6. package/dist/accessi-module/AccessiModule.js.map +1 -1
  7. package/dist/accessi-module/Console/console.js +1 -0
  8. package/dist/accessi-module/Console/wiki.js +1 -0
  9. package/dist/accessi-module/Console/wiki.js.map +1 -1
  10. package/dist/accessi-module/Controllers/AccessiIntrospectionController.js +9 -0
  11. package/dist/accessi-module/Controllers/AccessiIntrospectionController.js.map +1 -1
  12. package/dist/accessi-module/Controllers/AuthController.js +67 -8
  13. package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
  14. package/dist/accessi-module/Controllers/ConsoleEntryController.js +9 -0
  15. package/dist/accessi-module/Controllers/ConsoleEntryController.js.map +1 -1
  16. package/dist/accessi-module/Services/AuthService/AuthService.js +8 -2
  17. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  18. package/dist/accessi-module/index.d.ts +4 -0
  19. package/dist/accessi-module/index.js +15 -1
  20. package/dist/accessi-module/index.js.map +1 -1
  21. package/dist/accessi-module/observability/metrics.d.ts +79 -0
  22. package/dist/accessi-module/observability/metrics.js +216 -0
  23. package/dist/accessi-module/observability/metrics.js.map +1 -0
  24. package/dist/accessi-module/observability/redisMetrics.d.ts +12 -0
  25. package/dist/accessi-module/observability/redisMetrics.js +44 -0
  26. package/dist/accessi-module/observability/redisMetrics.js.map +1 -0
  27. package/dist/accessi-module/security/accessTokenRevocation.js +5 -3
  28. package/dist/accessi-module/security/accessTokenRevocation.js.map +1 -1
  29. package/dist/accessi-module/security/consoleEntry.js +5 -3
  30. package/dist/accessi-module/security/consoleEntry.js.map +1 -1
  31. package/dist/accessi-module/security/edgeRateLimit.js +3 -0
  32. package/dist/accessi-module/security/edgeRateLimit.js.map +1 -1
  33. package/dist/accessi-module/security/jwks.js +3 -0
  34. package/dist/accessi-module/security/jwks.js.map +1 -1
  35. package/dist/accessi-module/security/jwtTokenOptions.js +2 -0
  36. package/dist/accessi-module/security/jwtTokenOptions.js.map +1 -1
  37. package/dist/accessi-module/security/publicAuthRateLimit.js +3 -0
  38. package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
  39. package/dist/accessi-module/security/rateLimitStore.js +4 -2
  40. package/dist/accessi-module/security/rateLimitStore.js.map +1 -1
  41. package/dist/accessi-module/security/refreshTokenRotation.js +7 -5
  42. package/dist/accessi-module/security/refreshTokenRotation.js.map +1 -1
  43. package/dist/accessi-module/security/serviceTokenRateLimit.js +3 -0
  44. package/dist/accessi-module/security/serviceTokenRateLimit.js.map +1 -1
  45. package/dist/accessi-module/security/sessionRevocation.js +7 -3
  46. package/dist/accessi-module/security/sessionRevocation.js.map +1 -1
  47. package/dist/emilsoftware-utilities-2.0.0-dev.78.tgz +0 -0
  48. package/docs/metrics.md +153 -0
  49. package/docs/redis-load-testing.md +88 -0
  50. package/package.json +4 -3
  51. package/dist/emilsoftware-utilities-2.0.0-dev.77.tgz +0 -0
@@ -36,10 +36,24 @@ const jwt_strategy_1 = require("../jwt/jwt.strategy");
36
36
  const accessControl_1 = require("../security/accessControl");
37
37
  const authenticatedToken_1 = require("../security/authenticatedToken");
38
38
  const authCookies_1 = require("../security/authCookies");
39
+ const metrics_1 = require("../observability/metrics");
39
40
  const sessionRevocation_1 = require("../security/sessionRevocation");
40
41
  const accessTokenRevocation_1 = require("../security/accessTokenRevocation");
41
42
  const audit_1 = require("../security/audit");
42
43
  const publicAuthRateLimit_1 = require("../security/publicAuthRateLimit");
44
+ /** Estrae il codice stabile di un errore Nest `{ code, message }`. */
45
+ function authErrorCode(error) {
46
+ if (!error || typeof error !== 'object')
47
+ return undefined;
48
+ const response = typeof error.getResponse === 'function'
49
+ ? error.getResponse()
50
+ : error.response;
51
+ if (response && typeof response === 'object') {
52
+ const code = response.code;
53
+ return typeof code === 'string' ? code : undefined;
54
+ }
55
+ return undefined;
56
+ }
43
57
  let AuthController = AuthController_1 = class AuthController {
44
58
  constructor(authService, adminBootstrapService, options) {
45
59
  this.authService = authService;
@@ -157,13 +171,16 @@ let AuthController = AuthController_1 = class AuthController {
157
171
  }
158
172
  login(request, loginRequest, res) {
159
173
  return __awaiter(this, void 0, void 0, function* () {
174
+ const startedAt = Date.now();
160
175
  try {
161
176
  const rateLimitDecision = yield (0, publicAuthRateLimit_1.checkPublicAuthRateLimit)(this.options, 'login', request, [loginRequest === null || loginRequest === void 0 ? void 0 : loginRequest.email]);
162
177
  if (!rateLimitDecision.allowed) {
178
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_login_total', { result: 'rate_limited' });
163
179
  return (0, publicAuthRateLimit_1.sendPublicAuthRateLimitExceeded)(res, rateLimitDecision.retryAfterSeconds);
164
180
  }
165
181
  const userData = yield this.authService.login(loginRequest);
166
182
  if (!userData) {
183
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_login_total', { result: 'failure' });
167
184
  return Utilities_1.RestUtilities.sendInvalidCredentials(res);
168
185
  }
169
186
  if (!userData.challenge && !userData.passwordRequired) {
@@ -173,10 +190,23 @@ let AuthController = AuthController_1 = class AuthController {
173
190
  userData.refreshToken = tokens.refresh;
174
191
  (0, authCookies_1.applyAccessiAuthCookies)(res, (0, authCookies_1.resolveAccessiAuthCookieOptions)(this.options), userData);
175
192
  }
193
+ const result = userData.challenge
194
+ ? 'challenge'
195
+ : userData.passwordRequired
196
+ ? 'password_required'
197
+ : 'success';
198
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_login_total', { result });
176
199
  return Utilities_1.RestUtilities.sendBaseResponse(res, userData);
177
200
  }
178
201
  catch (error) {
179
- if ((error === null || error === void 0 ? void 0 : error.message) === 'PASSWORD_EXPIRED') {
202
+ const message = error === null || error === void 0 ? void 0 : error.message;
203
+ const result = message === 'PASSWORD_EXPIRED'
204
+ ? 'password_expired'
205
+ : message === AuthService_1.PASSWORD_LOGIN_DISABLED
206
+ ? 'sso_only'
207
+ : 'error';
208
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_login_total', { result });
209
+ if (message === 'PASSWORD_EXPIRED') {
180
210
  this.logger.warning('Password scaduta, cambiare password ', error);
181
211
  return Utilities_1.RestUtilities.sendPasswordExpired(res);
182
212
  }
@@ -197,10 +227,14 @@ let AuthController = AuthController_1 = class AuthController {
197
227
  }
198
228
  return Utilities_1.RestUtilities.sendInvalidCredentials(res);
199
229
  }
230
+ finally {
231
+ (0, metrics_1.observeAccessiMetric)(this.options, 'auth_login_duration_ms', Date.now() - startedAt);
232
+ }
200
233
  });
201
234
  }
202
235
  refresh(request, body, res) {
203
236
  return __awaiter(this, void 0, void 0, function* () {
237
+ const startedAt = Date.now();
204
238
  try {
205
239
  const cookieConfig = (0, authCookies_1.resolveAccessiAuthCookieOptions)(this.options);
206
240
  const cookieRefreshToken = (cookieConfig === null || cookieConfig === void 0 ? void 0 : cookieConfig.refreshFromCookie)
@@ -214,6 +248,7 @@ let AuthController = AuthController_1 = class AuthController {
214
248
  : undefined;
215
249
  const decision = yield (0, publicAuthRateLimit_1.checkPublicAuthRateLimit)(this.options, 'refresh', request, tokenKey ? [tokenKey] : []);
216
250
  if (!decision.allowed) {
251
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_refresh_total', { result: 'rate_limited' });
217
252
  return (0, publicAuthRateLimit_1.sendPublicAuthRateLimitExceeded)(res, decision.retryAfterSeconds);
218
253
  }
219
254
  if (!refreshToken) {
@@ -225,37 +260,63 @@ let AuthController = AuthController_1 = class AuthController {
225
260
  }
226
261
  const response = Object.assign({ token: result.token }, (result.refreshToken ? { refreshToken: result.refreshToken } : {}));
227
262
  (0, authCookies_1.applyAccessiAuthCookies)(res, cookieConfig, response);
263
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_refresh_total', { result: 'success' });
228
264
  return Utilities_1.RestUtilities.sendBaseResponse(res, response);
229
265
  }
230
266
  catch (error) {
267
+ const code = authErrorCode(error);
268
+ const result = code === 'ACCESSI_REFRESH_TOKEN_REUSE'
269
+ ? 'reuse'
270
+ : code === 'ACCESSI_REFRESH_FAMILY_REVOKED'
271
+ ? 'family_revoked'
272
+ : code === 'ACCESSI_REFRESH_ROTATION_UNAVAILABLE'
273
+ ? 'store_unavailable'
274
+ : 'invalid';
275
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_refresh_total', { result });
231
276
  return Utilities_1.RestUtilities.sendErrorMessage(res, error, AuthController_1.name, error instanceof common_1.HttpException ? error.getStatus() : common_1.HttpStatus.UNAUTHORIZED);
232
277
  }
278
+ finally {
279
+ (0, metrics_1.observeAccessiMetric)(this.options, 'auth_refresh_duration_ms', Date.now() - startedAt);
280
+ }
233
281
  });
234
282
  }
235
283
  verifyTwoFactor(request, body, res) {
236
284
  return __awaiter(this, void 0, void 0, function* () {
285
+ const startedAt = Date.now();
237
286
  try {
238
287
  const limit = yield (0, publicAuthRateLimit_1.checkPublicAuthRateLimit)(this.options, 'twoFactorVerify', request, [body.challengeId]);
239
- if (!limit.allowed)
288
+ if (!limit.allowed) {
289
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_two_factor_total', { action: 'verify', result: 'rate_limited' });
240
290
  return (0, publicAuthRateLimit_1.sendPublicAuthRateLimitExceeded)(res, limit.retryAfterSeconds);
291
+ }
241
292
  const result = yield this.authService.verifyTwoFactor(body.challengeId, body.code, body.scope);
242
293
  (0, authCookies_1.applyAccessiAuthCookies)(res, (0, authCookies_1.resolveAccessiAuthCookieOptions)(this.options), result);
294
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_two_factor_total', { action: 'verify', result: 'success' });
243
295
  return Utilities_1.RestUtilities.sendBaseResponse(res, result);
244
296
  }
245
297
  catch (error) {
298
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_two_factor_total', { action: 'verify', result: 'failure' });
246
299
  return Utilities_1.RestUtilities.sendErrorMessage(res, error, AuthController_1.name, error instanceof common_1.HttpException ? error.getStatus() : 500);
247
300
  }
301
+ finally {
302
+ (0, metrics_1.observeAccessiMetric)(this.options, 'auth_two_factor_duration_ms', Date.now() - startedAt, { action: 'verify' });
303
+ }
248
304
  });
249
305
  }
250
306
  resendTwoFactor(request, body, res) {
251
307
  return __awaiter(this, void 0, void 0, function* () {
252
308
  try {
253
309
  const limit = yield (0, publicAuthRateLimit_1.checkPublicAuthRateLimit)(this.options, 'twoFactorResend', request, [body.challengeId]);
254
- if (!limit.allowed)
310
+ if (!limit.allowed) {
311
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_two_factor_total', { action: 'resend', result: 'rate_limited' });
255
312
  return (0, publicAuthRateLimit_1.sendPublicAuthRateLimitExceeded)(res, limit.retryAfterSeconds);
256
- return Utilities_1.RestUtilities.sendBaseResponse(res, yield this.authService.resendTwoFactor(body.challengeId));
313
+ }
314
+ const result = yield this.authService.resendTwoFactor(body.challengeId);
315
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_two_factor_total', { action: 'resend', result: 'success' });
316
+ return Utilities_1.RestUtilities.sendBaseResponse(res, result);
257
317
  }
258
318
  catch (error) {
319
+ (0, metrics_1.countAccessiMetric)(this.options, 'auth_two_factor_total', { action: 'resend', result: 'failure' });
259
320
  return Utilities_1.RestUtilities.sendErrorMessage(res, error, AuthController_1.name, error instanceof common_1.HttpException ? error.getStatus() : 500);
260
321
  }
261
322
  });
@@ -477,12 +538,10 @@ __decorate([
477
538
  ], AuthController.prototype, "adminBootstrapStatus", null);
478
539
  exports.AuthController = AuthController = AuthController_1 = __decorate([
479
540
  (0, swagger_1.ApiTags)('Auth'),
480
- (0, common_1.Controller)('accessi/auth')
481
- /**
541
+ (0, common_1.Controller)('accessi/auth') /**
482
542
  * Endpoint pubblici di autenticazione locale e verifica sessione.
483
543
  * Il login SSO non riceve token esterni qui: il backend validante usa `FederatedAuthService.authenticate`.
484
- */
485
- ,
544
+ */,
486
545
  __param(2, (0, common_1.Inject)('ACCESSI_OPTIONS')),
487
546
  __metadata("design:paramtypes", [AuthService_1.AuthService,
488
547
  AdminBootstrapService_1.AdminBootstrapService, Object])
@@ -1 +1 @@
1
- {"version":3,"file":"AuthController.js","sourceRoot":"","sources":["../../../src/accessi-module/Controllers/AuthController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Body, Controller, Get, HttpException, HttpStatus, Inject, Param, Post, Req, Res, UseGuards } from '@nestjs/common';\nimport { ResendTwoFactorRequest, VerifyTwoFactorRequest } from '../Dtos/TwoFactorDtos';\nimport { ApiBody, ApiOkResponse, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';\nimport { Request, Response } from 'express';\nimport { createHash } from 'crypto';\nimport { Logger } from '../../Logger';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions } from '../AccessiModule';\nimport {\n ActionResponse,\n AdminBootstrapStatusResponse,\n BootstrapAdminRequest,\n BootstrapAdminResponse,\n ConfirmResetPasswordRequest,\n ErrorResponse,\n GetUserByTokenRequest,\n GetUserByTokenResponse,\n LoginRequest,\n LoginResponse,\n PasswordExpiredResponse,\n RefreshTokenRequest,\n RefreshTokenResponse,\n RevokeTokenRequest,\n} from '../Dtos';\nimport { AuthService, PASSWORD_LOGIN_DISABLED } from '../Services/AuthService/AuthService';\nimport { AdminBootstrapService } from '../Services/AdminBootstrapService/AdminBootstrapService';\nimport { JwtSimpleGuard } from '../jwt/jwt.strategy';\nimport { getAuthenticatedAccessiUser } from '../security/accessControl';\nimport { extractAccessiBearerToken } from '../security/authenticatedToken';\nimport {\n applyAccessiAuthCookies,\n clearAccessiAuthCookies,\n getAccessiRefreshTokenFromCookie,\n resolveAccessiAuthCookieOptions,\n} from '../security/authCookies';\nimport {\n getSessionRevocationStore,\n revokeAccessiUserSessions,\n} from '../security/sessionRevocation';\nimport {\n getAccessTokenRevocationStore,\n revokeAccessiAccessToken,\n} from '../security/accessTokenRevocation';\nimport { auditAccessi } from '../security/audit';\nimport {\n checkPublicAuthRateLimit,\n sendPublicAuthRateLimitExceeded,\n} from '../security/publicAuthRateLimit';\n\n@ApiTags('Auth')\n@Controller('accessi/auth')\n/**\n * Endpoint pubblici di autenticazione locale e verifica sessione.\n * Il login SSO non riceve token esterni qui: il backend validante usa `FederatedAuthService.authenticate`.\n */\nexport class AuthController {\n logger: Logger = new Logger(AuthController.name);\n\n constructor(\n private readonly authService: AuthService,\n private readonly adminBootstrapService: AdminBootstrapService,\n @Inject('ACCESSI_OPTIONS') private readonly options: AccessiOptions,\n ) {}\n\n @ApiOperation({ summary: 'Conferma il reset della password', operationId: 'resetPassword' })\n @ApiParam({ name: 'token', description: 'Token per il reset della password', required: true })\n @ApiBody({ type: ConfirmResetPasswordRequest })\n @ApiResponse({\n status: 200,\n description: 'Password aggiornata con successo',\n type: ActionResponse,\n })\n @ApiResponse({\n status: 400,\n description: 'Errore nella richiesta o token non valido',\n type: ErrorResponse,\n })\n @Post('confirm-reset-password/:token')\n async resetPassword(\n @Req() request: Request,\n @Res() res: Response,\n @Param('token') token: string,\n @Body() body: ConfirmResetPasswordRequest,\n ) {\n try {\n const rateLimitDecision = await checkPublicAuthRateLimit(\n this.options,\n 'passwordResetConfirm',\n request,\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n await this.authService.confirmResetPassword(token, body.newPassword);\n return RestUtilities.sendOKMessage(res, 'Password aggiornata con successo!');\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, HttpStatus.BAD_REQUEST);\n }\n }\n\n @ApiOperation({\n summary: 'Recupera le informazioni utente dal token JWT',\n operationId: 'getUserByToken',\n })\n @ApiBody({ type: GetUserByTokenRequest })\n @ApiResponse({\n status: 200,\n description: 'Informazioni utente recuperate con successo',\n type: GetUserByTokenResponse,\n })\n @ApiResponse({\n status: 401,\n description: 'Token non valido o scaduto',\n type: ErrorResponse,\n })\n @Post('get-user-by-token')\n async getUserByToken(\n @Req() request: Request,\n @Body() body: GetUserByTokenRequest,\n @Res() res: Response,\n ) {\n try {\n const rateLimitDecision = await checkPublicAuthRateLimit(\n this.options,\n 'getUserByToken',\n request,\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n const requestToken = typeof body?.token === 'string' && body.token.trim() !== ''\n ? body.token\n : extractAccessiBearerToken(request.headers.authorization);\n if (!requestToken) {\n return RestUtilities.sendErrorMessage(\n res,\n 'Token non fornito',\n AuthController.name,\n HttpStatus.BAD_REQUEST,\n );\n }\n\n const authenticatedPayload = await this.authService.getAuthenticatedTokenPayload(requestToken);\n const userData = (authenticatedPayload as { utente?: unknown })?.utente;\n if (!userData) {\n throw new Error('Il token non contiene un utente Accessi valido.');\n }\n\n // Keep the runtime response aligned with GetUserByTokenResponse and Orval:\n // Result.userData contains the authenticated user directly, not a nested JWT payload.\n return RestUtilities.sendBaseResponse(res, { userData });\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, HttpStatus.UNAUTHORIZED);\n }\n }\n\n @ApiOperation({\n summary: 'Revoca tutte le sessioni dell utente corrente',\n operationId: 'revokeSessions',\n description:\n 'Invalida i token emessi prima di questa chiamata. Richiede sessionRevocation.store configurato. I token emessi dopo la revoca restano validi.',\n })\n @ApiOkResponse({ type: ActionResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Token Accessi mancante o non valido.' })\n @ApiResponse({ status: 501, type: ErrorResponse, description: 'Revoca sessioni non configurata.' })\n @UseGuards(JwtSimpleGuard)\n @Post('revoke-sessions')\n async revokeSessions(@Req() request: Request, @Res() res: Response) {\n try {\n const user = getAuthenticatedAccessiUser(request);\n if (!getSessionRevocationStore(this.options)) {\n throw new HttpException(\n {\n code: 'ACCESSI_SESSION_REVOCATION_DISABLED',\n message: 'La revoca sessioni non e configurata su questa istanza.',\n },\n HttpStatus.NOT_IMPLEMENTED,\n );\n }\n await revokeAccessiUserSessions(this.options, user.codiceUtente);\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n if (cookieConfig) clearAccessiAuthCookies(res, cookieConfig);\n return RestUtilities.sendOKMessage(res, 'Sessioni revocate con successo.');\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.BAD_REQUEST,\n );\n }\n }\n\n @ApiOperation({\n summary: 'Revoca un singolo access token tramite jti',\n operationId: 'revokeToken',\n description:\n 'Annulla un solo token (logout del dispositivo corrente o token compromesso) senza toccare le altre sessioni. ' +\n 'Se il body non contiene jti viene revocato il token della richiesta. Richiede accessTokenRevocation.store configurato.',\n })\n @ApiBody({ type: RevokeTokenRequest })\n @ApiOkResponse({ type: ActionResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Token Accessi mancante o non valido.' })\n @ApiResponse({ status: 403, type: ErrorResponse, description: 'Non autorizzato a revocare il token indicato.' })\n @ApiResponse({ status: 501, type: ErrorResponse, description: 'Revoca token non configurata.' })\n @UseGuards(JwtSimpleGuard)\n @Post('revoke-token')\n async revokeToken(\n @Req() request: Request,\n @Body() body: RevokeTokenRequest,\n @Res() res: Response,\n ) {\n try {\n const user = getAuthenticatedAccessiUser(request);\n if (!getAccessTokenRevocationStore(this.options)) {\n throw new HttpException(\n {\n code: 'ACCESSI_ACCESS_TOKEN_REVOCATION_DISABLED',\n message: 'La revoca dei singoli token non e configurata su questa istanza.',\n },\n HttpStatus.NOT_IMPLEMENTED,\n );\n }\n\n const payload = ((request as Request & { user?: unknown }).user ?? {}) as Record<string, unknown>;\n const currentJti = typeof payload.jti === 'string' ? payload.jti : undefined;\n const requestedJti = typeof body?.jti === 'string' ? body.jti.trim() : '';\n const targetJti = requestedJti !== '' ? requestedJti : currentJti;\n\n if (!targetJti) {\n throw new HttpException(\n { code: 'ACCESSI_TOKEN_JTI_MISSING', message: 'Il token non contiene un jti revocabile.' },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n const isCurrentToken = targetJti === currentJti;\n if (!isCurrentToken && !user.flagAdmin && !user.flagSuper) {\n throw new HttpException(\n {\n code: 'ACCESSI_TOKEN_REVOKE_FORBIDDEN',\n message: 'Solo gli amministratori possono revocare il token di un altro utente.',\n },\n HttpStatus.FORBIDDEN,\n );\n }\n\n const expiresAt = Number(payload.exp);\n await revokeAccessiAccessToken(\n this.options,\n targetJti,\n isCurrentToken && Number.isFinite(expiresAt) ? expiresAt * 1000 : undefined,\n );\n auditAccessi('access_token_revoked', {\n codiceUtente: user.codiceUtente,\n actor: user.codiceUtente,\n jti: targetJti,\n self: isCurrentToken,\n });\n if (isCurrentToken) {\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n if (cookieConfig) clearAccessiAuthCookies(res, cookieConfig);\n }\n return RestUtilities.sendOKMessage(res, 'Token revocato con successo.');\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.BAD_REQUEST,\n );\n }\n }\n\n @ApiOperation({\n summary: 'Effettua il login utente',\n description:\n \"Con sola email restituisce passwordRequired oppure avvia il codice per utenti passwordless. Con password valida restituisce il login completo o challenge se la 2FA e attiva. Nessun JWT viene emesso prima della verifica del codice.\",\n operationId: 'login',\n })\n @ApiBody({ type: LoginRequest })\n @ApiResponse({\n status: 200,\n description: 'Login effettuato con successo',\n type: LoginResponse,\n })\n @ApiResponse({\n status: 401,\n description: 'Credenziali non valide',\n type: ErrorResponse,\n })\n @ApiResponse({\n status: 403,\n description: 'Password scaduta, e necessario aggiornarla.',\n type: PasswordExpiredResponse,\n })\n @ApiResponse({ status: 403, description: 'Utente abilitato solo a SSO.', type: ErrorResponse })\n @Post('login')\n async login(@Req() request: Request, @Body() loginRequest: LoginRequest, @Res() res: Response) {\n try {\n const rateLimitDecision = await checkPublicAuthRateLimit(\n this.options,\n 'login',\n request,\n [loginRequest?.email],\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n const userData = await this.authService.login(loginRequest);\n if (!userData) {\n return RestUtilities.sendInvalidCredentials(res);\n }\n\n if (!userData.challenge && !userData.passwordRequired) {\n const tokens = this.authService.createTokenPair(userData.utente, ['password']);\n userData.token = tokens.access;\n if (tokens.refresh) userData.refreshToken = tokens.refresh;\n applyAccessiAuthCookies(res, resolveAccessiAuthCookieOptions(this.options), userData);\n }\n\n return RestUtilities.sendBaseResponse(res, userData);\n } catch (error) {\n if ((error as Error)?.message === 'PASSWORD_EXPIRED') {\n this.logger.warning('Password scaduta, cambiare password ', error);\n return RestUtilities.sendPasswordExpired(res);\n }\n\n if (error instanceof HttpException) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error.getStatus());\n }\n\n if ((error as Error)?.message === PASSWORD_LOGIN_DISABLED) {\n return res.status(HttpStatus.FORBIDDEN).json({\n severity: 'error', status: HttpStatus.FORBIDDEN, statusCode: 2,\n code: PASSWORD_LOGIN_DISABLED,\n error: PASSWORD_LOGIN_DISABLED,\n message: 'Questo utente e abilitato solo tramite SSO. Accedi con un provider collegato.',\n });\n }\n\n this.logger.error('Errore durante il login', error);\n if (RestUtilities.isDatabaseSchemaError(error)) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n HttpStatus.SERVICE_UNAVAILABLE,\n );\n }\n return RestUtilities.sendInvalidCredentials(res);\n }\n }\n\n @ApiOperation({\n summary: 'Scambia un refresh token con un nuovo access token',\n operationId: 'refreshAccessToken',\n description:\n 'Richiede jwtOptions.refreshExpiresIn. Il refresh token ha typ=refresh e non e accettato dai guard API.',\n })\n @ApiBody({ type: RefreshTokenRequest })\n @ApiOkResponse({ type: RefreshTokenResponse })\n @ApiResponse({ status: 401, description: 'Refresh token non valido, scaduto o revocato.', type: ErrorResponse })\n @ApiResponse({ status: 429, description: 'Troppi tentativi.', type: ErrorResponse })\n @Post('refresh')\n async refresh(\n @Req() request: Request,\n @Body() body: RefreshTokenRequest,\n @Res() res: Response,\n ) {\n try {\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n const cookieRefreshToken = cookieConfig?.refreshFromCookie\n ? getAccessiRefreshTokenFromCookie(request.headers.cookie, cookieConfig)\n : undefined;\n const refreshToken = typeof body?.refreshToken === 'string' && body.refreshToken.trim() !== ''\n ? body.refreshToken\n : cookieRefreshToken;\n const tokenKey = typeof refreshToken === 'string'\n ? createHash('sha256').update(refreshToken).digest('hex').slice(0, 32)\n : undefined;\n const decision = await checkPublicAuthRateLimit(\n this.options,\n 'refresh',\n request,\n tokenKey ? [tokenKey] : [],\n );\n if (!decision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, decision.retryAfterSeconds);\n }\n\n if (!refreshToken) {\n throw new HttpException('Refresh token mancante.', HttpStatus.UNAUTHORIZED);\n }\n\n const result = await this.authService.refreshAccessToken(refreshToken);\n if (!result.token) {\n throw new HttpException('Refresh token non valido.', HttpStatus.UNAUTHORIZED);\n }\n const response = {\n token: result.token,\n ...(result.refreshToken ? { refreshToken: result.refreshToken } : {}),\n };\n applyAccessiAuthCookies(res, cookieConfig, response);\n return RestUtilities.sendBaseResponse(res, response);\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.UNAUTHORIZED,\n );\n }\n }\n\n @Post('two-factor/verify')\n @ApiOperation({ summary: 'Verifica il codice e completa il login', operationId: 'verifyTwoFactor' })\n @ApiBody({ type: VerifyTwoFactorRequest })\n @ApiResponse({ status: 200, type: LoginResponse })\n @ApiResponse({ status: 401, type: ErrorResponse })\n @ApiResponse({ status: 429, type: ErrorResponse })\n async verifyTwoFactor(@Req() request: Request, @Body() body: VerifyTwoFactorRequest, @Res() res: Response) {\n try {\n const limit = await checkPublicAuthRateLimit(this.options, 'twoFactorVerify', request, [body.challengeId]);\n if (!limit.allowed) return sendPublicAuthRateLimitExceeded(res, limit.retryAfterSeconds);\n const result = await this.authService.verifyTwoFactor(body.challengeId, body.code, body.scope);\n applyAccessiAuthCookies(res, resolveAccessiAuthCookieOptions(this.options), result);\n return RestUtilities.sendBaseResponse(res, result);\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error instanceof HttpException ? error.getStatus() : 500);\n }\n }\n\n @Post('two-factor/resend')\n @ApiOperation({ summary: 'Reinvia il codice, invalidando il precedente', operationId: 'resendTwoFactor' })\n @ApiBody({ type: ResendTwoFactorRequest })\n @ApiResponse({ status: 200, type: LoginResponse })\n @ApiResponse({ status: 401, type: ErrorResponse })\n @ApiResponse({ status: 429, type: ErrorResponse })\n async resendTwoFactor(@Req() request: Request, @Body() body: ResendTwoFactorRequest, @Res() res: Response) {\n try {\n const limit = await checkPublicAuthRateLimit(this.options, 'twoFactorResend', request, [body.challengeId]);\n if (!limit.allowed) return sendPublicAuthRateLimitExceeded(res, limit.retryAfterSeconds);\n return RestUtilities.sendBaseResponse(res, await this.authService.resendTwoFactor(body.challengeId));\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error instanceof HttpException ? error.getStatus() : 500);\n }\n }\n\n @Post('bootstrap-admin')\n @ApiOperation({\n summary: 'Crea il primo utente admin (bootstrap)',\n operationId: 'bootstrapAdmin',\n description:\n 'Endpoint pubblico ma protetto dal token di avvio: attivo solo con adminBootstrap.enabled. ' +\n 'Crea un utente in stato confermato senza email, con flag admin (e super opzionale) e password fornita o generata.',\n })\n @ApiBody({ type: BootstrapAdminRequest })\n @ApiResponse({ status: 200, type: BootstrapAdminResponse })\n @ApiResponse({ status: 401, description: 'Token di bootstrap non valido', type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Bootstrap admin non abilitato', type: ErrorResponse })\n @ApiResponse({ status: 429, description: 'Troppi tentativi', type: ErrorResponse })\n async bootstrapAdmin(@Req() request: Request, @Body() body: BootstrapAdminRequest, @Res() res: Response) {\n try {\n const limit = await checkPublicAuthRateLimit(this.options, 'adminBootstrap', request);\n if (!limit.allowed) return sendPublicAuthRateLimitExceeded(res, limit.retryAfterSeconds);\n return RestUtilities.sendBaseResponse(res, await this.adminBootstrapService.bootstrap(body));\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error instanceof HttpException ? error.getStatus() : 500);\n }\n }\n\n @Get('bootstrap-admin/status')\n @ApiOperation({\n summary: 'Indica se il bootstrap admin e abilitato',\n operationId: 'getAdminBootstrapStatus',\n description:\n 'Endpoint pubblico: la console mostra la sezione \"Crea utente admin\" solo quando enabled e true.',\n })\n @ApiResponse({ status: 200, type: AdminBootstrapStatusResponse })\n async adminBootstrapStatus(@Res() res: Response) {\n return RestUtilities.sendBaseResponse(res, { enabled: this.adminBootstrapService.isEnabled() });\n }\n}\n"]}
1
+ {"version":3,"file":"AuthController.js","sourceRoot":"","sources":["../../../src/accessi-module/Controllers/AuthController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA4H;AAC5H,yDAAuF;AACvF,6CAAuG;AAEvG,mCAAoC;AACpC,yCAAsC;AACtC,+CAAgD;AAEhD,kCAeiB;AACjB,qEAA2F;AAC3F,mGAAgG;AAChG,sDAAqD;AACrD,6DAAwE;AACxE,uEAA2E;AAC3E,yDAKiC;AACjC,sDAGkC;AAClC,qEAGuC;AACvC,6EAG2C;AAC3C,6CAAiD;AACjD,yEAGyC;AAEzC,sEAAsE;AACtE,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1D,MAAM,QAAQ,GAAG,OAAQ,KAAmC,CAAC,WAAW,KAAK,UAAU;QACrF,CAAC,CAAE,KAAwC,CAAC,WAAW,EAAE;QACzD,CAAC,CAAE,KAAgC,CAAC,QAAQ,CAAC;IAC/C,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAI,QAA+B,CAAC,IAAI,CAAC;QACnD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAOM,IAAM,cAAc,sBAApB,MAAM,cAAc;IAGzB,YACmB,WAAwB,EACxB,qBAA4C,EAClC,OAAwC;QAFlD,gBAAW,GAAX,WAAW,CAAa;QACxB,0BAAqB,GAArB,qBAAqB,CAAuB;QACjB,YAAO,GAAP,OAAO,CAAgB;QALrE,WAAM,GAAW,IAAI,eAAM,CAAC,gBAAc,CAAC,IAAI,CAAC,CAAC;IAM9C,CAAC;IAgBE,aAAa,CACV,OAAgB,EAChB,GAAa,EACJ,KAAa,EACrB,IAAiC;;YAEzC,IAAI,CAAC;gBACH,MAAM,iBAAiB,GAAG,MAAM,IAAA,8CAAwB,EACtD,IAAI,CAAC,OAAO,EACZ,sBAAsB,EACtB,OAAO,CACR,CAAC;gBACF,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;oBAC/B,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;gBACnF,CAAC;gBAED,MAAM,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBACrE,OAAO,yBAAa,CAAC,aAAa,CAAC,GAAG,EAAE,mCAAmC,CAAC,CAAC;YAC/E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAc,CAAC,IAAI,EAAE,mBAAU,CAAC,WAAW,CAAC,CAAC;YACjG,CAAC;QACH,CAAC;KAAA;IAkBK,cAAc,CACX,OAAgB,EACf,IAA2B,EAC5B,GAAa;;YAEpB,IAAI,CAAC;gBACH,MAAM,iBAAiB,GAAG,MAAM,IAAA,8CAAwB,EACtD,IAAI,CAAC,OAAO,EACZ,gBAAgB,EAChB,OAAO,CACR,CAAC;gBACF,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;oBAC/B,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;gBACnF,CAAC;gBAED,MAAM,YAAY,GAAG,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,CAAA,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;oBAC9E,CAAC,CAAC,IAAI,CAAC,KAAK;oBACZ,CAAC,CAAC,IAAA,8CAAyB,EAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBAC7D,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,OAAO,yBAAa,CAAC,gBAAgB,CACnC,GAAG,EACH,mBAAmB,EACnB,gBAAc,CAAC,IAAI,EACnB,mBAAU,CAAC,WAAW,CACvB,CAAC;gBACJ,CAAC;gBAED,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBAC/F,MAAM,QAAQ,GAAI,oBAA6C,aAA7C,oBAAoB,uBAApB,oBAAoB,CAA2B,MAAM,CAAC;gBACxE,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACrE,CAAC;gBAED,2EAA2E;gBAC3E,sFAAsF;gBACtF,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAc,CAAC,IAAI,EAAE,mBAAU,CAAC,YAAY,CAAC,CAAC;YAClG,CAAC;QACH,CAAC;KAAA;IAaK,cAAc,CAAQ,OAAgB,EAAS,GAAa;;YAChE,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAA,2CAA2B,EAAC,OAAO,CAAC,CAAC;gBAClD,IAAI,CAAC,IAAA,6CAAyB,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7C,MAAM,IAAI,sBAAa,CACrB;wBACE,IAAI,EAAE,qCAAqC;wBAC3C,OAAO,EAAE,yDAAyD;qBACnE,EACD,mBAAU,CAAC,eAAe,CAC3B,CAAC;gBACJ,CAAC;gBACD,MAAM,IAAA,6CAAyB,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;gBACjE,MAAM,YAAY,GAAG,IAAA,6CAA+B,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACnE,IAAI,YAAY;oBAAE,IAAA,qCAAuB,EAAC,GAAG,EAAE,YAAY,CAAC,CAAC;gBAC7D,OAAO,yBAAa,CAAC,aAAa,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;YAC7E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,yBAAa,CAAC,gBAAgB,CACnC,GAAG,EACH,KAAK,EACL,gBAAc,CAAC,IAAI,EACnB,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,mBAAU,CAAC,WAAW,CAC5E,CAAC;YACJ,CAAC;QACH,CAAC;KAAA;IAgBK,WAAW,CACR,OAAgB,EACf,IAAwB,EACzB,GAAa;;;YAEpB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAA,2CAA2B,EAAC,OAAO,CAAC,CAAC;gBAClD,IAAI,CAAC,IAAA,qDAA6B,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBACjD,MAAM,IAAI,sBAAa,CACrB;wBACE,IAAI,EAAE,0CAA0C;wBAChD,OAAO,EAAE,kEAAkE;qBAC5E,EACD,mBAAU,CAAC,eAAe,CAC3B,CAAC;gBACJ,CAAC;gBAED,MAAM,OAAO,GAAG,CAAC,MAAC,OAAwC,CAAC,IAAI,mCAAI,EAAE,CAA4B,CAAC;gBAClG,MAAM,UAAU,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC7E,MAAM,YAAY,GAAG,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1E,MAAM,SAAS,GAAG,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;gBAElE,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,IAAI,sBAAa,CACrB,EAAE,IAAI,EAAE,2BAA2B,EAAE,OAAO,EAAE,0CAA0C,EAAE,EAC1F,mBAAU,CAAC,WAAW,CACvB,CAAC;gBACJ,CAAC;gBAED,MAAM,cAAc,GAAG,SAAS,KAAK,UAAU,CAAC;gBAChD,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC1D,MAAM,IAAI,sBAAa,CACrB;wBACE,IAAI,EAAE,gCAAgC;wBACtC,OAAO,EAAE,uEAAuE;qBACjF,EACD,mBAAU,CAAC,SAAS,CACrB,CAAC;gBACJ,CAAC;gBAED,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACtC,MAAM,IAAA,gDAAwB,EAC5B,IAAI,CAAC,OAAO,EACZ,SAAS,EACT,cAAc,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAC5E,CAAC;gBACF,IAAA,oBAAY,EAAC,sBAAsB,EAAE;oBACnC,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,KAAK,EAAE,IAAI,CAAC,YAAY;oBACxB,GAAG,EAAE,SAAS;oBACd,IAAI,EAAE,cAAc;iBACrB,CAAC,CAAC;gBACH,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,YAAY,GAAG,IAAA,6CAA+B,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACnE,IAAI,YAAY;wBAAE,IAAA,qCAAuB,EAAC,GAAG,EAAE,YAAY,CAAC,CAAC;gBAC/D,CAAC;gBACD,OAAO,yBAAa,CAAC,aAAa,CAAC,GAAG,EAAE,8BAA8B,CAAC,CAAC;YAC1E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,yBAAa,CAAC,gBAAgB,CACnC,GAAG,EACH,KAAK,EACL,gBAAc,CAAC,IAAI,EACnB,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,mBAAU,CAAC,WAAW,CAC5E,CAAC;YACJ,CAAC;QACH,CAAC;KAAA;IA0BK,KAAK,CAAQ,OAAgB,EAAU,YAA0B,EAAS,GAAa;;YAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,iBAAiB,GAAG,MAAM,IAAA,8CAAwB,EACtD,IAAI,CAAC,OAAO,EACZ,OAAO,EACP,OAAO,EACP,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAC,CACtB,CAAC;gBACF,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;oBAC/B,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;oBACjF,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;gBACnF,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gBAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;oBAC5E,OAAO,yBAAa,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;gBACnD,CAAC;gBAED,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;oBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC/E,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;oBAC/B,IAAI,MAAM,CAAC,OAAO;wBAAE,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC;oBAC3D,IAAA,qCAAuB,EAAC,GAAG,EAAE,IAAA,6CAA+B,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACxF,CAAC;gBAED,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS;oBAC/B,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,QAAQ,CAAC,gBAAgB;wBACzB,CAAC,CAAC,mBAAmB;wBACrB,CAAC,CAAC,SAAS,CAAC;gBAChB,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACjE,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACvD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAI,KAAe,aAAf,KAAK,uBAAL,KAAK,CAAY,OAAO,CAAC;gBAC1C,MAAM,MAAM,GAAG,OAAO,KAAK,kBAAkB;oBAC3C,CAAC,CAAC,kBAAkB;oBACpB,CAAC,CAAC,OAAO,KAAK,qCAAuB;wBACnC,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,OAAO,CAAC;gBACd,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACjE,IAAI,OAAO,KAAK,kBAAkB,EAAE,CAAC;oBACnC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;oBACnE,OAAO,yBAAa,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;gBAChD,CAAC;gBAED,IAAI,KAAK,YAAY,sBAAa,EAAE,CAAC;oBACnC,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAc,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC5F,CAAC;gBAED,IAAI,CAAC,KAAe,aAAf,KAAK,uBAAL,KAAK,CAAY,OAAO,MAAK,qCAAuB,EAAE,CAAC;oBAC1D,OAAO,GAAG,CAAC,MAAM,CAAC,mBAAU,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;wBAC3C,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAU,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC;wBAC9D,IAAI,EAAE,qCAAuB;wBAC7B,KAAK,EAAE,qCAAuB;wBAC9B,OAAO,EAAE,+EAA+E;qBACzF,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;gBACpD,IAAI,yBAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/C,OAAO,yBAAa,CAAC,gBAAgB,CACnC,GAAG,EACH,KAAK,EACL,gBAAc,CAAC,IAAI,EACnB,mBAAU,CAAC,mBAAmB,CAC/B,CAAC;gBACJ,CAAC;gBACD,OAAO,yBAAa,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;YACnD,CAAC;oBAAS,CAAC;gBACT,IAAA,8BAAoB,EAAC,IAAI,CAAC,OAAO,EAAE,wBAAwB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;KAAA;IAaK,OAAO,CACJ,OAAgB,EACf,IAAyB,EAC1B,GAAa;;YAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,IAAA,6CAA+B,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACnE,MAAM,kBAAkB,GAAG,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,iBAAiB;oBACxD,CAAC,CAAC,IAAA,8CAAgC,EAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;oBACxE,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,YAAY,GAAG,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY,CAAA,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;oBAC5F,CAAC,CAAC,IAAI,CAAC,YAAY;oBACnB,CAAC,CAAC,kBAAkB,CAAC;gBACvB,MAAM,QAAQ,GAAG,OAAO,YAAY,KAAK,QAAQ;oBAC/C,CAAC,CAAC,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBACtE,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,QAAQ,GAAG,MAAM,IAAA,8CAAwB,EAC7C,IAAI,CAAC,OAAO,EACZ,SAAS,EACT,OAAO,EACP,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3B,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;oBACtB,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;oBACnF,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;gBAC1E,CAAC;gBAED,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,IAAI,sBAAa,CAAC,yBAAyB,EAAE,mBAAU,CAAC,YAAY,CAAC,CAAC;gBAC9E,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;gBACvE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,MAAM,IAAI,sBAAa,CAAC,2BAA2B,EAAE,mBAAU,CAAC,YAAY,CAAC,CAAC;gBAChF,CAAC;gBACD,MAAM,QAAQ,mBACZ,KAAK,EAAE,MAAM,CAAC,KAAK,IAChB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACtE,CAAC;gBACF,IAAA,qCAAuB,EAAC,GAAG,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;gBACrD,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC9E,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACvD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;gBAClC,MAAM,MAAM,GAAG,IAAI,KAAK,6BAA6B;oBACnD,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,IAAI,KAAK,gCAAgC;wBACzC,CAAC,CAAC,gBAAgB;wBAClB,CAAC,CAAC,IAAI,KAAK,sCAAsC;4BAC/C,CAAC,CAAC,mBAAmB;4BACrB,CAAC,CAAC,SAAS,CAAC;gBAClB,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACnE,OAAO,yBAAa,CAAC,gBAAgB,CACnC,GAAG,EACH,KAAK,EACL,gBAAc,CAAC,IAAI,EACnB,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,mBAAU,CAAC,YAAY,CAC7E,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,IAAA,8BAAoB,EAAC,IAAI,CAAC,OAAO,EAAE,0BAA0B,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;KAAA;IAQK,eAAe,CAAQ,OAAgB,EAAU,IAA4B,EAAS,GAAa;;YACvG,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,IAAA,8CAAwB,EAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC3G,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACnB,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;oBACxG,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACvE,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/F,IAAA,qCAAuB,EAAC,GAAG,EAAE,IAAA,6CAA+B,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;gBACpF,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACnG,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACnG,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAc,CAAC,IAAI,EAAE,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACnI,CAAC;oBAAS,CAAC;gBACT,IAAA,8BAAoB,EAAC,IAAI,CAAC,OAAO,EAAE,6BAA6B,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;KAAA;IAQK,eAAe,CAAQ,OAAgB,EAAU,IAA4B,EAAS,GAAa;;YACvG,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,IAAA,8CAAwB,EAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC3G,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACnB,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;oBACxG,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACvE,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACxE,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACnG,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACnG,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAc,CAAC,IAAI,EAAE,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACnI,CAAC;QACH,CAAC;KAAA;IAeK,cAAc,CAAQ,OAAgB,EAAU,IAA2B,EAAS,GAAa;;YACrG,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,IAAA,8CAAwB,EAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;gBACtF,IAAI,CAAC,KAAK,CAAC,OAAO;oBAAE,OAAO,IAAA,qDAA+B,EAAC,GAAG,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACzF,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/F,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAc,CAAC,IAAI,EAAE,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACnI,CAAC;QACH,CAAC;KAAA;IAUK,oBAAoB,CAAQ,GAAa;;YAC7C,OAAO,yBAAa,CAAC,gBAAgB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAClG,CAAC;KAAA;CACF,CAAA;AA7dY,wCAAc;AAuBnB;IAdL,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,kCAAkC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;IAC3F,IAAA,kBAAQ,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC7F,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,kCAA2B,EAAE,CAAC;IAC9C,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,kCAAkC;QAC/C,IAAI,EAAE,qBAAc;KACrB,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,2CAA2C;QACxD,IAAI,EAAE,oBAAa;KACpB,CAAC;IACD,IAAA,aAAI,EAAC,+BAA+B,CAAC;IAEnC,WAAA,IAAA,YAAG,GAAE,CAAA;IACL,WAAA,IAAA,YAAG,GAAE,CAAA;IACL,WAAA,IAAA,cAAK,EAAC,OAAO,CAAC,CAAA;IACd,WAAA,IAAA,aAAI,GAAE,CAAA;;6DAAO,kCAA2B;;mDAiB1C;AAkBK;IAhBL,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,+CAA+C;QACxD,WAAW,EAAE,gBAAgB;KAC9B,CAAC;IACD,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,4BAAqB,EAAE,CAAC;IACxC,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,6CAA6C;QAC1D,IAAI,EAAE,6BAAsB;KAC7B,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,4BAA4B;QACzC,IAAI,EAAE,oBAAa;KACpB,CAAC;IACD,IAAA,aAAI,EAAC,mBAAmB,CAAC;IAEvB,WAAA,IAAA,YAAG,GAAE,CAAA;IACL,WAAA,IAAA,aAAI,GAAE,CAAA;IACN,WAAA,IAAA,YAAG,GAAE,CAAA;;6CADQ,4BAAqB;;oDAqCpC;AAaK;IAXL,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,+CAA+C;QACxD,WAAW,EAAE,gBAAgB;QAC7B,WAAW,EACT,+IAA+I;KAClJ,CAAC;IACD,IAAA,uBAAa,EAAC,EAAE,IAAI,EAAE,qBAAc,EAAE,CAAC;IACvC,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;IACtG,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IAClG,IAAA,kBAAS,EAAC,6BAAc,CAAC;IACzB,IAAA,aAAI,EAAC,iBAAiB,CAAC;IACF,WAAA,IAAA,YAAG,GAAE,CAAA;IAAoB,WAAA,IAAA,YAAG,GAAE,CAAA;;;;oDAwBnD;AAgBK;IAdL,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,4CAA4C;QACrD,WAAW,EAAE,aAAa;QAC1B,WAAW,EACT,+GAA+G;YAC/G,wHAAwH;KAC3H,CAAC;IACD,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,yBAAkB,EAAE,CAAC;IACrC,IAAA,uBAAa,EAAC,EAAE,IAAI,EAAE,qBAAc,EAAE,CAAC;IACvC,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;IACtG,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC;IAC/G,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;IAC/F,IAAA,kBAAS,EAAC,6BAAc,CAAC;IACzB,IAAA,aAAI,EAAC,cAAc,CAAC;IAElB,WAAA,IAAA,YAAG,GAAE,CAAA;IACL,WAAA,IAAA,aAAI,GAAE,CAAA;IACN,WAAA,IAAA,YAAG,GAAE,CAAA;;6CADQ,yBAAkB;;iDA+DjC;AA0BK;IAxBL,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,0BAA0B;QACnC,WAAW,EACT,wOAAwO;QAC1O,WAAW,EAAE,OAAO;KACrB,CAAC;IACD,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,mBAAY,EAAE,CAAC;IAC/B,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,+BAA+B;QAC5C,IAAI,EAAE,oBAAa;KACpB,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,wBAAwB;QACrC,IAAI,EAAE,oBAAa;KACpB,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,6CAA6C;QAC1D,IAAI,EAAE,8BAAuB;KAC9B,CAAC;IACD,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,8BAA8B,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC9F,IAAA,aAAI,EAAC,OAAO,CAAC;IACD,WAAA,IAAA,YAAG,GAAE,CAAA;IAAoB,WAAA,IAAA,aAAI,GAAE,CAAA;IAA8B,WAAA,IAAA,YAAG,GAAE,CAAA;;6CAApB,mBAAY;;2CAyEtE;AAaK;IAXL,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,oDAAoD;QAC7D,WAAW,EAAE,oBAAoB;QACjC,WAAW,EACT,wGAAwG;KAC3G,CAAC;IACD,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,0BAAmB,EAAE,CAAC;IACtC,IAAA,uBAAa,EAAC,EAAE,IAAI,EAAE,2BAAoB,EAAE,CAAC;IAC7C,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,+CAA+C,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC/G,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,mBAAmB,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IACnF,IAAA,aAAI,EAAC,SAAS,CAAC;IAEb,WAAA,IAAA,YAAG,GAAE,CAAA;IACL,WAAA,IAAA,aAAI,GAAE,CAAA;IACN,WAAA,IAAA,YAAG,GAAE,CAAA;;6CADQ,0BAAmB;;6CA4DlC;AAQK;IANL,IAAA,aAAI,EAAC,mBAAmB,CAAC;IACzB,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,wCAAwC,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACnG,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,sCAAsB,EAAE,CAAC;IACzC,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IACjD,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IACjD,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC3B,WAAA,IAAA,YAAG,GAAE,CAAA;IAAoB,WAAA,IAAA,aAAI,GAAE,CAAA;IAAgC,WAAA,IAAA,YAAG,GAAE,CAAA;;6CAA9B,sCAAsB;;qDAkBlF;AAQK;IANL,IAAA,aAAI,EAAC,mBAAmB,CAAC;IACzB,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,8CAA8C,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACzG,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,sCAAsB,EAAE,CAAC;IACzC,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IACjD,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IACjD,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC3B,WAAA,IAAA,YAAG,GAAE,CAAA;IAAoB,WAAA,IAAA,aAAI,GAAE,CAAA;IAAgC,WAAA,IAAA,YAAG,GAAE,CAAA;;6CAA9B,sCAAsB;;qDAclF;AAeK;IAbL,IAAA,aAAI,EAAC,iBAAiB,CAAC;IACvB,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,wCAAwC;QACjD,WAAW,EAAE,gBAAgB;QAC7B,WAAW,EACT,4FAA4F;YAC5F,mHAAmH;KACtH,CAAC;IACD,IAAA,iBAAO,EAAC,EAAE,IAAI,EAAE,4BAAqB,EAAE,CAAC;IACxC,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,6BAAsB,EAAE,CAAC;IAC1D,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,+BAA+B,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC/F,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,+BAA+B,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC/F,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAa,EAAE,CAAC;IAC7D,WAAA,IAAA,YAAG,GAAE,CAAA;IAAoB,WAAA,IAAA,aAAI,GAAE,CAAA;IAA+B,WAAA,IAAA,YAAG,GAAE,CAAA;;6CAA7B,4BAAqB;;oDAQhF;AAUK;IARL,IAAA,YAAG,EAAC,wBAAwB,CAAC;IAC7B,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,0CAA0C;QACnD,WAAW,EAAE,yBAAyB;QACtC,WAAW,EACT,iGAAiG;KACpG,CAAC;IACD,IAAA,qBAAW,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,mCAA4B,EAAE,CAAC;IACrC,WAAA,IAAA,YAAG,GAAE,CAAA;;;;0DAEhC;yBA5dU,cAAc;IAL1B,IAAA,iBAAO,EAAC,MAAM,CAAC;IACf,IAAA,mBAAU,EAAC,cAAc,CAAC,CAAA;;;OAGxB;IAOE,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;qCAFI,yBAAW;QACD,6CAAqB;GALpD,cAAc,CA6d1B","sourcesContent":["import { Body, Controller, Get, HttpException, HttpStatus, Inject, Param, Post, Req, Res, UseGuards } from '@nestjs/common';\nimport { ResendTwoFactorRequest, VerifyTwoFactorRequest } from '../Dtos/TwoFactorDtos';\nimport { ApiBody, ApiOkResponse, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';\nimport { Request, Response } from 'express';\nimport { createHash } from 'crypto';\nimport { Logger } from '../../Logger';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions } from '../AccessiModule';\nimport {\n ActionResponse,\n AdminBootstrapStatusResponse,\n BootstrapAdminRequest,\n BootstrapAdminResponse,\n ConfirmResetPasswordRequest,\n ErrorResponse,\n GetUserByTokenRequest,\n GetUserByTokenResponse,\n LoginRequest,\n LoginResponse,\n PasswordExpiredResponse,\n RefreshTokenRequest,\n RefreshTokenResponse,\n RevokeTokenRequest,\n} from '../Dtos';\nimport { AuthService, PASSWORD_LOGIN_DISABLED } from '../Services/AuthService/AuthService';\nimport { AdminBootstrapService } from '../Services/AdminBootstrapService/AdminBootstrapService';\nimport { JwtSimpleGuard } from '../jwt/jwt.strategy';\nimport { getAuthenticatedAccessiUser } from '../security/accessControl';\nimport { extractAccessiBearerToken } from '../security/authenticatedToken';\nimport {\n applyAccessiAuthCookies,\n clearAccessiAuthCookies,\n getAccessiRefreshTokenFromCookie,\n resolveAccessiAuthCookieOptions,\n} from '../security/authCookies';\nimport {\n countAccessiMetric,\n observeAccessiMetric,\n} from '../observability/metrics';\nimport {\n getSessionRevocationStore,\n revokeAccessiUserSessions,\n} from '../security/sessionRevocation';\nimport {\n getAccessTokenRevocationStore,\n revokeAccessiAccessToken,\n} from '../security/accessTokenRevocation';\nimport { auditAccessi } from '../security/audit';\nimport {\n checkPublicAuthRateLimit,\n sendPublicAuthRateLimitExceeded,\n} from '../security/publicAuthRateLimit';\n\n/** Estrae il codice stabile di un errore Nest `{ code, message }`. */\nfunction authErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== 'object') return undefined;\n const response = typeof (error as { getResponse?: unknown }).getResponse === 'function'\n ? (error as { getResponse: () => unknown }).getResponse()\n : (error as { response?: unknown }).response;\n if (response && typeof response === 'object') {\n const code = (response as { code?: unknown }).code;\n return typeof code === 'string' ? code : undefined;\n }\n return undefined;\n}\n\n@ApiTags('Auth')\n@Controller('accessi/auth')/**\n * Endpoint pubblici di autenticazione locale e verifica sessione.\n * Il login SSO non riceve token esterni qui: il backend validante usa `FederatedAuthService.authenticate`.\n */\nexport class AuthController {\n logger: Logger = new Logger(AuthController.name);\n\n constructor(\n private readonly authService: AuthService,\n private readonly adminBootstrapService: AdminBootstrapService,\n @Inject('ACCESSI_OPTIONS') private readonly options: AccessiOptions,\n ) {}\n\n @ApiOperation({ summary: 'Conferma il reset della password', operationId: 'resetPassword' })\n @ApiParam({ name: 'token', description: 'Token per il reset della password', required: true })\n @ApiBody({ type: ConfirmResetPasswordRequest })\n @ApiResponse({\n status: 200,\n description: 'Password aggiornata con successo',\n type: ActionResponse,\n })\n @ApiResponse({\n status: 400,\n description: 'Errore nella richiesta o token non valido',\n type: ErrorResponse,\n })\n @Post('confirm-reset-password/:token')\n async resetPassword(\n @Req() request: Request,\n @Res() res: Response,\n @Param('token') token: string,\n @Body() body: ConfirmResetPasswordRequest,\n ) {\n try {\n const rateLimitDecision = await checkPublicAuthRateLimit(\n this.options,\n 'passwordResetConfirm',\n request,\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n await this.authService.confirmResetPassword(token, body.newPassword);\n return RestUtilities.sendOKMessage(res, 'Password aggiornata con successo!');\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, HttpStatus.BAD_REQUEST);\n }\n }\n\n @ApiOperation({\n summary: 'Recupera le informazioni utente dal token JWT',\n operationId: 'getUserByToken',\n })\n @ApiBody({ type: GetUserByTokenRequest })\n @ApiResponse({\n status: 200,\n description: 'Informazioni utente recuperate con successo',\n type: GetUserByTokenResponse,\n })\n @ApiResponse({\n status: 401,\n description: 'Token non valido o scaduto',\n type: ErrorResponse,\n })\n @Post('get-user-by-token')\n async getUserByToken(\n @Req() request: Request,\n @Body() body: GetUserByTokenRequest,\n @Res() res: Response,\n ) {\n try {\n const rateLimitDecision = await checkPublicAuthRateLimit(\n this.options,\n 'getUserByToken',\n request,\n );\n if (!rateLimitDecision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n const requestToken = typeof body?.token === 'string' && body.token.trim() !== ''\n ? body.token\n : extractAccessiBearerToken(request.headers.authorization);\n if (!requestToken) {\n return RestUtilities.sendErrorMessage(\n res,\n 'Token non fornito',\n AuthController.name,\n HttpStatus.BAD_REQUEST,\n );\n }\n\n const authenticatedPayload = await this.authService.getAuthenticatedTokenPayload(requestToken);\n const userData = (authenticatedPayload as { utente?: unknown })?.utente;\n if (!userData) {\n throw new Error('Il token non contiene un utente Accessi valido.');\n }\n\n // Keep the runtime response aligned with GetUserByTokenResponse and Orval:\n // Result.userData contains the authenticated user directly, not a nested JWT payload.\n return RestUtilities.sendBaseResponse(res, { userData });\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, HttpStatus.UNAUTHORIZED);\n }\n }\n\n @ApiOperation({\n summary: 'Revoca tutte le sessioni dell utente corrente',\n operationId: 'revokeSessions',\n description:\n 'Invalida i token emessi prima di questa chiamata. Richiede sessionRevocation.store configurato. I token emessi dopo la revoca restano validi.',\n })\n @ApiOkResponse({ type: ActionResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Token Accessi mancante o non valido.' })\n @ApiResponse({ status: 501, type: ErrorResponse, description: 'Revoca sessioni non configurata.' })\n @UseGuards(JwtSimpleGuard)\n @Post('revoke-sessions')\n async revokeSessions(@Req() request: Request, @Res() res: Response) {\n try {\n const user = getAuthenticatedAccessiUser(request);\n if (!getSessionRevocationStore(this.options)) {\n throw new HttpException(\n {\n code: 'ACCESSI_SESSION_REVOCATION_DISABLED',\n message: 'La revoca sessioni non e configurata su questa istanza.',\n },\n HttpStatus.NOT_IMPLEMENTED,\n );\n }\n await revokeAccessiUserSessions(this.options, user.codiceUtente);\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n if (cookieConfig) clearAccessiAuthCookies(res, cookieConfig);\n return RestUtilities.sendOKMessage(res, 'Sessioni revocate con successo.');\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.BAD_REQUEST,\n );\n }\n }\n\n @ApiOperation({\n summary: 'Revoca un singolo access token tramite jti',\n operationId: 'revokeToken',\n description:\n 'Annulla un solo token (logout del dispositivo corrente o token compromesso) senza toccare le altre sessioni. ' +\n 'Se il body non contiene jti viene revocato il token della richiesta. Richiede accessTokenRevocation.store configurato.',\n })\n @ApiBody({ type: RevokeTokenRequest })\n @ApiOkResponse({ type: ActionResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Token Accessi mancante o non valido.' })\n @ApiResponse({ status: 403, type: ErrorResponse, description: 'Non autorizzato a revocare il token indicato.' })\n @ApiResponse({ status: 501, type: ErrorResponse, description: 'Revoca token non configurata.' })\n @UseGuards(JwtSimpleGuard)\n @Post('revoke-token')\n async revokeToken(\n @Req() request: Request,\n @Body() body: RevokeTokenRequest,\n @Res() res: Response,\n ) {\n try {\n const user = getAuthenticatedAccessiUser(request);\n if (!getAccessTokenRevocationStore(this.options)) {\n throw new HttpException(\n {\n code: 'ACCESSI_ACCESS_TOKEN_REVOCATION_DISABLED',\n message: 'La revoca dei singoli token non e configurata su questa istanza.',\n },\n HttpStatus.NOT_IMPLEMENTED,\n );\n }\n\n const payload = ((request as Request & { user?: unknown }).user ?? {}) as Record<string, unknown>;\n const currentJti = typeof payload.jti === 'string' ? payload.jti : undefined;\n const requestedJti = typeof body?.jti === 'string' ? body.jti.trim() : '';\n const targetJti = requestedJti !== '' ? requestedJti : currentJti;\n\n if (!targetJti) {\n throw new HttpException(\n { code: 'ACCESSI_TOKEN_JTI_MISSING', message: 'Il token non contiene un jti revocabile.' },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n const isCurrentToken = targetJti === currentJti;\n if (!isCurrentToken && !user.flagAdmin && !user.flagSuper) {\n throw new HttpException(\n {\n code: 'ACCESSI_TOKEN_REVOKE_FORBIDDEN',\n message: 'Solo gli amministratori possono revocare il token di un altro utente.',\n },\n HttpStatus.FORBIDDEN,\n );\n }\n\n const expiresAt = Number(payload.exp);\n await revokeAccessiAccessToken(\n this.options,\n targetJti,\n isCurrentToken && Number.isFinite(expiresAt) ? expiresAt * 1000 : undefined,\n );\n auditAccessi('access_token_revoked', {\n codiceUtente: user.codiceUtente,\n actor: user.codiceUtente,\n jti: targetJti,\n self: isCurrentToken,\n });\n if (isCurrentToken) {\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n if (cookieConfig) clearAccessiAuthCookies(res, cookieConfig);\n }\n return RestUtilities.sendOKMessage(res, 'Token revocato con successo.');\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.BAD_REQUEST,\n );\n }\n }\n\n @ApiOperation({\n summary: 'Effettua il login utente',\n description:\n \"Con sola email restituisce passwordRequired oppure avvia il codice per utenti passwordless. Con password valida restituisce il login completo o challenge se la 2FA e attiva. Nessun JWT viene emesso prima della verifica del codice.\",\n operationId: 'login',\n })\n @ApiBody({ type: LoginRequest })\n @ApiResponse({\n status: 200,\n description: 'Login effettuato con successo',\n type: LoginResponse,\n })\n @ApiResponse({\n status: 401,\n description: 'Credenziali non valide',\n type: ErrorResponse,\n })\n @ApiResponse({\n status: 403,\n description: 'Password scaduta, e necessario aggiornarla.',\n type: PasswordExpiredResponse,\n })\n @ApiResponse({ status: 403, description: 'Utente abilitato solo a SSO.', type: ErrorResponse })\n @Post('login')\n async login(@Req() request: Request, @Body() loginRequest: LoginRequest, @Res() res: Response) {\n const startedAt = Date.now();\n try {\n const rateLimitDecision = await checkPublicAuthRateLimit(\n this.options,\n 'login',\n request,\n [loginRequest?.email],\n );\n if (!rateLimitDecision.allowed) {\n countAccessiMetric(this.options, 'auth_login_total', { result: 'rate_limited' });\n return sendPublicAuthRateLimitExceeded(res, rateLimitDecision.retryAfterSeconds);\n }\n\n const userData = await this.authService.login(loginRequest);\n if (!userData) {\n countAccessiMetric(this.options, 'auth_login_total', { result: 'failure' });\n return RestUtilities.sendInvalidCredentials(res);\n }\n\n if (!userData.challenge && !userData.passwordRequired) {\n const tokens = this.authService.createTokenPair(userData.utente, ['password']);\n userData.token = tokens.access;\n if (tokens.refresh) userData.refreshToken = tokens.refresh;\n applyAccessiAuthCookies(res, resolveAccessiAuthCookieOptions(this.options), userData);\n }\n\n const result = userData.challenge\n ? 'challenge'\n : userData.passwordRequired\n ? 'password_required'\n : 'success';\n countAccessiMetric(this.options, 'auth_login_total', { result });\n return RestUtilities.sendBaseResponse(res, userData);\n } catch (error) {\n const message = (error as Error)?.message;\n const result = message === 'PASSWORD_EXPIRED'\n ? 'password_expired'\n : message === PASSWORD_LOGIN_DISABLED\n ? 'sso_only'\n : 'error';\n countAccessiMetric(this.options, 'auth_login_total', { result });\n if (message === 'PASSWORD_EXPIRED') {\n this.logger.warning('Password scaduta, cambiare password ', error);\n return RestUtilities.sendPasswordExpired(res);\n }\n\n if (error instanceof HttpException) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error.getStatus());\n }\n\n if ((error as Error)?.message === PASSWORD_LOGIN_DISABLED) {\n return res.status(HttpStatus.FORBIDDEN).json({\n severity: 'error', status: HttpStatus.FORBIDDEN, statusCode: 2,\n code: PASSWORD_LOGIN_DISABLED,\n error: PASSWORD_LOGIN_DISABLED,\n message: 'Questo utente e abilitato solo tramite SSO. Accedi con un provider collegato.',\n });\n }\n\n this.logger.error('Errore durante il login', error);\n if (RestUtilities.isDatabaseSchemaError(error)) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n HttpStatus.SERVICE_UNAVAILABLE,\n );\n }\n return RestUtilities.sendInvalidCredentials(res);\n } finally {\n observeAccessiMetric(this.options, 'auth_login_duration_ms', Date.now() - startedAt);\n }\n }\n\n @ApiOperation({\n summary: 'Scambia un refresh token con un nuovo access token',\n operationId: 'refreshAccessToken',\n description:\n 'Richiede jwtOptions.refreshExpiresIn. Il refresh token ha typ=refresh e non e accettato dai guard API.',\n })\n @ApiBody({ type: RefreshTokenRequest })\n @ApiOkResponse({ type: RefreshTokenResponse })\n @ApiResponse({ status: 401, description: 'Refresh token non valido, scaduto o revocato.', type: ErrorResponse })\n @ApiResponse({ status: 429, description: 'Troppi tentativi.', type: ErrorResponse })\n @Post('refresh')\n async refresh(\n @Req() request: Request,\n @Body() body: RefreshTokenRequest,\n @Res() res: Response,\n ) {\n const startedAt = Date.now();\n try {\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n const cookieRefreshToken = cookieConfig?.refreshFromCookie\n ? getAccessiRefreshTokenFromCookie(request.headers.cookie, cookieConfig)\n : undefined;\n const refreshToken = typeof body?.refreshToken === 'string' && body.refreshToken.trim() !== ''\n ? body.refreshToken\n : cookieRefreshToken;\n const tokenKey = typeof refreshToken === 'string'\n ? createHash('sha256').update(refreshToken).digest('hex').slice(0, 32)\n : undefined;\n const decision = await checkPublicAuthRateLimit(\n this.options,\n 'refresh',\n request,\n tokenKey ? [tokenKey] : [],\n );\n if (!decision.allowed) {\n countAccessiMetric(this.options, 'auth_refresh_total', { result: 'rate_limited' });\n return sendPublicAuthRateLimitExceeded(res, decision.retryAfterSeconds);\n }\n\n if (!refreshToken) {\n throw new HttpException('Refresh token mancante.', HttpStatus.UNAUTHORIZED);\n }\n\n const result = await this.authService.refreshAccessToken(refreshToken);\n if (!result.token) {\n throw new HttpException('Refresh token non valido.', HttpStatus.UNAUTHORIZED);\n }\n const response = {\n token: result.token,\n ...(result.refreshToken ? { refreshToken: result.refreshToken } : {}),\n };\n applyAccessiAuthCookies(res, cookieConfig, response);\n countAccessiMetric(this.options, 'auth_refresh_total', { result: 'success' });\n return RestUtilities.sendBaseResponse(res, response);\n } catch (error) {\n const code = authErrorCode(error);\n const result = code === 'ACCESSI_REFRESH_TOKEN_REUSE'\n ? 'reuse'\n : code === 'ACCESSI_REFRESH_FAMILY_REVOKED'\n ? 'family_revoked'\n : code === 'ACCESSI_REFRESH_ROTATION_UNAVAILABLE'\n ? 'store_unavailable'\n : 'invalid';\n countAccessiMetric(this.options, 'auth_refresh_total', { result });\n return RestUtilities.sendErrorMessage(\n res,\n error,\n AuthController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.UNAUTHORIZED,\n );\n } finally {\n observeAccessiMetric(this.options, 'auth_refresh_duration_ms', Date.now() - startedAt);\n }\n }\n\n @Post('two-factor/verify')\n @ApiOperation({ summary: 'Verifica il codice e completa il login', operationId: 'verifyTwoFactor' })\n @ApiBody({ type: VerifyTwoFactorRequest })\n @ApiResponse({ status: 200, type: LoginResponse })\n @ApiResponse({ status: 401, type: ErrorResponse })\n @ApiResponse({ status: 429, type: ErrorResponse })\n async verifyTwoFactor(@Req() request: Request, @Body() body: VerifyTwoFactorRequest, @Res() res: Response) {\n const startedAt = Date.now();\n try {\n const limit = await checkPublicAuthRateLimit(this.options, 'twoFactorVerify', request, [body.challengeId]);\n if (!limit.allowed) {\n countAccessiMetric(this.options, 'auth_two_factor_total', { action: 'verify', result: 'rate_limited' });\n return sendPublicAuthRateLimitExceeded(res, limit.retryAfterSeconds);\n }\n const result = await this.authService.verifyTwoFactor(body.challengeId, body.code, body.scope);\n applyAccessiAuthCookies(res, resolveAccessiAuthCookieOptions(this.options), result);\n countAccessiMetric(this.options, 'auth_two_factor_total', { action: 'verify', result: 'success' });\n return RestUtilities.sendBaseResponse(res, result);\n } catch (error) {\n countAccessiMetric(this.options, 'auth_two_factor_total', { action: 'verify', result: 'failure' });\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error instanceof HttpException ? error.getStatus() : 500);\n } finally {\n observeAccessiMetric(this.options, 'auth_two_factor_duration_ms', Date.now() - startedAt, { action: 'verify' });\n }\n }\n\n @Post('two-factor/resend')\n @ApiOperation({ summary: 'Reinvia il codice, invalidando il precedente', operationId: 'resendTwoFactor' })\n @ApiBody({ type: ResendTwoFactorRequest })\n @ApiResponse({ status: 200, type: LoginResponse })\n @ApiResponse({ status: 401, type: ErrorResponse })\n @ApiResponse({ status: 429, type: ErrorResponse })\n async resendTwoFactor(@Req() request: Request, @Body() body: ResendTwoFactorRequest, @Res() res: Response) {\n try {\n const limit = await checkPublicAuthRateLimit(this.options, 'twoFactorResend', request, [body.challengeId]);\n if (!limit.allowed) {\n countAccessiMetric(this.options, 'auth_two_factor_total', { action: 'resend', result: 'rate_limited' });\n return sendPublicAuthRateLimitExceeded(res, limit.retryAfterSeconds);\n }\n const result = await this.authService.resendTwoFactor(body.challengeId);\n countAccessiMetric(this.options, 'auth_two_factor_total', { action: 'resend', result: 'success' });\n return RestUtilities.sendBaseResponse(res, result);\n } catch (error) {\n countAccessiMetric(this.options, 'auth_two_factor_total', { action: 'resend', result: 'failure' });\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error instanceof HttpException ? error.getStatus() : 500);\n }\n }\n\n @Post('bootstrap-admin')\n @ApiOperation({\n summary: 'Crea il primo utente admin (bootstrap)',\n operationId: 'bootstrapAdmin',\n description:\n 'Endpoint pubblico ma protetto dal token di avvio: attivo solo con adminBootstrap.enabled. ' +\n 'Crea un utente in stato confermato senza email, con flag admin (e super opzionale) e password fornita o generata.',\n })\n @ApiBody({ type: BootstrapAdminRequest })\n @ApiResponse({ status: 200, type: BootstrapAdminResponse })\n @ApiResponse({ status: 401, description: 'Token di bootstrap non valido', type: ErrorResponse })\n @ApiResponse({ status: 403, description: 'Bootstrap admin non abilitato', type: ErrorResponse })\n @ApiResponse({ status: 429, description: 'Troppi tentativi', type: ErrorResponse })\n async bootstrapAdmin(@Req() request: Request, @Body() body: BootstrapAdminRequest, @Res() res: Response) {\n try {\n const limit = await checkPublicAuthRateLimit(this.options, 'adminBootstrap', request);\n if (!limit.allowed) return sendPublicAuthRateLimitExceeded(res, limit.retryAfterSeconds);\n return RestUtilities.sendBaseResponse(res, await this.adminBootstrapService.bootstrap(body));\n } catch (error) {\n return RestUtilities.sendErrorMessage(res, error, AuthController.name, error instanceof HttpException ? error.getStatus() : 500);\n }\n }\n\n @Get('bootstrap-admin/status')\n @ApiOperation({\n summary: 'Indica se il bootstrap admin e abilitato',\n operationId: 'getAdminBootstrapStatus',\n description:\n 'Endpoint pubblico: la console mostra la sezione \"Crea utente admin\" solo quando enabled e true.',\n })\n @ApiResponse({ status: 200, type: AdminBootstrapStatusResponse })\n async adminBootstrapStatus(@Res() res: Response) {\n return RestUtilities.sendBaseResponse(res, { enabled: this.adminBootstrapService.isEnabled() });\n }\n}\n"]}
@@ -34,6 +34,7 @@ const authenticatedToken_1 = require("../security/authenticatedToken");
34
34
  const consoleEntry_1 = require("../security/consoleEntry");
35
35
  const publicAuthRateLimit_1 = require("../security/publicAuthRateLimit");
36
36
  const authCookies_1 = require("../security/authCookies");
37
+ const metrics_1 = require("../observability/metrics");
37
38
  /**
38
39
  * Auto-ingresso alla console amministrativa da un frontend gia autenticato.
39
40
  * Il frontend scambia la propria sessione Accessi con un ticket monouso, poi apre
@@ -61,9 +62,11 @@ let ConsoleEntryController = ConsoleEntryController_1 = class ConsoleEntryContro
61
62
  throw new common_1.UnauthorizedException({ code: 'ACCESSI_CONSOLE_ENTRY_TOKEN_MISSING', message: 'Token Accessi mancante.' });
62
63
  }
63
64
  const issued = yield this.store.issue({ token: tokenValue, codiceUtente: user.codiceUtente }, this.ttlMs);
65
+ (0, metrics_1.countAccessiMetric)(this.options, 'console_ticket_total', { action: 'create', result: 'issued' });
64
66
  return Utilities_1.RestUtilities.sendBaseResponse(res, issued);
65
67
  }
66
68
  catch (error) {
69
+ (0, metrics_1.countAccessiMetric)(this.options, 'console_ticket_total', { action: 'create', result: 'error' });
67
70
  return Utilities_1.RestUtilities.sendErrorMessage(res, error, ConsoleEntryController_1.name, error instanceof common_1.HttpException ? error.getStatus() : common_1.HttpStatus.UNAUTHORIZED);
68
71
  }
69
72
  });
@@ -74,6 +77,7 @@ let ConsoleEntryController = ConsoleEntryController_1 = class ConsoleEntryContro
74
77
  try {
75
78
  const decision = yield (0, publicAuthRateLimit_1.checkPublicAuthRateLimit)(this.options, 'consoleEntry', request, [(_a = body === null || body === void 0 ? void 0 : body.ticket) !== null && _a !== void 0 ? _a : '']);
76
79
  if (!decision.allowed) {
80
+ (0, metrics_1.countAccessiMetric)(this.options, 'console_ticket_total', { action: 'exchange', result: 'rate_limited' });
77
81
  return (0, publicAuthRateLimit_1.sendPublicAuthRateLimitExceeded)(res, decision.retryAfterSeconds);
78
82
  }
79
83
  const entry = yield this.store.consume(body === null || body === void 0 ? void 0 : body.ticket);
@@ -83,6 +87,7 @@ let ConsoleEntryController = ConsoleEntryController_1 = class ConsoleEntryContro
83
87
  message: 'Ticket di ingresso console non valido o scaduto. Riapri la console dal frontend.',
84
88
  });
85
89
  }
90
+ (0, metrics_1.countAccessiMetric)(this.options, 'console_ticket_total', { action: 'exchange', result: 'consumed' });
86
91
  const cookieConfig = (0, authCookies_1.resolveAccessiAuthCookieOptions)(this.options);
87
92
  if (cookieConfig) {
88
93
  (0, authCookies_1.setAccessiAuthCookies)(res, cookieConfig, { access: entry.token });
@@ -93,6 +98,10 @@ let ConsoleEntryController = ConsoleEntryController_1 = class ConsoleEntryContro
93
98
  return Utilities_1.RestUtilities.sendBaseResponse(res, { token: { value: entry.token, type: 'Bearer' } });
94
99
  }
95
100
  catch (error) {
101
+ (0, metrics_1.countAccessiMetric)(this.options, 'console_ticket_total', {
102
+ action: 'exchange',
103
+ result: error instanceof common_1.UnauthorizedException ? 'invalid' : 'error',
104
+ });
96
105
  return Utilities_1.RestUtilities.sendErrorMessage(res, error, ConsoleEntryController_1.name, error instanceof common_1.HttpException ? error.getStatus() : common_1.HttpStatus.UNAUTHORIZED);
97
106
  }
98
107
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ConsoleEntryController.js","sourceRoot":"","sources":["../../../src/accessi-module/Controllers/ConsoleEntryController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Body,\n Controller,\n HttpException,\n HttpStatus,\n Inject,\n Post,\n Req,\n Res,\n UnauthorizedException,\n UseGuards,\n} from '@nestjs/common';\nimport {\n ApiBearerAuth,\n ApiBody,\n ApiOkResponse,\n ApiOperation,\n ApiResponse,\n ApiTags,\n} from '@nestjs/swagger';\nimport { Request, Response } from 'express';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { ConsoleEntryExchangeRequest, ConsoleEntrySessionResponse, ConsoleEntryTicketResponse } from '../Dtos/ConsoleEntryDtos';\nimport { ErrorResponse } from '../Dtos/BaseResponse';\nimport { JwtSimpleGuard } from '../jwt/jwt.strategy';\nimport { ensureConsoleAccess, getAuthenticatedAccessiUser } from '../security/accessControl';\nimport { extractAccessiBearerToken } from '../security/authenticatedToken';\nimport { getDefaultConsoleEntryStore } from '../security/consoleEntry';\nimport type { ConsoleEntryStore } from '../security/consoleEntry';\nimport {\n checkPublicAuthRateLimit,\n sendPublicAuthRateLimitExceeded,\n} from '../security/publicAuthRateLimit';\nimport {\n resolveAccessiAuthCookieOptions,\n setAccessiAuthCookies,\n} from '../security/authCookies';\n\n/**\n * Auto-ingresso alla console amministrativa da un frontend gia autenticato.\n * Il frontend scambia la propria sessione Accessi con un ticket monouso, poi apre\n * `/api/accessi/console#entry=<ticket>`: il JWT non passa mai nell'URL.\n */\n@ApiTags('Console')\n@ApiBearerAuth()\n@Controller('accessi/console')\nexport class ConsoleEntryController {\n constructor(@Inject('ACCESSI_OPTIONS') private readonly options: AccessiOptions) {}\n\n private get store(): ConsoleEntryStore {\n return this.options.consoleEntry?.store ?? getDefaultConsoleEntryStore();\n }\n\n private get ttlMs(): number {\n return this.options.consoleEntry?.ttlMs ?? 60_000;\n }\n\n @ApiOperation({\n summary: 'Emetti un ticket di ingresso alla console',\n operationId: 'createConsoleEntryTicket',\n description: 'Riservato agli utenti abilitati alla console (FLGSUPER/FLGADMIN). Restituisce un ticket monouso legato all utente, valido pochi secondi.',\n })\n @ApiOkResponse({ type: ConsoleEntryTicketResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Token Accessi mancante o non valido.' })\n @ApiResponse({ status: 403, type: ErrorResponse, description: 'Utente non abilitato alla console.' })\n @UseGuards(JwtSimpleGuard)\n @Post('entry')\n async createEntryTicket(@Req() request: Request, @Res() res: Response) {\n try {\n const user = getAuthenticatedAccessiUser(request);\n ensureConsoleAccess(user);\n\n const tokenValue = extractAccessiBearerToken(request.headers['authorization']);\n if (!tokenValue) {\n throw new UnauthorizedException({ code: 'ACCESSI_CONSOLE_ENTRY_TOKEN_MISSING', message: 'Token Accessi mancante.' });\n }\n\n const issued = await this.store.issue(\n { token: tokenValue, codiceUtente: user.codiceUtente },\n this.ttlMs,\n );\n return RestUtilities.sendBaseResponse(res, issued);\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n ConsoleEntryController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.UNAUTHORIZED,\n );\n }\n }\n\n @ApiOperation({\n summary: 'Scambia il ticket con la sessione Accessi',\n operationId: 'exchangeConsoleEntryTicket',\n description: 'Endpoint pubblico (il ticket e l unica credenziale) protetto da rate limit; il ticket e monouso e scade in pochi secondi.',\n })\n @ApiBody({ type: ConsoleEntryExchangeRequest })\n @ApiOkResponse({ type: ConsoleEntrySessionResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Ticket non valido o scaduto.' })\n @ApiResponse({ status: 429, type: ErrorResponse, description: 'Troppi tentativi.' })\n @Post('entry/exchange')\n async exchangeEntryTicket(\n @Req() request: Request,\n @Body() body: ConsoleEntryExchangeRequest,\n @Res() res: Response,\n ) {\n try {\n const decision = await checkPublicAuthRateLimit(this.options, 'consoleEntry', request, [body?.ticket ?? '']);\n if (!decision.allowed) {\n return sendPublicAuthRateLimitExceeded(res, decision.retryAfterSeconds);\n }\n\n const entry = await this.store.consume(body?.ticket);\n if (!entry) {\n throw new UnauthorizedException({\n code: 'ACCESSI_CONSOLE_ENTRY_INVALID',\n message: 'Ticket di ingresso console non valido o scaduto. Riapri la console dal frontend.',\n });\n }\n\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n if (cookieConfig) {\n setAccessiAuthCookies(res, cookieConfig, { access: entry.token });\n if (!cookieConfig.exposeTokens) {\n return RestUtilities.sendBaseResponse(res, {});\n }\n }\n return RestUtilities.sendBaseResponse(res, { token: { value: entry.token, type: 'Bearer' } });\n } catch (error) {\n return RestUtilities.sendErrorMessage(\n res,\n error,\n ConsoleEntryController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.UNAUTHORIZED,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ConsoleEntryController.js","sourceRoot":"","sources":["../../../src/accessi-module/Controllers/ConsoleEntryController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Body,\n Controller,\n HttpException,\n HttpStatus,\n Inject,\n Post,\n Req,\n Res,\n UnauthorizedException,\n UseGuards,\n} from '@nestjs/common';\nimport {\n ApiBearerAuth,\n ApiBody,\n ApiOkResponse,\n ApiOperation,\n ApiResponse,\n ApiTags,\n} from '@nestjs/swagger';\nimport { Request, Response } from 'express';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { ConsoleEntryExchangeRequest, ConsoleEntrySessionResponse, ConsoleEntryTicketResponse } from '../Dtos/ConsoleEntryDtos';\nimport { ErrorResponse } from '../Dtos/BaseResponse';\nimport { JwtSimpleGuard } from '../jwt/jwt.strategy';\nimport { ensureConsoleAccess, getAuthenticatedAccessiUser } from '../security/accessControl';\nimport { extractAccessiBearerToken } from '../security/authenticatedToken';\nimport { getDefaultConsoleEntryStore } from '../security/consoleEntry';\nimport type { ConsoleEntryStore } from '../security/consoleEntry';\nimport {\n checkPublicAuthRateLimit,\n sendPublicAuthRateLimitExceeded,\n} from '../security/publicAuthRateLimit';\nimport {\n resolveAccessiAuthCookieOptions,\n setAccessiAuthCookies,\n} from '../security/authCookies';\nimport { countAccessiMetric } from '../observability/metrics';\n\n/**\n * Auto-ingresso alla console amministrativa da un frontend gia autenticato.\n * Il frontend scambia la propria sessione Accessi con un ticket monouso, poi apre\n * `/api/accessi/console#entry=<ticket>`: il JWT non passa mai nell'URL.\n */\n@ApiTags('Console')\n@ApiBearerAuth()\n@Controller('accessi/console')\nexport class ConsoleEntryController {\n constructor(@Inject('ACCESSI_OPTIONS') private readonly options: AccessiOptions) {}\n\n private get store(): ConsoleEntryStore {\n return this.options.consoleEntry?.store ?? getDefaultConsoleEntryStore();\n }\n\n private get ttlMs(): number {\n return this.options.consoleEntry?.ttlMs ?? 60_000;\n }\n\n @ApiOperation({\n summary: 'Emetti un ticket di ingresso alla console',\n operationId: 'createConsoleEntryTicket',\n description: 'Riservato agli utenti abilitati alla console (FLGSUPER/FLGADMIN). Restituisce un ticket monouso legato all utente, valido pochi secondi.',\n })\n @ApiOkResponse({ type: ConsoleEntryTicketResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Token Accessi mancante o non valido.' })\n @ApiResponse({ status: 403, type: ErrorResponse, description: 'Utente non abilitato alla console.' })\n @UseGuards(JwtSimpleGuard)\n @Post('entry')\n async createEntryTicket(@Req() request: Request, @Res() res: Response) {\n try {\n const user = getAuthenticatedAccessiUser(request);\n ensureConsoleAccess(user);\n\n const tokenValue = extractAccessiBearerToken(request.headers['authorization']);\n if (!tokenValue) {\n throw new UnauthorizedException({ code: 'ACCESSI_CONSOLE_ENTRY_TOKEN_MISSING', message: 'Token Accessi mancante.' });\n }\n\n const issued = await this.store.issue(\n { token: tokenValue, codiceUtente: user.codiceUtente },\n this.ttlMs,\n );\n countAccessiMetric(this.options, 'console_ticket_total', { action: 'create', result: 'issued' });\n return RestUtilities.sendBaseResponse(res, issued);\n } catch (error) {\n countAccessiMetric(this.options, 'console_ticket_total', { action: 'create', result: 'error' });\n return RestUtilities.sendErrorMessage(\n res,\n error,\n ConsoleEntryController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.UNAUTHORIZED,\n );\n }\n }\n\n @ApiOperation({\n summary: 'Scambia il ticket con la sessione Accessi',\n operationId: 'exchangeConsoleEntryTicket',\n description: 'Endpoint pubblico (il ticket e l unica credenziale) protetto da rate limit; il ticket e monouso e scade in pochi secondi.',\n })\n @ApiBody({ type: ConsoleEntryExchangeRequest })\n @ApiOkResponse({ type: ConsoleEntrySessionResponse })\n @ApiResponse({ status: 401, type: ErrorResponse, description: 'Ticket non valido o scaduto.' })\n @ApiResponse({ status: 429, type: ErrorResponse, description: 'Troppi tentativi.' })\n @Post('entry/exchange')\n async exchangeEntryTicket(\n @Req() request: Request,\n @Body() body: ConsoleEntryExchangeRequest,\n @Res() res: Response,\n ) {\n try {\n const decision = await checkPublicAuthRateLimit(this.options, 'consoleEntry', request, [body?.ticket ?? '']);\n if (!decision.allowed) {\n countAccessiMetric(this.options, 'console_ticket_total', { action: 'exchange', result: 'rate_limited' });\n return sendPublicAuthRateLimitExceeded(res, decision.retryAfterSeconds);\n }\n\n const entry = await this.store.consume(body?.ticket);\n if (!entry) {\n throw new UnauthorizedException({\n code: 'ACCESSI_CONSOLE_ENTRY_INVALID',\n message: 'Ticket di ingresso console non valido o scaduto. Riapri la console dal frontend.',\n });\n }\n\n countAccessiMetric(this.options, 'console_ticket_total', { action: 'exchange', result: 'consumed' });\n const cookieConfig = resolveAccessiAuthCookieOptions(this.options);\n if (cookieConfig) {\n setAccessiAuthCookies(res, cookieConfig, { access: entry.token });\n if (!cookieConfig.exposeTokens) {\n return RestUtilities.sendBaseResponse(res, {});\n }\n }\n return RestUtilities.sendBaseResponse(res, { token: { value: entry.token, type: 'Bearer' } });\n } catch (error) {\n countAccessiMetric(this.options, 'console_ticket_total', {\n action: 'exchange',\n result: error instanceof UnauthorizedException ? 'invalid' : 'error',\n });\n return RestUtilities.sendErrorMessage(\n res,\n error,\n ConsoleEntryController.name,\n error instanceof HttpException ? error.getStatus() : HttpStatus.UNAUTHORIZED,\n );\n }\n }\n}\n"]}
@@ -62,6 +62,7 @@ const TwoFactorService_1 = require("../TwoFactorService/TwoFactorService");
62
62
  const jwt = __importStar(require("jsonwebtoken"));
63
63
  const Orm_1 = require("../../../Orm");
64
64
  const Utilities_1 = require("../../../Utilities");
65
+ const metrics_1 = require("../../observability/metrics");
65
66
  const StatoRegistrazione_1 = require("../../Dtos/StatoRegistrazione");
66
67
  const UserService_1 = require("../UserService/UserService");
67
68
  const FiltriService_1 = require("../FiltriService/FiltriService");
@@ -435,7 +436,7 @@ let AuthService = AuthService_1 = class AuthService {
435
436
  */
436
437
  handleRefreshTokenReuse(params) {
437
438
  return __awaiter(this, void 0, void 0, function* () {
438
- var _a, _b, _c;
439
+ var _a, _b, _c, _d;
439
440
  const configuredGrace = Number((_b = (_a = this.accessiOptions.refreshTokenRotation) === null || _a === void 0 ? void 0 : _a.reuseGraceMs) !== null && _b !== void 0 ? _b : 10000);
440
441
  const graceMs = Number.isFinite(configuredGrace) ? Math.max(0, configuredGrace) : 10000;
441
442
  const consumedAtMs = params.consumedAtMs;
@@ -451,15 +452,20 @@ let AuthService = AuthService_1 = class AuthService {
451
452
  familyId: params.familyId,
452
453
  consumedAtMs,
453
454
  });
455
+ (0, metrics_1.countAccessiMetric)(this.accessiOptions, 'refresh_reuse_total', {
456
+ user_sessions_revoked: ((_c = this.accessiOptions.refreshTokenRotation) === null || _c === void 0 ? void 0 : _c.revokeUserSessionsOnReuse) === true,
457
+ });
454
458
  try {
455
459
  if (params.familyId) {
456
460
  yield (0, refreshTokenRotation_1.revokeRefreshTokenFamily)(this.accessiOptions, params.familyId, params.expiresAtMs);
461
+ (0, metrics_1.countAccessiMetric)(this.accessiOptions, 'refresh_family_revoked_total', { reason: 'reuse' });
457
462
  }
458
- if (((_c = this.accessiOptions.refreshTokenRotation) === null || _c === void 0 ? void 0 : _c.revokeUserSessionsOnReuse) === true) {
463
+ if (((_d = this.accessiOptions.refreshTokenRotation) === null || _d === void 0 ? void 0 : _d.revokeUserSessionsOnReuse) === true) {
459
464
  yield (0, sessionRevocation_1.revokeAccessiUserSessions)(this.accessiOptions, params.codiceUtente, Date.now(), 'refresh_token_reuse');
460
465
  }
461
466
  }
462
467
  catch (error) {
468
+ (0, metrics_1.recordAccessiMetric)('accessi_store_errors_total', 1, { store: 'refresh_token_rotation' });
463
469
  // La revoca e best effort: il token presentato resta comunque rifiutato.
464
470
  this.logger.error(`Revoca famiglia refresh token fallita: ${error instanceof Error ? error.message : String(error)}`);
465
471
  }