@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 @@
|
|
|
1
|
+
{"version":3,"file":"super-admin-protection.js","sourceRoot":"","sources":["../../src/lib/super-admin-protection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,gEAAgE;AAChE,MAAM,CAAC,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;AAE7D;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ;IACR,SAAS;IACT,MAAM;IACN,YAAY;IACZ,yBAAyB;IACzB,YAAY;CACJ,CAAC;AAIX,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAc;IACnD,yEAAyE;IACzE,gFAAgF;IAChF,MAAM,gBAAgB,GAAG,MAAM,qBAAqB,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAClF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,gBAAgB,KAAK,MAAM,CAAC;AACrC,CAAC;AAED,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,oCAAoC;IAC3B,MAAM,GAAG,GAAG,CAAC;IACtB,uCAAuC;IAC9B,SAAS,CAAqB;IAEvC,YAAY,SAA6B;QACvC,KAAK,CAAC,UAAU,SAAS,uBAAuB,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,SAA6B;IAE7B,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System configuration service — reads runtime settings from the system_config table.
|
|
3
|
+
*
|
|
4
|
+
* Values are cached in-memory with a configurable TTL to minimize database queries.
|
|
5
|
+
* The cache is shared across all requests within the process.
|
|
6
|
+
*
|
|
7
|
+
* The system_config table stores values as JSONB. Duration-type values are stored
|
|
8
|
+
* as JSONB strings (e.g., '"3600"'), while booleans and numbers are stored as
|
|
9
|
+
* native JSONB types. The typed getters handle parsing and coercion for each type.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const ttl = await getSystemConfigNumber('access_token_ttl', 3600);
|
|
13
|
+
* const secure = await getSystemConfigBoolean('cookie_secure', true);
|
|
14
|
+
* const allTtls = await loadOidcTtlConfig();
|
|
15
|
+
*/
|
|
16
|
+
/** OIDC TTL configuration loaded from system_config table */
|
|
17
|
+
export interface OidcTtlConfig {
|
|
18
|
+
/** Access token lifetime in seconds (default: 3600 = 1 hour) */
|
|
19
|
+
accessToken: number;
|
|
20
|
+
/** ID token lifetime in seconds (default: 3600 = 1 hour) */
|
|
21
|
+
idToken: number;
|
|
22
|
+
/** Refresh token lifetime in seconds (default: 2592000 = 30 days) */
|
|
23
|
+
refreshToken: number;
|
|
24
|
+
/** Authorization code lifetime in seconds (default: 600 = 10 minutes) */
|
|
25
|
+
authorizationCode: number;
|
|
26
|
+
/** Session lifetime in seconds (default: 86400 = 24 hours) */
|
|
27
|
+
session: number;
|
|
28
|
+
/** Interaction lifetime in seconds — hardcoded, not in system_config (default: 3600 = 1 hour) */
|
|
29
|
+
interaction: number;
|
|
30
|
+
/** Grant lifetime in seconds — same as refresh token (default: 2592000 = 30 days) */
|
|
31
|
+
grant: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get a string config value from the system_config table.
|
|
35
|
+
*
|
|
36
|
+
* @param key - Config key (e.g., 'magic_link_length')
|
|
37
|
+
* @param fallback - Default value returned if key not found or value is not a string
|
|
38
|
+
* @returns The config value as a string, or the fallback
|
|
39
|
+
*/
|
|
40
|
+
export declare function getSystemConfigString(key: string, fallback: string): Promise<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Get a numeric config value from the system_config table.
|
|
43
|
+
*
|
|
44
|
+
* Handles two storage patterns:
|
|
45
|
+
* - Duration-type values stored as JSONB strings (e.g., '"3600"') → parsed to number
|
|
46
|
+
* - Number-type values stored as native JSONB numbers (e.g., 10) → returned directly
|
|
47
|
+
*
|
|
48
|
+
* @param key - Config key (e.g., 'access_token_ttl')
|
|
49
|
+
* @param fallback - Default value returned if key not found or not a valid number
|
|
50
|
+
* @returns The config value as a number, or the fallback
|
|
51
|
+
*/
|
|
52
|
+
export declare function getSystemConfigNumber(key: string, fallback: number): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* Get a boolean config value from the system_config table.
|
|
55
|
+
*
|
|
56
|
+
* Handles native JSONB booleans (true/false) and string representations
|
|
57
|
+
* ('true'/'false') for maximum flexibility.
|
|
58
|
+
*
|
|
59
|
+
* @param key - Config key (e.g., 'cookie_secure')
|
|
60
|
+
* @param fallback - Default value returned if key not found or not a valid boolean
|
|
61
|
+
* @returns The config value as a boolean, or the fallback
|
|
62
|
+
*/
|
|
63
|
+
export declare function getSystemConfigBoolean(key: string, fallback: boolean): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Load all TTL config values needed by the OIDC provider.
|
|
66
|
+
*
|
|
67
|
+
* Reads each TTL key from system_config with hardcoded fallback defaults.
|
|
68
|
+
* Called once at provider initialization to build the TTL configuration.
|
|
69
|
+
* The interaction TTL is hardcoded (not stored in system_config).
|
|
70
|
+
*
|
|
71
|
+
* @returns Object with all OIDC TTL settings in seconds
|
|
72
|
+
*/
|
|
73
|
+
export declare function loadOidcTtlConfig(): Promise<OidcTtlConfig>;
|
|
74
|
+
/**
|
|
75
|
+
* Clear the in-memory config cache.
|
|
76
|
+
* Useful for testing to ensure fresh reads from the database.
|
|
77
|
+
*/
|
|
78
|
+
export declare function clearSystemConfigCache(): void;
|
|
79
|
+
//# sourceMappingURL=system-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-config.d.ts","sourceRoot":"","sources":["../../src/lib/system-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;CACf;AA8CD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM1F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB1F;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAe7F;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,CAoBhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System configuration service — reads runtime settings from the system_config table.
|
|
3
|
+
*
|
|
4
|
+
* Values are cached in-memory with a configurable TTL to minimize database queries.
|
|
5
|
+
* The cache is shared across all requests within the process.
|
|
6
|
+
*
|
|
7
|
+
* The system_config table stores values as JSONB. Duration-type values are stored
|
|
8
|
+
* as JSONB strings (e.g., '"3600"'), while booleans and numbers are stored as
|
|
9
|
+
* native JSONB types. The typed getters handle parsing and coercion for each type.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const ttl = await getSystemConfigNumber('access_token_ttl', 3600);
|
|
13
|
+
* const secure = await getSystemConfigBoolean('cookie_secure', true);
|
|
14
|
+
* const allTtls = await loadOidcTtlConfig();
|
|
15
|
+
*/
|
|
16
|
+
import { getPool } from './database.js';
|
|
17
|
+
import { logger } from './logger.js';
|
|
18
|
+
// In-memory cache with TTL (default: 60 seconds)
|
|
19
|
+
const cache = new Map();
|
|
20
|
+
const CACHE_TTL_MS = 60_000;
|
|
21
|
+
/**
|
|
22
|
+
* Fetch a raw config value from the database by key.
|
|
23
|
+
* Returns undefined if the key does not exist.
|
|
24
|
+
* Results are cached for CACHE_TTL_MS milliseconds.
|
|
25
|
+
*
|
|
26
|
+
* @param key - Config key to look up (e.g., 'access_token_ttl')
|
|
27
|
+
* @returns The JSONB value from the database, or undefined if not found
|
|
28
|
+
*/
|
|
29
|
+
async function getRawConfigValue(key) {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
// Check cache first
|
|
32
|
+
const cached = cache.get(key);
|
|
33
|
+
if (cached && cached.expiresAt > now) {
|
|
34
|
+
return cached.value;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const pool = getPool();
|
|
38
|
+
const result = await pool.query('SELECT value FROM system_config WHERE key = $1', [key]);
|
|
39
|
+
if (result.rows.length === 0) {
|
|
40
|
+
// Cache the miss to avoid repeated DB queries for unknown keys
|
|
41
|
+
cache.set(key, { value: undefined, expiresAt: now + CACHE_TTL_MS });
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const value = result.rows[0].value;
|
|
45
|
+
cache.set(key, { value, expiresAt: now + CACHE_TTL_MS });
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
// Log warning but don't fail — callers always provide fallback defaults
|
|
50
|
+
logger.warn({ key, error }, 'Failed to read system_config value, using fallback');
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get a string config value from the system_config table.
|
|
56
|
+
*
|
|
57
|
+
* @param key - Config key (e.g., 'magic_link_length')
|
|
58
|
+
* @param fallback - Default value returned if key not found or value is not a string
|
|
59
|
+
* @returns The config value as a string, or the fallback
|
|
60
|
+
*/
|
|
61
|
+
export async function getSystemConfigString(key, fallback) {
|
|
62
|
+
const raw = await getRawConfigValue(key);
|
|
63
|
+
if (raw === undefined || raw === null)
|
|
64
|
+
return fallback;
|
|
65
|
+
// JSONB values may be strings, numbers, or booleans — coerce to string
|
|
66
|
+
return String(raw);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get a numeric config value from the system_config table.
|
|
70
|
+
*
|
|
71
|
+
* Handles two storage patterns:
|
|
72
|
+
* - Duration-type values stored as JSONB strings (e.g., '"3600"') → parsed to number
|
|
73
|
+
* - Number-type values stored as native JSONB numbers (e.g., 10) → returned directly
|
|
74
|
+
*
|
|
75
|
+
* @param key - Config key (e.g., 'access_token_ttl')
|
|
76
|
+
* @param fallback - Default value returned if key not found or not a valid number
|
|
77
|
+
* @returns The config value as a number, or the fallback
|
|
78
|
+
*/
|
|
79
|
+
export async function getSystemConfigNumber(key, fallback) {
|
|
80
|
+
const raw = await getRawConfigValue(key);
|
|
81
|
+
if (raw === undefined || raw === null)
|
|
82
|
+
return fallback;
|
|
83
|
+
// If already a number (native JSONB number), return directly
|
|
84
|
+
if (typeof raw === 'number' && !Number.isNaN(raw))
|
|
85
|
+
return raw;
|
|
86
|
+
// If it's a string (duration values stored as JSONB strings like '"3600"'),
|
|
87
|
+
// parse as number
|
|
88
|
+
if (typeof raw === 'string') {
|
|
89
|
+
const parsed = Number(raw);
|
|
90
|
+
if (!Number.isNaN(parsed))
|
|
91
|
+
return parsed;
|
|
92
|
+
}
|
|
93
|
+
logger.warn({ key, raw }, 'system_config value is not a valid number, using fallback');
|
|
94
|
+
return fallback;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get a boolean config value from the system_config table.
|
|
98
|
+
*
|
|
99
|
+
* Handles native JSONB booleans (true/false) and string representations
|
|
100
|
+
* ('true'/'false') for maximum flexibility.
|
|
101
|
+
*
|
|
102
|
+
* @param key - Config key (e.g., 'cookie_secure')
|
|
103
|
+
* @param fallback - Default value returned if key not found or not a valid boolean
|
|
104
|
+
* @returns The config value as a boolean, or the fallback
|
|
105
|
+
*/
|
|
106
|
+
export async function getSystemConfigBoolean(key, fallback) {
|
|
107
|
+
const raw = await getRawConfigValue(key);
|
|
108
|
+
if (raw === undefined || raw === null)
|
|
109
|
+
return fallback;
|
|
110
|
+
// Native JSONB boolean
|
|
111
|
+
if (typeof raw === 'boolean')
|
|
112
|
+
return raw;
|
|
113
|
+
// String representation (from some JSONB encodings)
|
|
114
|
+
if (typeof raw === 'string') {
|
|
115
|
+
if (raw === 'true')
|
|
116
|
+
return true;
|
|
117
|
+
if (raw === 'false')
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
logger.warn({ key, raw }, 'system_config value is not a valid boolean, using fallback');
|
|
121
|
+
return fallback;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Load all TTL config values needed by the OIDC provider.
|
|
125
|
+
*
|
|
126
|
+
* Reads each TTL key from system_config with hardcoded fallback defaults.
|
|
127
|
+
* Called once at provider initialization to build the TTL configuration.
|
|
128
|
+
* The interaction TTL is hardcoded (not stored in system_config).
|
|
129
|
+
*
|
|
130
|
+
* @returns Object with all OIDC TTL settings in seconds
|
|
131
|
+
*/
|
|
132
|
+
export async function loadOidcTtlConfig() {
|
|
133
|
+
const [accessToken, idToken, refreshToken, authorizationCode, session] = await Promise.all([
|
|
134
|
+
getSystemConfigNumber('access_token_ttl', 3600),
|
|
135
|
+
getSystemConfigNumber('id_token_ttl', 3600),
|
|
136
|
+
getSystemConfigNumber('refresh_token_ttl', 2592000),
|
|
137
|
+
getSystemConfigNumber('authorization_code_ttl', 600),
|
|
138
|
+
getSystemConfigNumber('session_ttl', 86400),
|
|
139
|
+
]);
|
|
140
|
+
return {
|
|
141
|
+
accessToken,
|
|
142
|
+
idToken,
|
|
143
|
+
refreshToken,
|
|
144
|
+
authorizationCode,
|
|
145
|
+
session,
|
|
146
|
+
// Interaction TTL is hardcoded — not configurable via system_config
|
|
147
|
+
interaction: 3600,
|
|
148
|
+
// Grant TTL matches refresh token TTL by default
|
|
149
|
+
grant: refreshToken,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Clear the in-memory config cache.
|
|
154
|
+
* Useful for testing to ensure fresh reads from the database.
|
|
155
|
+
*/
|
|
156
|
+
export function clearSystemConfigCache() {
|
|
157
|
+
cache.clear();
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=system-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-config.js","sourceRoot":"","sources":["../../src/lib/system-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin API authentication and authorization middleware.
|
|
3
|
+
*
|
|
4
|
+
* Validates Bearer access tokens against Porta's own OIDC provider
|
|
5
|
+
* using opaque token lookup (provider.AccessToken.find()). Verifies
|
|
6
|
+
* the user belongs to the super-admin organization and has the
|
|
7
|
+
* porta-admin role. Sets ctx.state.adminUser for downstream handlers
|
|
8
|
+
* and audit logging.
|
|
9
|
+
*
|
|
10
|
+
* This middleware replaces the old requireSuperAdmin() that checked
|
|
11
|
+
* ctx.state.organization.isSuperAdmin (which required tenant-resolver
|
|
12
|
+
* context and was always undefined for /api/admin/* routes).
|
|
13
|
+
*
|
|
14
|
+
* Authentication flow:
|
|
15
|
+
* 1. Extract Bearer token from Authorization header
|
|
16
|
+
* 2. Validate opaque access token via OIDC provider lookup
|
|
17
|
+
* 3. Resolve super-admin organization
|
|
18
|
+
* 4. Look up user — must be active
|
|
19
|
+
* 5. Verify user belongs to the super-admin organization
|
|
20
|
+
* 6. Verify user has the porta-admin role
|
|
21
|
+
* 7. Set ctx.state.adminUser and proceed
|
|
22
|
+
*
|
|
23
|
+
* Response codes:
|
|
24
|
+
* 401 — Missing/invalid Bearer token, expired, revoked, unknown user
|
|
25
|
+
* 403 — Valid token but user not in admin org or lacks admin role
|
|
26
|
+
* 500 — System not initialized (provider not set, no super-admin org)
|
|
27
|
+
*/
|
|
28
|
+
import type { Middleware } from 'koa';
|
|
29
|
+
import type { Organization } from '../organizations/types.js';
|
|
30
|
+
/** Minimal opaque-token lookup boundary required from the OIDC provider. */
|
|
31
|
+
export interface AdminAccessTokenProvider {
|
|
32
|
+
/** Provider model used to resolve one opaque access token. */
|
|
33
|
+
readonly AccessToken: {
|
|
34
|
+
/** Resolve a token without exposing its storage mechanism to middleware. */
|
|
35
|
+
find(token: string): Promise<{
|
|
36
|
+
accountId?: string;
|
|
37
|
+
} | undefined>;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set the OIDC provider instance used for opaque access token validation.
|
|
42
|
+
* Must be called once at startup before any admin API requests are handled.
|
|
43
|
+
*
|
|
44
|
+
* The provider's AccessToken.find() method is used to look up opaque tokens
|
|
45
|
+
* from the token store (Redis for short-lived tokens).
|
|
46
|
+
*/
|
|
47
|
+
export declare function setAdminAuthProvider(provider: AdminAccessTokenProvider): void;
|
|
48
|
+
/** Remove the process-owned OIDC provider reference during orderly teardown. */
|
|
49
|
+
export declare function clearAdminAuthProvider(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Authenticated admin user identity.
|
|
52
|
+
*
|
|
53
|
+
* Populated by requireAdminAuth() middleware and available to all
|
|
54
|
+
* downstream route handlers via ctx.state.adminUser. Contains the
|
|
55
|
+
* user's ID, email, organization, and assigned role slugs.
|
|
56
|
+
*/
|
|
57
|
+
export interface AdminUser {
|
|
58
|
+
/** User UUID from access token accountId */
|
|
59
|
+
id: string;
|
|
60
|
+
/** User email address */
|
|
61
|
+
email: string;
|
|
62
|
+
/** Super-admin organization UUID */
|
|
63
|
+
organizationId: string;
|
|
64
|
+
/** Assigned role slugs (e.g., ['porta-super-admin', 'porta-org-admin']) */
|
|
65
|
+
roles: string[];
|
|
66
|
+
/** Resolved admin permissions from all assigned roles */
|
|
67
|
+
permissions: readonly string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Enforce super-admin organization membership through the shared public denial boundary.
|
|
71
|
+
*
|
|
72
|
+
* @returns `true` only when the authenticated account belongs to the required organization.
|
|
73
|
+
*/
|
|
74
|
+
export declare function requireAdminOrganizationMembership(ctx: Parameters<Middleware>[0], userOrganizationId: string, adminOrganizationId: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Extend Koa's default state to include the adminUser property.
|
|
77
|
+
* This provides type safety for route handlers accessing ctx.state.adminUser.
|
|
78
|
+
*/
|
|
79
|
+
declare module 'koa' {
|
|
80
|
+
interface DefaultState {
|
|
81
|
+
/** Tenant organization — set by tenant-resolver middleware on /:orgSlug/* routes */
|
|
82
|
+
organization?: Organization;
|
|
83
|
+
/** Authenticated admin identity — set by requireAdminAuth middleware on /api/admin/* routes */
|
|
84
|
+
adminUser?: AdminUser;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create middleware that requires admin authentication and authorization.
|
|
89
|
+
*
|
|
90
|
+
* Validates the Bearer access token in the Authorization header by looking
|
|
91
|
+
* it up via the OIDC provider's opaque token store, then verifies the user
|
|
92
|
+
* is an active member of the super-admin organization with the porta-admin role.
|
|
93
|
+
*
|
|
94
|
+
* On success, sets ctx.state.adminUser with the authenticated identity.
|
|
95
|
+
* On failure, responds with 401 (unauthenticated) or 403 (unauthorized).
|
|
96
|
+
*
|
|
97
|
+
* @returns Koa middleware
|
|
98
|
+
*/
|
|
99
|
+
export declare function requireAdminAuth(): Middleware;
|
|
100
|
+
//# sourceMappingURL=admin-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-auth.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAY9D,4EAA4E;AAC5E,MAAM,WAAW,wBAAwB;IACvC,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,EAAE;QACpB,4EAA4E;QAC5E,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC,CAAC;KAClE,CAAC;CACH;AAID;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAE7E;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yDAAyD;IACzD,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAC9B,kBAAkB,EAAE,MAAM,EAC1B,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAaT;AAMD;;;GAGG;AACH,OAAO,QAAQ,KAAK,CAAC;IACnB,UAAU,YAAY;QACpB,oFAAoF;QACpF,YAAY,CAAC,EAAE,YAAY,CAAC;QAC5B,+FAA+F;QAC/F,SAAS,CAAC,EAAE,SAAS,CAAC;KACvB;CACF;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CA+J7C"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin API authentication and authorization middleware.
|
|
3
|
+
*
|
|
4
|
+
* Validates Bearer access tokens against Porta's own OIDC provider
|
|
5
|
+
* using opaque token lookup (provider.AccessToken.find()). Verifies
|
|
6
|
+
* the user belongs to the super-admin organization and has the
|
|
7
|
+
* porta-admin role. Sets ctx.state.adminUser for downstream handlers
|
|
8
|
+
* and audit logging.
|
|
9
|
+
*
|
|
10
|
+
* This middleware replaces the old requireSuperAdmin() that checked
|
|
11
|
+
* ctx.state.organization.isSuperAdmin (which required tenant-resolver
|
|
12
|
+
* context and was always undefined for /api/admin/* routes).
|
|
13
|
+
*
|
|
14
|
+
* Authentication flow:
|
|
15
|
+
* 1. Extract Bearer token from Authorization header
|
|
16
|
+
* 2. Validate opaque access token via OIDC provider lookup
|
|
17
|
+
* 3. Resolve super-admin organization
|
|
18
|
+
* 4. Look up user — must be active
|
|
19
|
+
* 5. Verify user belongs to the super-admin organization
|
|
20
|
+
* 6. Verify user has the porta-admin role
|
|
21
|
+
* 7. Set ctx.state.adminUser and proceed
|
|
22
|
+
*
|
|
23
|
+
* Response codes:
|
|
24
|
+
* 401 — Missing/invalid Bearer token, expired, revoked, unknown user
|
|
25
|
+
* 403 — Valid token but user not in admin org or lacks admin role
|
|
26
|
+
* 500 — System not initialized (provider not set, no super-admin org)
|
|
27
|
+
*/
|
|
28
|
+
import { findUserForOidc } from '../users/service.js';
|
|
29
|
+
import { findSuperAdminOrganization } from '../organizations/repository.js';
|
|
30
|
+
import { getUserRoles } from '../rbac/user-role-service.js';
|
|
31
|
+
import { logger } from '../lib/logger.js';
|
|
32
|
+
import { resolvePermissionsFromRoles } from '../lib/admin-permissions.js';
|
|
33
|
+
import { recordSecurityDecision, recordSecurityReference } from '../security/decision-context.js';
|
|
34
|
+
let _provider = null;
|
|
35
|
+
/**
|
|
36
|
+
* Set the OIDC provider instance used for opaque access token validation.
|
|
37
|
+
* Must be called once at startup before any admin API requests are handled.
|
|
38
|
+
*
|
|
39
|
+
* The provider's AccessToken.find() method is used to look up opaque tokens
|
|
40
|
+
* from the token store (Redis for short-lived tokens).
|
|
41
|
+
*/
|
|
42
|
+
export function setAdminAuthProvider(provider) {
|
|
43
|
+
_provider = provider;
|
|
44
|
+
}
|
|
45
|
+
/** Remove the process-owned OIDC provider reference during orderly teardown. */
|
|
46
|
+
export function clearAdminAuthProvider() {
|
|
47
|
+
_provider = null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Enforce super-admin organization membership through the shared public denial boundary.
|
|
51
|
+
*
|
|
52
|
+
* @returns `true` only when the authenticated account belongs to the required organization.
|
|
53
|
+
*/
|
|
54
|
+
export function requireAdminOrganizationMembership(ctx, userOrganizationId, adminOrganizationId) {
|
|
55
|
+
if (userOrganizationId === adminOrganizationId)
|
|
56
|
+
return true;
|
|
57
|
+
recordSecurityDecision(ctx, {
|
|
58
|
+
decisionPoint: 'membership',
|
|
59
|
+
reasonCode: 'membership-required',
|
|
60
|
+
outcome: 'deny',
|
|
61
|
+
});
|
|
62
|
+
ctx.status = 403;
|
|
63
|
+
ctx.body = {
|
|
64
|
+
error: 'Forbidden',
|
|
65
|
+
message: 'Administrative access is not permitted',
|
|
66
|
+
};
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Admin auth middleware factory
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Admin role slug prefix — all admin roles start with 'porta-'.
|
|
74
|
+
* Legacy 'porta-admin' role is treated as super-admin for backward compatibility.
|
|
75
|
+
*/
|
|
76
|
+
const ADMIN_ROLE_PREFIX = 'porta-';
|
|
77
|
+
/**
|
|
78
|
+
* Create middleware that requires admin authentication and authorization.
|
|
79
|
+
*
|
|
80
|
+
* Validates the Bearer access token in the Authorization header by looking
|
|
81
|
+
* it up via the OIDC provider's opaque token store, then verifies the user
|
|
82
|
+
* is an active member of the super-admin organization with the porta-admin role.
|
|
83
|
+
*
|
|
84
|
+
* On success, sets ctx.state.adminUser with the authenticated identity.
|
|
85
|
+
* On failure, responds with 401 (unauthenticated) or 403 (unauthorized).
|
|
86
|
+
*
|
|
87
|
+
* @returns Koa middleware
|
|
88
|
+
*/
|
|
89
|
+
export function requireAdminAuth() {
|
|
90
|
+
return async (ctx, next) => {
|
|
91
|
+
// -----------------------------------------------------------------
|
|
92
|
+
// Step 1: Extract Bearer token from Authorization header
|
|
93
|
+
// -----------------------------------------------------------------
|
|
94
|
+
const authHeader = ctx.get('Authorization');
|
|
95
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
96
|
+
recordSecurityDecision(ctx, {
|
|
97
|
+
decisionPoint: 'authentication',
|
|
98
|
+
reasonCode: 'authentication-required',
|
|
99
|
+
outcome: 'deny',
|
|
100
|
+
});
|
|
101
|
+
ctx.status = 401;
|
|
102
|
+
ctx.body = {
|
|
103
|
+
error: 'Authentication required',
|
|
104
|
+
message: 'Missing or invalid Authorization header',
|
|
105
|
+
};
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const token = authHeader.slice(7); // Remove 'Bearer ' prefix
|
|
109
|
+
// -----------------------------------------------------------------
|
|
110
|
+
// Step 2: Validate opaque access token via OIDC provider
|
|
111
|
+
// -----------------------------------------------------------------
|
|
112
|
+
// Timing analysis (Phase K audit):
|
|
113
|
+
// Token validation uses DB/Redis lookups via provider.AccessToken.find(),
|
|
114
|
+
// which have inherent timing variability from network I/O. All auth
|
|
115
|
+
// failure paths return the same 401 status and generic error message
|
|
116
|
+
// ("Token validation failed"), preventing error-message enumeration.
|
|
117
|
+
// Constant-time string comparison is not needed here because we never
|
|
118
|
+
// compare secret material directly — the opaque token is used as a
|
|
119
|
+
// lookup key, not compared against a stored value.
|
|
120
|
+
// -----------------------------------------------------------------
|
|
121
|
+
// The OIDC provider issues opaque access tokens (not JWTs). We look
|
|
122
|
+
// them up directly in the token store using provider.AccessToken.find().
|
|
123
|
+
// This handles expiry (Redis TTL), revocation, and format validation
|
|
124
|
+
// in a single call — no need for JWT signature verification or issuer
|
|
125
|
+
// checks since the provider is the authoritative token store.
|
|
126
|
+
if (!_provider) {
|
|
127
|
+
logger.error('Admin auth: OIDC provider not initialized');
|
|
128
|
+
recordSecurityDecision(ctx, {
|
|
129
|
+
decisionPoint: 'handler',
|
|
130
|
+
reasonCode: 'handler-failed',
|
|
131
|
+
outcome: 'error',
|
|
132
|
+
});
|
|
133
|
+
ctx.status = 500;
|
|
134
|
+
ctx.body = { error: 'Server configuration error' };
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
let userId;
|
|
138
|
+
try {
|
|
139
|
+
const accessToken = await _provider.AccessToken.find(token);
|
|
140
|
+
if (!accessToken || !accessToken.accountId) {
|
|
141
|
+
logger.debug('Admin auth: access token not found or missing accountId');
|
|
142
|
+
recordSecurityDecision(ctx, {
|
|
143
|
+
decisionPoint: 'authentication',
|
|
144
|
+
reasonCode: 'authentication-required',
|
|
145
|
+
outcome: 'deny',
|
|
146
|
+
});
|
|
147
|
+
ctx.status = 401;
|
|
148
|
+
ctx.body = { error: 'Invalid token', message: 'Token validation failed' };
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
userId = accessToken.accountId;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Intentionally vague error message — don't reveal internal details.
|
|
155
|
+
// Log the real error server-side for debugging.
|
|
156
|
+
logger.debug({ event: 'admin-token-lookup-rejected' }, 'Admin token lookup rejected');
|
|
157
|
+
recordSecurityDecision(ctx, {
|
|
158
|
+
decisionPoint: 'authentication',
|
|
159
|
+
reasonCode: 'authentication-required',
|
|
160
|
+
outcome: 'deny',
|
|
161
|
+
});
|
|
162
|
+
ctx.status = 401;
|
|
163
|
+
ctx.body = { error: 'Invalid token', message: 'Token validation failed' };
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
// -----------------------------------------------------------------
|
|
167
|
+
// Step 3: Resolve super-admin organization
|
|
168
|
+
// -----------------------------------------------------------------
|
|
169
|
+
// Cached in-memory (60s TTL) so this is fast after first call.
|
|
170
|
+
const superAdminOrg = await findSuperAdminOrganization();
|
|
171
|
+
if (!superAdminOrg) {
|
|
172
|
+
// System not initialized — porta init has not been run
|
|
173
|
+
logger.error('Admin auth: super-admin organization not found — run porta init');
|
|
174
|
+
recordSecurityDecision(ctx, {
|
|
175
|
+
decisionPoint: 'handler',
|
|
176
|
+
reasonCode: 'handler-failed',
|
|
177
|
+
outcome: 'error',
|
|
178
|
+
});
|
|
179
|
+
ctx.status = 500;
|
|
180
|
+
ctx.body = { error: 'Server configuration error' };
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// -----------------------------------------------------------------
|
|
184
|
+
// Step 4: Look up user — must be active
|
|
185
|
+
// -----------------------------------------------------------------
|
|
186
|
+
// findUserForOidc returns null for non-existent or non-active users
|
|
187
|
+
const user = await findUserForOidc(userId);
|
|
188
|
+
if (!user) {
|
|
189
|
+
recordSecurityDecision(ctx, {
|
|
190
|
+
decisionPoint: 'authentication',
|
|
191
|
+
reasonCode: 'authentication-required',
|
|
192
|
+
outcome: 'deny',
|
|
193
|
+
});
|
|
194
|
+
ctx.status = 401;
|
|
195
|
+
ctx.body = { error: 'Invalid token', message: 'Token validation failed' };
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// -----------------------------------------------------------------
|
|
199
|
+
// Step 5: Verify user belongs to the super-admin organization
|
|
200
|
+
// -----------------------------------------------------------------
|
|
201
|
+
if (!requireAdminOrganizationMembership(ctx, user.organizationId, superAdminOrg.id))
|
|
202
|
+
return;
|
|
203
|
+
// -----------------------------------------------------------------
|
|
204
|
+
// Step 6: Verify user has an admin role (any porta-* role)
|
|
205
|
+
// -----------------------------------------------------------------
|
|
206
|
+
// Supports both legacy porta-admin and new granular roles:
|
|
207
|
+
// porta-super-admin, porta-org-admin, porta-user-admin, etc.
|
|
208
|
+
const userRoles = await getUserRoles(userId);
|
|
209
|
+
const adminRoleSlugs = userRoles
|
|
210
|
+
.map((role) => role.slug)
|
|
211
|
+
.filter((slug) => slug.startsWith(ADMIN_ROLE_PREFIX));
|
|
212
|
+
if (adminRoleSlugs.length === 0) {
|
|
213
|
+
recordSecurityDecision(ctx, {
|
|
214
|
+
decisionPoint: 'membership',
|
|
215
|
+
reasonCode: 'membership-required',
|
|
216
|
+
outcome: 'deny',
|
|
217
|
+
});
|
|
218
|
+
ctx.status = 403;
|
|
219
|
+
ctx.body = { error: 'Forbidden', message: 'Administrative access is not permitted' };
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
// -----------------------------------------------------------------
|
|
223
|
+
// Step 7: Resolve permissions from all admin roles
|
|
224
|
+
// -----------------------------------------------------------------
|
|
225
|
+
const permissions = resolvePermissionsFromRoles(adminRoleSlugs);
|
|
226
|
+
// -----------------------------------------------------------------
|
|
227
|
+
// Step 8: Set admin user context and proceed to route handler
|
|
228
|
+
// -----------------------------------------------------------------
|
|
229
|
+
ctx.state.adminUser = {
|
|
230
|
+
id: userId,
|
|
231
|
+
email: user.email,
|
|
232
|
+
organizationId: user.organizationId,
|
|
233
|
+
roles: adminRoleSlugs,
|
|
234
|
+
permissions,
|
|
235
|
+
};
|
|
236
|
+
recordSecurityReference(ctx, 'actor', userId);
|
|
237
|
+
recordSecurityReference(ctx, 'tenant', user.organizationId);
|
|
238
|
+
await next();
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=admin-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-auth.js","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin API CORS allow-list middleware.
|
|
3
|
+
*
|
|
4
|
+
* Implements a strict CORS policy for `/api/admin/*` endpoints.
|
|
5
|
+
* By default (empty `adminCorsOrigins` config), **no CORS headers are
|
|
6
|
+
* emitted** — all cross-origin requests are blocked by the browser.
|
|
7
|
+
*
|
|
8
|
+
* When `ADMIN_CORS_ORIGINS` is configured with one or more origin URLs,
|
|
9
|
+
* only those exact origins receive CORS headers. This is intended for
|
|
10
|
+
* operators who deploy a web-based admin dashboard on a different origin.
|
|
11
|
+
*
|
|
12
|
+
* Non-browser clients (CLI, same-origin requests) never send an `Origin`
|
|
13
|
+
* header, so they pass through this middleware untouched.
|
|
14
|
+
*
|
|
15
|
+
* Placement: mount after the admin metadata router and before
|
|
16
|
+
* `setAdminAuthProvider()` — preflight `OPTIONS` requests don't carry
|
|
17
|
+
* an `Authorization` header, so CORS must respond before auth runs.
|
|
18
|
+
*
|
|
19
|
+
* @module middleware/admin-cors
|
|
20
|
+
*/
|
|
21
|
+
import type { Middleware } from 'koa';
|
|
22
|
+
import type { AppConfig } from '../config/schema.js';
|
|
23
|
+
/** HTTP methods allowed for cross-origin admin API requests. */
|
|
24
|
+
export declare const CORS_ALLOWED_METHODS = "GET, POST, PUT, PATCH, DELETE, OPTIONS";
|
|
25
|
+
/** HTTP headers allowed in cross-origin admin API requests. */
|
|
26
|
+
export declare const CORS_ALLOWED_HEADERS = "Authorization, Content-Type";
|
|
27
|
+
/** Preflight cache duration in seconds (24 hours). */
|
|
28
|
+
export declare const CORS_MAX_AGE = "86400";
|
|
29
|
+
/**
|
|
30
|
+
* Create admin CORS middleware with the given application config.
|
|
31
|
+
*
|
|
32
|
+
* Uses a `Set` for O(1) origin lookup. The `Vary: Origin` header is
|
|
33
|
+
* required by the CORS specification when `Access-Control-Allow-Origin`
|
|
34
|
+
* is not the wildcard `*` — it tells caches that the response varies by
|
|
35
|
+
* the request's `Origin` header.
|
|
36
|
+
*
|
|
37
|
+
* @param config - Application config (reads `adminCorsOrigins`)
|
|
38
|
+
* @returns Koa middleware that handles CORS for `/api/admin/*` routes
|
|
39
|
+
*/
|
|
40
|
+
export declare function adminCors(config: AppConfig): Middleware;
|
|
41
|
+
//# sourceMappingURL=admin-cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-cors.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-cors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAMrD,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,2CAA2C,CAAC;AAE7E,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,sDAAsD;AACtD,eAAO,MAAM,YAAY,UAAU,CAAC;AAMpC;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CA4CvD"}
|