emilsoftware-utilities 2.0.0-dev.22 → 2.0.0-dev.24
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 +182 -38
- package/dist/ContractGenerator.d.ts +4 -3
- package/dist/ContractGenerator.js +15 -5
- package/dist/ContractGenerator.js.map +1 -1
- package/dist/DailyFileTransport.d.ts +21 -0
- package/dist/DailyFileTransport.js +74 -0
- package/dist/DailyFileTransport.js.map +1 -0
- package/dist/DatabaseUpdater.js +32 -29
- package/dist/DatabaseUpdater.js.map +1 -1
- package/dist/EmilsoftwareModule.js.map +1 -1
- package/dist/ExecutionTimeLogger.d.ts +2 -2
- package/dist/ExecutionTimeLogger.js +5 -4
- package/dist/ExecutionTimeLogger.js.map +1 -1
- package/dist/Logger.d.ts +22 -11
- package/dist/Logger.js +132 -119
- package/dist/Logger.js.map +1 -1
- package/dist/Orm.d.ts +26 -6
- package/dist/Orm.js +144 -40
- package/dist/Orm.js.map +1 -1
- package/dist/RoutesLoggerMiddleware.js.map +1 -1
- package/dist/Utilities.d.ts +18 -8
- package/dist/Utilities.js +115 -35
- package/dist/Utilities.js.map +1 -1
- package/dist/accessi-module/AccessiModule.d.ts +69 -0
- package/dist/accessi-module/AccessiModule.js +29 -5
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/accessiFetch.d.ts +7 -0
- package/dist/accessi-module/Console/accessiFetch.js +59 -0
- package/dist/accessi-module/Console/accessiFetch.js.map +1 -0
- package/dist/accessi-module/Console/console.css +618 -0
- package/dist/accessi-module/Console/console.d.ts +1 -0
- package/dist/accessi-module/Console/console.js +3101 -0
- package/dist/accessi-module/Console/console.js.map +1 -0
- package/dist/accessi-module/Console/generated/accessiApi.d.ts +542 -0
- package/dist/accessi-module/Console/generated/accessiApi.js +517 -0
- package/dist/accessi-module/Console/generated/accessiApi.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenu.d.ts +39 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenu.js +3 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenu.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuIcona.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuIcona.js +9 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuIcona.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuNote.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuNote.js +9 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuNote.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuPagina.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuPagina.js +9 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuPagina.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipo.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipo.js +9 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipo.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipoAbilitazione.d.ts +16 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipoAbilitazione.js +17 -0
- package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipoAbilitazione.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/actionResponse.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/actionResponse.js +9 -0
- package/dist/accessi-module/Console/generated/model/actionResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/assignPermissionsToUserRequest.d.ts +11 -0
- package/dist/accessi-module/Console/generated/model/assignPermissionsToUserRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/assignPermissionsToUserRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/assignRolesToUserRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/assignRolesToUserRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/assignRolesToUserRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/authenticatedTokenPayloadDto.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/authenticatedTokenPayloadDto.js +3 -0
- package/dist/accessi-module/Console/generated/model/authenticatedTokenPayloadDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.d.ts +19 -0
- package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/confirmResetPasswordRequest.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/confirmResetPasswordRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/confirmResetPasswordRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createFederatedIdentityRequest.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/createFederatedIdentityRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createFederatedIdentityRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createFederatedProviderRequest.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/createFederatedProviderRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createFederatedProviderRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createFederatedUserRequest.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/createFederatedUserRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/createFederatedUserRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequest.d.ts +23 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequestFlgEnabled.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequestFlgEnabled.js +15 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequestFlgEnabled.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.d.ts +27 -0
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createMenuRequest.d.ts +52 -0
- package/dist/accessi-module/Console/generated/model/createMenuRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createMenuRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createMenuTypeRequest.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/createMenuTypeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createMenuTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenRequest.d.ts +16 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/errorResponse.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/errorResponse.js +9 -0
- package/dist/accessi-module/Console/generated/model/errorResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityListResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityListResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityListResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityResponseDto.d.ts +23 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityResponseDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/federatedIdentityResponseDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderListResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderListResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderListResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderResponseDto.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderResponseDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/federatedProviderResponseDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/filtriUtente.d.ts +32 -0
- package/dist/accessi-module/Console/generated/model/filtriUtente.js +9 -0
- package/dist/accessi-module/Console/generated/model/filtriUtente.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getFiltriResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getFiltriResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getFiltriResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getFiltriUtenteParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getFiltriUtenteParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getFiltriUtenteParams.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getFiltriUtenteResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getFiltriUtenteResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getFiltriUtenteResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getGroupsWithMenusParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getGroupsWithMenusParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getGroupsWithMenusParams.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getGroupsWithMenusResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getGroupsWithMenusResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getGroupsWithMenusResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getMenuTypesResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getMenuTypesResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getMenuTypesResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getMenusResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getMenusResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getMenusResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getRolesResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getRolesResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getRolesResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensParams.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUserByTokenRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/getUserByTokenRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/getUserByTokenRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUserByTokenResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getUserByTokenResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getUserByTokenResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUsersParams.d.ts +32 -0
- package/dist/accessi-module/Console/generated/model/getUsersParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getUsersParams.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUsersResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getUsersResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getUsersResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUsersResult.d.ts +17 -0
- package/dist/accessi-module/Console/generated/model/getUsersResult.js +3 -0
- package/dist/accessi-module/Console/generated/model/getUsersResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUsersResultExtensionFields.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getUsersResultExtensionFields.js +9 -0
- package/dist/accessi-module/Console/generated/model/getUsersResultExtensionFields.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.d.ts +19 -0
- package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js +3 -0
- package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/index.d.ts +93 -0
- package/dist/accessi-module/Console/generated/model/index.js +110 -0
- package/dist/accessi-module/Console/generated/model/index.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/issuedServiceTokenDto.d.ts +30 -0
- package/dist/accessi-module/Console/generated/model/issuedServiceTokenDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/issuedServiceTokenDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginRequest.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/loginRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/loginRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/loginResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/loginResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginResult.d.ts +32 -0
- package/dist/accessi-module/Console/generated/model/loginResult.js +3 -0
- package/dist/accessi-module/Console/generated/model/loginResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginResultExtensionFields.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/loginResultExtensionFields.js +9 -0
- package/dist/accessi-module/Console/generated/model/loginResultExtensionFields.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginResultPasswordRequired.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/loginResultPasswordRequired.js +14 -0
- package/dist/accessi-module/Console/generated/model/loginResultPasswordRequired.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/menuEntity.d.ts +32 -0
- package/dist/accessi-module/Console/generated/model/menuEntity.js +9 -0
- package/dist/accessi-module/Console/generated/model/menuEntity.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/menuTypeEntity.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/menuTypeEntity.js +9 -0
- package/dist/accessi-module/Console/generated/model/menuTypeEntity.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/passwordExpiredResponse.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/passwordExpiredResponse.js +9 -0
- package/dist/accessi-module/Console/generated/model/passwordExpiredResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/permission.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/permission.js +9 -0
- package/dist/accessi-module/Console/generated/model/permission.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/publicRegisterRequest.d.ts +51 -0
- package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/publicRegisterRequestCellulare.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/publicRegisterRequestCellulare.js +9 -0
- package/dist/accessi-module/Console/generated/model/publicRegisterRequestCellulare.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/registerRequest.d.ts +62 -0
- package/dist/accessi-module/Console/generated/model/registerRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/registerRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/registerRequestCellulare.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/registerRequestCellulare.js +9 -0
- package/dist/accessi-module/Console/generated/model/registerRequestCellulare.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/registerResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/registerResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/registerResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/resendTwoFactorRequest.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/resendTwoFactorRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/resendTwoFactorRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/role.d.ts +15 -0
- package/dist/accessi-module/Console/generated/model/role.js +3 -0
- package/dist/accessi-module/Console/generated/model/role.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/ruoliMenu.d.ts +15 -0
- package/dist/accessi-module/Console/generated/model/ruoliMenu.js +3 -0
- package/dist/accessi-module/Console/generated/model/ruoliMenu.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/ruoliMenuTipoAbilitazione.d.ts +16 -0
- package/dist/accessi-module/Console/generated/model/ruoliMenuTipoAbilitazione.js +17 -0
- package/dist/accessi-module/Console/generated/model/ruoliMenuTipoAbilitazione.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/sendResetPasswordEmailRequest.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/sendResetPasswordEmailRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/sendResetPasswordEmailRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/serveResetPasswordPageParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/serveResetPasswordPageParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/serveResetPasswordPageParams.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/serviceTokenDto.d.ts +28 -0
- package/dist/accessi-module/Console/generated/model/serviceTokenDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/serviceTokenDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/setPasswordLoginPolicyRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/setPasswordLoginPolicyRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/setPasswordLoginPolicyRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDto.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDto.js +3 -0
- package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDtoStatoRegistrazione.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDtoStatoRegistrazione.js +19 -0
- package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDtoStatoRegistrazione.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/status.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/status.js +9 -0
- package/dist/accessi-module/Console/generated/model/status.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/tipoFiltro.d.ts +23 -0
- package/dist/accessi-module/Console/generated/model/tipoFiltro.js +3 -0
- package/dist/accessi-module/Console/generated/model/tipoFiltro.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/tipoFiltroFlgEnabled.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/tipoFiltroFlgEnabled.js +15 -0
- package/dist/accessi-module/Console/generated/model/tipoFiltroFlgEnabled.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/tokenResult.d.ts +15 -0
- package/dist/accessi-module/Console/generated/model/tokenResult.js +3 -0
- package/dist/accessi-module/Console/generated/model/tokenResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/tokenResultType.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/tokenResultType.js +15 -0
- package/dist/accessi-module/Console/generated/model/tokenResultType.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDto.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDto.js +3 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoMethod.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoMethod.js +14 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoMethod.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoTwoFactorRequired.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoTwoFactorRequired.js +14 -0
- package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoTwoFactorRequired.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateEnabledStatusRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/updateEnabledStatusRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateEnabledStatusRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateFederatedIdentityRequest.d.ts +11 -0
- package/dist/accessi-module/Console/generated/model/updateFederatedIdentityRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateFederatedIdentityRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateFederatedProviderRequest.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/updateFederatedProviderRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateFederatedProviderRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequest.d.ts +21 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequestFlgEnabled.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequestFlgEnabled.js +15 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequestFlgEnabled.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.d.ts +22 -0
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateMenuRequest.d.ts +47 -0
- package/dist/accessi-module/Console/generated/model/updateMenuRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateMenuRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateMenuTypeRequest.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/updateMenuTypeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateMenuTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/userDto.d.ts +88 -0
- package/dist/accessi-module/Console/generated/model/userDto.js +3 -0
- package/dist/accessi-module/Console/generated/model/userDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/userDtoAvatar.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/userDtoAvatar.js +9 -0
- package/dist/accessi-module/Console/generated/model/userDtoAvatar.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/userDtoCellulare.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/userDtoCellulare.js +9 -0
- package/dist/accessi-module/Console/generated/model/userDtoCellulare.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/userDtoStatoRegistrazione.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/userDtoStatoRegistrazione.js +19 -0
- package/dist/accessi-module/Console/generated/model/userDtoStatoRegistrazione.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/userGrantsDto.d.ts +16 -0
- package/dist/accessi-module/Console/generated/model/userGrantsDto.js +3 -0
- package/dist/accessi-module/Console/generated/model/userGrantsDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/userGrantsResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/userGrantsResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/userGrantsResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/verifyTwoFactorRequest.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/verifyTwoFactorRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/verifyTwoFactorRequest.js.map +1 -0
- package/dist/accessi-module/Console/help.d.ts +13 -0
- package/dist/accessi-module/Console/help.js +348 -0
- package/dist/accessi-module/Console/help.js.map +1 -0
- package/dist/accessi-module/Console/index.html +127 -0
- package/dist/accessi-module/Console/openApiClient.d.ts +34 -0
- package/dist/accessi-module/Console/openApiClient.js +111 -0
- package/dist/accessi-module/Console/openApiClient.js.map +1 -0
- package/dist/accessi-module/Console/wiki.d.ts +52 -0
- package/dist/accessi-module/Console/wiki.js +689 -0
- package/dist/accessi-module/Console/wiki.js.map +1 -0
- package/dist/accessi-module/Controllers/AccessiConsoleController.d.ts +18 -0
- package/dist/accessi-module/Controllers/AccessiConsoleController.js +111 -0
- package/dist/accessi-module/Controllers/AccessiConsoleController.js.map +1 -0
- package/dist/accessi-module/Controllers/AuthController.d.ts +4 -1
- package/dist/accessi-module/Controllers/AuthController.js +86 -47
- package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
- package/dist/accessi-module/Controllers/ConfiguratorController.d.ts +1 -3
- package/dist/accessi-module/Controllers/ConfiguratorController.js +9 -9
- package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
- package/dist/accessi-module/Controllers/EmailController.d.ts +2 -2
- package/dist/accessi-module/Controllers/EmailController.js +4 -2
- package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
- package/dist/accessi-module/Controllers/FiltriController.d.ts +5 -4
- package/dist/accessi-module/Controllers/FiltriController.js +95 -5
- package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
- package/dist/accessi-module/Controllers/PermissionController.d.ts +12 -1
- package/dist/accessi-module/Controllers/PermissionController.js +282 -13
- package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
- package/dist/accessi-module/Controllers/ServiceTokenController.d.ts +23 -0
- package/dist/accessi-module/Controllers/ServiceTokenController.js +176 -0
- package/dist/accessi-module/Controllers/ServiceTokenController.js.map +1 -0
- package/dist/accessi-module/Controllers/UserController.d.ts +5 -3
- package/dist/accessi-module/Controllers/UserController.js +65 -11
- 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 +16 -8
- 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 +1 -1
- package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.d.ts +3 -0
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js +18 -0
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js.map +1 -1
- package/dist/accessi-module/Dtos/BaseResponse.d.ts +2 -0
- package/dist/accessi-module/Dtos/BaseResponse.js +21 -2
- package/dist/accessi-module/Dtos/BaseResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/CatalogDtos.d.ts +66 -0
- package/dist/accessi-module/Dtos/CatalogDtos.js +336 -0
- package/dist/accessi-module/Dtos/CatalogDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/ConfirmResetPasswordRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/FederatedIdentityDtos.d.ts +69 -0
- package/dist/accessi-module/Dtos/FederatedIdentityDtos.js +236 -0
- package/dist/accessi-module/Dtos/FederatedIdentityDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/FiltriUtente.js +4 -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 +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/GetUserByTokenRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/GetUserByTokenResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetUsersResponse.d.ts +1 -1
- package/dist/accessi-module/Dtos/GetUsersResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/LoginRequest.d.ts +1 -1
- package/dist/accessi-module/Dtos/LoginRequest.js +3 -2
- package/dist/accessi-module/Dtos/LoginRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/LoginResponse.d.ts +6 -2
- package/dist/accessi-module/Dtos/LoginResponse.js +20 -7
- package/dist/accessi-module/Dtos/LoginResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/MenuItem.js +1 -0
- package/dist/accessi-module/Dtos/Permission.d.ts +1 -0
- package/dist/accessi-module/Dtos/Permission.js +1 -0
- package/dist/accessi-module/Dtos/Permission.js.map +1 -1
- package/dist/accessi-module/Dtos/PublicRegisterRequest.d.ts +1 -1
- package/dist/accessi-module/Dtos/PublicRegisterRequest.js +1 -0
- package/dist/accessi-module/Dtos/PublicRegisterRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterRequest.js +3 -1
- package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/Role.d.ts +4 -0
- package/dist/accessi-module/Dtos/Role.js +4 -0
- 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/SendResetPasswordEmailRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/ServiceToken.d.ts +34 -0
- package/dist/accessi-module/Dtos/ServiceToken.js +128 -0
- package/dist/accessi-module/Dtos/ServiceToken.js.map +1 -0
- 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.d.ts +4 -0
- package/dist/accessi-module/Dtos/TipoAbilitazione.js +4 -0
- 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/TwoFactorDtos.d.ts +13 -0
- package/dist/accessi-module/Dtos/TwoFactorDtos.js +60 -0
- package/dist/accessi-module/Dtos/TwoFactorDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/UpdateEnabledStatusRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/UserDto.d.ts +7 -0
- package/dist/accessi-module/Dtos/UserDto.js +26 -2
- 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/UserGrantsResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/index.d.ts +4 -0
- package/dist/accessi-module/Dtos/index.js +4 -0
- package/dist/accessi-module/Dtos/index.js.map +1 -1
- package/dist/accessi-module/Services/AuthService/AuthService.d.ts +40 -5
- package/dist/accessi-module/Services/AuthService/AuthService.js +192 -40
- package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
- package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.d.ts +3 -1
- package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.js +5 -1
- package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.js.map +1 -1
- package/dist/accessi-module/Services/EmailService/EmailService.d.ts +9 -2
- package/dist/accessi-module/Services/EmailService/EmailService.js +43 -22
- package/dist/accessi-module/Services/EmailService/EmailService.js.map +1 -1
- package/dist/accessi-module/Services/FiltriService/FiltriService.d.ts +18 -3
- package/dist/accessi-module/Services/FiltriService/FiltriService.js +92 -9
- package/dist/accessi-module/Services/FiltriService/FiltriService.js.map +1 -1
- package/dist/accessi-module/Services/PermissionService/PermissionService.d.ts +73 -2
- package/dist/accessi-module/Services/PermissionService/PermissionService.js +537 -198
- package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.d.ts +75 -0
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.js +265 -0
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.js.map +1 -0
- package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.d.ts +27 -0
- package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.js +175 -0
- package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.js.map +1 -0
- package/dist/accessi-module/Services/UserService/UserService.d.ts +36 -5
- package/dist/accessi-module/Services/UserService/UserService.js +341 -161
- 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 +46 -10
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +399 -181
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
- package/dist/accessi-module/database-updates/accessiSchema.d.ts +45 -0
- package/dist/accessi-module/database-updates/accessiSchema.js +87 -0
- package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -0
- package/dist/accessi-module/database-updates/optionalColumns.d.ts +7 -0
- package/dist/accessi-module/database-updates/optionalColumns.js +58 -0
- package/dist/accessi-module/database-updates/optionalColumns.js.map +1 -0
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js +18 -8
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js.map +1 -1
- package/dist/accessi-module/federated-auth/FederatedAuthController.d.ts +24 -0
- package/dist/accessi-module/federated-auth/FederatedAuthController.js +333 -0
- package/dist/accessi-module/federated-auth/FederatedAuthController.js.map +1 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.d.ts +100 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.js +451 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.js.map +1 -0
- package/dist/accessi-module/federated-auth/FederatedAuthTypes.d.ts +53 -0
- package/dist/accessi-module/federated-auth/FederatedAuthTypes.js +3 -0
- package/dist/accessi-module/federated-auth/FederatedAuthTypes.js.map +1 -0
- package/dist/accessi-module/index.d.ts +17 -0
- package/dist/accessi-module/index.js +25 -11
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/accessi-module/jwt/jwt.strategy.d.ts +1 -1
- package/dist/accessi-module/jwt/jwt.strategy.js +16 -7
- package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
- package/dist/accessi-module/middleware/accessiRequirements.d.ts +23 -1
- package/dist/accessi-module/middleware/accessiRequirements.js +7 -0
- package/dist/accessi-module/middleware/accessiRequirements.js.map +1 -1
- package/dist/accessi-module/middleware/authenticateGen.d.ts +16 -1
- package/dist/accessi-module/middleware/authenticateGen.js +63 -25
- package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
- package/dist/accessi-module/security/AccessiHttpExceptionFilter.d.ts +12 -0
- package/dist/accessi-module/security/AccessiHttpExceptionFilter.js +74 -0
- package/dist/accessi-module/security/AccessiHttpExceptionFilter.js.map +1 -0
- package/dist/accessi-module/security/accessControl.d.ts +11 -0
- package/dist/accessi-module/security/accessControl.js +19 -4
- package/dist/accessi-module/security/accessControl.js.map +1 -1
- package/dist/accessi-module/security/accessiValidation.d.ts +9 -0
- package/dist/accessi-module/security/accessiValidation.js +41 -0
- package/dist/accessi-module/security/accessiValidation.js.map +1 -0
- package/dist/accessi-module/security/authenticatedToken.d.ts +15 -1
- package/dist/accessi-module/security/authenticatedToken.js +31 -4
- package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
- package/dist/accessi-module/security/passwordResetToken.d.ts +13 -3
- package/dist/accessi-module/security/passwordResetToken.js +13 -5
- package/dist/accessi-module/security/passwordResetToken.js.map +1 -1
- package/dist/accessi-module/security/publicAuthRateLimit.d.ts +3 -3
- package/dist/accessi-module/security/publicAuthRateLimit.js +30 -8
- package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
- package/dist/accessi-module/security/serviceTokenGuard.d.ts +25 -0
- package/dist/accessi-module/security/serviceTokenGuard.js +85 -0
- package/dist/accessi-module/security/serviceTokenGuard.js.map +1 -0
- package/dist/accessi-module/security/serviceTokenRateLimit.d.ts +8 -0
- package/dist/accessi-module/security/serviceTokenRateLimit.js +49 -0
- package/dist/accessi-module/security/serviceTokenRateLimit.js.map +1 -0
- package/dist/allegati-module/AllegatiModule.d.ts +11 -0
- package/dist/allegati-module/AllegatiModule.js +11 -1
- package/dist/allegati-module/AllegatiModule.js.map +1 -1
- package/dist/allegati-module/Controllers/AllegatiController.d.ts +2 -1
- package/dist/allegati-module/Controllers/AllegatiController.js +23 -15
- 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.d.ts +10 -3
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.js +150 -101
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.js.map +1 -1
- package/dist/allegati-module/index.js.map +1 -1
- package/dist/allegati-module/security/allegatiAuthorizationGuard.d.ts +14 -0
- package/dist/allegati-module/security/allegatiAuthorizationGuard.js +70 -0
- package/dist/allegati-module/security/allegatiAuthorizationGuard.js.map +1 -0
- package/dist/autobind.d.ts +10 -3
- package/dist/autobind.js +24 -9
- package/dist/autobind.js.map +1 -1
- package/dist/firebird-compat.d.ts +13 -0
- package/dist/firebird-compat.js +3 -2
- package/dist/firebird-compat.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/initEmilsoftwareModule.js +7 -0
- package/dist/initEmilsoftwareModule.js.map +1 -1
- package/dist/scripts/generateAccessiOpenApi.d.ts +1 -0
- package/dist/scripts/generateAccessiOpenApi.js +57 -0
- package/dist/scripts/generateAccessiOpenApi.js.map +1 -0
- package/dist/scripts/generateAccessiWiki.d.ts +1 -0
- package/dist/scripts/generateAccessiWiki.js +131 -0
- package/dist/scripts/generateAccessiWiki.js.map +1 -0
- package/dist/swagger/SwaggerConfig.js +6 -3
- package/dist/swagger/SwaggerConfig.js.map +1 -1
- package/package.json +103 -83
- package/dist/emilsoftware-utilities-2.0.0-dev.22.tgz +0 -0
|
@@ -6,6 +6,8 @@ const common_1 = require("@nestjs/common");
|
|
|
6
6
|
const Utilities_1 = require("../../Utilities");
|
|
7
7
|
const DEFAULT_PUBLIC_AUTH_RATE_LIMITS = {
|
|
8
8
|
login: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },
|
|
9
|
+
twoFactorVerify: { windowMs: 15 * 60 * 1000, maxAttempts: 20 },
|
|
10
|
+
twoFactorResend: { windowMs: 15 * 60 * 1000, maxAttempts: 5 },
|
|
9
11
|
register: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },
|
|
10
12
|
passwordResetEmail: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },
|
|
11
13
|
passwordResetConfirm: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },
|
|
@@ -49,9 +51,27 @@ function pruneRateLimitBuckets(now) {
|
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
}
|
|
54
|
+
/** Mantiene il numero di bucket sotto la soglia, scartando i meno recenti. */
|
|
55
|
+
function enforceBucketCap() {
|
|
56
|
+
while (RATE_LIMIT_BUCKETS.size >= MAX_TRACKED_BUCKETS) {
|
|
57
|
+
let oldestKey;
|
|
58
|
+
let oldestSeen = Number.POSITIVE_INFINITY;
|
|
59
|
+
for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {
|
|
60
|
+
if (bucket.lastSeenAt < oldestSeen) {
|
|
61
|
+
oldestSeen = bucket.lastSeenAt;
|
|
62
|
+
oldestKey = key;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (oldestKey === undefined) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
RATE_LIMIT_BUCKETS.delete(oldestKey);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
52
71
|
function consumeBucket(bucketKey, rule, now) {
|
|
53
72
|
const existingBucket = RATE_LIMIT_BUCKETS.get(bucketKey);
|
|
54
73
|
if (!existingBucket || existingBucket.resetAt <= now) {
|
|
74
|
+
enforceBucketCap();
|
|
55
75
|
RATE_LIMIT_BUCKETS.set(bucketKey, {
|
|
56
76
|
count: 1,
|
|
57
77
|
resetAt: now + rule.windowMs,
|
|
@@ -69,23 +89,25 @@ function consumeBucket(bucketKey, rule, now) {
|
|
|
69
89
|
function checkPublicAuthRateLimit(options, scope, req, identifiers = []) {
|
|
70
90
|
var _a, _b, _c, _d, _e;
|
|
71
91
|
if (((_a = options.publicAuthRateLimit) === null || _a === void 0 ? void 0 : _a.enabled) === false) {
|
|
72
|
-
return { allowed: true };
|
|
92
|
+
return { allowed: true, retryAfterSeconds: 0 };
|
|
73
93
|
}
|
|
74
94
|
const rule = getRule(options, scope);
|
|
75
95
|
const now = Date.now();
|
|
76
96
|
pruneRateLimitBuckets(now);
|
|
77
97
|
const ipAddress = (_e = normalizeIdentifier((_d = (_b = req.ip) !== null && _b !== void 0 ? _b : (_c = req.socket) === null || _c === void 0 ? void 0 : _c.remoteAddress) !== null && _d !== void 0 ? _d : 'unknown')) !== null && _e !== void 0 ? _e : 'unknown';
|
|
78
|
-
|
|
98
|
+
// Consuma prima il bucket per IP: se gia bloccato non crea bucket per soggetto,
|
|
99
|
+
// evitando crescita di memoria con identificatori sempre diversi.
|
|
100
|
+
const ipRetryAfterSeconds = consumeBucket(`${scope}|ip|${ipAddress}`, rule, now);
|
|
101
|
+
if (ipRetryAfterSeconds) {
|
|
102
|
+
return { allowed: false, retryAfterSeconds: ipRetryAfterSeconds };
|
|
103
|
+
}
|
|
104
|
+
let retryAfterSeconds = 0;
|
|
79
105
|
for (const identifier of identifiers) {
|
|
80
106
|
const normalizedIdentifier = normalizeIdentifier(identifier);
|
|
81
107
|
if (!normalizedIdentifier) {
|
|
82
108
|
continue;
|
|
83
109
|
}
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
let retryAfterSeconds = 0;
|
|
87
|
-
for (const bucketKey of bucketKeys) {
|
|
88
|
-
const bucketRetryAfterSeconds = consumeBucket(bucketKey, rule, now);
|
|
110
|
+
const bucketRetryAfterSeconds = consumeBucket(`${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`, rule, now);
|
|
89
111
|
if (bucketRetryAfterSeconds) {
|
|
90
112
|
retryAfterSeconds = Math.max(retryAfterSeconds, bucketRetryAfterSeconds);
|
|
91
113
|
}
|
|
@@ -96,7 +118,7 @@ function checkPublicAuthRateLimit(options, scope, req, identifiers = []) {
|
|
|
96
118
|
retryAfterSeconds,
|
|
97
119
|
};
|
|
98
120
|
}
|
|
99
|
-
return { allowed: true };
|
|
121
|
+
return { allowed: true, retryAfterSeconds: 0 };
|
|
100
122
|
}
|
|
101
123
|
function sendPublicAuthRateLimitExceeded(res, retryAfterSeconds) {
|
|
102
124
|
res.setHeader('Retry-After', String(retryAfterSeconds));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicAuthRateLimit.js","sourceRoot":"","sources":["../../../src/accessi-module/security/publicAuthRateLimit.ts"],"names":[],"mappings":";;AA+GA,4DA2CC;AAED,0EAWC;AAvKD,2CAA4C;AAE5C,+CAAgD;AAqBhD,MAAM,+BAA+B,GAGjC;IACF,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;IACpD,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE;IACtD,kBAAkB,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE;IAChE,oBAAoB,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;IACnE,cAAc,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;CAC7D,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA2B,CAAC;AAC9D,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAClC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC5B,GAAG,MAAM,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC/E,CAAC;AAEF,SAAS,OAAO,CACd,OAAuB,EACvB,KAA+B;;IAE/B,MAAM,cAAc,GAAG,MAAA,OAAO,CAAC,mBAAmB,0CAAG,KAAK,CAAC,CAAC;IAE5D,IACE,cAAc;QACd,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QACxC,cAAc,CAAC,QAAQ,GAAG,CAAC;QAC3B,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC;QAC3C,cAAc,CAAC,WAAW,GAAG,CAAC,EAC9B,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC;YAC7C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;SACpD,CAAC;IACJ,CAAC;IAED,OAAO,+BAA+B,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,mBAAmB,CAAC,UAAkB;IAC7C,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,OAAO,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;AAC/C,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAW;IACxC,IAAI,kBAAkB,CAAC,IAAI,GAAG,mBAAmB,EAAE,CAAC;QAClD,OAAO;IACT,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC;QACzD,IAAI,MAAM,CAAC,OAAO,IAAI,GAAG,IAAI,MAAM,CAAC,UAAU,IAAI,GAAG,GAAG,aAAa,GAAG,CAAC,EAAE,CAAC;YAC1E,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,kBAAkB,CAAC,IAAI,GAAG,mBAAmB,EAAE,CAAC;YAClD,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,SAAiB,EACjB,IAAoC,EACpC,GAAW;IAEX,MAAM,cAAc,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;QACrD,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE;YAChC,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ;YAC5B,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,cAAc,CAAC,UAAU,GAAG,GAAG,CAAC;IAChC,IAAI,cAAc,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,cAAc,CAAC,KAAK,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,wBAAwB,CACtC,OAAuB,EACvB,KAA+B,EAC/B,GAAY,EACZ,cAAwB,EAAE;;IAE1B,IAAI,CAAA,MAAA,OAAO,CAAC,mBAAmB,0CAAE,OAAO,MAAK,KAAK,EAAE,CAAC;QACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAE3B,MAAM,SAAS,GACb,MAAA,mBAAmB,CAAC,MAAA,MAAA,GAAG,CAAC,EAAE,mCAAI,MAAA,GAAG,CAAC,MAAM,0CAAE,aAAa,mCAAI,SAAS,CAAC,mCAAI,SAAS,CAAC;IACrF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,KAAK,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC;IAEjE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC7D,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QAED,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,eAAe,SAAS,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,uBAAuB,GAAG,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACpE,IAAI,uBAAuB,EAAE,CAAC;YAC5B,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,iBAAiB;SAClB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,SAAgB,+BAA+B,CAC7C,GAAa,EACb,iBAAyB;IAEzB,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACxD,OAAO,yBAAa,CAAC,gBAAgB,CACnC,GAAG,EACH,sCAAsC,EACtC,qBAAqB,EACrB,mBAAU,CAAC,iBAAiB,CAC7B,CAAC;AACJ,CAAC","sourcesContent":["import { HttpStatus } from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport { RestUtilities } from '../../Utilities';\nimport { AccessiOptions, PublicAuthRateLimitRuleOptions } from '../AccessiModule';\n\nexport type PublicAuthRateLimitScope =\n | 'login'\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 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\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 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 };\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 const bucketKeys = new Set<string>([`${scope}|ip|${ipAddress}`]);\n\n for (const identifier of identifiers) {\n const normalizedIdentifier = normalizeIdentifier(identifier);\n if (!normalizedIdentifier) {\n continue;\n }\n\n bucketKeys.add(`${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`);\n }\n\n let retryAfterSeconds = 0;\n for (const bucketKey of bucketKeys) {\n const bucketRetryAfterSeconds = consumeBucket(bucketKey, rule, now);\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 };\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
|
+
{"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"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import type { Request } from 'express';
|
|
4
|
+
import { ServiceTokenService, VerifiedServiceToken } from '../Services/ServiceTokenService/ServiceTokenService';
|
|
5
|
+
/** Chiave dei metadata usata da `@RequireServiceTokenScopes`. */
|
|
6
|
+
export declare const SERVICE_TOKEN_SCOPES_METADATA = "accessi:service-token-scopes";
|
|
7
|
+
/** Richiede che il token di servizio presenti tutti gli scope indicati. */
|
|
8
|
+
export declare const RequireServiceTokenScopes: (...scopes: string[]) => import("@nestjs/common").CustomDecorator<string>;
|
|
9
|
+
export type AccessiServiceTokenRequest = Request & {
|
|
10
|
+
accessiServiceToken?: VerifiedServiceToken;
|
|
11
|
+
};
|
|
12
|
+
/** Restituisce il token di servizio verificato da `ServiceTokenGuard`; lancia 401 se assente. */
|
|
13
|
+
export declare function getAccessiServiceToken(req: Request): VerifiedServiceToken;
|
|
14
|
+
/**
|
|
15
|
+
* Autentica le chiamate tecniche macchina-a-macchina tramite `Authorization: Bearer <token>`.
|
|
16
|
+
*
|
|
17
|
+
* Il token e per installazione/servizio, non legato a un utente. Gli scope richiesti si dichiarano
|
|
18
|
+
* con `@RequireServiceTokenScopes('ia')`.
|
|
19
|
+
*/
|
|
20
|
+
export declare class ServiceTokenGuard implements CanActivate {
|
|
21
|
+
private readonly serviceTokenService;
|
|
22
|
+
private readonly reflector;
|
|
23
|
+
constructor(serviceTokenService: ServiceTokenService, reflector: Reflector);
|
|
24
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.ServiceTokenGuard = exports.RequireServiceTokenScopes = exports.SERVICE_TOKEN_SCOPES_METADATA = void 0;
|
|
22
|
+
exports.getAccessiServiceToken = getAccessiServiceToken;
|
|
23
|
+
const common_1 = require("@nestjs/common");
|
|
24
|
+
const core_1 = require("@nestjs/core");
|
|
25
|
+
const ServiceTokenService_1 = require("../Services/ServiceTokenService/ServiceTokenService");
|
|
26
|
+
const authenticatedToken_1 = require("./authenticatedToken");
|
|
27
|
+
const serviceTokenRateLimit_1 = require("./serviceTokenRateLimit");
|
|
28
|
+
/** Chiave dei metadata usata da `@RequireServiceTokenScopes`. */
|
|
29
|
+
exports.SERVICE_TOKEN_SCOPES_METADATA = 'accessi:service-token-scopes';
|
|
30
|
+
/** Richiede che il token di servizio presenti tutti gli scope indicati. */
|
|
31
|
+
const RequireServiceTokenScopes = (...scopes) => (0, common_1.SetMetadata)(exports.SERVICE_TOKEN_SCOPES_METADATA, scopes);
|
|
32
|
+
exports.RequireServiceTokenScopes = RequireServiceTokenScopes;
|
|
33
|
+
/** Restituisce il token di servizio verificato da `ServiceTokenGuard`; lancia 401 se assente. */
|
|
34
|
+
function getAccessiServiceToken(req) {
|
|
35
|
+
const verified = req.accessiServiceToken;
|
|
36
|
+
if (!verified) {
|
|
37
|
+
throw new common_1.UnauthorizedException('Token di servizio non verificato.');
|
|
38
|
+
}
|
|
39
|
+
return verified;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Autentica le chiamate tecniche macchina-a-macchina tramite `Authorization: Bearer <token>`.
|
|
43
|
+
*
|
|
44
|
+
* Il token e per installazione/servizio, non legato a un utente. Gli scope richiesti si dichiarano
|
|
45
|
+
* con `@RequireServiceTokenScopes('ia')`.
|
|
46
|
+
*/
|
|
47
|
+
let ServiceTokenGuard = class ServiceTokenGuard {
|
|
48
|
+
constructor(serviceTokenService, reflector) {
|
|
49
|
+
this.serviceTokenService = serviceTokenService;
|
|
50
|
+
this.reflector = reflector;
|
|
51
|
+
}
|
|
52
|
+
canActivate(context) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
var _a, _b, _c, _d;
|
|
55
|
+
const request = context.switchToHttp().getRequest();
|
|
56
|
+
const ip = (_c = (_a = request.ip) !== null && _a !== void 0 ? _a : (_b = request.socket) === null || _b === void 0 ? void 0 : _b.remoteAddress) !== null && _c !== void 0 ? _c : 'unknown';
|
|
57
|
+
(0, serviceTokenRateLimit_1.assertServiceTokenRateLimit)(ip);
|
|
58
|
+
const token = (0, authenticatedToken_1.extractAccessiBearerToken)(request.headers['authorization']);
|
|
59
|
+
if (!token) {
|
|
60
|
+
throw new common_1.UnauthorizedException('Token di servizio mancante.');
|
|
61
|
+
}
|
|
62
|
+
const verified = yield this.serviceTokenService.verify(token, { ip });
|
|
63
|
+
if (!verified) {
|
|
64
|
+
throw new common_1.UnauthorizedException('Token di servizio non valido, scaduto o revocato.');
|
|
65
|
+
}
|
|
66
|
+
request.accessiServiceToken = verified;
|
|
67
|
+
const requiredScopes = (_d = this.reflector.getAllAndOverride(exports.SERVICE_TOKEN_SCOPES_METADATA, [
|
|
68
|
+
context.getHandler(),
|
|
69
|
+
context.getClass(),
|
|
70
|
+
])) !== null && _d !== void 0 ? _d : [];
|
|
71
|
+
const missingScope = requiredScopes.find((scope) => !(0, ServiceTokenService_1.serviceTokenHasScope)(verified.scopes, scope));
|
|
72
|
+
if (missingScope) {
|
|
73
|
+
throw new common_1.ForbiddenException(`Scope '${missingScope}' non autorizzato per questo token.`);
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
exports.ServiceTokenGuard = ServiceTokenGuard;
|
|
80
|
+
exports.ServiceTokenGuard = ServiceTokenGuard = __decorate([
|
|
81
|
+
(0, common_1.Injectable)(),
|
|
82
|
+
__metadata("design:paramtypes", [ServiceTokenService_1.ServiceTokenService,
|
|
83
|
+
core_1.Reflector])
|
|
84
|
+
], ServiceTokenGuard);
|
|
85
|
+
//# sourceMappingURL=serviceTokenGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceTokenGuard.js","sourceRoot":"","sources":["../../../src/accessi-module/security/serviceTokenGuard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,wDAMC;AA7BD,2CAOwB;AACxB,uCAAyC;AAEzC,6FAAsI;AACtI,6DAAiE;AACjE,mEAAsE;AAEtE,iEAAiE;AACpD,QAAA,6BAA6B,GAAG,8BAA8B,CAAC;AAE5E,2EAA2E;AACpE,MAAM,yBAAyB,GAAG,CAAC,GAAG,MAAgB,EAAE,EAAE,CAAC,IAAA,oBAAW,EAAC,qCAA6B,EAAE,MAAM,CAAC,CAAC;AAAxG,QAAA,yBAAyB,6BAA+E;AAIrH,iGAAiG;AACjG,SAAgB,sBAAsB,CAAC,GAAY;IACjD,MAAM,QAAQ,GAAI,GAAkC,CAAC,mBAAmB,CAAC;IACzE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,8BAAqB,CAAC,mCAAmC,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC5B,YACmB,mBAAwC,EACxC,SAAoB;QADpB,wBAAmB,GAAnB,mBAAmB,CAAqB;QACxC,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEE,WAAW,CAAC,OAAyB;;;YACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;YAC7D,MAAM,EAAE,GAAG,MAAA,MAAA,OAAO,CAAC,EAAE,mCAAI,MAAA,OAAO,CAAC,MAAM,0CAAE,aAAa,mCAAI,SAAS,CAAC;YACpE,IAAA,mDAA2B,EAAC,EAAE,CAAC,CAAC;YAEhC,MAAM,KAAK,GAAG,IAAA,8CAAyB,EAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;YAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;YACjE,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YACtE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,8BAAqB,CAAC,mDAAmD,CAAC,CAAC;YACvF,CAAC;YAEA,OAAsC,CAAC,mBAAmB,GAAG,QAAQ,CAAC;YAEvE,MAAM,cAAc,GAAG,MAAA,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAW,qCAA6B,EAAE;gBAC/F,OAAO,CAAC,UAAU,EAAE;gBACpB,OAAO,CAAC,QAAQ,EAAE;aACnB,CAAC,mCAAI,EAAE,CAAC;YACT,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAA,0CAAoB,EAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;YACnG,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,IAAI,2BAAkB,CAAC,UAAU,YAAY,qCAAqC,CAAC,CAAC;YAC5F,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;KAAA;CACF,CAAA;AAlCY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;qCAG6B,yCAAmB;QAC7B,gBAAS;GAH5B,iBAAiB,CAkC7B","sourcesContent":["import {\n CanActivate,\n ExecutionContext,\n ForbiddenException,\n Injectable,\n SetMetadata,\n UnauthorizedException,\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport type { Request } from 'express';\nimport { ServiceTokenService, serviceTokenHasScope, VerifiedServiceToken } from '../Services/ServiceTokenService/ServiceTokenService';\nimport { extractAccessiBearerToken } from './authenticatedToken';\nimport { assertServiceTokenRateLimit } from './serviceTokenRateLimit';\n\n/** Chiave dei metadata usata da `@RequireServiceTokenScopes`. */\nexport const SERVICE_TOKEN_SCOPES_METADATA = 'accessi:service-token-scopes';\n\n/** Richiede che il token di servizio presenti tutti gli scope indicati. */\nexport const RequireServiceTokenScopes = (...scopes: string[]) => SetMetadata(SERVICE_TOKEN_SCOPES_METADATA, scopes);\n\nexport type AccessiServiceTokenRequest = Request & { accessiServiceToken?: VerifiedServiceToken };\n\n/** Restituisce il token di servizio verificato da `ServiceTokenGuard`; lancia 401 se assente. */\nexport function getAccessiServiceToken(req: Request): VerifiedServiceToken {\n const verified = (req as AccessiServiceTokenRequest).accessiServiceToken;\n if (!verified) {\n throw new UnauthorizedException('Token di servizio non verificato.');\n }\n return verified;\n}\n\n/**\n * Autentica le chiamate tecniche macchina-a-macchina tramite `Authorization: Bearer <token>`.\n *\n * Il token e per installazione/servizio, non legato a un utente. Gli scope richiesti si dichiarano\n * con `@RequireServiceTokenScopes('ia')`.\n */\n@Injectable()\nexport class ServiceTokenGuard implements CanActivate {\n constructor(\n private readonly serviceTokenService: ServiceTokenService,\n private readonly reflector: Reflector,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest<Request>();\n const ip = request.ip ?? request.socket?.remoteAddress ?? 'unknown';\n assertServiceTokenRateLimit(ip);\n\n const token = extractAccessiBearerToken(request.headers['authorization']);\n if (!token) {\n throw new UnauthorizedException('Token di servizio mancante.');\n }\n\n const verified = await this.serviceTokenService.verify(token, { ip });\n if (!verified) {\n throw new UnauthorizedException('Token di servizio non valido, scaduto o revocato.');\n }\n\n (request as AccessiServiceTokenRequest).accessiServiceToken = verified;\n\n const requiredScopes = this.reflector.getAllAndOverride<string[]>(SERVICE_TOKEN_SCOPES_METADATA, [\n context.getHandler(),\n context.getClass(),\n ]) ?? [];\n const missingScope = requiredScopes.find((scope) => !serviceTokenHasScope(verified.scopes, scope));\n if (missingScope) {\n throw new ForbiddenException(`Scope '${missingScope}' non autorizzato per questo token.`);\n }\n\n return true;\n }\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function checkServiceTokenRateLimit(identifier: string): {
|
|
2
|
+
allowed: boolean;
|
|
3
|
+
retryAfterSeconds: number;
|
|
4
|
+
};
|
|
5
|
+
/** Svuota i bucket (usato nei test). */
|
|
6
|
+
export declare function resetServiceTokenRateLimit(): void;
|
|
7
|
+
/** Lancia 429 con `Retry-After` quando il limite e superato. */
|
|
8
|
+
export declare function assertServiceTokenRateLimit(identifier: string): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkServiceTokenRateLimit = checkServiceTokenRateLimit;
|
|
4
|
+
exports.resetServiceTokenRateLimit = resetServiceTokenRateLimit;
|
|
5
|
+
exports.assertServiceTokenRateLimit = assertServiceTokenRateLimit;
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
/**
|
|
8
|
+
* Limite anti-abuso per la verifica dei token di servizio.
|
|
9
|
+
*
|
|
10
|
+
* Il segreto ha 256 bit di entropia (brute force non praticabile), ma il limite evita
|
|
11
|
+
* che un client difettoso o malevolo martelli l'endpoint. In-memory: in cluster va
|
|
12
|
+
* aggiunto un limite anche al gateway.
|
|
13
|
+
*/
|
|
14
|
+
const WINDOW_MS = 60000;
|
|
15
|
+
const MAX_ATTEMPTS = 120;
|
|
16
|
+
const MAX_BUCKETS = 20000;
|
|
17
|
+
const buckets = new Map();
|
|
18
|
+
function checkServiceTokenRateLimit(identifier) {
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
const key = identifier && identifier.trim() !== '' ? identifier : 'unknown';
|
|
21
|
+
const bucket = buckets.get(key);
|
|
22
|
+
if (!bucket || bucket.resetAt <= now) {
|
|
23
|
+
if (buckets.size >= MAX_BUCKETS) {
|
|
24
|
+
const oldestKey = buckets.keys().next().value;
|
|
25
|
+
if (oldestKey !== undefined) {
|
|
26
|
+
buckets.delete(oldestKey);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
buckets.set(key, { count: 1, resetAt: now + WINDOW_MS });
|
|
30
|
+
return { allowed: true, retryAfterSeconds: 0 };
|
|
31
|
+
}
|
|
32
|
+
if (bucket.count >= MAX_ATTEMPTS) {
|
|
33
|
+
return { allowed: false, retryAfterSeconds: Math.max(1, Math.ceil((bucket.resetAt - now) / 1000)) };
|
|
34
|
+
}
|
|
35
|
+
bucket.count += 1;
|
|
36
|
+
return { allowed: true, retryAfterSeconds: 0 };
|
|
37
|
+
}
|
|
38
|
+
/** Svuota i bucket (usato nei test). */
|
|
39
|
+
function resetServiceTokenRateLimit() {
|
|
40
|
+
buckets.clear();
|
|
41
|
+
}
|
|
42
|
+
/** Lancia 429 con `Retry-After` quando il limite e superato. */
|
|
43
|
+
function assertServiceTokenRateLimit(identifier) {
|
|
44
|
+
const decision = checkServiceTokenRateLimit(identifier);
|
|
45
|
+
if (!decision.allowed) {
|
|
46
|
+
throw new common_1.HttpException({ code: 'ACCESSI_SERVICE_TOKEN_RATE_LIMITED', message: 'Troppi tentativi. Riprova piu tardi.' }, common_1.HttpStatus.TOO_MANY_REQUESTS);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=serviceTokenRateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceTokenRateLimit.js","sourceRoot":"","sources":["../../../src/accessi-module/security/serviceTokenRateLimit.ts"],"names":[],"mappings":";;AAgBA,gEAsBC;AAGD,gEAEC;AAGD,kEAQC;AAtDD,2CAA2D;AAI3D;;;;;;GAMG;AACH,MAAM,SAAS,GAAG,KAAM,CAAC;AACzB,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,WAAW,GAAG,KAAM,CAAC;AAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEnD,SAAgB,0BAA0B,CAAC,UAAkB;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEhC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,SAAS,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACjD,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC;IACtG,CAAC;IAED,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;AACjD,CAAC;AAED,wCAAwC;AACxC,SAAgB,0BAA0B;IACxC,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC;AAED,gEAAgE;AAChE,SAAgB,2BAA2B,CAAC,UAAkB;IAC5D,MAAM,QAAQ,GAAG,0BAA0B,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,sBAAa,CACrB,EAAE,IAAI,EAAE,oCAAoC,EAAE,OAAO,EAAE,sCAAsC,EAAE,EAC/F,mBAAU,CAAC,iBAAiB,CAC7B,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { HttpException, HttpStatus } from '@nestjs/common';\n\ntype RateLimitBucket = { count: number; resetAt: number };\n\n/**\n * Limite anti-abuso per la verifica dei token di servizio.\n *\n * Il segreto ha 256 bit di entropia (brute force non praticabile), ma il limite evita\n * che un client difettoso o malevolo martelli l'endpoint. In-memory: in cluster va\n * aggiunto un limite anche al gateway.\n */\nconst WINDOW_MS = 60_000;\nconst MAX_ATTEMPTS = 120;\nconst MAX_BUCKETS = 20_000;\nconst buckets = new Map<string, RateLimitBucket>();\n\nexport function checkServiceTokenRateLimit(identifier: string): { allowed: boolean; retryAfterSeconds: number } {\n const now = Date.now();\n const key = identifier && identifier.trim() !== '' ? identifier : 'unknown';\n const bucket = buckets.get(key);\n\n if (!bucket || bucket.resetAt <= now) {\n if (buckets.size >= MAX_BUCKETS) {\n const oldestKey = buckets.keys().next().value;\n if (oldestKey !== undefined) {\n buckets.delete(oldestKey);\n }\n }\n buckets.set(key, { count: 1, resetAt: now + WINDOW_MS });\n return { allowed: true, retryAfterSeconds: 0 };\n }\n\n if (bucket.count >= MAX_ATTEMPTS) {\n return { allowed: false, retryAfterSeconds: Math.max(1, Math.ceil((bucket.resetAt - now) / 1000)) };\n }\n\n bucket.count += 1;\n return { allowed: true, retryAfterSeconds: 0 };\n}\n\n/** Svuota i bucket (usato nei test). */\nexport function resetServiceTokenRateLimit(): void {\n buckets.clear();\n}\n\n/** Lancia 429 con `Retry-After` quando il limite e superato. */\nexport function assertServiceTokenRateLimit(identifier: string): void {\n const decision = checkServiceTokenRateLimit(identifier);\n if (!decision.allowed) {\n throw new HttpException(\n { code: 'ACCESSI_SERVICE_TOKEN_RATE_LIMITED', message: 'Troppi tentativi. Riprova piu tardi.' },\n HttpStatus.TOO_MANY_REQUESTS,\n );\n }\n}\n"]}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { DynamicModule } from "@nestjs/common";
|
|
2
|
+
import { Request } from "express";
|
|
2
3
|
import { Options } from "node-firebird";
|
|
3
4
|
export interface AllegatiOptions {
|
|
4
5
|
databaseOptions: Options;
|
|
6
|
+
/**
|
|
7
|
+
* Guard applicato a ogni richiesta dei controller Allegati.
|
|
8
|
+
* Se definito e restituisce `false`, la richiesta viene rifiutata con 403.
|
|
9
|
+
*/
|
|
10
|
+
authorize?: (request: Request) => boolean | Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Sicurezza by default: se `authorize` non e configurato, le richieste vengono rifiutate con 403.
|
|
13
|
+
* Impostare `false` per ripristinare il comportamento storico (endpoint aperti) durante la migrazione.
|
|
14
|
+
*/
|
|
15
|
+
requireAuthorization?: boolean;
|
|
5
16
|
}
|
|
6
17
|
export declare class AllegatiModule {
|
|
7
18
|
static forRoot(options: AllegatiOptions): DynamicModule;
|
|
@@ -9,10 +9,19 @@ var AllegatiModule_1;
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.AllegatiModule = void 0;
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
|
+
const Logger_1 = require("../Logger");
|
|
12
13
|
const AllegatiService_1 = require("./Services/AllegatiService/AllegatiService");
|
|
13
14
|
const AllegatiController_1 = require("./Controllers/AllegatiController");
|
|
15
|
+
const allegatiAuthorizationGuard_1 = require("./security/allegatiAuthorizationGuard");
|
|
14
16
|
let AllegatiModule = AllegatiModule_1 = class AllegatiModule {
|
|
15
17
|
static forRoot(options) {
|
|
18
|
+
const logger = new Logger_1.Logger(AllegatiModule_1.name);
|
|
19
|
+
if ((options === null || options === void 0 ? void 0 : options.requireAuthorization) === false) {
|
|
20
|
+
logger.warning('Allegati con requireAuthorization: false: gli endpoint sono accessibili senza controllo di autorizzazione. Configurare authorize e rimuovere l opt-out.');
|
|
21
|
+
}
|
|
22
|
+
else if (!(options === null || options === void 0 ? void 0 : options.authorize)) {
|
|
23
|
+
logger.error('Allegati senza authorize: tutte le richieste saranno rifiutate con 403. Configurare allegatiOptions.authorize (oppure requireAuthorization: false per il comportamento storico).');
|
|
24
|
+
}
|
|
16
25
|
return {
|
|
17
26
|
module: AllegatiModule_1,
|
|
18
27
|
providers: [
|
|
@@ -21,6 +30,7 @@ let AllegatiModule = AllegatiModule_1 = class AllegatiModule {
|
|
|
21
30
|
useValue: options,
|
|
22
31
|
},
|
|
23
32
|
AllegatiService_1.AllegatiService,
|
|
33
|
+
allegatiAuthorizationGuard_1.AllegatiAuthorizationGuard,
|
|
24
34
|
],
|
|
25
35
|
exports: ['ALLEGATI_OPTIONS', AllegatiService_1.AllegatiService],
|
|
26
36
|
};
|
|
@@ -31,7 +41,7 @@ exports.AllegatiModule = AllegatiModule = AllegatiModule_1 = __decorate([
|
|
|
31
41
|
(0, common_1.Global)(),
|
|
32
42
|
(0, common_1.Module)({
|
|
33
43
|
controllers: [AllegatiController_1.AllegatiController],
|
|
34
|
-
providers: [AllegatiService_1.AllegatiService],
|
|
44
|
+
providers: [AllegatiService_1.AllegatiService, allegatiAuthorizationGuard_1.AllegatiAuthorizationGuard],
|
|
35
45
|
exports: [AllegatiService_1.AllegatiService],
|
|
36
46
|
})
|
|
37
47
|
], AllegatiModule);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllegatiModule.js","sourceRoot":"","sources":["../../src/allegati-module/AllegatiModule.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;
|
|
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\";\r\nimport { Request } from \"express\";\r\nimport { Options } from \"node-firebird\";\r\nimport { Logger } from \"../Logger\";\r\nimport { AllegatiService } from \"./Services/AllegatiService/AllegatiService\";\r\nimport { AllegatiController } from \"./Controllers/AllegatiController\";\r\nimport { AllegatiAuthorizationGuard } from \"./security/allegatiAuthorizationGuard\";\r\n\r\nexport interface AllegatiOptions {\r\n databaseOptions: Options;\r\n /**\r\n * Guard applicato a ogni richiesta dei controller Allegati.\r\n * Se definito e restituisce `false`, la richiesta viene rifiutata con 403.\r\n */\r\n authorize?: (request: Request) => boolean | Promise<boolean>;\r\n /**\r\n * Sicurezza by default: se `authorize` non e configurato, le richieste vengono rifiutate con 403.\r\n * Impostare `false` per ripristinare il comportamento storico (endpoint aperti) durante la migrazione.\r\n */\r\n requireAuthorization?: boolean;\r\n}\r\n\r\n@Global()\r\n@Module({\r\n controllers: [AllegatiController],\r\n providers: [AllegatiService, AllegatiAuthorizationGuard],\r\n exports: [AllegatiService],\r\n})\r\nexport class AllegatiModule {\r\n\r\n static forRoot(options: AllegatiOptions): DynamicModule {\r\n const logger = new Logger(AllegatiModule.name);\r\n if (options?.requireAuthorization === false) {\r\n logger.warning('Allegati con requireAuthorization: false: gli endpoint sono accessibili senza controllo di autorizzazione. Configurare authorize e rimuovere l opt-out.');\r\n } else if (!options?.authorize) {\r\n logger.error('Allegati senza authorize: tutte le richieste saranno rifiutate con 403. Configurare allegatiOptions.authorize (oppure requireAuthorization: false per il comportamento storico).');\r\n }\r\n\r\n return {\r\n module: AllegatiModule,\r\n providers: [\r\n {\r\n provide: 'ALLEGATI_OPTIONS',\r\n useValue: options,\r\n },\r\n AllegatiService,\r\n AllegatiAuthorizationGuard,\r\n ],\r\n exports: ['ALLEGATI_OPTIONS', AllegatiService],\r\n };\r\n }\r\n}\n"]}
|
|
@@ -6,6 +6,7 @@ import { UploadSingleFileRequest } from "../Dtos/UploadSingleFileRequest";
|
|
|
6
6
|
import e from "express";
|
|
7
7
|
export declare class AllegatiController {
|
|
8
8
|
private readonly allegatiService;
|
|
9
|
+
private readonly logger;
|
|
9
10
|
constructor(allegatiService: AllegatiService);
|
|
10
11
|
upload(files: Express.Multer.File[], uploadRequest: UploadSingleFileRequest): Promise<UploadAllegatoResponseDto>;
|
|
11
12
|
download(id: number): Promise<DownloadAllegatoResponseDto>;
|
|
@@ -23,7 +24,7 @@ export declare class AllegatiController {
|
|
|
23
24
|
codice?: number;
|
|
24
25
|
docrif?: string;
|
|
25
26
|
idxtipoall?: number;
|
|
26
|
-
}): Promise<AllegatoDto>;
|
|
27
|
+
}): Promise<AllegatoDto | null>;
|
|
27
28
|
updateFieldsById(id: number, body: {
|
|
28
29
|
tipcod?: string;
|
|
29
30
|
codice?: number;
|
|
@@ -23,21 +23,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
23
23
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
24
24
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
25
25
|
};
|
|
26
|
+
var AllegatiController_1;
|
|
26
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
28
|
exports.AllegatiController = void 0;
|
|
28
29
|
const swagger_1 = require("@nestjs/swagger");
|
|
29
30
|
const common_1 = require("@nestjs/common");
|
|
30
31
|
const platform_express_1 = require("@nestjs/platform-express");
|
|
32
|
+
const allegatiAuthorizationGuard_1 = require("../security/allegatiAuthorizationGuard");
|
|
31
33
|
const AllegatiService_1 = require("../Services/AllegatiService/AllegatiService");
|
|
32
34
|
const UploadAllegatoResponseDto_1 = require("../Dtos/responses/UploadAllegatoResponseDto");
|
|
33
35
|
const AllegatoDto_1 = require("../Dtos/AllegatoDto");
|
|
34
36
|
const DownloadAllegatoResponseDto_1 = require("../Dtos/responses/DownloadAllegatoResponseDto");
|
|
35
37
|
const UploadSingleFileRequest_1 = require("../Dtos/UploadSingleFileRequest");
|
|
36
38
|
const Utilities_1 = require("../../Utilities");
|
|
39
|
+
const Logger_1 = require("../../Logger");
|
|
37
40
|
const express_1 = __importDefault(require("express"));
|
|
38
|
-
let AllegatiController = class AllegatiController {
|
|
41
|
+
let AllegatiController = AllegatiController_1 = class AllegatiController {
|
|
39
42
|
constructor(allegatiService) {
|
|
40
43
|
this.allegatiService = allegatiService;
|
|
44
|
+
this.logger = new Logger_1.Logger(AllegatiController_1.name);
|
|
41
45
|
}
|
|
42
46
|
upload(files, uploadRequest) {
|
|
43
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -47,7 +51,11 @@ let AllegatiController = class AllegatiController {
|
|
|
47
51
|
if (files.length > 1) {
|
|
48
52
|
throw new common_1.BadRequestException('Questo endpoint accetta un solo file alla volta');
|
|
49
53
|
}
|
|
50
|
-
|
|
54
|
+
const file = files[0];
|
|
55
|
+
if (!file) {
|
|
56
|
+
throw new common_1.BadRequestException('Nessun file fornito');
|
|
57
|
+
}
|
|
58
|
+
return yield this.allegatiService.uploadFile(file, uploadRequest);
|
|
51
59
|
});
|
|
52
60
|
}
|
|
53
61
|
download(id) {
|
|
@@ -57,28 +65,27 @@ let AllegatiController = class AllegatiController {
|
|
|
57
65
|
}
|
|
58
66
|
downloadFile(id, res) {
|
|
59
67
|
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
var _a;
|
|
60
69
|
try {
|
|
61
70
|
const file = yield this.allegatiService.downloadFile(id);
|
|
62
|
-
// Convert base64 to buffer in chunks
|
|
71
|
+
// Convert base64 to buffer in chunks; Buffer.concat evita i NUL finali del prealloc.
|
|
63
72
|
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
64
73
|
const base64Content = file.contentBase64;
|
|
65
|
-
const
|
|
66
|
-
const buffer = Buffer.alloc(bufferSize);
|
|
67
|
-
let bufferIndex = 0;
|
|
74
|
+
const chunks = [];
|
|
68
75
|
for (let i = 0; i < base64Content.length; i += chunkSize) {
|
|
69
76
|
const chunk = base64Content.slice(i, i + chunkSize);
|
|
70
|
-
|
|
71
|
-
chunkBuffer.copy(buffer, bufferIndex);
|
|
72
|
-
bufferIndex += chunkBuffer.length;
|
|
77
|
+
chunks.push(Buffer.from(chunk, 'base64'));
|
|
73
78
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
const buffer = Buffer.concat(chunks);
|
|
80
|
+
// Set headers for file download; filename* (RFC 5987) per i nomi non ASCII.
|
|
81
|
+
const asciiName = file.filename.replace(/[^\x20-\x7e]/g, '_').replace(/["\\]/g, '_');
|
|
82
|
+
res.setHeader('Content-Type', (_a = file.mimetype) !== null && _a !== void 0 ? _a : 'application/octet-stream');
|
|
83
|
+
res.setHeader('Content-Disposition', `attachment; filename="${asciiName}"; filename*=UTF-8''${encodeURIComponent(file.filename)}`);
|
|
77
84
|
res.setHeader('Content-Length', buffer.length);
|
|
78
85
|
res.status(200).end(buffer);
|
|
79
86
|
}
|
|
80
87
|
catch (error) {
|
|
81
|
-
|
|
88
|
+
this.logger.error('[AllegatiController] downloadFile - Errore:', error);
|
|
82
89
|
throw error;
|
|
83
90
|
}
|
|
84
91
|
});
|
|
@@ -119,7 +126,7 @@ let AllegatiController = class AllegatiController {
|
|
|
119
126
|
exports.AllegatiController = AllegatiController;
|
|
120
127
|
__decorate([
|
|
121
128
|
(0, common_1.Post)('upload'),
|
|
122
|
-
(0, common_1.UseInterceptors)((0, platform_express_1.FilesInterceptor)('file')),
|
|
129
|
+
(0, common_1.UseInterceptors)((0, platform_express_1.FilesInterceptor)('file', 1, { limits: { fileSize: 90 * 1024 * 1024, files: 1 } })),
|
|
123
130
|
(0, swagger_1.ApiConsumes)('multipart/form-data'),
|
|
124
131
|
(0, swagger_1.ApiResponse)({ status: 201, description: 'File caricato con successo.', type: UploadAllegatoResponseDto_1.UploadAllegatoResponseDto }),
|
|
125
132
|
(0, swagger_1.ApiBody)({
|
|
@@ -215,7 +222,8 @@ __decorate([
|
|
|
215
222
|
__metadata("design:paramtypes", [Number, Object]),
|
|
216
223
|
__metadata("design:returntype", Promise)
|
|
217
224
|
], AllegatiController.prototype, "updateFieldsById", null);
|
|
218
|
-
exports.AllegatiController = AllegatiController = __decorate([
|
|
225
|
+
exports.AllegatiController = AllegatiController = AllegatiController_1 = __decorate([
|
|
226
|
+
(0, common_1.UseGuards)(allegatiAuthorizationGuard_1.AllegatiAuthorizationGuard),
|
|
219
227
|
(0, common_1.Controller)('allegati'),
|
|
220
228
|
__metadata("design:paramtypes", [AllegatiService_1.AllegatiService])
|
|
221
229
|
], AllegatiController);
|
|
@@ -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\";\n\nimport { Controller, Post, Get, Delete, Param, UploadedFiles, UseInterceptors, BadRequestException, Body, Response, Query, Res, Patch } from \"@nestjs/common\";\nimport { FilesInterceptor } from \"@nestjs/platform-express\";\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 e from \"express\";\nimport { GetListResponse } from \"../Dtos/responses/GetListResponse\";\n\n@Controller('allegati')\nexport class AllegatiController {\n\n constructor(private readonly allegatiService: AllegatiService) {}\n\n @Post('upload')\n @UseInterceptors(FilesInterceptor('file'))\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 return await this.allegatiService.uploadFile(files[0], 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\n const chunkSize = 1024 * 1024; // 1MB chunks\n const base64Content = file.contentBase64;\n const bufferSize = Math.ceil((base64Content.length * 3) / 4);\n const buffer = Buffer.alloc(bufferSize);\n \n let bufferIndex = 0;\n for (let i = 0; i < base64Content.length; i += chunkSize) {\n const chunk = base64Content.slice(i, i + chunkSize);\n const chunkBuffer = Buffer.from(chunk, 'base64');\n chunkBuffer.copy(buffer, bufferIndex);\n bufferIndex += chunkBuffer.length;\n }\n\n // Set headers for file download\n res.setHeader('Content-Type', file.mimetype);\n res.setHeader('Content-Disposition', `attachment; filename=\"${file.filename}\"`);\n res.setHeader('Content-Length', buffer.length);\n \n res.status(200).end(buffer);\n } catch (error) {\n console.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
|
+
{"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 +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;;
|
|
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\";\r\nimport { IsString, IsNotEmpty, IsNumber, IsOptional } from \"class-validator\";\r\n\r\nexport class AllegatoDto {\r\n\r\n @ApiProperty({\r\n description: 'ID univoco dell\\'allegato',\r\n example: 1,\r\n })\r\n @IsNumber()\r\n id!: number;\r\n\r\n @ApiProperty({\r\n description: 'Nome originale del file caricato',\r\n example: 'documento.pdf',\r\n })\r\n @IsString()\r\n @IsNotEmpty({ message: \"Il nome file è obbligatorio.\" })\r\n filename!: string;\r\n\r\n @ApiProperty({\r\n description: 'Tipo MIME del file',\r\n example: 'application/pdf',\r\n })\r\n @IsString()\r\n @IsNotEmpty({ message: \"Il tipo MIME è obbligatorio.\" })\r\n mimetype!: string;\r\n\r\n @ApiProperty({\r\n description: 'Data di caricamento del file in formato ISO',\r\n example: '2025-04-27T12:00:00Z',\r\n })\r\n @IsString()\r\n @IsNotEmpty({ message: \"La data di upload è obbligatoria.\" })\r\n uploadDate!: string;\r\n\r\n @ApiProperty({\r\n description: 'Codice incrementale',\r\n example: '1',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n codice?: string;\r\n\r\n @ApiProperty({\r\n description: 'Tipo del codice fornito',\r\n example: 'CF',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n tipoCodice?: string;\r\n\r\n @ApiProperty({\r\n description: 'Numero o valore usato per ordinare o identificare la sequenza degli allegati',\r\n example: '1',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n ordine?: string;\r\n\r\n @ApiProperty({\r\n description: 'Descrizione testuale dell\\'allegato',\r\n example: 'Documento di identità fronte',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n descrizioneAllegato?: string;\r\n\r\n @ApiProperty({\r\n description: 'Data di inizio validità del documento',\r\n example: '2024-01-01',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n dataInizioValidita?: string;\r\n\r\n @ApiProperty({\r\n description: 'Data di fine validità del documento',\r\n example: '2025-01-01',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n dataFineValidita?: string;\r\n\r\n @ApiProperty({\r\n description: 'ID del tipo di allegato',\r\n example: 3,\r\n })\r\n @IsNumber()\r\n @IsOptional()\r\n idTipoAllegato?: number;\r\n\r\n @ApiProperty({\r\n description: 'Riferimento esterno o identificativo del documento',\r\n example: 'PRAT-2024-0001',\r\n })\r\n @IsString()\r\n @IsOptional()\r\n riferimentoDocumento?: string;\r\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;;
|
|
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';\r\nimport { Type } from 'class-transformer';\r\nimport { IsObject, IsString, ValidateNested } from 'class-validator';\r\n\r\nexport class Status {\r\n @ApiProperty({ example: '0', description: 'Codice di errore, \"0\" se tutto ok' })\r\n @IsString()\r\n errorCode!: string;\r\n\r\n @ApiProperty({ example: 'Success', description: 'Descrizione dell\\'errore o successo' })\r\n @IsString()\r\n errorDescription!: string;\r\n}\r\n\r\nexport abstract class BaseResponse {\r\n @ApiProperty({ type: Status })\r\n @ValidateNested()\r\n @Type(() => Status)\r\n @IsObject()\r\n Status!: Status;\r\n}\r\n"]}
|