@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,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application and ApplicationModule types and interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Defines the data structures for the application model, including
|
|
5
|
+
* the full database record, input types for create/update, and
|
|
6
|
+
* pagination helpers. Also provides mapping functions to convert
|
|
7
|
+
* snake_case database rows to camelCase TypeScript objects.
|
|
8
|
+
*
|
|
9
|
+
* Applications are platform-wide (not scoped to organizations).
|
|
10
|
+
* They represent SaaS products (e.g., "BusinessSuite") that
|
|
11
|
+
* organizations subscribe to. Each application can have modules
|
|
12
|
+
* (e.g., "CRM", "Invoicing") used for permission namespacing.
|
|
13
|
+
*
|
|
14
|
+
* These types are the foundation that all other application modules
|
|
15
|
+
* depend on (repository, cache, service, routes).
|
|
16
|
+
*/
|
|
17
|
+
export type { PaginatedResult } from '../organizations/types.js';
|
|
18
|
+
/** Application status values — matches the DB CHECK constraint */
|
|
19
|
+
export type ApplicationStatus = 'active' | 'inactive' | 'archived';
|
|
20
|
+
/** Module status values — matches the DB CHECK constraint */
|
|
21
|
+
export type ModuleStatus = 'active' | 'inactive';
|
|
22
|
+
/**
|
|
23
|
+
* Full application record as stored in the database.
|
|
24
|
+
* Maps to the `applications` table columns (see migration 003).
|
|
25
|
+
*/
|
|
26
|
+
export interface Application {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
slug: string;
|
|
30
|
+
description: string | null;
|
|
31
|
+
status: ApplicationStatus;
|
|
32
|
+
createdAt: Date;
|
|
33
|
+
updatedAt: Date;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Full application module record as stored in the database.
|
|
37
|
+
* Maps to the `application_modules` table columns (see migration 003).
|
|
38
|
+
* Module slugs are unique within their parent application (composite key).
|
|
39
|
+
*/
|
|
40
|
+
export interface ApplicationModule {
|
|
41
|
+
id: string;
|
|
42
|
+
applicationId: string;
|
|
43
|
+
name: string;
|
|
44
|
+
slug: string;
|
|
45
|
+
description: string | null;
|
|
46
|
+
status: ModuleStatus;
|
|
47
|
+
createdAt: Date;
|
|
48
|
+
updatedAt: Date;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Input for creating a new application.
|
|
52
|
+
* Slug is auto-generated from name if not provided.
|
|
53
|
+
*/
|
|
54
|
+
export interface CreateApplicationInput {
|
|
55
|
+
name: string;
|
|
56
|
+
slug?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
}
|
|
59
|
+
/** Input for updating an existing application (partial). */
|
|
60
|
+
export interface UpdateApplicationInput {
|
|
61
|
+
name?: string;
|
|
62
|
+
description?: string | null;
|
|
63
|
+
}
|
|
64
|
+
/** Input for creating a module within an application. */
|
|
65
|
+
export interface CreateModuleInput {
|
|
66
|
+
name: string;
|
|
67
|
+
slug?: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
}
|
|
70
|
+
/** Input for updating an existing module (partial). */
|
|
71
|
+
export interface UpdateModuleInput {
|
|
72
|
+
name?: string;
|
|
73
|
+
description?: string | null;
|
|
74
|
+
}
|
|
75
|
+
/** Options for listing applications (paginated). */
|
|
76
|
+
export interface ListApplicationsOptions {
|
|
77
|
+
page: number;
|
|
78
|
+
pageSize: number;
|
|
79
|
+
status?: ApplicationStatus;
|
|
80
|
+
search?: string;
|
|
81
|
+
sortBy?: 'name' | 'created_at';
|
|
82
|
+
sortOrder?: 'asc' | 'desc';
|
|
83
|
+
}
|
|
84
|
+
/** Raw database row from the applications table (snake_case columns). */
|
|
85
|
+
export interface ApplicationRow {
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
slug: string;
|
|
89
|
+
description: string | null;
|
|
90
|
+
status: string;
|
|
91
|
+
created_at: Date;
|
|
92
|
+
updated_at: Date;
|
|
93
|
+
}
|
|
94
|
+
/** Raw database row from the application_modules table (snake_case columns). */
|
|
95
|
+
export interface ApplicationModuleRow {
|
|
96
|
+
id: string;
|
|
97
|
+
application_id: string;
|
|
98
|
+
name: string;
|
|
99
|
+
slug: string;
|
|
100
|
+
description: string | null;
|
|
101
|
+
status: string;
|
|
102
|
+
created_at: Date;
|
|
103
|
+
updated_at: Date;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Map a database row to an Application object.
|
|
107
|
+
*
|
|
108
|
+
* Converts snake_case column names from PostgreSQL to camelCase
|
|
109
|
+
* TypeScript properties. The `status` string is cast to
|
|
110
|
+
* `ApplicationStatus` — the DB CHECK constraint guarantees it
|
|
111
|
+
* is one of the valid values.
|
|
112
|
+
*
|
|
113
|
+
* @param row - Raw database row from the applications table
|
|
114
|
+
* @returns Mapped Application object with camelCase properties
|
|
115
|
+
*/
|
|
116
|
+
export declare function mapRowToApplication(row: ApplicationRow): Application;
|
|
117
|
+
/**
|
|
118
|
+
* Map a database row to an ApplicationModule object.
|
|
119
|
+
*
|
|
120
|
+
* Converts snake_case column names from PostgreSQL to camelCase
|
|
121
|
+
* TypeScript properties. The `status` string is cast to
|
|
122
|
+
* `ModuleStatus` — the DB CHECK constraint guarantees it
|
|
123
|
+
* is one of the valid values.
|
|
124
|
+
*
|
|
125
|
+
* @param row - Raw database row from the application_modules table
|
|
126
|
+
* @returns Mapped ApplicationModule object with camelCase properties
|
|
127
|
+
*/
|
|
128
|
+
export declare function mapRowToModule(row: ApplicationModuleRow): ApplicationModule;
|
|
129
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/applications/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAMjE,kEAAkE;AAClE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAMjD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAMD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAMD;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAMD,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAC/B,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC5B;AAMD,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,gFAAgF;AAChF,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,WAAW,CAUpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,oBAAoB,GAAG,iBAAiB,CAW3E"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application and ApplicationModule types and interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Defines the data structures for the application model, including
|
|
5
|
+
* the full database record, input types for create/update, and
|
|
6
|
+
* pagination helpers. Also provides mapping functions to convert
|
|
7
|
+
* snake_case database rows to camelCase TypeScript objects.
|
|
8
|
+
*
|
|
9
|
+
* Applications are platform-wide (not scoped to organizations).
|
|
10
|
+
* They represent SaaS products (e.g., "BusinessSuite") that
|
|
11
|
+
* organizations subscribe to. Each application can have modules
|
|
12
|
+
* (e.g., "CRM", "Invoicing") used for permission namespacing.
|
|
13
|
+
*
|
|
14
|
+
* These types are the foundation that all other application modules
|
|
15
|
+
* depend on (repository, cache, service, routes).
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Map a database row to an Application object.
|
|
19
|
+
*
|
|
20
|
+
* Converts snake_case column names from PostgreSQL to camelCase
|
|
21
|
+
* TypeScript properties. The `status` string is cast to
|
|
22
|
+
* `ApplicationStatus` — the DB CHECK constraint guarantees it
|
|
23
|
+
* is one of the valid values.
|
|
24
|
+
*
|
|
25
|
+
* @param row - Raw database row from the applications table
|
|
26
|
+
* @returns Mapped Application object with camelCase properties
|
|
27
|
+
*/
|
|
28
|
+
export function mapRowToApplication(row) {
|
|
29
|
+
return {
|
|
30
|
+
id: row.id,
|
|
31
|
+
name: row.name,
|
|
32
|
+
slug: row.slug,
|
|
33
|
+
description: row.description,
|
|
34
|
+
status: row.status,
|
|
35
|
+
createdAt: row.created_at,
|
|
36
|
+
updatedAt: row.updated_at,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Map a database row to an ApplicationModule object.
|
|
41
|
+
*
|
|
42
|
+
* Converts snake_case column names from PostgreSQL to camelCase
|
|
43
|
+
* TypeScript properties. The `status` string is cast to
|
|
44
|
+
* `ModuleStatus` — the DB CHECK constraint guarantees it
|
|
45
|
+
* is one of the valid values.
|
|
46
|
+
*
|
|
47
|
+
* @param row - Raw database row from the application_modules table
|
|
48
|
+
* @returns Mapped ApplicationModule object with camelCase properties
|
|
49
|
+
*/
|
|
50
|
+
export function mapRowToModule(row) {
|
|
51
|
+
return {
|
|
52
|
+
id: row.id,
|
|
53
|
+
applicationId: row.application_id,
|
|
54
|
+
name: row.name,
|
|
55
|
+
slug: row.slug,
|
|
56
|
+
description: row.description,
|
|
57
|
+
status: row.status,
|
|
58
|
+
createdAt: row.created_at,
|
|
59
|
+
updatedAt: row.updated_at,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/applications/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA+HH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAmB;IACrD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,MAAM,EAAE,GAAG,CAAC,MAA2B;QACvC,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,GAAyB;IACtD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,MAAM,EAAE,GAAG,CAAC,MAAsB;QAClC,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF token generation and verification.
|
|
3
|
+
*
|
|
4
|
+
* Provides cookie-based synchronized token protection for server-rendered forms.
|
|
5
|
+
* Tokens are generated with crypto.randomBytes and verified using
|
|
6
|
+
* crypto.timingSafeEqual to prevent timing attacks.
|
|
7
|
+
*
|
|
8
|
+
* Pattern:
|
|
9
|
+
* 1. On GET (render form): generate token → set HttpOnly SameSite=Lax cookie
|
|
10
|
+
* → embed same token in hidden form field `_csrf`
|
|
11
|
+
* 2. On POST (process form): read `_csrf` from cookie → read `_csrf` from
|
|
12
|
+
* form body → compare with verifyCsrfToken(cookieValue, formValue)
|
|
13
|
+
* 3. Reject if mismatch (CSRF attack) or missing
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // In route handler (render form):
|
|
17
|
+
* const token = generateCsrfToken();
|
|
18
|
+
* setCsrfCookie(ctx, token);
|
|
19
|
+
* await renderPage('login', { csrfToken: token });
|
|
20
|
+
*
|
|
21
|
+
* // In route handler (process form):
|
|
22
|
+
* const valid = verifyCsrfToken(getCsrfFromCookie(ctx), ctx.request.body._csrf);
|
|
23
|
+
* if (!valid) ctx.throw(403, 'Invalid CSRF token');
|
|
24
|
+
*/
|
|
25
|
+
import type { Context } from 'koa';
|
|
26
|
+
/**
|
|
27
|
+
* Generate a cryptographically secure CSRF token.
|
|
28
|
+
*
|
|
29
|
+
* Returns a base64url-encoded string suitable for embedding in HTML forms
|
|
30
|
+
* and storing in session data.
|
|
31
|
+
*
|
|
32
|
+
* @returns Base64url-encoded CSRF token string
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateCsrfToken(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Verify a CSRF token using constant-time comparison.
|
|
37
|
+
*
|
|
38
|
+
* Uses crypto.timingSafeEqual to prevent timing side-channel attacks
|
|
39
|
+
* that could allow an attacker to guess the token byte-by-byte.
|
|
40
|
+
*
|
|
41
|
+
* Returns false (rather than throwing) for any mismatch, missing value,
|
|
42
|
+
* or length difference — the caller decides whether to throw 403.
|
|
43
|
+
*
|
|
44
|
+
* @param expected - The token stored in the user's session (trusted)
|
|
45
|
+
* @param actual - The token submitted in the form field (untrusted)
|
|
46
|
+
* @returns true if tokens match, false otherwise
|
|
47
|
+
*/
|
|
48
|
+
export declare function verifyCsrfToken(expected: string | undefined, actual: string | undefined): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Set the CSRF token as an HttpOnly cookie on the response.
|
|
51
|
+
* Call this in every GET handler that renders a form.
|
|
52
|
+
*
|
|
53
|
+
* The cookie uses:
|
|
54
|
+
* - `httpOnly: true` — prevents JavaScript access (XSS safe)
|
|
55
|
+
* - `sameSite: 'lax'` — blocks cross-site POST but allows navigational GET
|
|
56
|
+
* - `secure` — HTTPS-only when the connection is secure (direct TLS or behind proxy)
|
|
57
|
+
* - `path: '/'` — available to all routes
|
|
58
|
+
*
|
|
59
|
+
* @param ctx - Koa context
|
|
60
|
+
* @param token - CSRF token (from generateCsrfToken())
|
|
61
|
+
*/
|
|
62
|
+
export declare function setCsrfCookie(ctx: Context, token: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Read the CSRF token from the request cookie.
|
|
65
|
+
* Call this in every POST handler to get the "expected" (trusted) token.
|
|
66
|
+
*
|
|
67
|
+
* @param ctx - Koa context
|
|
68
|
+
* @returns The CSRF token from the cookie, or undefined if not set
|
|
69
|
+
*/
|
|
70
|
+
export declare function getCsrfFromCookie(ctx: Context): string | undefined;
|
|
71
|
+
//# sourceMappingURL=csrf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../src/auth/csrf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAgBnC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAgBjG;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQ/D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAElE"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF token generation and verification.
|
|
3
|
+
*
|
|
4
|
+
* Provides cookie-based synchronized token protection for server-rendered forms.
|
|
5
|
+
* Tokens are generated with crypto.randomBytes and verified using
|
|
6
|
+
* crypto.timingSafeEqual to prevent timing attacks.
|
|
7
|
+
*
|
|
8
|
+
* Pattern:
|
|
9
|
+
* 1. On GET (render form): generate token → set HttpOnly SameSite=Lax cookie
|
|
10
|
+
* → embed same token in hidden form field `_csrf`
|
|
11
|
+
* 2. On POST (process form): read `_csrf` from cookie → read `_csrf` from
|
|
12
|
+
* form body → compare with verifyCsrfToken(cookieValue, formValue)
|
|
13
|
+
* 3. Reject if mismatch (CSRF attack) or missing
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // In route handler (render form):
|
|
17
|
+
* const token = generateCsrfToken();
|
|
18
|
+
* setCsrfCookie(ctx, token);
|
|
19
|
+
* await renderPage('login', { csrfToken: token });
|
|
20
|
+
*
|
|
21
|
+
* // In route handler (process form):
|
|
22
|
+
* const valid = verifyCsrfToken(getCsrfFromCookie(ctx), ctx.request.body._csrf);
|
|
23
|
+
* if (!valid) ctx.throw(403, 'Invalid CSRF token');
|
|
24
|
+
*/
|
|
25
|
+
import crypto from 'node:crypto';
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Constants
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/** Number of random bytes for CSRF tokens (32 bytes = 256 bits of entropy) */
|
|
30
|
+
const CSRF_TOKEN_BYTES = 32;
|
|
31
|
+
/** Cookie name for CSRF token */
|
|
32
|
+
const CSRF_COOKIE_NAME = '_csrf';
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Generation
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
/**
|
|
37
|
+
* Generate a cryptographically secure CSRF token.
|
|
38
|
+
*
|
|
39
|
+
* Returns a base64url-encoded string suitable for embedding in HTML forms
|
|
40
|
+
* and storing in session data.
|
|
41
|
+
*
|
|
42
|
+
* @returns Base64url-encoded CSRF token string
|
|
43
|
+
*/
|
|
44
|
+
export function generateCsrfToken() {
|
|
45
|
+
return crypto.randomBytes(CSRF_TOKEN_BYTES).toString('base64url');
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Verification
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Verify a CSRF token using constant-time comparison.
|
|
52
|
+
*
|
|
53
|
+
* Uses crypto.timingSafeEqual to prevent timing side-channel attacks
|
|
54
|
+
* that could allow an attacker to guess the token byte-by-byte.
|
|
55
|
+
*
|
|
56
|
+
* Returns false (rather than throwing) for any mismatch, missing value,
|
|
57
|
+
* or length difference — the caller decides whether to throw 403.
|
|
58
|
+
*
|
|
59
|
+
* @param expected - The token stored in the user's session (trusted)
|
|
60
|
+
* @param actual - The token submitted in the form field (untrusted)
|
|
61
|
+
* @returns true if tokens match, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
export function verifyCsrfToken(expected, actual) {
|
|
64
|
+
// Both must be present and non-empty
|
|
65
|
+
if (!expected || !actual) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
// Convert to buffers for timingSafeEqual
|
|
69
|
+
const expectedBuf = Buffer.from(expected, 'utf-8');
|
|
70
|
+
const actualBuf = Buffer.from(actual, 'utf-8');
|
|
71
|
+
// timingSafeEqual requires equal-length buffers — different lengths = guaranteed mismatch
|
|
72
|
+
if (expectedBuf.length !== actualBuf.length) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return crypto.timingSafeEqual(expectedBuf, actualBuf);
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Cookie helpers
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* Set the CSRF token as an HttpOnly cookie on the response.
|
|
82
|
+
* Call this in every GET handler that renders a form.
|
|
83
|
+
*
|
|
84
|
+
* The cookie uses:
|
|
85
|
+
* - `httpOnly: true` — prevents JavaScript access (XSS safe)
|
|
86
|
+
* - `sameSite: 'lax'` — blocks cross-site POST but allows navigational GET
|
|
87
|
+
* - `secure` — HTTPS-only when the connection is secure (direct TLS or behind proxy)
|
|
88
|
+
* - `path: '/'` — available to all routes
|
|
89
|
+
*
|
|
90
|
+
* @param ctx - Koa context
|
|
91
|
+
* @param token - CSRF token (from generateCsrfToken())
|
|
92
|
+
*/
|
|
93
|
+
export function setCsrfCookie(ctx, token) {
|
|
94
|
+
ctx.cookies.set(CSRF_COOKIE_NAME, token, {
|
|
95
|
+
httpOnly: true,
|
|
96
|
+
sameSite: 'lax',
|
|
97
|
+
path: '/',
|
|
98
|
+
secure: ctx.secure,
|
|
99
|
+
overwrite: true,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Read the CSRF token from the request cookie.
|
|
104
|
+
* Call this in every POST handler to get the "expected" (trusted) token.
|
|
105
|
+
*
|
|
106
|
+
* @param ctx - Koa context
|
|
107
|
+
* @returns The CSRF token from the cookie, or undefined if not set
|
|
108
|
+
*/
|
|
109
|
+
export function getCsrfFromCookie(ctx) {
|
|
110
|
+
return ctx.cookies.get(CSRF_COOKIE_NAME) ?? undefined;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=csrf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/auth/csrf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,iCAAiC;AACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAEjC,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACpE,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,QAA4B,EAAE,MAA0B;IACtF,qCAAqC;IACrC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yCAAyC;IACzC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/C,0FAA0F;IAC1F,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,KAAa;IACvD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE;QACvC,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC5C,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,SAAS,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email template renderer using Handlebars.
|
|
3
|
+
*
|
|
4
|
+
* Renders HTML and plaintext email templates with organization branding
|
|
5
|
+
* and i18n context. Supports per-organization template overrides:
|
|
6
|
+
* 1. Try: templates/{orgSlug}/emails/{templateName}.hbs
|
|
7
|
+
* 2. Fall back: templates/default/emails/{templateName}.hbs
|
|
8
|
+
*
|
|
9
|
+
* Both .hbs (HTML) and .txt.hbs (plaintext) variants are rendered.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { html, text } = await renderEmail('magic-link', 'acme-corp', {
|
|
13
|
+
* userName: 'Alice',
|
|
14
|
+
* magicLinkUrl: 'https://...',
|
|
15
|
+
* branding: { logoUrl: '...', primaryColor: '#3B82F6', companyName: 'Acme' },
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Render an email template (HTML + plaintext) with the given context.
|
|
20
|
+
*
|
|
21
|
+
* Template resolution order:
|
|
22
|
+
* 1. templates/{orgSlug}/emails/{templateName}.hbs (org override)
|
|
23
|
+
* 2. templates/default/emails/{templateName}.hbs (default)
|
|
24
|
+
*
|
|
25
|
+
* Automatically adds `year` to the context for footer copyright.
|
|
26
|
+
*
|
|
27
|
+
* @param templateName - Email template name (e.g., 'magic-link', 'password-reset')
|
|
28
|
+
* @param orgSlug - Organization slug for template override lookup
|
|
29
|
+
* @param context - Template variables (userName, branding, URLs, etc.)
|
|
30
|
+
* @returns Object with rendered `html` and `text` strings
|
|
31
|
+
* @throws Error if the HTML template cannot be found
|
|
32
|
+
*/
|
|
33
|
+
export declare function renderEmail(templateName: string, orgSlug: string, context: Record<string, unknown>): Promise<{
|
|
34
|
+
html: string;
|
|
35
|
+
text: string;
|
|
36
|
+
}>;
|
|
37
|
+
//# sourceMappingURL=email-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-renderer.d.ts","sourceRoot":"","sources":["../../src/auth/email-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAgEH;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAmCzC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email template renderer using Handlebars.
|
|
3
|
+
*
|
|
4
|
+
* Renders HTML and plaintext email templates with organization branding
|
|
5
|
+
* and i18n context. Supports per-organization template overrides:
|
|
6
|
+
* 1. Try: templates/{orgSlug}/emails/{templateName}.hbs
|
|
7
|
+
* 2. Fall back: templates/default/emails/{templateName}.hbs
|
|
8
|
+
*
|
|
9
|
+
* Both .hbs (HTML) and .txt.hbs (plaintext) variants are rendered.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { html, text } = await renderEmail('magic-link', 'acme-corp', {
|
|
13
|
+
* userName: 'Alice',
|
|
14
|
+
* magicLinkUrl: 'https://...',
|
|
15
|
+
* branding: { logoUrl: '...', primaryColor: '#3B82F6', companyName: 'Acme' },
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
import fs from 'node:fs/promises';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import Handlebars from 'handlebars';
|
|
21
|
+
import { logger } from '../lib/logger.js';
|
|
22
|
+
import { getTemplatesDirectory } from '../lib/runtime-paths.js';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Constants
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/** Absolute directory containing templates shipped with the server package. */
|
|
27
|
+
const TEMPLATES_DIR = getTemplatesDirectory();
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Template resolution
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a template file path with org-override support.
|
|
33
|
+
*
|
|
34
|
+
* Checks for an organization-specific template first, then falls back
|
|
35
|
+
* to the default template. Returns null if neither exists.
|
|
36
|
+
*
|
|
37
|
+
* @param orgSlug - Organization slug for override lookup
|
|
38
|
+
* @param templatePath - Relative path within the emails directory (e.g., 'magic-link.hbs')
|
|
39
|
+
* @returns Absolute path to the template file, or null if not found
|
|
40
|
+
*/
|
|
41
|
+
async function resolveTemplatePath(orgSlug, templatePath) {
|
|
42
|
+
// Try org-specific template first
|
|
43
|
+
const orgPath = path.join(TEMPLATES_DIR, orgSlug, 'emails', templatePath);
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(orgPath);
|
|
46
|
+
return orgPath;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Org-specific template doesn't exist — fall through to default
|
|
50
|
+
}
|
|
51
|
+
// Fall back to default template
|
|
52
|
+
const defaultPath = path.join(TEMPLATES_DIR, 'default', 'emails', templatePath);
|
|
53
|
+
try {
|
|
54
|
+
await fs.access(defaultPath);
|
|
55
|
+
return defaultPath;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Load and compile a Handlebars template from the file system.
|
|
63
|
+
*
|
|
64
|
+
* @param filePath - Absolute path to the template file
|
|
65
|
+
* @returns Compiled Handlebars template function
|
|
66
|
+
*/
|
|
67
|
+
async function loadTemplate(filePath) {
|
|
68
|
+
const source = await fs.readFile(filePath, 'utf-8');
|
|
69
|
+
return Handlebars.compile(source);
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Public API
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Render an email template (HTML + plaintext) with the given context.
|
|
76
|
+
*
|
|
77
|
+
* Template resolution order:
|
|
78
|
+
* 1. templates/{orgSlug}/emails/{templateName}.hbs (org override)
|
|
79
|
+
* 2. templates/default/emails/{templateName}.hbs (default)
|
|
80
|
+
*
|
|
81
|
+
* Automatically adds `year` to the context for footer copyright.
|
|
82
|
+
*
|
|
83
|
+
* @param templateName - Email template name (e.g., 'magic-link', 'password-reset')
|
|
84
|
+
* @param orgSlug - Organization slug for template override lookup
|
|
85
|
+
* @param context - Template variables (userName, branding, URLs, etc.)
|
|
86
|
+
* @returns Object with rendered `html` and `text` strings
|
|
87
|
+
* @throws Error if the HTML template cannot be found
|
|
88
|
+
*/
|
|
89
|
+
export async function renderEmail(templateName, orgSlug, context) {
|
|
90
|
+
// Resolve HTML template (required)
|
|
91
|
+
const htmlPath = await resolveTemplatePath(orgSlug, `${templateName}.hbs`);
|
|
92
|
+
if (!htmlPath) {
|
|
93
|
+
throw new Error(`Email template not found: ${templateName}.hbs (checked ${orgSlug}/ and default/)`);
|
|
94
|
+
}
|
|
95
|
+
// Resolve plaintext template (optional — fall back to empty string)
|
|
96
|
+
const textPath = await resolveTemplatePath(orgSlug, `${templateName}.txt.hbs`);
|
|
97
|
+
// Enrich context with common variables
|
|
98
|
+
const enrichedContext = {
|
|
99
|
+
...context,
|
|
100
|
+
year: new Date().getFullYear(),
|
|
101
|
+
};
|
|
102
|
+
// Render HTML
|
|
103
|
+
const htmlTemplate = await loadTemplate(htmlPath);
|
|
104
|
+
const html = htmlTemplate(enrichedContext);
|
|
105
|
+
// Render plaintext (if template exists)
|
|
106
|
+
let text = '';
|
|
107
|
+
if (textPath) {
|
|
108
|
+
const textTemplate = await loadTemplate(textPath);
|
|
109
|
+
text = textTemplate(enrichedContext);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
logger.debug({ templateName, orgSlug }, 'No plaintext email template found — using empty text body');
|
|
113
|
+
}
|
|
114
|
+
return { html, text };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=email-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-renderer.js","sourceRoot":"","sources":["../../src/auth/email-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,+EAA+E;AAC/E,MAAM,aAAa,GAAG,qBAAqB,EAAE,CAAC;AAE9C,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,KAAK,UAAU,mBAAmB,CAAC,OAAe,EAAE,YAAoB;IACtE,kCAAkC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC1E,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;IAED,gCAAgC;IAChC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC7B,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpD,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,YAAoB,EACpB,OAAe,EACf,OAAgC;IAEhC,mCAAmC;IACnC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,GAAG,YAAY,MAAM,CAAC,CAAC;IAC3E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,6BAA6B,YAAY,iBAAiB,OAAO,iBAAiB,CACnF,CAAC;IACJ,CAAC;IAED,oEAAoE;IACpE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,GAAG,YAAY,UAAU,CAAC,CAAC;IAE/E,uCAAuC;IACvC,MAAM,eAAe,GAAG;QACtB,GAAG,OAAO;QACV,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAC/B,CAAC;IAEF,cAAc;IACd,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;IAE3C,wCAAwC;IACxC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CACV,EAAE,YAAY,EAAE,OAAO,EAAE,EACzB,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
|