@portaidentity/server 1.7.3 → 1.8.0
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/CHANGELOG.md +5 -0
- package/dist/applications/index.d.ts +2 -2
- package/dist/applications/index.d.ts.map +1 -1
- package/dist/applications/index.js +2 -2
- package/dist/applications/index.js.map +1 -1
- package/dist/applications/repository.d.ts +49 -4
- package/dist/applications/repository.d.ts.map +1 -1
- package/dist/applications/repository.js +148 -10
- package/dist/applications/repository.js.map +1 -1
- package/dist/applications/service.d.ts +35 -17
- package/dist/applications/service.d.ts.map +1 -1
- package/dist/applications/service.js +144 -35
- package/dist/applications/service.js.map +1 -1
- package/dist/applications/types.d.ts +1 -1
- package/dist/applications/types.d.ts.map +1 -1
- package/dist/applications/validators.d.ts +14 -0
- package/dist/applications/validators.d.ts.map +1 -0
- package/dist/applications/validators.js +14 -0
- package/dist/applications/validators.js.map +1 -0
- package/dist/auth/effective-branding.d.ts +35 -0
- package/dist/auth/effective-branding.d.ts.map +1 -0
- package/dist/auth/effective-branding.js +81 -0
- package/dist/auth/effective-branding.js.map +1 -0
- package/dist/auth/email-service.d.ts +3 -8
- package/dist/auth/email-service.d.ts.map +1 -1
- package/dist/auth/email-service.js +22 -30
- package/dist/auth/email-service.js.map +1 -1
- package/dist/auth/i18n.d.ts +5 -0
- package/dist/auth/i18n.d.ts.map +1 -1
- package/dist/auth/i18n.js +6 -5
- package/dist/auth/i18n.js.map +1 -1
- package/dist/auth/rate-limiter.d.ts +6 -10
- package/dist/auth/rate-limiter.d.ts.map +1 -1
- package/dist/auth/rate-limiter.js +12 -16
- package/dist/auth/rate-limiter.js.map +1 -1
- package/dist/auth/recovery-job-processor.d.ts.map +1 -1
- package/dist/auth/recovery-job-processor.js +1 -1
- package/dist/auth/recovery-job-processor.js.map +1 -1
- package/dist/auth/template-engine.d.ts +3 -1
- package/dist/auth/template-engine.d.ts.map +1 -1
- package/dist/auth/template-engine.js +1 -1
- package/dist/auth/template-engine.js.map +1 -1
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +12 -12
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/error-handler.d.ts +3 -2
- package/dist/cli/error-handler.d.ts.map +1 -1
- package/dist/cli/error-handler.js +9 -2
- package/dist/cli/error-handler.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/clients/index.d.ts +1 -1
- package/dist/clients/index.js +1 -1
- package/dist/clients/repository.d.ts +18 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +36 -0
- package/dist/clients/repository.js.map +1 -1
- package/dist/clients/secret-repository.d.ts +35 -8
- package/dist/clients/secret-repository.d.ts.map +1 -1
- package/dist/clients/secret-repository.js +69 -16
- package/dist/clients/secret-repository.js.map +1 -1
- package/dist/clients/secret-service.d.ts +5 -9
- package/dist/clients/secret-service.d.ts.map +1 -1
- package/dist/clients/secret-service.js +13 -22
- package/dist/clients/secret-service.js.map +1 -1
- package/dist/clients/service.d.ts +10 -13
- package/dist/clients/service.d.ts.map +1 -1
- package/dist/clients/service.js +112 -40
- package/dist/clients/service.js.map +1 -1
- package/dist/clients/types.d.ts +1 -1
- package/dist/clients/types.d.ts.map +1 -1
- package/dist/clients/validators.d.ts +83 -1
- package/dist/clients/validators.d.ts.map +1 -1
- package/dist/clients/validators.js +110 -0
- package/dist/clients/validators.js.map +1 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +23 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/custom-claims/repository.d.ts +14 -9
- package/dist/custom-claims/repository.d.ts.map +1 -1
- package/dist/custom-claims/repository.js +38 -11
- package/dist/custom-claims/repository.js.map +1 -1
- package/dist/custom-claims/service.d.ts +11 -6
- package/dist/custom-claims/service.d.ts.map +1 -1
- package/dist/custom-claims/service.js +43 -20
- package/dist/custom-claims/service.js.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/admin-permissions.d.ts +12 -7
- package/dist/lib/admin-permissions.d.ts.map +1 -1
- package/dist/lib/admin-permissions.js +26 -16
- package/dist/lib/admin-permissions.js.map +1 -1
- package/dist/lib/audit-log.d.ts +2 -2
- package/dist/lib/audit-log.d.ts.map +1 -1
- package/dist/lib/audit-log.js +1 -1
- package/dist/lib/audit-log.js.map +1 -1
- package/dist/lib/authority-revocation.d.ts +18 -0
- package/dist/lib/authority-revocation.d.ts.map +1 -0
- package/dist/lib/authority-revocation.js +37 -0
- package/dist/lib/authority-revocation.js.map +1 -0
- package/dist/lib/branding-assets.d.ts +35 -5
- package/dist/lib/branding-assets.d.ts.map +1 -1
- package/dist/lib/branding-assets.js +33 -26
- package/dist/lib/branding-assets.js.map +1 -1
- package/dist/lib/bulk-operations.d.ts +1 -1
- package/dist/lib/bulk-operations.d.ts.map +1 -1
- package/dist/lib/bulk-operations.js +1 -13
- package/dist/lib/bulk-operations.js.map +1 -1
- package/dist/lib/cursor.d.ts +2 -0
- package/dist/lib/cursor.d.ts.map +1 -1
- package/dist/lib/cursor.js +2 -7
- package/dist/lib/cursor.js.map +1 -1
- package/dist/lib/database.d.ts.map +1 -1
- package/dist/lib/database.js +5 -0
- package/dist/lib/database.js.map +1 -1
- package/dist/lib/deletion-cleanup.d.ts +43 -0
- package/dist/lib/deletion-cleanup.d.ts.map +1 -0
- package/dist/lib/deletion-cleanup.js +207 -0
- package/dist/lib/deletion-cleanup.js.map +1 -0
- package/dist/lib/image-validator.d.ts +3 -1
- package/dist/lib/image-validator.d.ts.map +1 -1
- package/dist/lib/image-validator.js +32 -19
- package/dist/lib/image-validator.js.map +1 -1
- package/dist/lib/log-format.d.ts +20 -0
- package/dist/lib/log-format.d.ts.map +1 -0
- package/dist/lib/log-format.js +22 -0
- package/dist/lib/log-format.js.map +1 -0
- package/dist/lib/logger.d.ts +3 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +21 -4
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/redis.d.ts.map +1 -1
- package/dist/lib/redis.js +3 -0
- package/dist/lib/redis.js.map +1 -1
- package/dist/lib/session-tracking.d.ts +73 -11
- package/dist/lib/session-tracking.d.ts.map +1 -1
- package/dist/lib/session-tracking.js +76 -32
- package/dist/lib/session-tracking.js.map +1 -1
- package/dist/lib/signing-key-crypto.d.ts.map +1 -1
- package/dist/lib/signing-key-crypto.js +4 -5
- package/dist/lib/signing-key-crypto.js.map +1 -1
- package/dist/lib/signing-keys.d.ts +3 -4
- package/dist/lib/signing-keys.d.ts.map +1 -1
- package/dist/lib/signing-keys.js +66 -41
- package/dist/lib/signing-keys.js.map +1 -1
- package/dist/lib/super-admin-protection.d.ts +5 -5
- package/dist/lib/super-admin-protection.d.ts.map +1 -1
- package/dist/lib/super-admin-protection.js +6 -9
- package/dist/lib/super-admin-protection.js.map +1 -1
- package/dist/lib/system-config-catalog.d.ts +268 -0
- package/dist/lib/system-config-catalog.d.ts.map +1 -0
- package/dist/lib/system-config-catalog.js +90 -0
- package/dist/lib/system-config-catalog.js.map +1 -0
- package/dist/lib/system-config.d.ts +30 -33
- package/dist/lib/system-config.d.ts.map +1 -1
- package/dist/lib/system-config.js +78 -93
- package/dist/lib/system-config.js.map +1 -1
- package/dist/lib/with-timeout.d.ts +32 -0
- package/dist/lib/with-timeout.d.ts.map +1 -0
- package/dist/lib/with-timeout.js +45 -0
- package/dist/lib/with-timeout.js.map +1 -0
- package/dist/middleware/admin-auth.d.ts +6 -5
- package/dist/middleware/admin-auth.d.ts.map +1 -1
- package/dist/middleware/admin-auth.js +30 -20
- package/dist/middleware/admin-auth.js.map +1 -1
- package/dist/middleware/admin-cors.d.ts +3 -3
- package/dist/middleware/admin-cors.js +3 -3
- package/dist/middleware/admin-mutation-audit.d.ts +3 -2
- package/dist/middleware/admin-mutation-audit.d.ts.map +1 -1
- package/dist/middleware/admin-mutation-audit.js +12 -5
- package/dist/middleware/admin-mutation-audit.js.map +1 -1
- package/dist/middleware/admin-rate-limiter.d.ts +7 -8
- package/dist/middleware/admin-rate-limiter.d.ts.map +1 -1
- package/dist/middleware/admin-rate-limiter.js +7 -8
- package/dist/middleware/admin-rate-limiter.js.map +1 -1
- package/dist/middleware/client-secret-hash.d.ts +10 -29
- package/dist/middleware/client-secret-hash.d.ts.map +1 -1
- package/dist/middleware/client-secret-hash.js +161 -59
- package/dist/middleware/client-secret-hash.js.map +1 -1
- package/dist/middleware/health.d.ts +17 -0
- package/dist/middleware/health.d.ts.map +1 -1
- package/dist/middleware/health.js +25 -21
- package/dist/middleware/health.js.map +1 -1
- package/dist/middleware/ready.d.ts.map +1 -1
- package/dist/middleware/ready.js +1 -12
- package/dist/middleware/ready.js.map +1 -1
- package/dist/middleware/require-existing-organization.d.ts +18 -0
- package/dist/middleware/require-existing-organization.d.ts.map +1 -0
- package/dist/middleware/require-existing-organization.js +38 -0
- package/dist/middleware/require-existing-organization.js.map +1 -0
- package/dist/middleware/require-permission.d.ts.map +1 -1
- package/dist/middleware/require-permission.js +35 -1
- package/dist/middleware/require-permission.js.map +1 -1
- package/dist/middleware/require-user-organization.d.ts.map +1 -1
- package/dist/middleware/require-user-organization.js +4 -2
- package/dist/middleware/require-user-organization.js.map +1 -1
- package/dist/middleware/security-headers.d.ts +18 -0
- package/dist/middleware/security-headers.d.ts.map +1 -1
- package/dist/middleware/security-headers.js +32 -1
- package/dist/middleware/security-headers.js.map +1 -1
- package/dist/middleware/tenant-resolver.d.ts +1 -2
- package/dist/middleware/tenant-resolver.d.ts.map +1 -1
- package/dist/middleware/tenant-resolver.js +1 -5
- package/dist/middleware/tenant-resolver.js.map +1 -1
- package/dist/middleware/token-rate-limiter.d.ts +37 -16
- package/dist/middleware/token-rate-limiter.d.ts.map +1 -1
- package/dist/middleware/token-rate-limiter.js +126 -54
- package/dist/middleware/token-rate-limiter.js.map +1 -1
- package/dist/oidc/account-finder.d.ts +5 -5
- package/dist/oidc/account-finder.d.ts.map +1 -1
- package/dist/oidc/account-finder.js +31 -23
- package/dist/oidc/account-finder.js.map +1 -1
- package/dist/oidc/adapter-factory.d.ts.map +1 -1
- package/dist/oidc/adapter-factory.js +83 -3
- package/dist/oidc/adapter-factory.js.map +1 -1
- package/dist/oidc/configuration.d.ts +3 -8
- package/dist/oidc/configuration.d.ts.map +1 -1
- package/dist/oidc/configuration.js +64 -50
- package/dist/oidc/configuration.js.map +1 -1
- package/dist/oidc/provider.d.ts.map +1 -1
- package/dist/oidc/provider.js +7 -0
- package/dist/oidc/provider.js.map +1 -1
- package/dist/oidc/redis-adapter.d.ts +2 -3
- package/dist/oidc/redis-adapter.d.ts.map +1 -1
- package/dist/oidc/redis-adapter.js +54 -46
- package/dist/oidc/redis-adapter.js.map +1 -1
- package/dist/organizations/branding-url.d.ts +17 -0
- package/dist/organizations/branding-url.d.ts.map +1 -0
- package/dist/organizations/branding-url.js +38 -0
- package/dist/organizations/branding-url.js.map +1 -0
- package/dist/organizations/index.d.ts +2 -2
- package/dist/organizations/index.d.ts.map +1 -1
- package/dist/organizations/index.js +1 -1
- package/dist/organizations/index.js.map +1 -1
- package/dist/organizations/repository.d.ts +22 -32
- package/dist/organizations/repository.d.ts.map +1 -1
- package/dist/organizations/repository.js +64 -45
- package/dist/organizations/repository.js.map +1 -1
- package/dist/organizations/service.d.ts +14 -46
- package/dist/organizations/service.d.ts.map +1 -1
- package/dist/organizations/service.js +60 -112
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +1 -15
- package/dist/organizations/types.d.ts.map +1 -1
- package/dist/organizations/validators.d.ts +41 -0
- package/dist/organizations/validators.d.ts.map +1 -0
- package/dist/organizations/validators.js +48 -0
- package/dist/organizations/validators.js.map +1 -0
- package/dist/portability/apply.d.ts +15 -0
- package/dist/portability/apply.d.ts.map +1 -0
- package/dist/portability/apply.js +274 -0
- package/dist/portability/apply.js.map +1 -0
- package/dist/portability/authorization.d.ts +30 -0
- package/dist/portability/authorization.d.ts.map +1 -0
- package/dist/portability/authorization.js +130 -0
- package/dist/portability/authorization.js.map +1 -0
- package/dist/portability/cleanup.d.ts +29 -0
- package/dist/portability/cleanup.d.ts.map +1 -0
- package/dist/portability/cleanup.js +167 -0
- package/dist/portability/cleanup.js.map +1 -0
- package/dist/portability/export.d.ts +18 -0
- package/dist/portability/export.d.ts.map +1 -0
- package/dist/portability/export.js +125 -0
- package/dist/portability/export.js.map +1 -0
- package/dist/portability/import-repository.d.ts +204 -0
- package/dist/portability/import-repository.d.ts.map +1 -0
- package/dist/portability/import-repository.js +347 -0
- package/dist/portability/import-repository.js.map +1 -0
- package/dist/portability/import-user-client-writers.d.ts +40 -0
- package/dist/portability/import-user-client-writers.d.ts.map +1 -0
- package/dist/portability/import-user-client-writers.js +168 -0
- package/dist/portability/import-user-client-writers.js.map +1 -0
- package/dist/portability/index.d.ts +8 -0
- package/dist/portability/index.d.ts.map +1 -0
- package/dist/portability/index.js +8 -0
- package/dist/portability/index.js.map +1 -0
- package/dist/portability/plan-support.d.ts +137 -0
- package/dist/portability/plan-support.d.ts.map +1 -0
- package/dist/portability/plan-support.js +336 -0
- package/dist/portability/plan-support.js.map +1 -0
- package/dist/portability/plan.d.ts +34 -0
- package/dist/portability/plan.d.ts.map +1 -0
- package/dist/portability/plan.js +450 -0
- package/dist/portability/plan.js.map +1 -0
- package/dist/portability/repository.d.ts +95 -0
- package/dist/portability/repository.d.ts.map +1 -0
- package/dist/portability/repository.js +388 -0
- package/dist/portability/repository.js.map +1 -0
- package/dist/portability/schema.d.ts +589 -0
- package/dist/portability/schema.d.ts.map +1 -0
- package/dist/portability/schema.js +458 -0
- package/dist/portability/schema.js.map +1 -0
- package/dist/portability/types.d.ts +381 -0
- package/dist/portability/types.d.ts.map +1 -0
- package/dist/portability/types.js +19 -0
- package/dist/portability/types.js.map +1 -0
- package/dist/rbac/errors.d.ts +4 -0
- package/dist/rbac/errors.d.ts.map +1 -1
- package/dist/rbac/errors.js +7 -0
- package/dist/rbac/errors.js.map +1 -1
- package/dist/rbac/index.d.ts +3 -3
- package/dist/rbac/index.d.ts.map +1 -1
- package/dist/rbac/index.js +3 -3
- package/dist/rbac/index.js.map +1 -1
- package/dist/rbac/mapping-repository.d.ts +84 -9
- package/dist/rbac/mapping-repository.d.ts.map +1 -1
- package/dist/rbac/mapping-repository.js +222 -55
- package/dist/rbac/mapping-repository.js.map +1 -1
- package/dist/rbac/permission-repository.d.ts +36 -19
- package/dist/rbac/permission-repository.d.ts.map +1 -1
- package/dist/rbac/permission-repository.js +93 -35
- package/dist/rbac/permission-repository.js.map +1 -1
- package/dist/rbac/permission-service.d.ts +18 -19
- package/dist/rbac/permission-service.d.ts.map +1 -1
- package/dist/rbac/permission-service.js +100 -57
- package/dist/rbac/permission-service.js.map +1 -1
- package/dist/rbac/role-repository.d.ts +29 -24
- package/dist/rbac/role-repository.d.ts.map +1 -1
- package/dist/rbac/role-repository.js +66 -43
- package/dist/rbac/role-repository.js.map +1 -1
- package/dist/rbac/role-service.d.ts +35 -32
- package/dist/rbac/role-service.d.ts.map +1 -1
- package/dist/rbac/role-service.js +210 -96
- package/dist/rbac/role-service.js.map +1 -1
- package/dist/rbac/slugs.d.ts +16 -27
- package/dist/rbac/slugs.d.ts.map +1 -1
- package/dist/rbac/slugs.js +36 -59
- package/dist/rbac/slugs.js.map +1 -1
- package/dist/rbac/types.d.ts +2 -4
- package/dist/rbac/types.d.ts.map +1 -1
- package/dist/rbac/types.js.map +1 -1
- package/dist/rbac/user-role-service.d.ts +23 -24
- package/dist/rbac/user-role-service.d.ts.map +1 -1
- package/dist/rbac/user-role-service.js +117 -61
- package/dist/rbac/user-role-service.js.map +1 -1
- package/dist/routes/applications.d.ts +4 -2
- package/dist/routes/applications.d.ts.map +1 -1
- package/dist/routes/applications.js +57 -19
- package/dist/routes/applications.js.map +1 -1
- package/dist/routes/audit.js +1 -1
- package/dist/routes/audit.js.map +1 -1
- package/dist/routes/branding.d.ts +3 -3
- package/dist/routes/branding.d.ts.map +1 -1
- package/dist/routes/branding.js +44 -16
- package/dist/routes/branding.js.map +1 -1
- package/dist/routes/bulk.d.ts +0 -5
- package/dist/routes/bulk.d.ts.map +1 -1
- package/dist/routes/bulk.js +3 -5
- package/dist/routes/bulk.js.map +1 -1
- package/dist/routes/clients.d.ts +4 -4
- package/dist/routes/clients.d.ts.map +1 -1
- package/dist/routes/clients.js +111 -52
- package/dist/routes/clients.js.map +1 -1
- package/dist/routes/config.d.ts +17 -12
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +165 -64
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/custom-claims.d.ts.map +1 -1
- package/dist/routes/custom-claims.js +8 -2
- package/dist/routes/custom-claims.js.map +1 -1
- package/dist/routes/exports.d.ts +2 -1
- package/dist/routes/exports.d.ts.map +1 -1
- package/dist/routes/exports.js +57 -1
- package/dist/routes/exports.js.map +1 -1
- package/dist/routes/imports.d.ts +2 -2
- package/dist/routes/imports.d.ts.map +1 -1
- package/dist/routes/imports.js +95 -40
- package/dist/routes/imports.js.map +1 -1
- package/dist/routes/interactions.d.ts.map +1 -1
- package/dist/routes/interactions.js +16 -34
- package/dist/routes/interactions.js.map +1 -1
- package/dist/routes/invitation.d.ts.map +1 -1
- package/dist/routes/invitation.js +10 -23
- package/dist/routes/invitation.js.map +1 -1
- package/dist/routes/keys.d.ts.map +1 -1
- package/dist/routes/keys.js +26 -13
- package/dist/routes/keys.js.map +1 -1
- package/dist/routes/magic-link.d.ts.map +1 -1
- package/dist/routes/magic-link.js +5 -17
- package/dist/routes/magic-link.js.map +1 -1
- package/dist/routes/organizations.d.ts +1 -2
- package/dist/routes/organizations.d.ts.map +1 -1
- package/dist/routes/organizations.js +43 -104
- package/dist/routes/organizations.js.map +1 -1
- package/dist/routes/password-reset.d.ts.map +1 -1
- package/dist/routes/password-reset.js +13 -35
- package/dist/routes/password-reset.js.map +1 -1
- package/dist/routes/permissions.d.ts +1 -1
- package/dist/routes/permissions.d.ts.map +1 -1
- package/dist/routes/permissions.js +58 -17
- package/dist/routes/permissions.js.map +1 -1
- package/dist/routes/public-branding.d.ts +16 -0
- package/dist/routes/public-branding.d.ts.map +1 -0
- package/dist/routes/public-branding.js +52 -0
- package/dist/routes/public-branding.js.map +1 -0
- package/dist/routes/roles.d.ts +1 -1
- package/dist/routes/roles.d.ts.map +1 -1
- package/dist/routes/roles.js +63 -21
- package/dist/routes/roles.js.map +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +23 -12
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/two-factor.d.ts.map +1 -1
- package/dist/routes/two-factor.js +91 -38
- package/dist/routes/two-factor.js.map +1 -1
- package/dist/routes/user-roles.d.ts.map +1 -1
- package/dist/routes/user-roles.js +56 -9
- package/dist/routes/user-roles.js.map +1 -1
- package/dist/routes/users.d.ts +4 -8
- package/dist/routes/users.d.ts.map +1 -1
- package/dist/routes/users.js +108 -265
- package/dist/routes/users.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +53 -37
- package/dist/server.js.map +1 -1
- package/dist/two-factor/errors.d.ts +9 -0
- package/dist/two-factor/errors.d.ts.map +1 -1
- package/dist/two-factor/errors.js +12 -0
- package/dist/two-factor/errors.js.map +1 -1
- package/dist/two-factor/index.d.ts +5 -4
- package/dist/two-factor/index.d.ts.map +1 -1
- package/dist/two-factor/index.js +4 -4
- package/dist/two-factor/index.js.map +1 -1
- package/dist/two-factor/repository.d.ts +17 -6
- package/dist/two-factor/repository.d.ts.map +1 -1
- package/dist/two-factor/repository.js +37 -9
- package/dist/two-factor/repository.js.map +1 -1
- package/dist/two-factor/service.d.ts.map +1 -1
- package/dist/two-factor/service.js +26 -19
- package/dist/two-factor/service.js.map +1 -1
- package/dist/two-factor/totp.d.ts +13 -2
- package/dist/two-factor/totp.d.ts.map +1 -1
- package/dist/two-factor/totp.js +20 -7
- package/dist/two-factor/totp.js.map +1 -1
- package/dist/two-factor/types.d.ts +3 -0
- package/dist/two-factor/types.d.ts.map +1 -1
- package/dist/two-factor/types.js +5 -0
- package/dist/two-factor/types.js.map +1 -1
- package/dist/users/gdpr.d.ts +2 -40
- package/dist/users/gdpr.d.ts.map +1 -1
- package/dist/users/gdpr.js +3 -110
- package/dist/users/gdpr.js.map +1 -1
- package/dist/users/index.d.ts +5 -4
- package/dist/users/index.d.ts.map +1 -1
- package/dist/users/index.js +5 -4
- package/dist/users/index.js.map +1 -1
- package/dist/users/repository.d.ts +49 -3
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +169 -18
- package/dist/users/repository.js.map +1 -1
- package/dist/users/service.d.ts +19 -51
- package/dist/users/service.d.ts.map +1 -1
- package/dist/users/service.js +72 -122
- package/dist/users/service.js.map +1 -1
- package/dist/users/types.d.ts +4 -5
- package/dist/users/types.d.ts.map +1 -1
- package/dist/users/types.js.map +1 -1
- package/dist/users/validators.d.ts +28 -0
- package/dist/users/validators.d.ts.map +1 -0
- package/dist/users/validators.js +25 -0
- package/dist/users/validators.js.map +1 -0
- package/locales/default/en/errors.json +2 -1
- package/migrations/024_application_client_correction.sql +39 -0
- package/migrations/025_record_deletion_lifecycle.sql +26 -0
- package/migrations/026_simplify_user_lifecycle.sql +33 -0
- package/migrations/027_branding_asset_size_limits.sql +19 -0
- package/migrations/028_totp_replay_protection.sql +17 -0
- package/migrations/029_public_session_identifiers.sql +16 -0
- package/migrations/030_global_configuration_catalog.sql +39 -0
- package/migrations/031_monotonic_updated_at.sql +28 -0
- package/package.json +2 -2
- package/dist/lib/data-import-plan.d.ts +0 -50
- package/dist/lib/data-import-plan.d.ts.map +0 -1
- package/dist/lib/data-import-plan.js +0 -235
- package/dist/lib/data-import-plan.js.map +0 -1
- package/dist/lib/data-import.d.ts +0 -276
- package/dist/lib/data-import.d.ts.map +0 -1
- package/dist/lib/data-import.js +0 -1694
- package/dist/lib/data-import.js.map +0 -1
|
@@ -29,12 +29,21 @@ import type { Permission, CreatePermissionInput, UpdatePermissionInput } from '.
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function insertPermission(input: CreatePermissionInput): Promise<Permission>;
|
|
31
31
|
/**
|
|
32
|
-
* Find a permission
|
|
32
|
+
* Find a permission through its authoritative application parent.
|
|
33
33
|
*
|
|
34
|
+
* @param applicationId - Parent application UUID
|
|
34
35
|
* @param id - Permission UUID
|
|
35
36
|
* @returns Permission or null if not found
|
|
36
37
|
*/
|
|
37
|
-
export declare function findPermissionById(id: string): Promise<Permission | null>;
|
|
38
|
+
export declare function findPermissionById(applicationId: string, id: string): Promise<Permission | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Lock and return a permission through its authoritative application parent.
|
|
41
|
+
*
|
|
42
|
+
* @param applicationId - Parent application UUID
|
|
43
|
+
* @param id - Permission UUID
|
|
44
|
+
* @returns Locked permission or null when the parent-child pair does not exist
|
|
45
|
+
*/
|
|
46
|
+
export declare function lockPermissionById(applicationId: string, id: string): Promise<Permission | null>;
|
|
38
47
|
/**
|
|
39
48
|
* Find a permission by application ID and slug.
|
|
40
49
|
*
|
|
@@ -49,22 +58,40 @@ export declare function findPermissionBySlug(applicationId: string, slug: string
|
|
|
49
58
|
* Only explicitly provided fields (not undefined) are included in the
|
|
50
59
|
* UPDATE statement. Null is a valid value for description (clears it).
|
|
51
60
|
*
|
|
61
|
+
* @param applicationId - Parent application UUID
|
|
52
62
|
* @param id - Permission UUID
|
|
53
63
|
* @param input - Fields to update (name, description only)
|
|
54
64
|
* @returns Updated permission
|
|
55
65
|
* @throws Error if permission not found or no fields provided
|
|
56
66
|
*/
|
|
57
|
-
export declare function updatePermission(id: string, input: UpdatePermissionInput): Promise<Permission>;
|
|
67
|
+
export declare function updatePermission(applicationId: string, id: string, input: UpdatePermissionInput): Promise<Permission>;
|
|
58
68
|
/**
|
|
59
|
-
*
|
|
69
|
+
* Check whether a module belongs to an application before permission creation.
|
|
60
70
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
71
|
+
* The parent predicate prevents a globally valid module UUID from being attached
|
|
72
|
+
* to a permission owned by another application.
|
|
63
73
|
*
|
|
64
|
-
* @param
|
|
65
|
-
* @
|
|
74
|
+
* @param applicationId - Parent application UUID
|
|
75
|
+
* @param moduleId - Module UUID supplied by the permission request
|
|
76
|
+
* @returns True when the module exists beneath the application
|
|
66
77
|
*/
|
|
67
|
-
export declare function
|
|
78
|
+
export declare function lockPermissionModule(applicationId: string, moduleId: string): Promise<boolean>;
|
|
79
|
+
/** Lock, capture, and delete a permission through its authoritative application parent. */
|
|
80
|
+
export declare function deletePermission(applicationId: string, permissionId: string): Promise<{
|
|
81
|
+
permission: Permission;
|
|
82
|
+
userIds: string[];
|
|
83
|
+
roleIds: string[];
|
|
84
|
+
grantIds: string[];
|
|
85
|
+
} | null>;
|
|
86
|
+
/** Lock and capture a permission without deleting it. */
|
|
87
|
+
export declare function capturePermissionForDeletion(applicationId: string, permissionId: string): Promise<{
|
|
88
|
+
permission: Permission;
|
|
89
|
+
userIds: string[];
|
|
90
|
+
roleIds: string[];
|
|
91
|
+
grantIds: string[];
|
|
92
|
+
} | null>;
|
|
93
|
+
/** Physically delete a permission previously locked through its parent. */
|
|
94
|
+
export declare function deleteCapturedPermission(applicationId: string, permissionId: string): Promise<void>;
|
|
68
95
|
/**
|
|
69
96
|
* List permissions for an application, optionally filtered by module.
|
|
70
97
|
*
|
|
@@ -87,14 +114,4 @@ export declare function listPermissionsByApplication(applicationId: string, modu
|
|
|
87
114
|
* @returns true if the slug already exists
|
|
88
115
|
*/
|
|
89
116
|
export declare function permissionSlugExists(applicationId: string, slug: string): Promise<boolean>;
|
|
90
|
-
/**
|
|
91
|
-
* Count roles that have a specific permission assigned.
|
|
92
|
-
*
|
|
93
|
-
* Used by the service layer as a deletion guard: if roles have this
|
|
94
|
-
* permission, it cannot be deleted without force=true.
|
|
95
|
-
*
|
|
96
|
-
* @param permissionId - Permission UUID
|
|
97
|
-
* @returns Number of roles with this permission
|
|
98
|
-
*/
|
|
99
|
-
export declare function countRolesWithPermission(permissionId: string): Promise<number>;
|
|
100
117
|
//# sourceMappingURL=permission-repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-repository.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"permission-repository.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EACV,UAAU,EAEV,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAOpB;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBxF;AAMD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQ5B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAQlB;AAMD,2FAA2F;AAC3F,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IACT,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,IAAI,CAAC,CAKR;AAED,yDAAyD;AACzD,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IACT,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,IAAI,CAAC,CAoDR;AAED,2EAA2E;AAC3E,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAKf;AAMD;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAgBvB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhG"}
|
|
@@ -48,18 +48,32 @@ export async function insertPermission(input) {
|
|
|
48
48
|
// Find
|
|
49
49
|
// ---------------------------------------------------------------------------
|
|
50
50
|
/**
|
|
51
|
-
* Find a permission
|
|
51
|
+
* Find a permission through its authoritative application parent.
|
|
52
52
|
*
|
|
53
|
+
* @param applicationId - Parent application UUID
|
|
53
54
|
* @param id - Permission UUID
|
|
54
55
|
* @returns Permission or null if not found
|
|
55
56
|
*/
|
|
56
|
-
export async function findPermissionById(id) {
|
|
57
|
+
export async function findPermissionById(applicationId, id) {
|
|
57
58
|
const pool = getPool();
|
|
58
|
-
const result = await pool.query('SELECT * FROM permissions WHERE id = $
|
|
59
|
+
const result = await pool.query('SELECT * FROM permissions WHERE application_id = $1 AND id = $2', [applicationId, id]);
|
|
59
60
|
if (result.rows.length === 0)
|
|
60
61
|
return null;
|
|
61
62
|
return mapRowToPermission(result.rows[0]);
|
|
62
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Lock and return a permission through its authoritative application parent.
|
|
66
|
+
*
|
|
67
|
+
* @param applicationId - Parent application UUID
|
|
68
|
+
* @param id - Permission UUID
|
|
69
|
+
* @returns Locked permission or null when the parent-child pair does not exist
|
|
70
|
+
*/
|
|
71
|
+
export async function lockPermissionById(applicationId, id) {
|
|
72
|
+
const result = await getPool().query(`SELECT * FROM permissions
|
|
73
|
+
WHERE application_id = $1 AND id = $2
|
|
74
|
+
FOR UPDATE`, [applicationId, id]);
|
|
75
|
+
return result.rows[0] ? mapRowToPermission(result.rows[0]) : null;
|
|
76
|
+
}
|
|
63
77
|
/**
|
|
64
78
|
* Find a permission by application ID and slug.
|
|
65
79
|
*
|
|
@@ -83,17 +97,18 @@ export async function findPermissionBySlug(applicationId, slug) {
|
|
|
83
97
|
* Only explicitly provided fields (not undefined) are included in the
|
|
84
98
|
* UPDATE statement. Null is a valid value for description (clears it).
|
|
85
99
|
*
|
|
100
|
+
* @param applicationId - Parent application UUID
|
|
86
101
|
* @param id - Permission UUID
|
|
87
102
|
* @param input - Fields to update (name, description only)
|
|
88
103
|
* @returns Updated permission
|
|
89
104
|
* @throws Error if permission not found or no fields provided
|
|
90
105
|
*/
|
|
91
|
-
export async function updatePermission(id, input) {
|
|
106
|
+
export async function updatePermission(applicationId, id, input) {
|
|
92
107
|
const pool = getPool();
|
|
93
108
|
// Build dynamic SET clause — only name and description are updatable
|
|
94
109
|
const setClauses = [];
|
|
95
|
-
const values = [id];
|
|
96
|
-
let paramIndex =
|
|
110
|
+
const values = [applicationId, id];
|
|
111
|
+
let paramIndex = 3;
|
|
97
112
|
if (input.name !== undefined) {
|
|
98
113
|
setClauses.push(`name = $${paramIndex}`);
|
|
99
114
|
values.push(input.name);
|
|
@@ -106,29 +121,89 @@ export async function updatePermission(id, input) {
|
|
|
106
121
|
if (setClauses.length === 0) {
|
|
107
122
|
throw new Error('No fields to update');
|
|
108
123
|
}
|
|
109
|
-
const sql = `UPDATE permissions SET ${setClauses.join(', ')}
|
|
124
|
+
const sql = `UPDATE permissions SET ${setClauses.join(', ')}
|
|
125
|
+
WHERE application_id = $1 AND id = $2 RETURNING *`;
|
|
110
126
|
const result = await pool.query(sql, values);
|
|
111
127
|
if (result.rows.length === 0) {
|
|
112
128
|
throw new Error('Permission not found');
|
|
113
129
|
}
|
|
114
130
|
return mapRowToPermission(result.rows[0]);
|
|
115
131
|
}
|
|
116
|
-
// ---------------------------------------------------------------------------
|
|
117
|
-
// Delete
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
132
|
/**
|
|
120
|
-
*
|
|
133
|
+
* Check whether a module belongs to an application before permission creation.
|
|
121
134
|
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
135
|
+
* The parent predicate prevents a globally valid module UUID from being attached
|
|
136
|
+
* to a permission owned by another application.
|
|
124
137
|
*
|
|
125
|
-
* @param
|
|
126
|
-
* @
|
|
138
|
+
* @param applicationId - Parent application UUID
|
|
139
|
+
* @param moduleId - Module UUID supplied by the permission request
|
|
140
|
+
* @returns True when the module exists beneath the application
|
|
127
141
|
*/
|
|
128
|
-
export async function
|
|
142
|
+
export async function lockPermissionModule(applicationId, moduleId) {
|
|
143
|
+
const result = await getPool().query(`SELECT id FROM application_modules
|
|
144
|
+
WHERE application_id = $1 AND id = $2
|
|
145
|
+
FOR KEY SHARE`, [applicationId, moduleId]);
|
|
146
|
+
return result.rows.length === 1;
|
|
147
|
+
}
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Delete
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
/** Lock, capture, and delete a permission through its authoritative application parent. */
|
|
152
|
+
export async function deletePermission(applicationId, permissionId) {
|
|
153
|
+
const capture = await capturePermissionForDeletion(applicationId, permissionId);
|
|
154
|
+
if (!capture)
|
|
155
|
+
return null;
|
|
156
|
+
await deleteCapturedPermission(applicationId, permissionId);
|
|
157
|
+
return capture;
|
|
158
|
+
}
|
|
159
|
+
/** Lock and capture a permission without deleting it. */
|
|
160
|
+
export async function capturePermissionForDeletion(applicationId, permissionId) {
|
|
129
161
|
const pool = getPool();
|
|
130
|
-
const
|
|
131
|
-
|
|
162
|
+
const target = await pool.query(`SELECT * FROM permissions WHERE application_id = $1 AND id = $2 FOR UPDATE`, [applicationId, permissionId]);
|
|
163
|
+
if (!target.rows[0])
|
|
164
|
+
return null;
|
|
165
|
+
await pool.query(`SELECT role.id
|
|
166
|
+
FROM roles role
|
|
167
|
+
JOIN role_permissions mapping ON mapping.role_id = role.id
|
|
168
|
+
WHERE mapping.permission_id = $1
|
|
169
|
+
AND role.application_id = $2
|
|
170
|
+
ORDER BY role.id
|
|
171
|
+
FOR UPDATE OF role`, [permissionId, applicationId]);
|
|
172
|
+
const graph = await pool.query(`WITH affected_roles AS (
|
|
173
|
+
SELECT mapping.role_id
|
|
174
|
+
FROM role_permissions mapping
|
|
175
|
+
JOIN roles role ON role.id = mapping.role_id
|
|
176
|
+
WHERE mapping.permission_id = $1
|
|
177
|
+
AND role.application_id = $2
|
|
178
|
+
), affected_users AS (
|
|
179
|
+
SELECT DISTINCT assignment.user_id FROM user_roles assignment
|
|
180
|
+
WHERE assignment.role_id = ANY(ARRAY(SELECT role_id FROM affected_roles))
|
|
181
|
+
)
|
|
182
|
+
SELECT
|
|
183
|
+
ARRAY(SELECT user_id FROM affected_users ORDER BY user_id) AS user_ids,
|
|
184
|
+
ARRAY(SELECT role_id FROM affected_roles ORDER BY role_id) AS role_ids,
|
|
185
|
+
ARRAY(
|
|
186
|
+
SELECT payload.id FROM oidc_payloads payload
|
|
187
|
+
WHERE payload.type = 'Grant'
|
|
188
|
+
AND payload.payload->>'accountId' = ANY(ARRAY(SELECT user_id::text FROM affected_users))
|
|
189
|
+
AND payload.payload->>'clientId' = ANY(ARRAY(
|
|
190
|
+
SELECT client_id FROM clients WHERE application_id = $2
|
|
191
|
+
))
|
|
192
|
+
ORDER BY payload.id
|
|
193
|
+
) AS grant_ids`, [permissionId, applicationId]);
|
|
194
|
+
return {
|
|
195
|
+
permission: mapRowToPermission(target.rows[0]),
|
|
196
|
+
userIds: graph.rows[0].user_ids,
|
|
197
|
+
roleIds: graph.rows[0].role_ids,
|
|
198
|
+
grantIds: graph.rows[0].grant_ids,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/** Physically delete a permission previously locked through its parent. */
|
|
202
|
+
export async function deleteCapturedPermission(applicationId, permissionId) {
|
|
203
|
+
await getPool().query('DELETE FROM permissions WHERE application_id = $1 AND id = $2', [
|
|
204
|
+
applicationId,
|
|
205
|
+
permissionId,
|
|
206
|
+
]);
|
|
132
207
|
}
|
|
133
208
|
// ---------------------------------------------------------------------------
|
|
134
209
|
// List
|
|
@@ -170,21 +245,4 @@ export async function permissionSlugExists(applicationId, slug) {
|
|
|
170
245
|
const result = await pool.query('SELECT EXISTS(SELECT 1 FROM permissions WHERE application_id = $1 AND slug = $2) as exists', [applicationId, slug]);
|
|
171
246
|
return result.rows[0].exists;
|
|
172
247
|
}
|
|
173
|
-
// ---------------------------------------------------------------------------
|
|
174
|
-
// Role count (deletion guard)
|
|
175
|
-
// ---------------------------------------------------------------------------
|
|
176
|
-
/**
|
|
177
|
-
* Count roles that have a specific permission assigned.
|
|
178
|
-
*
|
|
179
|
-
* Used by the service layer as a deletion guard: if roles have this
|
|
180
|
-
* permission, it cannot be deleted without force=true.
|
|
181
|
-
*
|
|
182
|
-
* @param permissionId - Permission UUID
|
|
183
|
-
* @returns Number of roles with this permission
|
|
184
|
-
*/
|
|
185
|
-
export async function countRolesWithPermission(permissionId) {
|
|
186
|
-
const pool = getPool();
|
|
187
|
-
const result = await pool.query('SELECT COUNT(*)::int as count FROM role_permissions WHERE permission_id = $1', [permissionId]);
|
|
188
|
-
return parseInt(result.rows[0].count, 10);
|
|
189
|
-
}
|
|
190
248
|
//# sourceMappingURL=permission-repository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-repository.js","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"permission-repository.js","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* Orchestrates permission CRUD operations with slug format validation,
|
|
5
5
|
* uniqueness checks, deletion guards, cache management, and audit logging.
|
|
6
6
|
*
|
|
7
|
-
* Permission slugs
|
|
8
|
-
*
|
|
9
|
-
* and description can be updated.
|
|
7
|
+
* Permission slugs are application-defined claim values and are immutable after creation — only
|
|
8
|
+
* name and description can be updated.
|
|
10
9
|
*
|
|
11
10
|
* All write operations follow the pattern:
|
|
12
11
|
* validate → DB operation → cache invalidate → audit log
|
|
@@ -19,8 +18,7 @@ import type { Permission, Role, CreatePermissionInput, UpdatePermissionInput } f
|
|
|
19
18
|
/**
|
|
20
19
|
* Create a new permission for an application.
|
|
21
20
|
*
|
|
22
|
-
* Validates
|
|
23
|
-
* and ensures uniqueness within the application.
|
|
21
|
+
* Validates the exact claim value and ensures uniqueness within the application.
|
|
24
22
|
*
|
|
25
23
|
* @param input - Permission creation data
|
|
26
24
|
* @param actorId - Optional UUID of the admin performing the action
|
|
@@ -31,10 +29,11 @@ export declare function createPermission(input: CreatePermissionInput, actorId?:
|
|
|
31
29
|
/**
|
|
32
30
|
* Find a permission by ID.
|
|
33
31
|
*
|
|
32
|
+
* @param applicationId - Parent application UUID
|
|
34
33
|
* @param id - Permission UUID
|
|
35
34
|
* @returns Permission or null if not found
|
|
36
35
|
*/
|
|
37
|
-
export declare function findPermissionById(id: string): Promise<Permission | null>;
|
|
36
|
+
export declare function findPermissionById(applicationId: string, id: string): Promise<Permission | null>;
|
|
38
37
|
/**
|
|
39
38
|
* Find a permission by application ID and slug.
|
|
40
39
|
*
|
|
@@ -54,32 +53,32 @@ export declare function listPermissionsByApplication(applicationId: string, modu
|
|
|
54
53
|
/**
|
|
55
54
|
* Update a permission by ID (name and description only — slug is immutable).
|
|
56
55
|
*
|
|
56
|
+
* @param applicationId - Parent application UUID
|
|
57
57
|
* @param id - Permission UUID
|
|
58
58
|
* @param input - Fields to update (name, description only)
|
|
59
59
|
* @param actorId - Optional UUID of the admin performing the action
|
|
60
60
|
* @returns Updated permission
|
|
61
61
|
* @throws PermissionNotFoundError if permission doesn't exist
|
|
62
62
|
*/
|
|
63
|
-
export declare function updatePermission(id: string, input: UpdatePermissionInput, actorId?: string): Promise<Permission>;
|
|
63
|
+
export declare function updatePermission(applicationId: string, id: string, input: UpdatePermissionInput, actorId?: string): Promise<Permission>;
|
|
64
64
|
/**
|
|
65
|
-
* Delete a permission
|
|
65
|
+
* Delete a permission through its authoritative application parent.
|
|
66
66
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* @
|
|
72
|
-
* @param force - If true, delete even if assigned to roles
|
|
73
|
-
* @param actorId - Optional UUID of the admin performing the action
|
|
74
|
-
* @throws PermissionNotFoundError if permission doesn't exist
|
|
75
|
-
* @throws RbacValidationError if assigned to roles and force is false
|
|
67
|
+
* @param applicationId - Parent application UUID.
|
|
68
|
+
* @param permissionId - Child permission UUID.
|
|
69
|
+
* @param actorId - Actor identifier used for audit attribution when applicable.
|
|
70
|
+
* @returns Whether the actor must authenticate again
|
|
71
|
+
* @throws PermissionNotFoundError when the permission is absent from the requested boundary.
|
|
76
72
|
*/
|
|
77
|
-
export declare function deletePermission(
|
|
73
|
+
export declare function deletePermission(applicationId: string, permissionId: string, actorId?: string): Promise<{
|
|
74
|
+
reauthenticationRequired: boolean;
|
|
75
|
+
}>;
|
|
78
76
|
/**
|
|
79
77
|
* Get all roles that have a specific permission assigned.
|
|
80
78
|
*
|
|
79
|
+
* @param applicationId - Parent application UUID
|
|
81
80
|
* @param permissionId - Permission UUID
|
|
82
81
|
* @returns Array of roles with this permission
|
|
83
82
|
*/
|
|
84
|
-
export declare function getRolesWithPermission(permissionId: string): Promise<Role[]>;
|
|
83
|
+
export declare function getRolesWithPermission(applicationId: string, permissionId: string): Promise<Role[]>;
|
|
85
84
|
//# sourceMappingURL=permission-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-service.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"permission-service.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAkBH,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAgBjG;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAuCrB;AAMD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE5B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE5B;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,wBAAwB,EAAE,OAAO,CAAA;CAAE,CAAC,CAkChD;AAMD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,EAAE,CAAC,CAIjB"}
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* Orchestrates permission CRUD operations with slug format validation,
|
|
5
5
|
* uniqueness checks, deletion guards, cache management, and audit logging.
|
|
6
6
|
*
|
|
7
|
-
* Permission slugs
|
|
8
|
-
*
|
|
9
|
-
* and description can be updated.
|
|
7
|
+
* Permission slugs are application-defined claim values and are immutable after creation — only
|
|
8
|
+
* name and description can be updated.
|
|
10
9
|
*
|
|
11
10
|
* All write operations follow the pattern:
|
|
12
11
|
* validate → DB operation → cache invalidate → audit log
|
|
@@ -15,20 +14,27 @@
|
|
|
15
14
|
* @see mapping-repository.ts — Role-permission lookups
|
|
16
15
|
* @see cache.ts — Redis cache operations
|
|
17
16
|
*/
|
|
18
|
-
import { insertPermission, findPermissionById as repoFindPermissionById, findPermissionBySlug as repoFindPermissionBySlug, updatePermission as repoUpdatePermission,
|
|
17
|
+
import { insertPermission, findPermissionById as repoFindPermissionById, lockPermissionById, lockPermissionModule, findPermissionBySlug as repoFindPermissionBySlug, updatePermission as repoUpdatePermission, capturePermissionForDeletion, deleteCapturedPermission, listPermissionsByApplication as repoListPermissionsByApplication, permissionSlugExists, } from './permission-repository.js';
|
|
19
18
|
import { getRolesWithPermission as repoGetRolesWithPermission } from './mapping-repository.js';
|
|
20
|
-
import {
|
|
21
|
-
import { validatePermissionSlug } from './slugs.js';
|
|
19
|
+
import { normalizeRbacSlug, validatePermissionSlug } from './slugs.js';
|
|
22
20
|
import { PermissionNotFoundError, RbacValidationError } from './errors.js';
|
|
23
21
|
import { writeAuditLog } from '../lib/audit-log.js';
|
|
22
|
+
import { getDatabaseTransactionClient } from '../lib/database.js';
|
|
23
|
+
import { writeAuditLogInTransaction } from '../lib/audit-log.js';
|
|
24
|
+
import { registerDeletionCleanup } from '../lib/deletion-cleanup.js';
|
|
25
|
+
import { revokeAffectedAuthorityInTransaction } from '../lib/authority-revocation.js';
|
|
26
|
+
import { getApplicationBySlug } from '../applications/service.js';
|
|
27
|
+
import { ALL_ADMIN_PERMISSIONS } from '../lib/admin-permissions.js';
|
|
28
|
+
const PERMISSION_DELETED_EVENT = 'permission.deleted';
|
|
29
|
+
const ADMIN_APPLICATION_SLUG = 'porta-admin';
|
|
30
|
+
const ADMIN_PERMISSION_SLUGS = new Set(ALL_ADMIN_PERMISSIONS);
|
|
24
31
|
// ---------------------------------------------------------------------------
|
|
25
32
|
// Create
|
|
26
33
|
// ---------------------------------------------------------------------------
|
|
27
34
|
/**
|
|
28
35
|
* Create a new permission for an application.
|
|
29
36
|
*
|
|
30
|
-
* Validates
|
|
31
|
-
* and ensures uniqueness within the application.
|
|
37
|
+
* Validates the exact claim value and ensures uniqueness within the application.
|
|
32
38
|
*
|
|
33
39
|
* @param input - Permission creation data
|
|
34
40
|
* @param actorId - Optional UUID of the admin performing the action
|
|
@@ -36,17 +42,26 @@ import { writeAuditLog } from '../lib/audit-log.js';
|
|
|
36
42
|
* @throws RbacValidationError if slug format is invalid or already exists
|
|
37
43
|
*/
|
|
38
44
|
export async function createPermission(input, actorId) {
|
|
39
|
-
|
|
40
|
-
if (!validatePermissionSlug(
|
|
41
|
-
throw new RbacValidationError(
|
|
45
|
+
const slug = normalizeRbacSlug(input.slug);
|
|
46
|
+
if (!validatePermissionSlug(slug)) {
|
|
47
|
+
throw new RbacValidationError('Invalid permission slug. Must be 1-150 characters without control characters.');
|
|
48
|
+
}
|
|
49
|
+
await guardCanonicalAdminPermission(input.applicationId, slug);
|
|
50
|
+
if (input.moduleId) {
|
|
51
|
+
if (!getDatabaseTransactionClient()) {
|
|
52
|
+
throw new Error('Permission module validation requires an active database transaction');
|
|
53
|
+
}
|
|
54
|
+
if (!(await lockPermissionModule(input.applicationId, input.moduleId))) {
|
|
55
|
+
throw new RbacValidationError('Permission module must belong to the selected application');
|
|
56
|
+
}
|
|
42
57
|
}
|
|
43
58
|
// Check slug uniqueness within the application
|
|
44
|
-
const exists = await permissionSlugExists(input.applicationId,
|
|
59
|
+
const exists = await permissionSlugExists(input.applicationId, slug);
|
|
45
60
|
if (exists) {
|
|
46
|
-
throw new RbacValidationError(`Permission slug "${
|
|
61
|
+
throw new RbacValidationError(`Permission slug "${slug}" already exists for this application.`);
|
|
47
62
|
}
|
|
48
63
|
// Insert the permission
|
|
49
|
-
const permission = await insertPermission(input);
|
|
64
|
+
const permission = await insertPermission({ ...input, slug });
|
|
50
65
|
// Audit log (fire-and-forget)
|
|
51
66
|
void writeAuditLog({
|
|
52
67
|
eventType: 'permission.created',
|
|
@@ -66,11 +81,12 @@ export async function createPermission(input, actorId) {
|
|
|
66
81
|
/**
|
|
67
82
|
* Find a permission by ID.
|
|
68
83
|
*
|
|
84
|
+
* @param applicationId - Parent application UUID
|
|
69
85
|
* @param id - Permission UUID
|
|
70
86
|
* @returns Permission or null if not found
|
|
71
87
|
*/
|
|
72
|
-
export async function findPermissionById(id) {
|
|
73
|
-
return repoFindPermissionById(id);
|
|
88
|
+
export async function findPermissionById(applicationId, id) {
|
|
89
|
+
return repoFindPermissionById(applicationId, id);
|
|
74
90
|
}
|
|
75
91
|
/**
|
|
76
92
|
* Find a permission by application ID and slug.
|
|
@@ -98,26 +114,34 @@ export async function listPermissionsByApplication(applicationId, moduleId) {
|
|
|
98
114
|
/**
|
|
99
115
|
* Update a permission by ID (name and description only — slug is immutable).
|
|
100
116
|
*
|
|
117
|
+
* @param applicationId - Parent application UUID
|
|
101
118
|
* @param id - Permission UUID
|
|
102
119
|
* @param input - Fields to update (name, description only)
|
|
103
120
|
* @param actorId - Optional UUID of the admin performing the action
|
|
104
121
|
* @returns Updated permission
|
|
105
122
|
* @throws PermissionNotFoundError if permission doesn't exist
|
|
106
123
|
*/
|
|
107
|
-
export async function updatePermission(id, input, actorId) {
|
|
108
|
-
|
|
109
|
-
|
|
124
|
+
export async function updatePermission(applicationId, id, input, actorId) {
|
|
125
|
+
if (!getDatabaseTransactionClient()) {
|
|
126
|
+
throw new Error('Permission update requires an active database transaction');
|
|
127
|
+
}
|
|
128
|
+
const existing = await lockPermissionById(applicationId, id);
|
|
110
129
|
if (!existing) {
|
|
111
130
|
throw new PermissionNotFoundError(id);
|
|
112
131
|
}
|
|
132
|
+
await guardCanonicalAdminPermission(applicationId, existing.slug);
|
|
133
|
+
const changed = (input.name !== undefined && input.name !== existing.name) ||
|
|
134
|
+
(input.description !== undefined && input.description !== existing.description);
|
|
135
|
+
if (!changed)
|
|
136
|
+
return existing;
|
|
113
137
|
// Perform the update (slug is not updatable at the repository level)
|
|
114
|
-
const updated = await repoUpdatePermission(id, input);
|
|
138
|
+
const updated = await repoUpdatePermission(applicationId, id, input);
|
|
115
139
|
// Audit log (fire-and-forget)
|
|
116
140
|
void writeAuditLog({
|
|
117
141
|
eventType: 'permission.updated',
|
|
118
142
|
eventCategory: 'admin',
|
|
119
143
|
actorId,
|
|
120
|
-
metadata: { permissionId: id, changes: input },
|
|
144
|
+
metadata: { applicationId, permissionId: id, changes: input },
|
|
121
145
|
});
|
|
122
146
|
return updated;
|
|
123
147
|
}
|
|
@@ -125,44 +149,50 @@ export async function updatePermission(id, input, actorId) {
|
|
|
125
149
|
// Delete
|
|
126
150
|
// ---------------------------------------------------------------------------
|
|
127
151
|
/**
|
|
128
|
-
* Delete a permission
|
|
129
|
-
*
|
|
130
|
-
* By default (force=false), refuses to delete permissions that are
|
|
131
|
-
* assigned to any role. Pass force=true to delete regardless —
|
|
132
|
-
* CASCADE will remove role_permissions entries.
|
|
152
|
+
* Delete a permission through its authoritative application parent.
|
|
133
153
|
*
|
|
134
|
-
* @param
|
|
135
|
-
* @param
|
|
136
|
-
* @param actorId -
|
|
137
|
-
* @
|
|
138
|
-
* @throws
|
|
154
|
+
* @param applicationId - Parent application UUID.
|
|
155
|
+
* @param permissionId - Child permission UUID.
|
|
156
|
+
* @param actorId - Actor identifier used for audit attribution when applicable.
|
|
157
|
+
* @returns Whether the actor must authenticate again
|
|
158
|
+
* @throws PermissionNotFoundError when the permission is absent from the requested boundary.
|
|
139
159
|
*/
|
|
140
|
-
export async function deletePermission(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
throw new RbacValidationError(`Cannot delete permission "${existing.slug}": assigned to ${roleCount} role(s). Use force=true to override.`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
// Delete the permission (CASCADE handles related records)
|
|
154
|
-
await repoDeletePermission(id);
|
|
155
|
-
// Invalidate user caches — permissions may have changed for users who had this
|
|
156
|
-
if (force) {
|
|
157
|
-
await invalidateAllUserRbacCaches();
|
|
158
|
-
}
|
|
159
|
-
// Audit log (fire-and-forget)
|
|
160
|
-
void writeAuditLog({
|
|
161
|
-
eventType: 'permission.deleted',
|
|
162
|
-
eventCategory: 'admin',
|
|
160
|
+
export async function deletePermission(applicationId, permissionId, actorId) {
|
|
161
|
+
const transaction = getDatabaseTransactionClient();
|
|
162
|
+
if (!transaction)
|
|
163
|
+
throw new Error('Permission deletion requires an active database transaction');
|
|
164
|
+
const capture = await capturePermissionForDeletion(applicationId, permissionId);
|
|
165
|
+
if (!capture)
|
|
166
|
+
throw new PermissionNotFoundError(permissionId);
|
|
167
|
+
await guardCanonicalAdminPermission(applicationId, capture.permission.slug);
|
|
168
|
+
const revoked = await revokeAffectedAuthorityInTransaction(capture.userIds);
|
|
169
|
+
await writeAuditLogInTransaction(transaction, {
|
|
163
170
|
actorId,
|
|
164
|
-
|
|
171
|
+
eventType: PERMISSION_DELETED_EVENT,
|
|
172
|
+
eventCategory: 'admin',
|
|
173
|
+
metadata: {
|
|
174
|
+
applicationId,
|
|
175
|
+
permissionId,
|
|
176
|
+
slug: capture.permission.slug,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
await deleteCapturedPermission(applicationId, permissionId);
|
|
180
|
+
await registerDeletionCleanup({
|
|
181
|
+
resource: 'permission',
|
|
182
|
+
targetId: permissionId,
|
|
183
|
+
parentId: applicationId,
|
|
184
|
+
userIds: capture.userIds,
|
|
185
|
+
clientIds: [],
|
|
186
|
+
publicClientIds: [],
|
|
187
|
+
grantIds: revoked.grantIds,
|
|
188
|
+
roleIds: capture.roleIds,
|
|
189
|
+
permissionIds: [permissionId],
|
|
190
|
+
claimIds: [],
|
|
191
|
+
applicationIds: [applicationId],
|
|
165
192
|
});
|
|
193
|
+
return {
|
|
194
|
+
reauthenticationRequired: actorId !== undefined && capture.userIds.includes(actorId),
|
|
195
|
+
};
|
|
166
196
|
}
|
|
167
197
|
// ---------------------------------------------------------------------------
|
|
168
198
|
// Role lookups
|
|
@@ -170,10 +200,23 @@ export async function deletePermission(id, force = false, actorId) {
|
|
|
170
200
|
/**
|
|
171
201
|
* Get all roles that have a specific permission assigned.
|
|
172
202
|
*
|
|
203
|
+
* @param applicationId - Parent application UUID
|
|
173
204
|
* @param permissionId - Permission UUID
|
|
174
205
|
* @returns Array of roles with this permission
|
|
175
206
|
*/
|
|
176
|
-
export async function getRolesWithPermission(permissionId) {
|
|
177
|
-
|
|
207
|
+
export async function getRolesWithPermission(applicationId, permissionId) {
|
|
208
|
+
const permission = await repoFindPermissionById(applicationId, permissionId);
|
|
209
|
+
if (!permission)
|
|
210
|
+
throw new PermissionNotFoundError(permissionId);
|
|
211
|
+
return repoGetRolesWithPermission(applicationId, permissionId);
|
|
212
|
+
}
|
|
213
|
+
/** Reject generic creation or mutation of canonical Porta Admin permissions. */
|
|
214
|
+
async function guardCanonicalAdminPermission(applicationId, permissionSlug) {
|
|
215
|
+
if (!ADMIN_PERMISSION_SLUGS.has(permissionSlug))
|
|
216
|
+
return;
|
|
217
|
+
const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
|
|
218
|
+
if (adminApplication?.id === applicationId) {
|
|
219
|
+
throw new RbacValidationError('Canonical Porta Admin permissions cannot be modified');
|
|
220
|
+
}
|
|
178
221
|
}
|
|
179
222
|
//# sourceMappingURL=permission-service.js.map
|