@portaidentity/server 1.7.3 → 1.8.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 +5 -0
- package/dist/applications/index.d.ts +2 -2
- package/dist/applications/index.d.ts.map +1 -1
- package/dist/applications/index.js +2 -2
- package/dist/applications/index.js.map +1 -1
- package/dist/applications/repository.d.ts +49 -4
- package/dist/applications/repository.d.ts.map +1 -1
- package/dist/applications/repository.js +148 -10
- package/dist/applications/repository.js.map +1 -1
- package/dist/applications/service.d.ts +35 -17
- package/dist/applications/service.d.ts.map +1 -1
- package/dist/applications/service.js +144 -35
- package/dist/applications/service.js.map +1 -1
- package/dist/applications/types.d.ts +1 -1
- package/dist/applications/types.d.ts.map +1 -1
- package/dist/applications/validators.d.ts +14 -0
- package/dist/applications/validators.d.ts.map +1 -0
- package/dist/applications/validators.js +14 -0
- package/dist/applications/validators.js.map +1 -0
- package/dist/auth/effective-branding.d.ts +35 -0
- package/dist/auth/effective-branding.d.ts.map +1 -0
- package/dist/auth/effective-branding.js +81 -0
- package/dist/auth/effective-branding.js.map +1 -0
- package/dist/auth/email-service.d.ts +3 -8
- package/dist/auth/email-service.d.ts.map +1 -1
- package/dist/auth/email-service.js +22 -30
- package/dist/auth/email-service.js.map +1 -1
- package/dist/auth/i18n.d.ts +5 -0
- package/dist/auth/i18n.d.ts.map +1 -1
- package/dist/auth/i18n.js +6 -5
- package/dist/auth/i18n.js.map +1 -1
- package/dist/auth/rate-limiter.d.ts +6 -10
- package/dist/auth/rate-limiter.d.ts.map +1 -1
- package/dist/auth/rate-limiter.js +12 -16
- package/dist/auth/rate-limiter.js.map +1 -1
- package/dist/auth/recovery-job-processor.d.ts.map +1 -1
- package/dist/auth/recovery-job-processor.js +1 -1
- package/dist/auth/recovery-job-processor.js.map +1 -1
- package/dist/auth/template-engine.d.ts +3 -1
- package/dist/auth/template-engine.d.ts.map +1 -1
- package/dist/auth/template-engine.js +1 -1
- package/dist/auth/template-engine.js.map +1 -1
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +12 -12
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/error-handler.d.ts +3 -2
- package/dist/cli/error-handler.d.ts.map +1 -1
- package/dist/cli/error-handler.js +9 -2
- package/dist/cli/error-handler.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/clients/index.d.ts +1 -1
- package/dist/clients/index.js +1 -1
- package/dist/clients/repository.d.ts +18 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +36 -0
- package/dist/clients/repository.js.map +1 -1
- package/dist/clients/secret-repository.d.ts +35 -8
- package/dist/clients/secret-repository.d.ts.map +1 -1
- package/dist/clients/secret-repository.js +69 -16
- package/dist/clients/secret-repository.js.map +1 -1
- package/dist/clients/secret-service.d.ts +5 -9
- package/dist/clients/secret-service.d.ts.map +1 -1
- package/dist/clients/secret-service.js +13 -22
- package/dist/clients/secret-service.js.map +1 -1
- package/dist/clients/service.d.ts +10 -13
- package/dist/clients/service.d.ts.map +1 -1
- package/dist/clients/service.js +112 -40
- package/dist/clients/service.js.map +1 -1
- package/dist/clients/types.d.ts +1 -1
- package/dist/clients/types.d.ts.map +1 -1
- package/dist/clients/validators.d.ts +83 -1
- package/dist/clients/validators.d.ts.map +1 -1
- package/dist/clients/validators.js +110 -0
- package/dist/clients/validators.js.map +1 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +23 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/custom-claims/repository.d.ts +14 -9
- package/dist/custom-claims/repository.d.ts.map +1 -1
- package/dist/custom-claims/repository.js +38 -11
- package/dist/custom-claims/repository.js.map +1 -1
- package/dist/custom-claims/service.d.ts +11 -6
- package/dist/custom-claims/service.d.ts.map +1 -1
- package/dist/custom-claims/service.js +43 -20
- package/dist/custom-claims/service.js.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/admin-permissions.d.ts +12 -7
- package/dist/lib/admin-permissions.d.ts.map +1 -1
- package/dist/lib/admin-permissions.js +26 -16
- package/dist/lib/admin-permissions.js.map +1 -1
- package/dist/lib/audit-log.d.ts +2 -2
- package/dist/lib/audit-log.d.ts.map +1 -1
- package/dist/lib/audit-log.js +1 -1
- package/dist/lib/audit-log.js.map +1 -1
- package/dist/lib/authority-revocation.d.ts +18 -0
- package/dist/lib/authority-revocation.d.ts.map +1 -0
- package/dist/lib/authority-revocation.js +37 -0
- package/dist/lib/authority-revocation.js.map +1 -0
- package/dist/lib/branding-assets.d.ts +35 -5
- package/dist/lib/branding-assets.d.ts.map +1 -1
- package/dist/lib/branding-assets.js +33 -26
- package/dist/lib/branding-assets.js.map +1 -1
- package/dist/lib/bulk-operations.d.ts +1 -1
- package/dist/lib/bulk-operations.d.ts.map +1 -1
- package/dist/lib/bulk-operations.js +1 -13
- package/dist/lib/bulk-operations.js.map +1 -1
- package/dist/lib/cursor.d.ts +2 -0
- package/dist/lib/cursor.d.ts.map +1 -1
- package/dist/lib/cursor.js +2 -7
- package/dist/lib/cursor.js.map +1 -1
- package/dist/lib/database.d.ts.map +1 -1
- package/dist/lib/database.js +5 -0
- package/dist/lib/database.js.map +1 -1
- package/dist/lib/deletion-cleanup.d.ts +43 -0
- package/dist/lib/deletion-cleanup.d.ts.map +1 -0
- package/dist/lib/deletion-cleanup.js +207 -0
- package/dist/lib/deletion-cleanup.js.map +1 -0
- package/dist/lib/image-validator.d.ts +3 -1
- package/dist/lib/image-validator.d.ts.map +1 -1
- package/dist/lib/image-validator.js +32 -19
- package/dist/lib/image-validator.js.map +1 -1
- package/dist/lib/log-format.d.ts +20 -0
- package/dist/lib/log-format.d.ts.map +1 -0
- package/dist/lib/log-format.js +22 -0
- package/dist/lib/log-format.js.map +1 -0
- package/dist/lib/logger.d.ts +3 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +21 -4
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/redis.d.ts.map +1 -1
- package/dist/lib/redis.js +3 -0
- package/dist/lib/redis.js.map +1 -1
- package/dist/lib/session-tracking.d.ts +73 -11
- package/dist/lib/session-tracking.d.ts.map +1 -1
- package/dist/lib/session-tracking.js +76 -32
- package/dist/lib/session-tracking.js.map +1 -1
- package/dist/lib/signing-key-crypto.d.ts.map +1 -1
- package/dist/lib/signing-key-crypto.js +4 -5
- package/dist/lib/signing-key-crypto.js.map +1 -1
- package/dist/lib/signing-keys.d.ts +3 -4
- package/dist/lib/signing-keys.d.ts.map +1 -1
- package/dist/lib/signing-keys.js +66 -41
- package/dist/lib/signing-keys.js.map +1 -1
- package/dist/lib/super-admin-protection.d.ts +5 -5
- package/dist/lib/super-admin-protection.d.ts.map +1 -1
- package/dist/lib/super-admin-protection.js +6 -9
- package/dist/lib/super-admin-protection.js.map +1 -1
- package/dist/lib/system-config-catalog.d.ts +268 -0
- package/dist/lib/system-config-catalog.d.ts.map +1 -0
- package/dist/lib/system-config-catalog.js +90 -0
- package/dist/lib/system-config-catalog.js.map +1 -0
- package/dist/lib/system-config.d.ts +30 -33
- package/dist/lib/system-config.d.ts.map +1 -1
- package/dist/lib/system-config.js +78 -93
- package/dist/lib/system-config.js.map +1 -1
- package/dist/lib/with-timeout.d.ts +32 -0
- package/dist/lib/with-timeout.d.ts.map +1 -0
- package/dist/lib/with-timeout.js +45 -0
- package/dist/lib/with-timeout.js.map +1 -0
- package/dist/middleware/admin-auth.d.ts +6 -5
- package/dist/middleware/admin-auth.d.ts.map +1 -1
- package/dist/middleware/admin-auth.js +30 -20
- package/dist/middleware/admin-auth.js.map +1 -1
- package/dist/middleware/admin-cors.d.ts +3 -3
- package/dist/middleware/admin-cors.js +3 -3
- package/dist/middleware/admin-mutation-audit.d.ts +3 -2
- package/dist/middleware/admin-mutation-audit.d.ts.map +1 -1
- package/dist/middleware/admin-mutation-audit.js +12 -5
- package/dist/middleware/admin-mutation-audit.js.map +1 -1
- package/dist/middleware/admin-rate-limiter.d.ts +7 -8
- package/dist/middleware/admin-rate-limiter.d.ts.map +1 -1
- package/dist/middleware/admin-rate-limiter.js +7 -8
- package/dist/middleware/admin-rate-limiter.js.map +1 -1
- package/dist/middleware/client-secret-hash.d.ts +10 -29
- package/dist/middleware/client-secret-hash.d.ts.map +1 -1
- package/dist/middleware/client-secret-hash.js +161 -59
- package/dist/middleware/client-secret-hash.js.map +1 -1
- package/dist/middleware/health.d.ts +17 -0
- package/dist/middleware/health.d.ts.map +1 -1
- package/dist/middleware/health.js +25 -21
- package/dist/middleware/health.js.map +1 -1
- package/dist/middleware/ready.d.ts.map +1 -1
- package/dist/middleware/ready.js +1 -12
- package/dist/middleware/ready.js.map +1 -1
- package/dist/middleware/require-existing-organization.d.ts +18 -0
- package/dist/middleware/require-existing-organization.d.ts.map +1 -0
- package/dist/middleware/require-existing-organization.js +38 -0
- package/dist/middleware/require-existing-organization.js.map +1 -0
- package/dist/middleware/require-permission.d.ts.map +1 -1
- package/dist/middleware/require-permission.js +35 -1
- package/dist/middleware/require-permission.js.map +1 -1
- package/dist/middleware/require-user-organization.d.ts.map +1 -1
- package/dist/middleware/require-user-organization.js +4 -2
- package/dist/middleware/require-user-organization.js.map +1 -1
- package/dist/middleware/security-headers.d.ts +18 -0
- package/dist/middleware/security-headers.d.ts.map +1 -1
- package/dist/middleware/security-headers.js +32 -1
- package/dist/middleware/security-headers.js.map +1 -1
- package/dist/middleware/tenant-resolver.d.ts +1 -2
- package/dist/middleware/tenant-resolver.d.ts.map +1 -1
- package/dist/middleware/tenant-resolver.js +1 -5
- package/dist/middleware/tenant-resolver.js.map +1 -1
- package/dist/middleware/token-rate-limiter.d.ts +37 -16
- package/dist/middleware/token-rate-limiter.d.ts.map +1 -1
- package/dist/middleware/token-rate-limiter.js +126 -54
- package/dist/middleware/token-rate-limiter.js.map +1 -1
- package/dist/oidc/account-finder.d.ts +5 -5
- package/dist/oidc/account-finder.d.ts.map +1 -1
- package/dist/oidc/account-finder.js +31 -23
- package/dist/oidc/account-finder.js.map +1 -1
- package/dist/oidc/adapter-factory.d.ts.map +1 -1
- package/dist/oidc/adapter-factory.js +83 -3
- package/dist/oidc/adapter-factory.js.map +1 -1
- package/dist/oidc/configuration.d.ts +3 -8
- package/dist/oidc/configuration.d.ts.map +1 -1
- package/dist/oidc/configuration.js +64 -50
- package/dist/oidc/configuration.js.map +1 -1
- package/dist/oidc/provider.d.ts.map +1 -1
- package/dist/oidc/provider.js +7 -0
- package/dist/oidc/provider.js.map +1 -1
- package/dist/oidc/redis-adapter.d.ts +2 -3
- package/dist/oidc/redis-adapter.d.ts.map +1 -1
- package/dist/oidc/redis-adapter.js +54 -46
- package/dist/oidc/redis-adapter.js.map +1 -1
- package/dist/organizations/branding-url.d.ts +17 -0
- package/dist/organizations/branding-url.d.ts.map +1 -0
- package/dist/organizations/branding-url.js +38 -0
- package/dist/organizations/branding-url.js.map +1 -0
- package/dist/organizations/index.d.ts +2 -2
- package/dist/organizations/index.d.ts.map +1 -1
- package/dist/organizations/index.js +1 -1
- package/dist/organizations/index.js.map +1 -1
- package/dist/organizations/repository.d.ts +22 -32
- package/dist/organizations/repository.d.ts.map +1 -1
- package/dist/organizations/repository.js +64 -45
- package/dist/organizations/repository.js.map +1 -1
- package/dist/organizations/service.d.ts +14 -46
- package/dist/organizations/service.d.ts.map +1 -1
- package/dist/organizations/service.js +60 -112
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +1 -15
- package/dist/organizations/types.d.ts.map +1 -1
- package/dist/organizations/validators.d.ts +41 -0
- package/dist/organizations/validators.d.ts.map +1 -0
- package/dist/organizations/validators.js +48 -0
- package/dist/organizations/validators.js.map +1 -0
- package/dist/portability/apply.d.ts +15 -0
- package/dist/portability/apply.d.ts.map +1 -0
- package/dist/portability/apply.js +274 -0
- package/dist/portability/apply.js.map +1 -0
- package/dist/portability/authorization.d.ts +30 -0
- package/dist/portability/authorization.d.ts.map +1 -0
- package/dist/portability/authorization.js +130 -0
- package/dist/portability/authorization.js.map +1 -0
- package/dist/portability/cleanup.d.ts +29 -0
- package/dist/portability/cleanup.d.ts.map +1 -0
- package/dist/portability/cleanup.js +167 -0
- package/dist/portability/cleanup.js.map +1 -0
- package/dist/portability/export.d.ts +18 -0
- package/dist/portability/export.d.ts.map +1 -0
- package/dist/portability/export.js +125 -0
- package/dist/portability/export.js.map +1 -0
- package/dist/portability/import-repository.d.ts +204 -0
- package/dist/portability/import-repository.d.ts.map +1 -0
- package/dist/portability/import-repository.js +347 -0
- package/dist/portability/import-repository.js.map +1 -0
- package/dist/portability/import-user-client-writers.d.ts +40 -0
- package/dist/portability/import-user-client-writers.d.ts.map +1 -0
- package/dist/portability/import-user-client-writers.js +168 -0
- package/dist/portability/import-user-client-writers.js.map +1 -0
- package/dist/portability/index.d.ts +8 -0
- package/dist/portability/index.d.ts.map +1 -0
- package/dist/portability/index.js +8 -0
- package/dist/portability/index.js.map +1 -0
- package/dist/portability/plan-support.d.ts +137 -0
- package/dist/portability/plan-support.d.ts.map +1 -0
- package/dist/portability/plan-support.js +336 -0
- package/dist/portability/plan-support.js.map +1 -0
- package/dist/portability/plan.d.ts +34 -0
- package/dist/portability/plan.d.ts.map +1 -0
- package/dist/portability/plan.js +450 -0
- package/dist/portability/plan.js.map +1 -0
- package/dist/portability/repository.d.ts +95 -0
- package/dist/portability/repository.d.ts.map +1 -0
- package/dist/portability/repository.js +388 -0
- package/dist/portability/repository.js.map +1 -0
- package/dist/portability/schema.d.ts +589 -0
- package/dist/portability/schema.d.ts.map +1 -0
- package/dist/portability/schema.js +458 -0
- package/dist/portability/schema.js.map +1 -0
- package/dist/portability/types.d.ts +381 -0
- package/dist/portability/types.d.ts.map +1 -0
- package/dist/portability/types.js +19 -0
- package/dist/portability/types.js.map +1 -0
- package/dist/rbac/errors.d.ts +4 -0
- package/dist/rbac/errors.d.ts.map +1 -1
- package/dist/rbac/errors.js +7 -0
- package/dist/rbac/errors.js.map +1 -1
- package/dist/rbac/index.d.ts +3 -3
- package/dist/rbac/index.d.ts.map +1 -1
- package/dist/rbac/index.js +3 -3
- package/dist/rbac/index.js.map +1 -1
- package/dist/rbac/mapping-repository.d.ts +84 -9
- package/dist/rbac/mapping-repository.d.ts.map +1 -1
- package/dist/rbac/mapping-repository.js +222 -55
- package/dist/rbac/mapping-repository.js.map +1 -1
- package/dist/rbac/permission-repository.d.ts +36 -19
- package/dist/rbac/permission-repository.d.ts.map +1 -1
- package/dist/rbac/permission-repository.js +93 -35
- package/dist/rbac/permission-repository.js.map +1 -1
- package/dist/rbac/permission-service.d.ts +18 -19
- package/dist/rbac/permission-service.d.ts.map +1 -1
- package/dist/rbac/permission-service.js +100 -57
- package/dist/rbac/permission-service.js.map +1 -1
- package/dist/rbac/role-repository.d.ts +29 -24
- package/dist/rbac/role-repository.d.ts.map +1 -1
- package/dist/rbac/role-repository.js +66 -43
- package/dist/rbac/role-repository.js.map +1 -1
- package/dist/rbac/role-service.d.ts +35 -32
- package/dist/rbac/role-service.d.ts.map +1 -1
- package/dist/rbac/role-service.js +210 -96
- package/dist/rbac/role-service.js.map +1 -1
- package/dist/rbac/slugs.d.ts +16 -27
- package/dist/rbac/slugs.d.ts.map +1 -1
- package/dist/rbac/slugs.js +36 -59
- package/dist/rbac/slugs.js.map +1 -1
- package/dist/rbac/types.d.ts +2 -4
- package/dist/rbac/types.d.ts.map +1 -1
- package/dist/rbac/types.js.map +1 -1
- package/dist/rbac/user-role-service.d.ts +23 -24
- package/dist/rbac/user-role-service.d.ts.map +1 -1
- package/dist/rbac/user-role-service.js +117 -61
- package/dist/rbac/user-role-service.js.map +1 -1
- package/dist/routes/applications.d.ts +4 -2
- package/dist/routes/applications.d.ts.map +1 -1
- package/dist/routes/applications.js +57 -19
- package/dist/routes/applications.js.map +1 -1
- package/dist/routes/audit.js +1 -1
- package/dist/routes/audit.js.map +1 -1
- package/dist/routes/branding.d.ts +3 -3
- package/dist/routes/branding.d.ts.map +1 -1
- package/dist/routes/branding.js +44 -16
- package/dist/routes/branding.js.map +1 -1
- package/dist/routes/bulk.d.ts +0 -5
- package/dist/routes/bulk.d.ts.map +1 -1
- package/dist/routes/bulk.js +3 -5
- package/dist/routes/bulk.js.map +1 -1
- package/dist/routes/clients.d.ts +4 -4
- package/dist/routes/clients.d.ts.map +1 -1
- package/dist/routes/clients.js +111 -52
- package/dist/routes/clients.js.map +1 -1
- package/dist/routes/config.d.ts +17 -12
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +165 -64
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/custom-claims.d.ts.map +1 -1
- package/dist/routes/custom-claims.js +8 -2
- package/dist/routes/custom-claims.js.map +1 -1
- package/dist/routes/exports.d.ts +2 -1
- package/dist/routes/exports.d.ts.map +1 -1
- package/dist/routes/exports.js +57 -1
- package/dist/routes/exports.js.map +1 -1
- package/dist/routes/imports.d.ts +2 -2
- package/dist/routes/imports.d.ts.map +1 -1
- package/dist/routes/imports.js +95 -40
- package/dist/routes/imports.js.map +1 -1
- package/dist/routes/interactions.d.ts.map +1 -1
- package/dist/routes/interactions.js +16 -34
- package/dist/routes/interactions.js.map +1 -1
- package/dist/routes/invitation.d.ts.map +1 -1
- package/dist/routes/invitation.js +10 -23
- package/dist/routes/invitation.js.map +1 -1
- package/dist/routes/keys.d.ts.map +1 -1
- package/dist/routes/keys.js +26 -13
- package/dist/routes/keys.js.map +1 -1
- package/dist/routes/magic-link.d.ts.map +1 -1
- package/dist/routes/magic-link.js +5 -17
- package/dist/routes/magic-link.js.map +1 -1
- package/dist/routes/organizations.d.ts +1 -2
- package/dist/routes/organizations.d.ts.map +1 -1
- package/dist/routes/organizations.js +43 -104
- package/dist/routes/organizations.js.map +1 -1
- package/dist/routes/password-reset.d.ts.map +1 -1
- package/dist/routes/password-reset.js +13 -35
- package/dist/routes/password-reset.js.map +1 -1
- package/dist/routes/permissions.d.ts +1 -1
- package/dist/routes/permissions.d.ts.map +1 -1
- package/dist/routes/permissions.js +58 -17
- package/dist/routes/permissions.js.map +1 -1
- package/dist/routes/public-branding.d.ts +16 -0
- package/dist/routes/public-branding.d.ts.map +1 -0
- package/dist/routes/public-branding.js +52 -0
- package/dist/routes/public-branding.js.map +1 -0
- package/dist/routes/roles.d.ts +1 -1
- package/dist/routes/roles.d.ts.map +1 -1
- package/dist/routes/roles.js +63 -21
- package/dist/routes/roles.js.map +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +23 -12
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/two-factor.d.ts.map +1 -1
- package/dist/routes/two-factor.js +91 -38
- package/dist/routes/two-factor.js.map +1 -1
- package/dist/routes/user-roles.d.ts.map +1 -1
- package/dist/routes/user-roles.js +56 -9
- package/dist/routes/user-roles.js.map +1 -1
- package/dist/routes/users.d.ts +4 -8
- package/dist/routes/users.d.ts.map +1 -1
- package/dist/routes/users.js +108 -265
- package/dist/routes/users.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +53 -37
- package/dist/server.js.map +1 -1
- package/dist/two-factor/errors.d.ts +9 -0
- package/dist/two-factor/errors.d.ts.map +1 -1
- package/dist/two-factor/errors.js +12 -0
- package/dist/two-factor/errors.js.map +1 -1
- package/dist/two-factor/index.d.ts +5 -4
- package/dist/two-factor/index.d.ts.map +1 -1
- package/dist/two-factor/index.js +4 -4
- package/dist/two-factor/index.js.map +1 -1
- package/dist/two-factor/repository.d.ts +17 -6
- package/dist/two-factor/repository.d.ts.map +1 -1
- package/dist/two-factor/repository.js +37 -9
- package/dist/two-factor/repository.js.map +1 -1
- package/dist/two-factor/service.d.ts.map +1 -1
- package/dist/two-factor/service.js +26 -19
- package/dist/two-factor/service.js.map +1 -1
- package/dist/two-factor/totp.d.ts +13 -2
- package/dist/two-factor/totp.d.ts.map +1 -1
- package/dist/two-factor/totp.js +20 -7
- package/dist/two-factor/totp.js.map +1 -1
- package/dist/two-factor/types.d.ts +3 -0
- package/dist/two-factor/types.d.ts.map +1 -1
- package/dist/two-factor/types.js +5 -0
- package/dist/two-factor/types.js.map +1 -1
- package/dist/users/gdpr.d.ts +2 -40
- package/dist/users/gdpr.d.ts.map +1 -1
- package/dist/users/gdpr.js +3 -110
- package/dist/users/gdpr.js.map +1 -1
- package/dist/users/index.d.ts +5 -4
- package/dist/users/index.d.ts.map +1 -1
- package/dist/users/index.js +5 -4
- package/dist/users/index.js.map +1 -1
- package/dist/users/repository.d.ts +49 -3
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +169 -18
- package/dist/users/repository.js.map +1 -1
- package/dist/users/service.d.ts +19 -51
- package/dist/users/service.d.ts.map +1 -1
- package/dist/users/service.js +72 -122
- package/dist/users/service.js.map +1 -1
- package/dist/users/types.d.ts +4 -5
- package/dist/users/types.d.ts.map +1 -1
- package/dist/users/types.js.map +1 -1
- package/dist/users/validators.d.ts +28 -0
- package/dist/users/validators.d.ts.map +1 -0
- package/dist/users/validators.js +25 -0
- package/dist/users/validators.js.map +1 -0
- package/locales/default/en/errors.json +2 -1
- package/migrations/024_application_client_correction.sql +39 -0
- package/migrations/025_record_deletion_lifecycle.sql +26 -0
- package/migrations/026_simplify_user_lifecycle.sql +33 -0
- package/migrations/027_branding_asset_size_limits.sql +19 -0
- package/migrations/028_totp_replay_protection.sql +17 -0
- package/migrations/029_public_session_identifiers.sql +16 -0
- package/migrations/030_global_configuration_catalog.sql +39 -0
- package/migrations/031_monotonic_updated_at.sql +28 -0
- package/package.json +2 -2
- package/dist/lib/data-import-plan.d.ts +0 -50
- package/dist/lib/data-import-plan.d.ts.map +0 -1
- package/dist/lib/data-import-plan.js +0 -235
- package/dist/lib/data-import-plan.js.map +0 -1
- package/dist/lib/data-import.d.ts +0 -276
- package/dist/lib/data-import.d.ts.map +0 -1
- package/dist/lib/data-import.js +0 -1694
- package/dist/lib/data-import.js.map +0 -1
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Validates Bearer access tokens against Porta's own OIDC provider
|
|
5
5
|
* using opaque token lookup (provider.AccessToken.find()). Verifies
|
|
6
|
-
* the user belongs to the super-admin organization and has
|
|
7
|
-
*
|
|
8
|
-
* and audit logging.
|
|
6
|
+
* the user belongs to the super-admin organization and has a recognized
|
|
7
|
+
* built-in role owned by the canonical Porta Admin application. Sets
|
|
8
|
+
* ctx.state.adminUser for downstream handlers and audit logging.
|
|
9
9
|
*
|
|
10
10
|
* This middleware replaces the old requireSuperAdmin() that checked
|
|
11
11
|
* ctx.state.organization.isSuperAdmin (which required tenant-resolver
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* 3. Resolve super-admin organization
|
|
18
18
|
* 4. Look up user — must be active
|
|
19
19
|
* 5. Verify user belongs to the super-admin organization
|
|
20
|
-
* 6. Verify user has the
|
|
20
|
+
* 6. Verify the user has a recognized role from the canonical Admin application
|
|
21
21
|
* 7. Set ctx.state.adminUser and proceed
|
|
22
22
|
*
|
|
23
23
|
* Response codes:
|
|
@@ -27,9 +27,10 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { findUserForOidc } from '../users/service.js';
|
|
29
29
|
import { findSuperAdminOrganization } from '../organizations/repository.js';
|
|
30
|
-
import {
|
|
30
|
+
import { getUserRolesForAuthority } from '../rbac/user-role-service.js';
|
|
31
|
+
import { getApplicationBySlug } from '../applications/service.js';
|
|
31
32
|
import { logger } from '../lib/logger.js';
|
|
32
|
-
import { resolvePermissionsFromRoles } from '../lib/admin-permissions.js';
|
|
33
|
+
import { getPermissionsForAdminRole, resolvePermissionsFromRoles, } from '../lib/admin-permissions.js';
|
|
33
34
|
import { recordSecurityDecision, recordSecurityReference } from '../security/decision-context.js';
|
|
34
35
|
let _provider = null;
|
|
35
36
|
/**
|
|
@@ -69,17 +70,15 @@ export function requireAdminOrganizationMembership(ctx, userOrganizationId, admi
|
|
|
69
70
|
// ---------------------------------------------------------------------------
|
|
70
71
|
// Admin auth middleware factory
|
|
71
72
|
// ---------------------------------------------------------------------------
|
|
72
|
-
/**
|
|
73
|
-
|
|
74
|
-
* Legacy 'porta-admin' role is treated as super-admin for backward compatibility.
|
|
75
|
-
*/
|
|
76
|
-
const ADMIN_ROLE_PREFIX = 'porta-';
|
|
73
|
+
/** Immutable slug of the application that owns Porta's control-plane roles. */
|
|
74
|
+
const ADMIN_APPLICATION_SLUG = 'porta-admin';
|
|
77
75
|
/**
|
|
78
76
|
* Create middleware that requires admin authentication and authorization.
|
|
79
77
|
*
|
|
80
78
|
* Validates the Bearer access token in the Authorization header by looking
|
|
81
79
|
* it up via the OIDC provider's opaque token store, then verifies the user
|
|
82
|
-
* is an active member of the super-admin organization with
|
|
80
|
+
* is an active member of the super-admin organization with a recognized role
|
|
81
|
+
* owned by the canonical Porta Admin application.
|
|
83
82
|
*
|
|
84
83
|
* On success, sets ctx.state.adminUser with the authenticated identity.
|
|
85
84
|
* On failure, responds with 401 (unauthenticated) or 403 (unauthorized).
|
|
@@ -201,14 +200,27 @@ export function requireAdminAuth() {
|
|
|
201
200
|
if (!requireAdminOrganizationMembership(ctx, user.organizationId, superAdminOrg.id))
|
|
202
201
|
return;
|
|
203
202
|
// -----------------------------------------------------------------
|
|
204
|
-
// Step 6: Verify user has
|
|
203
|
+
// Step 6: Verify the user has a recognized role from the canonical Admin application.
|
|
205
204
|
// -----------------------------------------------------------------
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
|
|
206
|
+
if (!adminApplication) {
|
|
207
|
+
logger.error('Admin auth: canonical application not found — run porta init');
|
|
208
|
+
recordSecurityDecision(ctx, {
|
|
209
|
+
decisionPoint: 'handler',
|
|
210
|
+
reasonCode: 'handler-failed',
|
|
211
|
+
outcome: 'error',
|
|
212
|
+
});
|
|
213
|
+
ctx.status = 500;
|
|
214
|
+
ctx.body = { error: 'Server configuration error' };
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const userRoles = await getUserRolesForAuthority(userId);
|
|
209
218
|
const adminRoleSlugs = userRoles
|
|
210
|
-
.
|
|
211
|
-
.
|
|
219
|
+
.filter((role) => role.applicationId === adminApplication.id &&
|
|
220
|
+
getPermissionsForAdminRole(role.slug).length > 0)
|
|
221
|
+
.map((role) => role.slug);
|
|
222
|
+
recordSecurityReference(ctx, 'actor', userId);
|
|
223
|
+
recordSecurityReference(ctx, 'tenant', user.organizationId);
|
|
212
224
|
if (adminRoleSlugs.length === 0) {
|
|
213
225
|
recordSecurityDecision(ctx, {
|
|
214
226
|
decisionPoint: 'membership',
|
|
@@ -233,8 +245,6 @@ export function requireAdminAuth() {
|
|
|
233
245
|
roles: adminRoleSlugs,
|
|
234
246
|
permissions,
|
|
235
247
|
};
|
|
236
|
-
recordSecurityReference(ctx, 'actor', userId);
|
|
237
|
-
recordSecurityReference(ctx, 'tenant', user.organizationId);
|
|
238
248
|
await next();
|
|
239
249
|
};
|
|
240
250
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-auth.js","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"admin-auth.js","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* Non-browser clients (CLI, same-origin requests) never send an `Origin`
|
|
13
13
|
* header, so they pass through this middleware untouched.
|
|
14
14
|
*
|
|
15
|
-
* Placement: mount
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
15
|
+
* Placement: mount before Admin rate limiting, body parsing, and authentication.
|
|
16
|
+
* Preflight `OPTIONS` requests carry no `Authorization` header, so CORS must
|
|
17
|
+
* respond before authentication runs.
|
|
18
18
|
*
|
|
19
19
|
* @module middleware/admin-cors
|
|
20
20
|
*/
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* Non-browser clients (CLI, same-origin requests) never send an `Origin`
|
|
13
13
|
* header, so they pass through this middleware untouched.
|
|
14
14
|
*
|
|
15
|
-
* Placement: mount
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
15
|
+
* Placement: mount before Admin rate limiting, body parsing, and authentication.
|
|
16
|
+
* Preflight `OPTIONS` requests carry no `Authorization` header, so CORS must
|
|
17
|
+
* respond before authentication runs.
|
|
18
18
|
*
|
|
19
19
|
* @module middleware/admin-cors
|
|
20
20
|
*/
|
|
@@ -2,8 +2,9 @@ import type { Middleware } from 'koa';
|
|
|
2
2
|
/**
|
|
3
3
|
* Atomically bind successful administrative mutations to one durable audit row.
|
|
4
4
|
*
|
|
5
|
-
* Bulk and
|
|
6
|
-
* state-changing admin request shares one request-local PostgreSQL
|
|
5
|
+
* Bulk operations, portability and configuration updates own specialized transaction semantics and are
|
|
6
|
+
* excluded here. Every other state-changing admin request shares one request-local PostgreSQL
|
|
7
|
+
* client across repository calls.
|
|
7
8
|
*/
|
|
8
9
|
export declare function adminMutationAudit(): Middleware;
|
|
9
10
|
//# sourceMappingURL=admin-mutation-audit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-mutation-audit.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"admin-mutation-audit.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAgCtC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CA+C/C"}
|
|
@@ -2,7 +2,12 @@ import { writeAuditLogInTransaction } from '../lib/audit-log.js';
|
|
|
2
2
|
import { getDatabaseTransactionClient, runDatabaseTransaction } from '../lib/database.js';
|
|
3
3
|
import { normalizedRouteTemplate, recordSecurityDecision } from '../security/decision-context.js';
|
|
4
4
|
const MUTATION_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
|
|
5
|
-
const SELF_MANAGED_MUTATION_PREFIXES = [
|
|
5
|
+
const SELF_MANAGED_MUTATION_PREFIXES = [
|
|
6
|
+
'/api/admin/bulk',
|
|
7
|
+
'/api/admin/import',
|
|
8
|
+
'/api/admin/export/manifest',
|
|
9
|
+
'/api/admin/config',
|
|
10
|
+
];
|
|
6
11
|
/** Internal signal used to roll back a handled non-success response without replacing its body. */
|
|
7
12
|
class HandledMutationRejection extends Error {
|
|
8
13
|
}
|
|
@@ -22,8 +27,9 @@ function ownsAdministrativeMutation(method, path) {
|
|
|
22
27
|
/**
|
|
23
28
|
* Atomically bind successful administrative mutations to one durable audit row.
|
|
24
29
|
*
|
|
25
|
-
* Bulk and
|
|
26
|
-
* state-changing admin request shares one request-local PostgreSQL
|
|
30
|
+
* Bulk operations, portability and configuration updates own specialized transaction semantics and are
|
|
31
|
+
* excluded here. Every other state-changing admin request shares one request-local PostgreSQL
|
|
32
|
+
* client across repository calls.
|
|
27
33
|
*/
|
|
28
34
|
export function adminMutationAudit() {
|
|
29
35
|
return async (ctx, next) => {
|
|
@@ -42,9 +48,10 @@ export function adminMutationAudit() {
|
|
|
42
48
|
const actor = ctx.state.adminUser;
|
|
43
49
|
if (!actor)
|
|
44
50
|
throw new Error('Administrative mutation actor is unavailable');
|
|
51
|
+
const liveActor = await client.query('SELECT id, organization_id FROM users WHERE id = $1', [actor.id]);
|
|
45
52
|
await writeAuditLogInTransaction(client, {
|
|
46
|
-
organizationId:
|
|
47
|
-
actorId:
|
|
53
|
+
organizationId: liveActor.rows[0]?.organization_id,
|
|
54
|
+
actorId: liveActor.rows[0]?.id,
|
|
48
55
|
eventType: 'admin.mutation.committed',
|
|
49
56
|
eventCategory: 'admin',
|
|
50
57
|
metadata: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-mutation-audit.js","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAElG,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACrE,MAAM,8BAA8B,GAAG,
|
|
1
|
+
{"version":3,"file":"admin-mutation-audit.js","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
* `/api/admin/*`) against brute-force attacks and automated abuse.
|
|
6
6
|
* GET requests are read-only and pass through without rate limiting.
|
|
7
7
|
*
|
|
8
|
-
* Key format: `ratelimit:admin:{ip}
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* attackers from the same IP are blocked regardless of identity.
|
|
8
|
+
* Key format: `ratelimit:admin:{ip}`. The limiter intentionally runs before
|
|
9
|
+
* body parsing and authentication so rejected large requests consume minimal
|
|
10
|
+
* resources. A per-IP counter covers both unauthenticated abuse and legitimate
|
|
11
|
+
* administrators without requiring an authenticated user identifier.
|
|
13
12
|
*
|
|
14
13
|
* Limit: 60 requests / 60 seconds (sliding window).
|
|
15
14
|
*
|
|
@@ -17,9 +16,9 @@
|
|
|
17
16
|
* provides Redis INCR+EXPIRE sliding window and graceful degradation
|
|
18
17
|
* on Redis failure (allows request + logs warning).
|
|
19
18
|
*
|
|
20
|
-
* Placement: mount
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* Placement: mount after Admin CORS and before body parsing, authentication,
|
|
20
|
+
* and Admin route routers. The path + method check ensures only write requests
|
|
21
|
+
* to `/api/admin/*` are counted.
|
|
23
22
|
*
|
|
24
23
|
* @module middleware/admin-rate-limiter
|
|
25
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"admin-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAO/D,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAA8C,CAAC;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAG9B,CAAC;AAMF;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAyC7C"}
|
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
* `/api/admin/*`) against brute-force attacks and automated abuse.
|
|
6
6
|
* GET requests are read-only and pass through without rate limiting.
|
|
7
7
|
*
|
|
8
|
-
* Key format: `ratelimit:admin:{ip}
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* attackers from the same IP are blocked regardless of identity.
|
|
8
|
+
* Key format: `ratelimit:admin:{ip}`. The limiter intentionally runs before
|
|
9
|
+
* body parsing and authentication so rejected large requests consume minimal
|
|
10
|
+
* resources. A per-IP counter covers both unauthenticated abuse and legitimate
|
|
11
|
+
* administrators without requiring an authenticated user identifier.
|
|
13
12
|
*
|
|
14
13
|
* Limit: 60 requests / 60 seconds (sliding window).
|
|
15
14
|
*
|
|
@@ -17,9 +16,9 @@
|
|
|
17
16
|
* provides Redis INCR+EXPIRE sliding window and graceful degradation
|
|
18
17
|
* on Redis failure (allows request + logs warning).
|
|
19
18
|
*
|
|
20
|
-
* Placement: mount
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* Placement: mount after Admin CORS and before body parsing, authentication,
|
|
20
|
+
* and Admin route routers. The path + method check ensures only write requests
|
|
21
|
+
* to `/api/admin/*` are counted.
|
|
23
22
|
*
|
|
24
23
|
* @module middleware/admin-rate-limiter
|
|
25
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-rate-limiter.js","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"admin-rate-limiter.js","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,8EAA8E;AAC9E,6DAA6D;AAC7D,8EAA8E;AAE9E,wCAAwC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,GAAG,EAAE,EAAE;IACP,aAAa,EAAE,EAAE;CAClB,CAAC;AAEF,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,KAAK,UAAU,0BAA0B,CAAC,GAAG,EAAE,IAAI;QACxD,8DAA8D;QAC9D,mEAAmE;QACnE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpF,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,kEAAkE;QAClE,8DAA8D;QAC9D,sDAAsD;QACtD,MAAM,GAAG,GAAG,mBAAmB,GAAG,CAAC,EAAE,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAE3D,+DAA+D;QAC/D,iDAAiD;QACjD,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CACT;gBACE,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,EACD,+BAA+B,CAChC,CAAC;YAEF,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,GAAG;gBACT,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,wDAAwD;gBACjE,WAAW,EAAE,MAAM,CAAC,UAAU;aAC/B,CAAC;YACF,OAAO;QACT,CAAC;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,34 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SHA-256 client secret pre-hashing middleware.
|
|
3
|
-
*
|
|
4
|
-
* Transforms client_secret values in incoming requests by replacing
|
|
5
|
-
* the plaintext with its SHA-256 hash BEFORE oidc-provider processes them.
|
|
6
|
-
*
|
|
7
|
-
* Supports:
|
|
8
|
-
* - client_secret_basic: Authorization: Basic base64(client_id:secret)
|
|
9
|
-
* - client_secret_post: client_secret in POST body
|
|
10
|
-
*
|
|
11
|
-
* This allows oidc-provider's built-in string comparison to work
|
|
12
|
-
* with our SHA-256-hashed secret storage — no monkey-patching needed.
|
|
13
|
-
*
|
|
14
|
-
* How it works:
|
|
15
|
-
* 1. At secret generation: SHA-256(secret) is stored in the DB
|
|
16
|
-
* 2. At request time: This middleware hashes the presented secret
|
|
17
|
-
* 3. In the adapter: findForOidc() returns SHA-256 hash as client_secret
|
|
18
|
-
* 4. oidc-provider compares: SHA-256(presented) === SHA-256(stored) → ✅ MATCH
|
|
19
|
-
*
|
|
20
|
-
* Security: SHA-256 is appropriate for machine-generated, high-entropy
|
|
21
|
-
* client secrets (48 bytes / 384 bits of randomness).
|
|
22
|
-
*/
|
|
1
|
+
/** Confidential-client active-secret bridge for oidc-provider. */
|
|
23
2
|
import type { Middleware } from 'koa';
|
|
3
|
+
/** Optional controls for the active-secret bridge. */
|
|
4
|
+
export interface ClientSecretBridgeOptions {
|
|
5
|
+
/** Credential-free test hook awaited after validation and immediately before provider handoff. */
|
|
6
|
+
afterCredentialValidation?: () => Promise<void>;
|
|
7
|
+
}
|
|
24
8
|
/**
|
|
25
|
-
* Create
|
|
26
|
-
*
|
|
27
|
-
* Must be mounted BEFORE oidc-provider's callback handler on the
|
|
28
|
-
* OIDC router. Transparently transforms secrets so oidc-provider
|
|
29
|
-
* can compare them against stored SHA-256 hashes.
|
|
9
|
+
* Create the bounded active-secret bridge mounted immediately before oidc-provider.
|
|
30
10
|
*
|
|
31
|
-
* @
|
|
11
|
+
* @param options - Optional credential-free validation/handoff test hook
|
|
12
|
+
* @returns Koa middleware
|
|
32
13
|
*/
|
|
33
|
-
export declare function clientSecretHash(): Middleware;
|
|
14
|
+
export declare function clientSecretHash(options?: ClientSecretBridgeOptions): Middleware;
|
|
34
15
|
//# sourceMappingURL=client-secret-hash.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-secret-hash.d.ts","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client-secret-hash.d.ts","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAiBtC,sDAAsD;AACtD,MAAM,WAAW,yBAAyB;IACxC,kGAAkG;IAClG,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AA6HD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,yBAA8B,GAAG,UAAU,CAoEpF"}
|
|
@@ -1,74 +1,176 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
/** Confidential-client active-secret bridge for oidc-provider. */
|
|
2
|
+
import * as clientCrypto from '../clients/crypto.js';
|
|
3
|
+
import { getClientByClientId } from '../clients/service.js';
|
|
4
|
+
import { findActiveSecretIdBySha256, getActiveLegacySecretHashes, getLatestActiveSha256, } from '../clients/secret-repository.js';
|
|
5
|
+
import { checkRateLimitStrict } from '../auth/rate-limiter.js';
|
|
6
|
+
import { TOKEN_RATE_LIMIT } from './token-rate-limiter.js';
|
|
7
|
+
const MAX_CLIENT_ID_LENGTH = 255;
|
|
8
|
+
const MAX_SECRET_LENGTH = 512;
|
|
9
|
+
const BUSY_RETRY_SECONDS = 1;
|
|
10
|
+
let legacyBatchActive = false;
|
|
11
|
+
/** Identify a plain request-body record without coercing arrays or scalar values. */
|
|
12
|
+
function isRequestBody(value) {
|
|
13
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
/** Return a parsed object body without coercing arrays or scalar values. */
|
|
16
|
+
function requestBody(ctx) {
|
|
17
|
+
const body = ctx.request.body;
|
|
18
|
+
return isRequestBody(body) ? body : undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Parse bounded HTTP Basic credentials while leaving malformed input to the provider. */
|
|
21
|
+
function basicCredential(ctx) {
|
|
22
|
+
const authorization = ctx.headers.authorization;
|
|
23
|
+
if (authorization === undefined || !authorization.startsWith('Basic '))
|
|
24
|
+
return undefined;
|
|
25
|
+
try {
|
|
26
|
+
const decoded = Buffer.from(authorization.slice(6), 'base64').toString('utf8');
|
|
27
|
+
const separator = decoded.indexOf(':');
|
|
28
|
+
const clientId = decoded.slice(0, separator);
|
|
29
|
+
const plaintext = decoded.slice(separator + 1);
|
|
30
|
+
if (separator < 1 ||
|
|
31
|
+
clientId.length > MAX_CLIENT_ID_LENGTH ||
|
|
32
|
+
plaintext.length < 1 ||
|
|
33
|
+
plaintext.length > MAX_SECRET_LENGTH) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
clientId,
|
|
38
|
+
plaintext,
|
|
39
|
+
method: 'client_secret_basic',
|
|
40
|
+
replace(canonicalValue) {
|
|
41
|
+
const encoded = Buffer.from(`${clientId}:${canonicalValue}`).toString('base64');
|
|
42
|
+
ctx.headers.authorization = `Basic ${encoded}`;
|
|
43
|
+
ctx.req.headers.authorization = `Basic ${encoded}`;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Parse bounded form credentials from the body already parsed by the OIDC router. */
|
|
52
|
+
function postCredential(ctx) {
|
|
53
|
+
const body = requestBody(ctx);
|
|
54
|
+
const clientId = body?.client_id;
|
|
55
|
+
const plaintext = body?.client_secret;
|
|
56
|
+
if (body === undefined ||
|
|
57
|
+
typeof clientId !== 'string' ||
|
|
58
|
+
clientId.length < 1 ||
|
|
59
|
+
clientId.length > MAX_CLIENT_ID_LENGTH ||
|
|
60
|
+
typeof plaintext !== 'string' ||
|
|
61
|
+
plaintext.length < 1 ||
|
|
62
|
+
plaintext.length > MAX_SECRET_LENGTH) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const mutableBody = body;
|
|
66
|
+
return {
|
|
67
|
+
clientId,
|
|
68
|
+
plaintext,
|
|
69
|
+
method: 'client_secret_post',
|
|
70
|
+
replace(canonicalValue) {
|
|
71
|
+
mutableBody.client_secret = canonicalValue;
|
|
72
|
+
const rawBody = Reflect.get(ctx.req, 'body');
|
|
73
|
+
if (typeof rawBody === 'object' && rawBody !== null && !Array.isArray(rawBody)) {
|
|
74
|
+
Reflect.set(rawBody, 'client_secret', canonicalValue);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Return one supported credential source and reject ambiguous dual-mechanism input. */
|
|
80
|
+
function presentedCredential(ctx) {
|
|
81
|
+
const basic = basicCredential(ctx);
|
|
82
|
+
const post = postCredential(ctx);
|
|
83
|
+
if (basic !== undefined && post !== undefined)
|
|
84
|
+
return undefined;
|
|
85
|
+
return basic ?? post;
|
|
86
|
+
}
|
|
87
|
+
/** Return the resolved tenant identifier without trusting request-controlled text. */
|
|
88
|
+
function organizationId(ctx) {
|
|
89
|
+
const organization = ctx.state?.organization;
|
|
90
|
+
if (typeof organization !== 'object' || organization === null || Array.isArray(organization)) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const id = Reflect.get(organization, 'id');
|
|
94
|
+
return typeof id === 'string' && id.length > 0 ? id : undefined;
|
|
95
|
+
}
|
|
96
|
+
/** Emit the existing fixed token rate-limit response without credential detail. */
|
|
97
|
+
function denyProtectedWork(ctx, retryAfter) {
|
|
98
|
+
ctx.status = 429;
|
|
99
|
+
ctx.set('Retry-After', String(retryAfter));
|
|
100
|
+
ctx.body = {
|
|
101
|
+
error: 'rate_limit_exceeded',
|
|
102
|
+
error_description: 'Too many token requests. Please try again later.',
|
|
103
|
+
retry_after: retryAfter,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** Rewrite a proven credential and continue to oidc-provider. */
|
|
107
|
+
async function handOffValidatedCredential(credential, canonicalValue, options, next) {
|
|
108
|
+
credential.replace(canonicalValue);
|
|
109
|
+
await options.afterCredentialValidation?.();
|
|
110
|
+
await next();
|
|
29
111
|
}
|
|
30
112
|
/**
|
|
31
|
-
* Create
|
|
113
|
+
* Create the bounded active-secret bridge mounted immediately before oidc-provider.
|
|
32
114
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* can compare them against stored SHA-256 hashes.
|
|
36
|
-
*
|
|
37
|
-
* @returns Koa middleware function
|
|
115
|
+
* @param options - Optional credential-free validation/handoff test hook
|
|
116
|
+
* @returns Koa middleware
|
|
38
117
|
*/
|
|
39
|
-
export function clientSecretHash() {
|
|
118
|
+
export function clientSecretHash(options = {}) {
|
|
40
119
|
return async (ctx, next) => {
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
120
|
+
const credential = presentedCredential(ctx);
|
|
121
|
+
const tenantId = organizationId(ctx);
|
|
122
|
+
if (credential === undefined || tenantId === undefined)
|
|
123
|
+
return next();
|
|
124
|
+
try {
|
|
125
|
+
const client = await getClientByClientId(credential.clientId);
|
|
126
|
+
if (client === null ||
|
|
127
|
+
client.organizationId !== tenantId ||
|
|
128
|
+
client.clientType !== 'confidential' ||
|
|
129
|
+
client.status !== 'active' ||
|
|
130
|
+
client.tokenEndpointAuthMethod !== credential.method) {
|
|
131
|
+
return next();
|
|
132
|
+
}
|
|
133
|
+
const canonicalValue = await getLatestActiveSha256(client.id);
|
|
134
|
+
if (canonicalValue === null)
|
|
135
|
+
return next();
|
|
136
|
+
const presentedSha256 = clientCrypto.sha256Secret(credential.plaintext);
|
|
137
|
+
const modernMatchId = await findActiveSecretIdBySha256(client.id, presentedSha256);
|
|
138
|
+
if (modernMatchId !== null) {
|
|
139
|
+
return handOffValidatedCredential(credential, canonicalValue, options, next);
|
|
140
|
+
}
|
|
141
|
+
const legacySecrets = await getActiveLegacySecretHashes(client.id);
|
|
142
|
+
if (legacySecrets.length === 0 || legacySecrets.length > 10)
|
|
143
|
+
return next();
|
|
144
|
+
if (legacyBatchActive) {
|
|
145
|
+
denyProtectedWork(ctx, BUSY_RETRY_SECONDS);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
legacyBatchActive = true;
|
|
149
|
+
let legacyMatched = false;
|
|
44
150
|
try {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const newEncoded = Buffer.from(`${clientId}:${hashedSecret}`).toString('base64');
|
|
55
|
-
ctx.headers.authorization = `Basic ${newEncoded}`;
|
|
56
|
-
// Also update the raw request header for oidc-provider
|
|
57
|
-
ctx.req.headers.authorization = `Basic ${newEncoded}`;
|
|
151
|
+
const limit = await checkRateLimitStrict(`ratelimit:client-secret-legacy:${tenantId}:${client.id}`, TOKEN_RATE_LIMIT);
|
|
152
|
+
if (!limit.allowed) {
|
|
153
|
+
denyProtectedWork(ctx, limit.retryAfter);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
for (const legacy of legacySecrets) {
|
|
157
|
+
if (await clientCrypto.verifySecretHash(legacy.hash, credential.plaintext)) {
|
|
158
|
+
legacyMatched = true;
|
|
159
|
+
break;
|
|
58
160
|
}
|
|
59
161
|
}
|
|
60
162
|
}
|
|
61
|
-
|
|
62
|
-
|
|
163
|
+
finally {
|
|
164
|
+
legacyBatchActive = false;
|
|
165
|
+
}
|
|
166
|
+
if (legacyMatched) {
|
|
167
|
+
return handOffValidatedCredential(credential, canonicalValue, options, next);
|
|
63
168
|
}
|
|
64
169
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const body = ctx.request.body;
|
|
68
|
-
if (body && typeof body.client_secret === 'string' && body.client_secret.length > 0) {
|
|
69
|
-
body.client_secret = sha256(body.client_secret);
|
|
170
|
+
catch {
|
|
171
|
+
// Fail closed by leaving the credential untouched for the provider's minimal rejection.
|
|
70
172
|
}
|
|
71
|
-
|
|
173
|
+
return next();
|
|
72
174
|
};
|
|
73
175
|
}
|
|
74
176
|
//# sourceMappingURL=client-secret-hash.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-secret-hash.js","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client-secret-hash.js","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"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"}
|