@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,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus metrics middleware.
|
|
3
|
+
*
|
|
4
|
+
* Provides two Koa middleware functions:
|
|
5
|
+
* - `metricsCounter()` — increments an HTTP request counter per response
|
|
6
|
+
* - `metricsHandler()` — serves the Prometheus text format at GET /metrics
|
|
7
|
+
*
|
|
8
|
+
* Uses a dedicated `prom-client` Registry so default Node.js metrics
|
|
9
|
+
* (CPU, memory, event loop lag, GC, file descriptors) are collected
|
|
10
|
+
* automatically alongside the HTTP counter.
|
|
11
|
+
*
|
|
12
|
+
* Only mounted when `config.metricsEnabled === true`. When disabled,
|
|
13
|
+
* GET /metrics returns 404 (no route registered).
|
|
14
|
+
*
|
|
15
|
+
* Security note: the /metrics endpoint is unauthenticated by design
|
|
16
|
+
* (standard Prometheus scraping model). Operators must restrict access
|
|
17
|
+
* via network policy or reverse proxy.
|
|
18
|
+
*/
|
|
19
|
+
import type { Middleware } from 'koa';
|
|
20
|
+
/**
|
|
21
|
+
* Middleware that increments the `porta_http_requests_total` counter
|
|
22
|
+
* after every response. Should be mounted early in the middleware stack
|
|
23
|
+
* so it captures all downstream responses.
|
|
24
|
+
*
|
|
25
|
+
* @returns Koa middleware
|
|
26
|
+
*/
|
|
27
|
+
export declare function metricsCounter(): Middleware;
|
|
28
|
+
/**
|
|
29
|
+
* Request handler that returns all collected metrics in Prometheus text format.
|
|
30
|
+
* Mount at `GET /metrics` when metrics are enabled.
|
|
31
|
+
*
|
|
32
|
+
* @returns Koa middleware
|
|
33
|
+
*/
|
|
34
|
+
export declare function metricsHandler(): Middleware;
|
|
35
|
+
/**
|
|
36
|
+
* Reset all metrics — used in tests to avoid counter bleed between test cases.
|
|
37
|
+
* NOT for production use.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resetMetrics(): void;
|
|
40
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/middleware/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAqBtC;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,UAAU,CAa3C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,UAAU,CAK3C;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus metrics middleware.
|
|
3
|
+
*
|
|
4
|
+
* Provides two Koa middleware functions:
|
|
5
|
+
* - `metricsCounter()` — increments an HTTP request counter per response
|
|
6
|
+
* - `metricsHandler()` — serves the Prometheus text format at GET /metrics
|
|
7
|
+
*
|
|
8
|
+
* Uses a dedicated `prom-client` Registry so default Node.js metrics
|
|
9
|
+
* (CPU, memory, event loop lag, GC, file descriptors) are collected
|
|
10
|
+
* automatically alongside the HTTP counter.
|
|
11
|
+
*
|
|
12
|
+
* Only mounted when `config.metricsEnabled === true`. When disabled,
|
|
13
|
+
* GET /metrics returns 404 (no route registered).
|
|
14
|
+
*
|
|
15
|
+
* Security note: the /metrics endpoint is unauthenticated by design
|
|
16
|
+
* (standard Prometheus scraping model). Operators must restrict access
|
|
17
|
+
* via network policy or reverse proxy.
|
|
18
|
+
*/
|
|
19
|
+
import client from 'prom-client';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Registry — one per process, isolated from any global default registry.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const registry = new client.Registry();
|
|
24
|
+
client.collectDefaultMetrics({ register: registry });
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// HTTP request counter — low-cardinality labels only (no user IDs, no PII).
|
|
27
|
+
// `route` uses the matched koa-router pattern (e.g. "/api/admin/organizations/:id")
|
|
28
|
+
// so label cardinality stays bounded regardless of path parameter values.
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
const httpRequests = new client.Counter({
|
|
31
|
+
name: 'porta_http_requests_total',
|
|
32
|
+
help: 'Total HTTP requests by method, route pattern, and status code',
|
|
33
|
+
labelNames: ['method', 'route', 'status'],
|
|
34
|
+
registers: [registry],
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Middleware that increments the `porta_http_requests_total` counter
|
|
38
|
+
* after every response. Should be mounted early in the middleware stack
|
|
39
|
+
* so it captures all downstream responses.
|
|
40
|
+
*
|
|
41
|
+
* @returns Koa middleware
|
|
42
|
+
*/
|
|
43
|
+
export function metricsCounter() {
|
|
44
|
+
return async (ctx, next) => {
|
|
45
|
+
await next();
|
|
46
|
+
// koa-router sets ctx._matchedRoute to the pattern string (e.g. "/health").
|
|
47
|
+
// Fall back to "unknown" for routes not matched by koa-router (e.g. OIDC provider).
|
|
48
|
+
const route = typeof ctx._matchedRoute === 'string' ? ctx._matchedRoute : 'unknown';
|
|
49
|
+
httpRequests.inc({
|
|
50
|
+
method: ctx.method,
|
|
51
|
+
route,
|
|
52
|
+
status: String(ctx.status),
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Request handler that returns all collected metrics in Prometheus text format.
|
|
58
|
+
* Mount at `GET /metrics` when metrics are enabled.
|
|
59
|
+
*
|
|
60
|
+
* @returns Koa middleware
|
|
61
|
+
*/
|
|
62
|
+
export function metricsHandler() {
|
|
63
|
+
return async (ctx) => {
|
|
64
|
+
ctx.set('Content-Type', registry.contentType);
|
|
65
|
+
ctx.body = await registry.metrics();
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Reset all metrics — used in tests to avoid counter bleed between test cases.
|
|
70
|
+
* NOT for production use.
|
|
71
|
+
*/
|
|
72
|
+
export function resetMetrics() {
|
|
73
|
+
registry.resetMetrics();
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/middleware/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,8EAA8E;AAC9E,yEAAyE;AACzE,8EAA8E;AAC9E,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;AACvC,MAAM,CAAC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;AAErD,8EAA8E;AAC9E,4EAA4E;AAC5E,oFAAoF;AACpF,0EAA0E;AAC1E,8EAA8E;AAC9E,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC;IACtC,IAAI,EAAE,2BAA2B;IACjC,IAAI,EAAE,+DAA+D;IACrE,UAAU,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAU;IAClD,SAAS,EAAE,CAAC,QAAQ,CAAC;CACtB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,IAAI,EAAE,CAAC;QACb,4EAA4E;QAC5E,oFAAoF;QACpF,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,YAAY,CAAC,GAAG,CAAC;YACf,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,KAAK;YACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC9C,GAAG,CAAC,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,QAAQ,CAAC,YAAY,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC client-to-tenant binding middleware.
|
|
3
|
+
*
|
|
4
|
+
* Porta exposes one issuer per organization. A client identifier is valid only under the issuer
|
|
5
|
+
* owned by that client's organization. This middleware rejects cross-organization and unknown
|
|
6
|
+
* client identifiers before the shared OIDC provider can create an interaction or consume a
|
|
7
|
+
* credential under the wrong issuer.
|
|
8
|
+
*/
|
|
9
|
+
import type { Middleware } from 'koa';
|
|
10
|
+
/** Minimal provider model boundary needed to resolve an opaque access token's issuing client. */
|
|
11
|
+
export interface OidcOpaqueTokenProvider {
|
|
12
|
+
/** Opaque access-token model exposed by oidc-provider. */
|
|
13
|
+
readonly AccessToken: {
|
|
14
|
+
/** Finds an unexpired access token without interpreting it as a JWT. */
|
|
15
|
+
find(token: string): Promise<{
|
|
16
|
+
readonly clientId?: string;
|
|
17
|
+
} | undefined>;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Enforces that every presented OIDC client identifier belongs to the resolved organization.
|
|
22
|
+
*
|
|
23
|
+
* Query, form-body, and HTTP Basic identifiers are all checked because different OIDC endpoints
|
|
24
|
+
* carry client authentication in different locations. Unknown and foreign identifiers receive
|
|
25
|
+
* the same minimal response so this boundary cannot be used for cross-tenant client discovery.
|
|
26
|
+
* Requests without a client identifier continue to provider endpoints such as discovery and JWKS.
|
|
27
|
+
*
|
|
28
|
+
* Opaque bearer tokens on UserInfo do not carry a separate request `client_id`, so the middleware
|
|
29
|
+
* resolves the token's issuing client and applies the same organization comparison there. Invalid
|
|
30
|
+
* or unknown bearer values remain provider-owned errors; an otherwise valid foreign token is
|
|
31
|
+
* rejected before identity claims can be disclosed.
|
|
32
|
+
*
|
|
33
|
+
* @param provider - Provider model access used to resolve opaque UserInfo tokens
|
|
34
|
+
* @returns Koa middleware mounted after tenant resolution and body parsing
|
|
35
|
+
*/
|
|
36
|
+
export declare function oidcClientTenantBinding(provider: OidcOpaqueTokenProvider): Middleware;
|
|
37
|
+
//# sourceMappingURL=oidc-client-tenant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-client-tenant.d.ts","sourceRoot":"","sources":["../../src/middleware/oidc-client-tenant.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAQtC,iGAAiG;AACjG,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE;QACpB,wEAAwE;QACxE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC,CAAC;KAC1E,CAAC;CACH;AAkGD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,UAAU,CAoDrF"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC client-to-tenant binding middleware.
|
|
3
|
+
*
|
|
4
|
+
* Porta exposes one issuer per organization. A client identifier is valid only under the issuer
|
|
5
|
+
* owned by that client's organization. This middleware rejects cross-organization and unknown
|
|
6
|
+
* client identifiers before the shared OIDC provider can create an interaction or consume a
|
|
7
|
+
* credential under the wrong issuer.
|
|
8
|
+
*/
|
|
9
|
+
import { getClientByClientId } from '../clients/service.js';
|
|
10
|
+
import { observeProtocolSecurityRejection } from '../oidc/protocol-security-observer.js';
|
|
11
|
+
const MAX_CLIENT_ID_LENGTH = 255;
|
|
12
|
+
const MAX_BASIC_HEADER_LENGTH = 4096;
|
|
13
|
+
const MAX_BEARER_HEADER_LENGTH = 8192;
|
|
14
|
+
/** Returns one bounded client identifier or leaves malformed input for the provider to reject. */
|
|
15
|
+
function boundedClientId(value) {
|
|
16
|
+
if (typeof value !== 'string' || value.length === 0 || value.length > MAX_CLIENT_ID_LENGTH) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
/** Extracts the client identifier from HTTP Basic credentials without retaining the secret. */
|
|
22
|
+
function basicClientId(authorization) {
|
|
23
|
+
if (authorization === undefined ||
|
|
24
|
+
!authorization.startsWith('Basic ') ||
|
|
25
|
+
authorization.length > MAX_BASIC_HEADER_LENGTH) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const decoded = Buffer.from(authorization.slice(6), 'base64').toString('utf8');
|
|
30
|
+
const separator = decoded.indexOf(':');
|
|
31
|
+
return separator < 0 ? undefined : boundedClientId(decoded.slice(0, separator));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Reads a client identifier from an already parsed request body. */
|
|
38
|
+
function bodyClientId(body) {
|
|
39
|
+
if (typeof body !== 'object' || body === null || Array.isArray(body))
|
|
40
|
+
return undefined;
|
|
41
|
+
return boundedClientId(Reflect.get(body, 'client_id'));
|
|
42
|
+
}
|
|
43
|
+
/** Reads the organization identifier established by the tenant resolver. */
|
|
44
|
+
function resolvedOrganizationId(organization) {
|
|
45
|
+
if (typeof organization !== 'object' || organization === null || Array.isArray(organization)) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const id = Reflect.get(organization, 'id');
|
|
49
|
+
return typeof id === 'string' && id.length > 0 ? id : undefined;
|
|
50
|
+
}
|
|
51
|
+
/** Extracts one bounded opaque bearer token without decoding or retaining it. */
|
|
52
|
+
function bearerToken(authorization) {
|
|
53
|
+
if (authorization === undefined || authorization.length > MAX_BEARER_HEADER_LENGTH) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return /^Bearer ([^\s]+)$/i.exec(authorization)?.[1];
|
|
57
|
+
}
|
|
58
|
+
/** Reads a bounded form-carried access token without accepting arrays or coerced values. */
|
|
59
|
+
function formAccessToken(body) {
|
|
60
|
+
if (typeof body !== 'object' || body === null || Array.isArray(body))
|
|
61
|
+
return undefined;
|
|
62
|
+
const token = Reflect.get(body, 'access_token');
|
|
63
|
+
return typeof token === 'string' && token.length > 0 && token.length <= MAX_BEARER_HEADER_LENGTH
|
|
64
|
+
? token
|
|
65
|
+
: undefined;
|
|
66
|
+
}
|
|
67
|
+
/** Identifies supported provider UserInfo routes after the organization prefix. */
|
|
68
|
+
function isUserinfoRequest(method, path, organizationSlug) {
|
|
69
|
+
if (method !== 'GET' && method !== 'POST')
|
|
70
|
+
return false;
|
|
71
|
+
if (typeof organizationSlug !== 'string' || organizationSlug.length === 0)
|
|
72
|
+
return false;
|
|
73
|
+
const relativePath = path.slice(`/${organizationSlug}`.length);
|
|
74
|
+
return relativePath === '/me' || relativePath === '/userinfo';
|
|
75
|
+
}
|
|
76
|
+
/** Returns a single supported UserInfo token mechanism or delegates ambiguous input. */
|
|
77
|
+
function userinfoToken(method, authorization, body) {
|
|
78
|
+
const headerToken = bearerToken(authorization);
|
|
79
|
+
const bodyToken = method === 'POST' ? formAccessToken(body) : undefined;
|
|
80
|
+
if (headerToken !== undefined && bodyToken !== undefined)
|
|
81
|
+
return undefined;
|
|
82
|
+
return headerToken ?? bodyToken;
|
|
83
|
+
}
|
|
84
|
+
/** Sends the provider-compatible public response for a tenant-mismatched opaque token. */
|
|
85
|
+
function rejectUserinfoToken(ctx) {
|
|
86
|
+
ctx.status = 401;
|
|
87
|
+
ctx.set('WWW-Authenticate', 'Bearer error="invalid_token"');
|
|
88
|
+
ctx.body = { error: 'invalid_token' };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Enforces that every presented OIDC client identifier belongs to the resolved organization.
|
|
92
|
+
*
|
|
93
|
+
* Query, form-body, and HTTP Basic identifiers are all checked because different OIDC endpoints
|
|
94
|
+
* carry client authentication in different locations. Unknown and foreign identifiers receive
|
|
95
|
+
* the same minimal response so this boundary cannot be used for cross-tenant client discovery.
|
|
96
|
+
* Requests without a client identifier continue to provider endpoints such as discovery and JWKS.
|
|
97
|
+
*
|
|
98
|
+
* Opaque bearer tokens on UserInfo do not carry a separate request `client_id`, so the middleware
|
|
99
|
+
* resolves the token's issuing client and applies the same organization comparison there. Invalid
|
|
100
|
+
* or unknown bearer values remain provider-owned errors; an otherwise valid foreign token is
|
|
101
|
+
* rejected before identity claims can be disclosed.
|
|
102
|
+
*
|
|
103
|
+
* @param provider - Provider model access used to resolve opaque UserInfo tokens
|
|
104
|
+
* @returns Koa middleware mounted after tenant resolution and body parsing
|
|
105
|
+
*/
|
|
106
|
+
export function oidcClientTenantBinding(provider) {
|
|
107
|
+
return async (ctx, next) => {
|
|
108
|
+
const organizationId = resolvedOrganizationId(ctx.state.organization);
|
|
109
|
+
if (organizationId === undefined)
|
|
110
|
+
ctx.throw(500, 'Tenant context unavailable');
|
|
111
|
+
const candidates = new Set();
|
|
112
|
+
const queryClientId = boundedClientId(ctx.query.client_id);
|
|
113
|
+
const parsedBodyClientId = bodyClientId(ctx.request.body);
|
|
114
|
+
const authenticatedClientId = basicClientId(ctx.headers.authorization);
|
|
115
|
+
if (queryClientId !== undefined)
|
|
116
|
+
candidates.add(queryClientId);
|
|
117
|
+
if (parsedBodyClientId !== undefined)
|
|
118
|
+
candidates.add(parsedBodyClientId);
|
|
119
|
+
if (authenticatedClientId !== undefined)
|
|
120
|
+
candidates.add(authenticatedClientId);
|
|
121
|
+
for (const clientId of candidates) {
|
|
122
|
+
const client = await getClientByClientId(clientId);
|
|
123
|
+
if (client === null || client.organizationId !== organizationId) {
|
|
124
|
+
observeProtocolSecurityRejection({
|
|
125
|
+
request: ctx.req,
|
|
126
|
+
eventClass: 'client-tenant-binding-rejected',
|
|
127
|
+
clientId,
|
|
128
|
+
});
|
|
129
|
+
ctx.throw(404, 'Client not found');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (isUserinfoRequest(ctx.method, ctx.path, ctx.params?.orgSlug)) {
|
|
133
|
+
const token = userinfoToken(ctx.method, ctx.headers.authorization, ctx.request.body);
|
|
134
|
+
if (token !== undefined) {
|
|
135
|
+
const accessToken = await provider.AccessToken.find(token);
|
|
136
|
+
if (accessToken !== undefined) {
|
|
137
|
+
const clientId = boundedClientId(accessToken.clientId);
|
|
138
|
+
const client = clientId === undefined ? null : await getClientByClientId(clientId);
|
|
139
|
+
if (client === null ||
|
|
140
|
+
client.status !== 'active' ||
|
|
141
|
+
client.organizationId !== organizationId) {
|
|
142
|
+
observeProtocolSecurityRejection({
|
|
143
|
+
request: ctx.req,
|
|
144
|
+
eventClass: 'userinfo-rejected',
|
|
145
|
+
clientId,
|
|
146
|
+
});
|
|
147
|
+
rejectUserinfoToken(ctx);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
await next();
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=oidc-client-tenant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-client-tenant.js","sourceRoot":"","sources":["../../src/middleware/oidc-client-tenant.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS handler for OIDC endpoints.
|
|
3
|
+
*
|
|
4
|
+
* node-oidc-provider accepts a `clientBasedCORS` configuration function
|
|
5
|
+
* that determines whether a given origin is allowed for CORS requests.
|
|
6
|
+
*
|
|
7
|
+
* Origin resolution follows a two-tier strategy:
|
|
8
|
+
* 1. **Explicit allowed_origins** — checks the client's `allowed_origins`
|
|
9
|
+
* field from the database (stored as `urn:porta:allowed_origins` in
|
|
10
|
+
* provider metadata).
|
|
11
|
+
* 2. **Redirect URI derivation** — extracts the origin (scheme + host +
|
|
12
|
+
* port) from each of the client's registered `redirect_uris`. If the
|
|
13
|
+
* requesting origin matches any redirect URI's origin, CORS is allowed.
|
|
14
|
+
* This is safe because the client already trusts those origins for
|
|
15
|
+
* redirect flows.
|
|
16
|
+
*
|
|
17
|
+
* In development mode, all origins are allowed for convenience.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Determine if a CORS origin is allowed for OIDC requests.
|
|
21
|
+
*
|
|
22
|
+
* Called by node-oidc-provider for cross-origin requests to OIDC endpoints
|
|
23
|
+
* (e.g., /token from a browser-based SPA). Checks if the requesting origin
|
|
24
|
+
* matches the client's registered allowed_origins or the origin of any
|
|
25
|
+
* registered redirect_uri.
|
|
26
|
+
*
|
|
27
|
+
* @param _ctx - Koa context with OIDC extensions
|
|
28
|
+
* @param origin - The requesting origin (e.g., 'https://app.example.com')
|
|
29
|
+
* @param client - The matched OIDC client metadata (may be undefined for non-client requests)
|
|
30
|
+
* @returns true if the origin is allowed, false otherwise
|
|
31
|
+
*/
|
|
32
|
+
export declare function oidcCors(_ctx: unknown, origin: string, client: unknown): boolean;
|
|
33
|
+
//# sourceMappingURL=oidc-cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-cors.d.ts","sourceRoot":"","sources":["../../src/middleware/oidc-cors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,GACd,OAAO,CAqCT"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS handler for OIDC endpoints.
|
|
3
|
+
*
|
|
4
|
+
* node-oidc-provider accepts a `clientBasedCORS` configuration function
|
|
5
|
+
* that determines whether a given origin is allowed for CORS requests.
|
|
6
|
+
*
|
|
7
|
+
* Origin resolution follows a two-tier strategy:
|
|
8
|
+
* 1. **Explicit allowed_origins** — checks the client's `allowed_origins`
|
|
9
|
+
* field from the database (stored as `urn:porta:allowed_origins` in
|
|
10
|
+
* provider metadata).
|
|
11
|
+
* 2. **Redirect URI derivation** — extracts the origin (scheme + host +
|
|
12
|
+
* port) from each of the client's registered `redirect_uris`. If the
|
|
13
|
+
* requesting origin matches any redirect URI's origin, CORS is allowed.
|
|
14
|
+
* This is safe because the client already trusts those origins for
|
|
15
|
+
* redirect flows.
|
|
16
|
+
*
|
|
17
|
+
* In development mode, all origins are allowed for convenience.
|
|
18
|
+
*/
|
|
19
|
+
import { config } from '../config/index.js';
|
|
20
|
+
/**
|
|
21
|
+
* Determine if a CORS origin is allowed for OIDC requests.
|
|
22
|
+
*
|
|
23
|
+
* Called by node-oidc-provider for cross-origin requests to OIDC endpoints
|
|
24
|
+
* (e.g., /token from a browser-based SPA). Checks if the requesting origin
|
|
25
|
+
* matches the client's registered allowed_origins or the origin of any
|
|
26
|
+
* registered redirect_uri.
|
|
27
|
+
*
|
|
28
|
+
* @param _ctx - Koa context with OIDC extensions
|
|
29
|
+
* @param origin - The requesting origin (e.g., 'https://app.example.com')
|
|
30
|
+
* @param client - The matched OIDC client metadata (may be undefined for non-client requests)
|
|
31
|
+
* @returns true if the origin is allowed, false otherwise
|
|
32
|
+
*/
|
|
33
|
+
export function oidcCors(_ctx, origin, client) {
|
|
34
|
+
// In development, allow all origins for convenience during local testing
|
|
35
|
+
if (config.nodeEnv === 'development')
|
|
36
|
+
return true;
|
|
37
|
+
// If no client context, deny CORS (non-client requests shouldn't have CORS)
|
|
38
|
+
if (!client)
|
|
39
|
+
return false;
|
|
40
|
+
// Cast to access client metadata properties.
|
|
41
|
+
// findForOidc() stores allowed_origins under the namespaced key
|
|
42
|
+
// 'urn:porta:allowed_origins' (required by extraClientMetadata config).
|
|
43
|
+
// redirect_uris is a standard OIDC property always present on clients.
|
|
44
|
+
const clientMeta = client;
|
|
45
|
+
// 1. Check explicit allowed_origins
|
|
46
|
+
const allowedOrigins = clientMeta['urn:porta:allowed_origins'] ?? [];
|
|
47
|
+
if (allowedOrigins.includes(origin))
|
|
48
|
+
return true;
|
|
49
|
+
// 2. Derive origins from redirect_uris — if the client has a redirect_uri
|
|
50
|
+
// at a given origin, it's safe to allow CORS from that origin.
|
|
51
|
+
// new URL(uri).origin extracts 'scheme://host[:port]', which is exactly
|
|
52
|
+
// what the browser sends as the CORS Origin header.
|
|
53
|
+
const redirectUris = clientMeta.redirect_uris ?? [];
|
|
54
|
+
for (const uri of redirectUris) {
|
|
55
|
+
try {
|
|
56
|
+
const { origin: redirectOrigin } = new URL(uri);
|
|
57
|
+
// Skip native app schemes (e.g., 'myapp://callback') which produce
|
|
58
|
+
// 'null' as origin — native apps don't make browser CORS requests.
|
|
59
|
+
if (redirectOrigin !== 'null' && redirectOrigin === origin)
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Skip malformed URIs
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=oidc-cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-cors.js","sourceRoot":"","sources":["../../src/middleware/oidc-cors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAa,EACb,MAAc,EACd,MAAe;IAEf,yEAAyE;IACzE,IAAI,MAAM,CAAC,OAAO,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IAElD,4EAA4E;IAC5E,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,6CAA6C;IAC7C,gEAAgE;IAChE,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,UAAU,GAAG,MAGlB,CAAC;IAEF,oCAAoC;IACpC,MAAM,cAAc,GAAG,UAAU,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC;IACrE,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,0EAA0E;IAC1E,kEAAkE;IAClE,2EAA2E;IAC3E,uDAAuD;IACvD,MAAM,YAAY,GAAG,UAAU,CAAC,aAAa,IAAI,EAAE,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAChD,mEAAmE;YACnE,mEAAmE;YACnE,IAAI,cAAc,KAAK,MAAM,IAAI,cAAc,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC CORS middleware — pre-sets CORS headers at the outer Koa level.
|
|
3
|
+
*
|
|
4
|
+
* Solves a fundamental issue with node-oidc-provider's CORS handling:
|
|
5
|
+
* the provider uses @koa/cors with `keepHeadersOnError: false`, which
|
|
6
|
+
* means CORS headers are stripped from error responses (e.g., 400 from
|
|
7
|
+
* the token endpoint). SPAs that exchange authorization codes or refresh
|
|
8
|
+
* tokens via cross-origin fetch() cannot read error responses, breaking
|
|
9
|
+
* error handling in browser-based OIDC flows.
|
|
10
|
+
*
|
|
11
|
+
* How this middleware fixes it:
|
|
12
|
+
*
|
|
13
|
+
* 1. It sets `Access-Control-Allow-Origin` and related headers BEFORE
|
|
14
|
+
* the request enters oidc-provider's internal Koa context.
|
|
15
|
+
*
|
|
16
|
+
* 2. The provider's `cors.js` middleware detects existing `access-control-*`
|
|
17
|
+
* headers and SKIPS its own CORS handling entirely (see
|
|
18
|
+
* node_modules/oidc-provider/lib/shared/cors.js lines 32-37).
|
|
19
|
+
*
|
|
20
|
+
* 3. Because the headers are set at the outer Koa level and the provider
|
|
21
|
+
* doesn't touch them, they survive regardless of whether the OIDC
|
|
22
|
+
* endpoint succeeds or returns an error.
|
|
23
|
+
*
|
|
24
|
+
* Origin validation follows the same two-tier strategy as `oidc-cors.ts`:
|
|
25
|
+
* - In development mode: all origins are allowed.
|
|
26
|
+
* - In production: the client's `allowed_origins` and `redirect_uris`
|
|
27
|
+
* are checked. The client is identified from the `client_id` body
|
|
28
|
+
* parameter (standard for token, revocation, and introspection
|
|
29
|
+
* endpoints). If no client_id is present or the client cannot be
|
|
30
|
+
* found, no CORS headers are set — the request proceeds but the
|
|
31
|
+
* browser will block the response (correct security behavior).
|
|
32
|
+
*
|
|
33
|
+
* Placement: mount in the `oidcRouter` (server.ts) AFTER the body parser
|
|
34
|
+
* (so `client_id` is available from `ctx.request.body`) but BEFORE the
|
|
35
|
+
* `clientSecretHash` middleware and the provider delegation handler.
|
|
36
|
+
*
|
|
37
|
+
* For OIDC endpoints that don't require client authentication (e.g.,
|
|
38
|
+
* JWKS, discovery), CORS is always allowed — these are public endpoints
|
|
39
|
+
* that any origin may access. The middleware detects these by path.
|
|
40
|
+
*
|
|
41
|
+
* @module middleware/oidc-preflight-cors
|
|
42
|
+
*/
|
|
43
|
+
import type { Middleware } from 'koa';
|
|
44
|
+
/**
|
|
45
|
+
* Create the OIDC CORS middleware.
|
|
46
|
+
*
|
|
47
|
+
* Must be mounted in the oidcRouter AFTER the body parser (so
|
|
48
|
+
* `client_id` is available) but BEFORE `clientSecretHash` and the
|
|
49
|
+
* provider delegation handler.
|
|
50
|
+
*
|
|
51
|
+
* @returns Koa middleware that pre-sets CORS headers for OIDC routes
|
|
52
|
+
*/
|
|
53
|
+
export declare function oidcPreflightCors(): Middleware;
|
|
54
|
+
//# sourceMappingURL=oidc-preflight-cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-preflight-cors.d.ts","sourceRoot":"","sources":["../../src/middleware/oidc-preflight-cors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AA4JtC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CAiG9C"}
|