@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,34 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Configurable Login Methods (plans/client-login-methods)
|
|
4
|
+
-- Adds organization-level default login methods + per-client override.
|
|
5
|
+
-- Two-level inheritance model:
|
|
6
|
+
-- 1. organizations.default_login_methods — org-wide default (NOT NULL, defaults to {password, magic_link})
|
|
7
|
+
-- 2. clients.login_methods — per-client override (NULL = inherit from org)
|
|
8
|
+
--
|
|
9
|
+
-- Future-proof design: TEXT[] without a value CHECK so adding 'sso' or 'passkey' later
|
|
10
|
+
-- is a pure TypeScript change with no migration required. All writes are funneled through
|
|
11
|
+
-- the service layer, which validates against the LoginMethod TypeScript union.
|
|
12
|
+
|
|
13
|
+
-- Organizations: default authentication methods for all clients in the org.
|
|
14
|
+
ALTER TABLE organizations
|
|
15
|
+
ADD COLUMN default_login_methods TEXT[] NOT NULL
|
|
16
|
+
DEFAULT ARRAY['password', 'magic_link']::TEXT[];
|
|
17
|
+
|
|
18
|
+
COMMENT ON COLUMN organizations.default_login_methods IS
|
|
19
|
+
'Default authentication methods available for all clients in this org. Clients may override via clients.login_methods. Values: password, magic_link (extensible — sso/passkey in future).';
|
|
20
|
+
|
|
21
|
+
-- Clients: per-client override of org default. NULL = inherit from org.
|
|
22
|
+
-- Empty array ({}) is invalid and rejected by the service layer (NULL is the canonical
|
|
23
|
+
-- "inherit" sentinel). Non-null values must be a non-empty subset of LoginMethod.
|
|
24
|
+
ALTER TABLE clients
|
|
25
|
+
ADD COLUMN login_methods TEXT[] DEFAULT NULL;
|
|
26
|
+
|
|
27
|
+
COMMENT ON COLUMN clients.login_methods IS
|
|
28
|
+
'Authentication methods for this client. NULL = inherit from organizations.default_login_methods. Non-null must be non-empty.';
|
|
29
|
+
|
|
30
|
+
-- Down Migration
|
|
31
|
+
|
|
32
|
+
-- Drop in reverse order of creation (clients first since it's the leaf).
|
|
33
|
+
ALTER TABLE clients DROP COLUMN IF EXISTS login_methods;
|
|
34
|
+
ALTER TABLE organizations DROP COLUMN IF EXISTS default_login_methods;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Add encryption metadata columns to signing_keys table.
|
|
4
|
+
-- These support AES-256-GCM envelope encryption of private keys at rest.
|
|
5
|
+
-- Existing rows keep encrypted = false (plaintext) for backward compatibility.
|
|
6
|
+
ALTER TABLE signing_keys
|
|
7
|
+
ADD COLUMN private_key_iv VARCHAR(24),
|
|
8
|
+
ADD COLUMN private_key_tag VARCHAR(32),
|
|
9
|
+
ADD COLUMN encrypted BOOLEAN NOT NULL DEFAULT false;
|
|
10
|
+
|
|
11
|
+
COMMENT ON COLUMN signing_keys.private_key_iv IS 'AES-256-GCM initialization vector (hex) — NULL for unencrypted legacy keys';
|
|
12
|
+
COMMENT ON COLUMN signing_keys.private_key_tag IS 'AES-256-GCM authentication tag (hex) — NULL for unencrypted legacy keys';
|
|
13
|
+
COMMENT ON COLUMN signing_keys.encrypted IS 'Whether private_key is AES-256-GCM encrypted (false = plaintext legacy)';
|
|
14
|
+
|
|
15
|
+
-- Down Migration
|
|
16
|
+
|
|
17
|
+
ALTER TABLE signing_keys
|
|
18
|
+
DROP COLUMN IF EXISTS private_key_iv,
|
|
19
|
+
DROP COLUMN IF EXISTS private_key_tag,
|
|
20
|
+
DROP COLUMN IF EXISTS encrypted;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Add failed login tracking columns for account lockout.
|
|
4
|
+
-- Tracks consecutive failed password attempts per user and enables
|
|
5
|
+
-- automatic account lockout after exceeding the configured threshold
|
|
6
|
+
-- (system_config: max_failed_logins, lockout_duration_seconds).
|
|
7
|
+
--
|
|
8
|
+
-- The counter resets to 0 on successful login. Auto-locked accounts
|
|
9
|
+
-- (locked_reason = 'auto_lockout') auto-unlock after the cooldown.
|
|
10
|
+
|
|
11
|
+
ALTER TABLE users
|
|
12
|
+
ADD COLUMN IF NOT EXISTS failed_login_count INTEGER NOT NULL DEFAULT 0,
|
|
13
|
+
ADD COLUMN IF NOT EXISTS last_failed_login_at TIMESTAMPTZ;
|
|
14
|
+
|
|
15
|
+
-- Partial index for efficient auto-unlock queries: find locked users
|
|
16
|
+
-- whose cooldown has elapsed. Only indexes auto-locked rows.
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_users_locked_auto
|
|
18
|
+
ON users (locked_at)
|
|
19
|
+
WHERE status = 'locked' AND locked_reason = 'auto_lockout';
|
|
20
|
+
|
|
21
|
+
-- Down Migration
|
|
22
|
+
|
|
23
|
+
DROP INDEX IF EXISTS idx_users_locked_auto;
|
|
24
|
+
|
|
25
|
+
ALTER TABLE users
|
|
26
|
+
DROP COLUMN IF EXISTS last_failed_login_at,
|
|
27
|
+
DROP COLUMN IF EXISTS failed_login_count;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Add audit_retention_days system config value.
|
|
4
|
+
-- Controls how long audit log entries are kept before cleanup.
|
|
5
|
+
-- Used by `porta audit cleanup` CLI command.
|
|
6
|
+
INSERT INTO system_config (key, value, value_type, description, is_sensitive) VALUES
|
|
7
|
+
('audit_retention_days', '90', 'number', 'Number of days to retain audit log entries (default: 90 days)', FALSE);
|
|
8
|
+
|
|
9
|
+
-- Down Migration
|
|
10
|
+
|
|
11
|
+
DELETE FROM system_config WHERE key = 'audit_retention_days';
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Admin API Enhancements (RD-21)
|
|
4
|
+
-- Adds branding_assets table for organization logo/favicon image storage
|
|
5
|
+
-- and admin_sessions table for OIDC session tracking and management.
|
|
6
|
+
|
|
7
|
+
-- ============================================================================
|
|
8
|
+
-- Branding Assets: Organization logo/favicon storage
|
|
9
|
+
-- ============================================================================
|
|
10
|
+
-- Images stored as PostgreSQL bytea (simple deployment, images are small).
|
|
11
|
+
-- Unique constraint ensures one logo and one favicon per organization.
|
|
12
|
+
|
|
13
|
+
CREATE TABLE IF NOT EXISTS branding_assets (
|
|
14
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
15
|
+
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
16
|
+
asset_type VARCHAR(20) NOT NULL, -- 'logo', 'favicon'
|
|
17
|
+
content_type VARCHAR(50) NOT NULL, -- 'image/png', 'image/svg+xml', etc.
|
|
18
|
+
data BYTEA NOT NULL,
|
|
19
|
+
file_size INTEGER NOT NULL,
|
|
20
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
21
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
22
|
+
CONSTRAINT branding_assets_unique_org_type UNIQUE(organization_id, asset_type),
|
|
23
|
+
CONSTRAINT branding_assets_valid_type CHECK (asset_type IN ('logo', 'favicon')),
|
|
24
|
+
CONSTRAINT branding_assets_valid_size CHECK (file_size > 0 AND file_size <= 524288)
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
-- Index for looking up assets by organization
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_branding_assets_org_id
|
|
29
|
+
ON branding_assets(organization_id);
|
|
30
|
+
|
|
31
|
+
-- ============================================================================
|
|
32
|
+
-- Admin Sessions: OIDC session tracking for admin viewer/revocation
|
|
33
|
+
-- ============================================================================
|
|
34
|
+
-- PostgreSQL mirror of Redis OIDC sessions. Populated via adapter hooks
|
|
35
|
+
-- (fire-and-forget) for listing, filtering, and admin revocation.
|
|
36
|
+
-- Active sessions have revoked_at IS NULL.
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS admin_sessions (
|
|
39
|
+
session_id VARCHAR(128) PRIMARY KEY,
|
|
40
|
+
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
|
41
|
+
client_id UUID REFERENCES clients(id) ON DELETE SET NULL,
|
|
42
|
+
organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
|
|
43
|
+
grant_id VARCHAR(128),
|
|
44
|
+
ip_address INET,
|
|
45
|
+
user_agent TEXT,
|
|
46
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
47
|
+
expires_at TIMESTAMPTZ NOT NULL,
|
|
48
|
+
last_activity_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
49
|
+
revoked_at TIMESTAMPTZ,
|
|
50
|
+
CONSTRAINT admin_sessions_not_expired CHECK (expires_at > created_at)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
-- Partial indexes for efficient querying of active sessions
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_admin_sessions_user_active
|
|
55
|
+
ON admin_sessions(user_id)
|
|
56
|
+
WHERE revoked_at IS NULL;
|
|
57
|
+
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_admin_sessions_org_active
|
|
59
|
+
ON admin_sessions(organization_id)
|
|
60
|
+
WHERE revoked_at IS NULL;
|
|
61
|
+
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_admin_sessions_client_active
|
|
63
|
+
ON admin_sessions(client_id)
|
|
64
|
+
WHERE revoked_at IS NULL;
|
|
65
|
+
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_admin_sessions_expires
|
|
67
|
+
ON admin_sessions(expires_at)
|
|
68
|
+
WHERE revoked_at IS NULL;
|
|
69
|
+
|
|
70
|
+
-- Index for grant-based session lookup (used during revocation cascade)
|
|
71
|
+
CREATE INDEX IF NOT EXISTS idx_admin_sessions_grant_id
|
|
72
|
+
ON admin_sessions(grant_id)
|
|
73
|
+
WHERE grant_id IS NOT NULL;
|
|
74
|
+
|
|
75
|
+
-- Down Migration
|
|
76
|
+
|
|
77
|
+
DROP TABLE IF EXISTS admin_sessions;
|
|
78
|
+
DROP TABLE IF EXISTS branding_assets;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Migration 019: Add details JSONB column to invitation_tokens
|
|
4
|
+
--
|
|
5
|
+
-- Stores pre-assignment metadata (roles, claims, personal message, inviter)
|
|
6
|
+
-- in the invitation token so they can be applied when the invitation is accepted.
|
|
7
|
+
--
|
|
8
|
+
-- The details column is nullable — existing tokens without details continue
|
|
9
|
+
-- to work exactly as before (backward compatible).
|
|
10
|
+
|
|
11
|
+
ALTER TABLE invitation_tokens
|
|
12
|
+
ADD COLUMN details JSONB;
|
|
13
|
+
|
|
14
|
+
-- Add invited_by column to track which admin user created the invitation
|
|
15
|
+
ALTER TABLE invitation_tokens
|
|
16
|
+
ADD COLUMN invited_by UUID REFERENCES users(id) ON DELETE SET NULL;
|
|
17
|
+
|
|
18
|
+
COMMENT ON COLUMN invitation_tokens.details IS
|
|
19
|
+
'Optional JSONB storing pre-assignment metadata: roles, claims, personalMessage, inviterName';
|
|
20
|
+
|
|
21
|
+
COMMENT ON COLUMN invitation_tokens.invited_by IS
|
|
22
|
+
'User ID of the admin who created this invitation';
|
|
23
|
+
|
|
24
|
+
-- Down Migration
|
|
25
|
+
|
|
26
|
+
ALTER TABLE invitation_tokens DROP COLUMN IF EXISTS invited_by;
|
|
27
|
+
ALTER TABLE invitation_tokens DROP COLUMN IF EXISTS details;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Migration 020: Add admin:user:2fa permission for 2FA admin API management
|
|
4
|
+
--
|
|
5
|
+
-- This migration adds the admin:user:2fa permission to the porta-admin
|
|
6
|
+
-- application and assigns it to the porta-super-admin, porta-user-admin,
|
|
7
|
+
-- and porta-admin (legacy) roles.
|
|
8
|
+
--
|
|
9
|
+
-- The permission governs state-changing 2FA admin operations:
|
|
10
|
+
-- - POST .../two-factor/disable
|
|
11
|
+
-- - POST .../two-factor/reset
|
|
12
|
+
-- - POST .../two-factor/recovery-codes/regenerate
|
|
13
|
+
--
|
|
14
|
+
-- Read-only status inspection uses the existing admin:user:read permission.
|
|
15
|
+
--
|
|
16
|
+
-- Idempotent: uses INSERT ... ON CONFLICT DO NOTHING throughout.
|
|
17
|
+
|
|
18
|
+
DO $$
|
|
19
|
+
DECLARE
|
|
20
|
+
v_app_id UUID;
|
|
21
|
+
v_perm_id UUID;
|
|
22
|
+
v_super_admin_role_id UUID;
|
|
23
|
+
v_user_admin_role_id UUID;
|
|
24
|
+
v_legacy_admin_role_id UUID;
|
|
25
|
+
BEGIN
|
|
26
|
+
-- Find the porta-admin application
|
|
27
|
+
SELECT id INTO v_app_id
|
|
28
|
+
FROM applications
|
|
29
|
+
WHERE slug = 'porta-admin'
|
|
30
|
+
LIMIT 1;
|
|
31
|
+
|
|
32
|
+
-- If porta-admin app doesn't exist, skip (pre-init state)
|
|
33
|
+
IF v_app_id IS NULL THEN
|
|
34
|
+
RAISE NOTICE 'porta-admin application not found — skipping 2FA permission seed';
|
|
35
|
+
RETURN;
|
|
36
|
+
END IF;
|
|
37
|
+
|
|
38
|
+
-- Insert the permission
|
|
39
|
+
INSERT INTO permissions (application_id, slug, name, description, status)
|
|
40
|
+
VALUES (
|
|
41
|
+
v_app_id,
|
|
42
|
+
'admin:user:2fa',
|
|
43
|
+
'Manage User 2FA',
|
|
44
|
+
'Disable, reset, or regenerate recovery codes for user two-factor authentication',
|
|
45
|
+
'active'
|
|
46
|
+
)
|
|
47
|
+
ON CONFLICT (application_id, slug) DO NOTHING
|
|
48
|
+
RETURNING id INTO v_perm_id;
|
|
49
|
+
|
|
50
|
+
-- If permission already existed, look it up
|
|
51
|
+
IF v_perm_id IS NULL THEN
|
|
52
|
+
SELECT id INTO v_perm_id
|
|
53
|
+
FROM permissions
|
|
54
|
+
WHERE application_id = v_app_id AND slug = 'admin:user:2fa';
|
|
55
|
+
END IF;
|
|
56
|
+
|
|
57
|
+
-- Find role IDs
|
|
58
|
+
SELECT id INTO v_super_admin_role_id
|
|
59
|
+
FROM roles
|
|
60
|
+
WHERE application_id = v_app_id AND slug = 'porta-super-admin';
|
|
61
|
+
|
|
62
|
+
SELECT id INTO v_user_admin_role_id
|
|
63
|
+
FROM roles
|
|
64
|
+
WHERE application_id = v_app_id AND slug = 'porta-user-admin';
|
|
65
|
+
|
|
66
|
+
SELECT id INTO v_legacy_admin_role_id
|
|
67
|
+
FROM roles
|
|
68
|
+
WHERE application_id = v_app_id AND slug = 'porta-admin';
|
|
69
|
+
|
|
70
|
+
-- Assign permission to roles
|
|
71
|
+
IF v_super_admin_role_id IS NOT NULL AND v_perm_id IS NOT NULL THEN
|
|
72
|
+
INSERT INTO role_permissions (role_id, permission_id)
|
|
73
|
+
VALUES (v_super_admin_role_id, v_perm_id)
|
|
74
|
+
ON CONFLICT DO NOTHING;
|
|
75
|
+
END IF;
|
|
76
|
+
|
|
77
|
+
IF v_user_admin_role_id IS NOT NULL AND v_perm_id IS NOT NULL THEN
|
|
78
|
+
INSERT INTO role_permissions (role_id, permission_id)
|
|
79
|
+
VALUES (v_user_admin_role_id, v_perm_id)
|
|
80
|
+
ON CONFLICT DO NOTHING;
|
|
81
|
+
END IF;
|
|
82
|
+
|
|
83
|
+
IF v_legacy_admin_role_id IS NOT NULL AND v_perm_id IS NOT NULL THEN
|
|
84
|
+
INSERT INTO role_permissions (role_id, permission_id)
|
|
85
|
+
VALUES (v_legacy_admin_role_id, v_perm_id)
|
|
86
|
+
ON CONFLICT DO NOTHING;
|
|
87
|
+
END IF;
|
|
88
|
+
|
|
89
|
+
RAISE NOTICE 'admin:user:2fa permission seeded successfully';
|
|
90
|
+
END $$;
|
|
91
|
+
|
|
92
|
+
-- Down Migration
|
|
93
|
+
|
|
94
|
+
-- Remove the admin:user:2fa permission (CASCADE removes role_permissions mappings)
|
|
95
|
+
DO $$
|
|
96
|
+
DECLARE
|
|
97
|
+
v_app_id UUID;
|
|
98
|
+
BEGIN
|
|
99
|
+
SELECT id INTO v_app_id
|
|
100
|
+
FROM applications
|
|
101
|
+
WHERE slug = 'porta-admin'
|
|
102
|
+
LIMIT 1;
|
|
103
|
+
|
|
104
|
+
IF v_app_id IS NOT NULL THEN
|
|
105
|
+
DELETE FROM permissions
|
|
106
|
+
WHERE application_id = v_app_id AND slug = 'admin:user:2fa';
|
|
107
|
+
END IF;
|
|
108
|
+
END $$;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Durable recovery work keeps public authentication requests independent from account existence.
|
|
4
|
+
-- Protected addresses are encrypted before insertion; this table never stores plaintext addresses
|
|
5
|
+
-- or authentication artifacts.
|
|
6
|
+
CREATE TABLE auth_recovery_jobs (
|
|
7
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
8
|
+
job_type VARCHAR(32) NOT NULL,
|
|
9
|
+
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
10
|
+
address_ciphertext TEXT NOT NULL,
|
|
11
|
+
address_iv TEXT NOT NULL,
|
|
12
|
+
address_tag TEXT NOT NULL,
|
|
13
|
+
address_key_id VARCHAR(64) NOT NULL,
|
|
14
|
+
interaction_uid VARCHAR(128),
|
|
15
|
+
idempotency_digest CHAR(64) NOT NULL,
|
|
16
|
+
status VARCHAR(24) NOT NULL DEFAULT 'available',
|
|
17
|
+
available_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
18
|
+
claimed_at TIMESTAMPTZ,
|
|
19
|
+
claimed_by UUID,
|
|
20
|
+
attempt_count SMALLINT NOT NULL DEFAULT 0,
|
|
21
|
+
last_failure_reason VARCHAR(64),
|
|
22
|
+
completed_at TIMESTAMPTZ,
|
|
23
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
24
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
25
|
+
CONSTRAINT auth_recovery_jobs_type
|
|
26
|
+
CHECK (job_type IN ('magic_link', 'password_reset')),
|
|
27
|
+
CONSTRAINT auth_recovery_jobs_status
|
|
28
|
+
CHECK (status IN ('available', 'claimed', 'completed', 'terminal_failure')),
|
|
29
|
+
CONSTRAINT auth_recovery_jobs_attempt_count
|
|
30
|
+
CHECK (attempt_count BETWEEN 0 AND 5),
|
|
31
|
+
CONSTRAINT auth_recovery_jobs_idempotency_digest
|
|
32
|
+
CHECK (idempotency_digest ~ '^[0-9a-f]{64}$'),
|
|
33
|
+
CONSTRAINT auth_recovery_jobs_protected_address
|
|
34
|
+
CHECK (
|
|
35
|
+
address_ciphertext ~ '^[A-Za-z0-9_-]+$'
|
|
36
|
+
AND address_iv ~ '^[A-Za-z0-9_-]+$'
|
|
37
|
+
AND address_tag ~ '^[A-Za-z0-9_-]+$'
|
|
38
|
+
AND address_key_id ~ '^[A-Za-z0-9_-]{8,64}$'
|
|
39
|
+
),
|
|
40
|
+
CONSTRAINT auth_recovery_jobs_interaction_uid
|
|
41
|
+
CHECK (
|
|
42
|
+
(job_type = 'magic_link' AND char_length(interaction_uid) BETWEEN 1 AND 128)
|
|
43
|
+
OR (job_type = 'password_reset' AND interaction_uid IS NULL)
|
|
44
|
+
),
|
|
45
|
+
CONSTRAINT auth_recovery_jobs_failure_reason
|
|
46
|
+
CHECK (
|
|
47
|
+
last_failure_reason IS NULL
|
|
48
|
+
OR last_failure_reason ~ '^[a-z][a-z0-9_]{0,63}$'
|
|
49
|
+
),
|
|
50
|
+
CONSTRAINT auth_recovery_jobs_claim_state
|
|
51
|
+
CHECK (
|
|
52
|
+
(status = 'claimed' AND claimed_at IS NOT NULL AND claimed_by IS NOT NULL)
|
|
53
|
+
OR (status <> 'claimed' AND claimed_at IS NULL AND claimed_by IS NULL)
|
|
54
|
+
),
|
|
55
|
+
CONSTRAINT auth_recovery_jobs_completion_state
|
|
56
|
+
CHECK (
|
|
57
|
+
(status IN ('completed', 'terminal_failure') AND completed_at IS NOT NULL)
|
|
58
|
+
OR (status NOT IN ('completed', 'terminal_failure') AND completed_at IS NULL)
|
|
59
|
+
),
|
|
60
|
+
CONSTRAINT auth_recovery_jobs_idempotency
|
|
61
|
+
UNIQUE (organization_id, job_type, idempotency_digest)
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
CREATE INDEX auth_recovery_jobs_available
|
|
65
|
+
ON auth_recovery_jobs (available_at, created_at, id)
|
|
66
|
+
WHERE status = 'available' AND attempt_count < 5;
|
|
67
|
+
|
|
68
|
+
CREATE INDEX auth_recovery_jobs_expired_claims
|
|
69
|
+
ON auth_recovery_jobs (claimed_at, created_at, id)
|
|
70
|
+
WHERE status = 'claimed' AND attempt_count < 5;
|
|
71
|
+
|
|
72
|
+
-- Down Migration
|
|
73
|
+
|
|
74
|
+
DROP TABLE IF EXISTS auth_recovery_jobs;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- A durable recovery job may create at most one token artifact. The plaintext token is derived
|
|
4
|
+
-- deterministically from the protected job identity, so a retry can safely reuse the same link.
|
|
5
|
+
ALTER TABLE magic_link_tokens
|
|
6
|
+
ADD COLUMN recovery_job_id UUID REFERENCES auth_recovery_jobs(id) ON DELETE SET NULL;
|
|
7
|
+
|
|
8
|
+
ALTER TABLE password_reset_tokens
|
|
9
|
+
ADD COLUMN recovery_job_id UUID REFERENCES auth_recovery_jobs(id) ON DELETE SET NULL;
|
|
10
|
+
|
|
11
|
+
CREATE UNIQUE INDEX magic_link_tokens_recovery_job
|
|
12
|
+
ON magic_link_tokens (recovery_job_id)
|
|
13
|
+
WHERE recovery_job_id IS NOT NULL;
|
|
14
|
+
|
|
15
|
+
CREATE UNIQUE INDEX password_reset_tokens_recovery_job
|
|
16
|
+
ON password_reset_tokens (recovery_job_id)
|
|
17
|
+
WHERE recovery_job_id IS NOT NULL;
|
|
18
|
+
|
|
19
|
+
-- Down Migration
|
|
20
|
+
|
|
21
|
+
DROP INDEX IF EXISTS password_reset_tokens_recovery_job;
|
|
22
|
+
DROP INDEX IF EXISTS magic_link_tokens_recovery_job;
|
|
23
|
+
|
|
24
|
+
ALTER TABLE password_reset_tokens DROP COLUMN IF EXISTS recovery_job_id;
|
|
25
|
+
ALTER TABLE magic_link_tokens DROP COLUMN IF EXISTS recovery_job_id;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
-- Up Migration
|
|
2
|
+
|
|
3
|
+
-- Magic-link authority is persisted when a new artifact is created. Existing rows receive their
|
|
4
|
+
-- durable user organization only so the column can become mandatory, but remain explicitly
|
|
5
|
+
-- unbound because their original interaction authority cannot be reconstructed safely.
|
|
6
|
+
ALTER TABLE magic_link_tokens
|
|
7
|
+
ADD COLUMN organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
|
|
8
|
+
ADD COLUMN interaction_uid VARCHAR(128),
|
|
9
|
+
ADD COLUMN authority_bound BOOLEAN;
|
|
10
|
+
|
|
11
|
+
UPDATE magic_link_tokens AS token
|
|
12
|
+
SET organization_id = account.organization_id,
|
|
13
|
+
authority_bound = FALSE
|
|
14
|
+
FROM users AS account
|
|
15
|
+
WHERE account.id = token.user_id;
|
|
16
|
+
|
|
17
|
+
ALTER TABLE magic_link_tokens
|
|
18
|
+
ALTER COLUMN organization_id SET NOT NULL,
|
|
19
|
+
ALTER COLUMN authority_bound SET DEFAULT TRUE,
|
|
20
|
+
ALTER COLUMN authority_bound SET NOT NULL,
|
|
21
|
+
ADD CONSTRAINT magic_link_tokens_interaction_uid
|
|
22
|
+
CHECK (interaction_uid IS NULL OR char_length(interaction_uid) BETWEEN 1 AND 128),
|
|
23
|
+
ADD CONSTRAINT magic_link_tokens_recovery_authority
|
|
24
|
+
CHECK (recovery_job_id IS NULL OR authority_bound);
|
|
25
|
+
|
|
26
|
+
CREATE INDEX magic_link_tokens_authority_lookup
|
|
27
|
+
ON magic_link_tokens (token_hash, organization_id)
|
|
28
|
+
WHERE used_at IS NULL AND authority_bound;
|
|
29
|
+
|
|
30
|
+
-- Down Migration
|
|
31
|
+
|
|
32
|
+
DROP INDEX IF EXISTS magic_link_tokens_authority_lookup;
|
|
33
|
+
|
|
34
|
+
ALTER TABLE magic_link_tokens
|
|
35
|
+
DROP CONSTRAINT IF EXISTS magic_link_tokens_recovery_authority,
|
|
36
|
+
DROP CONSTRAINT IF EXISTS magic_link_tokens_interaction_uid,
|
|
37
|
+
DROP COLUMN IF EXISTS authority_bound,
|
|
38
|
+
DROP COLUMN IF EXISTS interaction_uid,
|
|
39
|
+
DROP COLUMN IF EXISTS organization_id;
|
package/package.json
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@portaidentity/server",
|
|
3
|
+
"version": "1.7.0",
|
|
4
|
+
"description": "Multi-tenant OIDC provider built on node-oidc-provider, Koa, and TypeScript",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"porta-server": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"locales",
|
|
13
|
+
"migrations",
|
|
14
|
+
"templates",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"CHANGELOG.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "../../node_modules/@typescript/native/bin/tsc",
|
|
21
|
+
"start": "node dist/index.js",
|
|
22
|
+
"dev": "tsx watch src/index.ts",
|
|
23
|
+
"test": "vitest run --project unit --project integration",
|
|
24
|
+
"test:all": "yarn test:unit && yarn test:integration && yarn test:e2e && yarn test:pentest",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"test:unit": "vitest run --project unit",
|
|
27
|
+
"test:integration": "vitest run --project integration",
|
|
28
|
+
"test:e2e": "vitest run --project e2e",
|
|
29
|
+
"test:pentest": "vitest run --project pentest",
|
|
30
|
+
"test:ui": "playwright test --config tests/ui/playwright.config.ts",
|
|
31
|
+
"test:ui:debug": "playwright test --config tests/ui/playwright.config.ts --headed --workers=1",
|
|
32
|
+
"test:coverage": "vitest run --coverage",
|
|
33
|
+
"lint": "eslint 'src/**/*.ts' 'tests/**/*.ts'",
|
|
34
|
+
"lint:fix": "eslint 'src/**/*.ts' 'tests/**/*.ts' --fix",
|
|
35
|
+
"typecheck": "../../node_modules/@typescript/native/bin/tsc --noEmit",
|
|
36
|
+
"format": "prettier --write 'src/**/*.ts' 'tests/**/*.ts'",
|
|
37
|
+
"format:check": "prettier --check 'src/**/*.ts' 'tests/**/*.ts'",
|
|
38
|
+
"verify": "yarn lint && yarn typecheck && yarn test:all && yarn build",
|
|
39
|
+
"migrate": "node-pg-migrate up --migrations-dir migrations --migration-file-language sql",
|
|
40
|
+
"migrate:rollback": "node-pg-migrate down --migrations-dir migrations --migration-file-language sql --count 1",
|
|
41
|
+
"migrate:status": "node-pg-migrate status --migrations-dir migrations --migration-file-language sql",
|
|
42
|
+
"migrate:create": "node-pg-migrate create --migrations-dir migrations --migration-file-language sql",
|
|
43
|
+
"porta": "tsx src/cli/index.ts",
|
|
44
|
+
"clean": "rm -rf dist"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@koa/router": "15.7.0",
|
|
48
|
+
"argon2": "0.45.1",
|
|
49
|
+
"chalk": "6.0.0",
|
|
50
|
+
"cli-table3": "0.6.5",
|
|
51
|
+
"dotenv": "17.4.2",
|
|
52
|
+
"handlebars": "4.7.9",
|
|
53
|
+
"i18next": "26.3.6",
|
|
54
|
+
"i18next-fs-backend": "2.6.7",
|
|
55
|
+
"ioredis": "6.0.0",
|
|
56
|
+
"jose": "6.2.8",
|
|
57
|
+
"koa": "3.2.1",
|
|
58
|
+
"koa-bodyparser": "4.4.1",
|
|
59
|
+
"node-pg-migrate": "9.0.0",
|
|
60
|
+
"nodemailer": "9.0.5",
|
|
61
|
+
"oidc-provider": "9.11.2",
|
|
62
|
+
"open": "11.0.0",
|
|
63
|
+
"otpauth": "9.5.1",
|
|
64
|
+
"pg": "8.23.0",
|
|
65
|
+
"pino": "10.3.1",
|
|
66
|
+
"pino-pretty": "13.1.3",
|
|
67
|
+
"prom-client": "^15",
|
|
68
|
+
"qrcode": "1.5.4",
|
|
69
|
+
"yaml": "2.9.0",
|
|
70
|
+
"yargs": "18.1.0",
|
|
71
|
+
"zod": "4.4.3"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@eslint/js": "10.0.1",
|
|
75
|
+
"@playwright/test": "1.62.1",
|
|
76
|
+
"@types/koa": "3.0.3",
|
|
77
|
+
"@types/koa-bodyparser": "4.3.13",
|
|
78
|
+
"@types/koa__router": "12.0.5",
|
|
79
|
+
"@types/node": "26.2.0",
|
|
80
|
+
"@types/nodemailer": "8.0.1",
|
|
81
|
+
"@types/oidc-provider": "9.11.1",
|
|
82
|
+
"@types/pg": "8.21.0",
|
|
83
|
+
"@types/qrcode": "1.5.6",
|
|
84
|
+
"@types/yargs": "17.0.35",
|
|
85
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
86
|
+
"@vitest/coverage-v8": "4.1.10",
|
|
87
|
+
"eslint": "10.8.1",
|
|
88
|
+
"eslint-config-prettier": "10.1.8",
|
|
89
|
+
"prettier": "3.9.6",
|
|
90
|
+
"tsx": "4.23.11",
|
|
91
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
92
|
+
"typescript-eslint": "8.66.0",
|
|
93
|
+
"vitest": "4.1.10"
|
|
94
|
+
},
|
|
95
|
+
"repository": {
|
|
96
|
+
"type": "git",
|
|
97
|
+
"url": "https://github.com/blendsdk/porta-identity.git",
|
|
98
|
+
"directory": "packages/server"
|
|
99
|
+
},
|
|
100
|
+
"publishConfig": {
|
|
101
|
+
"access": "public"
|
|
102
|
+
},
|
|
103
|
+
"engines": {
|
|
104
|
+
"node": ">=22.0.0"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<style>
|
|
7
|
+
body { font-family: system-ui, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
|
|
8
|
+
.wrapper { max-width: 560px; margin: 0 auto; padding: 40px 20px; }
|
|
9
|
+
.card { background: white; border-radius: 8px; padding: 32px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
10
|
+
.btn { display: inline-block; background: {{branding.primaryColor}}; color: white; text-decoration: none; padding: 12px 32px; border-radius: 4px; font-size: 16px; font-weight: 500; }
|
|
11
|
+
.footer { text-align: center; padding: 16px; color: #6b7280; font-size: 12px; }
|
|
12
|
+
.personal-message { background: #f9fafb; border-left: 3px solid {{branding.primaryColor}}; padding: 12px 16px; margin: 16px 0; border-radius: 0 4px 4px 0; color: #374151; font-style: italic; }
|
|
13
|
+
</style>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<div class="wrapper">
|
|
17
|
+
<div class="card">
|
|
18
|
+
{{#if branding.logoUrl}}<img src="{{branding.logoUrl}}" alt="{{branding.companyName}}" style="max-height: 40px; margin-bottom: 16px;">{{/if}}
|
|
19
|
+
<h1 style="font-size: 20px; margin: 0 0 12px 0;">You've been invited!</h1>
|
|
20
|
+
<p>Hi {{userName}},</p>
|
|
21
|
+
{{#if inviterName}}
|
|
22
|
+
<p><strong>{{inviterName}}</strong> has invited you to join <strong>{{orgName}}</strong>. Click the button below to set up your account. This invitation expires in {{expiresDays}} days.</p>
|
|
23
|
+
{{else}}
|
|
24
|
+
<p>You've been invited to join <strong>{{orgName}}</strong>. Click the button below to set up your account. This invitation expires in {{expiresDays}} days.</p>
|
|
25
|
+
{{/if}}
|
|
26
|
+
{{#if personalMessage}}
|
|
27
|
+
<div class="personal-message">
|
|
28
|
+
{{personalMessage}}
|
|
29
|
+
</div>
|
|
30
|
+
{{/if}}
|
|
31
|
+
<p style="text-align: center; margin: 24px 0;">
|
|
32
|
+
<a href="{{{inviteUrl}}}" class="btn">Accept Invitation</a>
|
|
33
|
+
</p>
|
|
34
|
+
<p style="color: #6b7280; font-size: 13px;">Or copy this link: {{{inviteUrl}}}</p>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="footer">© {{year}} {{branding.companyName}}</div>
|
|
37
|
+
</div>
|
|
38
|
+
</body>
|
|
39
|
+
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
You've been invited!
|
|
2
|
+
|
|
3
|
+
Hi {{userName}},
|
|
4
|
+
|
|
5
|
+
{{#if inviterName}}
|
|
6
|
+
{{inviterName}} has invited you to join {{orgName}}. Click the link below to set up your account. This invitation expires in {{expiresDays}} days.
|
|
7
|
+
{{else}}
|
|
8
|
+
You've been invited to join {{orgName}}. Click the link below to set up your account. This invitation expires in {{expiresDays}} days.
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if personalMessage}}
|
|
11
|
+
|
|
12
|
+
Message from {{#if inviterName}}{{inviterName}}{{else}}your admin{{/if}}:
|
|
13
|
+
"{{personalMessage}}"
|
|
14
|
+
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{{inviteUrl}}}
|
|
17
|
+
|
|
18
|
+
© {{year}} {{branding.companyName}}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<style>
|
|
7
|
+
body { font-family: system-ui, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
|
|
8
|
+
.wrapper { max-width: 560px; margin: 0 auto; padding: 40px 20px; }
|
|
9
|
+
.card { background: white; border-radius: 8px; padding: 32px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
10
|
+
.btn { display: inline-block; background: {{branding.primaryColor}}; color: white; text-decoration: none; padding: 12px 32px; border-radius: 4px; font-size: 16px; font-weight: 500; }
|
|
11
|
+
.footer { text-align: center; padding: 16px; color: #6b7280; font-size: 12px; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div class="wrapper">
|
|
16
|
+
<div class="card">
|
|
17
|
+
{{#if branding.logoUrl}}<img src="{{branding.logoUrl}}" alt="{{branding.companyName}}" style="max-height: 40px; margin-bottom: 16px;">{{/if}}
|
|
18
|
+
<h1 style="font-size: 20px; margin: 0 0 12px 0;">Sign in to your account</h1>
|
|
19
|
+
<p>Hi {{userName}},</p>
|
|
20
|
+
<p>Click the button below to sign in. This link expires in {{expiresMinutes}} minutes.</p>
|
|
21
|
+
<p style="text-align: center; margin: 24px 0;">
|
|
22
|
+
<a href="{{{magicLinkUrl}}}" class="btn">Sign In</a>
|
|
23
|
+
</p>
|
|
24
|
+
<p style="color: #6b7280; font-size: 13px;">If you didn't request this, you can safely ignore this email.</p>
|
|
25
|
+
<p style="color: #6b7280; font-size: 13px;">Or copy this link: {{{magicLinkUrl}}}</p>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="footer">© {{year}} {{branding.companyName}}</div>
|
|
28
|
+
</div>
|
|
29
|
+
</body>
|
|
30
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Sign in to your account
|
|
2
|
+
|
|
3
|
+
Hi {{userName}},
|
|
4
|
+
|
|
5
|
+
Click the link below to sign in. This link expires in {{expiresMinutes}} minutes.
|
|
6
|
+
|
|
7
|
+
{{{magicLinkUrl}}}
|
|
8
|
+
|
|
9
|
+
If you didn't request this, you can safely ignore this email.
|
|
10
|
+
|
|
11
|
+
© {{year}} {{branding.companyName}}
|