emilsoftware-utilities 2.0.0-dev.24 → 2.0.0-dev.26
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/README.MD +185 -182
- package/dist/ContractGenerator.js.map +1 -1
- package/dist/DailyFileTransport.js.map +1 -1
- package/dist/DatabaseUpdater.js +24 -24
- package/dist/DatabaseUpdater.js.map +1 -1
- package/dist/EmilsoftwareModule.js.map +1 -1
- package/dist/ExecutionTimeLogger.js.map +1 -1
- package/dist/Orm.js.map +1 -1
- package/dist/RoutesLoggerMiddleware.js.map +1 -1
- package/dist/Utilities.js.map +1 -1
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/console.js.map +1 -1
- package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
- package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
- package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
- package/dist/accessi-module/Controllers/UserController.js.map +1 -1
- package/dist/accessi-module/Dtos/Abilitazione.js.map +1 -1
- package/dist/accessi-module/Dtos/AbilitazioneMenu.js.map +1 -1
- package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/BaseResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/FiltriUtente.js.map +1 -1
- package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetMenusResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetRolesResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetUsersResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/LoginRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/LoginResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/Permission.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/Role.js.map +1 -1
- package/dist/accessi-module/Dtos/RuoliMenu.js.map +1 -1
- package/dist/accessi-module/Dtos/SetStatoRegistrazione.js.map +1 -1
- package/dist/accessi-module/Dtos/StatoRegistrazione.js.map +1 -1
- package/dist/accessi-module/Dtos/TipoAbilitazione.js.map +1 -1
- package/dist/accessi-module/Dtos/TipoFiltro.js.map +1 -1
- package/dist/accessi-module/Dtos/TokenResult.js.map +1 -1
- package/dist/accessi-module/Dtos/UpdateEnabledStatusRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
- package/dist/accessi-module/Dtos/UserGrantsDto.js.map +1 -1
- package/dist/accessi-module/Dtos/index.js.map +1 -1
- package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
- package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.js.map +1 -1
- package/dist/accessi-module/Services/EmailService/EmailService.js +11 -11
- package/dist/accessi-module/Services/EmailService/EmailService.js.map +1 -1
- package/dist/accessi-module/Services/FiltriService/FiltriService.js.map +1 -1
- package/dist/accessi-module/Services/PermissionService/PermissionService.js +118 -118
- package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.js +4 -4
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.js.map +1 -1
- package/dist/accessi-module/Services/UserService/UserService.js +72 -72
- package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
- package/dist/accessi-module/Views/reset-password.html +213 -213
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.d.ts +5 -0
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +82 -46
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js +9 -1
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js.map +1 -1
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
- package/dist/accessi-module/middleware/accessiRequirements.js.map +1 -1
- package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
- package/dist/accessi-module/security/accessControl.js.map +1 -1
- package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
- package/dist/accessi-module/security/passwordResetToken.js.map +1 -1
- package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
- package/dist/allegati-module/AllegatiModule.js.map +1 -1
- package/dist/allegati-module/Controllers/AllegatiController.js.map +1 -1
- package/dist/allegati-module/Dtos/AllegatoDto.js.map +1 -1
- package/dist/allegati-module/Dtos/BaseResponse.js.map +1 -1
- package/dist/allegati-module/Dtos/UploadSingleFileRequest.js.map +1 -1
- package/dist/allegati-module/Dtos/index.js.map +1 -1
- package/dist/allegati-module/Dtos/responses/DownloadAllegatoResponseDto.js.map +1 -1
- package/dist/allegati-module/Dtos/responses/GetListResponse.js.map +1 -1
- package/dist/allegati-module/Dtos/responses/UploadAllegatoResponseDto.js.map +1 -1
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.js +49 -49
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.js.map +1 -1
- package/dist/allegati-module/index.js.map +1 -1
- package/dist/autobind.js.map +1 -1
- package/dist/emilsoftware-utilities-2.0.0-dev.26.tgz +0 -0
- package/dist/firebird-compat.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/initEmilsoftwareModule.js.map +1 -1
- package/dist/swagger/SwaggerConfig.js.map +1 -1
- package/package.json +103 -103
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuIcona.d.ts +0 -12
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuIcona.js +0 -9
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuIcona.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuNote.d.ts +0 -12
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuNote.js +0 -9
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuNote.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuPagina.d.ts +0 -12
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuPagina.js +0 -9
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuPagina.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipo.d.ts +0 -12
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipo.js +0 -9
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipo.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/publicRegisterRequestCellulare.d.ts +0 -13
- package/dist/accessi-module/Console/generated/model/publicRegisterRequestCellulare.js +0 -9
- package/dist/accessi-module/Console/generated/model/publicRegisterRequestCellulare.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/registerRequestCellulare.d.ts +0 -13
- package/dist/accessi-module/Console/generated/model/registerRequestCellulare.js +0 -9
- package/dist/accessi-module/Console/generated/model/registerRequestCellulare.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/userDtoAvatar.d.ts +0 -13
- package/dist/accessi-module/Console/generated/model/userDtoAvatar.js +0 -9
- package/dist/accessi-module/Console/generated/model/userDtoAvatar.js.map +0 -1
- package/dist/accessi-module/Console/generated/model/userDtoCellulare.d.ts +0 -13
- package/dist/accessi-module/Console/generated/model/userDtoCellulare.js +0 -9
- package/dist/accessi-module/Console/generated/model/userDtoCellulare.js.map +0 -1
- package/dist/accessi-module/Console/openApiClient.d.ts +0 -34
- package/dist/accessi-module/Console/openApiClient.js +0 -111
- package/dist/accessi-module/Console/openApiClient.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../../src/accessi-module/jwt/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAOwB;AACxB,kDAAoC;AAEpC,qEAAkE;AAClE,uEAMwC;AACxC,uEAAqE;AAG9D,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAC8C,cAA8B,EACzD,WAAwB;QADG,mBAAc,GAAd,cAAc,CAAgB;QACzD,gBAAW,GAAX,WAAW,CAAa;IACxC,CAAC;IAEE,WAAW,CAAC,OAAyB;;YACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YAEpD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,8BAAqB,CAAC,iBAAiB,CAAC,CAAC;YAEpE,MAAM,KAAK,GAAG,IAAA,8CAAyB,EAAC,UAAU,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;YAEzE,IAAI,CAAC;gBACH,IAAI,MAAc,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,IAAA,wCAAmB,EAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;gBAC9D,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,qCAA4B,CAAC,6BAA6B,CAAC,CAAC;gBACxE,CAAC;gBACD,IAAI,OAAgC,CAAC;gBACrC,IAAI,CAAC;oBACC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACrE,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBACD,MAAM,YAAY,GAAG,IAAA,wDAAmC,EAAC,OAAO,CAAC,CAAC;gBAClE,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,IAAI,8BAAqB,CAAC,kCAAkC,CAAC,CAAC;gBACtE,CAAC;gBAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,IAAA,qDAAgC,EAAC,WAAW,CAAC,IAAI,CAAC,IAAA,iDAA4B,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC1G,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBAED,OAAO,CAAC,IAAI,GAAG,IAAA,mDAA8B,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBACpE,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,qCAA4B,IAAI,KAAK,YAAY,8BAAqB,EAAE,CAAC;oBAC5F,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,qCAA4B,CAAC,yCAAyC,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;KAAA;CACF,CAAA;AA/CY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CACI,yBAAW;GAHhC,cAAc,CA+C1B","sourcesContent":["import {\
|
|
1
|
+
{"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../../src/accessi-module/jwt/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAOwB;AACxB,kDAAoC;AAEpC,qEAAkE;AAClE,uEAMwC;AACxC,uEAAqE;AAG9D,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAC8C,cAA8B,EACzD,WAAwB;QADG,mBAAc,GAAd,cAAc,CAAgB;QACzD,gBAAW,GAAX,WAAW,CAAa;IACxC,CAAC;IAEE,WAAW,CAAC,OAAyB;;YACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YAEpD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,8BAAqB,CAAC,iBAAiB,CAAC,CAAC;YAEpE,MAAM,KAAK,GAAG,IAAA,8CAAyB,EAAC,UAAU,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;YAEzE,IAAI,CAAC;gBACH,IAAI,MAAc,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,IAAA,wCAAmB,EAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;gBAC9D,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,qCAA4B,CAAC,6BAA6B,CAAC,CAAC;gBACxE,CAAC;gBACD,IAAI,OAAgC,CAAC;gBACrC,IAAI,CAAC;oBACC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACrE,CAAC;gBAAC,WAAM,CAAC;oBACP,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBACD,MAAM,YAAY,GAAG,IAAA,wDAAmC,EAAC,OAAO,CAAC,CAAC;gBAClE,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,IAAI,8BAAqB,CAAC,kCAAkC,CAAC,CAAC;gBACtE,CAAC;gBAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBACtF,IAAI,CAAC,IAAA,qDAAgC,EAAC,WAAW,CAAC,IAAI,CAAC,IAAA,iDAA4B,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC1G,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;gBACjE,CAAC;gBAED,OAAO,CAAC,IAAI,GAAG,IAAA,mDAA8B,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBACpE,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,qCAA4B,IAAI,KAAK,YAAY,8BAAqB,EAAE,CAAC;oBAC5F,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,qCAA4B,CAAC,yCAAyC,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;KAAA;CACF,CAAA;AA/CY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;6CACI,yBAAW;GAHhC,cAAc,CA+C1B","sourcesContent":["import {\n CanActivate,\n ExecutionContext,\n Inject,\n Injectable,\n InternalServerErrorException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport * as jwt from 'jsonwebtoken';\nimport type { AccessiOptions } from '../AccessiModule';\nimport { UserService } from '../Services/UserService/UserService';\nimport {\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from '../security/authenticatedToken';\nimport { getAccessiJwtSecret } from '../security/passwordResetToken';\n\n@Injectable()\nexport class JwtSimpleGuard implements CanActivate {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n private readonly userService: UserService,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest();\n\n const authHeader = request.headers['authorization'];\n if (!authHeader) throw new UnauthorizedException('Token mancante.');\n\n const token = extractAccessiBearerToken(authHeader);\n if (!token) throw new UnauthorizedException('Formato token non valido.');\n\n try {\n let secret: string;\n try {\n secret = getAccessiJwtSecret(this.accessiOptions, 'access');\n } catch {\n throw new InternalServerErrorException('JWT secret non configurato.');\n }\n let payload: jwt.JwtPayload | string;\n try {\n payload = jwt.verify(token, secret, { algorithms: ['HS256'] });\n } catch {\n throw new UnauthorizedException('Token non valido o scaduto.');\n }\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(payload);\n if (!codiceUtente) {\n throw new UnauthorizedException('Token privo di un utente valido.');\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(payload, currentUser)) {\n throw new UnauthorizedException('Utente non piu autorizzato.');\n }\n\n request.user = buildAuthenticatedTokenPayload(payload, currentUser);\n return true;\n } catch (error) {\n if (error instanceof InternalServerErrorException || error instanceof UnauthorizedException) {\n throw error;\n }\n throw new InternalServerErrorException('Errore durante la verifica dell utente.');\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessiRequirements.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/accessiRequirements.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\r\n\r\n/** Grant effettivo letto da Accessi. Il confronto usa `tipoAbilitazione >= minPermissionLevel`. */\nexport type AccessiGrant = {\n codiceMenu: string;\r\n tipoAbilitazione?: number;\r\n};\r\n\r\n/** Risultato memoizzato durante una singola autorizzazione. Non modificarlo nel custom handler. */\nexport type GrantsResult = {\n grants?: AccessiGrant[];\r\n [key: string]: unknown;\r\n};\r\n\r\n/** Richiede l'accesso a un menu con almeno il livello indicato. Valori convenzionali: 10 lettura, 20 scrittura. */\nexport type AccessiPermissionRequirement = {\n type: \"permission\";\r\n menuCode: string;\r\n minPermissionLevel: number;\r\n};\r\n\r\n/** Tutti i requisiti figli devono essere soddisfatti. Una lista vuota e una configurazione non valida. */\nexport type AccessiAllRequirement = {\n type: \"and\";\r\n requirements: AccessiRequirementNode[];\r\n};\r\n\r\n/** Almeno un requisito figlio deve essere soddisfatto. Una lista vuota e una configurazione non valida. */\nexport type AccessiAnyRequirement = {\n type: \"or\";\r\n requirements: AccessiRequirementNode[];\r\n};\r\n\r\n/** Nega il risultato del requisito figlio. Usarlo con cautela per non creare policy difficili da verificare. */\nexport type AccessiNotRequirement = {\n type: \"not\";\r\n requirement: AccessiRequirementNode;\r\n};\r\n\r\n/** Delega una condizione applicativa a un handler registrato dal backend. */\nexport type AccessiCustomRequirement = {\n type: \"custom\";\r\n key: string;\r\n payload?: unknown;\r\n};\r\n\r\n/** Nodo composabile dell'albero di autorizzazione valutato da `authorizeAccessi`. */\nexport type AccessiRequirementNode =\n | AccessiPermissionRequirement\r\n | AccessiAllRequirement\r\n | AccessiAnyRequirement\r\n | AccessiNotRequirement\r\n | AccessiCustomRequirement;\r\n\r\n/** Contesto in sola lettura consegnato a un requisito personalizzato. */\nexport type AccessiCustomRequirementContext = {\n req: Request;\r\n decodedToken: Record<string, unknown>;\r\n userCode: number;\r\n getGrantsResult: () => Promise<GrantsResult>;\r\n};\r\n\r\n/** Handler applicativo per `accessiRequirement.custom`; `false` nega la richiesta, un errore produce 500. */\nexport type AccessiCustomRequirementHandler = (\n context: AccessiCustomRequirementContext,\r\n payload?: unknown\r\n) => boolean | Promise<boolean>;\r\n\r\n/**\n * Policy passata a `authorizeAccessi`.\n * `requirements` e la forma compatibile storica ed equivale a un AND; `requirementTree`\n * permette policy annidate e ha precedenza quando entrambi sono presenti.\n */\nexport type AccessiAuthorizationOptions = {\n requirements?: { menuCode: string; minPermissionLevel: number }[];\r\n requirementTree?: AccessiRequirementNode;\r\n customRequirementHandlers?: Record<string, AccessiCustomRequirementHandler>;\r\n};\r\n\r\n/** Errore di configurazione di una policy, distinto dal normale diniego 403. */\nexport class RequirementEvaluationError extends Error {\n constructor(public readonly code: string, message: string) {\r\n super(message);\r\n this.name = \"RequirementEvaluationError\";\r\n }\r\n}\r\n\r\nfunction requirementError(code: string, message: string): RequirementEvaluationError {\r\n return new RequirementEvaluationError(code, message);\r\n}\r\n\r\n/** Factory tipizzata per costruire policy leggibili senza dipendere dalla struttura interna dei nodi. */\nexport const accessiRequirement = {\n permission: (\r\n menuCode: string,\r\n minPermissionLevel: number\r\n ): AccessiPermissionRequirement => ({\r\n type: \"permission\",\r\n menuCode,\r\n minPermissionLevel,\r\n }),\r\n and: (...requirements: AccessiRequirementNode[]): AccessiAllRequirement => ({\r\n type: \"and\",\r\n requirements,\r\n }),\r\n or: (...requirements: AccessiRequirementNode[]): AccessiAnyRequirement => ({\r\n type: \"or\",\r\n requirements,\r\n }),\r\n not: (requirement: AccessiRequirementNode): AccessiNotRequirement => ({\r\n type: \"not\",\r\n requirement,\r\n }),\r\n custom: (key: string, payload?: unknown): AccessiCustomRequirement => ({\r\n type: \"custom\",\r\n key,\r\n payload,\r\n }),\r\n};\r\n\r\n/** Normalizza la forma compatibile `requirements` nell'albero interno. */\nexport function buildRequirementTree(\n options?: AccessiAuthorizationOptions\r\n): AccessiRequirementNode | undefined {\r\n if (options?.requirementTree) return options.requirementTree;\r\n\r\n const requirements = options?.requirements ?? [];\r\n if (requirements.length === 0) return undefined;\r\n\r\n const nodes: AccessiRequirementNode[] = requirements.map((requirement) =>\r\n accessiRequirement.permission(\r\n requirement.menuCode,\r\n requirement.minPermissionLevel\r\n )\r\n );\r\n\r\n return accessiRequirement.and(...nodes);\r\n}\r\n\r\n/**\n * Valuta ricorsivamente una policy. I grant sono caricati solo se necessari tramite `getGrantsResult`.\n * Questa funzione e pubblica per test e integrazioni avanzate; normalmente usare `authorizeAccessi`.\n */\nexport async function evaluateRequirement(\n requirement: AccessiRequirementNode,\r\n context: AccessiCustomRequirementContext,\r\n options?: AccessiAuthorizationOptions\r\n): Promise<boolean> {\r\n switch (requirement.type) {\r\n case \"permission\": {\r\n const grantsResult = await context.getGrantsResult();\r\n const grants = grantsResult.grants ?? [];\r\n return grants.some(\r\n (grant) =>\r\n grant.codiceMenu == requirement.menuCode &&\r\n Number(grant.tipoAbilitazione ?? 0) >= requirement.minPermissionLevel\r\n );\r\n }\r\n case \"and\":\r\n if (!requirement.requirements || requirement.requirements.length === 0) {\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n \"AND requirement must contain at least one child requirement\"\r\n );\r\n }\r\n for (const child of requirement.requirements) {\r\n if (!(await evaluateRequirement(child, context, options))) return false;\r\n }\r\n return true;\r\n case \"or\":\r\n if (!requirement.requirements || requirement.requirements.length === 0) {\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n \"OR requirement must contain at least one child requirement\"\r\n );\r\n }\r\n for (const child of requirement.requirements) {\r\n if (await evaluateRequirement(child, context, options)) return true;\r\n }\r\n return false;\r\n case \"not\":\r\n return !(await evaluateRequirement(requirement.requirement, context, options));\r\n case \"custom\": {\r\n const handlers = options?.customRequirementHandlers ?? {};\r\n const handler = handlers[requirement.key];\r\n if (!handler) {\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n `Custom requirement handler \"${requirement.key}\" not found`\r\n );\r\n }\r\n return Boolean(await handler(context, requirement.payload));\r\n }\r\n default:\r\n throw requirementError(\r\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\r\n \"Unknown requirement node type\"\r\n );\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"accessiRequirements.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/accessiRequirements.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\n\n/** Grant effettivo letto da Accessi. Il confronto usa `tipoAbilitazione >= minPermissionLevel`. */\nexport type AccessiGrant = {\n codiceMenu: string;\n tipoAbilitazione?: number;\n};\n\n/** Risultato memoizzato durante una singola autorizzazione. Non modificarlo nel custom handler. */\nexport type GrantsResult = {\n grants?: AccessiGrant[];\n [key: string]: unknown;\n};\n\n/** Richiede l'accesso a un menu con almeno il livello indicato. Valori convenzionali: 10 lettura, 20 scrittura. */\nexport type AccessiPermissionRequirement = {\n type: \"permission\";\n menuCode: string;\n minPermissionLevel: number;\n};\n\n/** Tutti i requisiti figli devono essere soddisfatti. Una lista vuota e una configurazione non valida. */\nexport type AccessiAllRequirement = {\n type: \"and\";\n requirements: AccessiRequirementNode[];\n};\n\n/** Almeno un requisito figlio deve essere soddisfatto. Una lista vuota e una configurazione non valida. */\nexport type AccessiAnyRequirement = {\n type: \"or\";\n requirements: AccessiRequirementNode[];\n};\n\n/** Nega il risultato del requisito figlio. Usarlo con cautela per non creare policy difficili da verificare. */\nexport type AccessiNotRequirement = {\n type: \"not\";\n requirement: AccessiRequirementNode;\n};\n\n/** Delega una condizione applicativa a un handler registrato dal backend. */\nexport type AccessiCustomRequirement = {\n type: \"custom\";\n key: string;\n payload?: unknown;\n};\n\n/** Nodo composabile dell'albero di autorizzazione valutato da `authorizeAccessi`. */\nexport type AccessiRequirementNode =\n | AccessiPermissionRequirement\n | AccessiAllRequirement\n | AccessiAnyRequirement\n | AccessiNotRequirement\n | AccessiCustomRequirement;\n\n/** Contesto in sola lettura consegnato a un requisito personalizzato. */\nexport type AccessiCustomRequirementContext = {\n req: Request;\n decodedToken: Record<string, unknown>;\n userCode: number;\n getGrantsResult: () => Promise<GrantsResult>;\n};\n\n/** Handler applicativo per `accessiRequirement.custom`; `false` nega la richiesta, un errore produce 500. */\nexport type AccessiCustomRequirementHandler = (\n context: AccessiCustomRequirementContext,\n payload?: unknown\n) => boolean | Promise<boolean>;\n\n/**\n * Policy passata a `authorizeAccessi`.\n * `requirements` e la forma compatibile storica ed equivale a un AND; `requirementTree`\n * permette policy annidate e ha precedenza quando entrambi sono presenti.\n */\nexport type AccessiAuthorizationOptions = {\n requirements?: { menuCode: string; minPermissionLevel: number }[];\n requirementTree?: AccessiRequirementNode;\n customRequirementHandlers?: Record<string, AccessiCustomRequirementHandler>;\n};\n\n/** Errore di configurazione di una policy, distinto dal normale diniego 403. */\nexport class RequirementEvaluationError extends Error {\n constructor(public readonly code: string, message: string) {\n super(message);\n this.name = \"RequirementEvaluationError\";\n }\n}\n\nfunction requirementError(code: string, message: string): RequirementEvaluationError {\n return new RequirementEvaluationError(code, message);\n}\n\n/** Factory tipizzata per costruire policy leggibili senza dipendere dalla struttura interna dei nodi. */\nexport const accessiRequirement = {\n permission: (\n menuCode: string,\n minPermissionLevel: number\n ): AccessiPermissionRequirement => ({\n type: \"permission\",\n menuCode,\n minPermissionLevel,\n }),\n and: (...requirements: AccessiRequirementNode[]): AccessiAllRequirement => ({\n type: \"and\",\n requirements,\n }),\n or: (...requirements: AccessiRequirementNode[]): AccessiAnyRequirement => ({\n type: \"or\",\n requirements,\n }),\n not: (requirement: AccessiRequirementNode): AccessiNotRequirement => ({\n type: \"not\",\n requirement,\n }),\n custom: (key: string, payload?: unknown): AccessiCustomRequirement => ({\n type: \"custom\",\n key,\n payload,\n }),\n};\n\n/** Normalizza la forma compatibile `requirements` nell'albero interno. */\nexport function buildRequirementTree(\n options?: AccessiAuthorizationOptions\n): AccessiRequirementNode | undefined {\n if (options?.requirementTree) return options.requirementTree;\n\n const requirements = options?.requirements ?? [];\n if (requirements.length === 0) return undefined;\n\n const nodes: AccessiRequirementNode[] = requirements.map((requirement) =>\n accessiRequirement.permission(\n requirement.menuCode,\n requirement.minPermissionLevel\n )\n );\n\n return accessiRequirement.and(...nodes);\n}\n\n/**\n * Valuta ricorsivamente una policy. I grant sono caricati solo se necessari tramite `getGrantsResult`.\n * Questa funzione e pubblica per test e integrazioni avanzate; normalmente usare `authorizeAccessi`.\n */\nexport async function evaluateRequirement(\n requirement: AccessiRequirementNode,\n context: AccessiCustomRequirementContext,\n options?: AccessiAuthorizationOptions\n): Promise<boolean> {\n switch (requirement.type) {\n case \"permission\": {\n const grantsResult = await context.getGrantsResult();\n const grants = grantsResult.grants ?? [];\n return grants.some(\n (grant) =>\n grant.codiceMenu == requirement.menuCode &&\n Number(grant.tipoAbilitazione ?? 0) >= requirement.minPermissionLevel\n );\n }\n case \"and\":\n if (!requirement.requirements || requirement.requirements.length === 0) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"AND requirement must contain at least one child requirement\"\n );\n }\n for (const child of requirement.requirements) {\n if (!(await evaluateRequirement(child, context, options))) return false;\n }\n return true;\n case \"or\":\n if (!requirement.requirements || requirement.requirements.length === 0) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"OR requirement must contain at least one child requirement\"\n );\n }\n for (const child of requirement.requirements) {\n if (await evaluateRequirement(child, context, options)) return true;\n }\n return false;\n case \"not\":\n return !(await evaluateRequirement(requirement.requirement, context, options));\n case \"custom\": {\n const handlers = options?.customRequirementHandlers ?? {};\n const handler = handlers[requirement.key];\n if (!handler) {\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n `Custom requirement handler \"${requirement.key}\" not found`\n );\n }\n return Boolean(await handler(context, requirement.payload));\n }\n default:\n throw requirementError(\n \"AUTH_REQUIREMENTS_MISCONFIGURED\",\n \"Unknown requirement node type\"\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticateGen.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/authenticateGen.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\r\nimport * as jwt from \"jsonwebtoken\";\r\nimport { Inject, Injectable } from \"@nestjs/common\";\r\nimport type { AccessiOptions } from \"../AccessiModule\";\r\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\r\nimport { UserService } from \"../Services/UserService/UserService\";\r\nimport { Logger } from \"../../Logger\";\r\nimport {\r\n AccessiAuthorizationOptions,\r\n AccessiCustomRequirementContext,\r\n GrantsResult,\r\n RequirementEvaluationError,\r\n buildRequirementTree,\r\n evaluateRequirement,\r\n} from \"./accessiRequirements\";\r\nimport {\r\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\r\n resolveCodiceUtenteFromTokenPayload,\r\n} from \"../security/authenticatedToken\";\r\nimport { getAccessiJwtSecret } from \"../security/passwordResetToken\";\n\r\nconst logger = new Logger(\"AuthenticateGen\");\r\nconst ACCESSI_AUTH_SERVICE_LOCALS_KEY = \"accessiAuthService\";\r\nconst ACCESSI_AUTH_SERVICE_GLOBAL_KEY = Symbol.for(\"emilsoftware.accessiAuthService\");\r\nconst ACCESSI_AUTH_SERVICE_WAIT_MS = 15000;\r\n\r\ntype Deferred<T> = {\r\n promise: Promise<T>;\r\n resolve: (value: T) => void;\r\n reject: (reason?: unknown) => void;\r\n};\r\n\r\nclass AuthMiddlewareError extends Error {\r\n constructor(\r\n public readonly status: number,\r\n public readonly code: string,\r\n message: string,\r\n public readonly details?: Record<string, unknown>\r\n ) {\r\n super(message);\r\n this.name = \"AuthMiddlewareError\";\r\n }\r\n}\r\n\r\nfunction authError(\r\n status: number,\r\n code: string,\r\n message: string,\r\n details?: Record<string, unknown>\r\n) {\r\n return new AuthMiddlewareError(status, code, message, details);\r\n}\r\n\r\nfunction normalizeAuthError(error: unknown): AuthMiddlewareError {\r\n if (error instanceof AuthMiddlewareError) return error;\r\n if (error instanceof RequirementEvaluationError) {\r\n return authError(500, error.code, error.message);\r\n }\r\n if (error instanceof Error) {\r\n return authError(500, \"AUTH_INTERNAL_ERROR\", error.message, {\r\n originalError: error.name,\r\n });\r\n }\r\n return authError(500, \"AUTH_INTERNAL_ERROR\", \"Unexpected authentication error\");\r\n}\r\n\r\nfunction logAuthFailure(req: Request, authErr: AuthMiddlewareError) {\n const payload = {\r\n code: authErr.code,\r\n status: authErr.status,\r\n message: authErr.message,\r\n details: authErr.details,\r\n method: req.method,\r\n path: req.originalUrl ?? req.url,\r\n ip: req.ip,\r\n };\r\n\r\n const message = `${authErr.status >= 500 ? \"Authentication failure\" : \"Authentication denied\"} ${JSON.stringify(payload)}`;\r\n if (authErr.status >= 500) logger.error(message);\r\n else logger.warning(message);\r\n}\n\n/** Sends the documented Accessi error contract from Express middleware. */\nfunction sendAuthenticationError(res: Response, authErr: AuthMiddlewareError): Response {\n const message =\n authErr.status === 403\n ? 'Operazione non autorizzata.'\n : authErr.status >= 500\n ? 'Errore interno del modulo Accessi.'\n : 'Autenticazione non valida o scaduta.';\n\n return res.status(authErr.status).json({\n severity: 'error',\n status: authErr.status,\n statusCode: 2,\n code: authErr.code,\n // Kept for callers of older versions which already inspected `error`.\n error: authErr.code,\n message,\n });\n}\n\r\nasync function authorizeWithDependencies(\r\n req: Request,\r\n res: Response,\r\n next: NextFunction,\r\n options: AccessiAuthorizationOptions | undefined,\r\n accessiOptions: AccessiOptions,\r\n permissionService: PermissionService,\r\n userService: UserService\r\n) {\r\n type AuthenticatedRequest = Request & {\r\n userGrants?: unknown;\r\n user?: unknown;\r\n data?: unknown;\r\n };\r\n const authenticatedRequest = req as AuthenticatedRequest;\r\n\r\n try {\r\n const authHeader = req.headers.authorization;\r\n if (!authHeader) {\r\n throw authError(401, \"AUTH_HEADER_MISSING\", \"Authorization header not found\");\r\n }\r\n\r\n const token = extractAccessiBearerToken(authHeader);\n if (!token) {\r\n throw authError(\r\n 401,\r\n \"AUTH_TOKEN_MISSING\",\r\n \"Token not found in Authorization header\"\r\n );\r\n }\r\n\r\n let secret: string;\r\n try {\r\n secret = getAccessiJwtSecret(accessiOptions, 'access');\r\n } catch {\r\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT secret not configured\");\r\n }\n\r\n let decoded: unknown;\r\n try {\r\n decoded = jwt.verify(token, secret, { algorithms: ['HS256'] });\r\n } catch {\r\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\r\n }\r\n\r\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\r\n if (!codiceUtente) {\r\n throw authError(\r\n 401,\r\n \"AUTH_USER_CODE_MISSING\",\r\n \"codiceUtente not found in token payload\"\r\n );\r\n }\r\n\r\n const currentUser = await userService.getAuthenticatedUserSnapshot(codiceUtente);\r\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw authError(\r\n 401,\r\n \"AUTH_USER_DISABLED\",\r\n \"User is no longer authorized\"\r\n );\r\n }\r\n\r\n const authenticatedPayload = buildAuthenticatedTokenPayload(decoded, currentUser);\r\n\r\n const requirementTree = buildRequirementTree(options);\r\n if (requirementTree) {\r\n if (!accessiOptions?.databaseOptions) {\r\n throw authError(\r\n 500,\r\n \"AUTH_DATABASE_OPTIONS_MISSING\",\r\n \"Database options not configured\"\r\n );\r\n }\r\n\r\n let grantsResultCache: GrantsResult | null = null;\r\n const getGrantsResult = async () => {\r\n if (!grantsResultCache) {\r\n grantsResultCache = await permissionService.getUserRolesAndGrants(\r\n codiceUtente\r\n );\r\n }\r\n return grantsResultCache;\r\n };\r\n\r\n const requirementContext: AccessiCustomRequirementContext = {\r\n req,\r\n decodedToken: authenticatedPayload,\r\n userCode: codiceUtente,\r\n getGrantsResult,\r\n };\r\n\r\n const hasPermissions = await evaluateRequirement(\r\n requirementTree,\r\n requirementContext,\r\n options\r\n );\r\n\r\n if (!hasPermissions) {\r\n throw authError(\r\n 403,\r\n \"AUTH_INSUFFICIENT_PERMISSIONS\",\r\n \"User does not have required permissions\"\r\n );\r\n }\r\n\r\n authenticatedRequest.userGrants = await getGrantsResult();\r\n }\r\n\r\n authenticatedRequest.user = authenticatedPayload;\r\n authenticatedRequest.data = authenticatedPayload;\r\n return next();\r\n } catch (error: unknown) {\r\n const authErr = normalizeAuthError(error);\r\n logAuthFailure(req, authErr);\r\n return sendAuthenticationError(res, authErr);\n }\r\n}\r\n\r\n@Injectable()\n/** Nest service behind the Express-compatible `authorizeAccessi` middleware. */\nexport class AuthenticateGenService {\n constructor(\r\n @Inject(\"ACCESSI_OPTIONS\")\r\n private readonly accessiOptions: AccessiOptions,\r\n private readonly permissionService: PermissionService,\r\n private readonly userService: UserService\r\n ) { }\r\n\r\n /**\n * Verifica JWT, stato corrente dell'utente e policy opzionale, poi popola `req.user` e `req.data`.\n * Se una policy richiede grant, popola anche `req.userGrants`; non chiamarlo direttamente fuori da test o adapter.\n */\n async authorize(\n req: Request,\r\n res: Response,\r\n next: NextFunction,\r\n options?: AccessiAuthorizationOptions\r\n ) {\r\n return authorizeWithDependencies(\r\n req,\r\n res,\r\n next,\r\n options,\r\n this.accessiOptions,\r\n this.permissionService,\r\n this.userService\r\n );\r\n }\r\n}\r\n\r\nlet authenticateGenServiceRef: AuthenticateGenService | null = null;\r\nlet authServiceBootstrapDeferred: Deferred<AuthenticateGenService> | null = null;\r\n\r\nfunction createDeferred<T>(): Deferred<T> {\r\n let resolve!: (value: T) => void;\r\n let reject!: (reason?: unknown) => void;\r\n const promise = new Promise<T>((res, rej) => {\r\n resolve = res;\r\n reject = rej;\r\n });\r\n return { promise, resolve, reject };\r\n}\r\n\r\nfunction isAuthenticateGenService(value: unknown): value is AuthenticateGenService {\r\n return Boolean(\r\n value &&\r\n typeof (value as { authorize?: unknown }).authorize === \"function\"\r\n );\r\n}\r\n\r\n/** Segnala al middleware che il bootstrap e in corso, consentendo una risposta 503 temporanea invece di un 500. */\nexport function beginAccessiAuthInitialization() {\n if (!authServiceBootstrapDeferred) {\r\n authServiceBootstrapDeferred = createDeferred<AuthenticateGenService>();\r\n }\r\n}\r\n\r\n/** Registra il servizio costruito da Nest nel bridge usato dalle rotte Express dell'app ospitante. */\nexport function setAccessiAuthService(service: AuthenticateGenService) {\n authenticateGenServiceRef = service;\r\n (globalThis as Record<symbol, unknown>)[ACCESSI_AUTH_SERVICE_GLOBAL_KEY] = service;\r\n if (authServiceBootstrapDeferred) {\r\n authServiceBootstrapDeferred.resolve(service);\r\n authServiceBootstrapDeferred = null;\r\n }\r\n}\r\n\r\n/** Propaga il fallimento del bootstrap alle richieste che stavano attendendo il bridge di autorizzazione. */\nexport function failAccessiAuthInitialization(error: unknown) {\n if (authServiceBootstrapDeferred) {\r\n authServiceBootstrapDeferred.reject(error);\r\n authServiceBootstrapDeferred = null;\r\n }\r\n}\r\n\r\nfunction getAccessiAuthServiceFromRequest(req: Request): AuthenticateGenService | null {\r\n const appLocalsService = (req.app?.locals as Record<string, unknown> | undefined)?.[\r\n ACCESSI_AUTH_SERVICE_LOCALS_KEY\r\n ];\r\n\r\n if (isAuthenticateGenService(appLocalsService)) {\r\n return appLocalsService as AuthenticateGenService;\r\n }\r\n\r\n const globalService = (globalThis as Record<symbol, unknown>)[\r\n ACCESSI_AUTH_SERVICE_GLOBAL_KEY\r\n ];\r\n if (isAuthenticateGenService(globalService)) {\r\n return globalService as AuthenticateGenService;\r\n }\r\n\r\n return authenticateGenServiceRef;\r\n}\r\n\r\nasync function waitForBootstrappedService(): Promise<AuthenticateGenService | null> {\r\n if (!authServiceBootstrapDeferred) {\r\n return null;\r\n }\r\n\r\n const bootstrapPromise = authServiceBootstrapDeferred.promise;\r\n const timeoutPromise = new Promise<null>((resolve) => {\r\n setTimeout(() => resolve(null), ACCESSI_AUTH_SERVICE_WAIT_MS);\r\n });\r\n\r\n try {\r\n const resolved = await Promise.race([bootstrapPromise, timeoutPromise]);\r\n return isAuthenticateGenService(resolved) ? resolved : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nasync function resolveAccessiAuthService(req: Request): Promise<AuthenticateGenService | null> {\r\n const immediateService = getAccessiAuthServiceFromRequest(req);\r\n if (immediateService) {\r\n return immediateService;\r\n }\r\n\r\n const bootstrappedService = await waitForBootstrappedService();\r\n if (bootstrappedService) {\r\n return bootstrappedService;\r\n }\r\n\r\n return getAccessiAuthServiceFromRequest(req);\r\n}\r\n\r\n/**\n * Middleware Express pubblico di Accessi.\n *\n * Applicarlo dopo `initializeAccessiModule`: legge `Authorization: Bearer <jwt>`, verifica l'utente corrente\n * e applica eventuali requisiti. Su successo valorizza `req.user` e continua; su errore risponde direttamente\n * con il contratto Accessi, quindi il chiamante non deve aggiungere un proprio `next(error)`.\n */\nexport async function authorizeAccessi(\n req: Request,\r\n res: Response,\r\n next: NextFunction,\r\n options?: AccessiAuthorizationOptions\r\n) {\r\n const authService = await resolveAccessiAuthService(req);\r\n\r\n if (!authService) {\r\n const status = authServiceBootstrapDeferred ? 503 : 500;\r\n const code = authServiceBootstrapDeferred\n ? 'ACCESSI_AUTH_INITIALIZING'\n : 'ACCESSI_AUTH_NOT_INITIALIZED';\n logger.error(\r\n `Authentication service not initialized ${JSON.stringify({\r\n method: req.method,\r\n path: req.originalUrl ?? req.url,\r\n status,\r\n })}`\r\n );\r\n return res.status(status).json({\n severity: 'error',\n status,\n statusCode: 2,\n code,\n error: code,\n message: status === 503\n ? 'Il modulo Accessi e in inizializzazione. Riprova tra poco.'\n : 'Il modulo Accessi non e disponibile.',\n });\n }\r\n\r\n return authService.authorize(req, res, next, options);\r\n}\r\n\r\n/** Alias storico di `authorizeAccessi`, mantenuto per retrocompatibilita. Preferire il nome esplicito nelle nuove integrazioni. */\nexport const authenticateGen = authorizeAccessi;\n"]}
|
|
1
|
+
{"version":3,"file":"authenticateGen.js","sourceRoot":"","sources":["../../../src/accessi-module/middleware/authenticateGen.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport * as jwt from \"jsonwebtoken\";\nimport { Inject, Injectable } from \"@nestjs/common\";\nimport type { AccessiOptions } from \"../AccessiModule\";\nimport { PermissionService } from \"../Services/PermissionService/PermissionService\";\nimport { UserService } from \"../Services/UserService/UserService\";\nimport { Logger } from \"../../Logger\";\nimport {\n AccessiAuthorizationOptions,\n AccessiCustomRequirementContext,\n GrantsResult,\n RequirementEvaluationError,\n buildRequirementTree,\n evaluateRequirement,\n} from \"./accessiRequirements\";\nimport {\n buildAuthenticatedTokenPayload,\n extractAccessiBearerToken,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../security/authenticatedToken\";\nimport { getAccessiJwtSecret } from \"../security/passwordResetToken\";\n\nconst logger = new Logger(\"AuthenticateGen\");\nconst ACCESSI_AUTH_SERVICE_LOCALS_KEY = \"accessiAuthService\";\nconst ACCESSI_AUTH_SERVICE_GLOBAL_KEY = Symbol.for(\"emilsoftware.accessiAuthService\");\nconst ACCESSI_AUTH_SERVICE_WAIT_MS = 15000;\n\ntype Deferred<T> = {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (reason?: unknown) => void;\n};\n\nclass AuthMiddlewareError extends Error {\n constructor(\n public readonly status: number,\n public readonly code: string,\n message: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = \"AuthMiddlewareError\";\n }\n}\n\nfunction authError(\n status: number,\n code: string,\n message: string,\n details?: Record<string, unknown>\n) {\n return new AuthMiddlewareError(status, code, message, details);\n}\n\nfunction normalizeAuthError(error: unknown): AuthMiddlewareError {\n if (error instanceof AuthMiddlewareError) return error;\n if (error instanceof RequirementEvaluationError) {\n return authError(500, error.code, error.message);\n }\n if (error instanceof Error) {\n return authError(500, \"AUTH_INTERNAL_ERROR\", error.message, {\n originalError: error.name,\n });\n }\n return authError(500, \"AUTH_INTERNAL_ERROR\", \"Unexpected authentication error\");\n}\n\nfunction logAuthFailure(req: Request, authErr: AuthMiddlewareError) {\n const payload = {\n code: authErr.code,\n status: authErr.status,\n message: authErr.message,\n details: authErr.details,\n method: req.method,\n path: req.originalUrl ?? req.url,\n ip: req.ip,\n };\n\n const message = `${authErr.status >= 500 ? \"Authentication failure\" : \"Authentication denied\"} ${JSON.stringify(payload)}`;\n if (authErr.status >= 500) logger.error(message);\n else logger.warning(message);\n}\n\n/** Sends the documented Accessi error contract from Express middleware. */\nfunction sendAuthenticationError(res: Response, authErr: AuthMiddlewareError): Response {\n const message =\n authErr.status === 403\n ? 'Operazione non autorizzata.'\n : authErr.status >= 500\n ? 'Errore interno del modulo Accessi.'\n : 'Autenticazione non valida o scaduta.';\n\n return res.status(authErr.status).json({\n severity: 'error',\n status: authErr.status,\n statusCode: 2,\n code: authErr.code,\n // Kept for callers of older versions which already inspected `error`.\n error: authErr.code,\n message,\n });\n}\n\nasync function authorizeWithDependencies(\n req: Request,\n res: Response,\n next: NextFunction,\n options: AccessiAuthorizationOptions | undefined,\n accessiOptions: AccessiOptions,\n permissionService: PermissionService,\n userService: UserService\n) {\n type AuthenticatedRequest = Request & {\n userGrants?: unknown;\n user?: unknown;\n data?: unknown;\n };\n const authenticatedRequest = req as AuthenticatedRequest;\n\n try {\n const authHeader = req.headers.authorization;\n if (!authHeader) {\n throw authError(401, \"AUTH_HEADER_MISSING\", \"Authorization header not found\");\n }\n\n const token = extractAccessiBearerToken(authHeader);\n if (!token) {\n throw authError(\n 401,\n \"AUTH_TOKEN_MISSING\",\n \"Token not found in Authorization header\"\n );\n }\n\n let secret: string;\n try {\n secret = getAccessiJwtSecret(accessiOptions, 'access');\n } catch {\n throw authError(500, \"AUTH_JWT_SECRET_MISSING\", \"JWT secret not configured\");\n }\n\n let decoded: unknown;\n try {\n decoded = jwt.verify(token, secret, { algorithms: ['HS256'] });\n } catch {\n throw authError(401, \"AUTH_TOKEN_INVALID\", \"Invalid JWT token\");\n }\n\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n if (!codiceUtente) {\n throw authError(\n 401,\n \"AUTH_USER_CODE_MISSING\",\n \"codiceUtente not found in token payload\"\n );\n }\n\n const currentUser = await userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw authError(\n 401,\n \"AUTH_USER_DISABLED\",\n \"User is no longer authorized\"\n );\n }\n\n const authenticatedPayload = buildAuthenticatedTokenPayload(decoded, currentUser);\n\n const requirementTree = buildRequirementTree(options);\n if (requirementTree) {\n if (!accessiOptions?.databaseOptions) {\n throw authError(\n 500,\n \"AUTH_DATABASE_OPTIONS_MISSING\",\n \"Database options not configured\"\n );\n }\n\n let grantsResultCache: GrantsResult | null = null;\n const getGrantsResult = async () => {\n if (!grantsResultCache) {\n grantsResultCache = await permissionService.getUserRolesAndGrants(\n codiceUtente\n );\n }\n return grantsResultCache;\n };\n\n const requirementContext: AccessiCustomRequirementContext = {\n req,\n decodedToken: authenticatedPayload,\n userCode: codiceUtente,\n getGrantsResult,\n };\n\n const hasPermissions = await evaluateRequirement(\n requirementTree,\n requirementContext,\n options\n );\n\n if (!hasPermissions) {\n throw authError(\n 403,\n \"AUTH_INSUFFICIENT_PERMISSIONS\",\n \"User does not have required permissions\"\n );\n }\n\n authenticatedRequest.userGrants = await getGrantsResult();\n }\n\n authenticatedRequest.user = authenticatedPayload;\n authenticatedRequest.data = authenticatedPayload;\n return next();\n } catch (error: unknown) {\n const authErr = normalizeAuthError(error);\n logAuthFailure(req, authErr);\n return sendAuthenticationError(res, authErr);\n }\n}\n\n@Injectable()\n/** Nest service behind the Express-compatible `authorizeAccessi` middleware. */\nexport class AuthenticateGenService {\n constructor(\n @Inject(\"ACCESSI_OPTIONS\")\n private readonly accessiOptions: AccessiOptions,\n private readonly permissionService: PermissionService,\n private readonly userService: UserService\n ) { }\n\n /**\n * Verifica JWT, stato corrente dell'utente e policy opzionale, poi popola `req.user` e `req.data`.\n * Se una policy richiede grant, popola anche `req.userGrants`; non chiamarlo direttamente fuori da test o adapter.\n */\n async authorize(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n ) {\n return authorizeWithDependencies(\n req,\n res,\n next,\n options,\n this.accessiOptions,\n this.permissionService,\n this.userService\n );\n }\n}\n\nlet authenticateGenServiceRef: AuthenticateGenService | null = null;\nlet authServiceBootstrapDeferred: Deferred<AuthenticateGenService> | null = null;\n\nfunction createDeferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (reason?: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\nfunction isAuthenticateGenService(value: unknown): value is AuthenticateGenService {\n return Boolean(\n value &&\n typeof (value as { authorize?: unknown }).authorize === \"function\"\n );\n}\n\n/** Segnala al middleware che il bootstrap e in corso, consentendo una risposta 503 temporanea invece di un 500. */\nexport function beginAccessiAuthInitialization() {\n if (!authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred = createDeferred<AuthenticateGenService>();\n }\n}\n\n/** Registra il servizio costruito da Nest nel bridge usato dalle rotte Express dell'app ospitante. */\nexport function setAccessiAuthService(service: AuthenticateGenService) {\n authenticateGenServiceRef = service;\n (globalThis as Record<symbol, unknown>)[ACCESSI_AUTH_SERVICE_GLOBAL_KEY] = service;\n if (authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred.resolve(service);\n authServiceBootstrapDeferred = null;\n }\n}\n\n/** Propaga il fallimento del bootstrap alle richieste che stavano attendendo il bridge di autorizzazione. */\nexport function failAccessiAuthInitialization(error: unknown) {\n if (authServiceBootstrapDeferred) {\n authServiceBootstrapDeferred.reject(error);\n authServiceBootstrapDeferred = null;\n }\n}\n\nfunction getAccessiAuthServiceFromRequest(req: Request): AuthenticateGenService | null {\n const appLocalsService = (req.app?.locals as Record<string, unknown> | undefined)?.[\n ACCESSI_AUTH_SERVICE_LOCALS_KEY\n ];\n\n if (isAuthenticateGenService(appLocalsService)) {\n return appLocalsService as AuthenticateGenService;\n }\n\n const globalService = (globalThis as Record<symbol, unknown>)[\n ACCESSI_AUTH_SERVICE_GLOBAL_KEY\n ];\n if (isAuthenticateGenService(globalService)) {\n return globalService as AuthenticateGenService;\n }\n\n return authenticateGenServiceRef;\n}\n\nasync function waitForBootstrappedService(): Promise<AuthenticateGenService | null> {\n if (!authServiceBootstrapDeferred) {\n return null;\n }\n\n const bootstrapPromise = authServiceBootstrapDeferred.promise;\n const timeoutPromise = new Promise<null>((resolve) => {\n setTimeout(() => resolve(null), ACCESSI_AUTH_SERVICE_WAIT_MS);\n });\n\n try {\n const resolved = await Promise.race([bootstrapPromise, timeoutPromise]);\n return isAuthenticateGenService(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\nasync function resolveAccessiAuthService(req: Request): Promise<AuthenticateGenService | null> {\n const immediateService = getAccessiAuthServiceFromRequest(req);\n if (immediateService) {\n return immediateService;\n }\n\n const bootstrappedService = await waitForBootstrappedService();\n if (bootstrappedService) {\n return bootstrappedService;\n }\n\n return getAccessiAuthServiceFromRequest(req);\n}\n\n/**\n * Middleware Express pubblico di Accessi.\n *\n * Applicarlo dopo `initializeAccessiModule`: legge `Authorization: Bearer <jwt>`, verifica l'utente corrente\n * e applica eventuali requisiti. Su successo valorizza `req.user` e continua; su errore risponde direttamente\n * con il contratto Accessi, quindi il chiamante non deve aggiungere un proprio `next(error)`.\n */\nexport async function authorizeAccessi(\n req: Request,\n res: Response,\n next: NextFunction,\n options?: AccessiAuthorizationOptions\n) {\n const authService = await resolveAccessiAuthService(req);\n\n if (!authService) {\n const status = authServiceBootstrapDeferred ? 503 : 500;\n const code = authServiceBootstrapDeferred\n ? 'ACCESSI_AUTH_INITIALIZING'\n : 'ACCESSI_AUTH_NOT_INITIALIZED';\n logger.error(\n `Authentication service not initialized ${JSON.stringify({\n method: req.method,\n path: req.originalUrl ?? req.url,\n status,\n })}`\n );\n return res.status(status).json({\n severity: 'error',\n status,\n statusCode: 2,\n code,\n error: code,\n message: status === 503\n ? 'Il modulo Accessi e in inizializzazione. Riprova tra poco.'\n : 'Il modulo Accessi non e disponibile.',\n });\n }\n\n return authService.authorize(req, res, next, options);\n}\n\n/** Alias storico di `authorizeAccessi`, mantenuto per retrocompatibilita. Preferire il nome esplicito nelle nuove integrazioni. */\nexport const authenticateGen = authorizeAccessi;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessControl.js","sourceRoot":"","sources":["../../../src/accessi-module/security/accessControl.ts"],"names":[],"mappings":";;AAmBA,kEAoBC;AAGD,0CAOC;AAGD,sDAUC;AAGD,4DAoBC;AArFD,2CAA2E;AAW3E,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAAC,GAAY;;IACtD,MAAM,OAAO,GAAI,GAAoC,CAAC,IAAI,CAAC;IAC3D,MAAM,aAAa,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAkC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9G,MAAM,QAAQ,GAAG,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,QAAQ,KAAI,OAAO,aAAa,CAAC,QAAQ,KAAK,QAAQ;QACpF,CAAC,CAAC,aAAa,CAAC,QAAmC;QACnD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,OAAO,GAAG,MAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,mCAAI,aAAa,CAAC;IAC3E,MAAM,MAAM,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAkC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,YAAY,CAAC,CAAC;IAElD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,8BAAqB,CAAC,yBAAyB,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACnE,SAAS,EAAE,oBAAoB,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS,CAAC;QAClD,qBAAqB,EAAE,oBAAoB,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,qBAAqB,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,SAAgB,eAAe,CAC7B,IAA8B,EAC9B,OAAO,GAAG,2CAA2C;IAErD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,2BAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAgB,qBAAqB,CACnC,IAA8B,EAC9B,cAAsB,EACtB,OAAO,GAAG,8CAA8C;IAExD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;QAC3D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,2BAAkB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,4FAA4F;AAC5F,SAAgB,wBAAwB,CAAC,IASxC;IACC,OAAO,CACL,IAAI,CAAC,kBAAkB,KAAK,SAAS;QACrC,IAAI,CAAC,SAAS,KAAK,SAAS;QAC5B,IAAI,CAAC,qBAAqB,KAAK,SAAS;QACxC,IAAI,CAAC,oBAAoB,KAAK,SAAS;QACvC,IAAI,CAAC,wBAAwB,KAAK,SAAS;QAC3C,IAAI,CAAC,cAAc,KAAK,SAAS;QACjC,IAAI,CAAC,KAAK,KAAK,SAAS;QACxB,IAAI,CAAC,WAAW,KAAK,SAAS,CAC/B,CAAC;AACJ,CAAC","sourcesContent":["import { ForbiddenException, UnauthorizedException } from '@nestjs/common';\
|
|
1
|
+
{"version":3,"file":"accessControl.js","sourceRoot":"","sources":["../../../src/accessi-module/security/accessControl.ts"],"names":[],"mappings":";;AAmBA,kEAoBC;AAGD,0CAOC;AAGD,sDAUC;AAGD,4DAoBC;AArFD,2CAA2E;AAW3E,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAAC,GAAY;;IACtD,MAAM,OAAO,GAAI,GAAoC,CAAC,IAAI,CAAC;IAC3D,MAAM,aAAa,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAkC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9G,MAAM,QAAQ,GAAG,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,QAAQ,KAAI,OAAO,aAAa,CAAC,QAAQ,KAAK,QAAQ;QACpF,CAAC,CAAC,aAAa,CAAC,QAAmC;QACnD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,OAAO,GAAG,MAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,mCAAI,aAAa,CAAC;IAC3E,MAAM,MAAM,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAkC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,YAAY,CAAC,CAAC;IAElD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,8BAAqB,CAAC,yBAAyB,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACnE,SAAS,EAAE,oBAAoB,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS,CAAC;QAClD,qBAAqB,EAAE,oBAAoB,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,qBAAqB,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,SAAgB,eAAe,CAC7B,IAA8B,EAC9B,OAAO,GAAG,2CAA2C;IAErD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,2BAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAgB,qBAAqB,CACnC,IAA8B,EAC9B,cAAsB,EACtB,OAAO,GAAG,8CAA8C;IAExD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;QAC3D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,2BAAkB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,4FAA4F;AAC5F,SAAgB,wBAAwB,CAAC,IASxC;IACC,OAAO,CACL,IAAI,CAAC,kBAAkB,KAAK,SAAS;QACrC,IAAI,CAAC,SAAS,KAAK,SAAS;QAC5B,IAAI,CAAC,qBAAqB,KAAK,SAAS;QACxC,IAAI,CAAC,oBAAoB,KAAK,SAAS;QACvC,IAAI,CAAC,wBAAwB,KAAK,SAAS;QAC3C,IAAI,CAAC,cAAc,KAAK,SAAS;QACjC,IAAI,CAAC,KAAK,KAAK,SAAS;QACxB,IAAI,CAAC,WAAW,KAAK,SAAS,CAC/B,CAAC;AACJ,CAAC","sourcesContent":["import { ForbiddenException, UnauthorizedException } from '@nestjs/common';\nimport { Request } from 'express';\n\n/** Profilo autorizzativo normalizzato estratto dal middleware Accessi. */\nexport interface AuthenticatedAccessiUser {\n codiceUtente: number;\n email?: string;\n flagSuper: boolean;\n flagAdminConfigurator: boolean;\n}\n\nfunction normalizeBooleanFlag(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n}\n\n/**\n * Estrae l'utente gia verificato da `authorizeAccessi` o `JwtSimpleGuard`.\n * Non usare questa funzione come autenticazione: se il middleware non e stato applicato genera 401.\n */\nexport function getAuthenticatedAccessiUser(req: Request): AuthenticatedAccessiUser {\n const payload = (req as Request & { user?: unknown }).user;\n const payloadRecord = payload && typeof payload === 'object' ? payload as Record<string, unknown> : undefined;\n const userData = payloadRecord?.userData && typeof payloadRecord.userData === 'object'\n ? payloadRecord.userData as Record<string, unknown>\n : undefined;\n const rawUser = payloadRecord?.utente ?? userData?.utente ?? payloadRecord;\n const utente = rawUser && typeof rawUser === 'object' ? rawUser as Record<string, unknown> : undefined;\n const codiceUtente = Number(utente?.codiceUtente);\n\n if (!Number.isSafeInteger(codiceUtente) || codiceUtente <= 0) {\n throw new UnauthorizedException('Utente non autenticato.');\n }\n\n return {\n codiceUtente,\n email: typeof utente?.email === 'string' ? utente.email : undefined,\n flagSuper: normalizeBooleanFlag(utente?.flagSuper),\n flagAdminConfigurator: normalizeBooleanFlag(utente?.flagAdminConfigurator),\n };\n}\n\n/** Impone il flag superutente, necessario per configurazione globale, utenti e catalogo SSO. */\nexport function ensureSuperUser(\n user: AuthenticatedAccessiUser,\n message = 'Operazione riservata agli amministratori.',\n): void {\n if (!user.flagSuper) {\n throw new ForbiddenException(message);\n }\n}\n\n/** Permette l'operazione al proprietario della risorsa o a un superutente. */\nexport function ensureSelfOrSuperUser(\n user: AuthenticatedAccessiUser,\n targetUserCode: number,\n message = 'Operazione non autorizzata su questo utente.',\n): void {\n if (user.flagSuper || user.codiceUtente === targetUserCode) {\n return;\n }\n\n throw new ForbiddenException(message);\n}\n\n/** Riconosce i campi che non possono essere aggiornati da un utente sul proprio profilo. */\nexport function hasPrivilegedUserChanges(user: {\n statoRegistrazione?: unknown;\n flagSuper?: unknown;\n flagAdminConfigurator?: unknown;\n passwordLoginEnabled?: unknown;\n passwordlessLoginEnabled?: unknown;\n flagDueFattori?: unknown;\n roles?: unknown;\n permissions?: unknown;\n}): boolean {\n return (\n user.statoRegistrazione !== undefined ||\n user.flagSuper !== undefined ||\n user.flagAdminConfigurator !== undefined ||\n user.passwordLoginEnabled !== undefined ||\n user.passwordlessLoginEnabled !== undefined ||\n user.flagDueFattori !== undefined ||\n user.roles !== undefined ||\n user.permissions !== undefined\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticatedToken.js","sourceRoot":"","sources":["../../../src/accessi-module/security/authenticatedToken.ts"],"names":[],"mappings":"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","sourcesContent":["import { StatoRegistrazione } from '../Dtos/StatoRegistrazione';\
|
|
1
|
+
{"version":3,"file":"authenticatedToken.js","sourceRoot":"","sources":["../../../src/accessi-module/security/authenticatedToken.ts"],"names":[],"mappings":"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","sourcesContent":["import { StatoRegistrazione } from '../Dtos/StatoRegistrazione';\n\n/** Stato autorevole minimo riletto dal database per ogni verifica JWT. */\nexport interface AccessiAuthenticatedUserSnapshot {\n codiceUtente: number;\n email?: string;\n statoRegistrazione: StatoRegistrazione;\n flagSuper: boolean;\n flagAdminConfigurator: boolean;\n flagDueFattori?: boolean;\n passwordlessLoginEnabled?: boolean;\n passwordLoginEnabled?: boolean;\n}\n\nfunction normalizeBooleanFlag(value: unknown): boolean {\n return value === true || value === 1 || value === '1';\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/** Shared, strict Bearer parsing for the Nest guard and Express middleware. */\nexport function extractAccessiBearerToken(header: unknown): string | undefined {\n if (typeof header !== 'string') return undefined;\n return /^Bearer[ \\t]+([^\\s]+)$/i.exec(header.trim())?.[1];\n}\n\n/** Estrae il codice utente sia dai JWT Accessi moderni sia dai payload legacy compatibili. */\nexport function resolveCodiceUtenteFromTokenPayload(decoded: unknown): number | undefined {\n // `typ` obbligatorio: un token senza tipo non e un access token Accessi.\n if (!isRecord(decoded) || decoded.typ !== 'access') {\n return undefined;\n }\n\n const userData = isRecord(decoded.userData) ? decoded.userData : undefined;\n const utente = isRecord(decoded.utente)\n ? decoded.utente\n : isRecord(userData?.utente)\n ? userData.utente\n : undefined;\n\n const codiceUtente = Number(utente?.codiceUtente ?? decoded.codiceUtente);\n if (!Number.isSafeInteger(codiceUtente) || codiceUtente <= 0) {\n return undefined;\n }\n\n return codiceUtente;\n}\n\n/**\n * Mantiene le claim estranee al modulo ma sovrascrive il profilo con valori correnti e autorevoli dal database.\n * `tokenPayload` conserva il payload verificato originale per audit o integrazioni che ne abbiano necessita.\n */\nexport function buildAuthenticatedTokenPayload(\n decoded: unknown,\n utente: AccessiAuthenticatedUserSnapshot,\n): Record<string, unknown> {\n const basePayload = isRecord(decoded) ? { ...decoded } : {};\n const userData = isRecord(basePayload.userData) ? { ...basePayload.userData } : {};\n\n const normalizedUser = {\n ...utente,\n flagSuper: normalizeBooleanFlag(utente.flagSuper),\n flagAdminConfigurator: normalizeBooleanFlag(utente.flagAdminConfigurator),\n flagDueFattori: normalizeBooleanFlag(utente.flagDueFattori),\n passwordlessLoginEnabled: normalizeBooleanFlag(utente.passwordlessLoginEnabled),\n };\n\n return {\n ...basePayload,\n codiceUtente: normalizedUser.codiceUtente,\n email: normalizedUser.email,\n statoRegistrazione: normalizedUser.statoRegistrazione,\n flagSuper: normalizedUser.flagSuper,\n flagAdminConfigurator: normalizedUser.flagAdminConfigurator,\n flagDueFattori: normalizedUser.flagDueFattori,\n passwordlessLoginEnabled: normalizedUser.passwordlessLoginEnabled,\n passwordLoginEnabled: normalizedUser.passwordLoginEnabled,\n utente: normalizedUser,\n userData: {\n ...userData,\n utente: normalizedUser,\n },\n tokenPayload: decoded,\n };\n}\n\n/** Enabling 2FA invalidates sessions which have not completed the required verification. */\nexport function isAccessiTokenAllowedForUser(decoded: unknown, user: AccessiAuthenticatedUserSnapshot): boolean {\n if (!isRecord(decoded)) return false;\n const methods = Array.isArray(decoded.amr) ? decoded.amr : [];\n if (user.flagDueFattori && !methods.includes('otp')) return false;\n if (methods.includes('passwordless') && (!user.flagDueFattori || !user.passwordlessLoginEnabled)) return false;\n return true;\n}\n\n/** Un JWT puo essere usato soltanto da utenti nello stato confermato, indipendentemente dalla sua scadenza. */\nexport function isAuthenticatedUserEnabledForJwt(\n utente: AccessiAuthenticatedUserSnapshot | null | undefined,\n): utente is AccessiAuthenticatedUserSnapshot {\n return utente?.statoRegistrazione === StatoRegistrazione.CONF;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passwordResetToken.js","sourceRoot":"","sources":["../../../src/accessi-module/security/passwordResetToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,kDAOC;AAGD,4DAqBC;AAGD,4DAeC;AApED,kDAAoC;AACpC,mCAAoC;AAGpC,mHAAmH;AACtG,QAAA,iCAAiC,GAAG,IAAI,CAAC;AAUtD;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,OAAuB,EAAE,UAA6B,QAAQ;;IAChG,MAAM,MAAM,GAAG,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,0CAAE,MAAM,KAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACzE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,eAAe,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,oHAAoH;AACpH,SAAgB,wBAAwB,CACtC,YAAoB,EACpB,KAAa,EACb,MAAc,EACd,YAA0C,yCAAiC;IAE3E,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CACb;QACE,KAAK;QACL,GAAG,EAAE,gBAAgB;KACtB,EACD,MAAM,EACN;QACE,OAAO,EAAE,GAAG,YAAY,EAAE;QAC1B,SAAS;KACV,CACF,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,SAAgB,wBAAwB,CACtC,KAAa,EACb,MAAc;IAEd,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAA8B,CAAC;IAClG,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,CAAC;IAE1C,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,MAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,OAAO,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAA,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1J,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC","sourcesContent":["import * as jwt from 'jsonwebtoken';\
|
|
1
|
+
{"version":3,"file":"passwordResetToken.js","sourceRoot":"","sources":["../../../src/accessi-module/security/passwordResetToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,kDAOC;AAGD,4DAqBC;AAGD,4DAeC;AApED,kDAAoC;AACpC,mCAAoC;AAGpC,mHAAmH;AACtG,QAAA,iCAAiC,GAAG,IAAI,CAAC;AAUtD;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,OAAuB,EAAE,UAA6B,QAAQ;;IAChG,MAAM,MAAM,GAAG,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,0CAAE,MAAM,KAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACzE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,eAAe,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,oHAAoH;AACpH,SAAgB,wBAAwB,CACtC,YAAoB,EACpB,KAAa,EACb,MAAc,EACd,YAA0C,yCAAiC;IAE3E,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CACb;QACE,KAAK;QACL,GAAG,EAAE,gBAAgB;KACtB,EACD,MAAM,EACN;QACE,OAAO,EAAE,GAAG,YAAY,EAAE;QAC1B,SAAS;KACV,CACF,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,SAAgB,wBAAwB,CACtC,KAAa,EACb,MAAc;IAEd,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAA8B,CAAC;IAClG,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,CAAC;IAE1C,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,MAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,OAAO,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAA,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1J,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC","sourcesContent":["import * as jwt from 'jsonwebtoken';\nimport { createHmac } from 'crypto';\nimport type { AccessiOptions } from '../AccessiModule';\n\n/** Durata predefinita del token di reset. La monouso e garantita anche dal nonce persistito in `UTENTI.KEYREG`. */\nexport const DEFAULT_PASSWORD_RESET_EXPIRES_IN = '1h';\n\ninterface PasswordResetTokenPayload extends jwt.JwtPayload {\n nonce: string;\n typ: 'password-reset';\n}\n\n/** Scopo della chiave derivata: separa le chiavi di access token, reset password e 2FA. */\nexport type AccessiJwtPurpose = 'access' | 'reset' | '2fa';\n\n/**\n * Deriva una chiave JWT per scopo dal segreto configurato (key separation senza nuova configurazione).\n * Un leak della chiave di reset non compromette gli access token e viceversa.\n */\nexport function getAccessiJwtSecret(options: AccessiOptions, purpose: AccessiJwtPurpose = 'access'): string {\n const secret = options?.jwtOptions?.secret || process.env.ACC_JWT_SECRET;\n if (!secret) {\n throw new Error('JWT secret non configurato.');\n }\n\n return createHmac('sha256', secret).update(`accessi:jwt:${purpose}:v1`).digest('hex');\n}\n\n/** Crea un token firmato contenente solo codice utente e nonce; non inserire email o dati personali nelle claim. */\nexport function createPasswordResetToken(\n codiceUtente: number,\n nonce: string,\n secret: string,\n expiresIn: jwt.SignOptions['expiresIn'] = DEFAULT_PASSWORD_RESET_EXPIRES_IN,\n): string {\n if (!codiceUtente || !nonce) {\n throw new Error('Dati insufficienti per generare il reset token.');\n }\n\n return jwt.sign(\n {\n nonce,\n typ: 'password-reset',\n },\n secret,\n {\n subject: `${codiceUtente}`,\n expiresIn,\n },\n );\n}\n\n/** Verifica firma e scadenza, quindi restituisce i dati minimi necessari al reset. */\nexport function verifyPasswordResetToken(\n token: string,\n secret: string,\n): { codiceUtente: number; nonce: string } {\n const decoded = jwt.verify(token, secret, { algorithms: ['HS256'] }) as PasswordResetTokenPayload;\n const codiceUtente = Number(decoded?.sub);\n\n if (decoded?.typ !== 'password-reset' || !Number.isSafeInteger(codiceUtente) || codiceUtente <= 0 || typeof decoded?.nonce !== 'string' || !decoded.nonce) {\n throw new Error('Token di reset non valido.');\n }\n\n return {\n codiceUtente,\n nonce: decoded.nonce,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicAuthRateLimit.js","sourceRoot":"","sources":["../../../src/accessi-module/security/publicAuthRateLimit.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpStatus } from '@nestjs/common';\r\nimport { Request, Response } from 'express';\r\nimport { RestUtilities } from '../../Utilities';\r\nimport type { AccessiOptions, PublicAuthRateLimitRuleOptions } from '../AccessiModule';\r\n\r\nexport type PublicAuthRateLimitScope =\r\n | 'login'\r\n | 'twoFactorVerify'\r\n | 'twoFactorResend'\r\n | 'register'\r\n | 'passwordResetEmail'\r\n | 'passwordResetConfirm'\r\n | 'getUserByToken';\r\n\r\ntype RateLimitBucket = {\r\n count: number;\r\n resetAt: number;\r\n lastSeenAt: number;\r\n};\r\n\r\ntype RateLimitDecision = {\r\n allowed: boolean;\r\n retryAfterSeconds: number;\r\n};\r\n\r\nconst DEFAULT_PUBLIC_AUTH_RATE_LIMITS: Record<\r\n PublicAuthRateLimitScope,\r\n PublicAuthRateLimitRuleOptions\r\n> = {\r\n login: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\r\n twoFactorVerify: { windowMs: 15 * 60 * 1000, maxAttempts: 20 },\r\n twoFactorResend: { windowMs: 15 * 60 * 1000, maxAttempts: 5 },\r\n register: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },\r\n passwordResetEmail: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },\r\n passwordResetConfirm: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\r\n getUserByToken: { windowMs: 5 * 60 * 1000, maxAttempts: 30 },\r\n};\r\n\r\nconst RATE_LIMIT_BUCKETS = new Map<string, RateLimitBucket>();\r\nconst MAX_TRACKED_BUCKETS = 20000;\r\nconst MAX_WINDOW_MS = Math.max(\r\n ...Object.values(DEFAULT_PUBLIC_AUTH_RATE_LIMITS).map((rule) => rule.windowMs),\r\n);\r\n\r\nfunction getRule(\r\n options: AccessiOptions,\r\n scope: PublicAuthRateLimitScope,\r\n): PublicAuthRateLimitRuleOptions {\r\n const configuredRule = options.publicAuthRateLimit?.[scope];\r\n\r\n if (\r\n configuredRule &&\r\n Number.isFinite(configuredRule.windowMs) &&\r\n configuredRule.windowMs > 0 &&\r\n Number.isFinite(configuredRule.maxAttempts) &&\r\n configuredRule.maxAttempts > 0\r\n ) {\r\n return {\r\n windowMs: Math.trunc(configuredRule.windowMs),\r\n maxAttempts: Math.trunc(configuredRule.maxAttempts),\r\n };\r\n }\r\n\r\n return DEFAULT_PUBLIC_AUTH_RATE_LIMITS[scope];\r\n}\r\n\r\nfunction normalizeIdentifier(identifier: string): string | null {\r\n if (typeof identifier !== 'string') {\r\n return null;\r\n }\r\n\r\n const normalized = identifier.trim().toLowerCase();\r\n return normalized === '' ? null : normalized;\r\n}\r\n\r\nfunction pruneRateLimitBuckets(now: number): void {\r\n if (RATE_LIMIT_BUCKETS.size < MAX_TRACKED_BUCKETS) {\r\n return;\r\n }\r\n\r\n for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {\r\n if (bucket.resetAt <= now || bucket.lastSeenAt <= now - MAX_WINDOW_MS * 2) {\r\n RATE_LIMIT_BUCKETS.delete(key);\r\n }\r\n\r\n if (RATE_LIMIT_BUCKETS.size < MAX_TRACKED_BUCKETS) {\r\n return;\r\n }\r\n }\r\n}\r\n\r\n/** Mantiene il numero di bucket sotto la soglia, scartando i meno recenti. */\r\nfunction enforceBucketCap(): void {\r\n while (RATE_LIMIT_BUCKETS.size >= MAX_TRACKED_BUCKETS) {\r\n let oldestKey: string | undefined;\r\n let oldestSeen = Number.POSITIVE_INFINITY;\r\n\r\n for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {\r\n if (bucket.lastSeenAt < oldestSeen) {\r\n oldestSeen = bucket.lastSeenAt;\r\n oldestKey = key;\r\n }\r\n }\r\n\r\n if (oldestKey === undefined) {\r\n return;\r\n }\r\n\r\n RATE_LIMIT_BUCKETS.delete(oldestKey);\r\n }\r\n}\r\n\r\nfunction consumeBucket(\r\n bucketKey: string,\r\n rule: PublicAuthRateLimitRuleOptions,\r\n now: number,\r\n): number | null {\r\n const existingBucket = RATE_LIMIT_BUCKETS.get(bucketKey);\r\n if (!existingBucket || existingBucket.resetAt <= now) {\r\n enforceBucketCap();\r\n RATE_LIMIT_BUCKETS.set(bucketKey, {\r\n count: 1,\r\n resetAt: now + rule.windowMs,\r\n lastSeenAt: now,\r\n });\r\n return null;\r\n }\r\n\r\n existingBucket.lastSeenAt = now;\r\n if (existingBucket.count >= rule.maxAttempts) {\r\n return Math.max(1, Math.ceil((existingBucket.resetAt - now) / 1000));\r\n }\r\n\r\n existingBucket.count += 1;\r\n return null;\r\n}\r\n\r\nexport function checkPublicAuthRateLimit(\r\n options: AccessiOptions,\r\n scope: PublicAuthRateLimitScope,\r\n req: Request,\r\n identifiers: string[] = [],\r\n): RateLimitDecision {\r\n if (options.publicAuthRateLimit?.enabled === false) {\r\n return { allowed: true, retryAfterSeconds: 0 };\r\n }\r\n\r\n const rule = getRule(options, scope);\r\n const now = Date.now();\r\n pruneRateLimitBuckets(now);\r\n\r\n const ipAddress =\r\n normalizeIdentifier(req.ip ?? req.socket?.remoteAddress ?? 'unknown') ?? 'unknown';\r\n\r\n // Consuma prima il bucket per IP: se gia bloccato non crea bucket per soggetto,\r\n // evitando crescita di memoria con identificatori sempre diversi.\r\n const ipRetryAfterSeconds = consumeBucket(`${scope}|ip|${ipAddress}`, rule, now);\r\n if (ipRetryAfterSeconds) {\r\n return { allowed: false, retryAfterSeconds: ipRetryAfterSeconds };\r\n }\r\n\r\n let retryAfterSeconds = 0;\r\n for (const identifier of identifiers) {\r\n const normalizedIdentifier = normalizeIdentifier(identifier);\r\n if (!normalizedIdentifier) {\r\n continue;\r\n }\r\n\r\n const bucketRetryAfterSeconds = consumeBucket(\r\n `${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`,\r\n rule,\r\n now,\r\n );\r\n if (bucketRetryAfterSeconds) {\r\n retryAfterSeconds = Math.max(retryAfterSeconds, bucketRetryAfterSeconds);\r\n }\r\n }\r\n\r\n if (retryAfterSeconds > 0) {\r\n return {\r\n allowed: false,\r\n retryAfterSeconds,\r\n };\r\n }\r\n\r\n return { allowed: true, retryAfterSeconds: 0 };\r\n}\r\n\r\nexport function sendPublicAuthRateLimitExceeded(\r\n res: Response,\r\n retryAfterSeconds: number,\r\n): Response {\r\n res.setHeader('Retry-After', String(retryAfterSeconds));\r\n return RestUtilities.sendErrorMessage(\r\n res,\r\n 'Troppi tentativi. Riprova piu tardi.',\r\n 'PublicAuthRateLimit',\r\n HttpStatus.TOO_MANY_REQUESTS,\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"publicAuthRateLimit.js","sourceRoot":"","sources":["../../../src/accessi-module/security/publicAuthRateLimit.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpStatus } from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions, PublicAuthRateLimitRuleOptions } from '../AccessiModule';\n\nexport type PublicAuthRateLimitScope =\n | 'login'\n | 'twoFactorVerify'\n | 'twoFactorResend'\n | 'register'\n | 'passwordResetEmail'\n | 'passwordResetConfirm'\n | 'getUserByToken';\n\ntype RateLimitBucket = {\n count: number;\n resetAt: number;\n lastSeenAt: number;\n};\n\ntype RateLimitDecision = {\n allowed: boolean;\n retryAfterSeconds: number;\n};\n\nconst DEFAULT_PUBLIC_AUTH_RATE_LIMITS: Record<\n PublicAuthRateLimitScope,\n PublicAuthRateLimitRuleOptions\n> = {\n login: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\n twoFactorVerify: { windowMs: 15 * 60 * 1000, maxAttempts: 20 },\n twoFactorResend: { windowMs: 15 * 60 * 1000, maxAttempts: 5 },\n register: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },\n passwordResetEmail: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },\n passwordResetConfirm: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\n getUserByToken: { windowMs: 5 * 60 * 1000, maxAttempts: 30 },\n};\n\nconst RATE_LIMIT_BUCKETS = new Map<string, RateLimitBucket>();\nconst MAX_TRACKED_BUCKETS = 20000;\nconst MAX_WINDOW_MS = Math.max(\n ...Object.values(DEFAULT_PUBLIC_AUTH_RATE_LIMITS).map((rule) => rule.windowMs),\n);\n\nfunction getRule(\n options: AccessiOptions,\n scope: PublicAuthRateLimitScope,\n): PublicAuthRateLimitRuleOptions {\n const configuredRule = options.publicAuthRateLimit?.[scope];\n\n if (\n configuredRule &&\n Number.isFinite(configuredRule.windowMs) &&\n configuredRule.windowMs > 0 &&\n Number.isFinite(configuredRule.maxAttempts) &&\n configuredRule.maxAttempts > 0\n ) {\n return {\n windowMs: Math.trunc(configuredRule.windowMs),\n maxAttempts: Math.trunc(configuredRule.maxAttempts),\n };\n }\n\n return DEFAULT_PUBLIC_AUTH_RATE_LIMITS[scope];\n}\n\nfunction normalizeIdentifier(identifier: string): string | null {\n if (typeof identifier !== 'string') {\n return null;\n }\n\n const normalized = identifier.trim().toLowerCase();\n return normalized === '' ? null : normalized;\n}\n\nfunction pruneRateLimitBuckets(now: number): void {\n if (RATE_LIMIT_BUCKETS.size < MAX_TRACKED_BUCKETS) {\n return;\n }\n\n for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {\n if (bucket.resetAt <= now || bucket.lastSeenAt <= now - MAX_WINDOW_MS * 2) {\n RATE_LIMIT_BUCKETS.delete(key);\n }\n\n if (RATE_LIMIT_BUCKETS.size < MAX_TRACKED_BUCKETS) {\n return;\n }\n }\n}\n\n/** Mantiene il numero di bucket sotto la soglia, scartando i meno recenti. */\nfunction enforceBucketCap(): void {\n while (RATE_LIMIT_BUCKETS.size >= MAX_TRACKED_BUCKETS) {\n let oldestKey: string | undefined;\n let oldestSeen = Number.POSITIVE_INFINITY;\n\n for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {\n if (bucket.lastSeenAt < oldestSeen) {\n oldestSeen = bucket.lastSeenAt;\n oldestKey = key;\n }\n }\n\n if (oldestKey === undefined) {\n return;\n }\n\n RATE_LIMIT_BUCKETS.delete(oldestKey);\n }\n}\n\nfunction consumeBucket(\n bucketKey: string,\n rule: PublicAuthRateLimitRuleOptions,\n now: number,\n): number | null {\n const existingBucket = RATE_LIMIT_BUCKETS.get(bucketKey);\n if (!existingBucket || existingBucket.resetAt <= now) {\n enforceBucketCap();\n RATE_LIMIT_BUCKETS.set(bucketKey, {\n count: 1,\n resetAt: now + rule.windowMs,\n lastSeenAt: now,\n });\n return null;\n }\n\n existingBucket.lastSeenAt = now;\n if (existingBucket.count >= rule.maxAttempts) {\n return Math.max(1, Math.ceil((existingBucket.resetAt - now) / 1000));\n }\n\n existingBucket.count += 1;\n return null;\n}\n\nexport function checkPublicAuthRateLimit(\n options: AccessiOptions,\n scope: PublicAuthRateLimitScope,\n req: Request,\n identifiers: string[] = [],\n): RateLimitDecision {\n if (options.publicAuthRateLimit?.enabled === false) {\n return { allowed: true, retryAfterSeconds: 0 };\n }\n\n const rule = getRule(options, scope);\n const now = Date.now();\n pruneRateLimitBuckets(now);\n\n const ipAddress =\n normalizeIdentifier(req.ip ?? req.socket?.remoteAddress ?? 'unknown') ?? 'unknown';\n\n // Consuma prima il bucket per IP: se gia bloccato non crea bucket per soggetto,\n // evitando crescita di memoria con identificatori sempre diversi.\n const ipRetryAfterSeconds = consumeBucket(`${scope}|ip|${ipAddress}`, rule, now);\n if (ipRetryAfterSeconds) {\n return { allowed: false, retryAfterSeconds: ipRetryAfterSeconds };\n }\n\n let retryAfterSeconds = 0;\n for (const identifier of identifiers) {\n const normalizedIdentifier = normalizeIdentifier(identifier);\n if (!normalizedIdentifier) {\n continue;\n }\n\n const bucketRetryAfterSeconds = consumeBucket(\n `${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`,\n rule,\n now,\n );\n if (bucketRetryAfterSeconds) {\n retryAfterSeconds = Math.max(retryAfterSeconds, bucketRetryAfterSeconds);\n }\n }\n\n if (retryAfterSeconds > 0) {\n return {\n allowed: false,\n retryAfterSeconds,\n };\n }\n\n return { allowed: true, retryAfterSeconds: 0 };\n}\n\nexport function sendPublicAuthRateLimitExceeded(\n res: Response,\n retryAfterSeconds: number,\n): Response {\n res.setHeader('Retry-After', String(retryAfterSeconds));\n return RestUtilities.sendErrorMessage(\n res,\n 'Troppi tentativi. Riprova piu tardi.',\n 'PublicAuthRateLimit',\n HttpStatus.TOO_MANY_REQUESTS,\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllegatiModule.js","sourceRoot":"","sources":["../../src/allegati-module/AllegatiModule.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAG/D,sCAAmC;AACnC,gFAA6E;AAC7E,yEAAsE;AACtE,sFAAmF;AAsB5E,IAAM,cAAc,sBAApB,MAAM,cAAc;IAEvB,MAAM,CAAC,OAAO,CAAC,OAAwB;QACnC,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,gBAAc,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,MAAK,KAAK,EAAE,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,yJAAyJ,CAAC,CAAC;QAC9K,CAAC;aAAM,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,CAAA,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,kLAAkL,CAAC,CAAC;QACrM,CAAC;QAED,OAAO;YACH,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE;gBACP;oBACI,OAAO,EAAE,kBAAkB;oBAC3B,QAAQ,EAAE,OAAO;iBACpB;gBACD,iCAAe;gBACf,uDAA0B;aAC7B;YACD,OAAO,EAAE,CAAC,kBAAkB,EAAE,iCAAe,CAAC;SACjD,CAAC;IACN,CAAC;CACJ,CAAA;AAvBY,wCAAc;yBAAd,cAAc;IAN1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACJ,WAAW,EAAE,CAAC,uCAAkB,CAAC;QACjC,SAAS,EAAE,CAAC,iCAAe,EAAE,uDAA0B,CAAC;QACxD,OAAO,EAAE,CAAC,iCAAe,CAAC;KAC7B,CAAC;GACW,cAAc,CAuB1B","sourcesContent":["import { DynamicModule, Global, Module } from \"@nestjs/common\";\
|
|
1
|
+
{"version":3,"file":"AllegatiModule.js","sourceRoot":"","sources":["../../src/allegati-module/AllegatiModule.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAG/D,sCAAmC;AACnC,gFAA6E;AAC7E,yEAAsE;AACtE,sFAAmF;AAsB5E,IAAM,cAAc,sBAApB,MAAM,cAAc;IAEvB,MAAM,CAAC,OAAO,CAAC,OAAwB;QACnC,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,gBAAc,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,MAAK,KAAK,EAAE,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,yJAAyJ,CAAC,CAAC;QAC9K,CAAC;aAAM,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,CAAA,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,kLAAkL,CAAC,CAAC;QACrM,CAAC;QAED,OAAO;YACH,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE;gBACP;oBACI,OAAO,EAAE,kBAAkB;oBAC3B,QAAQ,EAAE,OAAO;iBACpB;gBACD,iCAAe;gBACf,uDAA0B;aAC7B;YACD,OAAO,EAAE,CAAC,kBAAkB,EAAE,iCAAe,CAAC;SACjD,CAAC;IACN,CAAC;CACJ,CAAA;AAvBY,wCAAc;yBAAd,cAAc;IAN1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACJ,WAAW,EAAE,CAAC,uCAAkB,CAAC;QACjC,SAAS,EAAE,CAAC,iCAAe,EAAE,uDAA0B,CAAC;QACxD,OAAO,EAAE,CAAC,iCAAe,CAAC;KAC7B,CAAC;GACW,cAAc,CAuB1B","sourcesContent":["import { DynamicModule, Global, Module } from \"@nestjs/common\";\nimport { Request } from \"express\";\nimport { Options } from \"node-firebird\";\nimport { Logger } from \"../Logger\";\nimport { AllegatiService } from \"./Services/AllegatiService/AllegatiService\";\nimport { AllegatiController } from \"./Controllers/AllegatiController\";\nimport { AllegatiAuthorizationGuard } from \"./security/allegatiAuthorizationGuard\";\n\nexport interface AllegatiOptions {\n databaseOptions: Options;\n /**\n * Guard applicato a ogni richiesta dei controller Allegati.\n * Se definito e restituisce `false`, la richiesta viene rifiutata con 403.\n */\n authorize?: (request: Request) => boolean | Promise<boolean>;\n /**\n * Sicurezza by default: se `authorize` non e configurato, le richieste vengono rifiutate con 403.\n * Impostare `false` per ripristinare il comportamento storico (endpoint aperti) durante la migrazione.\n */\n requireAuthorization?: boolean;\n}\n\n@Global()\n@Module({\n controllers: [AllegatiController],\n providers: [AllegatiService, AllegatiAuthorizationGuard],\n exports: [AllegatiService],\n})\nexport class AllegatiModule {\n\n static forRoot(options: AllegatiOptions): DynamicModule {\n const logger = new Logger(AllegatiModule.name);\n if (options?.requireAuthorization === false) {\n logger.warning('Allegati con requireAuthorization: false: gli endpoint sono accessibili senza controllo di autorizzazione. Configurare authorize e rimuovere l opt-out.');\n } else if (!options?.authorize) {\n logger.error('Allegati senza authorize: tutte le richieste saranno rifiutate con 403. Configurare allegatiOptions.authorize (oppure requireAuthorization: false per il comportamento storico).');\n }\n\n return {\n module: AllegatiModule,\n providers: [\n {\n provide: 'ALLEGATI_OPTIONS',\n useValue: options,\n },\n AllegatiService,\n AllegatiAuthorizationGuard,\n ],\n exports: ['ALLEGATI_OPTIONS', AllegatiService],\n };\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllegatiController.js","sourceRoot":"","sources":["../../../src/allegati-module/Controllers/AllegatiController.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApiBody, ApiConsumes, ApiResponse, ApiQuery} from \"@nestjs/swagger\";\r\n\r\nimport { Controller, Post, Get, Delete, Param, UploadedFiles, UseGuards, UseInterceptors, BadRequestException, Body, Response, Query, Res, Patch } from \"@nestjs/common\";\r\nimport { FilesInterceptor } from \"@nestjs/platform-express\";\r\nimport { AllegatiAuthorizationGuard } from \"../security/allegatiAuthorizationGuard\";\r\nimport { AllegatiService } from \"../Services/AllegatiService/AllegatiService\";\r\nimport {UploadAllegatoResponseDto} from \"../Dtos/responses/UploadAllegatoResponseDto\";\r\nimport {AllegatoDto} from \"../Dtos/AllegatoDto\";\r\nimport {DownloadAllegatoResponseDto} from \"../Dtos/responses/DownloadAllegatoResponseDto\";\r\nimport { UploadSingleFileRequest } from \"../Dtos/UploadSingleFileRequest\";\r\nimport { RestUtilities } from \"../../Utilities\";\r\nimport { Logger } from \"../../Logger\";\r\nimport e from \"express\";\r\n\r\n@UseGuards(AllegatiAuthorizationGuard)\r\n@Controller('allegati')\r\nexport class AllegatiController {\r\n private readonly logger = new Logger(AllegatiController.name);\r\n\r\n constructor(private readonly allegatiService: AllegatiService) {}\r\n\r\n @Post('upload')\r\n @UseInterceptors(FilesInterceptor('file', 1, { limits: { fileSize: 90 * 1024 * 1024, files: 1 } }))\r\n @ApiConsumes('multipart/form-data')\r\n @ApiResponse({ status: 201, description: 'File caricato con successo.', type: UploadAllegatoResponseDto })\r\n @ApiBody({\r\n description: 'File e metadati per l\\'upload di un allegato',\r\n required: true,\r\n schema: {\r\n type: 'object',\r\n properties: {\r\n file: {\r\n type: 'string',\r\n format: 'binary',\r\n },\r\n codice: { type: 'integer', example: 1 },\r\n tipoCodice: { type: 'string', example: 'CF' },\r\n ordine: { type: 'string', example: '1' },\r\n descrizioneAllegato: { type: 'string', example: 'Documento di identità' },\r\n dataInizioValidita: { type: 'string', format: 'date', example: '2024-01-01' },\r\n dataFineValidita: { type: 'string', format: 'date', example: '2025-01-01' },\r\n idTipoAllegato: { type: 'integer', example: 3 },\r\n riferimentoDocumento: { type: 'string', example: 'PRAT-2024-0001' }\r\n },\r\n },\r\n })\r\n async upload(\r\n @UploadedFiles() files: Express.Multer.File[],\r\n @Body() uploadRequest: UploadSingleFileRequest\r\n ): Promise<UploadAllegatoResponseDto> {\r\n if (!files || files.length === 0) {\r\n throw new BadRequestException('Nessun file fornito');\r\n }\r\n if (files.length > 1) {\r\n throw new BadRequestException('Questo endpoint accetta un solo file alla volta');\r\n }\r\n const file = files[0];\r\n if (!file) {\r\n throw new BadRequestException('Nessun file fornito');\r\n }\r\n return await this.allegatiService.uploadFile(file, uploadRequest);\r\n }\r\n\r\n @Get(':id')\r\n @ApiResponse({ status: 200, description: 'File scaricato con successo.', type: DownloadAllegatoResponseDto })\r\n async download(@Param('id') id: number): Promise<DownloadAllegatoResponseDto> {\r\n return await this.allegatiService.downloadFile(id);\r\n }\r\n\r\n @Get(':id/download')\r\n @ApiResponse({ status: 200, description: 'File scaricato con successo.' })\r\n async downloadFile(\r\n @Param('id') id: number,\r\n @Res() res: e.Response\r\n ): Promise<void> {\r\n try {\r\n const file = await this.allegatiService.downloadFile(id);\r\n \r\n // Convert base64 to buffer in chunks; Buffer.concat evita i NUL finali del prealloc.\r\n const chunkSize = 1024 * 1024; // 1MB chunks\r\n const base64Content = file.contentBase64;\r\n const chunks: Buffer[] = [];\r\n for (let i = 0; i < base64Content.length; i += chunkSize) {\r\n const chunk = base64Content.slice(i, i + chunkSize);\r\n chunks.push(Buffer.from(chunk, 'base64'));\r\n }\r\n const buffer = Buffer.concat(chunks);\r\n\r\n // Set headers for file download; filename* (RFC 5987) per i nomi non ASCII.\r\n const asciiName = file.filename.replace(/[^\\x20-\\x7e]/g, '_').replace(/[\"\\\\]/g, '_');\r\n res.setHeader('Content-Type', file.mimetype ?? 'application/octet-stream');\r\n res.setHeader('Content-Disposition', `attachment; filename=\"${asciiName}\"; filename*=UTF-8''${encodeURIComponent(file.filename)}`);\r\n res.setHeader('Content-Length', buffer.length);\r\n \r\n res.status(200).end(buffer);\r\n } catch (error) {\r\n this.logger.error('[AllegatiController] downloadFile - Errore:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n @Delete(':id')\r\n @ApiResponse({ status: 200, description: 'File eliminato con successo.' })\r\n async delete(@Param('id') id: number, @Response() res: e.Response) {\r\n await this.allegatiService.deleteFile(id);\r\n return RestUtilities.sendOKMessage(res, \"File eliminato con successo\");\r\n }\r\n\r\n @Get()\r\n @ApiResponse({ status: 200, description: 'Lista degli allegati.', type: [AllegatoDto] })\r\n @ApiQuery({ name: 'tipcod', required: false, description: 'Filtra per tipo codice' })\r\n @ApiQuery({ name: 'codice', required: false, description: 'Filtra per codice' })\r\n @ApiQuery({ name: 'docrif', required: false, description: 'Filtra per riferimento documento' })\r\n @ApiQuery({ name: 'idxtipoall', required: false, description: 'Filtra per tipo allegato', type: Number })\r\n async list(\r\n @Query('tipcod') tipcod?: string,\r\n @Query('codice') codice?: number,\r\n @Query('docrif') docrif?: string,\r\n @Query('idxtipoall') idxtipoall?: number\r\n ): Promise<AllegatoDto[]> {\r\n return await this.allegatiService.listFiles({\r\n tipcod,\r\n codice,\r\n docrif,\r\n idxtipoall: idxtipoall ? Number(idxtipoall) : undefined\r\n });\r\n }\r\n\r\n @Post('search')\r\n@ApiResponse({ status: 200, description: 'Ricerca allegati per campi.' })\r\nasync searchByFields(@Body() body: { tipcod?: string; codice?: number; docrif?: string; idxtipoall?: number }) {\r\n return await this.allegatiService.findByFields(body);\r\n}\r\n\r\n@Post('get-by-fields')\r\n@ApiResponse({ status: 200, description: 'Ottieni un allegato per campi.' })\r\nasync getOneByFields(@Body() body: { tipcod?: string; codice?: number; docrif?: string; idxtipoall?: number }) {\r\n return await this.allegatiService.getOneByFields(body);\r\n}\r\n\r\n@Patch('update-fields/:id')\r\n@ApiResponse({ status: 200, description: 'Aggiorna i campi di un allegato.' })\r\nasync updateFieldsById(\r\n @Param('id') id: number,\r\n @Body() body: { tipcod?: string; codice?: number; docrif?: string; idxtipoall?: number }\r\n) {\r\n await this.allegatiService.updateFieldsById(Number(id), body);\r\n return { message: 'Aggiornamento completato' };\r\n}\r\n}"]}
|
|
1
|
+
{"version":3,"file":"AllegatiController.js","sourceRoot":"","sources":["../../../src/allegati-module/Controllers/AllegatiController.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApiBody, ApiConsumes, ApiResponse, ApiQuery} from \"@nestjs/swagger\";\n\nimport { Controller, Post, Get, Delete, Param, UploadedFiles, UseGuards, UseInterceptors, BadRequestException, Body, Response, Query, Res, Patch } from \"@nestjs/common\";\nimport { FilesInterceptor } from \"@nestjs/platform-express\";\nimport { AllegatiAuthorizationGuard } from \"../security/allegatiAuthorizationGuard\";\nimport { AllegatiService } from \"../Services/AllegatiService/AllegatiService\";\nimport {UploadAllegatoResponseDto} from \"../Dtos/responses/UploadAllegatoResponseDto\";\nimport {AllegatoDto} from \"../Dtos/AllegatoDto\";\nimport {DownloadAllegatoResponseDto} from \"../Dtos/responses/DownloadAllegatoResponseDto\";\nimport { UploadSingleFileRequest } from \"../Dtos/UploadSingleFileRequest\";\nimport { RestUtilities } from \"../../Utilities\";\nimport { Logger } from \"../../Logger\";\nimport e from \"express\";\n\n@UseGuards(AllegatiAuthorizationGuard)\n@Controller('allegati')\nexport class AllegatiController {\n private readonly logger = new Logger(AllegatiController.name);\n\n constructor(private readonly allegatiService: AllegatiService) {}\n\n @Post('upload')\n @UseInterceptors(FilesInterceptor('file', 1, { limits: { fileSize: 90 * 1024 * 1024, files: 1 } }))\n @ApiConsumes('multipart/form-data')\n @ApiResponse({ status: 201, description: 'File caricato con successo.', type: UploadAllegatoResponseDto })\n @ApiBody({\n description: 'File e metadati per l\\'upload di un allegato',\n required: true,\n schema: {\n type: 'object',\n properties: {\n file: {\n type: 'string',\n format: 'binary',\n },\n codice: { type: 'integer', example: 1 },\n tipoCodice: { type: 'string', example: 'CF' },\n ordine: { type: 'string', example: '1' },\n descrizioneAllegato: { type: 'string', example: 'Documento di identità' },\n dataInizioValidita: { type: 'string', format: 'date', example: '2024-01-01' },\n dataFineValidita: { type: 'string', format: 'date', example: '2025-01-01' },\n idTipoAllegato: { type: 'integer', example: 3 },\n riferimentoDocumento: { type: 'string', example: 'PRAT-2024-0001' }\n },\n },\n })\n async upload(\n @UploadedFiles() files: Express.Multer.File[],\n @Body() uploadRequest: UploadSingleFileRequest\n ): Promise<UploadAllegatoResponseDto> {\n if (!files || files.length === 0) {\n throw new BadRequestException('Nessun file fornito');\n }\n if (files.length > 1) {\n throw new BadRequestException('Questo endpoint accetta un solo file alla volta');\n }\n const file = files[0];\n if (!file) {\n throw new BadRequestException('Nessun file fornito');\n }\n return await this.allegatiService.uploadFile(file, uploadRequest);\n }\n\n @Get(':id')\n @ApiResponse({ status: 200, description: 'File scaricato con successo.', type: DownloadAllegatoResponseDto })\n async download(@Param('id') id: number): Promise<DownloadAllegatoResponseDto> {\n return await this.allegatiService.downloadFile(id);\n }\n\n @Get(':id/download')\n @ApiResponse({ status: 200, description: 'File scaricato con successo.' })\n async downloadFile(\n @Param('id') id: number,\n @Res() res: e.Response\n ): Promise<void> {\n try {\n const file = await this.allegatiService.downloadFile(id);\n \n // Convert base64 to buffer in chunks; Buffer.concat evita i NUL finali del prealloc.\n const chunkSize = 1024 * 1024; // 1MB chunks\n const base64Content = file.contentBase64;\n const chunks: Buffer[] = [];\n for (let i = 0; i < base64Content.length; i += chunkSize) {\n const chunk = base64Content.slice(i, i + chunkSize);\n chunks.push(Buffer.from(chunk, 'base64'));\n }\n const buffer = Buffer.concat(chunks);\n\n // Set headers for file download; filename* (RFC 5987) per i nomi non ASCII.\n const asciiName = file.filename.replace(/[^\\x20-\\x7e]/g, '_').replace(/[\"\\\\]/g, '_');\n res.setHeader('Content-Type', file.mimetype ?? 'application/octet-stream');\n res.setHeader('Content-Disposition', `attachment; filename=\"${asciiName}\"; filename*=UTF-8''${encodeURIComponent(file.filename)}`);\n res.setHeader('Content-Length', buffer.length);\n \n res.status(200).end(buffer);\n } catch (error) {\n this.logger.error('[AllegatiController] downloadFile - Errore:', error);\n throw error;\n }\n }\n\n @Delete(':id')\n @ApiResponse({ status: 200, description: 'File eliminato con successo.' })\n async delete(@Param('id') id: number, @Response() res: e.Response) {\n await this.allegatiService.deleteFile(id);\n return RestUtilities.sendOKMessage(res, \"File eliminato con successo\");\n }\n\n @Get()\n @ApiResponse({ status: 200, description: 'Lista degli allegati.', type: [AllegatoDto] })\n @ApiQuery({ name: 'tipcod', required: false, description: 'Filtra per tipo codice' })\n @ApiQuery({ name: 'codice', required: false, description: 'Filtra per codice' })\n @ApiQuery({ name: 'docrif', required: false, description: 'Filtra per riferimento documento' })\n @ApiQuery({ name: 'idxtipoall', required: false, description: 'Filtra per tipo allegato', type: Number })\n async list(\n @Query('tipcod') tipcod?: string,\n @Query('codice') codice?: number,\n @Query('docrif') docrif?: string,\n @Query('idxtipoall') idxtipoall?: number\n ): Promise<AllegatoDto[]> {\n return await this.allegatiService.listFiles({\n tipcod,\n codice,\n docrif,\n idxtipoall: idxtipoall ? Number(idxtipoall) : undefined\n });\n }\n\n @Post('search')\n@ApiResponse({ status: 200, description: 'Ricerca allegati per campi.' })\nasync searchByFields(@Body() body: { tipcod?: string; codice?: number; docrif?: string; idxtipoall?: number }) {\n return await this.allegatiService.findByFields(body);\n}\n\n@Post('get-by-fields')\n@ApiResponse({ status: 200, description: 'Ottieni un allegato per campi.' })\nasync getOneByFields(@Body() body: { tipcod?: string; codice?: number; docrif?: string; idxtipoall?: number }) {\n return await this.allegatiService.getOneByFields(body);\n}\n\n@Patch('update-fields/:id')\n@ApiResponse({ status: 200, description: 'Aggiorna i campi di un allegato.' })\nasync updateFieldsById(\n @Param('id') id: number,\n @Body() body: { tipcod?: string; codice?: number; docrif?: string; idxtipoall?: number }\n) {\n await this.allegatiService.updateFieldsById(Number(id), body);\n return { message: 'Aggiornamento completato' };\n}\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllegatoDto.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/AllegatoDto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAA6E;AAE7E,MAAa,WAAW;CAgGvB;AAhGD,kCAgGC;AAzFG;IALC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,CAAC;KACb,CAAC;IACD,IAAA,0BAAQ,GAAE;;uCACC;AAQZ;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,kCAAkC;QAC/C,OAAO,EAAE,eAAe;KAC3B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;6CACtC;AAQlB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,iBAAiB;KAC7B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;6CACtC;AAQlB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,6CAA6C;QAC1D,OAAO,EAAE,sBAAsB;KAClC,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;;+CACzC;AAQpB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qBAAqB;QAClC,OAAO,EAAE,GAAG;KACf,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;2CACG;AAQhB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,IAAI;KAChB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;+CACO;AAQpB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,8EAA8E;QAC3F,OAAO,EAAE,GAAG;KACf,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;2CACG;AAQhB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,8BAA8B;KAC1C,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;wDACgB;AAQ7B;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,uCAAuC;QACpD,OAAO,EAAE,YAAY;KACxB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;uDACe;AAQ5B;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,YAAY;KACxB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;qDACa;AAQ1B;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,CAAC;KACb,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;mDACW;AAQxB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oDAAoD;QACjE,OAAO,EAAE,gBAAgB;KAC5B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;yDACiB","sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\
|
|
1
|
+
{"version":3,"file":"AllegatoDto.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/AllegatoDto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAA6E;AAE7E,MAAa,WAAW;CAgGvB;AAhGD,kCAgGC;AAzFG;IALC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,CAAC;KACb,CAAC;IACD,IAAA,0BAAQ,GAAE;;uCACC;AAQZ;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,kCAAkC;QAC/C,OAAO,EAAE,eAAe;KAC3B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;6CACtC;AAQlB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,iBAAiB;KAC7B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;6CACtC;AAQlB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,6CAA6C;QAC1D,OAAO,EAAE,sBAAsB;KAClC,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;;+CACzC;AAQpB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qBAAqB;QAClC,OAAO,EAAE,GAAG;KACf,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;2CACG;AAQhB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,IAAI;KAChB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;+CACO;AAQpB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,8EAA8E;QAC3F,OAAO,EAAE,GAAG;KACf,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;2CACG;AAQhB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,8BAA8B;KAC1C,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;wDACgB;AAQ7B;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,uCAAuC;QACpD,OAAO,EAAE,YAAY;KACxB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;uDACe;AAQ5B;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,YAAY;KACxB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;qDACa;AAQ1B;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,CAAC;KACb,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;mDACW;AAQxB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oDAAoD;QACjE,OAAO,EAAE,gBAAgB;KAC5B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;yDACiB","sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsString, IsNotEmpty, IsNumber, IsOptional } from \"class-validator\";\n\nexport class AllegatoDto {\n\n @ApiProperty({\n description: 'ID univoco dell\\'allegato',\n example: 1,\n })\n @IsNumber()\n id!: number;\n\n @ApiProperty({\n description: 'Nome originale del file caricato',\n example: 'documento.pdf',\n })\n @IsString()\n @IsNotEmpty({ message: \"Il nome file è obbligatorio.\" })\n filename!: string;\n\n @ApiProperty({\n description: 'Tipo MIME del file',\n example: 'application/pdf',\n })\n @IsString()\n @IsNotEmpty({ message: \"Il tipo MIME è obbligatorio.\" })\n mimetype!: string;\n\n @ApiProperty({\n description: 'Data di caricamento del file in formato ISO',\n example: '2025-04-27T12:00:00Z',\n })\n @IsString()\n @IsNotEmpty({ message: \"La data di upload è obbligatoria.\" })\n uploadDate!: string;\n\n @ApiProperty({\n description: 'Codice incrementale',\n example: '1',\n })\n @IsString()\n @IsOptional()\n codice?: string;\n\n @ApiProperty({\n description: 'Tipo del codice fornito',\n example: 'CF',\n })\n @IsString()\n @IsOptional()\n tipoCodice?: string;\n\n @ApiProperty({\n description: 'Numero o valore usato per ordinare o identificare la sequenza degli allegati',\n example: '1',\n })\n @IsString()\n @IsOptional()\n ordine?: string;\n\n @ApiProperty({\n description: 'Descrizione testuale dell\\'allegato',\n example: 'Documento di identità fronte',\n })\n @IsString()\n @IsOptional()\n descrizioneAllegato?: string;\n\n @ApiProperty({\n description: 'Data di inizio validità del documento',\n example: '2024-01-01',\n })\n @IsString()\n @IsOptional()\n dataInizioValidita?: string;\n\n @ApiProperty({\n description: 'Data di fine validità del documento',\n example: '2025-01-01',\n })\n @IsString()\n @IsOptional()\n dataFineValidita?: string;\n\n @ApiProperty({\n description: 'ID del tipo di allegato',\n example: 3,\n })\n @IsNumber()\n @IsOptional()\n idTipoAllegato?: number;\n\n @ApiProperty({\n description: 'Riferimento esterno o identificativo del documento',\n example: 'PRAT-2024-0001',\n })\n @IsString()\n @IsOptional()\n riferimentoDocumento?: string;\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseResponse.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/BaseResponse.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,yDAAyC;AACzC,qDAAqE;AAErE,MAAa,MAAM;CAQlB;AARD,wBAQC;AALC;IAFC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IAC/E,IAAA,0BAAQ,GAAE;;yCACQ;AAInB;IAFC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;IACvF,IAAA,0BAAQ,GAAE;;gDACe;AAG5B,MAAsB,YAAY;CAMjC;AAND,oCAMC;AADC;IAJC,IAAA,qBAAW,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC7B,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IAClB,IAAA,0BAAQ,GAAE;8BACF,MAAM;4CAAC","sourcesContent":["import { ApiProperty } from '@nestjs/swagger';\
|
|
1
|
+
{"version":3,"file":"BaseResponse.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/BaseResponse.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,yDAAyC;AACzC,qDAAqE;AAErE,MAAa,MAAM;CAQlB;AARD,wBAQC;AALC;IAFC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IAC/E,IAAA,0BAAQ,GAAE;;yCACQ;AAInB;IAFC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;IACvF,IAAA,0BAAQ,GAAE;;gDACe;AAG5B,MAAsB,YAAY;CAMjC;AAND,oCAMC;AADC;IAJC,IAAA,qBAAW,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC7B,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IAClB,IAAA,0BAAQ,GAAE;8BACF,MAAM;4CAAC","sourcesContent":["import { ApiProperty } from '@nestjs/swagger';\nimport { Type } from 'class-transformer';\nimport { IsObject, IsString, ValidateNested } from 'class-validator';\n\nexport class Status {\n @ApiProperty({ example: '0', description: 'Codice di errore, \"0\" se tutto ok' })\n @IsString()\n errorCode!: string;\n\n @ApiProperty({ example: 'Success', description: 'Descrizione dell\\'errore o successo' })\n @IsString()\n errorDescription!: string;\n}\n\nexport abstract class BaseResponse {\n @ApiProperty({ type: Status })\n @ValidateNested()\n @Type(() => Status)\n @IsObject()\n Status!: Status;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadSingleFileRequest.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/UploadSingleFileRequest.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAE9C,MAAa,uBAAuB;CAsDnC;AAtDD,0DAsDC;AAjDC;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,wFAAwF;QACrG,OAAO,EAAE,kBAAkB;KAC5B,CAAC;;uDACc;AAMhB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,iDAAiD;QAC9D,OAAO,EAAE,IAAI;KACd,CAAC;;2DACkB;AAMpB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,8EAA8E;QAC3F,OAAO,EAAE,GAAG;KACb,CAAC;;uDACc;AAMhB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,8BAA8B;KACxC,CAAC;;oEAC2B;AAM7B;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,kCAAkC;QAC/C,OAAO,EAAE,wBAAwB;KAClC,CAAC;;yDACgB;AAMlB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,qDAAqD;QAClE,OAAO,EAAE,YAAY;KACtB,CAAC;;mEAC0B;AAM5B;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,mDAAmD;QAChE,OAAO,EAAE,YAAY;KACtB,CAAC;;iEACwB;AAM1B;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,qDAAqD;QAClE,OAAO,EAAE,CAAC;KACX,CAAC;;+DACsB;AAMxB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,yEAAyE;QACtF,OAAO,EAAE,gBAAgB;KAC1B,CAAC;;qEAC4B","sourcesContent":["import { ApiProperty } from '@nestjs/swagger';\
|
|
1
|
+
{"version":3,"file":"UploadSingleFileRequest.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/UploadSingleFileRequest.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAE9C,MAAa,uBAAuB;CAsDnC;AAtDD,0DAsDC;AAjDC;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,wFAAwF;QACrG,OAAO,EAAE,kBAAkB;KAC5B,CAAC;;uDACc;AAMhB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,iDAAiD;QAC9D,OAAO,EAAE,IAAI;KACd,CAAC;;2DACkB;AAMpB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,8EAA8E;QAC3F,OAAO,EAAE,GAAG;KACb,CAAC;;uDACc;AAMhB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,8BAA8B;KACxC,CAAC;;oEAC2B;AAM7B;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,kCAAkC;QAC/C,OAAO,EAAE,wBAAwB;KAClC,CAAC;;yDACgB;AAMlB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,qDAAqD;QAClE,OAAO,EAAE,YAAY;KACtB,CAAC;;mEAC0B;AAM5B;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,mDAAmD;QAChE,OAAO,EAAE,YAAY;KACtB,CAAC;;iEACwB;AAM1B;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,qDAAqD;QAClE,OAAO,EAAE,CAAC;KACX,CAAC;;+DACsB;AAMxB;IAJC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,yEAAyE;QACtF,OAAO,EAAE,gBAAgB;KAC1B,CAAC;;qEAC4B","sourcesContent":["import { ApiProperty } from '@nestjs/swagger';\n\nexport class UploadSingleFileRequest {\n @ApiProperty({\n description: 'Codice identificativo del soggetto o dell’entità (es. codice fiscale, matricola, ecc.)',\n example: 'RSSMRA85M01H501Z',\n })\n codice!: string;\n\n @ApiProperty({\n description: 'Tipo del codice fornito (es. CF, PI, MATRICOLA)',\n example: 'CF',\n })\n tipoCodice!: string;\n\n @ApiProperty({\n description: 'Numero o valore usato per ordinare o identificare la sequenza degli allegati',\n example: '1',\n })\n ordine!: string;\n\n @ApiProperty({\n description: 'Descrizione testuale dell’allegato',\n example: 'Documento di identità fronte',\n })\n descrizioneAllegato!: string;\n\n @ApiProperty({\n description: 'Nome del file originale caricato',\n example: 'documento_identita.pdf',\n })\n nomeFile!: string;\n\n @ApiProperty({\n description: 'Data di inizio validità del documento (formato ISO)',\n example: '2024-01-01',\n })\n dataInizioValidita!: string;\n\n @ApiProperty({\n description: 'Data di fine validità del documento (formato ISO)',\n example: '2025-01-01',\n })\n dataFineValidita!: string;\n\n @ApiProperty({\n description: 'ID del tipo di allegato secondo tabella master (FK)',\n example: 3,\n })\n idTipoAllegato!: number;\n\n @ApiProperty({\n description: 'Riferimento esterno o identificativo del documento (es. numero pratica)',\n example: 'PRAT-2024-0001',\n })\n riferimentoDocumento!: string;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,0EAAwD;AACxD,wEAAsD","sourcesContent":["export * from \"./AllegatoDto\";\
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/allegati-module/Dtos/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,0EAAwD;AACxD,wEAAsD","sourcesContent":["export * from \"./AllegatoDto\";\nexport * from \"./responses/DownloadAllegatoResponseDto\";\nexport * from \"./responses/UploadAllegatoResponseDto\";\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DownloadAllegatoResponseDto.js","sourceRoot":"","sources":["../../../../src/allegati-module/Dtos/responses/DownloadAllegatoResponseDto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAAmE;AAEnE,MAAa,2BAA2B;CAwBvC;AAxBD,kEAwBC;AAjBG;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,oDAAoD;KAChE,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;kEACjC;AAQvB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,eAAe;KAC3B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;6DACtC;AAQlB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,iBAAiB;KAC7B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;6DACK","sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\
|
|
1
|
+
{"version":3,"file":"DownloadAllegatoResponseDto.js","sourceRoot":"","sources":["../../../../src/allegati-module/Dtos/responses/DownloadAllegatoResponseDto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAAmE;AAEnE,MAAa,2BAA2B;CAwBvC;AAxBD,kEAwBC;AAjBG;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,oDAAoD;KAChE,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;kEACjC;AAQvB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,eAAe;KAC3B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;6DACtC;AAQlB;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,iBAAiB;KAC7B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;6DACK","sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsString, IsNotEmpty, IsOptional } from \"class-validator\";\n\nexport class DownloadAllegatoResponseDto {\n @ApiProperty({\n description: 'Contenuto base64 del file',\n example: 'JVBERi0xLjQKJcfsj6IKNSAwIG9iago8PAovVGl0bGUgKP7...',\n })\n @IsString()\n @IsNotEmpty({ message: \"Il contenuto è obbligatorio.\" })\n contentBase64!: string;\n\n @ApiProperty({\n description: 'Nome originale del file',\n example: 'documento.pdf',\n })\n @IsString()\n @IsNotEmpty({ message: \"Il nome file è obbligatorio.\" })\n filename!: string;\n\n @ApiProperty({\n description: 'Tipo MIME del file',\n example: 'application/pdf',\n })\n @IsString()\n @IsOptional()\n mimetype?: string;\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GetListResponse.js","sourceRoot":"","sources":["../../../../src/allegati-module/Dtos/responses/GetListResponse.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAE9C,yDAAyC;AACzC,qDAAiD;AACjD,kDAA+C;AAC/C,gDAA6C;AAE7C,MAAa,eAAgB,SAAQ,2BAAY;CAKhD;AALD,0CAKC;AADC;IAHC,IAAA,qBAAW,EAAC,EAAE,IAAI,EAAE,CAAC,yBAAW,CAAC,EAAE,CAAC;IACpC,IAAA,gCAAc,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,yBAAW,CAAC;;+CACD","sourcesContent":["import { ApiProperty } from '@nestjs/swagger';\
|
|
1
|
+
{"version":3,"file":"GetListResponse.js","sourceRoot":"","sources":["../../../../src/allegati-module/Dtos/responses/GetListResponse.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAE9C,yDAAyC;AACzC,qDAAiD;AACjD,kDAA+C;AAC/C,gDAA6C;AAE7C,MAAa,eAAgB,SAAQ,2BAAY;CAKhD;AALD,0CAKC;AADC;IAHC,IAAA,qBAAW,EAAC,EAAE,IAAI,EAAE,CAAC,yBAAW,CAAC,EAAE,CAAC;IACpC,IAAA,gCAAc,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,yBAAW,CAAC;;+CACD","sourcesContent":["import { ApiProperty } from '@nestjs/swagger';\n\nimport { Type } from 'class-transformer';\nimport { ValidateNested } from 'class-validator';\nimport { BaseResponse } from '../BaseResponse';\nimport { AllegatoDto } from '../AllegatoDto';\n\nexport class GetListResponse extends BaseResponse {\n @ApiProperty({ type: [AllegatoDto] })\n @ValidateNested({ each: true })\n @Type(() => AllegatoDto)\n Result!: AllegatoDto[];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadAllegatoResponseDto.js","sourceRoot":"","sources":["../../../../src/allegati-module/Dtos/responses/UploadAllegatoResponseDto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAAiE;AAEjE,MAAa,yBAAyB;CAerC;AAfD,8DAeC;AATG;IALC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,+BAA+B;QAC5C,OAAO,EAAE,EAAE;KACd,CAAC;IACD,IAAA,0BAAQ,GAAE;;qDACC;AAQZ;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,mBAAmB;QAChC,OAAO,EAAE,gBAAgB;KAC5B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;2DACtC","sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\
|
|
1
|
+
{"version":3,"file":"UploadAllegatoResponseDto.js","sourceRoot":"","sources":["../../../../src/allegati-module/Dtos/responses/UploadAllegatoResponseDto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAAiE;AAEjE,MAAa,yBAAyB;CAerC;AAfD,8DAeC;AATG;IALC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,+BAA+B;QAC5C,OAAO,EAAE,EAAE;KACd,CAAC;IACD,IAAA,0BAAQ,GAAE;;qDACC;AAQZ;IANC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,mBAAmB;QAChC,OAAO,EAAE,gBAAgB;KAC5B,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,EAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;;2DACtC","sourcesContent":["import { ApiProperty } from \"@nestjs/swagger\";\nimport { IsNumber, IsString, IsNotEmpty } from \"class-validator\";\n\nexport class UploadAllegatoResponseDto {\n @ApiProperty({\n description: 'ID assegnato al file caricato',\n example: 42,\n })\n @IsNumber()\n id!: number;\n\n @ApiProperty({\n description: 'Nome file salvato',\n example: 'preventivo.pdf',\n })\n @IsString()\n @IsNotEmpty({ message: \"Il nome file è obbligatorio.\" })\n filename!: string;\n}"]}
|