@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,511 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Organization service — business logic orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Composes the repository, cache, slug utilities, and audit log
|
|
5
|
+
* to provide the complete organization management API. All write
|
|
6
|
+
* operations follow the pattern:
|
|
7
|
+
* 1. Validate inputs
|
|
8
|
+
* 2. Perform DB operation (via repository)
|
|
9
|
+
* 3. Invalidate + re-cache (via cache)
|
|
10
|
+
* 4. Write audit log (fire-and-forget)
|
|
11
|
+
*
|
|
12
|
+
* Read operations check cache first, fall back to DB on miss.
|
|
13
|
+
*
|
|
14
|
+
* Status lifecycle rules:
|
|
15
|
+
* - suspend: active → suspended (super-admin blocked)
|
|
16
|
+
* - activate: suspended → active
|
|
17
|
+
* - archive: active|suspended → archived (super-admin blocked)
|
|
18
|
+
* - restore: archived → active
|
|
19
|
+
*/
|
|
20
|
+
import { insertOrganization, findOrganizationById, findOrganizationBySlug, updateOrganization as repoUpdate, listOrganizations as repoList, listOrganizationsCursor as repoListCursor, slugExists, hardDeleteOrganization, getCascadeCounts as repoGetCascadeCounts, } from './repository.js';
|
|
21
|
+
import { getCachedOrganizationById, getCachedOrganizationBySlug, cacheOrganization, invalidateOrganizationCache, } from './cache.js';
|
|
22
|
+
import { generateSlug, validateSlug } from './slugs.js';
|
|
23
|
+
import { writeAuditLog } from '../lib/audit-log.js';
|
|
24
|
+
import { OrganizationNotFoundError, OrganizationValidationError } from './errors.js';
|
|
25
|
+
// Import directly from the type/resolver modules (not the clients barrel)
|
|
26
|
+
// to keep the org→clients dependency narrow and avoid pulling the entire
|
|
27
|
+
// clients service surface into the organizations module.
|
|
28
|
+
import { LOGIN_METHODS } from '../clients/types.js';
|
|
29
|
+
import { normalizeLoginMethods } from '../clients/resolve-login-methods.js';
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Validation helpers (private)
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
/**
|
|
34
|
+
* Validate + normalize a `defaultLoginMethods` input array.
|
|
35
|
+
*
|
|
36
|
+
* Throws {@link OrganizationValidationError} when:
|
|
37
|
+
* - the value is not an array
|
|
38
|
+
* - the array is empty
|
|
39
|
+
* - any element is not a valid {@link LoginMethod}
|
|
40
|
+
*
|
|
41
|
+
* Returns the normalized (deduplicated, order-preserving) array on success.
|
|
42
|
+
*/
|
|
43
|
+
function validateDefaultLoginMethods(methods) {
|
|
44
|
+
if (methods === undefined)
|
|
45
|
+
return undefined;
|
|
46
|
+
if (!Array.isArray(methods) || methods.length === 0) {
|
|
47
|
+
throw new OrganizationValidationError('defaultLoginMethods: must be a non-empty array');
|
|
48
|
+
}
|
|
49
|
+
for (const m of methods) {
|
|
50
|
+
if (!LOGIN_METHODS.includes(m)) {
|
|
51
|
+
throw new OrganizationValidationError(`defaultLoginMethods: invalid method "${String(m)}"`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return normalizeLoginMethods(methods);
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Create
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
/**
|
|
60
|
+
* Create a new organization.
|
|
61
|
+
*
|
|
62
|
+
* 1. Generate slug from name if not provided
|
|
63
|
+
* 2. Validate slug format and reserved words
|
|
64
|
+
* 3. Check slug uniqueness in the database
|
|
65
|
+
* 4. Insert organization via repository
|
|
66
|
+
* 5. Cache the new organization
|
|
67
|
+
* 6. Write audit log entry
|
|
68
|
+
*
|
|
69
|
+
* @param input - Organization creation data
|
|
70
|
+
* @param actorId - UUID of the user performing the action (for audit)
|
|
71
|
+
* @returns Created organization
|
|
72
|
+
* @throws OrganizationValidationError if slug is invalid or already taken
|
|
73
|
+
*/
|
|
74
|
+
export async function createOrganization(input, actorId) {
|
|
75
|
+
// Generate or use provided slug
|
|
76
|
+
const slug = input.slug ?? generateSlug(input.name);
|
|
77
|
+
// Validate slug format and reserved words
|
|
78
|
+
const validation = validateSlug(slug);
|
|
79
|
+
if (!validation.isValid) {
|
|
80
|
+
throw new OrganizationValidationError(validation.error);
|
|
81
|
+
}
|
|
82
|
+
// Check uniqueness
|
|
83
|
+
const taken = await slugExists(slug);
|
|
84
|
+
if (taken) {
|
|
85
|
+
throw new OrganizationValidationError('Slug already in use');
|
|
86
|
+
}
|
|
87
|
+
// Validate + normalize defaultLoginMethods (throws on invalid input).
|
|
88
|
+
// Undefined → fall back to DB DEFAULT in the repository INSERT.
|
|
89
|
+
const defaultLoginMethods = validateDefaultLoginMethods(input.defaultLoginMethods);
|
|
90
|
+
// Insert into database
|
|
91
|
+
const org = await insertOrganization({
|
|
92
|
+
name: input.name,
|
|
93
|
+
slug,
|
|
94
|
+
defaultLocale: input.defaultLocale ?? 'en',
|
|
95
|
+
brandingLogoUrl: input.branding?.logoUrl,
|
|
96
|
+
brandingFaviconUrl: input.branding?.faviconUrl,
|
|
97
|
+
brandingPrimaryColor: input.branding?.primaryColor,
|
|
98
|
+
brandingCompanyName: input.branding?.companyName,
|
|
99
|
+
brandingCustomCss: input.branding?.customCss,
|
|
100
|
+
defaultLoginMethods,
|
|
101
|
+
});
|
|
102
|
+
// Cache the new organization
|
|
103
|
+
await cacheOrganization(org);
|
|
104
|
+
// Audit log (fire-and-forget) — include the resolved defaults so audit
|
|
105
|
+
// captures the effective configuration even when the caller relied on
|
|
106
|
+
// the DB DEFAULT.
|
|
107
|
+
await writeAuditLog({
|
|
108
|
+
organizationId: org.id,
|
|
109
|
+
actorId,
|
|
110
|
+
eventType: 'org.created',
|
|
111
|
+
eventCategory: 'admin',
|
|
112
|
+
metadata: {
|
|
113
|
+
slug: org.slug,
|
|
114
|
+
name: org.name,
|
|
115
|
+
defaultLoginMethods: org.defaultLoginMethods,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return org;
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Read
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
/**
|
|
124
|
+
* Find an organization by ID.
|
|
125
|
+
* Checks Redis cache first, falls back to database on miss.
|
|
126
|
+
*
|
|
127
|
+
* @param id - Organization UUID
|
|
128
|
+
* @returns Organization or null if not found
|
|
129
|
+
*/
|
|
130
|
+
export async function getOrganizationById(id) {
|
|
131
|
+
// Try cache first
|
|
132
|
+
const cached = await getCachedOrganizationById(id);
|
|
133
|
+
if (cached)
|
|
134
|
+
return cached;
|
|
135
|
+
// Fall back to database
|
|
136
|
+
const org = await findOrganizationById(id);
|
|
137
|
+
if (org) {
|
|
138
|
+
await cacheOrganization(org);
|
|
139
|
+
}
|
|
140
|
+
return org;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Find an organization by slug.
|
|
144
|
+
* Checks Redis cache first, falls back to database on miss.
|
|
145
|
+
*
|
|
146
|
+
* @param slug - Organization slug
|
|
147
|
+
* @returns Organization or null if not found
|
|
148
|
+
*/
|
|
149
|
+
export async function getOrganizationBySlug(slug) {
|
|
150
|
+
// Try cache first
|
|
151
|
+
const cached = await getCachedOrganizationBySlug(slug);
|
|
152
|
+
if (cached)
|
|
153
|
+
return cached;
|
|
154
|
+
// Fall back to database
|
|
155
|
+
const org = await findOrganizationBySlug(slug);
|
|
156
|
+
if (org) {
|
|
157
|
+
await cacheOrganization(org);
|
|
158
|
+
}
|
|
159
|
+
return org;
|
|
160
|
+
}
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// Update
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
/**
|
|
165
|
+
* Update an organization's basic fields (name, locale).
|
|
166
|
+
*
|
|
167
|
+
* @param id - Organization UUID
|
|
168
|
+
* @param input - Fields to update
|
|
169
|
+
* @param actorId - UUID of the user performing the action
|
|
170
|
+
* @returns Updated organization
|
|
171
|
+
* @throws OrganizationNotFoundError if organization not found
|
|
172
|
+
*/
|
|
173
|
+
export async function updateOrganization(id, input, actorId) {
|
|
174
|
+
// Build update data from input
|
|
175
|
+
const updateData = {};
|
|
176
|
+
if (input.name !== undefined)
|
|
177
|
+
updateData.name = input.name;
|
|
178
|
+
if (input.defaultLocale !== undefined)
|
|
179
|
+
updateData.defaultLocale = input.defaultLocale;
|
|
180
|
+
if (input.twoFactorPolicy !== undefined)
|
|
181
|
+
updateData.twoFactorPolicy = input.twoFactorPolicy;
|
|
182
|
+
// Validate + normalize defaultLoginMethods if provided (throws on invalid).
|
|
183
|
+
// Capture the previous value (for audit log diff) before the update is
|
|
184
|
+
// applied, so we can record the old → new transition.
|
|
185
|
+
let previousDefaultLoginMethods;
|
|
186
|
+
if (input.defaultLoginMethods !== undefined) {
|
|
187
|
+
const normalized = validateDefaultLoginMethods(input.defaultLoginMethods);
|
|
188
|
+
updateData.defaultLoginMethods = normalized;
|
|
189
|
+
// Look up the current value for the audit diff. We use the cache-aware
|
|
190
|
+
// accessor so we get a Date-deserialized object back; if the org doesn't
|
|
191
|
+
// exist the repo update will throw OrganizationNotFoundError below.
|
|
192
|
+
const existing = await getOrganizationById(id);
|
|
193
|
+
if (existing) {
|
|
194
|
+
previousDefaultLoginMethods = existing.defaultLoginMethods;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Include branding fields if provided
|
|
198
|
+
if (input.branding) {
|
|
199
|
+
if (input.branding.logoUrl !== undefined)
|
|
200
|
+
updateData.brandingLogoUrl = input.branding.logoUrl;
|
|
201
|
+
if (input.branding.faviconUrl !== undefined)
|
|
202
|
+
updateData.brandingFaviconUrl = input.branding.faviconUrl;
|
|
203
|
+
if (input.branding.primaryColor !== undefined)
|
|
204
|
+
updateData.brandingPrimaryColor = input.branding.primaryColor;
|
|
205
|
+
if (input.branding.companyName !== undefined)
|
|
206
|
+
updateData.brandingCompanyName = input.branding.companyName;
|
|
207
|
+
if (input.branding.customCss !== undefined)
|
|
208
|
+
updateData.brandingCustomCss = input.branding.customCss;
|
|
209
|
+
}
|
|
210
|
+
let org;
|
|
211
|
+
try {
|
|
212
|
+
org = await repoUpdate(id, updateData);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
if (err instanceof Error && err.message === 'Organization not found') {
|
|
216
|
+
throw new OrganizationNotFoundError(id);
|
|
217
|
+
}
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
// Invalidate old cache and re-cache the updated version
|
|
221
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
222
|
+
await cacheOrganization(org);
|
|
223
|
+
// Audit log (fire-and-forget) — include old/new login methods when
|
|
224
|
+
// they changed, for forensic traceability.
|
|
225
|
+
const auditMetadata = {
|
|
226
|
+
fields: Object.keys(updateData),
|
|
227
|
+
};
|
|
228
|
+
if (input.defaultLoginMethods !== undefined) {
|
|
229
|
+
auditMetadata.previousDefaultLoginMethods = previousDefaultLoginMethods ?? null;
|
|
230
|
+
auditMetadata.newDefaultLoginMethods = org.defaultLoginMethods;
|
|
231
|
+
}
|
|
232
|
+
await writeAuditLog({
|
|
233
|
+
organizationId: org.id,
|
|
234
|
+
actorId,
|
|
235
|
+
eventType: 'org.updated',
|
|
236
|
+
eventCategory: 'admin',
|
|
237
|
+
metadata: auditMetadata,
|
|
238
|
+
});
|
|
239
|
+
return org;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Update an organization's branding configuration.
|
|
243
|
+
*
|
|
244
|
+
* @param id - Organization UUID
|
|
245
|
+
* @param branding - Branding fields to update
|
|
246
|
+
* @param actorId - UUID of the user performing the action
|
|
247
|
+
* @returns Updated organization
|
|
248
|
+
* @throws OrganizationNotFoundError if organization not found
|
|
249
|
+
*/
|
|
250
|
+
export async function updateOrganizationBranding(id, branding, actorId) {
|
|
251
|
+
const updateData = {};
|
|
252
|
+
if (branding.logoUrl !== undefined)
|
|
253
|
+
updateData.brandingLogoUrl = branding.logoUrl;
|
|
254
|
+
if (branding.faviconUrl !== undefined)
|
|
255
|
+
updateData.brandingFaviconUrl = branding.faviconUrl;
|
|
256
|
+
if (branding.primaryColor !== undefined)
|
|
257
|
+
updateData.brandingPrimaryColor = branding.primaryColor;
|
|
258
|
+
if (branding.companyName !== undefined)
|
|
259
|
+
updateData.brandingCompanyName = branding.companyName;
|
|
260
|
+
if (branding.customCss !== undefined)
|
|
261
|
+
updateData.brandingCustomCss = branding.customCss;
|
|
262
|
+
let org;
|
|
263
|
+
try {
|
|
264
|
+
org = await repoUpdate(id, updateData);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
if (err instanceof Error && err.message === 'Organization not found') {
|
|
268
|
+
throw new OrganizationNotFoundError(id);
|
|
269
|
+
}
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
273
|
+
await cacheOrganization(org);
|
|
274
|
+
// Audit log (fire-and-forget)
|
|
275
|
+
await writeAuditLog({
|
|
276
|
+
organizationId: org.id,
|
|
277
|
+
actorId,
|
|
278
|
+
eventType: 'org.branding.updated',
|
|
279
|
+
eventCategory: 'admin',
|
|
280
|
+
metadata: { fields: Object.keys(updateData) },
|
|
281
|
+
});
|
|
282
|
+
return org;
|
|
283
|
+
}
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
// Status lifecycle
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
/**
|
|
288
|
+
* Load and validate an organization exists before a status change.
|
|
289
|
+
* @throws OrganizationNotFoundError if not found
|
|
290
|
+
*/
|
|
291
|
+
async function loadOrgForStatusChange(id) {
|
|
292
|
+
const org = await findOrganizationById(id);
|
|
293
|
+
if (!org)
|
|
294
|
+
throw new OrganizationNotFoundError(id);
|
|
295
|
+
return org;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Suspend an organization (active → suspended).
|
|
299
|
+
* Super-admin organization cannot be suspended.
|
|
300
|
+
*
|
|
301
|
+
* @param id - Organization UUID
|
|
302
|
+
* @param reason - Optional reason for suspension
|
|
303
|
+
* @param actorId - UUID of the user performing the action
|
|
304
|
+
* @throws OrganizationNotFoundError if not found
|
|
305
|
+
* @throws OrganizationValidationError if super-admin, already suspended, or archived
|
|
306
|
+
*/
|
|
307
|
+
export async function suspendOrganization(id, reason, actorId) {
|
|
308
|
+
const org = await loadOrgForStatusChange(id);
|
|
309
|
+
if (org.isSuperAdmin) {
|
|
310
|
+
throw new OrganizationValidationError('Super-admin organization cannot be suspended');
|
|
311
|
+
}
|
|
312
|
+
if (org.status === 'suspended') {
|
|
313
|
+
throw new OrganizationValidationError('Organization is already suspended');
|
|
314
|
+
}
|
|
315
|
+
if (org.status !== 'active') {
|
|
316
|
+
throw new OrganizationValidationError(`Cannot suspend organization from status: ${org.status}`);
|
|
317
|
+
}
|
|
318
|
+
await repoUpdate(id, { status: 'suspended' });
|
|
319
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
320
|
+
await writeAuditLog({
|
|
321
|
+
organizationId: org.id,
|
|
322
|
+
actorId,
|
|
323
|
+
eventType: 'org.suspended',
|
|
324
|
+
eventCategory: 'admin',
|
|
325
|
+
metadata: { reason: reason ?? null },
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Activate an organization (suspended → active).
|
|
330
|
+
*
|
|
331
|
+
* @param id - Organization UUID
|
|
332
|
+
* @param actorId - UUID of the user performing the action
|
|
333
|
+
* @throws OrganizationNotFoundError if not found
|
|
334
|
+
* @throws OrganizationValidationError if not currently suspended
|
|
335
|
+
*/
|
|
336
|
+
export async function activateOrganization(id, actorId) {
|
|
337
|
+
const org = await loadOrgForStatusChange(id);
|
|
338
|
+
if (org.status !== 'suspended') {
|
|
339
|
+
throw new OrganizationValidationError(`Cannot activate organization from status: ${org.status}`);
|
|
340
|
+
}
|
|
341
|
+
await repoUpdate(id, { status: 'active' });
|
|
342
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
343
|
+
await writeAuditLog({
|
|
344
|
+
organizationId: org.id,
|
|
345
|
+
actorId,
|
|
346
|
+
eventType: 'org.activated',
|
|
347
|
+
eventCategory: 'admin',
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Archive an organization (soft-delete).
|
|
352
|
+
* Super-admin organization cannot be archived.
|
|
353
|
+
*
|
|
354
|
+
* @param id - Organization UUID
|
|
355
|
+
* @param actorId - UUID of the user performing the action
|
|
356
|
+
* @throws OrganizationNotFoundError if not found
|
|
357
|
+
* @throws OrganizationValidationError if super-admin or already archived
|
|
358
|
+
*/
|
|
359
|
+
export async function archiveOrganization(id, actorId) {
|
|
360
|
+
const org = await loadOrgForStatusChange(id);
|
|
361
|
+
if (org.isSuperAdmin) {
|
|
362
|
+
throw new OrganizationValidationError('Super-admin organization cannot be archived');
|
|
363
|
+
}
|
|
364
|
+
if (org.status === 'archived') {
|
|
365
|
+
throw new OrganizationValidationError('Organization is already archived');
|
|
366
|
+
}
|
|
367
|
+
await repoUpdate(id, { status: 'archived' });
|
|
368
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
369
|
+
await writeAuditLog({
|
|
370
|
+
organizationId: org.id,
|
|
371
|
+
actorId,
|
|
372
|
+
eventType: 'org.archived',
|
|
373
|
+
eventCategory: 'admin',
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Restore an archived organization (archived → active).
|
|
378
|
+
*
|
|
379
|
+
* @param id - Organization UUID
|
|
380
|
+
* @param actorId - UUID of the user performing the action
|
|
381
|
+
* @throws OrganizationNotFoundError if not found
|
|
382
|
+
* @throws OrganizationValidationError if not currently archived
|
|
383
|
+
*/
|
|
384
|
+
export async function restoreOrganization(id, actorId) {
|
|
385
|
+
const org = await loadOrgForStatusChange(id);
|
|
386
|
+
if (org.status !== 'archived') {
|
|
387
|
+
throw new OrganizationValidationError(`Cannot restore organization from status: ${org.status}`);
|
|
388
|
+
}
|
|
389
|
+
await repoUpdate(id, { status: 'active' });
|
|
390
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
391
|
+
await writeAuditLog({
|
|
392
|
+
organizationId: org.id,
|
|
393
|
+
actorId,
|
|
394
|
+
eventType: 'org.restored',
|
|
395
|
+
eventCategory: 'admin',
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
// ---------------------------------------------------------------------------
|
|
399
|
+
// List
|
|
400
|
+
// ---------------------------------------------------------------------------
|
|
401
|
+
/**
|
|
402
|
+
* List organizations with pagination and filtering.
|
|
403
|
+
* Delegates directly to the repository.
|
|
404
|
+
*
|
|
405
|
+
* @param options - Pagination, filter, and sort options
|
|
406
|
+
* @returns Paginated result
|
|
407
|
+
*/
|
|
408
|
+
export async function listOrganizations(options) {
|
|
409
|
+
return repoList(options);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* List organizations with cursor-based keyset pagination.
|
|
413
|
+
* Provides stable, efficient pagination without COUNT queries.
|
|
414
|
+
* Delegates directly to the repository cursor implementation.
|
|
415
|
+
*
|
|
416
|
+
* @param options - Cursor, limit, filter, and sort options
|
|
417
|
+
* @returns Cursor-paginated result with nextCursor/hasMore
|
|
418
|
+
*/
|
|
419
|
+
export async function listOrganizationsCursor(options) {
|
|
420
|
+
return repoListCursor(options);
|
|
421
|
+
}
|
|
422
|
+
// ---------------------------------------------------------------------------
|
|
423
|
+
// Slug validation
|
|
424
|
+
// ---------------------------------------------------------------------------
|
|
425
|
+
/**
|
|
426
|
+
* Validate if a slug is available and valid.
|
|
427
|
+
* Checks both format/reserved words AND database uniqueness.
|
|
428
|
+
*
|
|
429
|
+
* @param slug - Slug to validate
|
|
430
|
+
* @param excludeId - Optional org ID to exclude (for updates)
|
|
431
|
+
* @returns Object with isValid boolean and optional error message
|
|
432
|
+
*/
|
|
433
|
+
export async function validateSlugAvailability(slug, excludeId) {
|
|
434
|
+
// Check format and reserved words first
|
|
435
|
+
const validation = validateSlug(slug);
|
|
436
|
+
if (!validation.isValid) {
|
|
437
|
+
return validation;
|
|
438
|
+
}
|
|
439
|
+
// Check database uniqueness
|
|
440
|
+
const taken = await slugExists(slug, excludeId);
|
|
441
|
+
if (taken) {
|
|
442
|
+
return { isValid: false, error: 'Slug already in use' };
|
|
443
|
+
}
|
|
444
|
+
return { isValid: true };
|
|
445
|
+
}
|
|
446
|
+
// ---------------------------------------------------------------------------
|
|
447
|
+
// Destroy (hard delete)
|
|
448
|
+
// ---------------------------------------------------------------------------
|
|
449
|
+
/**
|
|
450
|
+
* Get cascade counts for an organization (preview of what will be deleted).
|
|
451
|
+
*
|
|
452
|
+
* @param orgId - Organization UUID
|
|
453
|
+
* @returns Counts of each child entity type
|
|
454
|
+
*/
|
|
455
|
+
export async function getCascadeCounts(orgId) {
|
|
456
|
+
return repoGetCascadeCounts(orgId);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Destroy an organization and all its child entities via CASCADE.
|
|
460
|
+
*
|
|
461
|
+
* Safety checks:
|
|
462
|
+
* 1. Organization must exist
|
|
463
|
+
* 2. Organization must NOT be the super-admin org (application-level check)
|
|
464
|
+
* 3. Cascade counts are calculated before deletion (for audit trail)
|
|
465
|
+
* 4. Audit log is written BEFORE deletion (org_id becomes NULL after DELETE)
|
|
466
|
+
* 5. Hard-delete with SQL-level super-admin guard (defense in depth)
|
|
467
|
+
* 6. Cache invalidated after successful deletion
|
|
468
|
+
*
|
|
469
|
+
* @param idOrSlug - Organization ID or slug
|
|
470
|
+
* @param actorId - ID of the admin performing the destruction (for audit log)
|
|
471
|
+
* @returns Object with the deleted org and cascade counts
|
|
472
|
+
* @throws OrganizationNotFoundError if org doesn't exist
|
|
473
|
+
* @throws OrganizationValidationError if org is super-admin
|
|
474
|
+
*/
|
|
475
|
+
export async function destroyOrganization(idOrSlug, actorId) {
|
|
476
|
+
// 1. Resolve org (try by ID first, then by slug)
|
|
477
|
+
let org = await findOrganizationById(idOrSlug);
|
|
478
|
+
if (!org) {
|
|
479
|
+
org = await findOrganizationBySlug(idOrSlug);
|
|
480
|
+
}
|
|
481
|
+
if (!org) {
|
|
482
|
+
throw new OrganizationNotFoundError(idOrSlug);
|
|
483
|
+
}
|
|
484
|
+
// 2. Super-admin protection (application-level check)
|
|
485
|
+
if (org.isSuperAdmin) {
|
|
486
|
+
throw new OrganizationValidationError('Cannot destroy the super-admin organization');
|
|
487
|
+
}
|
|
488
|
+
// 3. Count cascade targets (for audit trail and response)
|
|
489
|
+
const cascadeCounts = await repoGetCascadeCounts(org.id);
|
|
490
|
+
// 4. Write audit log BEFORE deletion (org_id will be SET NULL after delete)
|
|
491
|
+
await writeAuditLog({
|
|
492
|
+
organizationId: org.id,
|
|
493
|
+
actorId,
|
|
494
|
+
eventType: 'org.destroyed',
|
|
495
|
+
eventCategory: 'admin',
|
|
496
|
+
metadata: {
|
|
497
|
+
name: org.name,
|
|
498
|
+
slug: org.slug,
|
|
499
|
+
cascadeCounts,
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
// 5. Hard-delete (CASCADE handles children)
|
|
503
|
+
const deleted = await hardDeleteOrganization(org.id);
|
|
504
|
+
if (!deleted) {
|
|
505
|
+
throw new OrganizationValidationError('Failed to delete organization — it may be the super-admin org');
|
|
506
|
+
}
|
|
507
|
+
// 6. Invalidate cache
|
|
508
|
+
await invalidateOrganizationCache(org.slug, org.id);
|
|
509
|
+
return { organization: org, cascadeCounts };
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/organizations/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slug generation and validation utilities.
|
|
3
|
+
*
|
|
4
|
+
* Organization slugs are URL-safe identifiers used in path-based
|
|
5
|
+
* multi-tenancy (e.g., /{slug}/.well-known/openid-configuration).
|
|
6
|
+
* They must be 3–100 characters, lowercase alphanumeric with hyphens,
|
|
7
|
+
* and cannot be a reserved system word.
|
|
8
|
+
*
|
|
9
|
+
* This module provides:
|
|
10
|
+
* - `generateSlug(name)` — Derive a slug from an organization name
|
|
11
|
+
* - `validateSlug(slug)` — Check format and reserved-word rules
|
|
12
|
+
* - `RESERVED_SLUGS` — The set of words that cannot be used as slugs
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Reserved slugs that cannot be used as organization slugs.
|
|
16
|
+
* These conflict with system routes, well-known paths, or
|
|
17
|
+
* could cause confusion with internal functionality.
|
|
18
|
+
*/
|
|
19
|
+
export declare const RESERVED_SLUGS: ReadonlySet<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Generate a URL-safe slug from an organization name.
|
|
22
|
+
*
|
|
23
|
+
* Transformation rules:
|
|
24
|
+
* 1. Convert to lowercase
|
|
25
|
+
* 2. Replace non-alphanumeric characters with hyphens
|
|
26
|
+
* 3. Collapse multiple consecutive hyphens into one
|
|
27
|
+
* 4. Trim leading and trailing hyphens
|
|
28
|
+
* 5. Truncate to 100 characters (trimming trailing hyphens after truncation)
|
|
29
|
+
*
|
|
30
|
+
* Returns an empty string for empty/whitespace-only input — the caller
|
|
31
|
+
* (service layer) is responsible for validation.
|
|
32
|
+
*
|
|
33
|
+
* @param name - Organization name to derive a slug from
|
|
34
|
+
* @returns Generated slug string
|
|
35
|
+
*/
|
|
36
|
+
export declare function generateSlug(name: string): string;
|
|
37
|
+
/** Result of slug validation — isValid flag with optional error message */
|
|
38
|
+
export interface SlugValidationResult {
|
|
39
|
+
isValid: boolean;
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validate a slug against format and reserved word rules.
|
|
44
|
+
*
|
|
45
|
+
* Checks (in order):
|
|
46
|
+
* 1. Minimum length (3 characters)
|
|
47
|
+
* 2. Maximum length (100 characters)
|
|
48
|
+
* 3. Format (lowercase alphanumeric + hyphens, no leading/trailing hyphens)
|
|
49
|
+
* 4. Not a reserved word
|
|
50
|
+
*
|
|
51
|
+
* Does NOT check uniqueness — that's the repository/service layer's job.
|
|
52
|
+
*
|
|
53
|
+
* @param slug - Slug string to validate
|
|
54
|
+
* @returns Object with isValid boolean and optional error message
|
|
55
|
+
*/
|
|
56
|
+
export declare function validateSlug(slug: string): SlugValidationResult;
|
|
57
|
+
//# sourceMappingURL=slugs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../src/organizations/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CA8B7C,CAAC;AAiBH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBjD;AAMD,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CA2B/D"}
|