emilsoftware-utilities 2.0.0-dev.6 → 2.0.0-dev.61
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 +213 -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.d.ts +1 -1
- package/dist/DatabaseUpdater.js +32 -29
- package/dist/DatabaseUpdater.js.map +1 -1
- package/dist/EmilsoftwareModule.d.ts +6 -0
- 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 +32 -12
- package/dist/Orm.js +194 -153
- 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 +143 -38
- package/dist/Utilities.js.map +1 -1
- package/dist/accessi-module/AccessiModule.d.ts +122 -1
- package/dist/accessi-module/AccessiModule.js +38 -5
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/accessiFetch.d.ts +16 -0
- package/dist/accessi-module/Console/accessiFetch.js +87 -0
- package/dist/accessi-module/Console/accessiFetch.js.map +1 -0
- package/dist/accessi-module/Console/console.css +774 -0
- package/dist/accessi-module/Console/console.d.ts +1 -0
- package/dist/accessi-module/Console/console.js +3974 -0
- package/dist/accessi-module/Console/console.js.map +1 -0
- package/dist/accessi-module/Console/generated/accessiApi.d.ts +711 -0
- package/dist/accessi-module/Console/generated/accessiApi.js +671 -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/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/adminBootstrapStatusResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/adminBootstrapStatusResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/adminBootstrapStatusResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/adminBootstrapStatusResult.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/adminBootstrapStatusResult.js +9 -0
- package/dist/accessi-module/Console/generated/model/adminBootstrapStatusResult.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/bootstrapAdminRequest.d.ts +17 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminResultDto.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminResultDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/bootstrapAdminResultDto.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/consoleEntryExchangeRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryExchangeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryExchangeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/consoleEntrySessionResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/consoleEntrySessionResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/consoleEntrySessionResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/consoleEntrySessionResult.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/consoleEntrySessionResult.js +3 -0
- package/dist/accessi-module/Console/generated/model/consoleEntrySessionResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTicketResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTicketResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTicketResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTicketResult.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTicketResult.js +9 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTicketResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTokenResult.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTokenResult.js +9 -0
- package/dist/accessi-module/Console/generated/model/consoleEntryTokenResult.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 +22 -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/createScopeRequest.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/createScopeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createScopeRequest.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 +16 -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/getMenuScopesResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getMenuScopesResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getMenuScopesResponse.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/getMenusParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getMenusParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getMenusParams.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/getSchemaResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getSchemaResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getSchemaResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getScopesResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getScopesResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getScopesResponse.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/getUserRolesAndGrantsParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getUserRolesAndGrantsParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getUserRolesAndGrantsParams.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 +120 -0
- package/dist/accessi-module/Console/generated/model/index.js +137 -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/loginAsRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/loginAsRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/loginAsRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginAsResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/loginAsResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/loginAsResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginAsResult.d.ts +16 -0
- package/dist/accessi-module/Console/generated/model/loginAsResult.js +9 -0
- package/dist/accessi-module/Console/generated/model/loginAsResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/loginRequest.d.ts +14 -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/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/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/schemaDdlResult.d.ts +20 -0
- package/dist/accessi-module/Console/generated/model/schemaDdlResult.js +3 -0
- package/dist/accessi-module/Console/generated/model/schemaDdlResult.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/schemaDdlSection.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/schemaDdlSection.js +9 -0
- package/dist/accessi-module/Console/generated/model/schemaDdlSection.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/scopeEntity.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/scopeEntity.js +9 -0
- package/dist/accessi-module/Console/generated/model/scopeEntity.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/setMenuScopesRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/setMenuScopesRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/setMenuScopesRequest.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/setScopeMenusRequest.d.ts +10 -0
- package/dist/accessi-module/Console/generated/model/setScopeMenusRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/setScopeMenusRequest.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/setUserPasswordRequest.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/setUserPasswordRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/setUserPasswordRequest.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 +17 -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/updateScopeRequest.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/updateScopeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateScopeRequest.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/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 +417 -0
- package/dist/accessi-module/Console/help.js.map +1 -0
- package/dist/accessi-module/Console/index.html +141 -0
- package/dist/accessi-module/Console/wiki.d.ts +52 -0
- package/dist/accessi-module/Console/wiki.js +740 -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 +13 -6
- package/dist/accessi-module/Controllers/AuthController.js +185 -82
- package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
- package/dist/accessi-module/Controllers/ConfiguratorController.d.ts +1 -5
- package/dist/accessi-module/Controllers/ConfiguratorController.js +26 -44
- package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
- package/dist/accessi-module/Controllers/ConsoleEntryController.d.ts +14 -0
- package/dist/accessi-module/Controllers/ConsoleEntryController.js +128 -0
- package/dist/accessi-module/Controllers/ConsoleEntryController.js.map +1 -0
- package/dist/accessi-module/Controllers/EmailController.d.ts +4 -6
- package/dist/accessi-module/Controllers/EmailController.js +12 -14
- package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
- package/dist/accessi-module/Controllers/FiltriController.d.ts +12 -4
- package/dist/accessi-module/Controllers/FiltriController.js +153 -6
- package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
- package/dist/accessi-module/Controllers/PermissionController.d.ts +31 -5
- package/dist/accessi-module/Controllers/PermissionController.js +559 -66
- package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
- package/dist/accessi-module/Controllers/SchemaController.d.ts +9 -0
- package/dist/accessi-module/Controllers/SchemaController.js +79 -0
- package/dist/accessi-module/Controllers/SchemaController.js.map +1 -0
- 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 +22 -5
- package/dist/accessi-module/Controllers/UserController.js +384 -32
- 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/AdminBootstrapDtos.d.ts +26 -0
- package/dist/accessi-module/Dtos/AdminBootstrapDtos.js +100 -0
- package/dist/accessi-module/Dtos/AdminBootstrapDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js +0 -1
- package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js +1 -2
- package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.d.ts +13 -0
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js +70 -0
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js.map +1 -0
- package/dist/accessi-module/Dtos/BaseResponse.d.ts +22 -0
- package/dist/accessi-module/Dtos/BaseResponse.js +106 -1
- package/dist/accessi-module/Dtos/BaseResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/CatalogDtos.d.ts +64 -0
- package/dist/accessi-module/Dtos/CatalogDtos.js +322 -0
- package/dist/accessi-module/Dtos/CatalogDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/ConfirmResetPasswordRequest.d.ts +3 -0
- package/dist/accessi-module/Dtos/ConfirmResetPasswordRequest.js +31 -0
- package/dist/accessi-module/Dtos/ConfirmResetPasswordRequest.js.map +1 -0
- package/dist/accessi-module/Dtos/ConsoleEntryDtos.d.ts +24 -0
- package/dist/accessi-module/Dtos/ConsoleEntryDtos.js +77 -0
- package/dist/accessi-module/Dtos/ConsoleEntryDtos.js.map +1 -0
- 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 +5 -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.d.ts +3 -0
- package/dist/accessi-module/Dtos/GetUserByTokenRequest.js +26 -0
- package/dist/accessi-module/Dtos/GetUserByTokenRequest.js.map +1 -0
- package/dist/accessi-module/Dtos/GetUserByTokenResponse.d.ts +5 -0
- package/dist/accessi-module/Dtos/GetUserByTokenResponse.js +27 -0
- package/dist/accessi-module/Dtos/GetUserByTokenResponse.js.map +1 -0
- 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/LoginAsDtos.d.ts +15 -0
- package/dist/accessi-module/Dtos/LoginAsDtos.js +68 -0
- package/dist/accessi-module/Dtos/LoginAsDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/LoginRequest.d.ts +3 -1
- package/dist/accessi-module/Dtos/LoginRequest.js +13 -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 +5 -0
- package/dist/accessi-module/Dtos/PublicRegisterRequest.js +15 -0
- package/dist/accessi-module/Dtos/PublicRegisterRequest.js.map +1 -0
- package/dist/accessi-module/Dtos/RegisterRequest.d.ts +2 -4
- package/dist/accessi-module/Dtos/RegisterRequest.js +17 -27
- package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterResponse.d.ts +1 -1
- package/dist/accessi-module/Dtos/RegisterResponse.js +3 -3
- 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/SchemaDtos.d.ts +19 -0
- package/dist/accessi-module/Dtos/SchemaDtos.js +84 -0
- package/dist/accessi-module/Dtos/SchemaDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/ScopeDtos.d.ts +28 -0
- package/dist/accessi-module/Dtos/ScopeDtos.js +103 -0
- package/dist/accessi-module/Dtos/ScopeDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/SendResetPasswordEmailRequest.d.ts +4 -0
- package/dist/accessi-module/Dtos/SendResetPasswordEmailRequest.js +36 -0
- package/dist/accessi-module/Dtos/SendResetPasswordEmailRequest.js.map +1 -0
- 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/SetUserPasswordRequest.d.ts +4 -0
- package/dist/accessi-module/Dtos/SetUserPasswordRequest.js +32 -0
- package/dist/accessi-module/Dtos/SetUserPasswordRequest.js.map +1 -0
- 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 +9 -4
- package/dist/accessi-module/Dtos/UserDto.js +37 -22
- 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.d.ts +5 -0
- package/dist/accessi-module/Dtos/UserGrantsResponse.js +27 -0
- package/dist/accessi-module/Dtos/UserGrantsResponse.js.map +1 -0
- package/dist/accessi-module/Dtos/index.d.ts +15 -0
- package/dist/accessi-module/Dtos/index.js +15 -0
- package/dist/accessi-module/Dtos/index.js.map +1 -1
- package/dist/accessi-module/Services/AdminBootstrapService/AdminBootstrapService.d.ts +33 -0
- package/dist/accessi-module/Services/AdminBootstrapService/AdminBootstrapService.js +106 -0
- package/dist/accessi-module/Services/AdminBootstrapService/AdminBootstrapService.js.map +1 -0
- package/dist/accessi-module/Services/AuthService/AuthService.d.ts +61 -5
- package/dist/accessi-module/Services/AuthService/AuthService.js +227 -50
- 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 +47 -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 -16
- package/dist/accessi-module/Services/FiltriService/FiltriService.js.map +1 -1
- package/dist/accessi-module/Services/PermissionService/PermissionService.d.ts +107 -5
- package/dist/accessi-module/Services/PermissionService/PermissionService.js +788 -215
- package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
- package/dist/accessi-module/Services/SchemaExportService/SchemaExportService.d.ts +36 -0
- package/dist/accessi-module/Services/SchemaExportService/SchemaExportService.js +125 -0
- package/dist/accessi-module/Services/SchemaExportService/SchemaExportService.js.map +1 -0
- 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 +67 -5
- package/dist/accessi-module/Services/UserService/UserService.js +520 -335
- package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
- package/dist/accessi-module/Views/reset-password.html +229 -213
- package/dist/accessi-module/accessiRuntime.d.ts +45 -0
- package/dist/accessi-module/accessiRuntime.js +39 -0
- package/dist/accessi-module/accessiRuntime.js.map +1 -0
- package/dist/accessi-module/database-updates/AccessiCatalogMigrator.d.ts +83 -0
- package/dist/accessi-module/database-updates/AccessiCatalogMigrator.js +360 -0
- package/dist/accessi-module/database-updates/AccessiCatalogMigrator.js.map +1 -0
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.d.ts +58 -10
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +508 -179
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
- package/dist/accessi-module/database-updates/accessiOptionsFromEnv.d.ts +5 -0
- package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js +79 -0
- package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js.map +1 -0
- package/dist/accessi-module/database-updates/accessiSchema.d.ts +67 -0
- package/dist/accessi-module/database-updates/accessiSchema.js +135 -0
- package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -0
- package/dist/accessi-module/database-updates/menuScopeSeed.d.ts +15 -0
- package/dist/accessi-module/database-updates/menuScopeSeed.js +338 -0
- package/dist/accessi-module/database-updates/menuScopeSeed.js.map +1 -0
- package/dist/accessi-module/database-updates/menuScopeSeeder.d.ts +8 -0
- package/dist/accessi-module/database-updates/menuScopeSeeder.js +131 -0
- package/dist/accessi-module/database-updates/menuScopeSeeder.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/runAccessiCatalogMigrations.d.ts +1 -0
- package/dist/accessi-module/database-updates/runAccessiCatalogMigrations.js +69 -0
- package/dist/accessi-module/database-updates/runAccessiCatalogMigrations.js.map +1 -0
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js +18 -53
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js.map +1 -1
- package/dist/accessi-module/federated-auth/FederatedAuthController.d.ts +33 -0
- package/dist/accessi-module/federated-auth/FederatedAuthController.js +373 -0
- package/dist/accessi-module/federated-auth/FederatedAuthController.js.map +1 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.d.ts +102 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.js +461 -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 +30 -0
- package/dist/accessi-module/index.js +93 -20
- 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 +77 -0
- package/dist/accessi-module/security/AccessiHttpExceptionFilter.js.map +1 -0
- package/dist/accessi-module/security/accessControl.d.ts +48 -2
- package/dist/accessi-module/security/accessControl.js +84 -8
- 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/adminBootstrap.d.ts +8 -0
- package/dist/accessi-module/security/adminBootstrap.js +41 -0
- package/dist/accessi-module/security/adminBootstrap.js.map +1 -0
- package/dist/accessi-module/security/authenticatedToken.d.ts +22 -2
- package/dist/accessi-module/security/authenticatedToken.js +44 -4
- package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
- package/dist/accessi-module/security/consoleEntry.d.ts +16 -0
- package/dist/accessi-module/security/consoleEntry.js +50 -0
- package/dist/accessi-module/security/consoleEntry.js.map +1 -0
- package/dist/accessi-module/security/emailConfiguration.d.ts +20 -0
- package/dist/accessi-module/security/emailConfiguration.js +41 -0
- package/dist/accessi-module/security/emailConfiguration.js.map +1 -0
- package/dist/accessi-module/security/loginAs.d.ts +8 -0
- package/dist/accessi-module/security/loginAs.js +45 -0
- package/dist/accessi-module/security/loginAs.js.map +1 -0
- package/dist/accessi-module/security/passwordPolicy.d.ts +21 -0
- package/dist/accessi-module/security/passwordPolicy.js +71 -0
- package/dist/accessi-module/security/passwordPolicy.js.map +1 -0
- 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 +32 -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/accessi-module/startupLog.d.ts +6 -0
- package/dist/accessi-module/startupLog.js +25 -0
- package/dist/accessi-module/startupLog.js.map +1 -0
- package/dist/allegati-module/AllegatiModule.d.ts +12 -1
- 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/emilsoftware-utilities-2.0.0-dev.61.tgz +0 -0
- package/dist/firebird-compat.d.ts +27 -6
- package/dist/firebird-compat.js +150 -140
- package/dist/firebird-compat.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/initEmilsoftwareModule.js +35 -9
- 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.d.ts +7 -1
- package/dist/swagger/SwaggerConfig.js +23 -8
- package/dist/swagger/SwaggerConfig.js.map +1 -1
- package/package.json +110 -83
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LOGIN_AS_QUERY_PARAM = void 0;
|
|
4
|
+
exports.buildLoginAsUrl = buildLoginAsUrl;
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
/** Nome del query parameter usato dalle applicazioni per consumare il token. */
|
|
7
|
+
exports.LOGIN_AS_QUERY_PARAM = 'loginAsToken';
|
|
8
|
+
/**
|
|
9
|
+
* Combina l'URL dell'applicazione con il token di accesso temporaneo.
|
|
10
|
+
* Accetta solo URL assoluti http/https: evita schemi come javascript: o data:
|
|
11
|
+
* che verrebbero restituiti alla console come link cliccabile.
|
|
12
|
+
*/
|
|
13
|
+
function buildLoginAsUrl(targetUrl, token) {
|
|
14
|
+
if (typeof targetUrl !== 'string' || targetUrl.trim() === '') {
|
|
15
|
+
throw new common_1.BadRequestException({
|
|
16
|
+
code: 'ACCESSI_LOGIN_AS_INVALID_URL',
|
|
17
|
+
message: 'Indica l URL dell applicazione a cui accedere.',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (typeof token !== 'string' || token.trim() === '') {
|
|
21
|
+
throw new common_1.BadRequestException({
|
|
22
|
+
code: 'ACCESSI_LOGIN_AS_INVALID_TOKEN',
|
|
23
|
+
message: 'Token di accesso temporaneo non valido.',
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
let parsed;
|
|
27
|
+
try {
|
|
28
|
+
parsed = new URL(targetUrl.trim());
|
|
29
|
+
}
|
|
30
|
+
catch (_a) {
|
|
31
|
+
throw new common_1.BadRequestException({
|
|
32
|
+
code: 'ACCESSI_LOGIN_AS_INVALID_URL',
|
|
33
|
+
message: 'L URL deve essere assoluto e valido, per esempio https://app.example.com.',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
37
|
+
throw new common_1.BadRequestException({
|
|
38
|
+
code: 'ACCESSI_LOGIN_AS_INVALID_URL',
|
|
39
|
+
message: 'L URL deve usare http o https.',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
parsed.searchParams.set(exports.LOGIN_AS_QUERY_PARAM, token);
|
|
43
|
+
return parsed.toString();
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=loginAs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loginAs.js","sourceRoot":"","sources":["../../../src/accessi-module/security/loginAs.ts"],"names":[],"mappings":";;;AAUA,0CAiCC;AA3CD,2CAAqD;AAErD,gFAAgF;AACnE,QAAA,oBAAoB,GAAG,cAAc,CAAC;AAEnD;;;;GAIG;AACH,SAAgB,eAAe,CAAC,SAAiB,EAAE,KAAa;IAC9D,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7D,MAAM,IAAI,4BAAmB,CAAC;YAC5B,IAAI,EAAE,8BAA8B;YACpC,OAAO,EAAE,gDAAgD;SAC1D,CAAC,CAAC;IACL,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,4BAAmB,CAAC;YAC5B,IAAI,EAAE,gCAAgC;YACtC,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,WAAM,CAAC;QACP,MAAM,IAAI,4BAAmB,CAAC;YAC5B,IAAI,EAAE,8BAA8B;YACpC,OAAO,EAAE,2EAA2E;SACrF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,4BAAmB,CAAC;YAC5B,IAAI,EAAE,8BAA8B;YACpC,OAAO,EAAE,gCAAgC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,4BAAoB,EAAE,KAAK,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["import { BadRequestException } from '@nestjs/common';\n\n/** Nome del query parameter usato dalle applicazioni per consumare il token. */\nexport const LOGIN_AS_QUERY_PARAM = 'loginAsToken';\n\n/**\n * Combina l'URL dell'applicazione con il token di accesso temporaneo.\n * Accetta solo URL assoluti http/https: evita schemi come javascript: o data:\n * che verrebbero restituiti alla console come link cliccabile.\n */\nexport function buildLoginAsUrl(targetUrl: string, token: string): string {\n if (typeof targetUrl !== 'string' || targetUrl.trim() === '') {\n throw new BadRequestException({\n code: 'ACCESSI_LOGIN_AS_INVALID_URL',\n message: 'Indica l URL dell applicazione a cui accedere.',\n });\n }\n if (typeof token !== 'string' || token.trim() === '') {\n throw new BadRequestException({\n code: 'ACCESSI_LOGIN_AS_INVALID_TOKEN',\n message: 'Token di accesso temporaneo non valido.',\n });\n }\n\n let parsed: URL;\n try {\n parsed = new URL(targetUrl.trim());\n } catch {\n throw new BadRequestException({\n code: 'ACCESSI_LOGIN_AS_INVALID_URL',\n message: 'L URL deve essere assoluto e valido, per esempio https://app.example.com.',\n });\n }\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new BadRequestException({\n code: 'ACCESSI_LOGIN_AS_INVALID_URL',\n message: 'L URL deve usare http o https.',\n });\n }\n\n parsed.searchParams.set(LOGIN_AS_QUERY_PARAM, token);\n return parsed.toString();\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Lunghezze canoniche della password Accessi. */
|
|
2
|
+
export declare const PASSWORD_MIN_LENGTH = 8;
|
|
3
|
+
export declare const PASSWORD_MAX_LENGTH = 100;
|
|
4
|
+
/** Codice errore stabile restituito quando la password non rispetta la policy. */
|
|
5
|
+
export declare const WEAK_PASSWORD_CODE = "ACCESSI_WEAK_PASSWORD";
|
|
6
|
+
export interface PasswordPolicyOptions {
|
|
7
|
+
minLength?: number;
|
|
8
|
+
maxLength?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Restituisce l'elenco leggibile delle violazioni della policy password.
|
|
12
|
+
* Policy: lunghezza, maiuscola, minuscola, cifra, carattere speciale, nessuno
|
|
13
|
+
* spazio, non comune.
|
|
14
|
+
*/
|
|
15
|
+
export declare function collectPasswordPolicyViolations(password: unknown, options?: PasswordPolicyOptions): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Valida la password secondo la policy moderna e, se non conforme, solleva un
|
|
18
|
+
* `BadRequestException` con codice `ACCESSI_WEAK_PASSWORD` e l'elenco dei
|
|
19
|
+
* requisiti mancanti. Da usare solo quando si IMPOSTA una password, mai al login.
|
|
20
|
+
*/
|
|
21
|
+
export declare function assertStrongPassword(password: unknown, options?: PasswordPolicyOptions): void;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WEAK_PASSWORD_CODE = exports.PASSWORD_MAX_LENGTH = exports.PASSWORD_MIN_LENGTH = void 0;
|
|
4
|
+
exports.collectPasswordPolicyViolations = collectPasswordPolicyViolations;
|
|
5
|
+
exports.assertStrongPassword = assertStrongPassword;
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
/** Lunghezze canoniche della password Accessi. */
|
|
8
|
+
exports.PASSWORD_MIN_LENGTH = 8;
|
|
9
|
+
exports.PASSWORD_MAX_LENGTH = 100;
|
|
10
|
+
/** Codice errore stabile restituito quando la password non rispetta la policy. */
|
|
11
|
+
exports.WEAK_PASSWORD_CODE = 'ACCESSI_WEAK_PASSWORD';
|
|
12
|
+
/**
|
|
13
|
+
* Password comuni o banalmente prevedibili rifiutate anche se rispettano la
|
|
14
|
+
* complessita. Confronto case-insensitive; elenco volutamente piccolo e senza
|
|
15
|
+
* dipendenze esterne.
|
|
16
|
+
*/
|
|
17
|
+
const COMMON_PASSWORDS = new Set([
|
|
18
|
+
'password', 'password1', 'password123', 'passw0rd', 'p@ssw0rd', 'p@ssword',
|
|
19
|
+
'12345678', '123456789', '1234567890', 'qwerty', 'qwerty123', 'qwertyuiop',
|
|
20
|
+
'admin', 'admin123', 'administrator', 'letmein', 'welcome', 'welcome1',
|
|
21
|
+
'iloveyou', 'abc12345', 'a1b2c3d4', 'monkey123', 'dragon123', 'changeme',
|
|
22
|
+
'accessi', 'emilsoftware',
|
|
23
|
+
]);
|
|
24
|
+
/**
|
|
25
|
+
* Restituisce l'elenco leggibile delle violazioni della policy password.
|
|
26
|
+
* Policy: lunghezza, maiuscola, minuscola, cifra, carattere speciale, nessuno
|
|
27
|
+
* spazio, non comune.
|
|
28
|
+
*/
|
|
29
|
+
function collectPasswordPolicyViolations(password, options = {}) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
if (typeof password !== 'string' || password.length === 0) {
|
|
32
|
+
return ['La password e obbligatoria.'];
|
|
33
|
+
}
|
|
34
|
+
const minLength = (_a = options.minLength) !== null && _a !== void 0 ? _a : exports.PASSWORD_MIN_LENGTH;
|
|
35
|
+
const maxLength = (_b = options.maxLength) !== null && _b !== void 0 ? _b : exports.PASSWORD_MAX_LENGTH;
|
|
36
|
+
const violations = [];
|
|
37
|
+
if (password.length < minLength)
|
|
38
|
+
violations.push(`almeno ${minLength} caratteri`);
|
|
39
|
+
if (password.length > maxLength)
|
|
40
|
+
violations.push(`al massimo ${maxLength} caratteri`);
|
|
41
|
+
if (/\s/.test(password))
|
|
42
|
+
violations.push('nessuno spazio');
|
|
43
|
+
if (!/[A-Z]/.test(password))
|
|
44
|
+
violations.push('almeno una lettera maiuscola');
|
|
45
|
+
if (!/[a-z]/.test(password))
|
|
46
|
+
violations.push('almeno una lettera minuscola');
|
|
47
|
+
if (!/\d/.test(password))
|
|
48
|
+
violations.push('almeno una cifra');
|
|
49
|
+
if (!/[^A-Za-z0-9]/.test(password))
|
|
50
|
+
violations.push('almeno un carattere speciale');
|
|
51
|
+
if (COMMON_PASSWORDS.has(password.toLowerCase()))
|
|
52
|
+
violations.push('una password non comune');
|
|
53
|
+
return violations;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Valida la password secondo la policy moderna e, se non conforme, solleva un
|
|
57
|
+
* `BadRequestException` con codice `ACCESSI_WEAK_PASSWORD` e l'elenco dei
|
|
58
|
+
* requisiti mancanti. Da usare solo quando si IMPOSTA una password, mai al login.
|
|
59
|
+
*/
|
|
60
|
+
function assertStrongPassword(password, options) {
|
|
61
|
+
const violations = collectPasswordPolicyViolations(password, options);
|
|
62
|
+
if (violations.length === 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
throw new common_1.BadRequestException({
|
|
66
|
+
code: exports.WEAK_PASSWORD_CODE,
|
|
67
|
+
message: `La password non rispetta i requisiti di sicurezza: richiede ${violations.join(', ')}.`,
|
|
68
|
+
details: violations,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=passwordPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwordPolicy.js","sourceRoot":"","sources":["../../../src/accessi-module/security/passwordPolicy.ts"],"names":[],"mappings":";;;AAgCA,0EAsBC;AAOD,oDAWC;AAxED,2CAAqD;AAErD,kDAAkD;AACrC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,mBAAmB,GAAG,GAAG,CAAC;AAEvC,kFAAkF;AACrE,QAAA,kBAAkB,GAAG,uBAAuB,CAAC;AAO1D;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC1E,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY;IAC1E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU;IACtE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU;IACxE,SAAS,EAAE,cAAc;CAC1B,CAAC,CAAC;AAEH;;;;GAIG;AACH,SAAgB,+BAA+B,CAC7C,QAAiB,EACjB,UAAiC,EAAE;;IAEnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,SAAS,GAAG,MAAA,OAAO,CAAC,SAAS,mCAAI,2BAAmB,CAAC;IAC3D,MAAM,SAAS,GAAG,MAAA,OAAO,CAAC,SAAS,mCAAI,2BAAmB,CAAC;IAC3D,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,IAAI,QAAQ,CAAC,MAAM,GAAG,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,UAAU,SAAS,YAAY,CAAC,CAAC;IAClF,IAAI,QAAQ,CAAC,MAAM,GAAG,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,cAAc,SAAS,YAAY,CAAC,CAAC;IACtF,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7E,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC9D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACpF,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAE7F,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,QAAiB,EAAE,OAA+B;IACrF,MAAM,UAAU,GAAG,+BAA+B,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,IAAI,4BAAmB,CAAC;QAC5B,IAAI,EAAE,0BAAkB;QACxB,OAAO,EAAE,+DAA+D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAChG,OAAO,EAAE,UAAU;KACpB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { BadRequestException } from '@nestjs/common';\n\n/** Lunghezze canoniche della password Accessi. */\nexport const PASSWORD_MIN_LENGTH = 8;\nexport const PASSWORD_MAX_LENGTH = 100;\n\n/** Codice errore stabile restituito quando la password non rispetta la policy. */\nexport const WEAK_PASSWORD_CODE = 'ACCESSI_WEAK_PASSWORD';\n\nexport interface PasswordPolicyOptions {\n minLength?: number;\n maxLength?: number;\n}\n\n/**\n * Password comuni o banalmente prevedibili rifiutate anche se rispettano la\n * complessita. Confronto case-insensitive; elenco volutamente piccolo e senza\n * dipendenze esterne.\n */\nconst COMMON_PASSWORDS = new Set([\n 'password', 'password1', 'password123', 'passw0rd', 'p@ssw0rd', 'p@ssword',\n '12345678', '123456789', '1234567890', 'qwerty', 'qwerty123', 'qwertyuiop',\n 'admin', 'admin123', 'administrator', 'letmein', 'welcome', 'welcome1',\n 'iloveyou', 'abc12345', 'a1b2c3d4', 'monkey123', 'dragon123', 'changeme',\n 'accessi', 'emilsoftware',\n]);\n\n/**\n * Restituisce l'elenco leggibile delle violazioni della policy password.\n * Policy: lunghezza, maiuscola, minuscola, cifra, carattere speciale, nessuno\n * spazio, non comune.\n */\nexport function collectPasswordPolicyViolations(\n password: unknown,\n options: PasswordPolicyOptions = {},\n): string[] {\n if (typeof password !== 'string' || password.length === 0) {\n return ['La password e obbligatoria.'];\n }\n\n const minLength = options.minLength ?? PASSWORD_MIN_LENGTH;\n const maxLength = options.maxLength ?? PASSWORD_MAX_LENGTH;\n const violations: string[] = [];\n\n if (password.length < minLength) violations.push(`almeno ${minLength} caratteri`);\n if (password.length > maxLength) violations.push(`al massimo ${maxLength} caratteri`);\n if (/\\s/.test(password)) violations.push('nessuno spazio');\n if (!/[A-Z]/.test(password)) violations.push('almeno una lettera maiuscola');\n if (!/[a-z]/.test(password)) violations.push('almeno una lettera minuscola');\n if (!/\\d/.test(password)) violations.push('almeno una cifra');\n if (!/[^A-Za-z0-9]/.test(password)) violations.push('almeno un carattere speciale');\n if (COMMON_PASSWORDS.has(password.toLowerCase())) violations.push('una password non comune');\n\n return violations;\n}\n\n/**\n * Valida la password secondo la policy moderna e, se non conforme, solleva un\n * `BadRequestException` con codice `ACCESSI_WEAK_PASSWORD` e l'elenco dei\n * requisiti mancanti. Da usare solo quando si IMPOSTA una password, mai al login.\n */\nexport function assertStrongPassword(password: unknown, options?: PasswordPolicyOptions): void {\n const violations = collectPasswordPolicyViolations(password, options);\n if (violations.length === 0) {\n return;\n }\n\n throw new BadRequestException({\n code: WEAK_PASSWORD_CODE,\n message: `La password non rispetta i requisiti di sicurezza: richiede ${violations.join(', ')}.`,\n details: violations,\n });\n}\n"]}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as jwt from 'jsonwebtoken';
|
|
2
|
+
import type { AccessiOptions } from '../AccessiModule';
|
|
3
|
+
/** Durata predefinita del token di reset. La monouso e garantita anche dal nonce persistito in `UTENTI.KEYREG`. */
|
|
2
4
|
export declare const DEFAULT_PASSWORD_RESET_EXPIRES_IN = "1h";
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
+
/** Scopo della chiave derivata: separa le chiavi di access token, reset password e 2FA. */
|
|
6
|
+
export type AccessiJwtPurpose = 'access' | 'reset' | '2fa';
|
|
7
|
+
/**
|
|
8
|
+
* Deriva una chiave JWT per scopo dal segreto configurato (key separation senza nuova configurazione).
|
|
9
|
+
* Un leak della chiave di reset non compromette gli access token e viceversa.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getAccessiJwtSecret(options: AccessiOptions, purpose?: AccessiJwtPurpose): string;
|
|
12
|
+
/** Crea un token firmato contenente solo codice utente e nonce; non inserire email o dati personali nelle claim. */
|
|
13
|
+
export declare function createPasswordResetToken(codiceUtente: number, nonce: string, secret: string, expiresIn?: jwt.SignOptions['expiresIn']): string;
|
|
14
|
+
/** Verifica firma e scadenza, quindi restituisce i dati minimi necessari al reset. */
|
|
5
15
|
export declare function verifyPasswordResetToken(token: string, secret: string): {
|
|
6
16
|
codiceUtente: number;
|
|
7
17
|
nonce: string;
|
|
@@ -38,15 +38,22 @@ exports.getAccessiJwtSecret = getAccessiJwtSecret;
|
|
|
38
38
|
exports.createPasswordResetToken = createPasswordResetToken;
|
|
39
39
|
exports.verifyPasswordResetToken = verifyPasswordResetToken;
|
|
40
40
|
const jwt = __importStar(require("jsonwebtoken"));
|
|
41
|
+
const crypto_1 = require("crypto");
|
|
42
|
+
/** Durata predefinita del token di reset. La monouso e garantita anche dal nonce persistito in `UTENTI.KEYREG`. */
|
|
41
43
|
exports.DEFAULT_PASSWORD_RESET_EXPIRES_IN = '1h';
|
|
42
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Deriva una chiave JWT per scopo dal segreto configurato (key separation senza nuova configurazione).
|
|
46
|
+
* Un leak della chiave di reset non compromette gli access token e viceversa.
|
|
47
|
+
*/
|
|
48
|
+
function getAccessiJwtSecret(options, purpose = 'access') {
|
|
43
49
|
var _a;
|
|
44
50
|
const secret = ((_a = options === null || options === void 0 ? void 0 : options.jwtOptions) === null || _a === void 0 ? void 0 : _a.secret) || process.env.ACC_JWT_SECRET;
|
|
45
51
|
if (!secret) {
|
|
46
52
|
throw new Error('JWT secret non configurato.');
|
|
47
53
|
}
|
|
48
|
-
return secret;
|
|
54
|
+
return (0, crypto_1.createHmac)('sha256', secret).update(`accessi:jwt:${purpose}:v1`).digest('hex');
|
|
49
55
|
}
|
|
56
|
+
/** Crea un token firmato contenente solo codice utente e nonce; non inserire email o dati personali nelle claim. */
|
|
50
57
|
function createPasswordResetToken(codiceUtente, nonce, secret, expiresIn = exports.DEFAULT_PASSWORD_RESET_EXPIRES_IN) {
|
|
51
58
|
if (!codiceUtente || !nonce) {
|
|
52
59
|
throw new Error('Dati insufficienti per generare il reset token.');
|
|
@@ -56,13 +63,14 @@ function createPasswordResetToken(codiceUtente, nonce, secret, expiresIn = expor
|
|
|
56
63
|
typ: 'password-reset',
|
|
57
64
|
}, secret, {
|
|
58
65
|
subject: `${codiceUtente}`,
|
|
59
|
-
expiresIn
|
|
66
|
+
expiresIn,
|
|
60
67
|
});
|
|
61
68
|
}
|
|
69
|
+
/** Verifica firma e scadenza, quindi restituisce i dati minimi necessari al reset. */
|
|
62
70
|
function verifyPasswordResetToken(token, secret) {
|
|
63
|
-
const decoded = jwt.verify(token, secret);
|
|
71
|
+
const decoded = jwt.verify(token, secret, { algorithms: ['HS256'] });
|
|
64
72
|
const codiceUtente = Number(decoded === null || decoded === void 0 ? void 0 : decoded.sub);
|
|
65
|
-
if ((decoded === null || decoded === void 0 ? void 0 : decoded.typ) !== 'password-reset' || !codiceUtente || typeof (decoded === null || decoded === void 0 ? void 0 : decoded.nonce) !== 'string') {
|
|
73
|
+
if ((decoded === null || decoded === void 0 ? void 0 : decoded.typ) !== 'password-reset' || !Number.isSafeInteger(codiceUtente) || codiceUtente <= 0 || typeof (decoded === null || decoded === void 0 ? void 0 : decoded.nonce) !== 'string' || !decoded.nonce) {
|
|
66
74
|
throw new Error('Token di reset non valido.');
|
|
67
75
|
}
|
|
68
76
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passwordResetToken.js","sourceRoot":"","sources":["../../../src/accessi-module/security/passwordResetToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"passwordResetToken.js","sourceRoot":"","sources":["../../../src/accessi-module/security/passwordResetToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,kDAOC;AAGD,4DAqBC;AAGD,4DAeC;AApED,kDAAoC;AACpC,mCAAoC;AAGpC,mHAAmH;AACtG,QAAA,iCAAiC,GAAG,IAAI,CAAC;AAUtD;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,OAAuB,EAAE,UAA6B,QAAQ;;IAChG,MAAM,MAAM,GAAG,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,0CAAE,MAAM,KAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACzE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,eAAe,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,oHAAoH;AACpH,SAAgB,wBAAwB,CACtC,YAAoB,EACpB,KAAa,EACb,MAAc,EACd,YAA0C,yCAAiC;IAE3E,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CACb;QACE,KAAK;QACL,GAAG,EAAE,gBAAgB;KACtB,EACD,MAAM,EACN;QACE,OAAO,EAAE,GAAG,YAAY,EAAE;QAC1B,SAAS;KACV,CACF,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,SAAgB,wBAAwB,CACtC,KAAa,EACb,MAAc;IAEd,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAA8B,CAAC;IAClG,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,CAAC;IAE1C,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,MAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,OAAO,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAA,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1J,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC","sourcesContent":["import * as jwt from 'jsonwebtoken';\nimport { createHmac } from 'crypto';\nimport type { AccessiOptions } from '../AccessiModule';\n\n/** Durata predefinita del token di reset. La monouso e garantita anche dal nonce persistito in `UTENTI.KEYREG`. */\nexport const DEFAULT_PASSWORD_RESET_EXPIRES_IN = '1h';\n\ninterface PasswordResetTokenPayload extends jwt.JwtPayload {\n nonce: string;\n typ: 'password-reset';\n}\n\n/** Scopo della chiave derivata: separa le chiavi di access token, reset password e 2FA. */\nexport type AccessiJwtPurpose = 'access' | 'reset' | '2fa';\n\n/**\n * Deriva una chiave JWT per scopo dal segreto configurato (key separation senza nuova configurazione).\n * Un leak della chiave di reset non compromette gli access token e viceversa.\n */\nexport function getAccessiJwtSecret(options: AccessiOptions, purpose: AccessiJwtPurpose = 'access'): string {\n const secret = options?.jwtOptions?.secret || process.env.ACC_JWT_SECRET;\n if (!secret) {\n throw new Error('JWT secret non configurato.');\n }\n\n return createHmac('sha256', secret).update(`accessi:jwt:${purpose}:v1`).digest('hex');\n}\n\n/** Crea un token firmato contenente solo codice utente e nonce; non inserire email o dati personali nelle claim. */\nexport function createPasswordResetToken(\n codiceUtente: number,\n nonce: string,\n secret: string,\n expiresIn: jwt.SignOptions['expiresIn'] = DEFAULT_PASSWORD_RESET_EXPIRES_IN,\n): string {\n if (!codiceUtente || !nonce) {\n throw new Error('Dati insufficienti per generare il reset token.');\n }\n\n return jwt.sign(\n {\n nonce,\n typ: 'password-reset',\n },\n secret,\n {\n subject: `${codiceUtente}`,\n expiresIn,\n },\n );\n}\n\n/** Verifica firma e scadenza, quindi restituisce i dati minimi necessari al reset. */\nexport function verifyPasswordResetToken(\n token: string,\n secret: string,\n): { codiceUtente: number; nonce: string } {\n const decoded = jwt.verify(token, secret, { algorithms: ['HS256'] }) as PasswordResetTokenPayload;\n const codiceUtente = Number(decoded?.sub);\n\n if (decoded?.typ !== 'password-reset' || !Number.isSafeInteger(codiceUtente) || codiceUtente <= 0 || typeof decoded?.nonce !== 'string' || !decoded.nonce) {\n throw new Error('Token di reset non valido.');\n }\n\n return {\n codiceUtente,\n nonce: decoded.nonce,\n };\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Request, Response } from 'express';
|
|
2
|
-
import { AccessiOptions } from '../AccessiModule';
|
|
3
|
-
export type PublicAuthRateLimitScope = 'login' | 'register' | 'passwordResetEmail' | 'passwordResetConfirm' | 'getUserByToken';
|
|
2
|
+
import type { AccessiOptions } from '../AccessiModule';
|
|
3
|
+
export type PublicAuthRateLimitScope = 'login' | 'twoFactorVerify' | 'twoFactorResend' | 'register' | 'passwordResetEmail' | 'passwordResetConfirm' | 'getUserByToken' | 'adminBootstrap' | 'consoleEntry';
|
|
4
4
|
type RateLimitDecision = {
|
|
5
5
|
allowed: boolean;
|
|
6
|
-
retryAfterSeconds
|
|
6
|
+
retryAfterSeconds: number;
|
|
7
7
|
};
|
|
8
8
|
export declare function checkPublicAuthRateLimit(options: AccessiOptions, scope: PublicAuthRateLimitScope, req: Request, identifiers?: string[]): RateLimitDecision;
|
|
9
9
|
export declare function sendPublicAuthRateLimitExceeded(res: Response, retryAfterSeconds: number): Response;
|
|
@@ -6,10 +6,14 @@ 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 },
|
|
12
14
|
getUserByToken: { windowMs: 5 * 60 * 1000, maxAttempts: 30 },
|
|
15
|
+
adminBootstrap: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },
|
|
16
|
+
consoleEntry: { windowMs: 5 * 60 * 1000, maxAttempts: 30 },
|
|
13
17
|
};
|
|
14
18
|
const RATE_LIMIT_BUCKETS = new Map();
|
|
15
19
|
const MAX_TRACKED_BUCKETS = 20000;
|
|
@@ -49,9 +53,27 @@ function pruneRateLimitBuckets(now) {
|
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
}
|
|
56
|
+
/** Mantiene il numero di bucket sotto la soglia, scartando i meno recenti. */
|
|
57
|
+
function enforceBucketCap() {
|
|
58
|
+
while (RATE_LIMIT_BUCKETS.size >= MAX_TRACKED_BUCKETS) {
|
|
59
|
+
let oldestKey;
|
|
60
|
+
let oldestSeen = Number.POSITIVE_INFINITY;
|
|
61
|
+
for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {
|
|
62
|
+
if (bucket.lastSeenAt < oldestSeen) {
|
|
63
|
+
oldestSeen = bucket.lastSeenAt;
|
|
64
|
+
oldestKey = key;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (oldestKey === undefined) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
RATE_LIMIT_BUCKETS.delete(oldestKey);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
52
73
|
function consumeBucket(bucketKey, rule, now) {
|
|
53
74
|
const existingBucket = RATE_LIMIT_BUCKETS.get(bucketKey);
|
|
54
75
|
if (!existingBucket || existingBucket.resetAt <= now) {
|
|
76
|
+
enforceBucketCap();
|
|
55
77
|
RATE_LIMIT_BUCKETS.set(bucketKey, {
|
|
56
78
|
count: 1,
|
|
57
79
|
resetAt: now + rule.windowMs,
|
|
@@ -69,23 +91,25 @@ function consumeBucket(bucketKey, rule, now) {
|
|
|
69
91
|
function checkPublicAuthRateLimit(options, scope, req, identifiers = []) {
|
|
70
92
|
var _a, _b, _c, _d, _e;
|
|
71
93
|
if (((_a = options.publicAuthRateLimit) === null || _a === void 0 ? void 0 : _a.enabled) === false) {
|
|
72
|
-
return { allowed: true };
|
|
94
|
+
return { allowed: true, retryAfterSeconds: 0 };
|
|
73
95
|
}
|
|
74
96
|
const rule = getRule(options, scope);
|
|
75
97
|
const now = Date.now();
|
|
76
98
|
pruneRateLimitBuckets(now);
|
|
77
99
|
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
|
-
|
|
100
|
+
// Consuma prima il bucket per IP: se gia bloccato non crea bucket per soggetto,
|
|
101
|
+
// evitando crescita di memoria con identificatori sempre diversi.
|
|
102
|
+
const ipRetryAfterSeconds = consumeBucket(`${scope}|ip|${ipAddress}`, rule, now);
|
|
103
|
+
if (ipRetryAfterSeconds) {
|
|
104
|
+
return { allowed: false, retryAfterSeconds: ipRetryAfterSeconds };
|
|
105
|
+
}
|
|
106
|
+
let retryAfterSeconds = 0;
|
|
79
107
|
for (const identifier of identifiers) {
|
|
80
108
|
const normalizedIdentifier = normalizeIdentifier(identifier);
|
|
81
109
|
if (!normalizedIdentifier) {
|
|
82
110
|
continue;
|
|
83
111
|
}
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
let retryAfterSeconds = 0;
|
|
87
|
-
for (const bucketKey of bucketKeys) {
|
|
88
|
-
const bucketRetryAfterSeconds = consumeBucket(bucketKey, rule, now);
|
|
112
|
+
const bucketRetryAfterSeconds = consumeBucket(`${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`, rule, now);
|
|
89
113
|
if (bucketRetryAfterSeconds) {
|
|
90
114
|
retryAfterSeconds = Math.max(retryAfterSeconds, bucketRetryAfterSeconds);
|
|
91
115
|
}
|
|
@@ -96,7 +120,7 @@ function checkPublicAuthRateLimit(options, scope, req, identifiers = []) {
|
|
|
96
120
|
retryAfterSeconds,
|
|
97
121
|
};
|
|
98
122
|
}
|
|
99
|
-
return { allowed: true };
|
|
123
|
+
return { allowed: true, retryAfterSeconds: 0 };
|
|
100
124
|
}
|
|
101
125
|
function sendPublicAuthRateLimitExceeded(res, retryAfterSeconds) {
|
|
102
126
|
res.setHeader('Retry-After', String(retryAfterSeconds));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicAuthRateLimit.js","sourceRoot":"","sources":["../../../src/accessi-module/security/publicAuthRateLimit.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpStatus } from '@nestjs/common';\r\nimport { Request, Response } from 'express';\r\nimport { RestUtilities } from '../../Utilities';\r\nimport { AccessiOptions, PublicAuthRateLimitRuleOptions } from '../AccessiModule';\r\n\r\nexport type PublicAuthRateLimitScope =\r\n | 'login'\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 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\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 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 };\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 const bucketKeys = new Set<string>([`${scope}|ip|${ipAddress}`]);\r\n\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 bucketKeys.add(`${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`);\r\n }\r\n\r\n let retryAfterSeconds = 0;\r\n for (const bucketKey of bucketKeys) {\r\n const bucketRetryAfterSeconds = consumeBucket(bucketKey, rule, now);\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 };\r\n}\r\n\r\nexport function sendPublicAuthRateLimitExceeded(\r\n res: Response,\r\n retryAfterSeconds: number,\r\n): Response {\r\n res.setHeader('Retry-After', String(retryAfterSeconds));\r\n return RestUtilities.sendErrorMessage(\r\n res,\r\n 'Troppi tentativi. Riprova piu tardi.',\r\n 'PublicAuthRateLimit',\r\n HttpStatus.TOO_MANY_REQUESTS,\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"publicAuthRateLimit.js","sourceRoot":"","sources":["../../../src/accessi-module/security/publicAuthRateLimit.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpStatus } from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport { RestUtilities } from '../../Utilities';\nimport type { AccessiOptions, PublicAuthRateLimitRuleOptions } from '../AccessiModule';\n\nexport type PublicAuthRateLimitScope =\n | 'login'\n | 'twoFactorVerify'\n | 'twoFactorResend'\n | 'register'\n | 'passwordResetEmail'\n | 'passwordResetConfirm'\n | 'getUserByToken'\n | 'adminBootstrap'\n | 'consoleEntry';\n\ntype RateLimitBucket = {\n count: number;\n resetAt: number;\n lastSeenAt: number;\n};\n\ntype RateLimitDecision = {\n allowed: boolean;\n retryAfterSeconds: number;\n};\n\nconst DEFAULT_PUBLIC_AUTH_RATE_LIMITS: Record<\n PublicAuthRateLimitScope,\n PublicAuthRateLimitRuleOptions\n> = {\n login: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\n twoFactorVerify: { windowMs: 15 * 60 * 1000, maxAttempts: 20 },\n twoFactorResend: { windowMs: 15 * 60 * 1000, maxAttempts: 5 },\n register: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },\n passwordResetEmail: { windowMs: 60 * 60 * 1000, maxAttempts: 5 },\n passwordResetConfirm: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\n getUserByToken: { windowMs: 5 * 60 * 1000, maxAttempts: 30 },\n adminBootstrap: { windowMs: 15 * 60 * 1000, maxAttempts: 10 },\n consoleEntry: { windowMs: 5 * 60 * 1000, maxAttempts: 30 },\n};\n\nconst RATE_LIMIT_BUCKETS = new Map<string, RateLimitBucket>();\nconst MAX_TRACKED_BUCKETS = 20000;\nconst MAX_WINDOW_MS = Math.max(\n ...Object.values(DEFAULT_PUBLIC_AUTH_RATE_LIMITS).map((rule) => rule.windowMs),\n);\n\nfunction getRule(\n options: AccessiOptions,\n scope: PublicAuthRateLimitScope,\n): PublicAuthRateLimitRuleOptions {\n const configuredRule = options.publicAuthRateLimit?.[scope];\n\n if (\n configuredRule &&\n Number.isFinite(configuredRule.windowMs) &&\n configuredRule.windowMs > 0 &&\n Number.isFinite(configuredRule.maxAttempts) &&\n configuredRule.maxAttempts > 0\n ) {\n return {\n windowMs: Math.trunc(configuredRule.windowMs),\n maxAttempts: Math.trunc(configuredRule.maxAttempts),\n };\n }\n\n return DEFAULT_PUBLIC_AUTH_RATE_LIMITS[scope];\n}\n\nfunction normalizeIdentifier(identifier: string): string | null {\n if (typeof identifier !== 'string') {\n return null;\n }\n\n const normalized = identifier.trim().toLowerCase();\n return normalized === '' ? null : normalized;\n}\n\nfunction pruneRateLimitBuckets(now: number): void {\n if (RATE_LIMIT_BUCKETS.size < MAX_TRACKED_BUCKETS) {\n return;\n }\n\n for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {\n if (bucket.resetAt <= now || bucket.lastSeenAt <= now - MAX_WINDOW_MS * 2) {\n RATE_LIMIT_BUCKETS.delete(key);\n }\n\n if (RATE_LIMIT_BUCKETS.size < MAX_TRACKED_BUCKETS) {\n return;\n }\n }\n}\n\n/** Mantiene il numero di bucket sotto la soglia, scartando i meno recenti. */\nfunction enforceBucketCap(): void {\n while (RATE_LIMIT_BUCKETS.size >= MAX_TRACKED_BUCKETS) {\n let oldestKey: string | undefined;\n let oldestSeen = Number.POSITIVE_INFINITY;\n\n for (const [key, bucket] of RATE_LIMIT_BUCKETS.entries()) {\n if (bucket.lastSeenAt < oldestSeen) {\n oldestSeen = bucket.lastSeenAt;\n oldestKey = key;\n }\n }\n\n if (oldestKey === undefined) {\n return;\n }\n\n RATE_LIMIT_BUCKETS.delete(oldestKey);\n }\n}\n\nfunction consumeBucket(\n bucketKey: string,\n rule: PublicAuthRateLimitRuleOptions,\n now: number,\n): number | null {\n const existingBucket = RATE_LIMIT_BUCKETS.get(bucketKey);\n if (!existingBucket || existingBucket.resetAt <= now) {\n enforceBucketCap();\n RATE_LIMIT_BUCKETS.set(bucketKey, {\n count: 1,\n resetAt: now + rule.windowMs,\n lastSeenAt: now,\n });\n return null;\n }\n\n existingBucket.lastSeenAt = now;\n if (existingBucket.count >= rule.maxAttempts) {\n return Math.max(1, Math.ceil((existingBucket.resetAt - now) / 1000));\n }\n\n existingBucket.count += 1;\n return null;\n}\n\nexport function checkPublicAuthRateLimit(\n options: AccessiOptions,\n scope: PublicAuthRateLimitScope,\n req: Request,\n identifiers: string[] = [],\n): RateLimitDecision {\n if (options.publicAuthRateLimit?.enabled === false) {\n return { allowed: true, retryAfterSeconds: 0 };\n }\n\n const rule = getRule(options, scope);\n const now = Date.now();\n pruneRateLimitBuckets(now);\n\n const ipAddress =\n normalizeIdentifier(req.ip ?? req.socket?.remoteAddress ?? 'unknown') ?? 'unknown';\n\n // Consuma prima il bucket per IP: se gia bloccato non crea bucket per soggetto,\n // evitando crescita di memoria con identificatori sempre diversi.\n const ipRetryAfterSeconds = consumeBucket(`${scope}|ip|${ipAddress}`, rule, now);\n if (ipRetryAfterSeconds) {\n return { allowed: false, retryAfterSeconds: ipRetryAfterSeconds };\n }\n\n let retryAfterSeconds = 0;\n for (const identifier of identifiers) {\n const normalizedIdentifier = normalizeIdentifier(identifier);\n if (!normalizedIdentifier) {\n continue;\n }\n\n const bucketRetryAfterSeconds = consumeBucket(\n `${scope}|ip-subject|${ipAddress}|${normalizedIdentifier}`,\n rule,\n now,\n );\n if (bucketRetryAfterSeconds) {\n retryAfterSeconds = Math.max(retryAfterSeconds, bucketRetryAfterSeconds);\n }\n }\n\n if (retryAfterSeconds > 0) {\n return {\n allowed: false,\n retryAfterSeconds,\n };\n }\n\n return { allowed: true, retryAfterSeconds: 0 };\n}\n\nexport function sendPublicAuthRateLimitExceeded(\n res: Response,\n retryAfterSeconds: number,\n): Response {\n res.setHeader('Retry-After', String(retryAfterSeconds));\n return RestUtilities.sendErrorMessage(\n res,\n 'Troppi tentativi. Riprova piu tardi.',\n 'PublicAuthRateLimit',\n HttpStatus.TOO_MANY_REQUESTS,\n );\n}\n"]}
|
|
@@ -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"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AccessiOptions } from './AccessiModule';
|
|
2
|
+
/**
|
|
3
|
+
* Logga gli indirizzi utili del modulo Accessi appena il bootstrap e completato, cosi che
|
|
4
|
+
* console, swagger e API siano visibili insieme nei log di avvio.
|
|
5
|
+
*/
|
|
6
|
+
export declare function logAccessiStartup(options: AccessiOptions): void;
|