emilsoftware-utilities 2.0.0-dev.73 → 2.0.0-dev.75

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 (45) hide show
  1. package/README.MD +2 -0
  2. package/dist/accessi/resource-server/token.js +62 -18
  3. package/dist/accessi/resource-server/token.js.map +1 -1
  4. package/dist/accessi/resource-server/types.d.ts +22 -0
  5. package/dist/accessi/resource-server/types.js.map +1 -1
  6. package/dist/accessi/server/index.d.ts +1 -1
  7. package/dist/accessi/server/index.js +2 -1
  8. package/dist/accessi/server/index.js.map +1 -1
  9. package/dist/accessi/server/standalone.d.ts +2 -4
  10. package/dist/accessi/server/standalone.js +4 -79
  11. package/dist/accessi/server/standalone.js.map +1 -1
  12. package/dist/accessi-module/AccessiModule.d.ts +12 -3
  13. package/dist/accessi-module/AccessiModule.js.map +1 -1
  14. package/dist/accessi-module/Console/console.js +2 -1
  15. package/dist/accessi-module/Console/wiki.js +2 -1
  16. package/dist/accessi-module/Console/wiki.js.map +1 -1
  17. package/dist/accessi-module/Services/AuthService/AuthService.js +2 -2
  18. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  19. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.d.ts +9 -1
  20. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js +53 -1
  21. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js.map +1 -1
  22. package/dist/accessi-module/health/nest.d.ts +31 -0
  23. package/dist/accessi-module/health/nest.js +89 -0
  24. package/dist/accessi-module/health/nest.js.map +1 -0
  25. package/dist/accessi-module/health/readiness.d.ts +53 -0
  26. package/dist/accessi-module/health/readiness.js +110 -0
  27. package/dist/accessi-module/health/readiness.js.map +1 -0
  28. package/dist/accessi-module/index.d.ts +6 -0
  29. package/dist/accessi-module/index.js +16 -1
  30. package/dist/accessi-module/index.js.map +1 -1
  31. package/dist/accessi-module/jwt/jwt.strategy.js +1 -35
  32. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  33. package/dist/accessi-module/middleware/authenticateGen.js +1 -35
  34. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  35. package/dist/accessi-module/security/jwtTokenOptions.d.ts +44 -9
  36. package/dist/accessi-module/security/jwtTokenOptions.js +118 -7
  37. package/dist/accessi-module/security/jwtTokenOptions.js.map +1 -1
  38. package/dist/accessi-module/security/validateOptions.js +31 -4
  39. package/dist/accessi-module/security/validateOptions.js.map +1 -1
  40. package/dist/emilsoftware-utilities-2.0.0-dev.75.tgz +0 -0
  41. package/docs/jwt-key-rotation.md +143 -0
  42. package/docs/proxy-ip.md +99 -0
  43. package/docs/standalone-service.md +25 -0
  44. package/package.json +5 -3
  45. package/dist/emilsoftware-utilities-2.0.0-dev.73.tgz +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/AuthService/AuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, ServiceUnavailableException, UnauthorizedException } from \"@nestjs/common\";\nimport { randomUUID } from \"crypto\";\nimport { TwoFactorService, TwoFactorProof } from '../TwoFactorService/TwoFactorService';\nimport * as jwt from \"jsonwebtoken\";\nimport { Orm } from \"../../../Orm\";\nimport { CryptUtilities, PasswordUtilities, RestUtilities } from \"../../../Utilities\";\nimport type { AccessiOptions } from \"../../AccessiModule\";\nimport { LoginRequest } from \"../../Dtos/LoginRequest\";\nimport { LoginResult } from \"../../Dtos/LoginResponse\";\nimport { StatoRegistrazione } from \"../../Dtos/StatoRegistrazione\";\nimport { UserService } from \"../UserService/UserService\";\nimport { FiltriService } from \"../FiltriService/FiltriService\";\nimport {\n buildAuthenticatedTokenPayload,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../../security/authenticatedToken\";\nimport {\n getAccessiJwtSecret,\n verifyPasswordResetToken,\n} from \"../../security/passwordResetToken\";\nimport {\n isAccessiTokenRevoked,\n revokeAccessiUserSessions,\n revokeAccessiUserSessionsIfConfigured,\n} from \"../../security/sessionRevocation\";\nimport {\n consumeRefreshToken,\n getRefreshTokenRotationStore,\n isRefreshTokenFamilyRevoked,\n revokeRefreshTokenFamily,\n} from \"../../security/refreshTokenRotation\";\nimport { auditAccessi } from \"../../security/audit\";\nimport {\n getAccessiAccessTokenSigningConfig,\n getAccessiAccessTokenVerificationConfig,\n getAccessiRefreshTokenSigningConfig,\n getAccessiRefreshTokenVerificationConfig,\n} from \"../../security/jwtTokenOptions\";\nimport { assertStrongPassword } from '../../security/passwordPolicy';\nimport { Logger } from \"../../../Logger\";\nimport { TokenResult } from '../../Dtos/TokenResult';\n\n/** Error code deliberately returned when a user is configured as SSO-only. */\nexport const PASSWORD_LOGIN_DISABLED = 'PASSWORD_LOGIN_DISABLED';\n\n/** Esito di una verifica token usata dall'endpoint di introspection. */\nexport interface AccessiTokenIntrospectionResult {\n active: boolean;\n codiceUtente?: number;\n payload?: Record<string, unknown>;\n}\n\ninterface AccessiTokenIssueOptions {\n /** Sovrascrive jwtOptions.expiresIn per token a durata ridotta (es. Login as). */\n expiresIn?: string | number;\n /** Claim aggiuntive, per esempio l'attore che ha generato un token di impersonazione. */\n extraClaims?: Record<string, unknown>;\n}\n\n@Injectable()\nexport class AuthService {\n private readonly logger = new Logger(AuthService.name);\n\n constructor(\n private userService: UserService,\n private filtriService: FiltriService,\n @Inject(\"ACCESSI_OPTIONS\") private readonly accessiOptions: AccessiOptions,\n private readonly twoFactorService: TwoFactorService,\n ) {}\n\n private async refreshPasswordExpiration(codiceUtente: number): Promise<void> {\n if (!this.accessiOptions.passwordExpiration) {\n return;\n }\n\n const configuredDays = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays =\n Number.isFinite(configuredDays) && configuredDays > 0\n ? Math.trunc(configuredDays)\n : 90;\n\n const query = `UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n }\n\n private isMockDemoUserEnabled(): boolean {\n if (!this.accessiOptions.mockDemoUser) {\n return false;\n }\n\n // La backdoor mock non e mai attiva in produzione, nemmeno con variabili d'ambiente,\n // perche emette un superutente senza verifica password.\n const nodeEnv = (process.env.NODE_ENV ?? \"production\").toLowerCase();\n return nodeEnv !== \"production\";\n }\n\n private createToken(\n utente: LoginResult['utente'],\n methods: string[],\n type: 'access' | 'refresh',\n tokenOptions: AccessiTokenIssueOptions = {},\n ): TokenResult {\n if (!utente?.codiceUtente) {\n throw new Error('Impossibile creare un token senza un utente Accessi valido.');\n }\n const loginAs = methods.includes('login_as');\n if ((utente.flagDueFattori === true || Number(utente.flagDueFattori) === 1) && !methods.includes('otp') && !loginAs) {\n throw new UnauthorizedException('Verifica del codice di accesso richiesta.');\n }\n\n const expiresIn = tokenOptions.expiresIn ?? this.accessiOptions.jwtOptions.expiresIn;\n const expiresInIsValid = typeof expiresIn === 'number'\n ? Number.isFinite(expiresIn) && expiresIn > 0\n : typeof expiresIn === 'string' && expiresIn.trim() !== '';\n if (!expiresInIsValid) {\n throw new Error('Durata token non configurata: impossibile emettere token senza scadenza.');\n }\n\n const signing = type === 'refresh'\n ? getAccessiRefreshTokenSigningConfig(this.accessiOptions)\n : getAccessiAccessTokenSigningConfig(this.accessiOptions);\n const token = jwt.sign(\n {\n ...(tokenOptions.extraClaims ?? {}),\n utente,\n typ: type,\n amr: methods,\n jti: randomUUID(),\n // Millisecondi: rende deterministica la revoca sessioni anche quando\n // il token e emesso nello stesso secondo del cambio password.\n iatMs: Date.now(),\n },\n signing.key,\n {\n expiresIn: expiresIn as jwt.SignOptions['expiresIn'],\n algorithm: signing.algorithm,\n ...signing.signOptions,\n },\n );\n\n // Difesa in profondita: un `expiresIn` malformato farebbe emettere un token permanente.\n const decoded = jwt.decode(token);\n const decodedPayload = decoded && typeof decoded === 'object' ? decoded as jwt.JwtPayload : undefined;\n if (typeof decodedPayload?.exp !== 'number') {\n throw new Error('Token emesso senza scadenza: configurazione JWT non valida.');\n }\n\n // Il contratto TokenResult espone sempre la validita in secondi, anche quando\n // jwtOptions.expiresIn usa un formato leggibile come '24h'.\n const issuedAt = typeof decodedPayload.iat === 'number' ? decodedPayload.iat : Math.floor(Date.now() / 1000);\n const expiresInSeconds = Math.max(0, Math.trunc(decodedPayload.exp - issuedAt));\n\n return {\n expiresIn: String(expiresInSeconds),\n value: token,\n type: 'Bearer',\n };\n }\n\n /** Creates the normal internal JWT consumed by all existing Accessi guards. */\n public createAccessiToken(\n utente: LoginResult['utente'],\n methods: string[] = [],\n tokenOptions: AccessiTokenIssueOptions = {},\n ): TokenResult {\n return this.createToken(utente, methods, 'access', tokenOptions);\n }\n\n /** Emette il refresh token quando `jwtOptions.refreshExpiresIn` e configurato. */\n public createRefreshToken(\n utente: LoginResult['utente'],\n methods: string[] = [],\n tokenOptions: AccessiTokenIssueOptions = {},\n ): TokenResult | undefined {\n const expiresIn = this.accessiOptions.jwtOptions.refreshExpiresIn;\n if (!expiresIn) return undefined;\n return this.createToken(utente, methods, 'refresh', {\n ...tokenOptions,\n expiresIn,\n });\n }\n\n /** Crea la coppia access + refresh token usata da login, 2FA e SSO. */\n public createTokenPair(\n utente: LoginResult['utente'],\n methods: string[] = [],\n options?: { familyId?: string },\n ): { access: TokenResult; refresh?: TokenResult } {\n // La famiglia identifica il login: access e refresh condividono lo stesso\n // `fid`, cosi la revoca per riuso sospetto invalida entrambi.\n const familyId = options?.familyId ?? randomUUID();\n const access = this.createAccessiToken(utente, methods, { extraClaims: { fid: familyId } });\n const refresh = this.createRefreshToken(utente, methods, { extraClaims: { fid: familyId } });\n return { access, ...(refresh ? { refresh } : {}) };\n }\n\n /**\n * Emette l'access token per l'utente target, con l'attore registrato nelle\n * claim `act` e `loginAs`. La durata e' quella standard di jwtOptions.expiresIn.\n */\n public createLoginAsToken(\n utente: LoginResult['utente'],\n actor: { codiceUtente: number; email?: string },\n ): TokenResult {\n return this.createAccessiToken(utente, ['login_as'], {\n extraClaims: {\n loginAs: true,\n act: {\n sub: String(actor.codiceUtente),\n email: actor.email,\n },\n },\n });\n }\n\n /** Builds the standard login response for a user authenticated by a supported method. */\n public async getLoginResultForUser(codiceUtente: number, scope?: string): Promise<LoginResult> {\n const users = await this.userService.getUsers(\n { codiceUtente },\n { includeExtensionFields: true, includeGrants: true, ...(scope ? { scope } : {}) },\n );\n const result = users[0];\n if (!result?.utente) {\n throw new Error('Utente Accessi non trovato.');\n }\n const current = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(current)) throw new UnauthorizedException('Utente non abilitato.');\n result.utente = { ...result.utente, ...current };\n\n return {\n utente: result.utente,\n filtri: await this.filtriService.getFiltriUser(codiceUtente),\n userGrants: result.userGrants,\n extensionFields: result.extensionFields,\n };\n }\n\n /** Users without a row retain the historic password-login enabled default. */\n private async isPasswordLoginEnabled(codiceUtente: number): Promise<boolean> {\n if (this.accessiOptions.federatedAuthentication?.enabled !== true) return true;\n\n const rows = await Orm.query(\n this.accessiOptions.databaseOptions,\n 'SELECT COALESCE(FLGPASSWORD, 1) AS password_login_enabled FROM UTENTI_CONFIG WHERE CODUTE = ?',\n [codiceUtente],\n );\n const policy = rows.map(RestUtilities.convertKeysToCamelCase)[0] as { passwordLoginEnabled?: unknown } | undefined;\n return policy?.passwordLoginEnabled !== false && policy?.passwordLoginEnabled !== 0 && policy?.passwordLoginEnabled !== '0';\n }\n\n /**\n * Autentica con credenziali locali e restituisce profilo, filtri e grant effettivi.\n * Non crea il JWT: il controller o il flusso SSO deve chiamare `createAccessiToken` sul risultato.\n * Per utenti SSO-only genera `PASSWORD_LOGIN_DISABLED`, da trattare come istruzione a usare l'SSO.\n */\n async login(request: LoginRequest): Promise<LoginResult> {\n const mockDemoUserEnabled = this.isMockDemoUserEnabled();\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"demo\"\n ) {\n return this.getDemoUser();\n }\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"admin\"\n ) {\n return this.getAdminUser();\n }\n\n const utente = await this.userService.getUserByEmail(\n request.email.trim().toLowerCase()\n );\n if (!utente) {\n if (!request.password) return { passwordRequired: true };\n throw new Error(\"Nome utente o password errata!\");\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(utente.codiceUtente);\n if (isAuthenticatedUserEnabledForJwt(currentUser) && currentUser.flagDueFattori && currentUser.passwordlessLoginEnabled) {\n return { challenge: await this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: (currentUser.email ?? '').trim(), mode: 'passwordless' }) };\n }\n // The email-only step has the same response for unknown and ordinary local accounts.\n if (!request.password) return { passwordRequired: true };\n\n switch (utente.statoRegistrazione) {\n case undefined:\n throw new Error(\n \"Struttura dati compromessa: Stato Registrazione inesistente.\"\n );\n case StatoRegistrazione.BLOCC:\n case StatoRegistrazione.DELETE:\n throw new Error(\"Utente non abilitato\");\n case StatoRegistrazione.INVIO:\n throw new Error(\"Rinnovo password necessario.\");\n }\n\n if (utente.statoRegistrazione !== StatoRegistrazione.CONF) {\n throw new Error(\n `Errore generico. Stato di registrazione non valido: ${utente.statoRegistrazione}.`\n );\n }\n\n if (!isAuthenticatedUserEnabledForJwt(currentUser)) throw new Error('Utente non abilitato');\n if (!(await this.isPasswordLoginEnabled(utente.codiceUtente))) {\n throw new Error(PASSWORD_LOGIN_DISABLED);\n }\n\n if (typeof request.password !== 'string' || request.password.length === 0) {\n throw new Error('Nome utente o password errata!');\n }\n\n const isPasswordValid = await this.verifyPassword(\n utente.codiceUtente,\n request.password\n );\n if (!isPasswordValid) throw new Error(\"Nome utente o password errata!\");\n\n if (\n this.accessiOptions.passwordExpiration &&\n this.accessiOptions.passwordExpiration == true\n ) {\n const today = new Date();\n const targetDate = utente.dataScadenzaPassword\n ? new Date(utente.dataScadenzaPassword)\n : undefined;\n\n // Legacy users may not have an expiration date. Preserve the former non-expiring behaviour for them.\n if (targetDate && !Number.isNaN(targetDate.getTime()) && today >= targetDate) {\n throw new Error(\"PASSWORD_EXPIRED\");\n }\n }\n\n if (currentUser.flagDueFattori) {\n return { challenge: await this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: currentUser.email ?? '', mode: 'password' }) };\n }\n\n const updateLastAccessDateQuery =\n \"UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?\";\n await Orm.query(\n this.accessiOptions.databaseOptions,\n updateLastAccessDateQuery,\n [utente.codiceUtente]\n );\n\n return this.getLoginResultForUser(utente.codiceUtente, request.scope);\n }\n\n /**\n * Verifica un access token Accessi senza sollevare eccezioni per token invalidi.\n *\n * Gli errori di configurazione o database continuano a propagarsi: un problema\n * infrastrutturale non deve essere confuso con un token scaduto.\n */\n public async introspectAccessToken(token: string): Promise<AccessiTokenIntrospectionResult> {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n return { active: false };\n }\n\n const verification = getAccessiAccessTokenVerificationConfig(this.accessiOptions);\n let decoded: unknown;\n try {\n decoded = jwt.verify(token.trim(), verification.key, verification.verifyOptions);\n } catch {\n return { active: false };\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n if (!codiceUtente) {\n return { active: false };\n }\n if (await isAccessiTokenRevoked(this.accessiOptions, decoded as Record<string, unknown>, codiceUtente)) {\n return { active: false };\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (\n !currentUser ||\n !isAuthenticatedUserEnabledForJwt(currentUser) ||\n !isAccessiTokenAllowedForUser(decoded, currentUser)\n ) {\n return { active: false };\n }\n\n return {\n active: true,\n codiceUtente,\n payload: buildAuthenticatedTokenPayload(decoded, currentUser),\n };\n }\n\n /**\n * Verifica un JWT Accessi e ricostruisce il profilo corrente dal database.\n * Questo evita che privilegi, stato utente o flag amministrativi presenti in un token vecchio restino validi.\n */\n public async getAuthenticatedTokenPayload(token: string): Promise<Record<string, unknown>> {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non fornito.\");\n }\n\n const introspection = await this.introspectAccessToken(token);\n if (!introspection.active || !introspection.payload) {\n throw new Error(\"Token non valido o utente non autorizzato.\");\n }\n\n return introspection.payload;\n }\n\n /**\n * Scambia un refresh token valido con una nuova coppia access + refresh.\n *\n * Il refresh token non e accettato dai guard API: ha `typ: \"refresh\"`.\n */\n public async refreshAccessToken(refreshToken: string): Promise<LoginResult> {\n if (!this.accessiOptions.jwtOptions.refreshExpiresIn) {\n throw new UnauthorizedException('Refresh token non abilitato.');\n }\n if (typeof refreshToken !== 'string' || refreshToken.trim() === '') {\n throw new UnauthorizedException('Refresh token mancante.');\n }\n\n const verification = getAccessiRefreshTokenVerificationConfig(this.accessiOptions);\n let decoded: unknown;\n try {\n decoded = jwt.verify(refreshToken.trim(), verification.key, verification.verifyOptions);\n } catch {\n throw new UnauthorizedException('Refresh token non valido o scaduto.');\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded, 'refresh');\n if (!codiceUtente) {\n throw new UnauthorizedException('Refresh token privo di un utente valido.');\n }\n\n const decodedRecord = decoded as { jti?: unknown; fid?: unknown; exp?: unknown };\n const familyId = typeof decodedRecord.fid === 'string' && decodedRecord.fid.trim() !== ''\n ? decodedRecord.fid\n : undefined;\n const jti = typeof decodedRecord.jti === 'string' ? decodedRecord.jti : undefined;\n const expiresAt = Number(decodedRecord.exp);\n\n // La famiglia va controllata per prima: un token appena emesso da uno store\n // compromesso deve produrre un codice stabile, non il generico 401 utente.\n if (await isRefreshTokenFamilyRevoked(this.accessiOptions, familyId)) {\n throw new UnauthorizedException({\n code: 'ACCESSI_REFRESH_FAMILY_REVOKED',\n message: 'Sessione revocata per riuso sospetto del refresh token.',\n });\n }\n\n if (await isAccessiTokenRevoked(this.accessiOptions, decoded as Record<string, unknown>, codiceUtente)) {\n throw new UnauthorizedException('Sessione revocata.');\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw new UnauthorizedException('Utente non piu autorizzato.');\n }\n\n const rotationStore = getRefreshTokenRotationStore(this.accessiOptions);\n if (rotationStore) {\n if (!jti || !Number.isFinite(expiresAt)) {\n throw new UnauthorizedException('Refresh token privo di jti o scadenza.');\n }\n let outcome;\n try {\n outcome = await consumeRefreshToken(this.accessiOptions, jti, expiresAt * 1000);\n } catch {\n throw new ServiceUnavailableException({\n code: 'ACCESSI_REFRESH_ROTATION_UNAVAILABLE',\n message: 'Rotazione refresh token non disponibile. Riprova piu tardi.',\n });\n }\n if (outcome && !outcome.consumed) {\n await this.handleRefreshTokenReuse({\n codiceUtente,\n jti,\n familyId,\n consumedAtMs: outcome.consumedAtMs,\n expiresAtMs: expiresAt * 1000,\n });\n throw new UnauthorizedException({\n code: 'ACCESSI_REFRESH_TOKEN_REUSE',\n message: 'Refresh token gia utilizzato.',\n });\n }\n }\n\n const login = await this.getLoginResultForUser(codiceUtente);\n const methods = Array.isArray((decoded as { amr?: unknown }).amr)\n ? ((decoded as { amr: unknown[] }).amr.filter((method): method is string => typeof method === 'string'))\n : [];\n const pair = this.createTokenPair(login.utente, methods, { familyId });\n login.token = pair.access;\n if (pair.refresh) login.refreshToken = pair.refresh;\n return login;\n }\n\n /**\n * Gestisce il riuso di un refresh token gia consumato.\n *\n * Il riuso entro `reuseGraceMs` e trattato come retry concorrente del client e\n * non revoca nulla. Oltre la finestra e considerato un possibile furto: viene\n * revocata l'intera famiglia (stesso login) e, solo se esplicitamente\n * configurato, anche le altre sessioni dell'utente.\n */\n private async handleRefreshTokenReuse(params: {\n codiceUtente: number;\n jti: string;\n familyId?: string;\n consumedAtMs?: number;\n expiresAtMs: number;\n }): Promise<void> {\n const configuredGrace = Number(this.accessiOptions.refreshTokenRotation?.reuseGraceMs ?? 10_000);\n const graceMs = Number.isFinite(configuredGrace) ? Math.max(0, configuredGrace) : 10_000;\n const consumedAtMs = params.consumedAtMs;\n if (\n graceMs > 0\n && consumedAtMs !== undefined\n && Number.isFinite(consumedAtMs)\n && Date.now() - consumedAtMs <= graceMs\n ) {\n return;\n }\n\n auditAccessi('accessi_refresh_token_reuse', {\n codiceUtente: params.codiceUtente,\n jti: params.jti,\n familyId: params.familyId,\n consumedAtMs,\n });\n\n try {\n if (params.familyId) {\n await revokeRefreshTokenFamily(\n this.accessiOptions,\n params.familyId,\n params.expiresAtMs,\n );\n }\n if (this.accessiOptions.refreshTokenRotation?.revokeUserSessionsOnReuse === true) {\n await revokeAccessiUserSessions(this.accessiOptions, params.codiceUtente, Date.now(), 'refresh_token_reuse');\n }\n } catch (error) {\n // La revoca e best effort: il token presentato resta comunque rifiutato.\n this.logger.error(\n `Revoca famiglia refresh token fallita: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /** Starts a second-factor challenge after the hosting backend has verified an SSO identity. */\n public async beginFederatedTwoFactor(codiceUtente: number, identityKey: string): Promise<LoginResult> {\n const user = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(user) || !user.flagDueFattori) throw new UnauthorizedException();\n return { challenge: await this.twoFactorService.issue({ codiceUtente, email: user.email ?? '', mode: 'federated', identityKey }) };\n }\n\n private async validateTwoFactorProof(proof: TwoFactorProof): Promise<void> {\n const user = await this.userService.getAuthenticatedUserSnapshot(proof.codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(user) || !user.flagDueFattori || user.email?.trim().toLowerCase() !== proof.email.trim().toLowerCase()) {\n throw new UnauthorizedException('Profilo modificato o utente non abilitato. Ripeti l accesso.');\n }\n if (proof.mode === 'passwordless' && !user.passwordlessLoginEnabled) throw new UnauthorizedException('Accesso senza password disabilitato.');\n if (proof.mode === 'password' && !(await this.isPasswordLoginEnabled(proof.codiceUtente))) throw new UnauthorizedException('Login locale disabilitato.');\n if (proof.mode === 'federated') {\n if (!this.accessiOptions.federatedAuthentication?.enabled) throw new UnauthorizedException();\n const rows = await Orm.query(this.accessiOptions.databaseOptions,\n 'SELECT I.IDNKEY FROM UTENTI_IDENTITA_EXT I INNER JOIN SSO_PROVIDER P ON P.PROVIDER = I.PROVIDER WHERE I.IDNKEY = ? AND I.CODUTE = ? AND I.FLGATTIVO = 1 AND P.FLGATTIVO = 1',\n [proof.identityKey, proof.codiceUtente], false);\n if (!rows.length) throw new UnauthorizedException('Identita SSO non piu abilitata.');\n }\n }\n\n public async verifyTwoFactor(challengeId: string, code: string, scope?: string): Promise<LoginResult> {\n const proof = await this.twoFactorService.consume(challengeId, code);\n await this.validateTwoFactorProof(proof);\n const result = await this.getLoginResultForUser(proof.codiceUtente, scope);\n const tokens = this.createTokenPair(result.utente, [proof.mode, 'otp']);\n result.token = tokens.access;\n if (tokens.refresh) result.refreshToken = tokens.refresh;\n await Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?', [proof.codiceUtente]);\n if (proof.mode === 'federated') {\n await Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI_IDENTITA_EXT SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE IDNKEY = ?', [proof.identityKey]);\n }\n return result;\n }\n\n public async resendTwoFactor(challengeId: string): Promise<LoginResult> {\n await this.validateTwoFactorProof(await this.twoFactorService.describe(challengeId));\n return { challenge: await this.twoFactorService.resend(challengeId) };\n }\n\n /**\n * Persiste una password hashata e aggiorna la scadenza, se la policy password e attiva. Non invia email.\n * Con `enforcePolicy` (default true) valida la password secondo la policy moderna; i flussi di\n * migrazione delle password legacy passano `enforcePolicy: false` per non bloccare password storiche.\n * Con `revokeSessions` (default true) invalida le sessioni precedenti: un cambio password deve\n * interrompere i token gia emessi.\n */\n public async setPassword(\n codiceUtente: number,\n nuovaPassword: string,\n options?: { enforcePolicy?: boolean; revokeSessions?: boolean },\n ) {\n if (options?.enforcePolicy !== false) {\n assertStrongPassword(nuovaPassword);\n }\n try {\n const query = `UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?)`;\n const hashedPassword = PasswordUtilities.hashPassword(nuovaPassword);\n\n const result = await Orm.execute(this.accessiOptions.databaseOptions, query, [\n codiceUtente,\n hashedPassword,\n ]);\n await this.refreshPasswordExpiration(codiceUtente);\n if (options?.revokeSessions !== false) {\n await this.revokeSessionsAfterSecurityChange(codiceUtente, 'password_change');\n }\n return result;\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Revoca le sessioni dopo un evento che deve invalidare i token esistenti.\n * Best effort: un errore dello store non deve annullare l'operazione gia\n * persistita (cambio password, blocco, cancellazione).\n */\n private async revokeSessionsAfterSecurityChange(codiceUtente: number, reason: string): Promise<void> {\n try {\n await revokeAccessiUserSessionsIfConfigured(this.accessiOptions, codiceUtente, reason);\n } catch (error) {\n this.logger.error(\n `Revoca sessioni fallita per l'utente ${codiceUtente} (${reason}): ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Converte le password legacy cifrate nel formato hash compatibile, senza conoscere le password in chiaro.\n * E idempotente: hash moderni e gia migrati vengono ignorati.\n */\n public async migrateLegacyEncryptedPasswords(): Promise<void> {\n const startedAt = performance.now();\n this.logger.info(\"Avvio migrazione password legacy accessi.\");\n const results = await Orm.query(\n this.accessiOptions.databaseOptions,\n \"SELECT CODUTE AS codice_utente, PWD AS password FROM UTENTI_PWD WHERE PWD IS NOT NULL\",\n []\n );\n\n const rows = results.map(RestUtilities.convertKeysToCamelCase) as {\n codiceUtente?: number;\n password?: string;\n }[];\n let migratedCount = 0;\n let skippedCount = 0;\n\n for (const row of rows) {\n const codiceUtente = Number(row.codiceUtente);\n const storedPassword = typeof row.password === \"string\" ? row.password : null;\n\n if (\n !codiceUtente ||\n !storedPassword ||\n PasswordUtilities.isPasswordHash(storedPassword) ||\n PasswordUtilities.isLegacyPasswordHash(storedPassword)\n ) {\n skippedCount += 1;\n continue;\n }\n\n const protectedLegacyPassword =\n PasswordUtilities.hashLegacyEncryptedPassword(storedPassword);\n\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n \"UPDATE UTENTI_PWD SET PWD = ? WHERE CODUTE = ? AND PWD = ?\",\n [protectedLegacyPassword, codiceUtente, storedPassword]\n );\n migratedCount += 1;\n }\n\n this.logger.info(\n `Migrazione password legacy accessi completata. Letti=${rows.length}, migrati=${migratedCount}, ignorati=${skippedCount}, durataMs=${(performance.now() - startedAt).toFixed(2)}`\n );\n }\n\n /** Verifica una password locale e migra automaticamente il formato legacy dopo una verifica positiva. */\n async verifyPassword(\n codiceUtente: number,\n plainPassword: string\n ): Promise<boolean> {\n const query = `SELECT PWD AS password FROM UTENTI_PWD WHERE CODUTE = ?`;\n const result = (await Orm.query(\n this.accessiOptions.databaseOptions,\n query,\n [codiceUtente]\n ).then((results) => results.map(RestUtilities.convertKeysToCamelCase))) as {\n password: string;\n }[];\n\n const stored = result[0];\n if (!stored || typeof stored.password !== \"string\") {\n return false;\n }\n\n const storedPassword = stored.password;\n\n if (PasswordUtilities.isPasswordHash(storedPassword)) {\n return PasswordUtilities.verifyPassword(plainPassword, storedPassword);\n }\n\n const legacyEncryptedPassword = CryptUtilities.encrypt(\n plainPassword,\n this.accessiOptions.encryptionKey\n );\n\n if (PasswordUtilities.isLegacyPasswordHash(storedPassword)) {\n const isMigratedLegacyPasswordValid =\n PasswordUtilities.verifyLegacyEncryptedPassword(\n legacyEncryptedPassword,\n storedPassword\n );\n\n if (isMigratedLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword, {\n enforcePolicy: false,\n revokeSessions: false,\n });\n }\n\n return isMigratedLegacyPasswordValid;\n }\n\n const isLegacyPasswordValid = PasswordUtilities.timingSafeStringEquals(\n storedPassword,\n legacyEncryptedPassword,\n );\n\n if (isLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword, {\n enforcePolicy: false,\n revokeSessions: false,\n });\n }\n\n return isLegacyPasswordValid;\n }\n\n /** Restituisce l'utente fittizio amministratore; usabile solo con `mockDemoUser` esplicitamente abilitato. */\n async getAdminUser(): Promise<LoginResult> {\n return {\n utente: {\n codiceUtente: 6789,\n email: \"admin\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Admin\",\n nome: \"Admin\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: true,\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n /** Restituisce l'utente demo fittizio; non contiene dati o grant reali. */\n getDemoUser(): LoginResult {\n return {\n utente: {\n codiceUtente: 12345,\n email: \"jdoe\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Doe\",\n nome: \"John\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: false,\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n /**\n * Consuma un token monouso di reset, riporta l'utente allo stato confermato e salva la nuova password.\n * Il nonce in `UTENTI.KEYREG` viene annullato prima di impostare la password, impedendo il riuso del token.\n */\n public async confirmResetPassword(\n token: string,\n newPassword: string\n ): Promise<void> {\n try {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non valido.\");\n }\n\n assertStrongPassword(newPassword);\n\n const secret = getAccessiJwtSecret(this.accessiOptions, 'reset');\n const { codiceUtente, nonce } = verifyPasswordResetToken(token.trim(), secret);\n\n const hashedPassword = PasswordUtilities.hashPassword(newPassword);\n\n await Orm.withTransaction(this.accessiOptions.databaseOptions, async (transaction) => {\n // A conditional write claims the nonce under the database row lock. A second\n // concurrent reset cannot also consume it; failures roll the whole reset back.\n const claimed = await Orm.transactionQuery<unknown>(\n transaction,\n 'UPDATE UTENTI SET KEYREG = NULL, STAREG = ? WHERE CODUTE = ? AND KEYREG = ? AND STAREG IN (?, ?) RETURNING CODUTE',\n [StatoRegistrazione.CONF, codiceUtente, nonce, StatoRegistrazione.CONF, StatoRegistrazione.INVIO],\n );\n const row = (Array.isArray(claimed) ? claimed[0] : claimed) as Record<string, unknown> | undefined;\n if (Number(row?.CODUTE ?? row?.codute) !== codiceUtente) {\n throw new Error('Token non valido, gia usato o utente non autorizzato.');\n }\n\n await Orm.transactionQuery(\n transaction,\n 'UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?) MATCHING (CODUTE)',\n [codiceUtente, hashedPassword],\n );\n\n if (this.accessiOptions.passwordExpiration) {\n const days = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays = Number.isFinite(days) && days > 0 ? Math.trunc(days) : 90;\n await Orm.transactionQuery(\n transaction,\n `UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`,\n [codiceUtente],\n );\n }\n });\n\n // Il reset e un cambio password: i token emessi prima non devono piu valere.\n await this.revokeSessionsAfterSecurityChange(codiceUtente, 'password_reset');\n } catch (error) {\n throw error;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/AuthService/AuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, ServiceUnavailableException, UnauthorizedException } from \"@nestjs/common\";\nimport { randomUUID } from \"crypto\";\nimport { TwoFactorService, TwoFactorProof } from '../TwoFactorService/TwoFactorService';\nimport * as jwt from \"jsonwebtoken\";\nimport { Orm } from \"../../../Orm\";\nimport { CryptUtilities, PasswordUtilities, RestUtilities } from \"../../../Utilities\";\nimport type { AccessiOptions } from \"../../AccessiModule\";\nimport { LoginRequest } from \"../../Dtos/LoginRequest\";\nimport { LoginResult } from \"../../Dtos/LoginResponse\";\nimport { StatoRegistrazione } from \"../../Dtos/StatoRegistrazione\";\nimport { UserService } from \"../UserService/UserService\";\nimport { FiltriService } from \"../FiltriService/FiltriService\";\nimport {\n buildAuthenticatedTokenPayload,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../../security/authenticatedToken\";\nimport {\n getAccessiJwtSecret,\n verifyPasswordResetToken,\n} from \"../../security/passwordResetToken\";\nimport {\n isAccessiTokenRevoked,\n revokeAccessiUserSessions,\n revokeAccessiUserSessionsIfConfigured,\n} from \"../../security/sessionRevocation\";\nimport {\n consumeRefreshToken,\n getRefreshTokenRotationStore,\n isRefreshTokenFamilyRevoked,\n revokeRefreshTokenFamily,\n} from \"../../security/refreshTokenRotation\";\nimport { auditAccessi } from \"../../security/audit\";\nimport {\n getAccessiAccessTokenSigningConfig,\n getAccessiAccessTokenVerificationConfig,\n getAccessiRefreshTokenSigningConfig,\n getAccessiRefreshTokenVerificationConfig,\n verifyAccessiJwt,\n} from \"../../security/jwtTokenOptions\";\nimport { assertStrongPassword } from '../../security/passwordPolicy';\nimport { Logger } from \"../../../Logger\";\nimport { TokenResult } from '../../Dtos/TokenResult';\n\n/** Error code deliberately returned when a user is configured as SSO-only. */\nexport const PASSWORD_LOGIN_DISABLED = 'PASSWORD_LOGIN_DISABLED';\n\n/** Esito di una verifica token usata dall'endpoint di introspection. */\nexport interface AccessiTokenIntrospectionResult {\n active: boolean;\n codiceUtente?: number;\n payload?: Record<string, unknown>;\n}\n\ninterface AccessiTokenIssueOptions {\n /** Sovrascrive jwtOptions.expiresIn per token a durata ridotta (es. Login as). */\n expiresIn?: string | number;\n /** Claim aggiuntive, per esempio l'attore che ha generato un token di impersonazione. */\n extraClaims?: Record<string, unknown>;\n}\n\n@Injectable()\nexport class AuthService {\n private readonly logger = new Logger(AuthService.name);\n\n constructor(\n private userService: UserService,\n private filtriService: FiltriService,\n @Inject(\"ACCESSI_OPTIONS\") private readonly accessiOptions: AccessiOptions,\n private readonly twoFactorService: TwoFactorService,\n ) {}\n\n private async refreshPasswordExpiration(codiceUtente: number): Promise<void> {\n if (!this.accessiOptions.passwordExpiration) {\n return;\n }\n\n const configuredDays = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays =\n Number.isFinite(configuredDays) && configuredDays > 0\n ? Math.trunc(configuredDays)\n : 90;\n\n const query = `UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n }\n\n private isMockDemoUserEnabled(): boolean {\n if (!this.accessiOptions.mockDemoUser) {\n return false;\n }\n\n // La backdoor mock non e mai attiva in produzione, nemmeno con variabili d'ambiente,\n // perche emette un superutente senza verifica password.\n const nodeEnv = (process.env.NODE_ENV ?? \"production\").toLowerCase();\n return nodeEnv !== \"production\";\n }\n\n private createToken(\n utente: LoginResult['utente'],\n methods: string[],\n type: 'access' | 'refresh',\n tokenOptions: AccessiTokenIssueOptions = {},\n ): TokenResult {\n if (!utente?.codiceUtente) {\n throw new Error('Impossibile creare un token senza un utente Accessi valido.');\n }\n const loginAs = methods.includes('login_as');\n if ((utente.flagDueFattori === true || Number(utente.flagDueFattori) === 1) && !methods.includes('otp') && !loginAs) {\n throw new UnauthorizedException('Verifica del codice di accesso richiesta.');\n }\n\n const expiresIn = tokenOptions.expiresIn ?? this.accessiOptions.jwtOptions.expiresIn;\n const expiresInIsValid = typeof expiresIn === 'number'\n ? Number.isFinite(expiresIn) && expiresIn > 0\n : typeof expiresIn === 'string' && expiresIn.trim() !== '';\n if (!expiresInIsValid) {\n throw new Error('Durata token non configurata: impossibile emettere token senza scadenza.');\n }\n\n const signing = type === 'refresh'\n ? getAccessiRefreshTokenSigningConfig(this.accessiOptions)\n : getAccessiAccessTokenSigningConfig(this.accessiOptions);\n const token = jwt.sign(\n {\n ...(tokenOptions.extraClaims ?? {}),\n utente,\n typ: type,\n amr: methods,\n jti: randomUUID(),\n // Millisecondi: rende deterministica la revoca sessioni anche quando\n // il token e emesso nello stesso secondo del cambio password.\n iatMs: Date.now(),\n },\n signing.key,\n {\n expiresIn: expiresIn as jwt.SignOptions['expiresIn'],\n algorithm: signing.algorithm,\n ...signing.signOptions,\n },\n );\n\n // Difesa in profondita: un `expiresIn` malformato farebbe emettere un token permanente.\n const decoded = jwt.decode(token);\n const decodedPayload = decoded && typeof decoded === 'object' ? decoded as jwt.JwtPayload : undefined;\n if (typeof decodedPayload?.exp !== 'number') {\n throw new Error('Token emesso senza scadenza: configurazione JWT non valida.');\n }\n\n // Il contratto TokenResult espone sempre la validita in secondi, anche quando\n // jwtOptions.expiresIn usa un formato leggibile come '24h'.\n const issuedAt = typeof decodedPayload.iat === 'number' ? decodedPayload.iat : Math.floor(Date.now() / 1000);\n const expiresInSeconds = Math.max(0, Math.trunc(decodedPayload.exp - issuedAt));\n\n return {\n expiresIn: String(expiresInSeconds),\n value: token,\n type: 'Bearer',\n };\n }\n\n /** Creates the normal internal JWT consumed by all existing Accessi guards. */\n public createAccessiToken(\n utente: LoginResult['utente'],\n methods: string[] = [],\n tokenOptions: AccessiTokenIssueOptions = {},\n ): TokenResult {\n return this.createToken(utente, methods, 'access', tokenOptions);\n }\n\n /** Emette il refresh token quando `jwtOptions.refreshExpiresIn` e configurato. */\n public createRefreshToken(\n utente: LoginResult['utente'],\n methods: string[] = [],\n tokenOptions: AccessiTokenIssueOptions = {},\n ): TokenResult | undefined {\n const expiresIn = this.accessiOptions.jwtOptions.refreshExpiresIn;\n if (!expiresIn) return undefined;\n return this.createToken(utente, methods, 'refresh', {\n ...tokenOptions,\n expiresIn,\n });\n }\n\n /** Crea la coppia access + refresh token usata da login, 2FA e SSO. */\n public createTokenPair(\n utente: LoginResult['utente'],\n methods: string[] = [],\n options?: { familyId?: string },\n ): { access: TokenResult; refresh?: TokenResult } {\n // La famiglia identifica il login: access e refresh condividono lo stesso\n // `fid`, cosi la revoca per riuso sospetto invalida entrambi.\n const familyId = options?.familyId ?? randomUUID();\n const access = this.createAccessiToken(utente, methods, { extraClaims: { fid: familyId } });\n const refresh = this.createRefreshToken(utente, methods, { extraClaims: { fid: familyId } });\n return { access, ...(refresh ? { refresh } : {}) };\n }\n\n /**\n * Emette l'access token per l'utente target, con l'attore registrato nelle\n * claim `act` e `loginAs`. La durata e' quella standard di jwtOptions.expiresIn.\n */\n public createLoginAsToken(\n utente: LoginResult['utente'],\n actor: { codiceUtente: number; email?: string },\n ): TokenResult {\n return this.createAccessiToken(utente, ['login_as'], {\n extraClaims: {\n loginAs: true,\n act: {\n sub: String(actor.codiceUtente),\n email: actor.email,\n },\n },\n });\n }\n\n /** Builds the standard login response for a user authenticated by a supported method. */\n public async getLoginResultForUser(codiceUtente: number, scope?: string): Promise<LoginResult> {\n const users = await this.userService.getUsers(\n { codiceUtente },\n { includeExtensionFields: true, includeGrants: true, ...(scope ? { scope } : {}) },\n );\n const result = users[0];\n if (!result?.utente) {\n throw new Error('Utente Accessi non trovato.');\n }\n const current = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(current)) throw new UnauthorizedException('Utente non abilitato.');\n result.utente = { ...result.utente, ...current };\n\n return {\n utente: result.utente,\n filtri: await this.filtriService.getFiltriUser(codiceUtente),\n userGrants: result.userGrants,\n extensionFields: result.extensionFields,\n };\n }\n\n /** Users without a row retain the historic password-login enabled default. */\n private async isPasswordLoginEnabled(codiceUtente: number): Promise<boolean> {\n if (this.accessiOptions.federatedAuthentication?.enabled !== true) return true;\n\n const rows = await Orm.query(\n this.accessiOptions.databaseOptions,\n 'SELECT COALESCE(FLGPASSWORD, 1) AS password_login_enabled FROM UTENTI_CONFIG WHERE CODUTE = ?',\n [codiceUtente],\n );\n const policy = rows.map(RestUtilities.convertKeysToCamelCase)[0] as { passwordLoginEnabled?: unknown } | undefined;\n return policy?.passwordLoginEnabled !== false && policy?.passwordLoginEnabled !== 0 && policy?.passwordLoginEnabled !== '0';\n }\n\n /**\n * Autentica con credenziali locali e restituisce profilo, filtri e grant effettivi.\n * Non crea il JWT: il controller o il flusso SSO deve chiamare `createAccessiToken` sul risultato.\n * Per utenti SSO-only genera `PASSWORD_LOGIN_DISABLED`, da trattare come istruzione a usare l'SSO.\n */\n async login(request: LoginRequest): Promise<LoginResult> {\n const mockDemoUserEnabled = this.isMockDemoUserEnabled();\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"demo\"\n ) {\n return this.getDemoUser();\n }\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"admin\"\n ) {\n return this.getAdminUser();\n }\n\n const utente = await this.userService.getUserByEmail(\n request.email.trim().toLowerCase()\n );\n if (!utente) {\n if (!request.password) return { passwordRequired: true };\n throw new Error(\"Nome utente o password errata!\");\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(utente.codiceUtente);\n if (isAuthenticatedUserEnabledForJwt(currentUser) && currentUser.flagDueFattori && currentUser.passwordlessLoginEnabled) {\n return { challenge: await this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: (currentUser.email ?? '').trim(), mode: 'passwordless' }) };\n }\n // The email-only step has the same response for unknown and ordinary local accounts.\n if (!request.password) return { passwordRequired: true };\n\n switch (utente.statoRegistrazione) {\n case undefined:\n throw new Error(\n \"Struttura dati compromessa: Stato Registrazione inesistente.\"\n );\n case StatoRegistrazione.BLOCC:\n case StatoRegistrazione.DELETE:\n throw new Error(\"Utente non abilitato\");\n case StatoRegistrazione.INVIO:\n throw new Error(\"Rinnovo password necessario.\");\n }\n\n if (utente.statoRegistrazione !== StatoRegistrazione.CONF) {\n throw new Error(\n `Errore generico. Stato di registrazione non valido: ${utente.statoRegistrazione}.`\n );\n }\n\n if (!isAuthenticatedUserEnabledForJwt(currentUser)) throw new Error('Utente non abilitato');\n if (!(await this.isPasswordLoginEnabled(utente.codiceUtente))) {\n throw new Error(PASSWORD_LOGIN_DISABLED);\n }\n\n if (typeof request.password !== 'string' || request.password.length === 0) {\n throw new Error('Nome utente o password errata!');\n }\n\n const isPasswordValid = await this.verifyPassword(\n utente.codiceUtente,\n request.password\n );\n if (!isPasswordValid) throw new Error(\"Nome utente o password errata!\");\n\n if (\n this.accessiOptions.passwordExpiration &&\n this.accessiOptions.passwordExpiration == true\n ) {\n const today = new Date();\n const targetDate = utente.dataScadenzaPassword\n ? new Date(utente.dataScadenzaPassword)\n : undefined;\n\n // Legacy users may not have an expiration date. Preserve the former non-expiring behaviour for them.\n if (targetDate && !Number.isNaN(targetDate.getTime()) && today >= targetDate) {\n throw new Error(\"PASSWORD_EXPIRED\");\n }\n }\n\n if (currentUser.flagDueFattori) {\n return { challenge: await this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: currentUser.email ?? '', mode: 'password' }) };\n }\n\n const updateLastAccessDateQuery =\n \"UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?\";\n await Orm.query(\n this.accessiOptions.databaseOptions,\n updateLastAccessDateQuery,\n [utente.codiceUtente]\n );\n\n return this.getLoginResultForUser(utente.codiceUtente, request.scope);\n }\n\n /**\n * Verifica un access token Accessi senza sollevare eccezioni per token invalidi.\n *\n * Gli errori di configurazione o database continuano a propagarsi: un problema\n * infrastrutturale non deve essere confuso con un token scaduto.\n */\n public async introspectAccessToken(token: string): Promise<AccessiTokenIntrospectionResult> {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n return { active: false };\n }\n\n const verification = getAccessiAccessTokenVerificationConfig(this.accessiOptions);\n let decoded: unknown;\n try {\n decoded = verifyAccessiJwt(token.trim(), verification);\n } catch {\n return { active: false };\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n if (!codiceUtente) {\n return { active: false };\n }\n if (await isAccessiTokenRevoked(this.accessiOptions, decoded as Record<string, unknown>, codiceUtente)) {\n return { active: false };\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (\n !currentUser ||\n !isAuthenticatedUserEnabledForJwt(currentUser) ||\n !isAccessiTokenAllowedForUser(decoded, currentUser)\n ) {\n return { active: false };\n }\n\n return {\n active: true,\n codiceUtente,\n payload: buildAuthenticatedTokenPayload(decoded, currentUser),\n };\n }\n\n /**\n * Verifica un JWT Accessi e ricostruisce il profilo corrente dal database.\n * Questo evita che privilegi, stato utente o flag amministrativi presenti in un token vecchio restino validi.\n */\n public async getAuthenticatedTokenPayload(token: string): Promise<Record<string, unknown>> {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non fornito.\");\n }\n\n const introspection = await this.introspectAccessToken(token);\n if (!introspection.active || !introspection.payload) {\n throw new Error(\"Token non valido o utente non autorizzato.\");\n }\n\n return introspection.payload;\n }\n\n /**\n * Scambia un refresh token valido con una nuova coppia access + refresh.\n *\n * Il refresh token non e accettato dai guard API: ha `typ: \"refresh\"`.\n */\n public async refreshAccessToken(refreshToken: string): Promise<LoginResult> {\n if (!this.accessiOptions.jwtOptions.refreshExpiresIn) {\n throw new UnauthorizedException('Refresh token non abilitato.');\n }\n if (typeof refreshToken !== 'string' || refreshToken.trim() === '') {\n throw new UnauthorizedException('Refresh token mancante.');\n }\n\n const verification = getAccessiRefreshTokenVerificationConfig(this.accessiOptions);\n let decoded: unknown;\n try {\n decoded = verifyAccessiJwt(refreshToken.trim(), verification);\n } catch {\n throw new UnauthorizedException('Refresh token non valido o scaduto.');\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded, 'refresh');\n if (!codiceUtente) {\n throw new UnauthorizedException('Refresh token privo di un utente valido.');\n }\n\n const decodedRecord = decoded as { jti?: unknown; fid?: unknown; exp?: unknown };\n const familyId = typeof decodedRecord.fid === 'string' && decodedRecord.fid.trim() !== ''\n ? decodedRecord.fid\n : undefined;\n const jti = typeof decodedRecord.jti === 'string' ? decodedRecord.jti : undefined;\n const expiresAt = Number(decodedRecord.exp);\n\n // La famiglia va controllata per prima: un token appena emesso da uno store\n // compromesso deve produrre un codice stabile, non il generico 401 utente.\n if (await isRefreshTokenFamilyRevoked(this.accessiOptions, familyId)) {\n throw new UnauthorizedException({\n code: 'ACCESSI_REFRESH_FAMILY_REVOKED',\n message: 'Sessione revocata per riuso sospetto del refresh token.',\n });\n }\n\n if (await isAccessiTokenRevoked(this.accessiOptions, decoded as Record<string, unknown>, codiceUtente)) {\n throw new UnauthorizedException('Sessione revocata.');\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw new UnauthorizedException('Utente non piu autorizzato.');\n }\n\n const rotationStore = getRefreshTokenRotationStore(this.accessiOptions);\n if (rotationStore) {\n if (!jti || !Number.isFinite(expiresAt)) {\n throw new UnauthorizedException('Refresh token privo di jti o scadenza.');\n }\n let outcome;\n try {\n outcome = await consumeRefreshToken(this.accessiOptions, jti, expiresAt * 1000);\n } catch {\n throw new ServiceUnavailableException({\n code: 'ACCESSI_REFRESH_ROTATION_UNAVAILABLE',\n message: 'Rotazione refresh token non disponibile. Riprova piu tardi.',\n });\n }\n if (outcome && !outcome.consumed) {\n await this.handleRefreshTokenReuse({\n codiceUtente,\n jti,\n familyId,\n consumedAtMs: outcome.consumedAtMs,\n expiresAtMs: expiresAt * 1000,\n });\n throw new UnauthorizedException({\n code: 'ACCESSI_REFRESH_TOKEN_REUSE',\n message: 'Refresh token gia utilizzato.',\n });\n }\n }\n\n const login = await this.getLoginResultForUser(codiceUtente);\n const methods = Array.isArray((decoded as { amr?: unknown }).amr)\n ? ((decoded as { amr: unknown[] }).amr.filter((method): method is string => typeof method === 'string'))\n : [];\n const pair = this.createTokenPair(login.utente, methods, { familyId });\n login.token = pair.access;\n if (pair.refresh) login.refreshToken = pair.refresh;\n return login;\n }\n\n /**\n * Gestisce il riuso di un refresh token gia consumato.\n *\n * Il riuso entro `reuseGraceMs` e trattato come retry concorrente del client e\n * non revoca nulla. Oltre la finestra e considerato un possibile furto: viene\n * revocata l'intera famiglia (stesso login) e, solo se esplicitamente\n * configurato, anche le altre sessioni dell'utente.\n */\n private async handleRefreshTokenReuse(params: {\n codiceUtente: number;\n jti: string;\n familyId?: string;\n consumedAtMs?: number;\n expiresAtMs: number;\n }): Promise<void> {\n const configuredGrace = Number(this.accessiOptions.refreshTokenRotation?.reuseGraceMs ?? 10_000);\n const graceMs = Number.isFinite(configuredGrace) ? Math.max(0, configuredGrace) : 10_000;\n const consumedAtMs = params.consumedAtMs;\n if (\n graceMs > 0\n && consumedAtMs !== undefined\n && Number.isFinite(consumedAtMs)\n && Date.now() - consumedAtMs <= graceMs\n ) {\n return;\n }\n\n auditAccessi('accessi_refresh_token_reuse', {\n codiceUtente: params.codiceUtente,\n jti: params.jti,\n familyId: params.familyId,\n consumedAtMs,\n });\n\n try {\n if (params.familyId) {\n await revokeRefreshTokenFamily(\n this.accessiOptions,\n params.familyId,\n params.expiresAtMs,\n );\n }\n if (this.accessiOptions.refreshTokenRotation?.revokeUserSessionsOnReuse === true) {\n await revokeAccessiUserSessions(this.accessiOptions, params.codiceUtente, Date.now(), 'refresh_token_reuse');\n }\n } catch (error) {\n // La revoca e best effort: il token presentato resta comunque rifiutato.\n this.logger.error(\n `Revoca famiglia refresh token fallita: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /** Starts a second-factor challenge after the hosting backend has verified an SSO identity. */\n public async beginFederatedTwoFactor(codiceUtente: number, identityKey: string): Promise<LoginResult> {\n const user = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(user) || !user.flagDueFattori) throw new UnauthorizedException();\n return { challenge: await this.twoFactorService.issue({ codiceUtente, email: user.email ?? '', mode: 'federated', identityKey }) };\n }\n\n private async validateTwoFactorProof(proof: TwoFactorProof): Promise<void> {\n const user = await this.userService.getAuthenticatedUserSnapshot(proof.codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(user) || !user.flagDueFattori || user.email?.trim().toLowerCase() !== proof.email.trim().toLowerCase()) {\n throw new UnauthorizedException('Profilo modificato o utente non abilitato. Ripeti l accesso.');\n }\n if (proof.mode === 'passwordless' && !user.passwordlessLoginEnabled) throw new UnauthorizedException('Accesso senza password disabilitato.');\n if (proof.mode === 'password' && !(await this.isPasswordLoginEnabled(proof.codiceUtente))) throw new UnauthorizedException('Login locale disabilitato.');\n if (proof.mode === 'federated') {\n if (!this.accessiOptions.federatedAuthentication?.enabled) throw new UnauthorizedException();\n const rows = await Orm.query(this.accessiOptions.databaseOptions,\n 'SELECT I.IDNKEY FROM UTENTI_IDENTITA_EXT I INNER JOIN SSO_PROVIDER P ON P.PROVIDER = I.PROVIDER WHERE I.IDNKEY = ? AND I.CODUTE = ? AND I.FLGATTIVO = 1 AND P.FLGATTIVO = 1',\n [proof.identityKey, proof.codiceUtente], false);\n if (!rows.length) throw new UnauthorizedException('Identita SSO non piu abilitata.');\n }\n }\n\n public async verifyTwoFactor(challengeId: string, code: string, scope?: string): Promise<LoginResult> {\n const proof = await this.twoFactorService.consume(challengeId, code);\n await this.validateTwoFactorProof(proof);\n const result = await this.getLoginResultForUser(proof.codiceUtente, scope);\n const tokens = this.createTokenPair(result.utente, [proof.mode, 'otp']);\n result.token = tokens.access;\n if (tokens.refresh) result.refreshToken = tokens.refresh;\n await Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?', [proof.codiceUtente]);\n if (proof.mode === 'federated') {\n await Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI_IDENTITA_EXT SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE IDNKEY = ?', [proof.identityKey]);\n }\n return result;\n }\n\n public async resendTwoFactor(challengeId: string): Promise<LoginResult> {\n await this.validateTwoFactorProof(await this.twoFactorService.describe(challengeId));\n return { challenge: await this.twoFactorService.resend(challengeId) };\n }\n\n /**\n * Persiste una password hashata e aggiorna la scadenza, se la policy password e attiva. Non invia email.\n * Con `enforcePolicy` (default true) valida la password secondo la policy moderna; i flussi di\n * migrazione delle password legacy passano `enforcePolicy: false` per non bloccare password storiche.\n * Con `revokeSessions` (default true) invalida le sessioni precedenti: un cambio password deve\n * interrompere i token gia emessi.\n */\n public async setPassword(\n codiceUtente: number,\n nuovaPassword: string,\n options?: { enforcePolicy?: boolean; revokeSessions?: boolean },\n ) {\n if (options?.enforcePolicy !== false) {\n assertStrongPassword(nuovaPassword);\n }\n try {\n const query = `UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?)`;\n const hashedPassword = PasswordUtilities.hashPassword(nuovaPassword);\n\n const result = await Orm.execute(this.accessiOptions.databaseOptions, query, [\n codiceUtente,\n hashedPassword,\n ]);\n await this.refreshPasswordExpiration(codiceUtente);\n if (options?.revokeSessions !== false) {\n await this.revokeSessionsAfterSecurityChange(codiceUtente, 'password_change');\n }\n return result;\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Revoca le sessioni dopo un evento che deve invalidare i token esistenti.\n * Best effort: un errore dello store non deve annullare l'operazione gia\n * persistita (cambio password, blocco, cancellazione).\n */\n private async revokeSessionsAfterSecurityChange(codiceUtente: number, reason: string): Promise<void> {\n try {\n await revokeAccessiUserSessionsIfConfigured(this.accessiOptions, codiceUtente, reason);\n } catch (error) {\n this.logger.error(\n `Revoca sessioni fallita per l'utente ${codiceUtente} (${reason}): ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Converte le password legacy cifrate nel formato hash compatibile, senza conoscere le password in chiaro.\n * E idempotente: hash moderni e gia migrati vengono ignorati.\n */\n public async migrateLegacyEncryptedPasswords(): Promise<void> {\n const startedAt = performance.now();\n this.logger.info(\"Avvio migrazione password legacy accessi.\");\n const results = await Orm.query(\n this.accessiOptions.databaseOptions,\n \"SELECT CODUTE AS codice_utente, PWD AS password FROM UTENTI_PWD WHERE PWD IS NOT NULL\",\n []\n );\n\n const rows = results.map(RestUtilities.convertKeysToCamelCase) as {\n codiceUtente?: number;\n password?: string;\n }[];\n let migratedCount = 0;\n let skippedCount = 0;\n\n for (const row of rows) {\n const codiceUtente = Number(row.codiceUtente);\n const storedPassword = typeof row.password === \"string\" ? row.password : null;\n\n if (\n !codiceUtente ||\n !storedPassword ||\n PasswordUtilities.isPasswordHash(storedPassword) ||\n PasswordUtilities.isLegacyPasswordHash(storedPassword)\n ) {\n skippedCount += 1;\n continue;\n }\n\n const protectedLegacyPassword =\n PasswordUtilities.hashLegacyEncryptedPassword(storedPassword);\n\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n \"UPDATE UTENTI_PWD SET PWD = ? WHERE CODUTE = ? AND PWD = ?\",\n [protectedLegacyPassword, codiceUtente, storedPassword]\n );\n migratedCount += 1;\n }\n\n this.logger.info(\n `Migrazione password legacy accessi completata. Letti=${rows.length}, migrati=${migratedCount}, ignorati=${skippedCount}, durataMs=${(performance.now() - startedAt).toFixed(2)}`\n );\n }\n\n /** Verifica una password locale e migra automaticamente il formato legacy dopo una verifica positiva. */\n async verifyPassword(\n codiceUtente: number,\n plainPassword: string\n ): Promise<boolean> {\n const query = `SELECT PWD AS password FROM UTENTI_PWD WHERE CODUTE = ?`;\n const result = (await Orm.query(\n this.accessiOptions.databaseOptions,\n query,\n [codiceUtente]\n ).then((results) => results.map(RestUtilities.convertKeysToCamelCase))) as {\n password: string;\n }[];\n\n const stored = result[0];\n if (!stored || typeof stored.password !== \"string\") {\n return false;\n }\n\n const storedPassword = stored.password;\n\n if (PasswordUtilities.isPasswordHash(storedPassword)) {\n return PasswordUtilities.verifyPassword(plainPassword, storedPassword);\n }\n\n const legacyEncryptedPassword = CryptUtilities.encrypt(\n plainPassword,\n this.accessiOptions.encryptionKey\n );\n\n if (PasswordUtilities.isLegacyPasswordHash(storedPassword)) {\n const isMigratedLegacyPasswordValid =\n PasswordUtilities.verifyLegacyEncryptedPassword(\n legacyEncryptedPassword,\n storedPassword\n );\n\n if (isMigratedLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword, {\n enforcePolicy: false,\n revokeSessions: false,\n });\n }\n\n return isMigratedLegacyPasswordValid;\n }\n\n const isLegacyPasswordValid = PasswordUtilities.timingSafeStringEquals(\n storedPassword,\n legacyEncryptedPassword,\n );\n\n if (isLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword, {\n enforcePolicy: false,\n revokeSessions: false,\n });\n }\n\n return isLegacyPasswordValid;\n }\n\n /** Restituisce l'utente fittizio amministratore; usabile solo con `mockDemoUser` esplicitamente abilitato. */\n async getAdminUser(): Promise<LoginResult> {\n return {\n utente: {\n codiceUtente: 6789,\n email: \"admin\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Admin\",\n nome: \"Admin\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: true,\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n /** Restituisce l'utente demo fittizio; non contiene dati o grant reali. */\n getDemoUser(): LoginResult {\n return {\n utente: {\n codiceUtente: 12345,\n email: \"jdoe\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Doe\",\n nome: \"John\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: false,\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n /**\n * Consuma un token monouso di reset, riporta l'utente allo stato confermato e salva la nuova password.\n * Il nonce in `UTENTI.KEYREG` viene annullato prima di impostare la password, impedendo il riuso del token.\n */\n public async confirmResetPassword(\n token: string,\n newPassword: string\n ): Promise<void> {\n try {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non valido.\");\n }\n\n assertStrongPassword(newPassword);\n\n const secret = getAccessiJwtSecret(this.accessiOptions, 'reset');\n const { codiceUtente, nonce } = verifyPasswordResetToken(token.trim(), secret);\n\n const hashedPassword = PasswordUtilities.hashPassword(newPassword);\n\n await Orm.withTransaction(this.accessiOptions.databaseOptions, async (transaction) => {\n // A conditional write claims the nonce under the database row lock. A second\n // concurrent reset cannot also consume it; failures roll the whole reset back.\n const claimed = await Orm.transactionQuery<unknown>(\n transaction,\n 'UPDATE UTENTI SET KEYREG = NULL, STAREG = ? WHERE CODUTE = ? AND KEYREG = ? AND STAREG IN (?, ?) RETURNING CODUTE',\n [StatoRegistrazione.CONF, codiceUtente, nonce, StatoRegistrazione.CONF, StatoRegistrazione.INVIO],\n );\n const row = (Array.isArray(claimed) ? claimed[0] : claimed) as Record<string, unknown> | undefined;\n if (Number(row?.CODUTE ?? row?.codute) !== codiceUtente) {\n throw new Error('Token non valido, gia usato o utente non autorizzato.');\n }\n\n await Orm.transactionQuery(\n transaction,\n 'UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?) MATCHING (CODUTE)',\n [codiceUtente, hashedPassword],\n );\n\n if (this.accessiOptions.passwordExpiration) {\n const days = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays = Number.isFinite(days) && days > 0 ? Math.trunc(days) : 90;\n await Orm.transactionQuery(\n transaction,\n `UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`,\n [codiceUtente],\n );\n }\n });\n\n // Il reset e un cambio password: i token emessi prima non devono piu valere.\n await this.revokeSessionsAfterSecurityChange(codiceUtente, 'password_reset');\n } catch (error) {\n throw error;\n }\n }\n}\n"]}
@@ -1,4 +1,12 @@
1
- import type { AccessiOptions, CatalogScriptsOptions } from '../AccessiModule';
1
+ import type { AccessiOptions, CatalogScriptsOptions, JwtOptions } from '../AccessiModule';
2
+ /**
3
+ * Legge `ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS`: array JSON di chiavi pubbliche.
4
+ *
5
+ * Sono accettate sia stringhe PEM sia oggetti `{ publicKey, keyId, algorithm }`.
6
+ * Gli errori indicano l'indice e il nome della variabile, perché una rotazione
7
+ * malformata deve fermare il boot invece di lasciare token non verificabili.
8
+ */
9
+ export declare function parseAccessiPreviousPublicKeys(value: string | undefined, variableName?: string): NonNullable<JwtOptions['previousPublicKeys']> | undefined;
2
10
  /** Catalog migrations lette dall'ambiente: cartella in ACCESSI_CATALOG_FOLDER. */
3
11
  export declare function createCatalogScriptsOptionsFromEnv(): CatalogScriptsOptions | undefined;
4
12
  /** Costruisce `AccessiOptions` dalle variabili ambiente (stesse di runAccessiDbUpdate). */
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseAccessiPreviousPublicKeys = parseAccessiPreviousPublicKeys;
3
4
  exports.createCatalogScriptsOptionsFromEnv = createCatalogScriptsOptionsFromEnv;
4
5
  exports.createAccessiOptionsFromEnv = createAccessiOptionsFromEnv;
5
6
  const Utilities_1 = require("../../Utilities");
@@ -29,6 +30,56 @@ function getJwtAlgorithm() {
29
30
  const value = (_a = process.env.ACCESSI_JWT_ALGORITHM) === null || _a === void 0 ? void 0 : _a.trim().toUpperCase();
30
31
  return JWT_ALGORITHMS.find((algorithm) => algorithm === value);
31
32
  }
33
+ /** Normalizza una chiave PEM incollata in una variabile a riga singola. */
34
+ function normalizePem(value) {
35
+ return value.includes('\\n') ? value.replace(/\\n/g, '\n') : value;
36
+ }
37
+ /**
38
+ * Legge `ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS`: array JSON di chiavi pubbliche.
39
+ *
40
+ * Sono accettate sia stringhe PEM sia oggetti `{ publicKey, keyId, algorithm }`.
41
+ * Gli errori indicano l'indice e il nome della variabile, perché una rotazione
42
+ * malformata deve fermare il boot invece di lasciare token non verificabili.
43
+ */
44
+ function parseAccessiPreviousPublicKeys(value, variableName = 'ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS') {
45
+ if (value === undefined || value.trim() === '')
46
+ return undefined;
47
+ let parsed;
48
+ try {
49
+ parsed = JSON.parse(value);
50
+ }
51
+ catch (error) {
52
+ const detail = error instanceof Error ? error.message : String(error);
53
+ throw new Error(`${variableName}: JSON non valido (${detail}).`);
54
+ }
55
+ if (!Array.isArray(parsed)) {
56
+ throw new Error(`${variableName}: atteso un array JSON di chiavi pubbliche.`);
57
+ }
58
+ return parsed.map((entry, index) => {
59
+ const position = `${variableName}[${index}]`;
60
+ if (typeof entry === 'string') {
61
+ if (entry.trim() === '') {
62
+ throw new Error(`${position}: chiave pubblica PEM vuota.`);
63
+ }
64
+ return { publicKey: normalizePem(entry) };
65
+ }
66
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
67
+ throw new Error(`${position}: atteso un PEM oppure un oggetto { publicKey, keyId, algorithm }.`);
68
+ }
69
+ const record = entry;
70
+ if (typeof record.publicKey !== 'string' || record.publicKey.trim() === '') {
71
+ throw new Error(`${position}: publicKey deve essere una stringa PEM non vuota.`);
72
+ }
73
+ if (record.keyId !== undefined && (typeof record.keyId !== 'string' || record.keyId.trim() === '')) {
74
+ throw new Error(`${position}: keyId, se presente, deve essere una stringa non vuota.`);
75
+ }
76
+ const algorithm = typeof record.algorithm === 'string' ? record.algorithm.trim().toUpperCase() : undefined;
77
+ if (algorithm !== undefined && !JWT_ALGORITHMS.some((supported) => supported === algorithm)) {
78
+ throw new Error(`${position}: algoritmo ${algorithm} non supportato.`);
79
+ }
80
+ return Object.assign(Object.assign({ publicKey: normalizePem(record.publicKey) }, (typeof record.keyId === 'string' ? { keyId: record.keyId.trim() } : {})), (algorithm ? { algorithm: algorithm } : {}));
81
+ });
82
+ }
32
83
  /** Catalog migrations lette dall'ambiente: cartella in ACCESSI_CATALOG_FOLDER. */
33
84
  function createCatalogScriptsOptionsFromEnv() {
34
85
  const folder = process.env.ACCESSI_CATALOG_FOLDER;
@@ -54,7 +105,8 @@ function createAccessiOptionsFromEnv() {
54
105
  databaseOptions.wireCrypt = wireCrypt;
55
106
  if (authPlugin)
56
107
  databaseOptions.pluginName = authPlugin;
57
- return Object.assign(Object.assign({ databaseOptions, confirmationEmailUrl: getEnv("ACCESSI_CONFIRMATION_EMAIL_URL", "http://localhost"), confirmationEmailReturnUrl: getEnv("ACCESSI_CONFIRMATION_RETURN_EMAIL_URL", "http://localhost"), confirmationEmailPrefix: process.env.ACCESSI_CONFIRMATION_EMAIL_PREFIX, customResetPage: process.env.ACCESSI_CUSTOM_RESET_PAGE, consoleApiBaseUrl: process.env.ACCESSI_CONSOLE_API_BASE_URL, publicBaseUrl: process.env.ACCESSI_PUBLIC_BASE_URL, encryptionKey: getEnv("ACCESSI_ENCRYPTION_KEY", "1234567890ABCDEF"), mockDemoUser: getOptionalBoolean("ACCESSI_MOCK_DEMO_USER", false), passwordExpiration: getOptionalBoolean("ACCESSI_PASSWORD_EXPIRATION", false), autoUpdateDatabase: true, jwtOptions: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ secret: getEnv("ACCESSI_JWT_SECRET", "local-accessi-update"), expiresIn: getEnv("ACCESSI_JWT_EXPIRES", "24h") }, (process.env.ACCESSI_JWT_REFRESH_EXPIRES ? { refreshExpiresIn: process.env.ACCESSI_JWT_REFRESH_EXPIRES } : {})), (process.env.ACCESSI_JWT_ISSUER ? { issuer: process.env.ACCESSI_JWT_ISSUER } : {})), (process.env.ACCESSI_JWT_AUDIENCE ? { audience: process.env.ACCESSI_JWT_AUDIENCE } : {})), (getJwtAlgorithm() ? { algorithm: getJwtAlgorithm() } : {})), (process.env.ACCESSI_JWT_PRIVATE_KEY ? { privateKey: process.env.ACCESSI_JWT_PRIVATE_KEY } : {})), (process.env.ACCESSI_JWT_PUBLIC_KEY ? { publicKey: process.env.ACCESSI_JWT_PUBLIC_KEY } : {})), (process.env.ACCESSI_JWT_KEY_ID ? { keyId: process.env.ACCESSI_JWT_KEY_ID } : {})), (process.env.ACCESSI_JWKS_PATH ? { jwksPath: process.env.ACCESSI_JWKS_PATH } : {})), emailOptions: {
108
+ const previousPublicKeys = parseAccessiPreviousPublicKeys(process.env.ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS);
109
+ return Object.assign(Object.assign({ databaseOptions, confirmationEmailUrl: getEnv("ACCESSI_CONFIRMATION_EMAIL_URL", "http://localhost"), confirmationEmailReturnUrl: getEnv("ACCESSI_CONFIRMATION_RETURN_EMAIL_URL", "http://localhost"), confirmationEmailPrefix: process.env.ACCESSI_CONFIRMATION_EMAIL_PREFIX, customResetPage: process.env.ACCESSI_CUSTOM_RESET_PAGE, consoleApiBaseUrl: process.env.ACCESSI_CONSOLE_API_BASE_URL, publicBaseUrl: process.env.ACCESSI_PUBLIC_BASE_URL, encryptionKey: getEnv("ACCESSI_ENCRYPTION_KEY", "1234567890ABCDEF"), mockDemoUser: getOptionalBoolean("ACCESSI_MOCK_DEMO_USER", false), passwordExpiration: getOptionalBoolean("ACCESSI_PASSWORD_EXPIRATION", false), autoUpdateDatabase: true, jwtOptions: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ secret: getEnv("ACCESSI_JWT_SECRET", "local-accessi-update"), expiresIn: getEnv("ACCESSI_JWT_EXPIRES", "24h") }, (process.env.ACCESSI_JWT_REFRESH_EXPIRES ? { refreshExpiresIn: process.env.ACCESSI_JWT_REFRESH_EXPIRES } : {})), (process.env.ACCESSI_JWT_ISSUER ? { issuer: process.env.ACCESSI_JWT_ISSUER } : {})), (process.env.ACCESSI_JWT_AUDIENCE ? { audience: process.env.ACCESSI_JWT_AUDIENCE } : {})), (getJwtAlgorithm() ? { algorithm: getJwtAlgorithm() } : {})), (process.env.ACCESSI_JWT_PRIVATE_KEY ? { privateKey: process.env.ACCESSI_JWT_PRIVATE_KEY } : {})), (process.env.ACCESSI_JWT_PUBLIC_KEY ? { publicKey: process.env.ACCESSI_JWT_PUBLIC_KEY } : {})), (process.env.ACCESSI_JWT_KEY_ID ? { keyId: process.env.ACCESSI_JWT_KEY_ID } : {})), (process.env.ACCESSI_JWKS_PATH ? { jwksPath: process.env.ACCESSI_JWKS_PATH } : {})), (previousPublicKeys ? { previousPublicKeys } : {})), emailOptions: {
58
110
  host: getEnv("ACCESSI_EMAIL_HOST", "localhost"),
59
111
  port: Number(getEnv("ACCESSI_EMAIL_PORT", "25")),
60
112
  secure: getOptionalBoolean("ACCESSI_EMAIL_SECURE", false),
@@ -1 +1 @@
1
- {"version":3,"file":"accessiOptionsFromEnv.js","sourceRoot":"","sources":["../../../src/accessi-module/database-updates/accessiOptionsFromEnv.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessiOptions, CatalogScriptsOptions } from '../AccessiModule';\nimport { DatabaseUtilities } from '../../Utilities';\n\nfunction getEnv(names: string | string[], fallback?: string): string {\n const candidates = Array.isArray(names) ? names : [names];\n const value = candidates.map((name) => process.env[name]).find((candidate) => candidate !== undefined && candidate !== \"\") ?? fallback;\n if (!value) {\n throw new Error(`Variabile ambiente mancante: ${candidates.join(\" oppure \")}`);\n }\n return value;\n}\n\nfunction getOptionalBoolean(name: string, fallback: boolean): boolean {\n const value = process.env[name];\n if (value === undefined) {\n return fallback;\n }\n return value.toLowerCase() === \"true\";\n}\n\nconst JWT_ALGORITHMS = [\n \"HS256\", \"HS384\", \"HS512\",\n \"RS256\", \"RS384\", \"RS512\",\n \"ES256\", \"ES384\", \"ES512\",\n] as const;\n\nfunction getJwtAlgorithm(): (typeof JWT_ALGORITHMS)[number] | undefined {\n const value = process.env.ACCESSI_JWT_ALGORITHM?.trim().toUpperCase();\n return JWT_ALGORITHMS.find((algorithm) => algorithm === value);\n}\n\n/** Catalog migrations lette dall'ambiente: cartella in ACCESSI_CATALOG_FOLDER. */\nexport function createCatalogScriptsOptionsFromEnv(): CatalogScriptsOptions | undefined {\n const folder = process.env.ACCESSI_CATALOG_FOLDER;\n if (!folder) {\n return undefined;\n }\n\n const policy = process.env.ACCESSI_CATALOG_CHECKSUM_POLICY;\n const checksumPolicy = policy === 'warn' || policy === 'reapply' || policy === 'error' ? policy : undefined;\n\n return {\n enabled: true,\n folder,\n onChecksumMismatch: checksumPolicy,\n stopOnError: getOptionalBoolean('ACCESSI_CATALOG_STOP_ON_ERROR', true),\n };\n}\n\n/** Costruisce `AccessiOptions` dalle variabili ambiente (stesse di runAccessiDbUpdate). */\nexport function createAccessiOptionsFromEnv(): AccessiOptions {\n const databaseOptions = DatabaseUtilities.createOption(\n getEnv([\"ACCESSI_DB_HOST\", \"ACCESSI_FIREBIRD_HOST\"]),\n Number(getEnv([\"ACCESSI_DB_PORT\", \"ACCESSI_FIREBIRD_PORT\"], \"3050\")),\n getEnv([\"ACCESSI_DB_DATABASE\", \"ACCESSI_FIREBIRD_DATABASE\"]),\n getEnv([\"ACCESSI_DB_USER\", \"ACCESSI_FIREBIRD_USER\"], \"SYSDBA\"),\n getEnv([\"ACCESSI_DB_PASSWORD\", \"ACCESSI_FIREBIRD_PASSWORD\"], \"masterkey\")\n );\n\n // Firebird 2.5 richiede Legacy_Auth e non supporta la cifratura del wire: override opzionale via env.\n const wireCrypt = process.env.ACCESSI_DB_WIRE_CRYPT;\n const authPlugin = process.env.ACCESSI_DB_AUTH_PLUGIN;\n if (wireCrypt) (databaseOptions as { wireCrypt?: string }).wireCrypt = wireCrypt;\n if (authPlugin) (databaseOptions as { pluginName?: string }).pluginName = authPlugin;\n\n return {\n databaseOptions,\n confirmationEmailUrl: getEnv(\"ACCESSI_CONFIRMATION_EMAIL_URL\", \"http://localhost\"),\n confirmationEmailReturnUrl: getEnv(\"ACCESSI_CONFIRMATION_RETURN_EMAIL_URL\", \"http://localhost\"),\n confirmationEmailPrefix: process.env.ACCESSI_CONFIRMATION_EMAIL_PREFIX,\n customResetPage: process.env.ACCESSI_CUSTOM_RESET_PAGE,\n consoleApiBaseUrl: process.env.ACCESSI_CONSOLE_API_BASE_URL,\n publicBaseUrl: process.env.ACCESSI_PUBLIC_BASE_URL,\n encryptionKey: getEnv(\"ACCESSI_ENCRYPTION_KEY\", \"1234567890ABCDEF\"),\n mockDemoUser: getOptionalBoolean(\"ACCESSI_MOCK_DEMO_USER\", false),\n passwordExpiration: getOptionalBoolean(\"ACCESSI_PASSWORD_EXPIRATION\", false),\n autoUpdateDatabase: true,\n jwtOptions: {\n secret: getEnv(\"ACCESSI_JWT_SECRET\", \"local-accessi-update\"),\n expiresIn: getEnv(\"ACCESSI_JWT_EXPIRES\", \"24h\"),\n ...(process.env.ACCESSI_JWT_REFRESH_EXPIRES ? { refreshExpiresIn: process.env.ACCESSI_JWT_REFRESH_EXPIRES } : {}),\n ...(process.env.ACCESSI_JWT_ISSUER ? { issuer: process.env.ACCESSI_JWT_ISSUER } : {}),\n ...(process.env.ACCESSI_JWT_AUDIENCE ? { audience: process.env.ACCESSI_JWT_AUDIENCE } : {}),\n ...(getJwtAlgorithm() ? { algorithm: getJwtAlgorithm() } : {}),\n ...(process.env.ACCESSI_JWT_PRIVATE_KEY ? { privateKey: process.env.ACCESSI_JWT_PRIVATE_KEY } : {}),\n ...(process.env.ACCESSI_JWT_PUBLIC_KEY ? { publicKey: process.env.ACCESSI_JWT_PUBLIC_KEY } : {}),\n ...(process.env.ACCESSI_JWT_KEY_ID ? { keyId: process.env.ACCESSI_JWT_KEY_ID } : {}),\n ...(process.env.ACCESSI_JWKS_PATH ? { jwksPath: process.env.ACCESSI_JWKS_PATH } : {}),\n },\n emailOptions: {\n host: getEnv(\"ACCESSI_EMAIL_HOST\", \"localhost\"),\n port: Number(getEnv(\"ACCESSI_EMAIL_PORT\", \"25\")),\n secure: getOptionalBoolean(\"ACCESSI_EMAIL_SECURE\", false),\n requireTLS: getOptionalBoolean(\"ACCESSI_EMAIL_REQUIRE_TLS\", false),\n tls: {\n rejectUnauthorized: getOptionalBoolean(\"ACCESSI_EMAIL_TLS_REJECT_UNAUTHORIZED\", false),\n },\n from: getEnv(\"ACCESSI_EMAIL_FROM\", \"noreply@example.local\"),\n auth: {\n user: getEnv(\"ACCESSI_EMAIL_USER\", \"local-user\"),\n pass: getEnv(\"ACCESSI_EMAIL_PASSWORD\", \"local-password\"),\n },\n },\n ...(process.env.ACCESSI_CONSOLE_ENTRY_TTL_MS\n ? {\n consoleEntry: {\n ttlMs: Number(process.env.ACCESSI_CONSOLE_ENTRY_TTL_MS),\n },\n }\n : {}),\n extensionFieldsOptions: [],\n catalogScripts: createCatalogScriptsOptionsFromEnv(),\n };\n}\n"]}
1
+ {"version":3,"file":"accessiOptionsFromEnv.js","sourceRoot":"","sources":["../../../src/accessi-module/database-updates/accessiOptionsFromEnv.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessiOptions, CatalogScriptsOptions, JwtOptions } from '../AccessiModule';\nimport { DatabaseUtilities } from '../../Utilities';\n\nfunction getEnv(names: string | string[], fallback?: string): string {\n const candidates = Array.isArray(names) ? names : [names];\n const value = candidates.map((name) => process.env[name]).find((candidate) => candidate !== undefined && candidate !== \"\") ?? fallback;\n if (!value) {\n throw new Error(`Variabile ambiente mancante: ${candidates.join(\" oppure \")}`);\n }\n return value;\n}\n\nfunction getOptionalBoolean(name: string, fallback: boolean): boolean {\n const value = process.env[name];\n if (value === undefined) {\n return fallback;\n }\n return value.toLowerCase() === \"true\";\n}\n\nconst JWT_ALGORITHMS = [\n \"HS256\", \"HS384\", \"HS512\",\n \"RS256\", \"RS384\", \"RS512\",\n \"ES256\", \"ES384\", \"ES512\",\n] as const;\n\nfunction getJwtAlgorithm(): (typeof JWT_ALGORITHMS)[number] | undefined {\n const value = process.env.ACCESSI_JWT_ALGORITHM?.trim().toUpperCase();\n return JWT_ALGORITHMS.find((algorithm) => algorithm === value);\n}\n\n/** Normalizza una chiave PEM incollata in una variabile a riga singola. */\nfunction normalizePem(value: string): string {\n return value.includes('\\\\n') ? value.replace(/\\\\n/g, '\\n') : value;\n}\n\n/**\n * Legge `ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS`: array JSON di chiavi pubbliche.\n *\n * Sono accettate sia stringhe PEM sia oggetti `{ publicKey, keyId, algorithm }`.\n * Gli errori indicano l'indice e il nome della variabile, perché una rotazione\n * malformata deve fermare il boot invece di lasciare token non verificabili.\n */\nexport function parseAccessiPreviousPublicKeys(\n value: string | undefined,\n variableName = 'ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS',\n): NonNullable<JwtOptions['previousPublicKeys']> | undefined {\n if (value === undefined || value.trim() === '') return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new Error(`${variableName}: JSON non valido (${detail}).`);\n }\n\n if (!Array.isArray(parsed)) {\n throw new Error(`${variableName}: atteso un array JSON di chiavi pubbliche.`);\n }\n\n return parsed.map((entry, index) => {\n const position = `${variableName}[${index}]`;\n\n if (typeof entry === 'string') {\n if (entry.trim() === '') {\n throw new Error(`${position}: chiave pubblica PEM vuota.`);\n }\n return { publicKey: normalizePem(entry) };\n }\n\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n throw new Error(`${position}: atteso un PEM oppure un oggetto { publicKey, keyId, algorithm }.`);\n }\n\n const record = entry as Record<string, unknown>;\n if (typeof record.publicKey !== 'string' || record.publicKey.trim() === '') {\n throw new Error(`${position}: publicKey deve essere una stringa PEM non vuota.`);\n }\n if (record.keyId !== undefined && (typeof record.keyId !== 'string' || record.keyId.trim() === '')) {\n throw new Error(`${position}: keyId, se presente, deve essere una stringa non vuota.`);\n }\n const algorithm = typeof record.algorithm === 'string' ? record.algorithm.trim().toUpperCase() : undefined;\n if (algorithm !== undefined && !JWT_ALGORITHMS.some((supported) => supported === algorithm)) {\n throw new Error(`${position}: algoritmo ${algorithm} non supportato.`);\n }\n\n return {\n publicKey: normalizePem(record.publicKey),\n ...(typeof record.keyId === 'string' ? { keyId: record.keyId.trim() } : {}),\n ...(algorithm ? { algorithm: algorithm as (typeof JWT_ALGORITHMS)[number] } : {}),\n };\n });\n}\n\n/** Catalog migrations lette dall'ambiente: cartella in ACCESSI_CATALOG_FOLDER. */\nexport function createCatalogScriptsOptionsFromEnv(): CatalogScriptsOptions | undefined {\n const folder = process.env.ACCESSI_CATALOG_FOLDER;\n if (!folder) {\n return undefined;\n }\n\n const policy = process.env.ACCESSI_CATALOG_CHECKSUM_POLICY;\n const checksumPolicy = policy === 'warn' || policy === 'reapply' || policy === 'error' ? policy : undefined;\n\n return {\n enabled: true,\n folder,\n onChecksumMismatch: checksumPolicy,\n stopOnError: getOptionalBoolean('ACCESSI_CATALOG_STOP_ON_ERROR', true),\n };\n}\n\n/** Costruisce `AccessiOptions` dalle variabili ambiente (stesse di runAccessiDbUpdate). */\nexport function createAccessiOptionsFromEnv(): AccessiOptions {\n const databaseOptions = DatabaseUtilities.createOption(\n getEnv([\"ACCESSI_DB_HOST\", \"ACCESSI_FIREBIRD_HOST\"]),\n Number(getEnv([\"ACCESSI_DB_PORT\", \"ACCESSI_FIREBIRD_PORT\"], \"3050\")),\n getEnv([\"ACCESSI_DB_DATABASE\", \"ACCESSI_FIREBIRD_DATABASE\"]),\n getEnv([\"ACCESSI_DB_USER\", \"ACCESSI_FIREBIRD_USER\"], \"SYSDBA\"),\n getEnv([\"ACCESSI_DB_PASSWORD\", \"ACCESSI_FIREBIRD_PASSWORD\"], \"masterkey\")\n );\n\n // Firebird 2.5 richiede Legacy_Auth e non supporta la cifratura del wire: override opzionale via env.\n const wireCrypt = process.env.ACCESSI_DB_WIRE_CRYPT;\n const authPlugin = process.env.ACCESSI_DB_AUTH_PLUGIN;\n if (wireCrypt) (databaseOptions as { wireCrypt?: string }).wireCrypt = wireCrypt;\n if (authPlugin) (databaseOptions as { pluginName?: string }).pluginName = authPlugin;\n\n const previousPublicKeys = parseAccessiPreviousPublicKeys(\n process.env.ACCESSI_JWT_PREVIOUS_PUBLIC_KEYS,\n );\n\n return {\n databaseOptions,\n confirmationEmailUrl: getEnv(\"ACCESSI_CONFIRMATION_EMAIL_URL\", \"http://localhost\"),\n confirmationEmailReturnUrl: getEnv(\"ACCESSI_CONFIRMATION_RETURN_EMAIL_URL\", \"http://localhost\"),\n confirmationEmailPrefix: process.env.ACCESSI_CONFIRMATION_EMAIL_PREFIX,\n customResetPage: process.env.ACCESSI_CUSTOM_RESET_PAGE,\n consoleApiBaseUrl: process.env.ACCESSI_CONSOLE_API_BASE_URL,\n publicBaseUrl: process.env.ACCESSI_PUBLIC_BASE_URL,\n encryptionKey: getEnv(\"ACCESSI_ENCRYPTION_KEY\", \"1234567890ABCDEF\"),\n mockDemoUser: getOptionalBoolean(\"ACCESSI_MOCK_DEMO_USER\", false),\n passwordExpiration: getOptionalBoolean(\"ACCESSI_PASSWORD_EXPIRATION\", false),\n autoUpdateDatabase: true,\n jwtOptions: {\n secret: getEnv(\"ACCESSI_JWT_SECRET\", \"local-accessi-update\"),\n expiresIn: getEnv(\"ACCESSI_JWT_EXPIRES\", \"24h\"),\n ...(process.env.ACCESSI_JWT_REFRESH_EXPIRES ? { refreshExpiresIn: process.env.ACCESSI_JWT_REFRESH_EXPIRES } : {}),\n ...(process.env.ACCESSI_JWT_ISSUER ? { issuer: process.env.ACCESSI_JWT_ISSUER } : {}),\n ...(process.env.ACCESSI_JWT_AUDIENCE ? { audience: process.env.ACCESSI_JWT_AUDIENCE } : {}),\n ...(getJwtAlgorithm() ? { algorithm: getJwtAlgorithm() } : {}),\n ...(process.env.ACCESSI_JWT_PRIVATE_KEY ? { privateKey: process.env.ACCESSI_JWT_PRIVATE_KEY } : {}),\n ...(process.env.ACCESSI_JWT_PUBLIC_KEY ? { publicKey: process.env.ACCESSI_JWT_PUBLIC_KEY } : {}),\n ...(process.env.ACCESSI_JWT_KEY_ID ? { keyId: process.env.ACCESSI_JWT_KEY_ID } : {}),\n ...(process.env.ACCESSI_JWKS_PATH ? { jwksPath: process.env.ACCESSI_JWKS_PATH } : {}),\n ...(previousPublicKeys ? { previousPublicKeys } : {}),\n },\n emailOptions: {\n host: getEnv(\"ACCESSI_EMAIL_HOST\", \"localhost\"),\n port: Number(getEnv(\"ACCESSI_EMAIL_PORT\", \"25\")),\n secure: getOptionalBoolean(\"ACCESSI_EMAIL_SECURE\", false),\n requireTLS: getOptionalBoolean(\"ACCESSI_EMAIL_REQUIRE_TLS\", false),\n tls: {\n rejectUnauthorized: getOptionalBoolean(\"ACCESSI_EMAIL_TLS_REJECT_UNAUTHORIZED\", false),\n },\n from: getEnv(\"ACCESSI_EMAIL_FROM\", \"noreply@example.local\"),\n auth: {\n user: getEnv(\"ACCESSI_EMAIL_USER\", \"local-user\"),\n pass: getEnv(\"ACCESSI_EMAIL_PASSWORD\", \"local-password\"),\n },\n },\n ...(process.env.ACCESSI_CONSOLE_ENTRY_TTL_MS\n ? {\n consoleEntry: {\n ttlMs: Number(process.env.ACCESSI_CONSOLE_ENTRY_TTL_MS),\n },\n }\n : {}),\n extensionFieldsOptions: [],\n catalogScripts: createCatalogScriptsOptionsFromEnv(),\n };\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { AccessiOptions } from '../AccessiModule';
3
+ import type { AccessiReadinessCheck, AccessiReadinessDependencies } from './readiness';
4
+ export interface AccessiHealthModuleOptions {
5
+ /** Opzioni gia passate ad `AccessiModule.forRoot` / `initializeAccessiModule`. */
6
+ accessiOptions: AccessiOptions;
7
+ /** Check applicativi aggiuntivi, come nel servizio standalone. */
8
+ readinessChecks?: AccessiReadinessCheck[];
9
+ /** Override dei check (es. pool database esterni o test). */
10
+ readinessDependencies?: AccessiReadinessDependencies;
11
+ /** Path base degli endpoint. Default: `/health`. */
12
+ path?: string;
13
+ }
14
+ /**
15
+ * Crea un modulo Nest con `/health/live` e `/health/ready`.
16
+ *
17
+ * Stesso contratto del servizio standalone: readiness 200/503 con il dettaglio
18
+ * di bootstrap, database, store condivisi e check applicativi. Da importare
19
+ * nell'host Nest accanto ad `AccessiModule.forRoot`:
20
+ *
21
+ * ```ts
22
+ * @Module({
23
+ * imports: [
24
+ * AccessiModule.forRoot(accessiOptions),
25
+ * createAccessiHealthModule({ accessiOptions }),
26
+ * ],
27
+ * })
28
+ * export class AppModule {}
29
+ * ```
30
+ */
31
+ export declare function createAccessiHealthModule(options: AccessiHealthModuleOptions): DynamicModule;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.createAccessiHealthModule = createAccessiHealthModule;
25
+ const common_1 = require("@nestjs/common");
26
+ const readiness_1 = require("./readiness");
27
+ function normalizeHealthPath(value) {
28
+ return `/${value.replace(/^\/+|\/+$/g, '')}`;
29
+ }
30
+ let AccessiHealthHostModule = class AccessiHealthHostModule {
31
+ };
32
+ AccessiHealthHostModule = __decorate([
33
+ (0, common_1.Module)({})
34
+ ], AccessiHealthHostModule);
35
+ /**
36
+ * Crea un modulo Nest con `/health/live` e `/health/ready`.
37
+ *
38
+ * Stesso contratto del servizio standalone: readiness 200/503 con il dettaglio
39
+ * di bootstrap, database, store condivisi e check applicativi. Da importare
40
+ * nell'host Nest accanto ad `AccessiModule.forRoot`:
41
+ *
42
+ * ```ts
43
+ * @Module({
44
+ * imports: [
45
+ * AccessiModule.forRoot(accessiOptions),
46
+ * createAccessiHealthModule({ accessiOptions }),
47
+ * ],
48
+ * })
49
+ * export class AppModule {}
50
+ * ```
51
+ */
52
+ function createAccessiHealthModule(options) {
53
+ var _a, _b;
54
+ const readinessChecks = (_a = options.readinessChecks) !== null && _a !== void 0 ? _a : [];
55
+ const basePath = normalizeHealthPath((_b = options.path) !== null && _b !== void 0 ? _b : '/health');
56
+ let AccessiHealthController = class AccessiHealthController {
57
+ live() {
58
+ return (0, readiness_1.createAccessiLiveReport)();
59
+ }
60
+ ready(res) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const report = yield (0, readiness_1.checkAccessiReadiness)(options.accessiOptions, readinessChecks, options.readinessDependencies);
63
+ res.status((0, readiness_1.readinessHttpStatus)(report));
64
+ return report;
65
+ });
66
+ }
67
+ };
68
+ __decorate([
69
+ (0, common_1.Get)('live'),
70
+ __metadata("design:type", Function),
71
+ __metadata("design:paramtypes", []),
72
+ __metadata("design:returntype", Object)
73
+ ], AccessiHealthController.prototype, "live", null);
74
+ __decorate([
75
+ (0, common_1.Get)('ready'),
76
+ __param(0, (0, common_1.Res)({ passthrough: true })),
77
+ __metadata("design:type", Function),
78
+ __metadata("design:paramtypes", [Object]),
79
+ __metadata("design:returntype", Promise)
80
+ ], AccessiHealthController.prototype, "ready", null);
81
+ AccessiHealthController = __decorate([
82
+ (0, common_1.Controller)(basePath)
83
+ ], AccessiHealthController);
84
+ return {
85
+ module: AccessiHealthHostModule,
86
+ controllers: [AccessiHealthController],
87
+ };
88
+ }
89
+ //# sourceMappingURL=nest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nest.js","sourceRoot":"","sources":["../../../src/accessi-module/health/nest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAmDA,8DA2BC;AA9ED,2CAA8D;AAI9D,2CAIqB;AAmBrB,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAGD,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;CAAG,CAAA;AAA1B,uBAAuB;IAD5B,IAAA,eAAM,EAAC,EAAE,CAAC;GACL,uBAAuB,CAAG;AAEhC;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,yBAAyB,CAAC,OAAmC;;IAC3E,MAAM,eAAe,GAAG,MAAA,OAAO,CAAC,eAAe,mCAAI,EAAE,CAAC;IACtD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAA,OAAO,CAAC,IAAI,mCAAI,SAAS,CAAC,CAAC;IAGhE,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;QAE3B,IAAI;YACF,OAAO,IAAA,mCAAuB,GAAE,CAAC;QACnC,CAAC;QAGK,KAAK,CAA6B,GAAa;;gBACnD,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAqB,EACxC,OAAO,CAAC,cAAc,EACtB,eAAe,EACf,OAAO,CAAC,qBAAqB,CAC9B,CAAC;gBACF,GAAG,CAAC,MAAM,CAAC,IAAA,+BAAmB,EAAC,MAAM,CAAC,CAAC,CAAC;gBACxC,OAAO,MAAM,CAAC;YAChB,CAAC;SAAA;KACF,CAAA;IAdC;QADC,IAAA,YAAG,EAAC,MAAM,CAAC;;;;uDAGX;IAGK;QADL,IAAA,YAAG,EAAC,OAAO,CAAC;QACA,WAAA,IAAA,YAAG,EAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;;;;wDAQtC;IAfG,uBAAuB;QAD5B,IAAA,mBAAU,EAAC,QAAQ,CAAC;OACf,uBAAuB,CAgB5B;IAED,OAAO;QACL,MAAM,EAAE,uBAAuB;QAC/B,WAAW,EAAE,CAAC,uBAAuB,CAAC;KACvC,CAAC;AACJ,CAAC","sourcesContent":["import { Controller, Get, Module, Res } from '@nestjs/common';\nimport type { DynamicModule } from '@nestjs/common';\nimport type { Response } from 'express';\nimport type { AccessiOptions } from '../AccessiModule';\nimport {\n checkAccessiReadiness,\n createAccessiLiveReport,\n readinessHttpStatus,\n} from './readiness';\nimport type {\n AccessiLiveReport,\n AccessiReadinessCheck,\n AccessiReadinessDependencies,\n AccessiReadinessReport,\n} from './readiness';\n\nexport interface AccessiHealthModuleOptions {\n /** Opzioni gia passate ad `AccessiModule.forRoot` / `initializeAccessiModule`. */\n accessiOptions: AccessiOptions;\n /** Check applicativi aggiuntivi, come nel servizio standalone. */\n readinessChecks?: AccessiReadinessCheck[];\n /** Override dei check (es. pool database esterni o test). */\n readinessDependencies?: AccessiReadinessDependencies;\n /** Path base degli endpoint. Default: `/health`. */\n path?: string;\n}\n\nfunction normalizeHealthPath(value: string): string {\n return `/${value.replace(/^\\/+|\\/+$/g, '')}`;\n}\n\n@Module({})\nclass AccessiHealthHostModule {}\n\n/**\n * Crea un modulo Nest con `/health/live` e `/health/ready`.\n *\n * Stesso contratto del servizio standalone: readiness 200/503 con il dettaglio\n * di bootstrap, database, store condivisi e check applicativi. Da importare\n * nell'host Nest accanto ad `AccessiModule.forRoot`:\n *\n * ```ts\n * @Module({\n * imports: [\n * AccessiModule.forRoot(accessiOptions),\n * createAccessiHealthModule({ accessiOptions }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\nexport function createAccessiHealthModule(options: AccessiHealthModuleOptions): DynamicModule {\n const readinessChecks = options.readinessChecks ?? [];\n const basePath = normalizeHealthPath(options.path ?? '/health');\n\n @Controller(basePath)\n class AccessiHealthController {\n @Get('live')\n live(): AccessiLiveReport {\n return createAccessiLiveReport();\n }\n\n @Get('ready')\n async ready(@Res({ passthrough: true }) res: Response): Promise<AccessiReadinessReport> {\n const report = await checkAccessiReadiness(\n options.accessiOptions,\n readinessChecks,\n options.readinessDependencies,\n );\n res.status(readinessHttpStatus(report));\n return report;\n }\n }\n\n return {\n module: AccessiHealthHostModule,\n controllers: [AccessiHealthController],\n };\n}\n"]}