@portaidentity/server 1.7.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 +11 -0
- package/LICENSE +21 -0
- package/README.md +33 -0
- package/dist/applications/cache.d.ts +64 -0
- package/dist/applications/cache.d.ts.map +1 -0
- package/dist/applications/cache.js +161 -0
- package/dist/applications/cache.js.map +1 -0
- package/dist/applications/errors.d.ts +25 -0
- package/dist/applications/errors.d.ts.map +1 -0
- package/dist/applications/errors.js +31 -0
- package/dist/applications/errors.js.map +1 -0
- package/dist/applications/index.d.ts +17 -0
- package/dist/applications/index.d.ts.map +1 -0
- package/dist/applications/index.js +19 -0
- package/dist/applications/index.js.map +1 -0
- package/dist/applications/repository.d.ts +184 -0
- package/dist/applications/repository.d.ts.map +1 -0
- package/dist/applications/repository.js +367 -0
- package/dist/applications/repository.js.map +1 -0
- package/dist/applications/service.d.ts +160 -0
- package/dist/applications/service.d.ts.map +1 -0
- package/dist/applications/service.js +388 -0
- package/dist/applications/service.js.map +1 -0
- package/dist/applications/slugs.d.ts +61 -0
- package/dist/applications/slugs.d.ts.map +1 -0
- package/dist/applications/slugs.js +115 -0
- package/dist/applications/slugs.js.map +1 -0
- package/dist/applications/types.d.ts +129 -0
- package/dist/applications/types.d.ts.map +1 -0
- package/dist/applications/types.js +62 -0
- package/dist/applications/types.js.map +1 -0
- package/dist/auth/csrf.d.ts +71 -0
- package/dist/auth/csrf.d.ts.map +1 -0
- package/dist/auth/csrf.js +112 -0
- package/dist/auth/csrf.js.map +1 -0
- package/dist/auth/email-renderer.d.ts +37 -0
- package/dist/auth/email-renderer.d.ts.map +1 -0
- package/dist/auth/email-renderer.js +116 -0
- package/dist/auth/email-renderer.js.map +1 -0
- package/dist/auth/email-service.d.ts +154 -0
- package/dist/auth/email-service.d.ts.map +1 -0
- package/dist/auth/email-service.js +415 -0
- package/dist/auth/email-service.js.map +1 -0
- package/dist/auth/email-transport.d.ts +65 -0
- package/dist/auth/email-transport.d.ts.map +1 -0
- package/dist/auth/email-transport.js +82 -0
- package/dist/auth/email-transport.js.map +1 -0
- package/dist/auth/i18n.d.ts +81 -0
- package/dist/auth/i18n.d.ts.map +1 -0
- package/dist/auth/i18n.js +395 -0
- package/dist/auth/i18n.js.map +1 -0
- package/dist/auth/index.d.ts +28 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +31 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/interaction-authority.d.ts +39 -0
- package/dist/auth/interaction-authority.d.ts.map +1 -0
- package/dist/auth/interaction-authority.js +30 -0
- package/dist/auth/interaction-authority.js.map +1 -0
- package/dist/auth/magic-link-session.d.ts +81 -0
- package/dist/auth/magic-link-session.d.ts.map +1 -0
- package/dist/auth/magic-link-session.js +183 -0
- package/dist/auth/magic-link-session.js.map +1 -0
- package/dist/auth/rate-limiter.d.ts +143 -0
- package/dist/auth/rate-limiter.d.ts.map +1 -0
- package/dist/auth/rate-limiter.js +220 -0
- package/dist/auth/rate-limiter.js.map +1 -0
- package/dist/auth/recovery-crypto.d.ts +34 -0
- package/dist/auth/recovery-crypto.d.ts.map +1 -0
- package/dist/auth/recovery-crypto.js +103 -0
- package/dist/auth/recovery-crypto.js.map +1 -0
- package/dist/auth/recovery-job-processor.d.ts +24 -0
- package/dist/auth/recovery-job-processor.d.ts.map +1 -0
- package/dist/auth/recovery-job-processor.js +123 -0
- package/dist/auth/recovery-job-processor.js.map +1 -0
- package/dist/auth/recovery-job-repository.d.ts +219 -0
- package/dist/auth/recovery-job-repository.d.ts.map +1 -0
- package/dist/auth/recovery-job-repository.js +340 -0
- package/dist/auth/recovery-job-repository.js.map +1 -0
- package/dist/auth/recovery-service.d.ts +27 -0
- package/dist/auth/recovery-service.d.ts.map +1 -0
- package/dist/auth/recovery-service.js +53 -0
- package/dist/auth/recovery-service.js.map +1 -0
- package/dist/auth/recovery-worker.d.ts +158 -0
- package/dist/auth/recovery-worker.d.ts.map +1 -0
- package/dist/auth/recovery-worker.js +306 -0
- package/dist/auth/recovery-worker.js.map +1 -0
- package/dist/auth/template-engine.d.ts +134 -0
- package/dist/auth/template-engine.d.ts.map +1 -0
- package/dist/auth/template-engine.js +225 -0
- package/dist/auth/template-engine.js.map +1 -0
- package/dist/auth/token-repository.d.ts +238 -0
- package/dist/auth/token-repository.d.ts.map +1 -0
- package/dist/auth/token-repository.js +475 -0
- package/dist/auth/token-repository.js.map +1 -0
- package/dist/auth/tokens.d.ts +45 -0
- package/dist/auth/tokens.d.ts.map +1 -0
- package/dist/auth/tokens.js +51 -0
- package/dist/auth/tokens.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +55 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +90 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/commands/health.d.ts +20 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +80 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/init.d.ts +48 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +349 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +19 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +88 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/seed.d.ts +19 -0
- package/dist/cli/commands/seed.d.ts.map +1 -0
- package/dist/cli/commands/seed.js +71 -0
- package/dist/cli/commands/seed.js.map +1 -0
- package/dist/cli/commands/user-2fa.d.ts +29 -0
- package/dist/cli/commands/user-2fa.d.ts.map +1 -0
- package/dist/cli/commands/user-2fa.js +113 -0
- package/dist/cli/commands/user-2fa.js.map +1 -0
- package/dist/cli/error-handler.d.ts +31 -0
- package/dist/cli/error-handler.d.ts.map +1 -0
- package/dist/cli/error-handler.js +65 -0
- package/dist/cli/error-handler.js.map +1 -0
- package/dist/cli/index.d.ts +48 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output.d.ts +94 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +124 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/prompt.d.ts +48 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +96 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/clients/cache.d.ts +63 -0
- package/dist/clients/cache.d.ts.map +1 -0
- package/dist/clients/cache.js +160 -0
- package/dist/clients/cache.js.map +1 -0
- package/dist/clients/crypto.d.ts +69 -0
- package/dist/clients/crypto.d.ts.map +1 -0
- package/dist/clients/crypto.js +83 -0
- package/dist/clients/crypto.js.map +1 -0
- package/dist/clients/errors.d.ts +27 -0
- package/dist/clients/errors.d.ts.map +1 -0
- package/dist/clients/errors.js +33 -0
- package/dist/clients/errors.js.map +1 -0
- package/dist/clients/index.d.ts +19 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +23 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/repository.d.ts +161 -0
- package/dist/clients/repository.d.ts.map +1 -0
- package/dist/clients/repository.js +318 -0
- package/dist/clients/repository.js.map +1 -0
- package/dist/clients/resolve-login-methods.d.ts +74 -0
- package/dist/clients/resolve-login-methods.d.ts.map +1 -0
- package/dist/clients/resolve-login-methods.js +68 -0
- package/dist/clients/resolve-login-methods.js.map +1 -0
- package/dist/clients/secret-repository.d.ts +109 -0
- package/dist/clients/secret-repository.d.ts.map +1 -0
- package/dist/clients/secret-repository.js +166 -0
- package/dist/clients/secret-repository.js.map +1 -0
- package/dist/clients/secret-service.d.ts +87 -0
- package/dist/clients/secret-service.d.ts.map +1 -0
- package/dist/clients/secret-service.js +204 -0
- package/dist/clients/secret-service.js.map +1 -0
- package/dist/clients/service.d.ts +158 -0
- package/dist/clients/service.d.ts.map +1 -0
- package/dist/clients/service.js +523 -0
- package/dist/clients/service.js.map +1 -0
- package/dist/clients/types.d.ts +214 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +77 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/clients/validators.d.ts +87 -0
- package/dist/clients/validators.d.ts.map +1 -0
- package/dist/clients/validators.js +164 -0
- package/dist/clients/validators.js.map +1 -0
- package/dist/config/index.d.ts +23 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +52 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +35 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +167 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/custom-claims/cache.d.ts +48 -0
- package/dist/custom-claims/cache.d.ts.map +1 -0
- package/dist/custom-claims/cache.js +122 -0
- package/dist/custom-claims/cache.js.map +1 -0
- package/dist/custom-claims/errors.d.ts +25 -0
- package/dist/custom-claims/errors.d.ts.map +1 -0
- package/dist/custom-claims/errors.js +31 -0
- package/dist/custom-claims/errors.js.map +1 -0
- package/dist/custom-claims/index.d.ts +14 -0
- package/dist/custom-claims/index.d.ts.map +1 -0
- package/dist/custom-claims/index.js +17 -0
- package/dist/custom-claims/index.js.map +1 -0
- package/dist/custom-claims/repository.d.ts +147 -0
- package/dist/custom-claims/repository.d.ts.map +1 -0
- package/dist/custom-claims/repository.js +338 -0
- package/dist/custom-claims/repository.js.map +1 -0
- package/dist/custom-claims/service.d.ts +129 -0
- package/dist/custom-claims/service.d.ts.map +1 -0
- package/dist/custom-claims/service.js +296 -0
- package/dist/custom-claims/service.js.map +1 -0
- package/dist/custom-claims/types.d.ts +132 -0
- package/dist/custom-claims/types.d.ts.map +1 -0
- package/dist/custom-claims/types.js +61 -0
- package/dist/custom-claims/types.js.map +1 -0
- package/dist/custom-claims/validators.d.ts +61 -0
- package/dist/custom-claims/validators.d.ts.map +1 -0
- package/dist/custom-claims/validators.js +136 -0
- package/dist/custom-claims/validators.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/admin-permissions.d.ts +147 -0
- package/dist/lib/admin-permissions.d.ts.map +1 -0
- package/dist/lib/admin-permissions.js +261 -0
- package/dist/lib/admin-permissions.js.map +1 -0
- package/dist/lib/audit-log.d.ts +45 -0
- package/dist/lib/audit-log.d.ts.map +1 -0
- package/dist/lib/audit-log.js +79 -0
- package/dist/lib/audit-log.js.map +1 -0
- package/dist/lib/branding-assets.d.ts +47 -0
- package/dist/lib/branding-assets.d.ts.map +1 -0
- package/dist/lib/branding-assets.js +93 -0
- package/dist/lib/branding-assets.js.map +1 -0
- package/dist/lib/bulk-operations.d.ts +54 -0
- package/dist/lib/bulk-operations.d.ts.map +1 -0
- package/dist/lib/bulk-operations.js +201 -0
- package/dist/lib/bulk-operations.js.map +1 -0
- package/dist/lib/cursor.d.ts +110 -0
- package/dist/lib/cursor.d.ts.map +1 -0
- package/dist/lib/cursor.js +115 -0
- package/dist/lib/cursor.js.map +1 -0
- package/dist/lib/data-export.d.ts +67 -0
- package/dist/lib/data-export.d.ts.map +1 -0
- package/dist/lib/data-export.js +272 -0
- package/dist/lib/data-export.js.map +1 -0
- package/dist/lib/data-import-plan.d.ts +50 -0
- package/dist/lib/data-import-plan.d.ts.map +1 -0
- package/dist/lib/data-import-plan.js +235 -0
- package/dist/lib/data-import-plan.js.map +1 -0
- package/dist/lib/data-import.d.ts +276 -0
- package/dist/lib/data-import.d.ts.map +1 -0
- package/dist/lib/data-import.js +1694 -0
- package/dist/lib/data-import.js.map +1 -0
- package/dist/lib/database.d.ts +22 -0
- package/dist/lib/database.d.ts.map +1 -0
- package/dist/lib/database.js +103 -0
- package/dist/lib/database.js.map +1 -0
- package/dist/lib/entity-history.d.ts +52 -0
- package/dist/lib/entity-history.d.ts.map +1 -0
- package/dist/lib/entity-history.js +121 -0
- package/dist/lib/entity-history.js.map +1 -0
- package/dist/lib/etag.d.ts +92 -0
- package/dist/lib/etag.d.ts.map +1 -0
- package/dist/lib/etag.js +155 -0
- package/dist/lib/etag.js.map +1 -0
- package/dist/lib/image-validator.d.ts +44 -0
- package/dist/lib/image-validator.d.ts.map +1 -0
- package/dist/lib/image-validator.js +204 -0
- package/dist/lib/image-validator.js.map +1 -0
- package/dist/lib/logger.d.ts +15 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +84 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/migrator.d.ts +14 -0
- package/dist/lib/migrator.d.ts.map +1 -0
- package/dist/lib/migrator.js +34 -0
- package/dist/lib/migrator.js.map +1 -0
- package/dist/lib/redis.d.ts +5 -0
- package/dist/lib/redis.d.ts.map +1 -0
- package/dist/lib/redis.js +29 -0
- package/dist/lib/redis.js.map +1 -0
- package/dist/lib/runtime-paths.d.ts +38 -0
- package/dist/lib/runtime-paths.d.ts.map +1 -0
- package/dist/lib/runtime-paths.js +50 -0
- package/dist/lib/runtime-paths.js.map +1 -0
- package/dist/lib/session-tracking.d.ts +81 -0
- package/dist/lib/session-tracking.d.ts.map +1 -0
- package/dist/lib/session-tracking.js +145 -0
- package/dist/lib/session-tracking.js.map +1 -0
- package/dist/lib/signing-key-crypto.d.ts +53 -0
- package/dist/lib/signing-key-crypto.d.ts.map +1 -0
- package/dist/lib/signing-key-crypto.js +108 -0
- package/dist/lib/signing-key-crypto.js.map +1 -0
- package/dist/lib/signing-keys.d.ts +141 -0
- package/dist/lib/signing-keys.d.ts.map +1 -0
- package/dist/lib/signing-keys.js +206 -0
- package/dist/lib/signing-keys.js.map +1 -0
- package/dist/lib/stats.d.ts +83 -0
- package/dist/lib/stats.d.ts.map +1 -0
- package/dist/lib/stats.js +187 -0
- package/dist/lib/stats.js.map +1 -0
- package/dist/lib/super-admin-protection.d.ts +69 -0
- package/dist/lib/super-admin-protection.d.ts.map +1 -0
- package/dist/lib/super-admin-protection.js +102 -0
- package/dist/lib/super-admin-protection.js.map +1 -0
- package/dist/lib/system-config.d.ts +79 -0
- package/dist/lib/system-config.d.ts.map +1 -0
- package/dist/lib/system-config.js +159 -0
- package/dist/lib/system-config.js.map +1 -0
- package/dist/middleware/admin-auth.d.ts +100 -0
- package/dist/middleware/admin-auth.d.ts.map +1 -0
- package/dist/middleware/admin-auth.js +241 -0
- package/dist/middleware/admin-auth.js.map +1 -0
- package/dist/middleware/admin-cors.d.ts +41 -0
- package/dist/middleware/admin-cors.d.ts.map +1 -0
- package/dist/middleware/admin-cors.js +83 -0
- package/dist/middleware/admin-cors.js.map +1 -0
- package/dist/middleware/admin-mutation-audit.d.ts +9 -0
- package/dist/middleware/admin-mutation-audit.d.ts.map +1 -0
- package/dist/middleware/admin-mutation-audit.js +76 -0
- package/dist/middleware/admin-mutation-audit.js.map +1 -0
- package/dist/middleware/admin-rate-limiter.d.ts +56 -0
- package/dist/middleware/admin-rate-limiter.d.ts.map +1 -0
- package/dist/middleware/admin-rate-limiter.js +97 -0
- package/dist/middleware/admin-rate-limiter.js.map +1 -0
- package/dist/middleware/client-secret-hash.d.ts +34 -0
- package/dist/middleware/client-secret-hash.d.ts.map +1 -0
- package/dist/middleware/client-secret-hash.js +74 -0
- package/dist/middleware/client-secret-hash.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +3 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +93 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/health.d.ts +3 -0
- package/dist/middleware/health.d.ts.map +1 -0
- package/dist/middleware/health.js +35 -0
- package/dist/middleware/health.js.map +1 -0
- package/dist/middleware/metrics.d.ts +40 -0
- package/dist/middleware/metrics.d.ts.map +1 -0
- package/dist/middleware/metrics.js +75 -0
- package/dist/middleware/metrics.js.map +1 -0
- package/dist/middleware/oidc-client-tenant.d.ts +37 -0
- package/dist/middleware/oidc-client-tenant.d.ts.map +1 -0
- package/dist/middleware/oidc-client-tenant.js +156 -0
- package/dist/middleware/oidc-client-tenant.js.map +1 -0
- package/dist/middleware/oidc-cors.d.ts +33 -0
- package/dist/middleware/oidc-cors.d.ts.map +1 -0
- package/dist/middleware/oidc-cors.js +68 -0
- package/dist/middleware/oidc-cors.js.map +1 -0
- package/dist/middleware/oidc-preflight-cors.d.ts +54 -0
- package/dist/middleware/oidc-preflight-cors.d.ts.map +1 -0
- package/dist/middleware/oidc-preflight-cors.js +267 -0
- package/dist/middleware/oidc-preflight-cors.js.map +1 -0
- package/dist/middleware/prompt-login-reset.d.ts +103 -0
- package/dist/middleware/prompt-login-reset.d.ts.map +1 -0
- package/dist/middleware/prompt-login-reset.js +204 -0
- package/dist/middleware/prompt-login-reset.js.map +1 -0
- package/dist/middleware/ready.d.ts +23 -0
- package/dist/middleware/ready.d.ts.map +1 -0
- package/dist/middleware/ready.js +60 -0
- package/dist/middleware/ready.js.map +1 -0
- package/dist/middleware/request-logger.d.ts +27 -0
- package/dist/middleware/request-logger.d.ts.map +1 -0
- package/dist/middleware/request-logger.js +46 -0
- package/dist/middleware/request-logger.js.map +1 -0
- package/dist/middleware/require-permission.d.ts +28 -0
- package/dist/middleware/require-permission.d.ts.map +1 -0
- package/dist/middleware/require-permission.js +63 -0
- package/dist/middleware/require-permission.js.map +1 -0
- package/dist/middleware/require-user-organization.d.ts +18 -0
- package/dist/middleware/require-user-organization.d.ts.map +1 -0
- package/dist/middleware/require-user-organization.js +53 -0
- package/dist/middleware/require-user-organization.js.map +1 -0
- package/dist/middleware/root-page.d.ts +62 -0
- package/dist/middleware/root-page.d.ts.map +1 -0
- package/dist/middleware/root-page.js +134 -0
- package/dist/middleware/root-page.js.map +1 -0
- package/dist/middleware/security-headers.d.ts +98 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +159 -0
- package/dist/middleware/security-headers.js.map +1 -0
- package/dist/middleware/tenant-resolver.d.ts +37 -0
- package/dist/middleware/tenant-resolver.d.ts.map +1 -0
- package/dist/middleware/tenant-resolver.js +71 -0
- package/dist/middleware/tenant-resolver.js.map +1 -0
- package/dist/middleware/token-rate-limiter.d.ts +89 -0
- package/dist/middleware/token-rate-limiter.d.ts.map +1 -0
- package/dist/middleware/token-rate-limiter.js +189 -0
- package/dist/middleware/token-rate-limiter.js.map +1 -0
- package/dist/oidc/account-finder.d.ts +52 -0
- package/dist/oidc/account-finder.d.ts.map +1 -0
- package/dist/oidc/account-finder.js +134 -0
- package/dist/oidc/account-finder.js.map +1 -0
- package/dist/oidc/adapter-factory.d.ts +90 -0
- package/dist/oidc/adapter-factory.d.ts.map +1 -0
- package/dist/oidc/adapter-factory.js +165 -0
- package/dist/oidc/adapter-factory.js.map +1 -0
- package/dist/oidc/configuration.d.ts +155 -0
- package/dist/oidc/configuration.d.ts.map +1 -0
- package/dist/oidc/configuration.js +531 -0
- package/dist/oidc/configuration.js.map +1 -0
- package/dist/oidc/postgres-adapter.d.ts +159 -0
- package/dist/oidc/postgres-adapter.d.ts.map +1 -0
- package/dist/oidc/postgres-adapter.js +222 -0
- package/dist/oidc/postgres-adapter.js.map +1 -0
- package/dist/oidc/protocol-security-observer.d.ts +38 -0
- package/dist/oidc/protocol-security-observer.d.ts.map +1 -0
- package/dist/oidc/protocol-security-observer.js +93 -0
- package/dist/oidc/protocol-security-observer.js.map +1 -0
- package/dist/oidc/provider.d.ts +37 -0
- package/dist/oidc/provider.d.ts.map +1 -0
- package/dist/oidc/provider.js +71 -0
- package/dist/oidc/provider.js.map +1 -0
- package/dist/oidc/redis-adapter.d.ts +140 -0
- package/dist/oidc/redis-adapter.d.ts.map +1 -0
- package/dist/oidc/redis-adapter.js +344 -0
- package/dist/oidc/redis-adapter.js.map +1 -0
- package/dist/organizations/cache.d.ts +60 -0
- package/dist/organizations/cache.d.ts.map +1 -0
- package/dist/organizations/cache.js +157 -0
- package/dist/organizations/cache.js.map +1 -0
- package/dist/organizations/errors.d.ts +25 -0
- package/dist/organizations/errors.d.ts.map +1 -0
- package/dist/organizations/errors.js +31 -0
- package/dist/organizations/errors.js.map +1 -0
- package/dist/organizations/index.d.ts +15 -0
- package/dist/organizations/index.d.ts.map +1 -0
- package/dist/organizations/index.js +15 -0
- package/dist/organizations/index.js.map +1 -0
- package/dist/organizations/repository.d.ts +183 -0
- package/dist/organizations/repository.d.ts.map +1 -0
- package/dist/organizations/repository.js +354 -0
- package/dist/organizations/repository.js.map +1 -0
- package/dist/organizations/service.d.ts +168 -0
- package/dist/organizations/service.d.ts.map +1 -0
- package/dist/organizations/service.js +511 -0
- package/dist/organizations/service.js.map +1 -0
- package/dist/organizations/slugs.d.ts +57 -0
- package/dist/organizations/slugs.d.ts.map +1 -0
- package/dist/organizations/slugs.js +130 -0
- package/dist/organizations/slugs.js.map +1 -0
- package/dist/organizations/types.d.ts +146 -0
- package/dist/organizations/types.d.ts.map +1 -0
- package/dist/organizations/types.js +49 -0
- package/dist/organizations/types.js.map +1 -0
- package/dist/rbac/cache.d.ts +110 -0
- package/dist/rbac/cache.d.ts.map +1 -0
- package/dist/rbac/cache.js +271 -0
- package/dist/rbac/cache.js.map +1 -0
- package/dist/rbac/errors.d.ts +34 -0
- package/dist/rbac/errors.d.ts.map +1 -0
- package/dist/rbac/errors.js +43 -0
- package/dist/rbac/errors.js.map +1 -0
- package/dist/rbac/index.d.ts +17 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +21 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/mapping-repository.d.ts +121 -0
- package/dist/rbac/mapping-repository.d.ts.map +1 -0
- package/dist/rbac/mapping-repository.js +224 -0
- package/dist/rbac/mapping-repository.js.map +1 -0
- package/dist/rbac/permission-repository.d.ts +100 -0
- package/dist/rbac/permission-repository.d.ts.map +1 -0
- package/dist/rbac/permission-repository.js +190 -0
- package/dist/rbac/permission-repository.js.map +1 -0
- package/dist/rbac/permission-service.d.ts +85 -0
- package/dist/rbac/permission-service.d.ts.map +1 -0
- package/dist/rbac/permission-service.js +179 -0
- package/dist/rbac/permission-service.js.map +1 -0
- package/dist/rbac/role-repository.d.ts +104 -0
- package/dist/rbac/role-repository.d.ts.map +1 -0
- package/dist/rbac/role-repository.js +202 -0
- package/dist/rbac/role-repository.js.map +1 -0
- package/dist/rbac/role-service.d.ts +111 -0
- package/dist/rbac/role-service.d.ts.map +1 -0
- package/dist/rbac/role-service.js +256 -0
- package/dist/rbac/role-service.js.map +1 -0
- package/dist/rbac/slugs.d.ts +116 -0
- package/dist/rbac/slugs.d.ts.map +1 -0
- package/dist/rbac/slugs.js +178 -0
- package/dist/rbac/slugs.js.map +1 -0
- package/dist/rbac/types.d.ts +187 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +75 -0
- package/dist/rbac/types.js.map +1 -0
- package/dist/rbac/user-role-service.d.ts +101 -0
- package/dist/rbac/user-role-service.d.ts.map +1 -0
- package/dist/rbac/user-role-service.js +166 -0
- package/dist/rbac/user-role-service.js.map +1 -0
- package/dist/routes/applications.d.ts +40 -0
- package/dist/routes/applications.d.ts.map +1 -0
- package/dist/routes/applications.js +284 -0
- package/dist/routes/applications.js.map +1 -0
- package/dist/routes/audit.d.ts +31 -0
- package/dist/routes/audit.d.ts.map +1 -0
- package/dist/routes/audit.js +140 -0
- package/dist/routes/audit.js.map +1 -0
- package/dist/routes/branding.d.ts +17 -0
- package/dist/routes/branding.d.ts.map +1 -0
- package/dist/routes/branding.js +104 -0
- package/dist/routes/branding.js.map +1 -0
- package/dist/routes/bulk.d.ts +37 -0
- package/dist/routes/bulk.d.ts.map +1 -0
- package/dist/routes/bulk.js +94 -0
- package/dist/routes/bulk.js.map +1 -0
- package/dist/routes/clients.d.ts +44 -0
- package/dist/routes/clients.d.ts.map +1 -0
- package/dist/routes/clients.js +353 -0
- package/dist/routes/clients.js.map +1 -0
- package/dist/routes/config.d.ts +35 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +115 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/custom-claims.d.ts +38 -0
- package/dist/routes/custom-claims.d.ts.map +1 -0
- package/dist/routes/custom-claims.js +208 -0
- package/dist/routes/custom-claims.js.map +1 -0
- package/dist/routes/exports.d.ts +21 -0
- package/dist/routes/exports.d.ts.map +1 -0
- package/dist/routes/exports.js +98 -0
- package/dist/routes/exports.js.map +1 -0
- package/dist/routes/imports.d.ts +18 -0
- package/dist/routes/imports.d.ts.map +1 -0
- package/dist/routes/imports.js +72 -0
- package/dist/routes/imports.js.map +1 -0
- package/dist/routes/interactions.d.ts +111 -0
- package/dist/routes/interactions.d.ts.map +1 -0
- package/dist/routes/interactions.js +1074 -0
- package/dist/routes/interactions.js.map +1 -0
- package/dist/routes/invitation.d.ts +31 -0
- package/dist/routes/invitation.d.ts.map +1 -0
- package/dist/routes/invitation.js +342 -0
- package/dist/routes/invitation.js.map +1 -0
- package/dist/routes/keys.d.ts +28 -0
- package/dist/routes/keys.d.ts.map +1 -0
- package/dist/routes/keys.js +91 -0
- package/dist/routes/keys.js.map +1 -0
- package/dist/routes/magic-link.d.ts +43 -0
- package/dist/routes/magic-link.d.ts.map +1 -0
- package/dist/routes/magic-link.js +264 -0
- package/dist/routes/magic-link.js.map +1 -0
- package/dist/routes/organizations.d.ts +38 -0
- package/dist/routes/organizations.d.ts.map +1 -0
- package/dist/routes/organizations.js +347 -0
- package/dist/routes/organizations.js.map +1 -0
- package/dist/routes/password-reset.d.ts +65 -0
- package/dist/routes/password-reset.d.ts.map +1 -0
- package/dist/routes/password-reset.js +493 -0
- package/dist/routes/password-reset.js.map +1 -0
- package/dist/routes/permissions.d.ts +33 -0
- package/dist/routes/permissions.d.ts.map +1 -0
- package/dist/routes/permissions.js +166 -0
- package/dist/routes/permissions.js.map +1 -0
- package/dist/routes/roles.d.ts +37 -0
- package/dist/routes/roles.d.ts.map +1 -0
- package/dist/routes/roles.js +222 -0
- package/dist/routes/roles.js.map +1 -0
- package/dist/routes/sessions.d.ts +37 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +121 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/stats.d.ts +28 -0
- package/dist/routes/stats.d.ts.map +1 -0
- package/dist/routes/stats.js +65 -0
- package/dist/routes/stats.js.map +1 -0
- package/dist/routes/two-factor-admin.d.ts +54 -0
- package/dist/routes/two-factor-admin.d.ts.map +1 -0
- package/dist/routes/two-factor-admin.js +344 -0
- package/dist/routes/two-factor-admin.js.map +1 -0
- package/dist/routes/two-factor.d.ts +31 -0
- package/dist/routes/two-factor.d.ts.map +1 -0
- package/dist/routes/two-factor.js +595 -0
- package/dist/routes/two-factor.js.map +1 -0
- package/dist/routes/user-roles.d.ts +33 -0
- package/dist/routes/user-roles.d.ts.map +1 -0
- package/dist/routes/user-roles.js +129 -0
- package/dist/routes/user-roles.js.map +1 -0
- package/dist/routes/users.d.ts +61 -0
- package/dist/routes/users.d.ts.map +1 -0
- package/dist/routes/users.js +868 -0
- package/dist/routes/users.js.map +1 -0
- package/dist/security/decision-context.d.ts +52 -0
- package/dist/security/decision-context.d.ts.map +1 -0
- package/dist/security/decision-context.js +150 -0
- package/dist/security/decision-context.js.map +1 -0
- package/dist/security/decision-event.d.ts +128 -0
- package/dist/security/decision-event.d.ts.map +1 -0
- package/dist/security/decision-event.js +225 -0
- package/dist/security/decision-event.js.map +1 -0
- package/dist/security/transport-decision.d.ts +6 -0
- package/dist/security/transport-decision.d.ts.map +1 -0
- package/dist/security/transport-decision.js +37 -0
- package/dist/security/transport-decision.js.map +1 -0
- package/dist/server.d.ts +50 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +491 -0
- package/dist/server.js.map +1 -0
- package/dist/two-factor/cache.d.ts +47 -0
- package/dist/two-factor/cache.d.ts.map +1 -0
- package/dist/two-factor/cache.js +122 -0
- package/dist/two-factor/cache.js.map +1 -0
- package/dist/two-factor/crypto.d.ts +41 -0
- package/dist/two-factor/crypto.d.ts.map +1 -0
- package/dist/two-factor/crypto.js +94 -0
- package/dist/two-factor/crypto.js.map +1 -0
- package/dist/two-factor/errors.d.ts +82 -0
- package/dist/two-factor/errors.d.ts.map +1 -0
- package/dist/two-factor/errors.js +112 -0
- package/dist/two-factor/errors.js.map +1 -0
- package/dist/two-factor/index.d.ts +18 -0
- package/dist/two-factor/index.d.ts.map +1 -0
- package/dist/two-factor/index.js +25 -0
- package/dist/two-factor/index.js.map +1 -0
- package/dist/two-factor/otp.d.ts +43 -0
- package/dist/two-factor/otp.d.ts.map +1 -0
- package/dist/two-factor/otp.js +57 -0
- package/dist/two-factor/otp.js.map +1 -0
- package/dist/two-factor/recovery.d.ts +45 -0
- package/dist/two-factor/recovery.d.ts.map +1 -0
- package/dist/two-factor/recovery.js +104 -0
- package/dist/two-factor/recovery.js.map +1 -0
- package/dist/two-factor/repository.d.ts +156 -0
- package/dist/two-factor/repository.d.ts.map +1 -0
- package/dist/two-factor/repository.js +251 -0
- package/dist/two-factor/repository.js.map +1 -0
- package/dist/two-factor/service.d.ts +232 -0
- package/dist/two-factor/service.d.ts.map +1 -0
- package/dist/two-factor/service.js +599 -0
- package/dist/two-factor/service.js.map +1 -0
- package/dist/two-factor/totp.d.ts +57 -0
- package/dist/two-factor/totp.d.ts.map +1 -0
- package/dist/two-factor/totp.js +96 -0
- package/dist/two-factor/totp.js.map +1 -0
- package/dist/two-factor/types.d.ts +152 -0
- package/dist/two-factor/types.d.ts.map +1 -0
- package/dist/two-factor/types.js +64 -0
- package/dist/two-factor/types.js.map +1 -0
- package/dist/users/cache.d.ts +49 -0
- package/dist/users/cache.d.ts.map +1 -0
- package/dist/users/cache.js +140 -0
- package/dist/users/cache.js.map +1 -0
- package/dist/users/claims.d.ts +67 -0
- package/dist/users/claims.d.ts.map +1 -0
- package/dist/users/claims.js +104 -0
- package/dist/users/claims.js.map +1 -0
- package/dist/users/errors.d.ts +25 -0
- package/dist/users/errors.d.ts.map +1 -0
- package/dist/users/errors.js +31 -0
- package/dist/users/errors.js.map +1 -0
- package/dist/users/gdpr.d.ts +110 -0
- package/dist/users/gdpr.d.ts.map +1 -0
- package/dist/users/gdpr.js +211 -0
- package/dist/users/gdpr.js.map +1 -0
- package/dist/users/index.d.ts +20 -0
- package/dist/users/index.d.ts.map +1 -0
- package/dist/users/index.js +19 -0
- package/dist/users/index.js.map +1 -0
- package/dist/users/password.d.ts +85 -0
- package/dist/users/password.d.ts.map +1 -0
- package/dist/users/password.js +138 -0
- package/dist/users/password.js.map +1 -0
- package/dist/users/repository.d.ts +263 -0
- package/dist/users/repository.d.ts.map +1 -0
- package/dist/users/repository.js +499 -0
- package/dist/users/repository.js.map +1 -0
- package/dist/users/service.d.ts +299 -0
- package/dist/users/service.d.ts.map +1 -0
- package/dist/users/service.js +698 -0
- package/dist/users/service.js.map +1 -0
- package/dist/users/types.d.ts +220 -0
- package/dist/users/types.d.ts.map +1 -0
- package/dist/users/types.js +77 -0
- package/dist/users/types.js.map +1 -0
- package/locales/default/en/common.json +10 -0
- package/locales/default/en/consent.json +13 -0
- package/locales/default/en/emails.json +17 -0
- package/locales/default/en/errors.json +21 -0
- package/locales/default/en/forgot-password.json +11 -0
- package/locales/default/en/invitation.json +18 -0
- package/locales/default/en/login.json +17 -0
- package/locales/default/en/logout.json +9 -0
- package/locales/default/en/magic-link.json +12 -0
- package/locales/default/en/reset-password.json +16 -0
- package/locales/default/en/two-factor.json +29 -0
- package/migrations/.gitkeep +0 -0
- package/migrations/001_extensions.sql +22 -0
- package/migrations/002_organizations.sql +43 -0
- package/migrations/003_applications.sql +50 -0
- package/migrations/004_clients.sql +74 -0
- package/migrations/005_users.sql +119 -0
- package/migrations/006_roles_permissions.sql +80 -0
- package/migrations/007_custom_claims.sql +55 -0
- package/migrations/008_config.sql +51 -0
- package/migrations/009_audit_log.sql +31 -0
- package/migrations/010_oidc_adapter.sql +34 -0
- package/migrations/011_seed.sql +53 -0
- package/migrations/012_two_factor.sql +88 -0
- package/migrations/013_client_secret_sha256.sql +22 -0
- package/migrations/014_login_methods.sql +34 -0
- package/migrations/015_signing_key_encryption.sql +20 -0
- package/migrations/016_failed_login_count.sql +27 -0
- package/migrations/017_audit_retention.sql +11 -0
- package/migrations/018_admin_api_enhancements.sql +78 -0
- package/migrations/019_invitation_details.sql +27 -0
- package/migrations/020_two_factor_admin_permission.sql +108 -0
- package/migrations/021_auth_recovery_jobs.sql +74 -0
- package/migrations/022_recovery_artifact_ownership.sql +25 -0
- package/migrations/023_magic_link_authority.sql +39 -0
- package/package.json +106 -0
- package/templates/default/emails/invitation.hbs +39 -0
- package/templates/default/emails/invitation.txt.hbs +18 -0
- package/templates/default/emails/magic-link.hbs +30 -0
- package/templates/default/emails/magic-link.txt.hbs +11 -0
- package/templates/default/emails/otp-code.hbs +31 -0
- package/templates/default/emails/otp-code.txt.hbs +15 -0
- package/templates/default/emails/password-changed.hbs +24 -0
- package/templates/default/emails/password-changed.txt.hbs +7 -0
- package/templates/default/emails/password-reset.hbs +30 -0
- package/templates/default/emails/password-reset.txt.hbs +11 -0
- package/templates/default/emails/welcome.hbs +25 -0
- package/templates/default/emails/welcome.txt.hbs +9 -0
- package/templates/default/layouts/main.hbs +49 -0
- package/templates/default/pages/accept-invite.hbs +25 -0
- package/templates/default/pages/consent.hbs +27 -0
- package/templates/default/pages/error.hbs +15 -0
- package/templates/default/pages/forgot-password.hbs +21 -0
- package/templates/default/pages/invite-expired.hbs +6 -0
- package/templates/default/pages/invite-success.hbs +9 -0
- package/templates/default/pages/login.hbs +108 -0
- package/templates/default/pages/logout-success.hbs +5 -0
- package/templates/default/pages/logout.hbs +24 -0
- package/templates/default/pages/magic-link-sent.hbs +10 -0
- package/templates/default/pages/magic-link-success.hbs +17 -0
- package/templates/default/pages/reset-password.hbs +20 -0
- package/templates/default/pages/reset-success.hbs +9 -0
- package/templates/default/pages/two-factor-setup.hbs +65 -0
- package/templates/default/pages/two-factor-verify.hbs +77 -0
- package/templates/default/partials/flash-messages.hbs +10 -0
- package/templates/default/partials/footer.hbs +4 -0
- package/templates/default/partials/header.hbs +8 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mapping repository — PostgreSQL data access for RBAC join tables.
|
|
3
|
+
*
|
|
4
|
+
* Handles the role_permissions and user_roles join tables that link:
|
|
5
|
+
* - Roles ↔ Permissions (which permissions a role grants)
|
|
6
|
+
* - Users ↔ Roles (which roles a user has)
|
|
7
|
+
*
|
|
8
|
+
* Key patterns:
|
|
9
|
+
* - Bulk INSERT with ON CONFLICT DO NOTHING for idempotent assignment
|
|
10
|
+
* - Multi-table JOINs for permission resolution through roles
|
|
11
|
+
* - DISTINCT for deduplicated permission lists across multiple roles
|
|
12
|
+
* - Parameterized bulk VALUES lists for safe multi-row operations
|
|
13
|
+
*
|
|
14
|
+
* The permission resolution query (getPermissionsForUser) is the hot path
|
|
15
|
+
* for token claims — it resolves user → roles → permissions in a single query.
|
|
16
|
+
*
|
|
17
|
+
* Database tables: role_permissions, user_roles (see migration 006_roles_permissions.sql)
|
|
18
|
+
*/
|
|
19
|
+
import { getPool } from '../lib/database.js';
|
|
20
|
+
import { mapRowToRole, mapRowToPermission, mapRowToUserRole } from './types.js';
|
|
21
|
+
// ===========================================================================
|
|
22
|
+
// Role-Permission Mapping
|
|
23
|
+
// ===========================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Assign multiple permissions to a role (bulk insert).
|
|
26
|
+
*
|
|
27
|
+
* Uses ON CONFLICT DO NOTHING to make the operation idempotent —
|
|
28
|
+
* already-assigned permissions are silently skipped. This allows
|
|
29
|
+
* callers to assign without checking for existing assignments first.
|
|
30
|
+
*
|
|
31
|
+
* @param roleId - Role UUID
|
|
32
|
+
* @param permissionIds - Array of permission UUIDs to assign
|
|
33
|
+
*/
|
|
34
|
+
export async function assignPermissionsToRole(roleId, permissionIds) {
|
|
35
|
+
if (permissionIds.length === 0)
|
|
36
|
+
return;
|
|
37
|
+
const pool = getPool();
|
|
38
|
+
// Build parameterized VALUES list: ($1, $2), ($1, $3), ($1, $4), ...
|
|
39
|
+
// $1 is always the roleId, subsequent params are permission IDs
|
|
40
|
+
const valuesList = [];
|
|
41
|
+
const params = [roleId];
|
|
42
|
+
for (let i = 0; i < permissionIds.length; i++) {
|
|
43
|
+
params.push(permissionIds[i]);
|
|
44
|
+
valuesList.push(`($1, $${i + 2})`);
|
|
45
|
+
}
|
|
46
|
+
await pool.query(`INSERT INTO role_permissions (role_id, permission_id)
|
|
47
|
+
VALUES ${valuesList.join(', ')}
|
|
48
|
+
ON CONFLICT DO NOTHING`, params);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Remove multiple permissions from a role.
|
|
52
|
+
*
|
|
53
|
+
* Silently succeeds if any of the permission IDs are not currently
|
|
54
|
+
* assigned to the role.
|
|
55
|
+
*
|
|
56
|
+
* @param roleId - Role UUID
|
|
57
|
+
* @param permissionIds - Array of permission UUIDs to remove
|
|
58
|
+
*/
|
|
59
|
+
export async function removePermissionsFromRole(roleId, permissionIds) {
|
|
60
|
+
if (permissionIds.length === 0)
|
|
61
|
+
return;
|
|
62
|
+
const pool = getPool();
|
|
63
|
+
// Build parameterized IN list: $2, $3, $4, ...
|
|
64
|
+
const placeholders = permissionIds.map((_, i) => `$${i + 2}`).join(', ');
|
|
65
|
+
const params = [roleId, ...permissionIds];
|
|
66
|
+
await pool.query(`DELETE FROM role_permissions WHERE role_id = $1 AND permission_id IN (${placeholders})`, params);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get all permissions assigned to a role.
|
|
70
|
+
*
|
|
71
|
+
* JOINs role_permissions with permissions table to return full
|
|
72
|
+
* Permission objects, ordered by slug for consistent output.
|
|
73
|
+
*
|
|
74
|
+
* @param roleId - Role UUID
|
|
75
|
+
* @returns Array of permissions assigned to the role
|
|
76
|
+
*/
|
|
77
|
+
export async function getPermissionsForRole(roleId) {
|
|
78
|
+
const pool = getPool();
|
|
79
|
+
const result = await pool.query(`SELECT p.*
|
|
80
|
+
FROM role_permissions rp
|
|
81
|
+
JOIN permissions p ON p.id = rp.permission_id
|
|
82
|
+
WHERE rp.role_id = $1
|
|
83
|
+
ORDER BY p.slug ASC`, [roleId]);
|
|
84
|
+
return result.rows.map(mapRowToPermission);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get all roles that have a specific permission assigned.
|
|
88
|
+
*
|
|
89
|
+
* JOINs role_permissions with roles table to return full Role objects,
|
|
90
|
+
* ordered by name for consistent output.
|
|
91
|
+
*
|
|
92
|
+
* @param permissionId - Permission UUID
|
|
93
|
+
* @returns Array of roles that have this permission
|
|
94
|
+
*/
|
|
95
|
+
export async function getRolesWithPermission(permissionId) {
|
|
96
|
+
const pool = getPool();
|
|
97
|
+
const result = await pool.query(`SELECT r.*
|
|
98
|
+
FROM role_permissions rp
|
|
99
|
+
JOIN roles r ON r.id = rp.role_id
|
|
100
|
+
WHERE rp.permission_id = $1
|
|
101
|
+
ORDER BY r.name ASC`, [permissionId]);
|
|
102
|
+
return result.rows.map(mapRowToRole);
|
|
103
|
+
}
|
|
104
|
+
// ===========================================================================
|
|
105
|
+
// User-Role Mapping
|
|
106
|
+
// ===========================================================================
|
|
107
|
+
/**
|
|
108
|
+
* Assign multiple roles to a user (bulk insert).
|
|
109
|
+
*
|
|
110
|
+
* Uses ON CONFLICT DO NOTHING to make the operation idempotent —
|
|
111
|
+
* already-assigned roles are silently skipped. Tracks who performed
|
|
112
|
+
* the assignment via the optional assignedBy parameter.
|
|
113
|
+
*
|
|
114
|
+
* @param userId - User UUID
|
|
115
|
+
* @param roleIds - Array of role UUIDs to assign
|
|
116
|
+
* @param assignedBy - Optional UUID of the admin who performed the assignment
|
|
117
|
+
*/
|
|
118
|
+
export async function assignRolesToUser(userId, roleIds, assignedBy) {
|
|
119
|
+
if (roleIds.length === 0)
|
|
120
|
+
return;
|
|
121
|
+
const pool = getPool();
|
|
122
|
+
// Build parameterized VALUES list
|
|
123
|
+
// $1 = userId, $2 = assignedBy (or null), subsequent params = roleIds
|
|
124
|
+
const valuesList = [];
|
|
125
|
+
const params = [userId, assignedBy ?? null];
|
|
126
|
+
for (let i = 0; i < roleIds.length; i++) {
|
|
127
|
+
params.push(roleIds[i]);
|
|
128
|
+
valuesList.push(`($1, $${i + 3}, $2)`);
|
|
129
|
+
}
|
|
130
|
+
await pool.query(`INSERT INTO user_roles (user_id, role_id, assigned_by)
|
|
131
|
+
VALUES ${valuesList.join(', ')}
|
|
132
|
+
ON CONFLICT DO NOTHING`, params);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Remove multiple roles from a user.
|
|
136
|
+
*
|
|
137
|
+
* Silently succeeds if any of the role IDs are not currently
|
|
138
|
+
* assigned to the user.
|
|
139
|
+
*
|
|
140
|
+
* @param userId - User UUID
|
|
141
|
+
* @param roleIds - Array of role UUIDs to remove
|
|
142
|
+
*/
|
|
143
|
+
export async function removeRolesFromUser(userId, roleIds) {
|
|
144
|
+
if (roleIds.length === 0)
|
|
145
|
+
return;
|
|
146
|
+
const pool = getPool();
|
|
147
|
+
// Build parameterized IN list: $2, $3, $4, ...
|
|
148
|
+
const placeholders = roleIds.map((_, i) => `$${i + 2}`).join(', ');
|
|
149
|
+
const params = [userId, ...roleIds];
|
|
150
|
+
await pool.query(`DELETE FROM user_roles WHERE user_id = $1 AND role_id IN (${placeholders})`, params);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get all roles assigned to a user.
|
|
154
|
+
*
|
|
155
|
+
* JOINs user_roles with roles table to return full Role objects,
|
|
156
|
+
* ordered by name for consistent output.
|
|
157
|
+
*
|
|
158
|
+
* @param userId - User UUID
|
|
159
|
+
* @returns Array of roles assigned to the user
|
|
160
|
+
*/
|
|
161
|
+
export async function getRolesForUser(userId) {
|
|
162
|
+
const pool = getPool();
|
|
163
|
+
const result = await pool.query(`SELECT r.*
|
|
164
|
+
FROM user_roles ur
|
|
165
|
+
JOIN roles r ON r.id = ur.role_id
|
|
166
|
+
WHERE ur.user_id = $1
|
|
167
|
+
ORDER BY r.name ASC`, [userId]);
|
|
168
|
+
return result.rows.map(mapRowToRole);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get all permissions for a user, resolved through their assigned roles.
|
|
172
|
+
*
|
|
173
|
+
* This is the hot path for token claims — it resolves the full chain:
|
|
174
|
+
* user_roles → roles → role_permissions → permissions
|
|
175
|
+
* in a single query. Results are deduplicated (DISTINCT) since a user
|
|
176
|
+
* may have the same permission through multiple roles.
|
|
177
|
+
*
|
|
178
|
+
* @param userId - User UUID
|
|
179
|
+
* @returns Deduplicated array of permissions the user has through their roles
|
|
180
|
+
*/
|
|
181
|
+
export async function getPermissionsForUser(userId) {
|
|
182
|
+
const pool = getPool();
|
|
183
|
+
const result = await pool.query(`SELECT DISTINCT p.*
|
|
184
|
+
FROM user_roles ur
|
|
185
|
+
JOIN role_permissions rp ON rp.role_id = ur.role_id
|
|
186
|
+
JOIN permissions p ON p.id = rp.permission_id
|
|
187
|
+
WHERE ur.user_id = $1
|
|
188
|
+
ORDER BY p.slug ASC`, [userId]);
|
|
189
|
+
return result.rows.map(mapRowToPermission);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* List user-role assignments for a specific role within an organization.
|
|
193
|
+
*
|
|
194
|
+
* Supports pagination for admin UI views showing which users have a
|
|
195
|
+
* particular role. JOINs with users table to filter by organization.
|
|
196
|
+
*
|
|
197
|
+
* @param roleId - Role UUID
|
|
198
|
+
* @param orgId - Organization UUID (to scope users)
|
|
199
|
+
* @param page - Page number (1-based)
|
|
200
|
+
* @param pageSize - Number of results per page
|
|
201
|
+
* @returns Paginated user-role assignments and total count
|
|
202
|
+
*/
|
|
203
|
+
export async function getUsersWithRole(roleId, orgId, page, pageSize) {
|
|
204
|
+
const pool = getPool();
|
|
205
|
+
const offset = (page - 1) * pageSize;
|
|
206
|
+
// Count total matching assignments
|
|
207
|
+
const countResult = await pool.query(`SELECT COUNT(*)::int as count
|
|
208
|
+
FROM user_roles ur
|
|
209
|
+
JOIN users u ON u.id = ur.user_id
|
|
210
|
+
WHERE ur.role_id = $1 AND u.organization_id = $2`, [roleId, orgId]);
|
|
211
|
+
const total = parseInt(countResult.rows[0].count, 10);
|
|
212
|
+
// Fetch paginated data
|
|
213
|
+
const dataResult = await pool.query(`SELECT ur.*
|
|
214
|
+
FROM user_roles ur
|
|
215
|
+
JOIN users u ON u.id = ur.user_id
|
|
216
|
+
WHERE ur.role_id = $1 AND u.organization_id = $2
|
|
217
|
+
ORDER BY ur.created_at DESC
|
|
218
|
+
LIMIT $3 OFFSET $4`, [roleId, orgId, pageSize, offset]);
|
|
219
|
+
return {
|
|
220
|
+
rows: dataResult.rows.map(mapRowToUserRole),
|
|
221
|
+
total,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=mapping-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapping-repository.js","sourceRoot":"","sources":["../../src/rbac/mapping-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission repository — PostgreSQL data access layer.
|
|
3
|
+
*
|
|
4
|
+
* Provides CRUD operations for the `permissions` table using parameterized
|
|
5
|
+
* queries. Each function acquires the pool via `getPool()` and returns
|
|
6
|
+
* mapped Permission objects via `mapRowToPermission()`.
|
|
7
|
+
*
|
|
8
|
+
* Permissions are scoped to an application (application_id FK) with a
|
|
9
|
+
* unique slug per application enforced by DB constraint UNIQUE(application_id, slug).
|
|
10
|
+
* Permissions may optionally be linked to an application module (module_id FK).
|
|
11
|
+
*
|
|
12
|
+
* Key patterns:
|
|
13
|
+
* - Slug is immutable after creation (only name and description can be updated)
|
|
14
|
+
* - List supports optional module filter for scoped permission views
|
|
15
|
+
* - Role count for deletion guard (prevent deleting permissions assigned to roles)
|
|
16
|
+
*
|
|
17
|
+
* Database table: permissions (see migration 006_roles_permissions.sql)
|
|
18
|
+
*/
|
|
19
|
+
import type { Permission, CreatePermissionInput, UpdatePermissionInput } from './types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Insert a new permission into the database.
|
|
22
|
+
*
|
|
23
|
+
* Uses RETURNING * to get the full row back in a single round trip.
|
|
24
|
+
* The (application_id, slug) pair must be unique (enforced by DB constraint).
|
|
25
|
+
*
|
|
26
|
+
* @param input - Permission data to insert
|
|
27
|
+
* @returns The newly created permission
|
|
28
|
+
* @throws If (application_id, slug) already exists (unique constraint violation)
|
|
29
|
+
*/
|
|
30
|
+
export declare function insertPermission(input: CreatePermissionInput): Promise<Permission>;
|
|
31
|
+
/**
|
|
32
|
+
* Find a permission by its UUID.
|
|
33
|
+
*
|
|
34
|
+
* @param id - Permission UUID
|
|
35
|
+
* @returns Permission or null if not found
|
|
36
|
+
*/
|
|
37
|
+
export declare function findPermissionById(id: string): Promise<Permission | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Find a permission by application ID and slug.
|
|
40
|
+
*
|
|
41
|
+
* @param applicationId - Application UUID
|
|
42
|
+
* @param slug - Permission slug (unique within application)
|
|
43
|
+
* @returns Permission or null if not found
|
|
44
|
+
*/
|
|
45
|
+
export declare function findPermissionBySlug(applicationId: string, slug: string): Promise<Permission | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Update a permission by ID (name and description only — slug is immutable).
|
|
48
|
+
*
|
|
49
|
+
* Only explicitly provided fields (not undefined) are included in the
|
|
50
|
+
* UPDATE statement. Null is a valid value for description (clears it).
|
|
51
|
+
*
|
|
52
|
+
* @param id - Permission UUID
|
|
53
|
+
* @param input - Fields to update (name, description only)
|
|
54
|
+
* @returns Updated permission
|
|
55
|
+
* @throws Error if permission not found or no fields provided
|
|
56
|
+
*/
|
|
57
|
+
export declare function updatePermission(id: string, input: UpdatePermissionInput): Promise<Permission>;
|
|
58
|
+
/**
|
|
59
|
+
* Delete a permission by ID.
|
|
60
|
+
*
|
|
61
|
+
* Returns true if a row was deleted, false if the permission didn't exist.
|
|
62
|
+
* CASCADE constraints will automatically remove related role_permissions entries.
|
|
63
|
+
*
|
|
64
|
+
* @param id - Permission UUID
|
|
65
|
+
* @returns true if deleted, false if not found
|
|
66
|
+
*/
|
|
67
|
+
export declare function deletePermission(id: string): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* List permissions for an application, optionally filtered by module.
|
|
70
|
+
*
|
|
71
|
+
* Returns a simple array ordered by slug ascending. When moduleId is
|
|
72
|
+
* provided, only permissions linked to that module are returned.
|
|
73
|
+
*
|
|
74
|
+
* @param applicationId - Application UUID
|
|
75
|
+
* @param moduleId - Optional module UUID to filter by
|
|
76
|
+
* @returns Array of permissions
|
|
77
|
+
*/
|
|
78
|
+
export declare function listPermissionsByApplication(applicationId: string, moduleId?: string): Promise<Permission[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Check if a permission slug already exists for a given application.
|
|
81
|
+
*
|
|
82
|
+
* Used for uniqueness validation before insert. Permission slugs are
|
|
83
|
+
* immutable, so no excludeId parameter is needed (unlike roles).
|
|
84
|
+
*
|
|
85
|
+
* @param applicationId - Application UUID
|
|
86
|
+
* @param slug - Slug to check
|
|
87
|
+
* @returns true if the slug already exists
|
|
88
|
+
*/
|
|
89
|
+
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
|
+
//# sourceMappingURL=permission-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-repository.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAiB,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAO1G;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBxF;AAMD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU/E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,UAAU,CAAC,CA+BrB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASnE;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,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAQlB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpF"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission repository — PostgreSQL data access layer.
|
|
3
|
+
*
|
|
4
|
+
* Provides CRUD operations for the `permissions` table using parameterized
|
|
5
|
+
* queries. Each function acquires the pool via `getPool()` and returns
|
|
6
|
+
* mapped Permission objects via `mapRowToPermission()`.
|
|
7
|
+
*
|
|
8
|
+
* Permissions are scoped to an application (application_id FK) with a
|
|
9
|
+
* unique slug per application enforced by DB constraint UNIQUE(application_id, slug).
|
|
10
|
+
* Permissions may optionally be linked to an application module (module_id FK).
|
|
11
|
+
*
|
|
12
|
+
* Key patterns:
|
|
13
|
+
* - Slug is immutable after creation (only name and description can be updated)
|
|
14
|
+
* - List supports optional module filter for scoped permission views
|
|
15
|
+
* - Role count for deletion guard (prevent deleting permissions assigned to roles)
|
|
16
|
+
*
|
|
17
|
+
* Database table: permissions (see migration 006_roles_permissions.sql)
|
|
18
|
+
*/
|
|
19
|
+
import { getPool } from '../lib/database.js';
|
|
20
|
+
import { mapRowToPermission } from './types.js';
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Insert
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Insert a new permission into the database.
|
|
26
|
+
*
|
|
27
|
+
* Uses RETURNING * to get the full row back in a single round trip.
|
|
28
|
+
* The (application_id, slug) pair must be unique (enforced by DB constraint).
|
|
29
|
+
*
|
|
30
|
+
* @param input - Permission data to insert
|
|
31
|
+
* @returns The newly created permission
|
|
32
|
+
* @throws If (application_id, slug) already exists (unique constraint violation)
|
|
33
|
+
*/
|
|
34
|
+
export async function insertPermission(input) {
|
|
35
|
+
const pool = getPool();
|
|
36
|
+
const result = await pool.query(`INSERT INTO permissions (application_id, module_id, name, slug, description)
|
|
37
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
38
|
+
RETURNING *`, [
|
|
39
|
+
input.applicationId,
|
|
40
|
+
input.moduleId ?? null,
|
|
41
|
+
input.name,
|
|
42
|
+
input.slug,
|
|
43
|
+
input.description ?? null,
|
|
44
|
+
]);
|
|
45
|
+
return mapRowToPermission(result.rows[0]);
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Find
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Find a permission by its UUID.
|
|
52
|
+
*
|
|
53
|
+
* @param id - Permission UUID
|
|
54
|
+
* @returns Permission or null if not found
|
|
55
|
+
*/
|
|
56
|
+
export async function findPermissionById(id) {
|
|
57
|
+
const pool = getPool();
|
|
58
|
+
const result = await pool.query('SELECT * FROM permissions WHERE id = $1', [id]);
|
|
59
|
+
if (result.rows.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
return mapRowToPermission(result.rows[0]);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Find a permission by application ID and slug.
|
|
65
|
+
*
|
|
66
|
+
* @param applicationId - Application UUID
|
|
67
|
+
* @param slug - Permission slug (unique within application)
|
|
68
|
+
* @returns Permission or null if not found
|
|
69
|
+
*/
|
|
70
|
+
export async function findPermissionBySlug(applicationId, slug) {
|
|
71
|
+
const pool = getPool();
|
|
72
|
+
const result = await pool.query('SELECT * FROM permissions WHERE application_id = $1 AND slug = $2', [applicationId, slug]);
|
|
73
|
+
if (result.rows.length === 0)
|
|
74
|
+
return null;
|
|
75
|
+
return mapRowToPermission(result.rows[0]);
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Update
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* Update a permission by ID (name and description only — slug is immutable).
|
|
82
|
+
*
|
|
83
|
+
* Only explicitly provided fields (not undefined) are included in the
|
|
84
|
+
* UPDATE statement. Null is a valid value for description (clears it).
|
|
85
|
+
*
|
|
86
|
+
* @param id - Permission UUID
|
|
87
|
+
* @param input - Fields to update (name, description only)
|
|
88
|
+
* @returns Updated permission
|
|
89
|
+
* @throws Error if permission not found or no fields provided
|
|
90
|
+
*/
|
|
91
|
+
export async function updatePermission(id, input) {
|
|
92
|
+
const pool = getPool();
|
|
93
|
+
// Build dynamic SET clause — only name and description are updatable
|
|
94
|
+
const setClauses = [];
|
|
95
|
+
const values = [id]; // $1 is always the ID
|
|
96
|
+
let paramIndex = 2;
|
|
97
|
+
if (input.name !== undefined) {
|
|
98
|
+
setClauses.push(`name = $${paramIndex}`);
|
|
99
|
+
values.push(input.name);
|
|
100
|
+
paramIndex++;
|
|
101
|
+
}
|
|
102
|
+
if (input.description !== undefined) {
|
|
103
|
+
setClauses.push(`description = $${paramIndex}`);
|
|
104
|
+
values.push(input.description);
|
|
105
|
+
}
|
|
106
|
+
if (setClauses.length === 0) {
|
|
107
|
+
throw new Error('No fields to update');
|
|
108
|
+
}
|
|
109
|
+
const sql = `UPDATE permissions SET ${setClauses.join(', ')} WHERE id = $1 RETURNING *`;
|
|
110
|
+
const result = await pool.query(sql, values);
|
|
111
|
+
if (result.rows.length === 0) {
|
|
112
|
+
throw new Error('Permission not found');
|
|
113
|
+
}
|
|
114
|
+
return mapRowToPermission(result.rows[0]);
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// Delete
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
/**
|
|
120
|
+
* Delete a permission by ID.
|
|
121
|
+
*
|
|
122
|
+
* Returns true if a row was deleted, false if the permission didn't exist.
|
|
123
|
+
* CASCADE constraints will automatically remove related role_permissions entries.
|
|
124
|
+
*
|
|
125
|
+
* @param id - Permission UUID
|
|
126
|
+
* @returns true if deleted, false if not found
|
|
127
|
+
*/
|
|
128
|
+
export async function deletePermission(id) {
|
|
129
|
+
const pool = getPool();
|
|
130
|
+
const result = await pool.query('DELETE FROM permissions WHERE id = $1', [id]);
|
|
131
|
+
return (result.rowCount ?? 0) > 0;
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// List
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* List permissions for an application, optionally filtered by module.
|
|
138
|
+
*
|
|
139
|
+
* Returns a simple array ordered by slug ascending. When moduleId is
|
|
140
|
+
* provided, only permissions linked to that module are returned.
|
|
141
|
+
*
|
|
142
|
+
* @param applicationId - Application UUID
|
|
143
|
+
* @param moduleId - Optional module UUID to filter by
|
|
144
|
+
* @returns Array of permissions
|
|
145
|
+
*/
|
|
146
|
+
export async function listPermissionsByApplication(applicationId, moduleId) {
|
|
147
|
+
const pool = getPool();
|
|
148
|
+
if (moduleId) {
|
|
149
|
+
const result = await pool.query('SELECT * FROM permissions WHERE application_id = $1 AND module_id = $2 ORDER BY slug ASC', [applicationId, moduleId]);
|
|
150
|
+
return result.rows.map(mapRowToPermission);
|
|
151
|
+
}
|
|
152
|
+
const result = await pool.query('SELECT * FROM permissions WHERE application_id = $1 ORDER BY slug ASC', [applicationId]);
|
|
153
|
+
return result.rows.map(mapRowToPermission);
|
|
154
|
+
}
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Slug existence check
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
/**
|
|
159
|
+
* Check if a permission slug already exists for a given application.
|
|
160
|
+
*
|
|
161
|
+
* Used for uniqueness validation before insert. Permission slugs are
|
|
162
|
+
* immutable, so no excludeId parameter is needed (unlike roles).
|
|
163
|
+
*
|
|
164
|
+
* @param applicationId - Application UUID
|
|
165
|
+
* @param slug - Slug to check
|
|
166
|
+
* @returns true if the slug already exists
|
|
167
|
+
*/
|
|
168
|
+
export async function permissionSlugExists(applicationId, slug) {
|
|
169
|
+
const pool = getPool();
|
|
170
|
+
const result = await pool.query('SELECT EXISTS(SELECT 1 FROM permissions WHERE application_id = $1 AND slug = $2) as exists', [applicationId, slug]);
|
|
171
|
+
return result.rows[0].exists;
|
|
172
|
+
}
|
|
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
|
+
//# sourceMappingURL=permission-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-repository.js","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission service — business logic for permission management.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates permission CRUD operations with slug format validation,
|
|
5
|
+
* uniqueness checks, deletion guards, cache management, and audit logging.
|
|
6
|
+
*
|
|
7
|
+
* Permission slugs follow the module:resource:action format (e.g.,
|
|
8
|
+
* "crm:contacts:read") and are immutable after creation — only name
|
|
9
|
+
* and description can be updated.
|
|
10
|
+
*
|
|
11
|
+
* All write operations follow the pattern:
|
|
12
|
+
* validate → DB operation → cache invalidate → audit log
|
|
13
|
+
*
|
|
14
|
+
* @see permission-repository.ts — Database operations
|
|
15
|
+
* @see mapping-repository.ts — Role-permission lookups
|
|
16
|
+
* @see cache.ts — Redis cache operations
|
|
17
|
+
*/
|
|
18
|
+
import type { Permission, Role, CreatePermissionInput, UpdatePermissionInput } from './types.js';
|
|
19
|
+
/**
|
|
20
|
+
* Create a new permission for an application.
|
|
21
|
+
*
|
|
22
|
+
* Validates that the slug follows the module:resource:action format
|
|
23
|
+
* and ensures uniqueness within the application.
|
|
24
|
+
*
|
|
25
|
+
* @param input - Permission creation data
|
|
26
|
+
* @param actorId - Optional UUID of the admin performing the action
|
|
27
|
+
* @returns The newly created permission
|
|
28
|
+
* @throws RbacValidationError if slug format is invalid or already exists
|
|
29
|
+
*/
|
|
30
|
+
export declare function createPermission(input: CreatePermissionInput, actorId?: string): Promise<Permission>;
|
|
31
|
+
/**
|
|
32
|
+
* Find a permission by ID.
|
|
33
|
+
*
|
|
34
|
+
* @param id - Permission UUID
|
|
35
|
+
* @returns Permission or null if not found
|
|
36
|
+
*/
|
|
37
|
+
export declare function findPermissionById(id: string): Promise<Permission | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Find a permission by application ID and slug.
|
|
40
|
+
*
|
|
41
|
+
* @param applicationId - Application UUID
|
|
42
|
+
* @param slug - Permission slug
|
|
43
|
+
* @returns Permission or null if not found
|
|
44
|
+
*/
|
|
45
|
+
export declare function findPermissionBySlug(applicationId: string, slug: string): Promise<Permission | null>;
|
|
46
|
+
/**
|
|
47
|
+
* List permissions for an application, optionally filtered by module.
|
|
48
|
+
*
|
|
49
|
+
* @param applicationId - Application UUID
|
|
50
|
+
* @param moduleId - Optional module UUID to filter by
|
|
51
|
+
* @returns Array of permissions
|
|
52
|
+
*/
|
|
53
|
+
export declare function listPermissionsByApplication(applicationId: string, moduleId?: string): Promise<Permission[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Update a permission by ID (name and description only — slug is immutable).
|
|
56
|
+
*
|
|
57
|
+
* @param id - Permission UUID
|
|
58
|
+
* @param input - Fields to update (name, description only)
|
|
59
|
+
* @param actorId - Optional UUID of the admin performing the action
|
|
60
|
+
* @returns Updated permission
|
|
61
|
+
* @throws PermissionNotFoundError if permission doesn't exist
|
|
62
|
+
*/
|
|
63
|
+
export declare function updatePermission(id: string, input: UpdatePermissionInput, actorId?: string): Promise<Permission>;
|
|
64
|
+
/**
|
|
65
|
+
* Delete a permission by ID.
|
|
66
|
+
*
|
|
67
|
+
* By default (force=false), refuses to delete permissions that are
|
|
68
|
+
* assigned to any role. Pass force=true to delete regardless —
|
|
69
|
+
* CASCADE will remove role_permissions entries.
|
|
70
|
+
*
|
|
71
|
+
* @param id - Permission UUID
|
|
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
|
|
76
|
+
*/
|
|
77
|
+
export declare function deletePermission(id: string, force?: boolean, actorId?: string): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Get all roles that have a specific permission assigned.
|
|
80
|
+
*
|
|
81
|
+
* @param permissionId - Permission UUID
|
|
82
|
+
* @returns Array of roles with this permission
|
|
83
|
+
*/
|
|
84
|
+
export declare function getRolesWithPermission(permissionId: string): Promise<Role[]>;
|
|
85
|
+
//# sourceMappingURL=permission-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-service.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAiBH,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAMjG;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAMD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE/E;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;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAmBrB;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,GAAE,OAAe,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAgCf;AAMD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAElF"}
|