@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,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC Standard Claims builder.
|
|
3
|
+
*
|
|
4
|
+
* Builds OIDC Standard Claims from a User profile based on the granted
|
|
5
|
+
* OAuth2 scopes. Follows the scope-to-claims mapping defined in
|
|
6
|
+
* OpenID Connect Core 1.0, §5.4:
|
|
7
|
+
*
|
|
8
|
+
* - openid → sub (always included)
|
|
9
|
+
* - profile → name, given_name, family_name, middle_name, nickname,
|
|
10
|
+
* preferred_username, profile, picture, website, gender,
|
|
11
|
+
* birthdate, zoneinfo, locale, updated_at
|
|
12
|
+
* - email → email, email_verified
|
|
13
|
+
* - phone → phone_number, phone_number_verified
|
|
14
|
+
* - address → address (structured object per §5.1.1)
|
|
15
|
+
*
|
|
16
|
+
* Custom claims (org_id, org_slug, roles) are handled in RD-08, not here.
|
|
17
|
+
* This module only handles the OIDC Standard Claims specification.
|
|
18
|
+
*/
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Claims builder
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Build OIDC Standard Claims from a user profile based on granted scopes.
|
|
24
|
+
*
|
|
25
|
+
* The `sub` claim is always included. Additional claims are added based
|
|
26
|
+
* on which scopes are present in the `scopes` array. Null profile fields
|
|
27
|
+
* are included as null (not omitted) — per the OIDC spec, null indicates
|
|
28
|
+
* "no value" which is different from "not requested".
|
|
29
|
+
*
|
|
30
|
+
* The `updated_at` claim is a Unix timestamp (seconds since epoch) per
|
|
31
|
+
* the OIDC specification, not an ISO 8601 string.
|
|
32
|
+
*
|
|
33
|
+
* @param user - User whose profile claims to build
|
|
34
|
+
* @param scopes - Array of granted OAuth2 scope strings
|
|
35
|
+
* @returns Claims object with `sub` and scope-dependent fields
|
|
36
|
+
*/
|
|
37
|
+
export function buildUserClaims(user, scopes) {
|
|
38
|
+
// sub is always included (required by OIDC)
|
|
39
|
+
const claims = { sub: user.id };
|
|
40
|
+
// profile scope — OIDC §5.4 profile claims
|
|
41
|
+
if (scopes.includes('profile')) {
|
|
42
|
+
// Derive "name" from given_name + middle_name + family_name parts
|
|
43
|
+
const nameParts = [user.givenName, user.middleName, user.familyName].filter(Boolean);
|
|
44
|
+
if (nameParts.length > 0) {
|
|
45
|
+
claims.name = nameParts.join(' ');
|
|
46
|
+
}
|
|
47
|
+
claims.given_name = user.givenName;
|
|
48
|
+
claims.family_name = user.familyName;
|
|
49
|
+
claims.middle_name = user.middleName;
|
|
50
|
+
claims.nickname = user.nickname;
|
|
51
|
+
claims.preferred_username = user.preferredUsername;
|
|
52
|
+
claims.profile = user.profileUrl;
|
|
53
|
+
claims.picture = user.pictureUrl;
|
|
54
|
+
claims.website = user.websiteUrl;
|
|
55
|
+
claims.gender = user.gender;
|
|
56
|
+
claims.birthdate = user.birthdate;
|
|
57
|
+
claims.zoneinfo = user.zoneinfo;
|
|
58
|
+
claims.locale = user.locale;
|
|
59
|
+
// updated_at must be Unix timestamp (seconds) per OIDC spec
|
|
60
|
+
claims.updated_at = Math.floor(user.updatedAt.getTime() / 1000);
|
|
61
|
+
}
|
|
62
|
+
// email scope — OIDC §5.4 email claims
|
|
63
|
+
if (scopes.includes('email')) {
|
|
64
|
+
claims.email = user.email;
|
|
65
|
+
claims.email_verified = user.emailVerified;
|
|
66
|
+
}
|
|
67
|
+
// phone scope — OIDC §5.4 phone claims
|
|
68
|
+
if (scopes.includes('phone')) {
|
|
69
|
+
claims.phone_number = user.phoneNumber;
|
|
70
|
+
claims.phone_number_verified = user.phoneNumberVerified;
|
|
71
|
+
}
|
|
72
|
+
// address scope — OIDC §5.1.1 structured address (only if any field present)
|
|
73
|
+
if (scopes.includes('address') && hasAddress(user)) {
|
|
74
|
+
claims.address = {
|
|
75
|
+
street_address: user.addressStreet,
|
|
76
|
+
locality: user.addressLocality,
|
|
77
|
+
region: user.addressRegion,
|
|
78
|
+
postal_code: user.addressPostalCode,
|
|
79
|
+
country: user.addressCountry,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return claims;
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Helpers
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Check if a user has any address fields populated.
|
|
89
|
+
*
|
|
90
|
+
* Returns true if at least one address field is non-null/non-empty.
|
|
91
|
+
* Used to decide whether to include the address claim object —
|
|
92
|
+
* per the spec, the address claim should not be an empty object.
|
|
93
|
+
*
|
|
94
|
+
* @param user - User to check
|
|
95
|
+
* @returns true if any address field has a value
|
|
96
|
+
*/
|
|
97
|
+
export function hasAddress(user) {
|
|
98
|
+
return !!(user.addressStreet ||
|
|
99
|
+
user.addressLocality ||
|
|
100
|
+
user.addressRegion ||
|
|
101
|
+
user.addressPostalCode ||
|
|
102
|
+
user.addressCountry);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=claims.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../../src/users/claims.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA8BH,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,MAAgB;IAC1D,4CAA4C;IAC5C,MAAM,MAAM,GAAe,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IAE5C,2CAA2C;IAC3C,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,kEAAkE;QAClE,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QACnC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;QACrC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;QACrC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAChC,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACnD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5B,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAClC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5B,4DAA4D;QAC5D,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAClE,CAAC;IAED,uCAAuC;IACvC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1B,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC;IAC7C,CAAC;IAED,uCAAuC;IACvC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;QACvC,MAAM,CAAC,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,CAAC;IAC1D,CAAC;IAED,6EAA6E;IAC7E,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,OAAO,GAAG;YACf,cAAc,EAAE,IAAI,CAAC,aAAa;YAClC,QAAQ,EAAE,IAAI,CAAC,eAAe;YAC9B,MAAM,EAAE,IAAI,CAAC,aAAa;YAC1B,WAAW,EAAE,IAAI,CAAC,iBAAiB;YACnC,OAAO,EAAE,IAAI,CAAC,cAAc;SACd,CAAC;IACnB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,CAAC,CAAC,CACP,IAAI,CAAC,aAAa;QAClB,IAAI,CAAC,eAAe;QACpB,IAAI,CAAC,aAAa;QAClB,IAAI,CAAC,iBAAiB;QACtB,IAAI,CAAC,cAAc,CACpB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User domain error types.
|
|
3
|
+
*
|
|
4
|
+
* Custom error classes for user-specific business rule violations.
|
|
5
|
+
* API routes map these to appropriate HTTP status codes:
|
|
6
|
+
* - UserNotFoundError → 404
|
|
7
|
+
* - UserValidationError → 400
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Thrown when a user cannot be found by ID or email.
|
|
11
|
+
* Maps to HTTP 404 in route handlers.
|
|
12
|
+
*/
|
|
13
|
+
export declare class UserNotFoundError extends Error {
|
|
14
|
+
constructor(identifier: string);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Thrown when an operation violates user business rules.
|
|
18
|
+
* Examples: duplicate email within org, invalid status transition,
|
|
19
|
+
* invalid password format, missing required fields.
|
|
20
|
+
* Maps to HTTP 400 in route handlers.
|
|
21
|
+
*/
|
|
22
|
+
export declare class UserValidationError extends Error {
|
|
23
|
+
constructor(message: string);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/users/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,UAAU,EAAE,MAAM,EAG7B;CACF;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User domain error types.
|
|
3
|
+
*
|
|
4
|
+
* Custom error classes for user-specific business rule violations.
|
|
5
|
+
* API routes map these to appropriate HTTP status codes:
|
|
6
|
+
* - UserNotFoundError → 404
|
|
7
|
+
* - UserValidationError → 400
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Thrown when a user cannot be found by ID or email.
|
|
11
|
+
* Maps to HTTP 404 in route handlers.
|
|
12
|
+
*/
|
|
13
|
+
export class UserNotFoundError extends Error {
|
|
14
|
+
constructor(identifier) {
|
|
15
|
+
super(`User not found: ${identifier}`);
|
|
16
|
+
this.name = 'UserNotFoundError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Thrown when an operation violates user business rules.
|
|
21
|
+
* Examples: duplicate email within org, invalid status transition,
|
|
22
|
+
* invalid password format, missing required fields.
|
|
23
|
+
* Maps to HTTP 400 in route handlers.
|
|
24
|
+
*/
|
|
25
|
+
export class UserValidationError extends Error {
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'UserValidationError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/users/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,UAAkB;QAC5B,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GDPR data export and purge for users.
|
|
3
|
+
*
|
|
4
|
+
* Implements Article 17 (right to erasure) and Article 20 (data portability)
|
|
5
|
+
* capabilities for Porta's user data. These functions collect all user-related
|
|
6
|
+
* data across multiple tables for export, or anonymize/delete it for purge.
|
|
7
|
+
*
|
|
8
|
+
* **Export** collects: user profile, role assignments, custom claim values,
|
|
9
|
+
* audit log entries (as actor or target), 2FA enrollment status (NOT secrets),
|
|
10
|
+
* and active OIDC sessions/grants.
|
|
11
|
+
*
|
|
12
|
+
* **Purge** anonymizes the user record and audit entries, deletes all
|
|
13
|
+
* related data (roles, claims, 2FA, OIDC sessions), and writes the compliance
|
|
14
|
+
* audit event in the same transaction before commit.
|
|
15
|
+
*
|
|
16
|
+
* Safety: Purging super-admin org users is blocked to prevent lock-out.
|
|
17
|
+
*
|
|
18
|
+
* @module users/gdpr
|
|
19
|
+
*/
|
|
20
|
+
import type { User } from './types.js';
|
|
21
|
+
/** Complete GDPR data export for a user */
|
|
22
|
+
export interface UserDataExport {
|
|
23
|
+
exportedAt: string;
|
|
24
|
+
user: {
|
|
25
|
+
id: string;
|
|
26
|
+
email: string;
|
|
27
|
+
givenName: string | null;
|
|
28
|
+
familyName: string | null;
|
|
29
|
+
middleName: string | null;
|
|
30
|
+
nickname: string | null;
|
|
31
|
+
preferredUsername: string | null;
|
|
32
|
+
locale: string | null;
|
|
33
|
+
phoneNumber: string | null;
|
|
34
|
+
status: string;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
lastLoginAt: string | null;
|
|
37
|
+
};
|
|
38
|
+
organization: {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
slug: string;
|
|
42
|
+
};
|
|
43
|
+
roles: Array<{
|
|
44
|
+
roleId: string;
|
|
45
|
+
roleName: string;
|
|
46
|
+
roleSlug: string;
|
|
47
|
+
applicationId: string;
|
|
48
|
+
assignedAt: string;
|
|
49
|
+
}>;
|
|
50
|
+
customClaims: Array<{
|
|
51
|
+
claimName: string;
|
|
52
|
+
value: unknown;
|
|
53
|
+
applicationId: string;
|
|
54
|
+
}>;
|
|
55
|
+
auditLog: Array<{
|
|
56
|
+
id: string;
|
|
57
|
+
eventType: string;
|
|
58
|
+
eventCategory: string;
|
|
59
|
+
description: string | null;
|
|
60
|
+
createdAt: string;
|
|
61
|
+
}>;
|
|
62
|
+
twoFactor: {
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
method: string | null;
|
|
65
|
+
};
|
|
66
|
+
oidcSessions: number;
|
|
67
|
+
}
|
|
68
|
+
/** Result from a purge operation */
|
|
69
|
+
export interface PurgeResult {
|
|
70
|
+
userId: string;
|
|
71
|
+
anonymizedEmail: string;
|
|
72
|
+
deletedRoles: number;
|
|
73
|
+
deletedClaims: number;
|
|
74
|
+
deletedTwoFactor: number;
|
|
75
|
+
deletedOidcPayloads: number;
|
|
76
|
+
anonymizedAuditEntries: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Export all data Porta holds for a user as a structured JSON document.
|
|
80
|
+
*
|
|
81
|
+
* Collects data from: users, organizations, user_roles + roles,
|
|
82
|
+
* user_claim_values + claim_definitions, audit_log, user 2FA columns,
|
|
83
|
+
* and oidc_payloads. Does NOT export TOTP secrets or recovery codes
|
|
84
|
+
* (security-sensitive material).
|
|
85
|
+
*
|
|
86
|
+
* @param user - The user to export data for (must be a full User object)
|
|
87
|
+
* @returns Complete GDPR export document
|
|
88
|
+
*/
|
|
89
|
+
export declare function exportUserData(user: User): Promise<UserDataExport>;
|
|
90
|
+
/**
|
|
91
|
+
* Irreversibly purge all PII for a user.
|
|
92
|
+
*
|
|
93
|
+
* Anonymizes the user record (email → purged-{id}@purged.local, clears
|
|
94
|
+
* name fields, sets status to 'inactive'). Deletes related records: role
|
|
95
|
+
* assignments, custom claim values, 2FA data, OIDC sessions/grants.
|
|
96
|
+
* Anonymizes audit log entries (actor_email → [purged]).
|
|
97
|
+
*
|
|
98
|
+
* Fires a `user.purged` audit event BEFORE anonymization for compliance trail.
|
|
99
|
+
*
|
|
100
|
+
* Safety checks:
|
|
101
|
+
* - Cannot purge users belonging to the super-admin organization
|
|
102
|
+
* - Requires explicit confirmation (caller responsibility)
|
|
103
|
+
*
|
|
104
|
+
* @param user - The user to purge (must be a full User object)
|
|
105
|
+
* @param actorId - ID of the admin performing the purge
|
|
106
|
+
* @returns Summary of what was deleted/anonymized
|
|
107
|
+
* @throws Error if user belongs to super-admin org
|
|
108
|
+
*/
|
|
109
|
+
export declare function purgeUserData(user: User, actorId: string): Promise<PurgeResult>;
|
|
110
|
+
//# sourceMappingURL=gdpr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gdpr.d.ts","sourceRoot":"","sources":["../../src/users/gdpr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvC,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;IACF,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,EAAE,KAAK,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,YAAY,EAAE,KAAK,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;IACH,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAkHxE;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAkGrF"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GDPR data export and purge for users.
|
|
3
|
+
*
|
|
4
|
+
* Implements Article 17 (right to erasure) and Article 20 (data portability)
|
|
5
|
+
* capabilities for Porta's user data. These functions collect all user-related
|
|
6
|
+
* data across multiple tables for export, or anonymize/delete it for purge.
|
|
7
|
+
*
|
|
8
|
+
* **Export** collects: user profile, role assignments, custom claim values,
|
|
9
|
+
* audit log entries (as actor or target), 2FA enrollment status (NOT secrets),
|
|
10
|
+
* and active OIDC sessions/grants.
|
|
11
|
+
*
|
|
12
|
+
* **Purge** anonymizes the user record and audit entries, deletes all
|
|
13
|
+
* related data (roles, claims, 2FA, OIDC sessions), and writes the compliance
|
|
14
|
+
* audit event in the same transaction before commit.
|
|
15
|
+
*
|
|
16
|
+
* Safety: Purging super-admin org users is blocked to prevent lock-out.
|
|
17
|
+
*
|
|
18
|
+
* @module users/gdpr
|
|
19
|
+
*/
|
|
20
|
+
import { getDatabaseTransactionClient, getPool, runDatabaseTransaction } from '../lib/database.js';
|
|
21
|
+
import { writeAuditLogInTransaction } from '../lib/audit-log.js';
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Export — collect all user data (Article 20)
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Export all data Porta holds for a user as a structured JSON document.
|
|
27
|
+
*
|
|
28
|
+
* Collects data from: users, organizations, user_roles + roles,
|
|
29
|
+
* user_claim_values + claim_definitions, audit_log, user 2FA columns,
|
|
30
|
+
* and oidc_payloads. Does NOT export TOTP secrets or recovery codes
|
|
31
|
+
* (security-sensitive material).
|
|
32
|
+
*
|
|
33
|
+
* @param user - The user to export data for (must be a full User object)
|
|
34
|
+
* @returns Complete GDPR export document
|
|
35
|
+
*/
|
|
36
|
+
export async function exportUserData(user) {
|
|
37
|
+
const pool = getPool();
|
|
38
|
+
// Parallel queries for all user-related data
|
|
39
|
+
const [orgResult, rolesResult, claimsResult, auditResult, oidcResult] = await Promise.all([
|
|
40
|
+
// Organization the user belongs to
|
|
41
|
+
pool.query('SELECT id, name, slug FROM organizations WHERE id = $1', [user.organizationId]),
|
|
42
|
+
// Role assignments with role details
|
|
43
|
+
pool.query(`SELECT r.id AS role_id, r.name, r.slug, r.application_id, ur.created_at
|
|
44
|
+
FROM user_roles ur
|
|
45
|
+
JOIN roles r ON r.id = ur.role_id
|
|
46
|
+
WHERE ur.user_id = $1
|
|
47
|
+
ORDER BY ur.created_at`, [user.id]),
|
|
48
|
+
// Custom claim values with definition names
|
|
49
|
+
pool.query(`SELECT cd.claim_name, ucv.value, cd.application_id
|
|
50
|
+
FROM user_claim_values ucv
|
|
51
|
+
JOIN claim_definitions cd ON cd.id = ucv.definition_id
|
|
52
|
+
WHERE ucv.user_id = $1
|
|
53
|
+
ORDER BY cd.claim_name`, [user.id]),
|
|
54
|
+
// Audit log entries where user is actor or target (limited to 500)
|
|
55
|
+
pool.query(`SELECT id, event_type, event_category, description, created_at
|
|
56
|
+
FROM audit_log
|
|
57
|
+
WHERE actor_id = $1 OR user_id = $1
|
|
58
|
+
ORDER BY created_at DESC
|
|
59
|
+
LIMIT 500`, [user.id]),
|
|
60
|
+
// Count of active OIDC sessions/grants for user
|
|
61
|
+
pool.query(`SELECT COUNT(*) AS count FROM oidc_payloads
|
|
62
|
+
WHERE payload->>'accountId' = $1
|
|
63
|
+
AND (expires_at IS NULL OR expires_at > NOW())`, [user.id]),
|
|
64
|
+
]);
|
|
65
|
+
const org = orgResult.rows[0] ?? { id: user.organizationId, name: 'Unknown', slug: 'unknown' };
|
|
66
|
+
return {
|
|
67
|
+
exportedAt: new Date().toISOString(),
|
|
68
|
+
user: {
|
|
69
|
+
id: user.id,
|
|
70
|
+
email: user.email,
|
|
71
|
+
givenName: user.givenName,
|
|
72
|
+
familyName: user.familyName,
|
|
73
|
+
middleName: user.middleName,
|
|
74
|
+
nickname: user.nickname,
|
|
75
|
+
preferredUsername: user.preferredUsername,
|
|
76
|
+
locale: user.locale,
|
|
77
|
+
phoneNumber: user.phoneNumber,
|
|
78
|
+
status: user.status,
|
|
79
|
+
createdAt: user.createdAt.toISOString(),
|
|
80
|
+
lastLoginAt: user.lastLoginAt?.toISOString() ?? null,
|
|
81
|
+
},
|
|
82
|
+
organization: {
|
|
83
|
+
id: org.id,
|
|
84
|
+
name: org.name,
|
|
85
|
+
slug: org.slug,
|
|
86
|
+
},
|
|
87
|
+
roles: rolesResult.rows.map((r) => ({
|
|
88
|
+
roleId: r.role_id,
|
|
89
|
+
roleName: r.name,
|
|
90
|
+
roleSlug: r.slug,
|
|
91
|
+
applicationId: r.application_id,
|
|
92
|
+
assignedAt: String(r.created_at),
|
|
93
|
+
})),
|
|
94
|
+
customClaims: claimsResult.rows.map((r) => ({
|
|
95
|
+
claimName: r.claim_name,
|
|
96
|
+
value: r.value,
|
|
97
|
+
applicationId: r.application_id,
|
|
98
|
+
})),
|
|
99
|
+
auditLog: auditResult.rows.map((r) => ({
|
|
100
|
+
id: r.id,
|
|
101
|
+
eventType: r.event_type,
|
|
102
|
+
eventCategory: r.event_category,
|
|
103
|
+
description: r.description,
|
|
104
|
+
createdAt: String(r.created_at),
|
|
105
|
+
})),
|
|
106
|
+
twoFactor: {
|
|
107
|
+
enabled: user.twoFactorEnabled,
|
|
108
|
+
method: user.twoFactorMethod ?? null,
|
|
109
|
+
},
|
|
110
|
+
oidcSessions: parseInt(oidcResult.rows[0]?.count ?? '0', 10),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Purge — anonymize/delete all user data (Article 17)
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
/**
|
|
117
|
+
* Irreversibly purge all PII for a user.
|
|
118
|
+
*
|
|
119
|
+
* Anonymizes the user record (email → purged-{id}@purged.local, clears
|
|
120
|
+
* name fields, sets status to 'inactive'). Deletes related records: role
|
|
121
|
+
* assignments, custom claim values, 2FA data, OIDC sessions/grants.
|
|
122
|
+
* Anonymizes audit log entries (actor_email → [purged]).
|
|
123
|
+
*
|
|
124
|
+
* Fires a `user.purged` audit event BEFORE anonymization for compliance trail.
|
|
125
|
+
*
|
|
126
|
+
* Safety checks:
|
|
127
|
+
* - Cannot purge users belonging to the super-admin organization
|
|
128
|
+
* - Requires explicit confirmation (caller responsibility)
|
|
129
|
+
*
|
|
130
|
+
* @param user - The user to purge (must be a full User object)
|
|
131
|
+
* @param actorId - ID of the admin performing the purge
|
|
132
|
+
* @returns Summary of what was deleted/anonymized
|
|
133
|
+
* @throws Error if user belongs to super-admin org
|
|
134
|
+
*/
|
|
135
|
+
export async function purgeUserData(user, actorId) {
|
|
136
|
+
return runDatabaseTransaction(async () => {
|
|
137
|
+
const client = getDatabaseTransactionClient();
|
|
138
|
+
if (!client)
|
|
139
|
+
throw new Error('GDPR purge transaction is unavailable');
|
|
140
|
+
// The authority check and destructive changes share the same transaction.
|
|
141
|
+
const orgCheck = await client.query('SELECT is_super_admin FROM organizations WHERE id = $1 FOR SHARE', [user.organizationId]);
|
|
142
|
+
if (orgCheck.rows[0]?.is_super_admin) {
|
|
143
|
+
throw new Error('Cannot purge users belonging to the super-admin organization');
|
|
144
|
+
}
|
|
145
|
+
// 1. Revoke all active OIDC sessions/grants
|
|
146
|
+
const oidcDelete = await client.query(`DELETE FROM oidc_payloads WHERE payload->>'accountId' = $1`, [user.id]);
|
|
147
|
+
// 2. Delete 2FA data (TOTP secrets, OTP codes, recovery codes)
|
|
148
|
+
await client.query('DELETE FROM user_totp WHERE user_id = $1', [user.id]);
|
|
149
|
+
await client.query('DELETE FROM two_factor_otp_codes WHERE user_id = $1', [user.id]);
|
|
150
|
+
const twoFactorDelete = await client.query('DELETE FROM two_factor_recovery_codes WHERE user_id = $1', [user.id]);
|
|
151
|
+
// 3. Delete custom claim values
|
|
152
|
+
const claimsDelete = await client.query('DELETE FROM user_claim_values WHERE user_id = $1', [
|
|
153
|
+
user.id,
|
|
154
|
+
]);
|
|
155
|
+
// 4. Delete role assignments
|
|
156
|
+
const rolesDelete = await client.query('DELETE FROM user_roles WHERE user_id = $1', [user.id]);
|
|
157
|
+
// 5. Anonymize audit log entries referencing this user
|
|
158
|
+
const auditUpdate = await client.query(`UPDATE audit_log
|
|
159
|
+
SET metadata = metadata || '{"purged": true}'::jsonb
|
|
160
|
+
WHERE actor_id = $1 OR user_id = $1`, [user.id]);
|
|
161
|
+
// 6. Anonymize user record — clear PII, keep ID for referential integrity
|
|
162
|
+
const anonymizedEmail = `purged-${user.id}@purged.local`;
|
|
163
|
+
await client.query(`UPDATE users SET
|
|
164
|
+
email = $2,
|
|
165
|
+
email_verified = false,
|
|
166
|
+
password_hash = NULL,
|
|
167
|
+
given_name = NULL,
|
|
168
|
+
family_name = NULL,
|
|
169
|
+
middle_name = NULL,
|
|
170
|
+
nickname = NULL,
|
|
171
|
+
preferred_username = NULL,
|
|
172
|
+
profile_url = NULL,
|
|
173
|
+
picture_url = NULL,
|
|
174
|
+
website_url = NULL,
|
|
175
|
+
gender = NULL,
|
|
176
|
+
birthdate = NULL,
|
|
177
|
+
zoneinfo = NULL,
|
|
178
|
+
locale = NULL,
|
|
179
|
+
phone_number = NULL,
|
|
180
|
+
phone_number_verified = false,
|
|
181
|
+
address_street = NULL,
|
|
182
|
+
address_locality = NULL,
|
|
183
|
+
address_region = NULL,
|
|
184
|
+
address_postal_code = NULL,
|
|
185
|
+
address_country = NULL,
|
|
186
|
+
status = 'inactive',
|
|
187
|
+
two_factor_enabled = false,
|
|
188
|
+
two_factor_method = NULL,
|
|
189
|
+
updated_at = NOW()
|
|
190
|
+
WHERE id = $1`, [user.id, anonymizedEmail]);
|
|
191
|
+
await writeAuditLogInTransaction(client, {
|
|
192
|
+
organizationId: user.organizationId,
|
|
193
|
+
userId: user.id,
|
|
194
|
+
actorId,
|
|
195
|
+
eventType: 'user.purged',
|
|
196
|
+
eventCategory: 'gdpr',
|
|
197
|
+
description: 'GDPR purge committed',
|
|
198
|
+
metadata: { userId: user.id },
|
|
199
|
+
});
|
|
200
|
+
return {
|
|
201
|
+
userId: user.id,
|
|
202
|
+
anonymizedEmail,
|
|
203
|
+
deletedRoles: rolesDelete.rowCount ?? 0,
|
|
204
|
+
deletedClaims: claimsDelete.rowCount ?? 0,
|
|
205
|
+
deletedTwoFactor: twoFactorDelete.rowCount ?? 0,
|
|
206
|
+
deletedOidcPayloads: oidcDelete.rowCount ?? 0,
|
|
207
|
+
anonymizedAuditEntries: auditUpdate.rowCount ?? 0,
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=gdpr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gdpr.js","sourceRoot":"","sources":["../../src/users/gdpr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Users module — public API barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the types, service functions, claims builder, error classes,
|
|
5
|
+
* and password utilities that other modules need. Internal implementation
|
|
6
|
+
* details (repository, cache) are NOT exported — they are consumed only
|
|
7
|
+
* by the service layer.
|
|
8
|
+
*/
|
|
9
|
+
export type { User, UserRow, UserStatus, CreateUserInput, UpdateUserInput, AddressInput, UserListOptions, PaginatedResult, } from './types.js';
|
|
10
|
+
export { createUser, getUserById, getUserByEmail, updateUser, listUsersByOrganization, listUsersCursor, deactivateUser, reactivateUser, suspendUser, unsuspendUser, lockUser, unlockUser, setUserPassword, verifyUserPassword, clearUserPassword, markEmailVerified, markEmailUnverified, recordLogin, recordFailedLogin, checkAutoUnlock, findUserForOidc, } from './service.js';
|
|
11
|
+
export { buildUserClaims, hasAddress } from './claims.js';
|
|
12
|
+
export type { OidcClaims, OidcAddress } from './claims.js';
|
|
13
|
+
export type { ListUsersCursorOptions } from './repository.js';
|
|
14
|
+
export type { CursorPaginatedResult } from '../lib/cursor.js';
|
|
15
|
+
export { UserNotFoundError, UserValidationError } from './errors.js';
|
|
16
|
+
export { validatePassword, MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH, } from './password.js';
|
|
17
|
+
export type { PasswordValidationResult } from './password.js';
|
|
18
|
+
export { exportUserData, purgeUserData } from './gdpr.js';
|
|
19
|
+
export type { UserDataExport, PurgeResult } from './gdpr.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/users/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,IAAI,EACJ,OAAO,EACP,UAAU,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG9D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGrE,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Users module — public API barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the types, service functions, claims builder, error classes,
|
|
5
|
+
* and password utilities that other modules need. Internal implementation
|
|
6
|
+
* details (repository, cache) are NOT exported — they are consumed only
|
|
7
|
+
* by the service layer.
|
|
8
|
+
*/
|
|
9
|
+
// Service functions
|
|
10
|
+
export { createUser, getUserById, getUserByEmail, updateUser, listUsersByOrganization, listUsersCursor, deactivateUser, reactivateUser, suspendUser, unsuspendUser, lockUser, unlockUser, setUserPassword, verifyUserPassword, clearUserPassword, markEmailVerified, markEmailUnverified, recordLogin, recordFailedLogin, checkAutoUnlock, findUserForOidc, } from './service.js';
|
|
11
|
+
// Claims builder
|
|
12
|
+
export { buildUserClaims, hasAddress } from './claims.js';
|
|
13
|
+
// Error types
|
|
14
|
+
export { UserNotFoundError, UserValidationError } from './errors.js';
|
|
15
|
+
// Password utilities (for external consumers like CLI)
|
|
16
|
+
export { validatePassword, MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH, } from './password.js';
|
|
17
|
+
// GDPR export/purge (Article 17 + Article 20)
|
|
18
|
+
export { exportUserData, purgeUserData } from './gdpr.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/users/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAcH,oBAAoB;AACpB,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC;AAEtB,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO1D,cAAc;AACd,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAErE,uDAAuD;AACvD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,8CAA8C;AAC9C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password management utilities.
|
|
3
|
+
*
|
|
4
|
+
* Provides password validation (NIST SP 800-63B compliant length checks),
|
|
5
|
+
* Argon2id hashing, and verification. Follows the same pattern as
|
|
6
|
+
* `src/clients/crypto.ts` but with password-specific naming and a
|
|
7
|
+
* validation function.
|
|
8
|
+
*
|
|
9
|
+
* Design decisions:
|
|
10
|
+
* - No complexity rules (uppercase, special chars) per NIST SP 800-63B
|
|
11
|
+
* guidance — length is the primary strength factor
|
|
12
|
+
* - Argon2id with library defaults (OWASP compliant parameters)
|
|
13
|
+
* - verifyPassword returns false on any error (invalid hash format, etc.)
|
|
14
|
+
* to prevent timing side-channels from leaking hash validity info
|
|
15
|
+
*/
|
|
16
|
+
/** Minimum password length per NIST SP 800-63B recommendation */
|
|
17
|
+
export declare const MIN_PASSWORD_LENGTH = 8;
|
|
18
|
+
/** Maximum password length to prevent denial-of-service via huge inputs */
|
|
19
|
+
export declare const MAX_PASSWORD_LENGTH = 128;
|
|
20
|
+
/** Result of password validation — includes error message when invalid */
|
|
21
|
+
export interface PasswordValidationResult {
|
|
22
|
+
isValid: boolean;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validate a password against length constraints.
|
|
27
|
+
*
|
|
28
|
+
* Checks min/max length per NIST SP 800-63B. No complexity rules
|
|
29
|
+
* (uppercase, numbers, special chars) are enforced — NIST recommends
|
|
30
|
+
* against them as they don't meaningfully improve security and
|
|
31
|
+
* frustrate users.
|
|
32
|
+
*
|
|
33
|
+
* @param password - The plaintext password to validate
|
|
34
|
+
* @returns Validation result with `isValid` flag and optional `error` message
|
|
35
|
+
*/
|
|
36
|
+
export declare function validatePassword(password: string): PasswordValidationResult;
|
|
37
|
+
/**
|
|
38
|
+
* Hash a password using Argon2id.
|
|
39
|
+
*
|
|
40
|
+
* Argon2id combines Argon2d (GPU-resistant) and Argon2i (side-channel
|
|
41
|
+
* resistant). The argon2 library's default parameters follow OWASP
|
|
42
|
+
* recommendations for password hashing.
|
|
43
|
+
*
|
|
44
|
+
* The returned hash string includes the algorithm, salt, and parameters
|
|
45
|
+
* in PHC format — everything needed for verification.
|
|
46
|
+
*
|
|
47
|
+
* @param plaintext - The password to hash
|
|
48
|
+
* @returns Argon2id hash string (PHC format)
|
|
49
|
+
*/
|
|
50
|
+
export declare function hashPassword(plaintext: string): Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Initialize the process-owned Argon2id dummy hash.
|
|
53
|
+
*
|
|
54
|
+
* Startup awaits this operation so an authentication process never serves requests with a cheap
|
|
55
|
+
* missing-account branch. Repeated calls are idempotent for the lifetime of the process.
|
|
56
|
+
*/
|
|
57
|
+
export declare function initializeDummyPasswordHash(): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Read the initialized process-owned dummy hash.
|
|
60
|
+
*
|
|
61
|
+
* @returns Argon2id hash with no authentication authority.
|
|
62
|
+
* @throws Error when startup did not initialize the dummy hash.
|
|
63
|
+
*/
|
|
64
|
+
export declare function getDummyPasswordHash(): string;
|
|
65
|
+
/**
|
|
66
|
+
* Return the process-owned dummy hash, initializing it when an embedded app bypassed the entry
|
|
67
|
+
* point. Production startup still awaits initialization before listening.
|
|
68
|
+
*
|
|
69
|
+
* @returns Initialized non-authoritative Argon2id hash.
|
|
70
|
+
*/
|
|
71
|
+
export declare function ensureDummyPasswordHash(): Promise<string>;
|
|
72
|
+
/**
|
|
73
|
+
* Verify a plaintext password against a stored Argon2id hash.
|
|
74
|
+
*
|
|
75
|
+
* Returns true if the password matches, false otherwise. Any errors
|
|
76
|
+
* during verification (e.g., invalid hash format) are caught and
|
|
77
|
+
* treated as a non-match to prevent timing side-channels from
|
|
78
|
+
* leaking information about hash validity.
|
|
79
|
+
*
|
|
80
|
+
* @param hash - Stored Argon2id hash (PHC format)
|
|
81
|
+
* @param plaintext - Password to verify
|
|
82
|
+
* @returns true if the password matches the hash, false otherwise
|
|
83
|
+
*/
|
|
84
|
+
export declare function verifyPassword(hash: string, plaintext: string): Promise<boolean>;
|
|
85
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/users/password.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAYvC,0EAA0E;AAC1E,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,wBAAwB,CAgB3E;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIrE;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAG/D;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQtF"}
|