emilsoftware-utilities 2.0.0-dev.69 → 2.0.0-dev.70
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.
- package/dist/accessi/resource-server/runtime.js +51 -10
- package/dist/accessi/resource-server/runtime.js.map +1 -1
- package/dist/accessi/resource-server/types.d.ts +9 -2
- package/dist/accessi/resource-server/types.js.map +1 -1
- package/dist/accessi/server/standalone.js +3 -2
- package/dist/accessi/server/standalone.js.map +1 -1
- package/dist/accessi-module/AccessiModule.d.ts +4 -1
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/console.js +5 -3
- package/dist/accessi-module/Console/generated/emilsoftware-utilities.d.ts +11 -1
- package/dist/accessi-module/Console/generated/emilsoftware-utilities.js +12 -4
- package/dist/accessi-module/Console/generated/emilsoftware-utilities.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/index.d.ts +1 -0
- package/dist/accessi-module/Console/generated/model/index.js +1 -0
- package/dist/accessi-module/Console/generated/model/index.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/revokeTokenRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/revokeTokenRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/revokeTokenRequest.js.map +1 -0
- package/dist/accessi-module/Console/wiki.js +5 -3
- package/dist/accessi-module/Console/wiki.js.map +1 -1
- package/dist/accessi-module/Controllers/AuthController.d.ts +2 -1
- package/dist/accessi-module/Controllers/AuthController.js +63 -0
- package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
- package/dist/accessi-module/Dtos/RevokeTokenRequest.d.ts +3 -0
- package/dist/accessi-module/Dtos/RevokeTokenRequest.js +27 -0
- package/dist/accessi-module/Dtos/RevokeTokenRequest.js.map +1 -0
- package/dist/accessi-module/Dtos/index.d.ts +1 -0
- package/dist/accessi-module/Dtos/index.js +1 -0
- package/dist/accessi-module/Dtos/index.js.map +1 -1
- package/dist/accessi-module/Services/AuthService/AuthService.d.ts +22 -2
- package/dist/accessi-module/Services/AuthService/AuthService.js +115 -19
- package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
- package/dist/accessi-module/Services/UserService/UserService.d.ts +6 -0
- package/dist/accessi-module/Services/UserService/UserService.js +61 -5
- package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
- package/dist/accessi-module/federated-auth/FederatedAuthService.js +5 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.js.map +1 -1
- package/dist/accessi-module/index.d.ts +5 -3
- package/dist/accessi-module/index.js +13 -2
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/accessi-module/security/accessTokenRevocation.d.ts +47 -0
- package/dist/accessi-module/security/accessTokenRevocation.js +143 -0
- package/dist/accessi-module/security/accessTokenRevocation.js.map +1 -0
- package/dist/accessi-module/security/refreshTokenRotation.d.ts +42 -2
- package/dist/accessi-module/security/refreshTokenRotation.js +123 -10
- package/dist/accessi-module/security/refreshTokenRotation.js.map +1 -1
- package/dist/accessi-module/security/sessionRevocation.d.ts +21 -6
- package/dist/accessi-module/security/sessionRevocation.js +51 -5
- package/dist/accessi-module/security/sessionRevocation.js.map +1 -1
- package/dist/emilsoftware-utilities-2.0.0-dev.70.tgz +0 -0
- package/docs/accessi-openapi-fingerprint.json +2 -0
- package/package.json +3 -3
- package/dist/emilsoftware-utilities-2.0.0-dev.69.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 { isAccessiTokenRevoked } from \"../../security/sessionRevocation\";\nimport { getRefreshTokenRotationStore } from \"../../security/refreshTokenRotation\";\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 },\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 ): TokenResult | undefined {\n const expiresIn = this.accessiOptions.jwtOptions.refreshExpiresIn;\n if (!expiresIn) return undefined;\n return this.createToken(utente, methods, 'refresh', { expiresIn });\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 ): { access: TokenResult; refresh?: TokenResult } {\n const access = this.createAccessiToken(utente, methods);\n const refresh = this.createRefreshToken(utente, methods);\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 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 const decodedRecord = decoded as { jti?: unknown; exp?: unknown };\n const jti = typeof decodedRecord.jti === 'string' ? decodedRecord.jti : undefined;\n const expiresAt = Number(decodedRecord.exp);\n if (!jti || !Number.isFinite(expiresAt)) {\n throw new UnauthorizedException('Refresh token privo di jti o scadenza.');\n }\n try {\n const consumed = await rotationStore.consume(jti, expiresAt * 1000);\n if (!consumed) {\n throw new UnauthorizedException('Refresh token gia utilizzato.');\n }\n } catch (error) {\n if (error instanceof UnauthorizedException) throw error;\n throw new ServiceUnavailableException({\n code: 'ACCESSI_REFRESH_ROTATION_UNAVAILABLE',\n message: 'Rotazione refresh token non disponibile. Riprova piu tardi.',\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);\n login.token = pair.access;\n if (pair.refresh) login.refreshToken = pair.refresh;\n return login;\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 */\n public async setPassword(\n codiceUtente: number,\n nuovaPassword: string,\n options?: { enforcePolicy?: 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 return result;\n } catch (error) {\n throw error;\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, { enforcePolicy: false });\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, { enforcePolicy: false });\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 } 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} 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"]}
|
|
@@ -14,6 +14,12 @@ export declare class UserService {
|
|
|
14
14
|
private readonly filtriService;
|
|
15
15
|
constructor(accessiOptions: AccessiOptions, emailService: EmailService, permissionService: PermissionService, filtriService: FiltriService);
|
|
16
16
|
private normalizeDatabaseBoolean;
|
|
17
|
+
/**
|
|
18
|
+
* Revoca best effort delle sessioni dopo un evento che deve invalidare i
|
|
19
|
+
* token gia emessi. Lo store e opzionale: se non configurato (o non
|
|
20
|
+
* raggiungibile) l'operazione principale non deve fallire.
|
|
21
|
+
*/
|
|
22
|
+
private revokeSessionsBestEffort;
|
|
17
23
|
private normalizeUserFlags;
|
|
18
24
|
private normalizeEmail;
|
|
19
25
|
private ensureEmailIsAvailable;
|
|
@@ -31,6 +31,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
31
31
|
}
|
|
32
32
|
return t;
|
|
33
33
|
};
|
|
34
|
+
var UserService_1;
|
|
34
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
36
|
exports.UserService = void 0;
|
|
36
37
|
const common_1 = require("@nestjs/common");
|
|
@@ -38,9 +39,11 @@ const optionalColumns_1 = require("../../database-updates/optionalColumns");
|
|
|
38
39
|
const autobind_1 = require("../../../autobind");
|
|
39
40
|
const Orm_1 = require("../../../Orm");
|
|
40
41
|
const Utilities_1 = require("../../../Utilities");
|
|
42
|
+
const Logger_1 = require("../../../Logger");
|
|
41
43
|
const FiltriUtente_1 = require("../../Dtos/FiltriUtente");
|
|
42
44
|
const StatoRegistrazione_1 = require("../../Dtos/StatoRegistrazione");
|
|
43
45
|
const emailConfiguration_1 = require("../../security/emailConfiguration");
|
|
46
|
+
const sessionRevocation_1 = require("../../security/sessionRevocation");
|
|
44
47
|
const EmailService_1 = require("../EmailService/EmailService");
|
|
45
48
|
const FiltriService_1 = require("../FiltriService/FiltriService");
|
|
46
49
|
const PermissionService_1 = require("../PermissionService/PermissionService");
|
|
@@ -52,7 +55,7 @@ function hasFilterPayload(dto) {
|
|
|
52
55
|
const values = dto;
|
|
53
56
|
return Object.keys(FiltriUtente_1.FILTRI_UTENTE_DB_MAPPING).some((key) => values[key] !== undefined);
|
|
54
57
|
}
|
|
55
|
-
let UserService = class UserService {
|
|
58
|
+
let UserService = UserService_1 = class UserService {
|
|
56
59
|
constructor(accessiOptions, emailService, permissionService, filtriService) {
|
|
57
60
|
this.accessiOptions = accessiOptions;
|
|
58
61
|
this.emailService = emailService;
|
|
@@ -62,6 +65,21 @@ let UserService = class UserService {
|
|
|
62
65
|
normalizeDatabaseBoolean(value) {
|
|
63
66
|
return value === true || value === 1 || value === '1';
|
|
64
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Revoca best effort delle sessioni dopo un evento che deve invalidare i
|
|
70
|
+
* token gia emessi. Lo store e opzionale: se non configurato (o non
|
|
71
|
+
* raggiungibile) l'operazione principale non deve fallire.
|
|
72
|
+
*/
|
|
73
|
+
revokeSessionsBestEffort(codiceUtente, reason) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
try {
|
|
76
|
+
yield (0, sessionRevocation_1.revokeAccessiUserSessionsIfConfigured)(this.accessiOptions, codiceUtente, reason);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
new Logger_1.Logger(UserService_1.name).error(`Revoca sessioni fallita per l'utente ${codiceUtente} (${reason}): ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
65
83
|
normalizeUserFlags(user) {
|
|
66
84
|
const normalized = Object.assign(Object.assign({}, user), { flagSuper: this.normalizeDatabaseBoolean(user.flagSuper), flagAdmin: this.normalizeDatabaseBoolean(user.flagAdmin), flagDueFattori: this.normalizeDatabaseBoolean(user.flagDueFattori), passwordlessLoginEnabled: this.normalizeDatabaseBoolean(user.passwordlessLoginEnabled), passwordLoginEnabled: user.passwordLoginEnabled == null || this.normalizeDatabaseBoolean(user.passwordLoginEnabled) });
|
|
67
85
|
return normalized;
|
|
@@ -533,10 +551,17 @@ let UserService = class UserService {
|
|
|
533
551
|
user.permissions !== undefined)) {
|
|
534
552
|
throw new Error('Non e consentito modificare campi privilegiati.');
|
|
535
553
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
if (
|
|
554
|
+
let currentSnapshot;
|
|
555
|
+
const getCurrentSnapshot = () => __awaiter(this, void 0, void 0, function* () {
|
|
556
|
+
if (currentSnapshot === undefined) {
|
|
557
|
+
currentSnapshot = yield this.getAuthenticatedUserSnapshot(codiceUtente);
|
|
558
|
+
}
|
|
559
|
+
if (!currentSnapshot)
|
|
539
560
|
throw new common_1.BadRequestException('Utente non trovato.');
|
|
561
|
+
return currentSnapshot;
|
|
562
|
+
});
|
|
563
|
+
if (user.flagDueFattori !== undefined || user.passwordlessLoginEnabled !== undefined || user.email !== undefined) {
|
|
564
|
+
const current = yield getCurrentSnapshot();
|
|
540
565
|
const twoFactor = (_a = user.flagDueFattori) !== null && _a !== void 0 ? _a : current.flagDueFattori;
|
|
541
566
|
const passwordless = (_b = user.passwordlessLoginEnabled) !== null && _b !== void 0 ? _b : current.passwordlessLoginEnabled;
|
|
542
567
|
if (passwordless && !twoFactor)
|
|
@@ -545,6 +570,28 @@ let UserService = class UserService {
|
|
|
545
570
|
throw new common_1.BadRequestException('Per attivare i codici di accesso serve un indirizzo email valido.');
|
|
546
571
|
}
|
|
547
572
|
}
|
|
573
|
+
// Ogni modifica a stato o policy di autenticazione deve invalidare i token emessi.
|
|
574
|
+
let revocationReason;
|
|
575
|
+
if (user.statoRegistrazione !== undefined
|
|
576
|
+
|| user.flagDueFattori !== undefined
|
|
577
|
+
|| user.passwordlessLoginEnabled !== undefined
|
|
578
|
+
|| user.passwordLoginEnabled !== undefined) {
|
|
579
|
+
const before = yield getCurrentSnapshot();
|
|
580
|
+
if (user.statoRegistrazione !== undefined && Number(before.statoRegistrazione) !== Number(user.statoRegistrazione)) {
|
|
581
|
+
revocationReason = 'user_state_change';
|
|
582
|
+
}
|
|
583
|
+
else if (user.flagDueFattori !== undefined && Boolean(before.flagDueFattori) !== user.flagDueFattori) {
|
|
584
|
+
revocationReason = 'two_factor_policy_change';
|
|
585
|
+
}
|
|
586
|
+
else if (user.passwordlessLoginEnabled !== undefined
|
|
587
|
+
&& Boolean(before.passwordlessLoginEnabled) !== user.passwordlessLoginEnabled) {
|
|
588
|
+
revocationReason = 'login_policy_change';
|
|
589
|
+
}
|
|
590
|
+
else if (user.passwordLoginEnabled !== undefined
|
|
591
|
+
&& Boolean(before.passwordLoginEnabled) !== user.passwordLoginEnabled) {
|
|
592
|
+
revocationReason = 'login_policy_change';
|
|
593
|
+
}
|
|
594
|
+
}
|
|
548
595
|
const utentiUpdates = [];
|
|
549
596
|
const utentiParams = [];
|
|
550
597
|
if (user.email !== undefined) {
|
|
@@ -626,6 +673,9 @@ let UserService = class UserService {
|
|
|
626
673
|
if (hasFilterPayload(user)) {
|
|
627
674
|
yield this.filtriService.upsertFiltriUtente(codiceUtente, user);
|
|
628
675
|
}
|
|
676
|
+
if (revocationReason) {
|
|
677
|
+
yield this.revokeSessionsBestEffort(codiceUtente, revocationReason);
|
|
678
|
+
}
|
|
629
679
|
}
|
|
630
680
|
catch (error) {
|
|
631
681
|
throw error;
|
|
@@ -646,6 +696,7 @@ let UserService = class UserService {
|
|
|
646
696
|
StatoRegistrazione_1.StatoRegistrazione.DELETE,
|
|
647
697
|
codiceCliente,
|
|
648
698
|
]);
|
|
699
|
+
yield this.revokeSessionsBestEffort(codiceCliente, 'user_soft_delete');
|
|
649
700
|
}
|
|
650
701
|
catch (error) {
|
|
651
702
|
throw error;
|
|
@@ -678,6 +729,7 @@ let UserService = class UserService {
|
|
|
678
729
|
{ query: 'DELETE FROM UTENTI_GDPR WHERE CODUTE = ?', params },
|
|
679
730
|
{ query: 'DELETE FROM UTENTI WHERE CODUTE = ?', params },
|
|
680
731
|
]);
|
|
732
|
+
yield this.revokeSessionsBestEffort(codiceUtente, 'user_delete');
|
|
681
733
|
}
|
|
682
734
|
catch (error) {
|
|
683
735
|
if (this.isForeignKeyViolation(error)) {
|
|
@@ -708,6 +760,10 @@ let UserService = class UserService {
|
|
|
708
760
|
statoRegistrazione,
|
|
709
761
|
codiceCliente,
|
|
710
762
|
]);
|
|
763
|
+
if (statoRegistrazione === StatoRegistrazione_1.StatoRegistrazione.BLOCC
|
|
764
|
+
|| statoRegistrazione === StatoRegistrazione_1.StatoRegistrazione.DELETE) {
|
|
765
|
+
yield this.revokeSessionsBestEffort(codiceCliente, 'user_disabled');
|
|
766
|
+
}
|
|
711
767
|
}
|
|
712
768
|
catch (error) {
|
|
713
769
|
throw error;
|
|
@@ -770,7 +826,7 @@ let UserService = class UserService {
|
|
|
770
826
|
}
|
|
771
827
|
};
|
|
772
828
|
exports.UserService = UserService;
|
|
773
|
-
exports.UserService = UserService = __decorate([
|
|
829
|
+
exports.UserService = UserService = UserService_1 = __decorate([
|
|
774
830
|
autobind_1.autobind,
|
|
775
831
|
(0, common_1.Injectable)(),
|
|
776
832
|
__param(0, (0, common_1.Inject)('ACCESSI_OPTIONS')),
|