@contember/engine-tenant-api 2.2.0-alpha.3 → 2.2.0-alpha.6
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/CLAUDE.md +36 -2
- package/dist/development/index.cjs +32 -0
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +33 -1
- package/dist/development/index.js.map +1 -1
- package/dist/development/src/TenantContainer.cjs +15 -3
- package/dist/development/src/TenantContainer.cjs.map +1 -1
- package/dist/development/src/TenantContainer.js +15 -3
- package/dist/development/src/TenantContainer.js.map +1 -1
- package/dist/development/src/bridges/system/IdentityFetcher.cjs +2 -1
- package/dist/development/src/bridges/system/IdentityFetcher.cjs.map +1 -1
- package/dist/development/src/bridges/system/IdentityFetcher.js +2 -1
- package/dist/development/src/bridges/system/IdentityFetcher.js.map +1 -1
- package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs +10 -0
- package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs.map +1 -0
- package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.js +11 -0
- package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.js.map +1 -0
- package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs +9 -0
- package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs.map +1 -0
- package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.js +10 -0
- package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.js.map +1 -0
- package/dist/development/src/migrations/2026-08-04-120000-config-panel.cjs +11 -0
- package/dist/development/src/migrations/2026-08-04-120000-config-panel.cjs.map +1 -0
- package/dist/development/src/migrations/2026-08-04-120000-config-panel.js +12 -0
- package/dist/development/src/migrations/2026-08-04-120000-config-panel.js.map +1 -0
- package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs +18 -0
- package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs.map +1 -0
- package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js +19 -0
- package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js.map +1 -0
- package/dist/development/src/migrations/runner.cjs +11 -2
- package/dist/development/src/migrations/runner.cjs.map +1 -1
- package/dist/development/src/migrations/runner.js +11 -2
- package/dist/development/src/migrations/runner.js.map +1 -1
- package/dist/development/src/migrations/snapshot.cjs +8 -2
- package/dist/development/src/migrations/snapshot.cjs.map +1 -1
- package/dist/development/src/migrations/snapshot.js +8 -2
- package/dist/development/src/migrations/snapshot.js.map +1 -1
- package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.cjs +5 -3
- package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.cjs.map +1 -1
- package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.js +5 -3
- package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.js.map +1 -1
- package/dist/development/src/model/commands/idp/CreateIdpCommand.cjs +8 -2
- package/dist/development/src/model/commands/idp/CreateIdpCommand.cjs.map +1 -1
- package/dist/development/src/model/commands/idp/CreateIdpCommand.js +8 -2
- package/dist/development/src/model/commands/idp/CreateIdpCommand.js.map +1 -1
- package/dist/development/src/model/commands/idp/UpdateIdpCommand.cjs +6 -2
- package/dist/development/src/model/commands/idp/UpdateIdpCommand.cjs.map +1 -1
- package/dist/development/src/model/commands/idp/UpdateIdpCommand.js +6 -2
- package/dist/development/src/model/commands/idp/UpdateIdpCommand.js.map +1 -1
- package/dist/development/src/model/commands/membership/{RemoveProjectMembershipsCommand.cjs → RemoveProjectMembershipCommand.cjs} +1 -1
- package/dist/development/src/model/commands/membership/RemoveProjectMembershipCommand.cjs.map +1 -0
- package/dist/development/src/model/commands/membership/{RemoveProjectMembershipsCommand.js → RemoveProjectMembershipCommand.js} +1 -1
- package/dist/development/src/model/commands/membership/RemoveProjectMembershipCommand.js.map +1 -0
- package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.cjs +2 -2
- package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.cjs.map +1 -1
- package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.js +1 -1
- package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.js.map +1 -1
- package/dist/development/src/model/commands/person/EnablePersonCommand.cjs +17 -0
- package/dist/development/src/model/commands/person/EnablePersonCommand.cjs.map +1 -0
- package/dist/development/src/model/commands/person/EnablePersonCommand.js +17 -0
- package/dist/development/src/model/commands/person/EnablePersonCommand.js.map +1 -0
- package/dist/development/src/model/queries/configuration/ConfigurationQuery.cjs +4 -0
- package/dist/development/src/model/queries/configuration/ConfigurationQuery.cjs.map +1 -1
- package/dist/development/src/model/queries/configuration/ConfigurationQuery.js +4 -0
- package/dist/development/src/model/queries/configuration/ConfigurationQuery.js.map +1 -1
- package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs +21 -0
- package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs.map +1 -0
- package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js +21 -0
- package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js.map +1 -0
- package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.cjs +1 -1
- package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.cjs.map +1 -1
- package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.js +1 -1
- package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.js.map +1 -1
- package/dist/development/src/model/queries/idp/helpers.cjs +3 -3
- package/dist/development/src/model/queries/idp/helpers.cjs.map +1 -1
- package/dist/development/src/model/queries/idp/helpers.js +3 -3
- package/dist/development/src/model/queries/idp/helpers.js.map +1 -1
- package/dist/development/src/model/queries/membership/ProjectMembersQuery.cjs +1 -1
- package/dist/development/src/model/queries/membership/ProjectMembersQuery.cjs.map +1 -1
- package/dist/development/src/model/queries/membership/ProjectMembersQuery.js +1 -1
- package/dist/development/src/model/queries/membership/ProjectMembersQuery.js.map +1 -1
- package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.cjs +1 -1
- package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.cjs.map +1 -1
- package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.js +1 -1
- package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
- package/dist/development/src/model/service/AuthLogService.cjs +8 -2
- package/dist/development/src/model/service/AuthLogService.cjs.map +1 -1
- package/dist/development/src/model/service/AuthLogService.js +8 -2
- package/dist/development/src/model/service/AuthLogService.js.map +1 -1
- package/dist/development/src/model/service/IDPSignInManager.cjs +29 -2
- package/dist/development/src/model/service/IDPSignInManager.cjs.map +1 -1
- package/dist/development/src/model/service/IDPSignInManager.js +29 -2
- package/dist/development/src/model/service/IDPSignInManager.js.map +1 -1
- package/dist/development/src/model/service/PanelAccessResolver.cjs +31 -0
- package/dist/development/src/model/service/PanelAccessResolver.cjs.map +1 -0
- package/dist/development/src/model/service/PanelAccessResolver.js +31 -0
- package/dist/development/src/model/service/PanelAccessResolver.js.map +1 -0
- package/dist/development/src/model/service/PasswordResetManager.cjs +5 -0
- package/dist/development/src/model/service/PasswordResetManager.cjs.map +1 -1
- package/dist/development/src/model/service/PasswordResetManager.js +5 -0
- package/dist/development/src/model/service/PasswordResetManager.js.map +1 -1
- package/dist/development/src/model/service/PasswordlessSignInManager.cjs +19 -0
- package/dist/development/src/model/service/PasswordlessSignInManager.cjs.map +1 -1
- package/dist/development/src/model/service/PasswordlessSignInManager.js +19 -0
- package/dist/development/src/model/service/PasswordlessSignInManager.js.map +1 -1
- package/dist/development/src/model/service/PersonAccessManager.cjs +10 -2
- package/dist/development/src/model/service/PersonAccessManager.cjs.map +1 -1
- package/dist/development/src/model/service/PersonAccessManager.js +10 -2
- package/dist/development/src/model/service/PersonAccessManager.js.map +1 -1
- package/dist/development/src/model/service/SignInManager.cjs +5 -0
- package/dist/development/src/model/service/SignInManager.cjs.map +1 -1
- package/dist/development/src/model/service/SignInManager.js +5 -0
- package/dist/development/src/model/service/SignInManager.js.map +1 -1
- package/dist/development/src/model/service/apiKey/ApiKeyManager.cjs +4 -3
- package/dist/development/src/model/service/apiKey/ApiKeyManager.cjs.map +1 -1
- package/dist/development/src/model/service/apiKey/ApiKeyManager.js +4 -3
- package/dist/development/src/model/service/apiKey/ApiKeyManager.js.map +1 -1
- package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.cjs +7 -0
- package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.cjs.map +1 -1
- package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.js +8 -1
- package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.js.map +1 -1
- package/dist/development/src/model/service/idp/ClaimMapping.cjs +187 -0
- package/dist/development/src/model/service/idp/ClaimMapping.cjs.map +1 -0
- package/dist/development/src/model/service/idp/ClaimMapping.js +170 -0
- package/dist/development/src/model/service/idp/ClaimMapping.js.map +1 -0
- package/dist/development/src/model/service/idp/ClaimMappingEvaluator.cjs +155 -0
- package/dist/development/src/model/service/idp/ClaimMappingEvaluator.cjs.map +1 -0
- package/dist/development/src/model/service/idp/ClaimMappingEvaluator.js +155 -0
- package/dist/development/src/model/service/idp/ClaimMappingEvaluator.js.map +1 -0
- package/dist/development/src/model/service/idp/ClaimMappingValidation.cjs +83 -0
- package/dist/development/src/model/service/idp/ClaimMappingValidation.cjs.map +1 -0
- package/dist/development/src/model/service/idp/ClaimMappingValidation.js +83 -0
- package/dist/development/src/model/service/idp/ClaimMappingValidation.js.map +1 -0
- package/dist/development/src/model/service/idp/IDPClaimSyncService.cjs +260 -0
- package/dist/development/src/model/service/idp/IDPClaimSyncService.cjs.map +1 -0
- package/dist/development/src/model/service/idp/IDPClaimSyncService.js +260 -0
- package/dist/development/src/model/service/idp/IDPClaimSyncService.js.map +1 -0
- package/dist/development/src/model/service/idp/IDPManager.cjs +96 -20
- package/dist/development/src/model/service/idp/IDPManager.cjs.map +1 -1
- package/dist/development/src/model/service/idp/IDPManager.js +96 -20
- package/dist/development/src/model/service/idp/IDPManager.js.map +1 -1
- package/dist/development/src/model/service/idp/IdpSessionRevalidator.cjs +55 -1
- package/dist/development/src/model/service/idp/IdpSessionRevalidator.cjs.map +1 -1
- package/dist/development/src/model/service/idp/IdpSessionRevalidator.js +55 -1
- package/dist/development/src/model/service/idp/IdpSessionRevalidator.js.map +1 -1
- package/dist/development/src/model/service/idp/PersonIdentityProviderManager.cjs +6 -0
- package/dist/development/src/model/service/idp/PersonIdentityProviderManager.cjs.map +1 -1
- package/dist/development/src/model/service/idp/PersonIdentityProviderManager.js +6 -0
- package/dist/development/src/model/service/idp/PersonIdentityProviderManager.js.map +1 -1
- package/dist/development/src/model/service/idp/providers/OIDCHelpers.cjs +69 -33
- package/dist/development/src/model/service/idp/providers/OIDCHelpers.cjs.map +1 -1
- package/dist/development/src/model/service/idp/providers/OIDCHelpers.js +69 -33
- package/dist/development/src/model/service/idp/providers/OIDCHelpers.js.map +1 -1
- package/dist/development/src/model/service/idp/providers/OIDCProvider.cjs +4 -1
- package/dist/development/src/model/service/idp/providers/OIDCProvider.cjs.map +1 -1
- package/dist/development/src/model/service/idp/providers/OIDCProvider.js +4 -1
- package/dist/development/src/model/service/idp/providers/OIDCProvider.js.map +1 -1
- package/dist/development/src/model/utils/DatabaseContext.cjs +7 -2
- package/dist/development/src/model/utils/DatabaseContext.cjs.map +1 -1
- package/dist/development/src/model/utils/DatabaseContext.js +8 -3
- package/dist/development/src/model/utils/DatabaseContext.js.map +1 -1
- package/dist/development/src/resolvers/ResolverFactory.cjs +6 -2
- package/dist/development/src/resolvers/ResolverFactory.cjs.map +1 -1
- package/dist/development/src/resolvers/ResolverFactory.js +6 -2
- package/dist/development/src/resolvers/ResolverFactory.js.map +1 -1
- package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs +4 -2
- package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.js +4 -2
- package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs +4 -2
- package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js +4 -2
- package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/audit.cjs +1 -0
- package/dist/development/src/resolvers/mutation/idp/audit.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/idp/audit.js +1 -0
- package/dist/development/src/resolvers/mutation/idp/audit.js.map +1 -1
- package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs +4 -3
- package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.js +4 -3
- package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs +60 -0
- package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs.map +1 -0
- package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.js +60 -0
- package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.js.map +1 -0
- package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.cjs +27 -1
- package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.js +27 -1
- package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs +6 -1
- package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.js +6 -1
- package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.cjs +4 -3
- package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.js +4 -3
- package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs +2 -1
- package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js +2 -1
- package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/ApiKeyQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/ApiKeyQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/ApiKeyQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/ApiKeyQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/AuthLogQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/AuthLogQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/AuthLogQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/AuthLogQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/ConfigurationQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/ConfigurationQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/ConfigurationQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/ConfigurationQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/IDPQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/IDPQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/IDPQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/IDPQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/MailTemplateQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/MailTemplateQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/MailTemplateQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/MailTemplateQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/PersonQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/PersonQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/PersonQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/PersonQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.cjs +2 -1
- package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.js +2 -1
- package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/query/ProjectQueryResolver.cjs +5 -3
- package/dist/development/src/resolvers/query/ProjectQueryResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/query/ProjectQueryResolver.js +5 -3
- package/dist/development/src/resolvers/query/ProjectQueryResolver.js.map +1 -1
- package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs +2 -1
- package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs.map +1 -1
- package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.js +2 -1
- package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.js.map +1 -1
- package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.cjs +5 -0
- package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.cjs.map +1 -1
- package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.js +5 -0
- package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.js.map +1 -1
- package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.cjs +23 -0
- package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.cjs.map +1 -0
- package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.js +23 -0
- package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.js.map +1 -0
- package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.cjs +2 -1
- package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.cjs.map +1 -1
- package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.js +2 -1
- package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.js.map +1 -1
- package/dist/development/src/resolvers/types/IdentityTypeResolver.cjs +37 -4
- package/dist/development/src/resolvers/types/IdentityTypeResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/types/IdentityTypeResolver.js +37 -4
- package/dist/development/src/resolvers/types/IdentityTypeResolver.js.map +1 -1
- package/dist/development/src/resolvers/types/PersonTypeResolver.cjs +30 -1
- package/dist/development/src/resolvers/types/PersonTypeResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/types/PersonTypeResolver.js +30 -1
- package/dist/development/src/resolvers/types/PersonTypeResolver.js.map +1 -1
- package/dist/development/src/resolvers/types/ProjectTypeResolver.cjs +25 -1
- package/dist/development/src/resolvers/types/ProjectTypeResolver.cjs.map +1 -1
- package/dist/development/src/resolvers/types/ProjectTypeResolver.js +25 -1
- package/dist/development/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
- package/dist/development/src/schema/tenant.graphql.cjs +144 -0
- package/dist/development/src/schema/tenant.graphql.cjs.map +1 -1
- package/dist/development/src/schema/tenant.graphql.js +144 -0
- package/dist/development/src/schema/tenant.graphql.js.map +1 -1
- package/dist/production/index.cjs +32 -0
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.js +33 -1
- package/dist/production/index.js.map +1 -1
- package/dist/production/src/TenantContainer.cjs +15 -3
- package/dist/production/src/TenantContainer.cjs.map +1 -1
- package/dist/production/src/TenantContainer.js +15 -3
- package/dist/production/src/TenantContainer.js.map +1 -1
- package/dist/production/src/bridges/system/IdentityFetcher.cjs +2 -1
- package/dist/production/src/bridges/system/IdentityFetcher.cjs.map +1 -1
- package/dist/production/src/bridges/system/IdentityFetcher.js +2 -1
- package/dist/production/src/bridges/system/IdentityFetcher.js.map +1 -1
- package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs +10 -0
- package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs.map +1 -0
- package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.js +11 -0
- package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.js.map +1 -0
- package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs +9 -0
- package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs.map +1 -0
- package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.js +10 -0
- package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.js.map +1 -0
- package/dist/production/src/migrations/2026-08-04-120000-config-panel.cjs +11 -0
- package/dist/production/src/migrations/2026-08-04-120000-config-panel.cjs.map +1 -0
- package/dist/production/src/migrations/2026-08-04-120000-config-panel.js +12 -0
- package/dist/production/src/migrations/2026-08-04-120000-config-panel.js.map +1 -0
- package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs +18 -0
- package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs.map +1 -0
- package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js +19 -0
- package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js.map +1 -0
- package/dist/production/src/migrations/runner.cjs +11 -2
- package/dist/production/src/migrations/runner.cjs.map +1 -1
- package/dist/production/src/migrations/runner.js +11 -2
- package/dist/production/src/migrations/runner.js.map +1 -1
- package/dist/production/src/migrations/snapshot.cjs +8 -2
- package/dist/production/src/migrations/snapshot.cjs.map +1 -1
- package/dist/production/src/migrations/snapshot.js +8 -2
- package/dist/production/src/migrations/snapshot.js.map +1 -1
- package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.cjs +5 -3
- package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.cjs.map +1 -1
- package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.js +5 -3
- package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.js.map +1 -1
- package/dist/production/src/model/commands/idp/CreateIdpCommand.cjs +8 -2
- package/dist/production/src/model/commands/idp/CreateIdpCommand.cjs.map +1 -1
- package/dist/production/src/model/commands/idp/CreateIdpCommand.js +8 -2
- package/dist/production/src/model/commands/idp/CreateIdpCommand.js.map +1 -1
- package/dist/production/src/model/commands/idp/UpdateIdpCommand.cjs +6 -2
- package/dist/production/src/model/commands/idp/UpdateIdpCommand.cjs.map +1 -1
- package/dist/production/src/model/commands/idp/UpdateIdpCommand.js +6 -2
- package/dist/production/src/model/commands/idp/UpdateIdpCommand.js.map +1 -1
- package/dist/production/src/model/commands/membership/{RemoveProjectMembershipsCommand.cjs → RemoveProjectMembershipCommand.cjs} +1 -1
- package/dist/production/src/model/commands/membership/RemoveProjectMembershipCommand.cjs.map +1 -0
- package/dist/production/src/model/commands/membership/{RemoveProjectMembershipsCommand.js → RemoveProjectMembershipCommand.js} +1 -1
- package/dist/production/src/model/commands/membership/RemoveProjectMembershipCommand.js.map +1 -0
- package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.cjs +2 -2
- package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.cjs.map +1 -1
- package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.js +1 -1
- package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.js.map +1 -1
- package/dist/production/src/model/commands/person/EnablePersonCommand.cjs +17 -0
- package/dist/production/src/model/commands/person/EnablePersonCommand.cjs.map +1 -0
- package/dist/production/src/model/commands/person/EnablePersonCommand.js +17 -0
- package/dist/production/src/model/commands/person/EnablePersonCommand.js.map +1 -0
- package/dist/production/src/model/queries/configuration/ConfigurationQuery.cjs +4 -0
- package/dist/production/src/model/queries/configuration/ConfigurationQuery.cjs.map +1 -1
- package/dist/production/src/model/queries/configuration/ConfigurationQuery.js +4 -0
- package/dist/production/src/model/queries/configuration/ConfigurationQuery.js.map +1 -1
- package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs +21 -0
- package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs.map +1 -0
- package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js +21 -0
- package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js.map +1 -0
- package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.cjs +1 -1
- package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.cjs.map +1 -1
- package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.js +1 -1
- package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.js.map +1 -1
- package/dist/production/src/model/queries/idp/helpers.cjs +3 -3
- package/dist/production/src/model/queries/idp/helpers.cjs.map +1 -1
- package/dist/production/src/model/queries/idp/helpers.js +3 -3
- package/dist/production/src/model/queries/idp/helpers.js.map +1 -1
- package/dist/production/src/model/queries/membership/ProjectMembersQuery.cjs +1 -1
- package/dist/production/src/model/queries/membership/ProjectMembersQuery.cjs.map +1 -1
- package/dist/production/src/model/queries/membership/ProjectMembersQuery.js +1 -1
- package/dist/production/src/model/queries/membership/ProjectMembersQuery.js.map +1 -1
- package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.cjs +1 -1
- package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.cjs.map +1 -1
- package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.js +1 -1
- package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
- package/dist/production/src/model/service/AuthLogService.cjs +8 -2
- package/dist/production/src/model/service/AuthLogService.cjs.map +1 -1
- package/dist/production/src/model/service/AuthLogService.js +8 -2
- package/dist/production/src/model/service/AuthLogService.js.map +1 -1
- package/dist/production/src/model/service/IDPSignInManager.cjs +29 -2
- package/dist/production/src/model/service/IDPSignInManager.cjs.map +1 -1
- package/dist/production/src/model/service/IDPSignInManager.js +29 -2
- package/dist/production/src/model/service/IDPSignInManager.js.map +1 -1
- package/dist/production/src/model/service/PanelAccessResolver.cjs +31 -0
- package/dist/production/src/model/service/PanelAccessResolver.cjs.map +1 -0
- package/dist/production/src/model/service/PanelAccessResolver.js +31 -0
- package/dist/production/src/model/service/PanelAccessResolver.js.map +1 -0
- package/dist/production/src/model/service/PasswordResetManager.cjs +5 -0
- package/dist/production/src/model/service/PasswordResetManager.cjs.map +1 -1
- package/dist/production/src/model/service/PasswordResetManager.js +5 -0
- package/dist/production/src/model/service/PasswordResetManager.js.map +1 -1
- package/dist/production/src/model/service/PasswordlessSignInManager.cjs +19 -0
- package/dist/production/src/model/service/PasswordlessSignInManager.cjs.map +1 -1
- package/dist/production/src/model/service/PasswordlessSignInManager.js +19 -0
- package/dist/production/src/model/service/PasswordlessSignInManager.js.map +1 -1
- package/dist/production/src/model/service/PersonAccessManager.cjs +10 -2
- package/dist/production/src/model/service/PersonAccessManager.cjs.map +1 -1
- package/dist/production/src/model/service/PersonAccessManager.js +10 -2
- package/dist/production/src/model/service/PersonAccessManager.js.map +1 -1
- package/dist/production/src/model/service/SignInManager.cjs +5 -0
- package/dist/production/src/model/service/SignInManager.cjs.map +1 -1
- package/dist/production/src/model/service/SignInManager.js +5 -0
- package/dist/production/src/model/service/SignInManager.js.map +1 -1
- package/dist/production/src/model/service/apiKey/ApiKeyManager.cjs +4 -3
- package/dist/production/src/model/service/apiKey/ApiKeyManager.cjs.map +1 -1
- package/dist/production/src/model/service/apiKey/ApiKeyManager.js +4 -3
- package/dist/production/src/model/service/apiKey/ApiKeyManager.js.map +1 -1
- package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.cjs +7 -0
- package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.cjs.map +1 -1
- package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.js +8 -1
- package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.js.map +1 -1
- package/dist/production/src/model/service/idp/ClaimMapping.cjs +187 -0
- package/dist/production/src/model/service/idp/ClaimMapping.cjs.map +1 -0
- package/dist/production/src/model/service/idp/ClaimMapping.js +170 -0
- package/dist/production/src/model/service/idp/ClaimMapping.js.map +1 -0
- package/dist/production/src/model/service/idp/ClaimMappingEvaluator.cjs +155 -0
- package/dist/production/src/model/service/idp/ClaimMappingEvaluator.cjs.map +1 -0
- package/dist/production/src/model/service/idp/ClaimMappingEvaluator.js +155 -0
- package/dist/production/src/model/service/idp/ClaimMappingEvaluator.js.map +1 -0
- package/dist/production/src/model/service/idp/ClaimMappingValidation.cjs +83 -0
- package/dist/production/src/model/service/idp/ClaimMappingValidation.cjs.map +1 -0
- package/dist/production/src/model/service/idp/ClaimMappingValidation.js +83 -0
- package/dist/production/src/model/service/idp/ClaimMappingValidation.js.map +1 -0
- package/dist/production/src/model/service/idp/IDPClaimSyncService.cjs +260 -0
- package/dist/production/src/model/service/idp/IDPClaimSyncService.cjs.map +1 -0
- package/dist/production/src/model/service/idp/IDPClaimSyncService.js +260 -0
- package/dist/production/src/model/service/idp/IDPClaimSyncService.js.map +1 -0
- package/dist/production/src/model/service/idp/IDPManager.cjs +96 -20
- package/dist/production/src/model/service/idp/IDPManager.cjs.map +1 -1
- package/dist/production/src/model/service/idp/IDPManager.js +96 -20
- package/dist/production/src/model/service/idp/IDPManager.js.map +1 -1
- package/dist/production/src/model/service/idp/IdpSessionRevalidator.cjs +55 -1
- package/dist/production/src/model/service/idp/IdpSessionRevalidator.cjs.map +1 -1
- package/dist/production/src/model/service/idp/IdpSessionRevalidator.js +55 -1
- package/dist/production/src/model/service/idp/IdpSessionRevalidator.js.map +1 -1
- package/dist/production/src/model/service/idp/PersonIdentityProviderManager.cjs +6 -0
- package/dist/production/src/model/service/idp/PersonIdentityProviderManager.cjs.map +1 -1
- package/dist/production/src/model/service/idp/PersonIdentityProviderManager.js +6 -0
- package/dist/production/src/model/service/idp/PersonIdentityProviderManager.js.map +1 -1
- package/dist/production/src/model/service/idp/providers/OIDCHelpers.cjs +69 -33
- package/dist/production/src/model/service/idp/providers/OIDCHelpers.cjs.map +1 -1
- package/dist/production/src/model/service/idp/providers/OIDCHelpers.js +69 -33
- package/dist/production/src/model/service/idp/providers/OIDCHelpers.js.map +1 -1
- package/dist/production/src/model/service/idp/providers/OIDCProvider.cjs +4 -1
- package/dist/production/src/model/service/idp/providers/OIDCProvider.cjs.map +1 -1
- package/dist/production/src/model/service/idp/providers/OIDCProvider.js +4 -1
- package/dist/production/src/model/service/idp/providers/OIDCProvider.js.map +1 -1
- package/dist/production/src/model/utils/DatabaseContext.cjs +7 -2
- package/dist/production/src/model/utils/DatabaseContext.cjs.map +1 -1
- package/dist/production/src/model/utils/DatabaseContext.js +8 -3
- package/dist/production/src/model/utils/DatabaseContext.js.map +1 -1
- package/dist/production/src/resolvers/ResolverFactory.cjs +6 -2
- package/dist/production/src/resolvers/ResolverFactory.cjs.map +1 -1
- package/dist/production/src/resolvers/ResolverFactory.js +6 -2
- package/dist/production/src/resolvers/ResolverFactory.js.map +1 -1
- package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs +4 -2
- package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.js +4 -2
- package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs +4 -2
- package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js +4 -2
- package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/audit.cjs +1 -0
- package/dist/production/src/resolvers/mutation/idp/audit.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/idp/audit.js +1 -0
- package/dist/production/src/resolvers/mutation/idp/audit.js.map +1 -1
- package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs +4 -3
- package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.js +4 -3
- package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs +60 -0
- package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs.map +1 -0
- package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.js +60 -0
- package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.js.map +1 -0
- package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.cjs +27 -1
- package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.js +27 -1
- package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs +6 -1
- package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.js +6 -1
- package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.cjs +4 -3
- package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.js +4 -3
- package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs +2 -1
- package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js +2 -1
- package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/ApiKeyQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/ApiKeyQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/ApiKeyQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/ApiKeyQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/AuthLogQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/AuthLogQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/AuthLogQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/AuthLogQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/ConfigurationQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/ConfigurationQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/ConfigurationQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/ConfigurationQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/IDPQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/IDPQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/IDPQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/IDPQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/MailTemplateQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/MailTemplateQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/MailTemplateQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/MailTemplateQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/PersonQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/PersonQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/PersonQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/PersonQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.cjs +2 -1
- package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.js +2 -1
- package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/query/ProjectQueryResolver.cjs +5 -3
- package/dist/production/src/resolvers/query/ProjectQueryResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/query/ProjectQueryResolver.js +5 -3
- package/dist/production/src/resolvers/query/ProjectQueryResolver.js.map +1 -1
- package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs +2 -1
- package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs.map +1 -1
- package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.js +2 -1
- package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.js.map +1 -1
- package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.cjs +5 -0
- package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.cjs.map +1 -1
- package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.js +5 -0
- package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.js.map +1 -1
- package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.cjs +23 -0
- package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.cjs.map +1 -0
- package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.js +23 -0
- package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.js.map +1 -0
- package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.cjs +2 -1
- package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.cjs.map +1 -1
- package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.js +2 -1
- package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.js.map +1 -1
- package/dist/production/src/resolvers/types/IdentityTypeResolver.cjs +37 -4
- package/dist/production/src/resolvers/types/IdentityTypeResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/types/IdentityTypeResolver.js +37 -4
- package/dist/production/src/resolvers/types/IdentityTypeResolver.js.map +1 -1
- package/dist/production/src/resolvers/types/PersonTypeResolver.cjs +30 -1
- package/dist/production/src/resolvers/types/PersonTypeResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/types/PersonTypeResolver.js +30 -1
- package/dist/production/src/resolvers/types/PersonTypeResolver.js.map +1 -1
- package/dist/production/src/resolvers/types/ProjectTypeResolver.cjs +25 -1
- package/dist/production/src/resolvers/types/ProjectTypeResolver.cjs.map +1 -1
- package/dist/production/src/resolvers/types/ProjectTypeResolver.js +25 -1
- package/dist/production/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
- package/dist/production/src/schema/tenant.graphql.cjs +144 -0
- package/dist/production/src/schema/tenant.graphql.cjs.map +1 -1
- package/dist/production/src/schema/tenant.graphql.js +144 -0
- package/dist/production/src/schema/tenant.graphql.js.map +1 -1
- package/dist/tests/cases/integration/mocked/configurationPanel.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/configurationPanel.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/disablePersonMutation.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/disablePersonMutation.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/enablePersonMutation.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/enablePersonMutation.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/gql/addProjectMember.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/changeMyPassword.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/changeMyProfile.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/changePassword.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/changeProfile.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/confirmOtp.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/createApiKey.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/createResetPasswordRequest.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/createSessionToken.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/emailOtp.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/emailVerification.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/invite.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/myIdentityProviders.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/passwordless.d.ts +4 -1
- package/dist/tests/cases/integration/mocked/gql/passwordless.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/prepareOtp.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/resetPassword.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/signIn.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/signInIdp.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/signUp.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/unmanagedInvite.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/gql/updateProjectMember.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/idpClaimMappingConfig.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/idpClaimMappingConfig.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/localAuthenticationDisabled.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/localAuthenticationDisabled.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/permissionsQuery.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/permissionsQuery.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/signInIdpClaimMapping.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/signInIdpClaimMapping.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/signInIdpClaimMappingFixes.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/signInIdpClaimMappingFixes.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/signInIdpClaimMappingSafety.test.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/signInIdpClaimMappingSafety.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/sql/authLogSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/authPolicySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/consumeBackupCodeSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createApiKeySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createIdentitySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createMembershipSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createMembershipVariableSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createPersonSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createPersonTokenSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/createSessionKeySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/disableApiKeySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/disableOneOffKeySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/emailOtpSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/generateBackupCodesSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getApiKeySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getConfigSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getIdentityByIdSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getIdentityProjectsSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getIdpBySlugSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getIdpSessionByApiKeySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getMailTemplateSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getNextLoginAttemptSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getNextMailAttemptSql.d.ts +1 -1
- package/dist/tests/cases/integration/mocked/sql/getNextMailAttemptSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getPersonByEmailSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getPersonByIdentity.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getPersonByIdpSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getPersonsByIdentitySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getProjectBySlugSql.d.ts +1 -1
- package/dist/tests/cases/integration/mocked/sql/getProjectBySlugSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/getProjectMembershipSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/listApiKeysSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/listPersonsSql.d.ts +2 -0
- package/dist/tests/cases/integration/mocked/sql/listPersonsSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/listProjectSecretsSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/listSessionsSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/localAuthDisablingIdpsSql.d.ts +10 -0
- package/dist/tests/cases/integration/mocked/sql/localAuthDisablingIdpsSql.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/sql/loginHistorySql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/patchVariablesSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/personIdentityProvidersSql.d.ts +1 -0
- package/dist/tests/cases/integration/mocked/sql/personIdentityProvidersSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/removeMembershipSql.d.ts +8 -0
- package/dist/tests/cases/integration/mocked/sql/removeMembershipSql.d.ts.map +1 -0
- package/dist/tests/cases/integration/mocked/sql/selectMembershipsSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/setEmailOtpEnabledSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/sqlTransaction.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/updatePesonNameSql.d.ts.map +1 -1
- package/dist/tests/cases/integration/mocked/sql/updatePesonPasswordSql.d.ts.map +1 -1
- package/dist/tests/cases/unit/databaseContextRetry.test.d.ts +2 -0
- package/dist/tests/cases/unit/databaseContextRetry.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/idp/claimMappingEvaluator.test.d.ts +2 -0
- package/dist/tests/cases/unit/idp/claimMappingEvaluator.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/idp/claimMappingValidation.test.d.ts +2 -0
- package/dist/tests/cases/unit/idp/claimMappingValidation.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/idp/idpManagerConfigMerge.test.d.ts +2 -0
- package/dist/tests/cases/unit/idp/idpManagerConfigMerge.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/idp/idpManagerUnknownConfigKeys.test.d.ts +2 -0
- package/dist/tests/cases/unit/idp/idpManagerUnknownConfigKeys.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/idp/oidcClaims.test.d.ts +2 -0
- package/dist/tests/cases/unit/idp/oidcClaims.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/panelAccessResolver.test.d.ts +2 -0
- package/dist/tests/cases/unit/panelAccessResolver.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/updateConfigurationCommand.test.d.ts +2 -0
- package/dist/tests/cases/unit/updateConfigurationCommand.test.d.ts.map +1 -0
- package/dist/tests/src/IdPMock.d.ts.map +1 -1
- package/dist/tests/src/dbUtils.d.ts.map +1 -1
- package/dist/tests/src/tags.d.ts.map +1 -1
- package/dist/tests/src/testGraphql.d.ts.map +1 -1
- package/dist/tests/src/testTenant.d.ts +7 -1
- package/dist/tests/src/testTenant.d.ts.map +1 -1
- package/dist/tests/src/testUuid.d.ts.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/TenantContainer.d.ts +21 -13
- package/dist/types/TenantContainer.d.ts.map +1 -1
- package/dist/types/bridges/system/IdentityFetcher.d.ts +2 -2
- package/dist/types/bridges/system/IdentityFetcher.d.ts.map +1 -1
- package/dist/types/exceptions.d.ts.map +1 -1
- package/dist/types/migrations/2026-06-18-120000-idp-claim-mapping.d.ts +3 -0
- package/dist/types/migrations/2026-06-18-120000-idp-claim-mapping.d.ts.map +1 -0
- package/dist/types/migrations/2026-08-03-120000-person-enable-auth-log.d.ts +3 -0
- package/dist/types/migrations/2026-08-03-120000-person-enable-auth-log.d.ts.map +1 -0
- package/dist/types/migrations/2026-08-04-120000-config-panel.d.ts +3 -0
- package/dist/types/migrations/2026-08-04-120000-config-panel.d.ts.map +1 -0
- package/dist/types/migrations/2026-09-04-120000-idp-disable-local-authentication.d.ts +3 -0
- package/dist/types/migrations/2026-09-04-120000-idp-disable-local-authentication.d.ts.map +1 -0
- package/dist/types/migrations/runner.d.ts.map +1 -1
- package/dist/types/migrations/snapshot-factory.d.ts.map +1 -1
- package/dist/types/migrations/snapshot.d.ts.map +1 -1
- package/dist/types/migrations/tenantCredentials.d.ts.map +1 -1
- package/dist/types/model/authorization/AclSchemaAccessNodeFactory.d.ts.map +1 -1
- package/dist/types/model/authorization/DirectPermissionsAccessNode.d.ts.map +1 -1
- package/dist/types/model/authorization/Identity.d.ts.map +1 -1
- package/dist/types/model/authorization/IdentityFactory.d.ts.map +1 -1
- package/dist/types/model/authorization/IdentityScope.d.ts.map +1 -1
- package/dist/types/model/authorization/MembershipMatcher.d.ts.map +1 -1
- package/dist/types/model/authorization/PermissionActions.d.ts.map +1 -1
- package/dist/types/model/authorization/PermissionContext.d.ts.map +1 -1
- package/dist/types/model/authorization/PermissionContextFactory.d.ts.map +1 -1
- package/dist/types/model/authorization/PermissionsFactory.d.ts.map +1 -1
- package/dist/types/model/authorization/ProjectScope.d.ts.map +1 -1
- package/dist/types/model/authorization/ProjectScopeFactory.d.ts.map +1 -1
- package/dist/types/model/commands/CommandBus.d.ts.map +1 -1
- package/dist/types/model/commands/apiKey/ApiKeyHelper.d.ts.map +1 -1
- package/dist/types/model/commands/apiKey/CreateApiKeyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/apiKey/DisableApiKeyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/apiKey/DisableIdentityApiKeysCommand.d.ts.map +1 -1
- package/dist/types/model/commands/apiKey/DisableOneOffApiKeyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/apiKey/ProlongApiKeyCommand.d.ts +1 -1
- package/dist/types/model/commands/apiKey/ProlongApiKeyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/authLog/CreateAuthLogEntryCommand.d.ts.map +1 -1
- package/dist/types/model/commands/authPolicy/CreateAuthPolicyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/authPolicy/DeleteAuthPolicyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/authPolicy/UpdateAuthPolicyCommand.d.ts.map +1 -1
- package/dist/types/model/commands/backupCode/ConsumeBackupCodeCommand.d.ts.map +1 -1
- package/dist/types/model/commands/backupCode/CreateBackupCodeCommand.d.ts.map +1 -1
- package/dist/types/model/commands/backupCode/DeleteBackupCodesCommand.d.ts.map +1 -1
- package/dist/types/model/commands/configuration/UpdateConfigurationCommand.d.ts.map +1 -1
- package/dist/types/model/commands/identity/CreateIdentityCommand.d.ts.map +1 -1
- package/dist/types/model/commands/identity/PatchIdentityGlobalRoles.d.ts.map +1 -1
- package/dist/types/model/commands/idp/ClaimIdpRevalidationCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/CreateIdpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/CreateIdpSessionCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/DisableIdpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/DisconnectPersonIdentityProviderCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/EnableIdpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/UpdateIdpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/idp/UpdateIdpSessionCommand.d.ts.map +1 -1
- package/dist/types/model/commands/mailTemplate/AddMailTemplateCommand.d.ts.map +1 -1
- package/dist/types/model/commands/mailTemplate/RemoveMailTemplateCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/AddProjectMemberCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/CreateOrUpdateProjectMembershipCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/RemoveProjectMemberCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/{RemoveProjectMembershipsCommand.d.ts → RemoveProjectMembershipCommand.d.ts} +1 -1
- package/dist/types/model/commands/membership/RemoveProjectMembershipCommand.d.ts.map +1 -0
- package/dist/types/model/commands/membership/UpdateProjectMemberCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/index.d.ts +2 -1
- package/dist/types/model/commands/membership/index.d.ts.map +1 -1
- package/dist/types/model/commands/membership/variables/PatchProjectMembershipVariableValuesCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/variables/PatchProjectMembershipVariablesCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/variables/SetProjectMembershipVariableValuesCommand.d.ts.map +1 -1
- package/dist/types/model/commands/membership/variables/index.d.ts +1 -0
- package/dist/types/model/commands/membership/variables/index.d.ts.map +1 -1
- package/dist/types/model/commands/otp/ConfirmOtpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/otp/DisableOtpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/otp/PrepareOtpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/otp/ReEncryptOtpSecretCommand.d.ts.map +1 -1
- package/dist/types/model/commands/otp/SetEmailOtpEnabledCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/ChangePasswordCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/ChangeProfileCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/CreatePersonCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/CreatePersonIdentityProviderIdentifierCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/DisablePersonCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/EnablePersonCommand.d.ts +7 -0
- package/dist/types/model/commands/person/EnablePersonCommand.d.ts.map +1 -0
- package/dist/types/model/commands/person/MarkEmailVerifiedCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/ResetPersonMfaCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/SetMfaGraceUntilCommand.d.ts.map +1 -1
- package/dist/types/model/commands/person/TogglePersonPasswordlessCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/ActivateOtpCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/ClaimOtpAttemptCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/CreatePersonTokenCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/IncreaseOtpAttemptCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/InvalidateEmailOtpTokensCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/InvalidateTokenCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/ResetPasswordCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/SaveEmailOtpTokenCommand.d.ts.map +1 -1
- package/dist/types/model/commands/personToken/SavePersonTokenCommand.d.ts.map +1 -1
- package/dist/types/model/commands/project/CreateProjectCommand.d.ts.map +1 -1
- package/dist/types/model/commands/project/SetProjectSecretCommand.d.ts.map +1 -1
- package/dist/types/model/commands/project/UpdateProjectCommand.d.ts.map +1 -1
- package/dist/types/model/commands/rateLimit/RecordRateLimitEventCommand.d.ts.map +1 -1
- package/dist/types/model/dtos/Password.d.ts.map +1 -1
- package/dist/types/model/mailing/UserMailer.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/BackupCodesExhausted.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/EmailChangeNotify.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/EmailChangeVerify.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/EmailOtp.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/EmailVerification.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/ExistingUserInvited.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/ForcedSignOut.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/Layout.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/NewUserInvited.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/PasswordReset.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/PasswordlessSignIn.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/templates/UnusualLogin.mustache.d.ts.map +1 -1
- package/dist/types/model/mailing/type.d.ts.map +1 -1
- package/dist/types/model/queries/apiKey/ApiKeyListQuery.d.ts.map +1 -1
- package/dist/types/model/queries/apiKey/ApiKeyQuery.d.ts.map +1 -1
- package/dist/types/model/queries/apiKey/ApiKeySessionsQuery.d.ts.map +1 -1
- package/dist/types/model/queries/authLog/AuthLogQuery.d.ts.map +1 -1
- package/dist/types/model/queries/authLog/NextLoginAttemptQuery.d.ts.map +1 -1
- package/dist/types/model/queries/authLog/NextMailAttemptQuery.d.ts.map +1 -1
- package/dist/types/model/queries/authPolicy/AuthPoliciesQuery.d.ts.map +1 -1
- package/dist/types/model/queries/configuration/ConfigurationQuery.d.ts.map +1 -1
- package/dist/types/model/queries/identity/IdentityQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/IdentityProviderBySlugQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/IdentityProvidersQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/IdpSessionByApiKeyQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/IdpSessionsBySidQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/IdpSessionsBySubQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/LocalAuthDisablingIdpsQuery.d.ts +18 -0
- package/dist/types/model/queries/idp/LocalAuthDisablingIdpsQuery.d.ts.map +1 -0
- package/dist/types/model/queries/idp/PersonIdentityProvidersQuery.d.ts +1 -0
- package/dist/types/model/queries/idp/PersonIdentityProvidersQuery.d.ts.map +1 -1
- package/dist/types/model/queries/idp/helpers.d.ts +1 -1
- package/dist/types/model/queries/idp/helpers.d.ts.map +1 -1
- package/dist/types/model/queries/idp/index.d.ts +1 -0
- package/dist/types/model/queries/idp/index.d.ts.map +1 -1
- package/dist/types/model/queries/idp/types.d.ts +1 -0
- package/dist/types/model/queries/idp/types.d.ts.map +1 -1
- package/dist/types/model/queries/mailTemplate/MailTemplateListQuery.d.ts.map +1 -1
- package/dist/types/model/queries/mailTemplate/MailTemplateQuery.d.ts.map +1 -1
- package/dist/types/model/queries/membership/AllProjectRolesByIdentityQuery.d.ts.map +1 -1
- package/dist/types/model/queries/membership/ProjectMembersQuery.d.ts.map +1 -1
- package/dist/types/model/queries/membership/ProjectMembershipByIdentityQuery.d.ts.map +1 -1
- package/dist/types/model/queries/membership/ProjectRolesByIdentityQuery.d.ts.map +1 -1
- package/dist/types/model/queries/membership/ProjectSlugSpecification.d.ts.map +1 -1
- package/dist/types/model/queries/person/PersonByIdPQuery.d.ts.map +1 -1
- package/dist/types/model/queries/person/PersonByIdentityBatchQuery.d.ts.map +1 -1
- package/dist/types/model/queries/person/PersonQuery.d.ts.map +1 -1
- package/dist/types/model/queries/person/PersonQueryBuilderFactory.d.ts.map +1 -1
- package/dist/types/model/queries/person/PersonsQuery.d.ts.map +1 -1
- package/dist/types/model/queries/person/types.d.ts +1 -0
- package/dist/types/model/queries/person/types.d.ts.map +1 -1
- package/dist/types/model/queries/personToken/PersonTokenQuery.d.ts.map +1 -1
- package/dist/types/model/queries/project/ProjectBySlugQuery.d.ts.map +1 -1
- package/dist/types/model/queries/project/ProjectSecretKeysQuery.d.ts.map +1 -1
- package/dist/types/model/queries/project/ProjectSecretsQuery.d.ts.map +1 -1
- package/dist/types/model/queries/project/ProjectUpdateTimestampQuery.d.ts.map +1 -1
- package/dist/types/model/queries/project/ProjectsByIdentityQuery.d.ts.map +1 -1
- package/dist/types/model/queries/project/ProjectsQuery.d.ts.map +1 -1
- package/dist/types/model/queries/rateLimit/RateLimitCountQuery.d.ts.map +1 -1
- package/dist/types/model/service/AuthLogService.d.ts.map +1 -1
- package/dist/types/model/service/AuthPolicyManager.d.ts.map +1 -1
- package/dist/types/model/service/AuthPolicyResolver.d.ts.map +1 -1
- package/dist/types/model/service/BackupCodeManager.d.ts.map +1 -1
- package/dist/types/model/service/ConfigurationManager.d.ts.map +1 -1
- package/dist/types/model/service/EmailChangeManager.d.ts.map +1 -1
- package/dist/types/model/service/EmailOtpManager.d.ts.map +1 -1
- package/dist/types/model/service/EmailValidator.d.ts.map +1 -1
- package/dist/types/model/service/EmailVerificationManager.d.ts.map +1 -1
- package/dist/types/model/service/HibpChecker.d.ts.map +1 -1
- package/dist/types/model/service/IDPSignInManager.d.ts +11 -1
- package/dist/types/model/service/IDPSignInManager.d.ts.map +1 -1
- package/dist/types/model/service/InviteManager.d.ts.map +1 -1
- package/dist/types/model/service/LoginRiskAnalyzer.d.ts +1 -1
- package/dist/types/model/service/LoginRiskAnalyzer.d.ts.map +1 -1
- package/dist/types/model/service/MailTemplateManager.d.ts.map +1 -1
- package/dist/types/model/service/MembershipValidator.d.ts.map +1 -1
- package/dist/types/model/service/OtpAuthenticator.d.ts.map +1 -1
- package/dist/types/model/service/OtpManager.d.ts.map +1 -1
- package/dist/types/model/service/PanelAccessResolver.d.ts +19 -0
- package/dist/types/model/service/PanelAccessResolver.d.ts.map +1 -0
- package/dist/types/model/service/PasswordChangeManager.d.ts.map +1 -1
- package/dist/types/model/service/PasswordResetManager.d.ts.map +1 -1
- package/dist/types/model/service/PasswordStrengthValidator.d.ts.map +1 -1
- package/dist/types/model/service/PasswordlessSignInManager.d.ts.map +1 -1
- package/dist/types/model/service/PersonAccessManager.d.ts +5 -2
- package/dist/types/model/service/PersonAccessManager.d.ts.map +1 -1
- package/dist/types/model/service/PersonManager.d.ts.map +1 -1
- package/dist/types/model/service/ProjectManager.d.ts.map +1 -1
- package/dist/types/model/service/ProjectMemberManager.d.ts.map +1 -1
- package/dist/types/model/service/RateLimiter.d.ts.map +1 -1
- package/dist/types/model/service/RolesManager.d.ts.map +1 -1
- package/dist/types/model/service/SecretsManager.d.ts.map +1 -1
- package/dist/types/model/service/SignInManager.d.ts.map +1 -1
- package/dist/types/model/service/SignOutManager.d.ts.map +1 -1
- package/dist/types/model/service/SignUpManager.d.ts.map +1 -1
- package/dist/types/model/service/apiKey/ApiKeyManager.d.ts.map +1 -1
- package/dist/types/model/service/apiKey/ApiKeyService.d.ts.map +1 -1
- package/dist/types/model/service/apiKey/UnpersistedApiKeyManager.d.ts +18 -0
- package/dist/types/model/service/apiKey/UnpersistedApiKeyManager.d.ts.map +1 -1
- package/dist/types/model/service/captcha/CaptchaValidator.d.ts.map +1 -1
- package/dist/types/model/service/captcha/HCaptchaProvider.d.ts.map +1 -1
- package/dist/types/model/service/captcha/RecaptchaV3Provider.d.ts.map +1 -1
- package/dist/types/model/service/captcha/TurnstileProvider.d.ts.map +1 -1
- package/dist/types/model/service/helpers/getPreferredProject.d.ts.map +1 -1
- package/dist/types/model/service/helpers/isPasswordlessEnabled.d.ts.map +1 -1
- package/dist/types/model/service/idp/BackchannelLogoutManager.d.ts.map +1 -1
- package/dist/types/model/service/idp/ClaimMapping.d.ts +330 -0
- package/dist/types/model/service/idp/ClaimMapping.d.ts.map +1 -0
- package/dist/types/model/service/idp/ClaimMappingEvaluator.d.ts +30 -0
- package/dist/types/model/service/idp/ClaimMappingEvaluator.d.ts.map +1 -0
- package/dist/types/model/service/idp/ClaimMappingValidation.d.ts +55 -0
- package/dist/types/model/service/idp/ClaimMappingValidation.d.ts.map +1 -0
- package/dist/types/model/service/idp/IDPClaimSyncService.d.ts +113 -0
- package/dist/types/model/service/idp/IDPClaimSyncService.d.ts.map +1 -0
- package/dist/types/model/service/idp/IDPHandlerRegistry.d.ts.map +1 -1
- package/dist/types/model/service/idp/IDPManager.d.ts +31 -1
- package/dist/types/model/service/idp/IDPManager.d.ts.map +1 -1
- package/dist/types/model/service/idp/IdentityProviderHandler.d.ts +7 -0
- package/dist/types/model/service/idp/IdentityProviderHandler.d.ts.map +1 -1
- package/dist/types/model/service/idp/IdpSessionRevalidator.d.ts +13 -1
- package/dist/types/model/service/idp/IdpSessionRevalidator.d.ts.map +1 -1
- package/dist/types/model/service/idp/PersonIdentityProviderManager.d.ts.map +1 -1
- package/dist/types/model/service/idp/index.d.ts +4 -0
- package/dist/types/model/service/idp/index.d.ts.map +1 -1
- package/dist/types/model/service/idp/providers/AppleProvider.d.ts +2 -2
- package/dist/types/model/service/idp/providers/AppleProvider.d.ts.map +1 -1
- package/dist/types/model/service/idp/providers/FacebookProvider.d.ts +2 -2
- package/dist/types/model/service/idp/providers/FacebookProvider.d.ts.map +1 -1
- package/dist/types/model/service/idp/providers/OIDCHelpers.d.ts +13 -1
- package/dist/types/model/service/idp/providers/OIDCHelpers.d.ts.map +1 -1
- package/dist/types/model/service/idp/providers/OIDCProvider.d.ts +1 -1
- package/dist/types/model/service/idp/providers/OIDCProvider.d.ts.map +1 -1
- package/dist/types/model/service/idp/providers/OIDCTypes.d.ts +5 -5
- package/dist/types/model/service/idp/providers/helpers.d.ts.map +1 -1
- package/dist/types/model/service/index.d.ts +1 -0
- package/dist/types/model/service/index.d.ts.map +1 -1
- package/dist/types/model/service/membershipUtils.d.ts.map +1 -1
- package/dist/types/model/type/AuthLog.d.ts +1 -1
- package/dist/types/model/type/AuthLog.d.ts.map +1 -1
- package/dist/types/model/type/Config.d.ts +2 -0
- package/dist/types/model/type/Config.d.ts.map +1 -1
- package/dist/types/model/type/IdentityProvider.d.ts +2 -0
- package/dist/types/model/type/IdentityProvider.d.ts.map +1 -1
- package/dist/types/model/type/RateLimit.d.ts +6 -6
- package/dist/types/model/type/RateLimit.d.ts.map +1 -1
- package/dist/types/model/utils/DatabaseContext.d.ts +14 -1
- package/dist/types/model/utils/DatabaseContext.d.ts.map +1 -1
- package/dist/types/model/utils/Response.d.ts.map +1 -1
- package/dist/types/model/utils/email.d.ts.map +1 -1
- package/dist/types/model/utils/hex.d.ts.map +1 -1
- package/dist/types/model/utils/interval.d.ts.map +1 -1
- package/dist/types/model/utils/time.d.ts.map +1 -1
- package/dist/types/model/utils/token.d.ts.map +1 -1
- package/dist/types/resolvers/ResolverFactory.d.ts +2 -0
- package/dist/types/resolvers/ResolverFactory.d.ts.map +1 -1
- package/dist/types/resolvers/TenantResolverContextFactory.d.ts.map +1 -1
- package/dist/types/resolvers/errorUtils.d.ts.map +1 -1
- package/dist/types/resolvers/membershipUtils.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/configuration/AuthPolicyMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/configuration/ConfigurationMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/identity/GlobalRolesMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/idp/AddIDPMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/idp/DisableIDPMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/idp/EnableIDPMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/idp/UpdateIDPMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/idp/audit.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/ChangePasswordMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/ChangeProfileMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/DisablePersonMutationResolver.d.ts +1 -1
- package/dist/types/resolvers/mutation/person/DisablePersonMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/EmailOtpMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/EmailVerificationMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/EnablePersonMutationResolver.d.ts +11 -0
- package/dist/types/resolvers/mutation/person/EnablePersonMutationResolver.d.ts.map +1 -0
- package/dist/types/resolvers/mutation/person/ForceSignOutMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/IDPMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/InviteMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/OtpMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/PasswordlessMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/ResetPasswordMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/ResetPersonMfaMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/RevokeSessionMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/SignInMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/SignOutMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/SignUpMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/person/TogglePasswordlessMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/project/CreateProjectMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/project/SetProjectSecretMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/project/UpdateProjectMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.d.ts.map +1 -1
- package/dist/types/resolvers/mutation/projectMember/audit.d.ts +1 -1
- package/dist/types/resolvers/mutation/projectMember/audit.d.ts.map +1 -1
- package/dist/types/resolvers/query/ApiKeyQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/AuthLogQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/AuthPolicyQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/ConfigurationQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/IDPQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/MailTemplateQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/MeQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/PersonQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/ProjectMembersQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/query/ProjectQueryResolver.d.ts.map +1 -1
- package/dist/types/resolvers/responseHelpers/ApiKeyResponseFactory.d.ts.map +1 -1
- package/dist/types/resolvers/responseHelpers/PersonResponseFactory.d.ts.map +1 -1
- package/dist/types/resolvers/responseHelpers/ProjectResponseFactory.d.ts +10 -0
- package/dist/types/resolvers/responseHelpers/ProjectResponseFactory.d.ts.map +1 -0
- package/dist/types/resolvers/responseHelpers/SignInResponseFactory.d.ts.map +1 -1
- package/dist/types/resolvers/types/IdentityTypeResolver.d.ts.map +1 -1
- package/dist/types/resolvers/types/PersonTypeResolver.d.ts +15 -1
- package/dist/types/resolvers/types/PersonTypeResolver.d.ts.map +1 -1
- package/dist/types/resolvers/types/ProjectTypeResolver.d.ts +15 -6
- package/dist/types/resolvers/types/ProjectTypeResolver.d.ts.map +1 -1
- package/dist/types/schema/index.d.ts +194 -4
- package/dist/types/schema/index.d.ts.map +1 -1
- package/dist/types/schema/tenant.graphql.d.ts.map +1 -1
- package/dist/types/schema/types.d.ts +2 -2
- package/dist/types/schema/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/utils/Mailer.d.ts.map +1 -1
- package/dist/types/utils/TemplateRenderer.d.ts.map +1 -1
- package/dist/types/utils/array.d.ts.map +1 -1
- package/dist/types/utils/batchQuery.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/TenantContainer.ts +17 -3
- package/src/migrations/2026-06-18-120000-idp-claim-mapping.ts +15 -0
- package/src/migrations/2026-08-03-120000-person-enable-auth-log.ts +12 -0
- package/src/migrations/2026-08-04-120000-config-panel.ts +13 -0
- package/src/migrations/2026-09-04-120000-idp-disable-local-authentication.ts +18 -0
- package/src/migrations/runner.ts +8 -0
- package/src/migrations/snapshot.ts +8 -2
- package/src/model/commands/configuration/UpdateConfigurationCommand.ts +5 -4
- package/src/model/commands/idp/CreateIdpCommand.ts +7 -1
- package/src/model/commands/idp/UpdateIdpCommand.ts +5 -1
- package/src/model/commands/membership/UpdateProjectMemberCommand.ts +1 -1
- package/src/model/commands/membership/index.ts +2 -1
- package/src/model/commands/membership/variables/index.ts +1 -0
- package/src/model/commands/person/EnablePersonCommand.ts +18 -0
- package/src/model/queries/configuration/ConfigurationQuery.ts +4 -0
- package/src/model/queries/idp/LocalAuthDisablingIdpsQuery.ts +41 -0
- package/src/model/queries/idp/PersonIdentityProvidersQuery.ts +2 -0
- package/src/model/queries/idp/helpers.ts +3 -2
- package/src/model/queries/idp/index.ts +1 -0
- package/src/model/queries/idp/types.ts +1 -0
- package/src/model/queries/membership/ProjectMembersQuery.ts +1 -0
- package/src/model/queries/person/PersonQueryBuilderFactory.ts +1 -0
- package/src/model/queries/person/types.ts +1 -0
- package/src/model/service/AuthLogService.ts +18 -2
- package/src/model/service/IDPSignInManager.ts +49 -1
- package/src/model/service/PanelAccessResolver.ts +32 -0
- package/src/model/service/PasswordResetManager.ts +9 -1
- package/src/model/service/PasswordlessSignInManager.ts +23 -1
- package/src/model/service/PersonAccessManager.ts +19 -3
- package/src/model/service/SignInManager.ts +9 -1
- package/src/model/service/apiKey/ApiKeyManager.ts +5 -3
- package/src/model/service/apiKey/UnpersistedApiKeyManager.ts +24 -0
- package/src/model/service/idp/ClaimMapping.ts +283 -0
- package/src/model/service/idp/ClaimMappingEvaluator.ts +226 -0
- package/src/model/service/idp/ClaimMappingValidation.ts +158 -0
- package/src/model/service/idp/IDPClaimSyncService.ts +401 -0
- package/src/model/service/idp/IDPManager.ts +126 -21
- package/src/model/service/idp/IdentityProviderHandler.ts +7 -0
- package/src/model/service/idp/IdpSessionRevalidator.ts +90 -0
- package/src/model/service/idp/PersonIdentityProviderManager.ts +8 -0
- package/src/model/service/idp/index.ts +4 -0
- package/src/model/service/idp/providers/OIDCHelpers.ts +161 -53
- package/src/model/service/idp/providers/OIDCProvider.ts +4 -1
- package/src/model/service/index.ts +1 -0
- package/src/model/type/AuthLog.ts +3 -0
- package/src/model/type/Config.ts +3 -0
- package/src/model/type/IdentityProvider.ts +2 -0
- package/src/model/utils/DatabaseContext.ts +27 -6
- package/src/resolvers/ResolverFactory.ts +6 -0
- package/src/resolvers/mutation/idp/AddIDPMutationResolver.ts +1 -0
- package/src/resolvers/mutation/idp/UpdateIDPMutationResolver.ts +1 -0
- package/src/resolvers/mutation/idp/audit.ts +1 -0
- package/src/resolvers/mutation/person/DisablePersonMutationResolver.ts +3 -3
- package/src/resolvers/mutation/person/EnablePersonMutationResolver.ts +50 -0
- package/src/resolvers/mutation/person/IDPMutationResolver.ts +31 -0
- package/src/resolvers/mutation/person/PasswordlessMutationResolver.ts +7 -0
- package/src/resolvers/mutation/person/SignInMutationResolver.ts +2 -2
- package/src/resolvers/query/ProjectQueryResolver.ts +3 -2
- package/src/resolvers/responseHelpers/PersonResponseFactory.ts +5 -0
- package/src/resolvers/responseHelpers/ProjectResponseFactory.ts +24 -0
- package/src/resolvers/types/IdentityTypeResolver.ts +39 -3
- package/src/resolvers/types/PersonTypeResolver.ts +35 -2
- package/src/resolvers/types/ProjectTypeResolver.ts +33 -1
- package/src/schema/index.ts +212 -0
- package/src/schema/tenant.graphql.ts +144 -0
- package/tests/cases/integration/mocked/configurationPanel.test.ts +105 -0
- package/tests/cases/integration/mocked/disablePersonMutation.test.ts +89 -0
- package/tests/cases/integration/mocked/enablePersonMutation.test.ts +130 -0
- package/tests/cases/integration/mocked/gql/passwordless.ts +10 -0
- package/tests/cases/integration/mocked/idpClaimMappingConfig.test.ts +332 -0
- package/tests/cases/integration/mocked/listProjectMembersQuery.test.ts +8 -3
- package/tests/cases/integration/mocked/localAuthenticationDisabled.test.ts +182 -0
- package/tests/cases/integration/mocked/permissionsQuery.test.ts +153 -0
- package/tests/cases/integration/mocked/personIdentityProviders.test.ts +67 -0
- package/tests/cases/integration/mocked/personsQuery.test.ts +38 -5
- package/tests/cases/integration/mocked/signInAnomalyDetection.test.ts +11 -0
- package/tests/cases/integration/mocked/signInIdpClaimMapping.test.ts +1258 -0
- package/tests/cases/integration/mocked/signInIdpClaimMappingFixes.test.ts +344 -0
- package/tests/cases/integration/mocked/signInIdpClaimMappingSafety.test.ts +531 -0
- package/tests/cases/integration/mocked/signInIdpMutation.test.ts +5 -0
- package/tests/cases/integration/mocked/signInMfaEnforcement.test.ts +7 -0
- package/tests/cases/integration/mocked/signInMutation.test.ts +14 -0
- package/tests/cases/integration/mocked/signInPasswordlessMutation.test.ts +36 -0
- package/tests/cases/integration/mocked/sql/getConfigSql.ts +3 -0
- package/tests/cases/integration/mocked/sql/getIdpBySlugSql.ts +1 -1
- package/tests/cases/integration/mocked/sql/getProjectBySlugSql.ts +1 -1
- package/tests/cases/integration/mocked/sql/listPersonsSql.ts +5 -2
- package/tests/cases/integration/mocked/sql/localAuthDisablingIdpsSql.ts +21 -0
- package/tests/cases/integration/mocked/sql/personIdentityProvidersSql.ts +3 -1
- package/tests/cases/integration/mocked/sql/removeMembershipSql.ts +14 -0
- package/tests/cases/integration/mocked/trustForwardedClientInfo.test.ts +3 -0
- package/tests/cases/unit/databaseContextRetry.test.ts +81 -0
- package/tests/cases/unit/idp/claimMappingEvaluator.test.ts +554 -0
- package/tests/cases/unit/idp/claimMappingValidation.test.ts +134 -0
- package/tests/cases/unit/idp/idpManagerConfigMerge.test.ts +97 -0
- package/tests/cases/unit/idp/idpManagerUnknownConfigKeys.test.ts +108 -0
- package/tests/cases/unit/idp/idpSessionRevalidator.test.ts +226 -24
- package/tests/cases/unit/idp/oidcClaims.test.ts +29 -0
- package/tests/cases/unit/idp/oidcResponse.test.ts +54 -0
- package/tests/cases/unit/idp/oidcRevalidate.test.ts +94 -2
- package/tests/cases/unit/panelAccessResolver.test.ts +57 -0
- package/tests/cases/unit/updateConfigurationCommand.test.ts +63 -0
- package/tests/src/IdPMock.ts +4 -0
- package/tests/src/testTenant.ts +32 -1
- package/dist/development/src/model/commands/membership/RemoveProjectMembershipsCommand.cjs.map +0 -1
- package/dist/development/src/model/commands/membership/RemoveProjectMembershipsCommand.js.map +0 -1
- package/dist/production/src/model/commands/membership/RemoveProjectMembershipsCommand.cjs.map +0 -1
- package/dist/production/src/model/commands/membership/RemoveProjectMembershipsCommand.js.map +0 -1
- package/dist/types/model/commands/membership/RemoveProjectMembershipsCommand.d.ts.map +0 -1
- /package/src/model/commands/membership/{RemoveProjectMembershipsCommand.ts → RemoveProjectMembershipCommand.ts} +0 -0
|
@@ -17,7 +17,9 @@ import { CreatePersonIdentityProviderIdentifierCommand } from "../commands/perso
|
|
|
17
17
|
import { CreateIdentityCommand } from "../commands/identity/CreateIdentityCommand.js";
|
|
18
18
|
import { CreateAuthLogEntryCommand } from "../commands/authLog/CreateAuthLogEntryCommand.js";
|
|
19
19
|
import "./idp/IDPRevalidation.js";
|
|
20
|
+
import { parseClaimMapping } from "./idp/ClaimMapping.js";
|
|
20
21
|
import { IDPValidationError } from "./idp/IDPValidationError.js";
|
|
22
|
+
import "@contember/schema-utils";
|
|
21
23
|
import { IDPResponseError } from "./idp/IDPResponseError.js";
|
|
22
24
|
import "./idp/providers/AppleProvider.js";
|
|
23
25
|
import "openid-client";
|
|
@@ -29,9 +31,10 @@ import { CreateIdpSessionCommand } from "../commands/idp/CreateIdpSessionCommand
|
|
|
29
31
|
import { NoPassword } from "../dtos/Password.js";
|
|
30
32
|
import { AuthLogService } from "./AuthLogService.js";
|
|
31
33
|
class IDPSignInManager {
|
|
32
|
-
constructor(apiKeyManager, idpRegistry) {
|
|
34
|
+
constructor(apiKeyManager, idpRegistry, claimSyncService) {
|
|
33
35
|
this.apiKeyManager = apiKeyManager;
|
|
34
36
|
this.idpRegistry = idpRegistry;
|
|
37
|
+
this.claimSyncService = claimSyncService;
|
|
35
38
|
}
|
|
36
39
|
async signInIDP(dbContext, idpSlug, responseData, expiration, requestInfo, trustForwardedInfo) {
|
|
37
40
|
return dbContext.transaction(async (db) => {
|
|
@@ -87,6 +90,27 @@ class IDPSignInManager {
|
|
|
87
90
|
})
|
|
88
91
|
});
|
|
89
92
|
}
|
|
93
|
+
let mapping = null;
|
|
94
|
+
let claimMappingFailed = false;
|
|
95
|
+
try {
|
|
96
|
+
mapping = parseClaimMapping(provider.configuration);
|
|
97
|
+
} catch {
|
|
98
|
+
claimMappingFailed = true;
|
|
99
|
+
}
|
|
100
|
+
let claimMappingAudit = null;
|
|
101
|
+
if (mapping) {
|
|
102
|
+
const syncResult = await this.claimSyncService.sync(
|
|
103
|
+
db,
|
|
104
|
+
mapping,
|
|
105
|
+
claim,
|
|
106
|
+
{ id: personRow.identity_id },
|
|
107
|
+
resolved.isNewPerson === true
|
|
108
|
+
);
|
|
109
|
+
claimMappingAudit = syncResult.audit;
|
|
110
|
+
if (syncResult.droppedUnsafeRules) {
|
|
111
|
+
claimMappingFailed = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
90
114
|
const { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(
|
|
91
115
|
db,
|
|
92
116
|
personRow.identity_id,
|
|
@@ -118,6 +142,9 @@ class IDPSignInManager {
|
|
|
118
142
|
person: personRow,
|
|
119
143
|
token: sessionToken,
|
|
120
144
|
idpResponse: claim,
|
|
145
|
+
claimMappingAudit,
|
|
146
|
+
claimMappingFailed,
|
|
147
|
+
identityProviderId: provider.id,
|
|
121
148
|
[AuthLogService.Key]: new AuthLogService.Bag({
|
|
122
149
|
personId: personRow.id,
|
|
123
150
|
identityProviderId: provider.id,
|
|
@@ -167,7 +194,7 @@ class IDPSignInManager {
|
|
|
167
194
|
if (provider.autoSignUp) {
|
|
168
195
|
const signedUpPerson = await this.signUp(db, claim, provider);
|
|
169
196
|
await this.saveIdpIdentifier(db, provider, claim, signedUpPerson);
|
|
170
|
-
return { person: signedUpPerson };
|
|
197
|
+
return { person: signedUpPerson, isNewPerson: true };
|
|
171
198
|
}
|
|
172
199
|
return { person: null };
|
|
173
200
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDPSignInManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/IDPSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { IdentityProviderBySlugQuery, PersonByIdPQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { IDPHandlerRegistry, IDPResponse, IDPResponseError, IDPValidationError } from './idp/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { InitSignInIdpErrorCode, InitSignInIdpResult, SignInIdpErrorCode } from '../../schema/index.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ApiKeyRequestInfo, CreateIdentityCommand, CreatePersonCommand, CreatePersonIdentityProviderIdentifierCommand } from '../commands/index.js'\nimport { CreateIdpSessionCommand } from '../commands/idp/CreateIdpSessionCommand.js'\nimport { CreateAuthLogEntryCommand } from '../commands/authLog/CreateAuthLogEntryCommand.js'\nimport { TenantRole } from '../authorization/index.js'\nimport { NoPassword } from '../dtos/index.js'\nimport { IdentityProviderRow } from '../queries/idp/types.js'\nimport { AuthLogService } from './AuthLogService.js'\n\nclass IDPSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly idpRegistry: IDPHandlerRegistry,\n\t) {}\n\n\tasync signInIDP(\n\t\tdbContext: DatabaseContext,\n\t\tidpSlug: string,\n\t\tresponseData: unknown,\n\t\texpiration?: number,\n\t\trequestInfo?: ApiKeyRequestInfo,\n\t\ttrustForwardedInfo?: boolean,\n\t): Promise<IDPSignInManager.SignInIDPResponse> {\n\t\treturn dbContext.transaction(async (db): Promise<IDPSignInManager.SignInIDPResponse> => {\n\t\t\tconst provider = await db.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\t\tif (!provider || provider.disabledAt) {\n\t\t\t\tthrow new Error('provider not found')\n\t\t\t}\n\t\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\t\tlet claim: IDPResponse\n\t\t\ttry {\n\t\t\t\tclaim = await providerService.processResponse(\n\t\t\t\t\tvalidatedConfig,\n\t\t\t\t\tresponseData,\n\t\t\t\t)\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof IDPResponseError) {\n\t\t\t\t\treturn new ResponseError('INVALID_IDP_RESPONSE', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow e\n\t\t\t}\n\t\t\tconst resolved = await this.resolvePerson(db, claim, provider)\n\t\t\tconst personRow = resolved.person\n\n\t\t\tif (!personRow) {\n\t\t\t\t// Keep the external error generic (no account-existence leak), but\n\t\t\t\t// record the email-verification gate block distinctly in the audit\n\t\t\t\t// log — it is a takeover-grade event, not an ordinary \"not found\".\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${claim.email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: resolved.blockedPersonId,\n\t\t\t\t\t\teventData: resolved.blockedReason ? { reason: resolved.blockedReason } : undefined,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person with e-mail ${claim.email} is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(\n\t\t\t\tdb,\n\t\t\t\tpersonRow.identity_id,\n\t\t\t\texpiration,\n\t\t\t\trequestInfo,\n\t\t\t\ttrustForwardedInfo,\n\t\t\t)\n\n\t\t\t// Bind the federated-session state to this session so it can be re-validated\n\t\t\t// against the IdP later. Present only when the provider supports it and\n\t\t\t// revalidation is enabled on the IdP configuration (A24). Refresh tokens must be\n\t\t\t// encrypted at rest, so when no encryption key is configured we skip persisting a\n\t\t\t// token-bearing session (it would otherwise crash or store secrets in plaintext) —\n\t\t\t// the session then behaves like a plain session with no re-validation.\n\t\t\tif (claim.idpSession) {\n\t\t\t\tconst hasTokens = !!claim.idpSession.tokens && Object.keys(claim.idpSession.tokens).length > 0\n\t\t\t\tif (!hasTokens || db.providers.encryptionEnabled) {\n\t\t\t\t\tawait db.commandBus.execute(new CreateIdpSessionCommand(apiKeyId, provider.id, claim.idpSession))\n\t\t\t\t} else {\n\t\t\t\t\t// Re-validation is enabled on this IdP but no encryption key is configured, so we\n\t\t\t\t\t// won't store the token-bearing session — it silently degrades to a plain,\n\t\t\t\t\t// non-revalidated session. Audit the downgrade (errorCode `encryption_disabled`)\n\t\t\t\t\t// so the operator can see that a session they expected to be continuously\n\t\t\t\t\t// re-validated is in fact not protected, instead of failing closed at sign-in.\n\t\t\t\t\tawait db.commandBus.execute(\n\t\t\t\t\t\tnew CreateAuthLogEntryCommand({\n\t\t\t\t\t\t\ttype: 'idp_session_revalidation_failed',\n\t\t\t\t\t\t\tinvokedById: personRow.identity_id,\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t\tpersonTokenId: apiKeyId,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\terrorCode: 'encryption_disabled',\n\t\t\t\t\t\t\tipAddress: requestInfo?.ip,\n\t\t\t\t\t\t\tuserAgent: requestInfo?.userAgent,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tidpResponse: claim,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initSignInIDP(dbContext: DatabaseContext, idpSlug: string, data: unknown): Promise<IDPSignInManager.InitSignInIDPResponse> {\n\t\tconst provider = await dbContext.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\tif (!provider || provider.disabledAt) {\n\t\t\treturn new ResponseError('PROVIDER_NOT_FOUND', `Identity provider ${idpSlug} not found`)\n\t\t}\n\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\ttry {\n\t\t\tconst initResponse = await providerService.initAuth(validatedConfig, data)\n\n\t\t\tconst publicConfig = providerService.getPublicConfiguration\n\t\t\t\t? providerService.getPublicConfiguration(validatedConfig)\n\t\t\t\t: validatedConfig\n\n\t\t\treturn new ResponseOk({\n\t\t\t\t...initResponse,\n\t\t\t\tidpConfiguration: provider.initReturnsConfig ? publicConfig : null,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message)\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tprivate async resolvePerson(db: DatabaseContext, claim: IDPResponse, provider: IdentityProviderRow): Promise<IDPSignInManager.ResolvePersonResult> {\n\t\tconst personByIdPQuery = new PersonByIdPQuery(provider.id, claim.externalIdentifier)\n\t\tconst personByIdp = await db.queryHandler.fetch(personByIdPQuery)\n\t\tif (personByIdp) {\n\t\t\treturn { person: personByIdp }\n\t\t}\n\n\t\tif (!provider.exclusive) {\n\t\t\tconst personByEmail = typeof claim.email === 'string' && claim.email\n\t\t\t\t? await db.queryHandler.fetch(PersonQuery.byEmail(claim.email))\n\t\t\t\t: null\n\t\t\tif (personByEmail) {\n\t\t\t\t// Auto-linking an IdP identity to a pre-existing local account by\n\t\t\t\t// e-mail is takeover-grade: if the provider returns an unverified\n\t\t\t\t// (or attacker-controlled) e-mail, it could hijack the account. When\n\t\t\t\t// the provider requires a verified e-mail, refuse to link — and to\n\t\t\t\t// sign in — unless the address is asserted verified. `assumeEmailVerified`\n\t\t\t\t// lets a trusted IdP that never emits the claim still satisfy the gate.\n\t\t\t\tconst emailVerified = provider.assumeEmailVerified || claim.emailVerified === true\n\t\t\t\tif (provider.requireVerifiedEmail && !emailVerified) {\n\t\t\t\t\treturn { person: null, blockedReason: 'idp_email_unverified', blockedPersonId: personByEmail.id }\n\t\t\t\t}\n\t\t\t\tawait this.saveIdpIdentifier(db, provider, claim, personByEmail)\n\t\t\t\treturn { person: personByEmail }\n\t\t\t}\n\t\t}\n\n\t\tif (provider.autoSignUp) {\n\t\t\tconst signedUpPerson = await this.signUp(db, claim, provider)\n\t\t\tawait this.saveIdpIdentifier(db, provider, claim, signedUpPerson)\n\t\t\treturn { person: signedUpPerson }\n\t\t}\n\n\t\treturn { person: null }\n\t}\n\n\tprivate async signUp(db: DatabaseContext, { email, name, externalIdentifier }: IDPResponse, provider: IdentityProviderRow): Promise<PersonRow> {\n\t\tconst roles = [TenantRole.PERSON]\n\t\tconst identityId = await db.commandBus.execute(new CreateIdentityCommand(roles))\n\t\tconst newPerson = await db.commandBus.execute(\n\t\t\tnew CreatePersonCommand({\n\t\t\t\tidentityId,\n\t\t\t\temail: provider.exclusive ? undefined : email,\n\t\t\t\tpassword: NoPassword,\n\t\t\t\tname: name ?? email?.split('@')[0] ?? externalIdentifier,\n\t\t\t\tidpOnly: provider.exclusive,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\t...newPerson,\n\t\t\troles,\n\t\t}\n\t}\n\n\tprivate async saveIdpIdentifier(db: DatabaseContext, provider: IdentityProviderRow, claim: IDPResponse, person: PersonRow) {\n\t\tawait db.commandBus.execute(new CreatePersonIdentityProviderIdentifierCommand(provider.id, person.id, claim.externalIdentifier))\n\t}\n}\n\nnamespace IDPSignInManager {\n\texport type ResolvePersonResult = {\n\t\treadonly person: PersonRow | null\n\t\treadonly blockedReason?: 'idp_email_unverified'\n\t\treadonly blockedPersonId?: string\n\t}\n\n\texport type InitSignInIDPResponse = Response<InitSignInIdpResult, InitSignInIdpErrorCode>\n\n\tinterface SignInIDPResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\treadonly idpResponse?: Record<string, unknown>\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\n\texport type SignInIDPResponse = Response<SignInIDPResult, SignInIdpErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n}\n\nexport { IDPSignInManager }\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IDPSignInManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/IDPSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { IdentityProviderBySlugQuery, PersonByIdPQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { IDPHandlerRegistry, IDPResponse, IDPResponseError, IDPValidationError } from './idp/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { InitSignInIdpErrorCode, InitSignInIdpResult, SignInIdpErrorCode } from '../../schema/index.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ApiKeyRequestInfo, CreateIdentityCommand, CreatePersonCommand, CreatePersonIdentityProviderIdentifierCommand } from '../commands/index.js'\nimport { CreateIdpSessionCommand } from '../commands/idp/CreateIdpSessionCommand.js'\nimport { CreateAuthLogEntryCommand } from '../commands/authLog/CreateAuthLogEntryCommand.js'\nimport { TenantRole } from '../authorization/index.js'\nimport { NoPassword } from '../dtos/index.js'\nimport { IdentityProviderRow } from '../queries/idp/types.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { ClaimMappingAudit, IDPClaimSyncService } from './idp/IDPClaimSyncService.js'\nimport { ClaimMapping, parseClaimMapping } from './idp/ClaimMapping.js'\n\nclass IDPSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly idpRegistry: IDPHandlerRegistry,\n\t\tprivate readonly claimSyncService: IDPClaimSyncService,\n\t) {}\n\n\tasync signInIDP(\n\t\tdbContext: DatabaseContext,\n\t\tidpSlug: string,\n\t\tresponseData: unknown,\n\t\texpiration?: number,\n\t\trequestInfo?: ApiKeyRequestInfo,\n\t\ttrustForwardedInfo?: boolean,\n\t): Promise<IDPSignInManager.SignInIDPResponse> {\n\t\treturn dbContext.transaction(async (db): Promise<IDPSignInManager.SignInIDPResponse> => {\n\t\t\tconst provider = await db.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\t\tif (!provider || provider.disabledAt) {\n\t\t\t\tthrow new Error('provider not found')\n\t\t\t}\n\t\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\t\tlet claim: IDPResponse\n\t\t\ttry {\n\t\t\t\tclaim = await providerService.processResponse(\n\t\t\t\t\tvalidatedConfig,\n\t\t\t\t\tresponseData,\n\t\t\t\t)\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof IDPResponseError) {\n\t\t\t\t\treturn new ResponseError('INVALID_IDP_RESPONSE', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow e\n\t\t\t}\n\t\t\tconst resolved = await this.resolvePerson(db, claim, provider)\n\t\t\tconst personRow = resolved.person\n\n\t\t\tif (!personRow) {\n\t\t\t\t// Keep the external error generic (no account-existence leak), but\n\t\t\t\t// record the email-verification gate block distinctly in the audit\n\t\t\t\t// log — it is a takeover-grade event, not an ordinary \"not found\".\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${claim.email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: resolved.blockedPersonId,\n\t\t\t\t\t\teventData: resolved.blockedReason ? { reason: resolved.blockedReason } : undefined,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person with e-mail ${claim.email} is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// A09 — map IdP claims to project memberships. Returns a `{ before, after }` delta only\n\t\t\t// when something actually changed; the resolver emits the `idp_role_mapped` audit from it\n\t\t\t// (audit stays at the resolver layer).\n\t\t\t//\n\t\t\t// Fail-open on a MALFORMED/out-of-band `claimMapping`: parsing is caught so a bad config can\n\t\t\t// never lock the user out — sign-in proceeds without claim mapping and the resolver emits an\n\t\t\t// `idp_role_mapping_failed` marker. A DB error during the apply itself is NOT caught: it\n\t\t\t// propagates and rolls back the whole sign-in transaction, so a half-applied set of grants is\n\t\t\t// never committed (failing sign-in on an infra error is the safe outcome).\n\t\t\tlet mapping: ClaimMapping | null = null\n\t\t\tlet claimMappingFailed = false\n\t\t\ttry {\n\t\t\t\tmapping = parseClaimMapping(provider.configuration)\n\t\t\t} catch {\n\t\t\t\tclaimMappingFailed = true\n\t\t\t}\n\t\t\tlet claimMappingAudit: ClaimMappingAudit | null = null\n\t\t\tif (mapping) {\n\t\t\t\tconst syncResult = await this.claimSyncService.sync(\n\t\t\t\t\tdb,\n\t\t\t\t\tmapping,\n\t\t\t\t\tclaim,\n\t\t\t\t\t{ id: personRow.identity_id },\n\t\t\t\t\tresolved.isNewPerson === true,\n\t\t\t\t)\n\t\t\t\tclaimMappingAudit = syncResult.audit\n\t\t\t\t// The apply-time safety backstop dropped a configured rule (config-time validation was skipped, or\n\t\t\t\t// the project's ACL drifted since): surface the same fail-open marker as a malformed config, so a\n\t\t\t\t// silently-unapplied grant is visible to the operator. The resolver emits `idp_role_mapping_failed`.\n\t\t\t\tif (syncResult.droppedUnsafeRules) {\n\t\t\t\t\tclaimMappingFailed = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(\n\t\t\t\tdb,\n\t\t\t\tpersonRow.identity_id,\n\t\t\t\texpiration,\n\t\t\t\trequestInfo,\n\t\t\t\ttrustForwardedInfo,\n\t\t\t)\n\n\t\t\t// Bind the federated-session state to this session so it can be re-validated\n\t\t\t// against the IdP later. Present only when the provider supports it and\n\t\t\t// revalidation is enabled on the IdP configuration (A24). Refresh tokens must be\n\t\t\t// encrypted at rest, so when no encryption key is configured we skip persisting a\n\t\t\t// token-bearing session (it would otherwise crash or store secrets in plaintext) —\n\t\t\t// the session then behaves like a plain session with no re-validation.\n\t\t\tif (claim.idpSession) {\n\t\t\t\tconst hasTokens = !!claim.idpSession.tokens && Object.keys(claim.idpSession.tokens).length > 0\n\t\t\t\tif (!hasTokens || db.providers.encryptionEnabled) {\n\t\t\t\t\tawait db.commandBus.execute(new CreateIdpSessionCommand(apiKeyId, provider.id, claim.idpSession))\n\t\t\t\t} else {\n\t\t\t\t\t// Re-validation is enabled on this IdP but no encryption key is configured, so we\n\t\t\t\t\t// won't store the token-bearing session — it silently degrades to a plain,\n\t\t\t\t\t// non-revalidated session. Audit the downgrade (errorCode `encryption_disabled`)\n\t\t\t\t\t// so the operator can see that a session they expected to be continuously\n\t\t\t\t\t// re-validated is in fact not protected, instead of failing closed at sign-in.\n\t\t\t\t\tawait db.commandBus.execute(\n\t\t\t\t\t\tnew CreateAuthLogEntryCommand({\n\t\t\t\t\t\t\ttype: 'idp_session_revalidation_failed',\n\t\t\t\t\t\t\tinvokedById: personRow.identity_id,\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t\tpersonTokenId: apiKeyId,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\terrorCode: 'encryption_disabled',\n\t\t\t\t\t\t\tipAddress: requestInfo?.ip,\n\t\t\t\t\t\t\tuserAgent: requestInfo?.userAgent,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tidpResponse: claim,\n\t\t\t\tclaimMappingAudit,\n\t\t\t\tclaimMappingFailed,\n\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initSignInIDP(dbContext: DatabaseContext, idpSlug: string, data: unknown): Promise<IDPSignInManager.InitSignInIDPResponse> {\n\t\tconst provider = await dbContext.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\tif (!provider || provider.disabledAt) {\n\t\t\treturn new ResponseError('PROVIDER_NOT_FOUND', `Identity provider ${idpSlug} not found`)\n\t\t}\n\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\ttry {\n\t\t\tconst initResponse = await providerService.initAuth(validatedConfig, data)\n\n\t\t\tconst publicConfig = providerService.getPublicConfiguration\n\t\t\t\t? providerService.getPublicConfiguration(validatedConfig)\n\t\t\t\t: validatedConfig\n\n\t\t\treturn new ResponseOk({\n\t\t\t\t...initResponse,\n\t\t\t\tidpConfiguration: provider.initReturnsConfig ? publicConfig : null,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message)\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tprivate async resolvePerson(db: DatabaseContext, claim: IDPResponse, provider: IdentityProviderRow): Promise<IDPSignInManager.ResolvePersonResult> {\n\t\tconst personByIdPQuery = new PersonByIdPQuery(provider.id, claim.externalIdentifier)\n\t\tconst personByIdp = await db.queryHandler.fetch(personByIdPQuery)\n\t\tif (personByIdp) {\n\t\t\treturn { person: personByIdp }\n\t\t}\n\n\t\tif (!provider.exclusive) {\n\t\t\tconst personByEmail = typeof claim.email === 'string' && claim.email\n\t\t\t\t? await db.queryHandler.fetch(PersonQuery.byEmail(claim.email))\n\t\t\t\t: null\n\t\t\tif (personByEmail) {\n\t\t\t\t// Auto-linking an IdP identity to a pre-existing local account by\n\t\t\t\t// e-mail is takeover-grade: if the provider returns an unverified\n\t\t\t\t// (or attacker-controlled) e-mail, it could hijack the account. When\n\t\t\t\t// the provider requires a verified e-mail, refuse to link — and to\n\t\t\t\t// sign in — unless the address is asserted verified. `assumeEmailVerified`\n\t\t\t\t// lets a trusted IdP that never emits the claim still satisfy the gate.\n\t\t\t\tconst emailVerified = provider.assumeEmailVerified || claim.emailVerified === true\n\t\t\t\tif (provider.requireVerifiedEmail && !emailVerified) {\n\t\t\t\t\treturn { person: null, blockedReason: 'idp_email_unverified', blockedPersonId: personByEmail.id }\n\t\t\t\t}\n\t\t\t\tawait this.saveIdpIdentifier(db, provider, claim, personByEmail)\n\t\t\t\treturn { person: personByEmail }\n\t\t\t}\n\t\t}\n\n\t\tif (provider.autoSignUp) {\n\t\t\tconst signedUpPerson = await this.signUp(db, claim, provider)\n\t\t\tawait this.saveIdpIdentifier(db, provider, claim, signedUpPerson)\n\t\t\treturn { person: signedUpPerson, isNewPerson: true }\n\t\t}\n\n\t\treturn { person: null }\n\t}\n\n\tprivate async signUp(db: DatabaseContext, { email, name, externalIdentifier }: IDPResponse, provider: IdentityProviderRow): Promise<PersonRow> {\n\t\tconst roles = [TenantRole.PERSON]\n\t\tconst identityId = await db.commandBus.execute(new CreateIdentityCommand(roles))\n\t\tconst newPerson = await db.commandBus.execute(\n\t\t\tnew CreatePersonCommand({\n\t\t\t\tidentityId,\n\t\t\t\temail: provider.exclusive ? undefined : email,\n\t\t\t\tpassword: NoPassword,\n\t\t\t\tname: name ?? email?.split('@')[0] ?? externalIdentifier,\n\t\t\t\tidpOnly: provider.exclusive,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\t...newPerson,\n\t\t\troles,\n\t\t}\n\t}\n\n\tprivate async saveIdpIdentifier(db: DatabaseContext, provider: IdentityProviderRow, claim: IDPResponse, person: PersonRow) {\n\t\tawait db.commandBus.execute(new CreatePersonIdentityProviderIdentifierCommand(provider.id, person.id, claim.externalIdentifier))\n\t}\n}\n\nnamespace IDPSignInManager {\n\texport type ResolvePersonResult = {\n\t\treadonly person: PersonRow | null\n\t\treadonly blockedReason?: 'idp_email_unverified'\n\t\treadonly blockedPersonId?: string\n\t\t/** True when the person row was just created by auto-sign-up (drives the `sticky` claim-mapping policy). */\n\t\treadonly isNewPerson?: boolean\n\t}\n\n\texport type InitSignInIDPResponse = Response<InitSignInIdpResult, InitSignInIdpErrorCode>\n\n\tinterface SignInIDPResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\treadonly idpResponse?: Record<string, unknown>\n\t\t/** Identity provider the sign-in went through (for the resolver's audit). */\n\t\treadonly identityProviderId?: string\n\t\t/** Claim-mapping (A09) before/after delta — present only when a mapping changed grants. */\n\t\treadonly claimMappingAudit?: ClaimMappingAudit | null\n\t\t/** True when claim mapping failed and was skipped (fail-open) — drives the `idp_role_mapping_failed` audit. */\n\t\treadonly claimMappingFailed?: boolean\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\n\texport type SignInIDPResponse = Response<SignInIDPResult, SignInIdpErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n}\n\nexport { IDPSignInManager }\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
require("../queries/apiKey/ApiKeyQuery.cjs");
|
|
4
|
+
require("@contember/database");
|
|
5
|
+
require("../type/ApiKey.cjs");
|
|
6
|
+
const ConfigurationQuery = require("../queries/configuration/ConfigurationQuery.cjs");
|
|
7
|
+
const AllProjectRolesByIdentityQuery = require("../queries/membership/AllProjectRolesByIdentityQuery.cjs");
|
|
8
|
+
require("../authorization/PermissionActions.cjs");
|
|
9
|
+
require("@contember/authorization");
|
|
10
|
+
require("../authorization/PermissionContext.cjs");
|
|
11
|
+
require("../authorization/PermissionsFactory.cjs");
|
|
12
|
+
require("@contember/schema");
|
|
13
|
+
class PanelAccessResolver {
|
|
14
|
+
constructor(providers) {
|
|
15
|
+
this.providers = providers;
|
|
16
|
+
}
|
|
17
|
+
async isAllowed(db, identityId, globalRoles) {
|
|
18
|
+
const config = await db.queryHandler.fetch(new ConfigurationQuery.ConfigurationQuery(this.providers));
|
|
19
|
+
const policy = config.panel;
|
|
20
|
+
if (policy.globalRoles.some((role) => globalRoles.includes(role))) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (policy.projectRoles.length === 0) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery.AllProjectRolesByIdentityQuery(identityId));
|
|
27
|
+
return projectRoles.some((it) => policy.projectRoles.includes(it.role));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.PanelAccessResolver = PanelAccessResolver;
|
|
31
|
+
//# sourceMappingURL=PanelAccessResolver.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanelAccessResolver.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PanelAccessResolver.ts"],"sourcesContent":["import { DatabaseContext } from '../utils/index.js'\nimport { AllProjectRolesByIdentityQuery, ConfigurationQuery } from '../queries/index.js'\nimport { Providers } from '../providers.js'\n\n/**\n * Decides whether an identity may enter the management panel served by the engine.\n *\n * This is an **entry gate for the console, not an authorization system**: everything the panel shows\n * still goes through the tenant ACL, and whoever gets in could equally call `/tenant` directly. Its\n * job is to keep the console door shut for accounts that have no business there, so an admin surface\n * on a public API port does not look like a leak.\n *\n * An identity is allowed when it holds one of `globalRoles`, or a membership with one of\n * `projectRoles` in **any** project. Empty lists mean nobody.\n */\nexport class PanelAccessResolver {\n\tconstructor(private readonly providers: Providers) {}\n\n\tasync isAllowed(db: DatabaseContext, identityId: string, globalRoles: readonly string[]): Promise<boolean> {\n\t\tconst config = await db.queryHandler.fetch(new ConfigurationQuery(this.providers))\n\t\tconst policy = config.panel\n\n\t\tif (policy.globalRoles.some(role => globalRoles.includes(role))) {\n\t\t\treturn true\n\t\t}\n\t\tif (policy.projectRoles.length === 0) {\n\t\t\treturn false\n\t\t}\n\t\tconst projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery(identityId))\n\t\treturn projectRoles.some(it => policy.projectRoles.includes(it.role))\n\t}\n}\n"],"names":["ConfigurationQuery","AllProjectRolesByIdentityQuery"],"mappings":";;;;;;;;;;;;AAeO,MAAM,oBAAoB;AAAA,EAChC,YAA6B,WAAsB;AAAtB,SAAA,YAAA;AAAA,EAAuB;AAAA,EAEpD,MAAM,UAAU,IAAqB,YAAoB,aAAkD;AAC1G,UAAM,SAAS,MAAM,GAAG,aAAa,MAAM,IAAIA,mBAAAA,mBAAmB,KAAK,SAAS,CAAC;AACjF,UAAM,SAAS,OAAO;AAEtB,QAAI,OAAO,YAAY,KAAK,CAAA,SAAQ,YAAY,SAAS,IAAI,CAAC,GAAG;AAChE,aAAO;AAAA,IACR;AACA,QAAI,OAAO,aAAa,WAAW,GAAG;AACrC,aAAO;AAAA,IACR;AACA,UAAM,eAAe,MAAM,GAAG,aAAa,MAAM,IAAIC,+BAAAA,+BAA+B,UAAU,CAAC;AAC/F,WAAO,aAAa,KAAK,CAAA,OAAM,OAAO,aAAa,SAAS,GAAG,IAAI,CAAC;AAAA,EACrE;AACD;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import "../queries/apiKey/ApiKeyQuery.js";
|
|
2
|
+
import "@contember/database";
|
|
3
|
+
import "../type/ApiKey.js";
|
|
4
|
+
import { ConfigurationQuery } from "../queries/configuration/ConfigurationQuery.js";
|
|
5
|
+
import { AllProjectRolesByIdentityQuery } from "../queries/membership/AllProjectRolesByIdentityQuery.js";
|
|
6
|
+
import "../authorization/PermissionActions.js";
|
|
7
|
+
import "@contember/authorization";
|
|
8
|
+
import "../authorization/PermissionContext.js";
|
|
9
|
+
import "../authorization/PermissionsFactory.js";
|
|
10
|
+
import "@contember/schema";
|
|
11
|
+
class PanelAccessResolver {
|
|
12
|
+
constructor(providers) {
|
|
13
|
+
this.providers = providers;
|
|
14
|
+
}
|
|
15
|
+
async isAllowed(db, identityId, globalRoles) {
|
|
16
|
+
const config = await db.queryHandler.fetch(new ConfigurationQuery(this.providers));
|
|
17
|
+
const policy = config.panel;
|
|
18
|
+
if (policy.globalRoles.some((role) => globalRoles.includes(role))) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (policy.projectRoles.length === 0) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery(identityId));
|
|
25
|
+
return projectRoles.some((it) => policy.projectRoles.includes(it.role));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
PanelAccessResolver
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=PanelAccessResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanelAccessResolver.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PanelAccessResolver.ts"],"sourcesContent":["import { DatabaseContext } from '../utils/index.js'\nimport { AllProjectRolesByIdentityQuery, ConfigurationQuery } from '../queries/index.js'\nimport { Providers } from '../providers.js'\n\n/**\n * Decides whether an identity may enter the management panel served by the engine.\n *\n * This is an **entry gate for the console, not an authorization system**: everything the panel shows\n * still goes through the tenant ACL, and whoever gets in could equally call `/tenant` directly. Its\n * job is to keep the console door shut for accounts that have no business there, so an admin surface\n * on a public API port does not look like a leak.\n *\n * An identity is allowed when it holds one of `globalRoles`, or a membership with one of\n * `projectRoles` in **any** project. Empty lists mean nobody.\n */\nexport class PanelAccessResolver {\n\tconstructor(private readonly providers: Providers) {}\n\n\tasync isAllowed(db: DatabaseContext, identityId: string, globalRoles: readonly string[]): Promise<boolean> {\n\t\tconst config = await db.queryHandler.fetch(new ConfigurationQuery(this.providers))\n\t\tconst policy = config.panel\n\n\t\tif (policy.globalRoles.some(role => globalRoles.includes(role))) {\n\t\t\treturn true\n\t\t}\n\t\tif (policy.projectRoles.length === 0) {\n\t\t\treturn false\n\t\t}\n\t\tconst projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery(identityId))\n\t\treturn projectRoles.some(it => policy.projectRoles.includes(it.role))\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;;;AAeO,MAAM,oBAAoB;AAAA,EAChC,YAA6B,WAAsB;AAAtB,SAAA,YAAA;AAAA,EAAuB;AAAA,EAEpD,MAAM,UAAU,IAAqB,YAAoB,aAAkD;AAC1G,UAAM,SAAS,MAAM,GAAG,aAAa,MAAM,IAAI,mBAAmB,KAAK,SAAS,CAAC;AACjF,UAAM,SAAS,OAAO;AAEtB,QAAI,OAAO,YAAY,KAAK,CAAA,SAAQ,YAAY,SAAS,IAAI,CAAC,GAAG;AAChE,aAAO;AAAA,IACR;AACA,QAAI,OAAO,aAAa,WAAW,GAAG;AACrC,aAAO;AAAA,IACR;AACA,UAAM,eAAe,MAAM,GAAG,aAAa,MAAM,IAAI,+BAA+B,UAAU,CAAC;AAC/F,WAAO,aAAa,KAAK,CAAA,OAAM,OAAO,aAAa,SAAS,GAAG,IAAI,CAAC;AAAA,EACrE;AACD;"}
|
|
@@ -6,6 +6,7 @@ require("@contember/database");
|
|
|
6
6
|
require("../type/ApiKey.cjs");
|
|
7
7
|
const ConfigurationQuery = require("../queries/configuration/ConfigurationQuery.cjs");
|
|
8
8
|
const exceptions = require("../../exceptions.cjs");
|
|
9
|
+
const LocalAuthDisablingIdpsQuery = require("../queries/idp/LocalAuthDisablingIdpsQuery.cjs");
|
|
9
10
|
require("../authorization/PermissionActions.cjs");
|
|
10
11
|
require("@contember/authorization");
|
|
11
12
|
require("../authorization/PermissionContext.cjs");
|
|
@@ -28,6 +29,10 @@ class PasswordResetManager {
|
|
|
28
29
|
if (!person.email) {
|
|
29
30
|
throw new exceptions.ImplementationException();
|
|
30
31
|
}
|
|
32
|
+
const exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery.LocalAuthDisablingIdpsQuery(person.id));
|
|
33
|
+
if (exclusiveIdps.length > 0) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
31
36
|
const nextAllowed = await dbContext.queryHandler.fetch(
|
|
32
37
|
new NextMailAttemptQuery.NextMailAttemptQuery(person.email, "password_reset_init", "password_reset")
|
|
33
38
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\n\t) {}\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\n\t\tconst result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = getPreferredProject(projects, mailOptions.project ?? null)\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":["ImplementationException","NextMailAttemptQuery","CreatePersonTokenCommand","getPreferredProject","ConfigurationQuery","PersonTokenQuery","ResponseError","AuthLogService","ResetPasswordCommand","ResponseOk"],"mappings":"
|
|
1
|
+
{"version":3,"file":"PasswordResetManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, LocalAuthDisablingIdpsQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\n\t) {}\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// A person federated through a provider with `disableLocalAuthentication`\n\t\t// cannot sign in with a password, so a reset mail would only offer them a\n\t\t// credential the tenant refuses — and one more link worth phishing.\n\t\tconst exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id))\n\t\tif (exclusiveIdps.length > 0) {\n\t\t\treturn\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\n\t\tconst result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = getPreferredProject(projects, mailOptions.project ?? null)\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":["ImplementationException","LocalAuthDisablingIdpsQuery","NextMailAttemptQuery","CreatePersonTokenCommand","getPreferredProject","ConfigurationQuery","PersonTokenQuery","ResponseError","AuthLogService","ResetPasswordCommand","ResponseOk"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBACA,2BAChB;AAHgB,SAAA,SAAA;AACA,SAAA,iBAAA;AACA,SAAA,4BAAA;AAAA,EACf;AAAA,EAEH,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AAChB,QAAI,CAAC,OAAO,OAAO;AAClB,YAAM,IAAIA,WAAAA,wBAAA;AAAA,IACX;AAKA,UAAM,gBAAgB,MAAM,UAAU,aAAa,MAAM,IAAIC,4BAAAA,4BAA4B,OAAO,EAAE,CAAC;AACnG,QAAI,cAAc,SAAS,GAAG;AAC7B;AAAA,IACD;AAKA,UAAM,cAAc,MAAM,UAAU,aAAa;AAAA,MAChD,IAAIC,0CAAqB,OAAO,OAAO,uBAAuB,gBAAgB;AAAA,IAAA;AAE/E,QAAI,cAAc,oBAAI,QAAQ;AAC7B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,QAAQC,yBAAAA,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAChH,UAAM,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAUC,oBAAAA,oBAAoB,UAAU,YAAY,WAAW,IAAI;AAEzE,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MAAA;AAAA,MAEvB;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAAA;AAAA,IAC3B;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACvH,UAAM,SAAS,MAAM,UAAU,aAAa,MAAM,IAAIC,mBAAAA,mBAAmB,UAAU,SAAS,CAAC;AAC7F,UAAM,WAAW,MAAM,UAAU,aAAa,MAAMC,iBAAAA,iBAAiB,QAAQ,OAAO,gBAAgB,CAAC;AACrG,QAAI,CAAC,UAAU;AACd,aAAO,IAAIC,SAAAA,cAAc,mBAAmB,mBAAmB;AAAA,QAC9D,CAACC,eAAAA,eAAe,GAAG,GAAG,IAAIA,eAAAA,eAAe,IAAI,CAAA,CAAE;AAAA,MAAA,CAC/C;AAAA,IACF;AAEA,UAAM,cAAc,IAAIA,eAAAA,eAAe,IAAI;AAAA,MAC1C,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IAAA,CAClB;AACD,UAAM,eAAe,MAAM,KAAK,0BAA0B,OAAO,UAAU,OAAO,UAAU,mBAAmB;AAC/G,QAAI,CAAC,aAAa,IAAI;AACrB,aAAO,IAAID,SAAAA,cAAc,aAAa,OAAO,aAAa,cAAc;AAAA,QACvE,GAAG,aAAa,YAAY,CAAA;AAAA,QAC5B,CAACC,eAAAA,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,UAAU,WAAW,QAAQ,IAAIC,qBAAAA,qBAAqB,OAAO,QAAQ,CAAC;AACxG,QAAI,CAAC,oBAAoB,IAAI;AAC5B,aAAO,IAAIF,SAAAA,cAAc,oBAAoB,OAAO,oBAAoB,cAAc;AAAA,QACrF,GAAG,oBAAoB,YAAY,CAAA;AAAA,QACnC,CAACC,eAAAA,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,WAAO,IAAIE,SAAAA,WAAW;AAAA,MACrB,CAACF,eAAAA,eAAe,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACF;AACD;;"}
|
|
@@ -4,6 +4,7 @@ import "@contember/database";
|
|
|
4
4
|
import "../type/ApiKey.js";
|
|
5
5
|
import { ConfigurationQuery } from "../queries/configuration/ConfigurationQuery.js";
|
|
6
6
|
import { ImplementationException } from "../../exceptions.js";
|
|
7
|
+
import { LocalAuthDisablingIdpsQuery } from "../queries/idp/LocalAuthDisablingIdpsQuery.js";
|
|
7
8
|
import "../authorization/PermissionActions.js";
|
|
8
9
|
import "@contember/authorization";
|
|
9
10
|
import "../authorization/PermissionContext.js";
|
|
@@ -26,6 +27,10 @@ class PasswordResetManager {
|
|
|
26
27
|
if (!person.email) {
|
|
27
28
|
throw new ImplementationException();
|
|
28
29
|
}
|
|
30
|
+
const exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id));
|
|
31
|
+
if (exclusiveIdps.length > 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
29
34
|
const nextAllowed = await dbContext.queryHandler.fetch(
|
|
30
35
|
new NextMailAttemptQuery(person.email, "password_reset_init", "password_reset")
|
|
31
36
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\n\t) {}\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\n\t\tconst result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = getPreferredProject(projects, mailOptions.project ?? null)\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PasswordResetManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, LocalAuthDisablingIdpsQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\n\t) {}\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// A person federated through a provider with `disableLocalAuthentication`\n\t\t// cannot sign in with a password, so a reset mail would only offer them a\n\t\t// credential the tenant refuses — and one more link worth phishing.\n\t\tconst exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id))\n\t\tif (exclusiveIdps.length > 0) {\n\t\t\treturn\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\n\t\tconst result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = getPreferredProject(projects, mailOptions.project ?? null)\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAoBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBACA,2BAChB;AAHgB,SAAA,SAAA;AACA,SAAA,iBAAA;AACA,SAAA,4BAAA;AAAA,EACf;AAAA,EAEH,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AAChB,QAAI,CAAC,OAAO,OAAO;AAClB,YAAM,IAAI,wBAAA;AAAA,IACX;AAKA,UAAM,gBAAgB,MAAM,UAAU,aAAa,MAAM,IAAI,4BAA4B,OAAO,EAAE,CAAC;AACnG,QAAI,cAAc,SAAS,GAAG;AAC7B;AAAA,IACD;AAKA,UAAM,cAAc,MAAM,UAAU,aAAa;AAAA,MAChD,IAAI,qBAAqB,OAAO,OAAO,uBAAuB,gBAAgB;AAAA,IAAA;AAE/E,QAAI,cAAc,oBAAI,QAAQ;AAC7B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,QAAQ,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAChH,UAAM,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAU,oBAAoB,UAAU,YAAY,WAAW,IAAI;AAEzE,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MAAA;AAAA,MAEvB;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAAA;AAAA,IAC3B;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACvH,UAAM,SAAS,MAAM,UAAU,aAAa,MAAM,IAAI,mBAAmB,UAAU,SAAS,CAAC;AAC7F,UAAM,WAAW,MAAM,UAAU,aAAa,MAAM,iBAAiB,QAAQ,OAAO,gBAAgB,CAAC;AACrG,QAAI,CAAC,UAAU;AACd,aAAO,IAAI,cAAc,mBAAmB,mBAAmB;AAAA,QAC9D,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI,CAAA,CAAE;AAAA,MAAA,CAC/C;AAAA,IACF;AAEA,UAAM,cAAc,IAAI,eAAe,IAAI;AAAA,MAC1C,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IAAA,CAClB;AACD,UAAM,eAAe,MAAM,KAAK,0BAA0B,OAAO,UAAU,OAAO,UAAU,mBAAmB;AAC/G,QAAI,CAAC,aAAa,IAAI;AACrB,aAAO,IAAI,cAAc,aAAa,OAAO,aAAa,cAAc;AAAA,QACvE,GAAG,aAAa,YAAY,CAAA;AAAA,QAC5B,CAAC,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,QAAQ,CAAC;AACxG,QAAI,CAAC,oBAAoB,IAAI;AAC5B,aAAO,IAAI,cAAc,oBAAoB,OAAO,oBAAoB,cAAc;AAAA,QACrF,GAAG,oBAAoB,YAAY,CAAA;AAAA,QACnC,CAAC,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,WAAO,IAAI,WAAW;AAAA,MACrB,CAAC,eAAe,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACF;AACD;"}
|
|
@@ -6,6 +6,7 @@ require("../type/ApiKey.cjs");
|
|
|
6
6
|
const ConfigurationQuery = require("../queries/configuration/ConfigurationQuery.cjs");
|
|
7
7
|
const exceptions = require("../../exceptions.cjs");
|
|
8
8
|
const PersonQuery = require("../queries/person/PersonQuery.cjs");
|
|
9
|
+
const LocalAuthDisablingIdpsQuery = require("../queries/idp/LocalAuthDisablingIdpsQuery.cjs");
|
|
9
10
|
require("../authorization/PermissionActions.cjs");
|
|
10
11
|
require("@contember/authorization");
|
|
11
12
|
require("../authorization/PermissionContext.cjs");
|
|
@@ -48,6 +49,15 @@ class PasswordlessSignInManager {
|
|
|
48
49
|
})
|
|
49
50
|
});
|
|
50
51
|
}
|
|
52
|
+
const exclusiveIdps = await db2.queryHandler.fetch(new LocalAuthDisablingIdpsQuery.LocalAuthDisablingIdpsQuery(person.id));
|
|
53
|
+
if (exclusiveIdps.length > 0) {
|
|
54
|
+
return new Response.ResponseError("IDP_REQUIRED", `Sign in using ${exclusiveIdps.join(" or ")}`, {
|
|
55
|
+
[AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
|
|
56
|
+
personInput: email,
|
|
57
|
+
personId: person.id
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
}
|
|
51
61
|
if (!isPasswordlessEnabled.isPasswordlessEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {
|
|
52
62
|
return new Response.ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled for this person", {
|
|
53
63
|
[AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
|
|
@@ -149,6 +159,15 @@ class PasswordlessSignInManager {
|
|
|
149
159
|
})
|
|
150
160
|
});
|
|
151
161
|
}
|
|
162
|
+
const exclusiveIdps = await db2.queryHandler.fetch(new LocalAuthDisablingIdpsQuery.LocalAuthDisablingIdpsQuery(personRow.id));
|
|
163
|
+
if (exclusiveIdps.length > 0) {
|
|
164
|
+
return new Response.ResponseError("IDP_REQUIRED", `Sign in using ${exclusiveIdps.join(" or ")}`, {
|
|
165
|
+
[AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
|
|
166
|
+
personId: personRow.id,
|
|
167
|
+
tokenId: tokenResult?.id
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
}
|
|
152
171
|
let usedBackupCode = false;
|
|
153
172
|
if (personRow.otp_secret && personRow.otp_activated_at) {
|
|
154
173
|
if (mfaOtp) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordlessSignInManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordlessSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { ConfigurationQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport {\n\tActivatePasswordlessOtpErrorCode,\n\tInitSignInPasswordlessErrorCode,\n\tInitSignInPasswordlessResult,\n\tSignInPasswordlessErrorCode,\n} from '../../schema/index.js'\nimport { DatabaseContext, validateToken } from '../utils/index.js'\nimport { UserMailer } from '../mailing/index.js'\nimport {\n\tActivateOtpCommand,\n\tApiKeyRequestInfo,\n\tCreatePersonTokenCommand,\n\tIncreaseOtpAttemptCommand,\n\tInvalidateTokenCommand,\n\tMarkEmailVerifiedCommand,\n} from '../commands/index.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { isPasswordlessEnabled } from './helpers/isPasswordlessEnabled.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { OtpManager } from './OtpManager.js'\nimport { BackupCodeManager } from './BackupCodeManager.js'\nimport { PersonToken } from '../type/index.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { intervalToSeconds } from '../utils/interval.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\n\nclass PasswordlessSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly otpManager: OtpManager,\n\t\tprivate readonly backupCodeManager: BackupCodeManager,\n\t) {}\n\n\tasync initSignInPasswordless({ db, permissionContext, mailVariant, mailProject, email }: {\n\t\tdb: DatabaseContext\n\t\tpermissionContext: PermissionContext\n\t\temail: string\n\t\tmailVariant?: string\n\t\tmailProject?: string\n\t}): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> => {\n\t\t\tconst configuration = await db.queryHandler.fetch(new ConfigurationQuery(db.providers))\n\t\t\tif (configuration.passwordless.enabled === 'never') {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled', {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst person = await db.queryHandler.fetch(PersonQuery.byEmail(email))\n\t\t\tif (!person) {\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (!isPasswordlessEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled for this person', {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Per-email exponential backoff on outbound mails — bound the spam\n\t\t\t// pressure on a real user even if attackers spray the endpoint.\n\t\t\t// Reuses login_* backoff config against person_auth_log.\n\t\t\tconst nextAllowed = await db.queryHandler.fetch(\n\t\t\t\tnew NextMailAttemptQuery(email, 'passwordless_login_init', 'passwordless_login'),\n\t\t\t)\n\t\t\tif (nextAllowed > new Date()) {\n\t\t\t\tconst retryAfterSeconds = Math.max(1, Math.ceil((nextAllowed.getTime() - Date.now()) / 1000))\n\t\t\t\treturn new ResponseError(\n\t\t\t\t\t'RATE_LIMIT_EXCEEDED',\n\t\t\t\t\t`Too many passwordless sign-in requests for this email. Retry after ${retryAfterSeconds}s.`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst createTokenCommand = CreatePersonTokenCommand.createPasswordlessRequest(\n\t\t\t\tperson.id,\n\t\t\t\tintervalToSeconds(configuration.passwordless.expiration) / 60,\n\t\t\t)\n\t\t\tconst result = await db.commandBus.execute(createTokenCommand)\n\n\t\t\tconst url = this.formatUrl(configuration.passwordless.url ?? null, result.token, result.id, email) ?? undefined\n\n\t\t\tconst projects = await this.projectManager.getProjectsByIdentity(db, person.identity_id, permissionContext)\n\t\t\tconst project = getPreferredProject(projects, mailProject ?? null)\n\n\t\t\tawait this.mailer.sendPasswordlessEmail(db, {\n\t\t\t\temail,\n\t\t\t\ttoken: result.token,\n\t\t\t\turl,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t\trequestId: result.id,\n\t\t\t}, {\n\t\t\t\tvariant: mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t})\n\n\t\t\treturn new ResponseOk({\n\t\t\t\trequestId: result.id,\n\t\t\t\texpiresAt: result.expiresAt,\n\t\t\t\tperson,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonInput: email,\n\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\ttokenId: result.id,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate formatUrl(url: string | null, token: string, requestId: string, email: string): string | null {\n\t\tif (!url) {\n\t\t\treturn null\n\t\t}\n\t\tconst urlObj = new URL(url)\n\t\turlObj.searchParams.set('token', token)\n\t\turlObj.searchParams.set('request_id', requestId)\n\t\turlObj.searchParams.set('email', email)\n\t\treturn urlObj.toString()\n\t}\n\n\tasync signInPasswordless({ db, expiration, token, requestId, mfaOtp, backupCode, validationType, requestInfo, trustForwardedInfo }: {\n\t\tdb: DatabaseContext\n\t\tvalidationType: PersonToken.ValidationType\n\t\trequestId: string\n\t\ttoken: string\n\t\tmfaOtp?: string\n\t\tbackupCode?: string\n\t\texpiration?: number\n\t\trequestInfo?: ApiKeyRequestInfo\n\t\ttrustForwardedInfo?: boolean\n\t}): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> => {\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType,\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\tif (tokenValidationResult.error === 'TOKEN_INVALID' && validationType === 'otp') {\n\t\t\t\t\tawait db.commandBus.execute(new IncreaseOtpAttemptCommand(tokenResult!.id))\n\t\t\t\t}\n\t\t\t\treturn new ResponseError(tokenValidationResult.error, tokenValidationResult.errorMessage, {\n\t\t\t\t\t...tokenValidationResult.metadata ?? {},\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: tokenResult?.person_id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (!tokenResult) {\n\t\t\t\tthrow new ImplementationException()\n\t\t\t}\n\t\t\tconst personRow = await db.queryHandler.fetch(PersonQuery.byId(tokenValidationResult.result.person_id))\n\t\t\tif (!personRow) {\n\t\t\t\tthrow new ImplementationException()\n\t\t\t}\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tlet usedBackupCode = false\n\t\t\tif (personRow.otp_secret && personRow.otp_activated_at) {\n\t\t\t\tif (mfaOtp) {\n\t\t\t\t\tif (!await this.otpManager.verifyOtp(db, personRow, mfaOtp)) {\n\t\t\t\t\t\treturn new ResponseError('INVALID_OTP_TOKEN', 'OTP token validation has failed', {\n\t\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else if (backupCode) {\n\t\t\t\t\tif (!await this.backupCodeManager.verifyAndConsume(db, personRow, backupCode)) {\n\t\t\t\t\t\treturn new ResponseError('INVALID_OTP_TOKEN', 'OTP token validation has failed', {\n\t\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tusedBackupCode = true\n\t\t\t\t} else {\n\t\t\t\t\treturn new ResponseError('OTP_REQUIRED', `2FA is enabled. OTP token is required`, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\t// NOTE: passwordless sign-in does NOT enforce mandatory-MFA enrollment.\n\t\t\t// A person with no MFA factor is let through even when an auth_policy would\n\t\t\t// require MFA — enroll-via-sign-in is password-only, and passwordless email\n\t\t\t// access is itself a possession factor. An existing factor (TOTP/backup\n\t\t\t// code, handled above) is still verified. Documented limitation (A06).\n\n\t\t\tawait db.commandBus.execute(new InvalidateTokenCommand(tokenValidationResult.result.id))\n\t\t\t// Receiving and clicking the magic link proves ownership of the address,\n\t\t\t// so a successful passwordless sign-in also satisfies the e-mail\n\t\t\t// verification requirement. Without this, a required-but-unverified\n\t\t\t// account could obtain a session here while being blocked from password\n\t\t\t// sign-in (SignInManager) — an inconsistent, exploitable gap.\n\t\t\tconst emailVerifiedNow = personRow.email_verified_at === null\n\t\t\tif (emailVerifiedNow) {\n\t\t\t\tawait db.commandBus.execute(new MarkEmailVerifiedCommand(personRow.id))\n\t\t\t}\n\t\t\tconst sessionToken = await this.apiKeyManager.createSessionApiKey(db, personRow.identity_id, expiration, requestInfo, trustForwardedInfo)\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tusedBackupCode,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t// Record that this sign-in also satisfied e-mail verification, so\n\t\t\t\t\t// the audit trail shows when/how the address became verified.\n\t\t\t\t\teventData: emailVerifiedNow ? { emailVerified: true } : undefined,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync activatePasswordlessOtp({ db, token, requestId, otpHash }: {\n\t\tdb: DatabaseContext\n\t\trequestId: string\n\t\ttoken: string\n\t\totpHash: string\n\t}): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> => {\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType: 'token',\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\treturn new ResponseError(tokenValidationResult.error, tokenValidationResult.errorMessage, {\n\t\t\t\t\t...tokenValidationResult.metadata ?? {},\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: tokenResult?.person_id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tawait db.commandBus.execute(new ActivateOtpCommand(tokenValidationResult.result.id, otpHash))\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: tokenResult?.person_id,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: tokenResult?.person_id,\n\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n}\n\nnamespace PasswordlessSignInManager {\n\texport type InitSignInPasswordlessResponse = Response<\n\t\tInitSignInPasswordlessResult & {\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t},\n\t\tInitSignInPasswordlessErrorCode,\n\t\t{\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t}\n\t>\n\n\tinterface SignInPasswordlessResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\t/** True when MFA was satisfied by consuming a backup code (instead of a TOTP token). */\n\t\treadonly usedBackupCode?: boolean\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\texport type SignInPasswordlessResponse = Response<SignInPasswordlessResult, SignInPasswordlessErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n\n\texport type ActivatePasswordlessOtpResponse = Response<\n\t\t{\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t},\n\t\tActivatePasswordlessOtpErrorCode,\n\t\t{\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t}\n\t>\n}\n\nexport { PasswordlessSignInManager }\n"],"names":["db","ConfigurationQuery","ResponseError","AuthLogService","PersonQuery","isPasswordlessEnabled","NextMailAttemptQuery","CreatePersonTokenCommand","intervalToSeconds","getPreferredProject","ResponseOk","token","PersonTokenQuery","validateToken","IncreaseOtpAttemptCommand","ImplementationException","InvalidateTokenCommand","MarkEmailVerifiedCommand","ActivateOtpCommand"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PasswordlessSignInManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordlessSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { ConfigurationQuery, LocalAuthDisablingIdpsQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport {\n\tActivatePasswordlessOtpErrorCode,\n\tInitSignInPasswordlessErrorCode,\n\tInitSignInPasswordlessResult,\n\tSignInPasswordlessErrorCode,\n} from '../../schema/index.js'\nimport { DatabaseContext, validateToken } from '../utils/index.js'\nimport { UserMailer } from '../mailing/index.js'\nimport {\n\tActivateOtpCommand,\n\tApiKeyRequestInfo,\n\tCreatePersonTokenCommand,\n\tIncreaseOtpAttemptCommand,\n\tInvalidateTokenCommand,\n\tMarkEmailVerifiedCommand,\n} from '../commands/index.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { isPasswordlessEnabled } from './helpers/isPasswordlessEnabled.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { OtpManager } from './OtpManager.js'\nimport { BackupCodeManager } from './BackupCodeManager.js'\nimport { PersonToken } from '../type/index.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { intervalToSeconds } from '../utils/interval.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\n\nclass PasswordlessSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly otpManager: OtpManager,\n\t\tprivate readonly backupCodeManager: BackupCodeManager,\n\t) {}\n\n\tasync initSignInPasswordless({ db, permissionContext, mailVariant, mailProject, email }: {\n\t\tdb: DatabaseContext\n\t\tpermissionContext: PermissionContext\n\t\temail: string\n\t\tmailVariant?: string\n\t\tmailProject?: string\n\t}): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> => {\n\t\t\tconst configuration = await db.queryHandler.fetch(new ConfigurationQuery(db.providers))\n\t\t\tif (configuration.passwordless.enabled === 'never') {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled', {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst person = await db.queryHandler.fetch(PersonQuery.byEmail(email))\n\t\t\tif (!person) {\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst exclusiveIdps = await db.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id))\n\t\t\tif (exclusiveIdps.length > 0) {\n\t\t\t\treturn new ResponseError('IDP_REQUIRED', `Sign in using ${exclusiveIdps.join(' or ')}`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (!isPasswordlessEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled for this person', {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Per-email exponential backoff on outbound mails — bound the spam\n\t\t\t// pressure on a real user even if attackers spray the endpoint.\n\t\t\t// Reuses login_* backoff config against person_auth_log.\n\t\t\tconst nextAllowed = await db.queryHandler.fetch(\n\t\t\t\tnew NextMailAttemptQuery(email, 'passwordless_login_init', 'passwordless_login'),\n\t\t\t)\n\t\t\tif (nextAllowed > new Date()) {\n\t\t\t\tconst retryAfterSeconds = Math.max(1, Math.ceil((nextAllowed.getTime() - Date.now()) / 1000))\n\t\t\t\treturn new ResponseError(\n\t\t\t\t\t'RATE_LIMIT_EXCEEDED',\n\t\t\t\t\t`Too many passwordless sign-in requests for this email. Retry after ${retryAfterSeconds}s.`,\n\t\t\t\t\t{\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonInput: email,\n\t\t\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst createTokenCommand = CreatePersonTokenCommand.createPasswordlessRequest(\n\t\t\t\tperson.id,\n\t\t\t\tintervalToSeconds(configuration.passwordless.expiration) / 60,\n\t\t\t)\n\t\t\tconst result = await db.commandBus.execute(createTokenCommand)\n\n\t\t\tconst url = this.formatUrl(configuration.passwordless.url ?? null, result.token, result.id, email) ?? undefined\n\n\t\t\tconst projects = await this.projectManager.getProjectsByIdentity(db, person.identity_id, permissionContext)\n\t\t\tconst project = getPreferredProject(projects, mailProject ?? null)\n\n\t\t\tawait this.mailer.sendPasswordlessEmail(db, {\n\t\t\t\temail,\n\t\t\t\ttoken: result.token,\n\t\t\t\turl,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t\trequestId: result.id,\n\t\t\t}, {\n\t\t\t\tvariant: mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t})\n\n\t\t\treturn new ResponseOk({\n\t\t\t\trequestId: result.id,\n\t\t\t\texpiresAt: result.expiresAt,\n\t\t\t\tperson,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonInput: email,\n\t\t\t\t\tpersonId: person.id,\n\t\t\t\t\ttokenId: result.id,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate formatUrl(url: string | null, token: string, requestId: string, email: string): string | null {\n\t\tif (!url) {\n\t\t\treturn null\n\t\t}\n\t\tconst urlObj = new URL(url)\n\t\turlObj.searchParams.set('token', token)\n\t\turlObj.searchParams.set('request_id', requestId)\n\t\turlObj.searchParams.set('email', email)\n\t\treturn urlObj.toString()\n\t}\n\n\tasync signInPasswordless({ db, expiration, token, requestId, mfaOtp, backupCode, validationType, requestInfo, trustForwardedInfo }: {\n\t\tdb: DatabaseContext\n\t\tvalidationType: PersonToken.ValidationType\n\t\trequestId: string\n\t\ttoken: string\n\t\tmfaOtp?: string\n\t\tbackupCode?: string\n\t\texpiration?: number\n\t\trequestInfo?: ApiKeyRequestInfo\n\t\ttrustForwardedInfo?: boolean\n\t}): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> => {\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType,\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\tif (tokenValidationResult.error === 'TOKEN_INVALID' && validationType === 'otp') {\n\t\t\t\t\tawait db.commandBus.execute(new IncreaseOtpAttemptCommand(tokenResult!.id))\n\t\t\t\t}\n\t\t\t\treturn new ResponseError(tokenValidationResult.error, tokenValidationResult.errorMessage, {\n\t\t\t\t\t...tokenValidationResult.metadata ?? {},\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: tokenResult?.person_id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (!tokenResult) {\n\t\t\t\tthrow new ImplementationException()\n\t\t\t}\n\t\t\tconst personRow = await db.queryHandler.fetch(PersonQuery.byId(tokenValidationResult.result.person_id))\n\t\t\tif (!personRow) {\n\t\t\t\tthrow new ImplementationException()\n\t\t\t}\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Re-checked here and not only at init: a link created while this magic link\n\t\t\t// was in flight would otherwise still mint a locally authenticated session.\n\t\t\tconst exclusiveIdps = await db.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(personRow.id))\n\t\t\tif (exclusiveIdps.length > 0) {\n\t\t\t\treturn new ResponseError('IDP_REQUIRED', `Sign in using ${exclusiveIdps.join(' or ')}`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tlet usedBackupCode = false\n\t\t\tif (personRow.otp_secret && personRow.otp_activated_at) {\n\t\t\t\tif (mfaOtp) {\n\t\t\t\t\tif (!await this.otpManager.verifyOtp(db, personRow, mfaOtp)) {\n\t\t\t\t\t\treturn new ResponseError('INVALID_OTP_TOKEN', 'OTP token validation has failed', {\n\t\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else if (backupCode) {\n\t\t\t\t\tif (!await this.backupCodeManager.verifyAndConsume(db, personRow, backupCode)) {\n\t\t\t\t\t\treturn new ResponseError('INVALID_OTP_TOKEN', 'OTP token validation has failed', {\n\t\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tusedBackupCode = true\n\t\t\t\t} else {\n\t\t\t\t\treturn new ResponseError('OTP_REQUIRED', `2FA is enabled. OTP token is required`, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\t// NOTE: passwordless sign-in does NOT enforce mandatory-MFA enrollment.\n\t\t\t// A person with no MFA factor is let through even when an auth_policy would\n\t\t\t// require MFA — enroll-via-sign-in is password-only, and passwordless email\n\t\t\t// access is itself a possession factor. An existing factor (TOTP/backup\n\t\t\t// code, handled above) is still verified. Documented limitation (A06).\n\n\t\t\tawait db.commandBus.execute(new InvalidateTokenCommand(tokenValidationResult.result.id))\n\t\t\t// Receiving and clicking the magic link proves ownership of the address,\n\t\t\t// so a successful passwordless sign-in also satisfies the e-mail\n\t\t\t// verification requirement. Without this, a required-but-unverified\n\t\t\t// account could obtain a session here while being blocked from password\n\t\t\t// sign-in (SignInManager) — an inconsistent, exploitable gap.\n\t\t\tconst emailVerifiedNow = personRow.email_verified_at === null\n\t\t\tif (emailVerifiedNow) {\n\t\t\t\tawait db.commandBus.execute(new MarkEmailVerifiedCommand(personRow.id))\n\t\t\t}\n\t\t\tconst sessionToken = await this.apiKeyManager.createSessionApiKey(db, personRow.identity_id, expiration, requestInfo, trustForwardedInfo)\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tusedBackupCode,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t// Record that this sign-in also satisfied e-mail verification, so\n\t\t\t\t\t// the audit trail shows when/how the address became verified.\n\t\t\t\t\teventData: emailVerifiedNow ? { emailVerified: true } : undefined,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync activatePasswordlessOtp({ db, token, requestId, otpHash }: {\n\t\tdb: DatabaseContext\n\t\trequestId: string\n\t\ttoken: string\n\t\totpHash: string\n\t}): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> => {\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType: 'token',\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\treturn new ResponseError(tokenValidationResult.error, tokenValidationResult.errorMessage, {\n\t\t\t\t\t...tokenValidationResult.metadata ?? {},\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tpersonId: tokenResult?.person_id,\n\t\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tawait db.commandBus.execute(new ActivateOtpCommand(tokenValidationResult.result.id, otpHash))\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: tokenResult?.person_id,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: tokenResult?.person_id,\n\t\t\t\t\ttokenId: tokenResult?.id,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n}\n\nnamespace PasswordlessSignInManager {\n\texport type InitSignInPasswordlessResponse = Response<\n\t\tInitSignInPasswordlessResult & {\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t},\n\t\tInitSignInPasswordlessErrorCode,\n\t\t{\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t}\n\t>\n\n\tinterface SignInPasswordlessResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\t/** True when MFA was satisfied by consuming a backup code (instead of a TOTP token). */\n\t\treadonly usedBackupCode?: boolean\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\texport type SignInPasswordlessResponse = Response<SignInPasswordlessResult, SignInPasswordlessErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n\n\texport type ActivatePasswordlessOtpResponse = Response<\n\t\t{\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t},\n\t\tActivatePasswordlessOtpErrorCode,\n\t\t{\n\t\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t\t}\n\t>\n}\n\nexport { PasswordlessSignInManager }\n"],"names":["db","ConfigurationQuery","ResponseError","AuthLogService","PersonQuery","LocalAuthDisablingIdpsQuery","isPasswordlessEnabled","NextMailAttemptQuery","CreatePersonTokenCommand","intervalToSeconds","getPreferredProject","ResponseOk","token","PersonTokenQuery","validateToken","IncreaseOtpAttemptCommand","ImplementationException","InvalidateTokenCommand","MarkEmailVerifiedCommand","ActivateOtpCommand"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import "../type/ApiKey.js";
|
|
|
4
4
|
import { ConfigurationQuery } from "../queries/configuration/ConfigurationQuery.js";
|
|
5
5
|
import { ImplementationException } from "../../exceptions.js";
|
|
6
6
|
import { PersonQuery } from "../queries/person/PersonQuery.js";
|
|
7
|
+
import { LocalAuthDisablingIdpsQuery } from "../queries/idp/LocalAuthDisablingIdpsQuery.js";
|
|
7
8
|
import "../authorization/PermissionActions.js";
|
|
8
9
|
import "@contember/authorization";
|
|
9
10
|
import "../authorization/PermissionContext.js";
|
|
@@ -46,6 +47,15 @@ class PasswordlessSignInManager {
|
|
|
46
47
|
})
|
|
47
48
|
});
|
|
48
49
|
}
|
|
50
|
+
const exclusiveIdps = await db2.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id));
|
|
51
|
+
if (exclusiveIdps.length > 0) {
|
|
52
|
+
return new ResponseError("IDP_REQUIRED", `Sign in using ${exclusiveIdps.join(" or ")}`, {
|
|
53
|
+
[AuthLogService.Key]: new AuthLogService.Bag({
|
|
54
|
+
personInput: email,
|
|
55
|
+
personId: person.id
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
}
|
|
49
59
|
if (!isPasswordlessEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {
|
|
50
60
|
return new ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled for this person", {
|
|
51
61
|
[AuthLogService.Key]: new AuthLogService.Bag({
|
|
@@ -147,6 +157,15 @@ class PasswordlessSignInManager {
|
|
|
147
157
|
})
|
|
148
158
|
});
|
|
149
159
|
}
|
|
160
|
+
const exclusiveIdps = await db2.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(personRow.id));
|
|
161
|
+
if (exclusiveIdps.length > 0) {
|
|
162
|
+
return new ResponseError("IDP_REQUIRED", `Sign in using ${exclusiveIdps.join(" or ")}`, {
|
|
163
|
+
[AuthLogService.Key]: new AuthLogService.Bag({
|
|
164
|
+
personId: personRow.id,
|
|
165
|
+
tokenId: tokenResult?.id
|
|
166
|
+
})
|
|
167
|
+
});
|
|
168
|
+
}
|
|
150
169
|
let usedBackupCode = false;
|
|
151
170
|
if (personRow.otp_secret && personRow.otp_activated_at) {
|
|
152
171
|
if (mfaOtp) {
|