@de-otio/trellis 0.7.0 → 0.9.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/LICENSE +661 -0
- package/dist/db.js +10 -18
- package/dist/db.js.map +1 -1
- package/dist/env.d.ts +66 -6
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +89 -70
- package/dist/env.js.map +1 -1
- package/dist/extensions.js +3 -8
- package/dist/extensions.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -9
- package/dist/index.js.map +1 -1
- package/dist/lambda/cleanup-cron.d.ts.map +1 -1
- package/dist/lambda/cleanup-cron.js +20 -24
- package/dist/lambda/cleanup-cron.js.map +1 -1
- package/dist/lambda/create-auth-challenge.d.ts.map +1 -1
- package/dist/lambda/create-auth-challenge.js +17 -19
- package/dist/lambda/create-auth-challenge.js.map +1 -1
- package/dist/lambda/custom-message.js +1 -5
- package/dist/lambda/custom-message.js.map +1 -1
- package/dist/lambda/define-auth-challenge.js +1 -5
- package/dist/lambda/define-auth-challenge.js.map +1 -1
- package/dist/lambda/delete-account-worker.d.ts.map +1 -1
- package/dist/lambda/delete-account-worker.js +25 -58
- package/dist/lambda/delete-account-worker.js.map +1 -1
- package/dist/lambda/diagnostics-proxy.d.ts.map +1 -1
- package/dist/lambda/diagnostics-proxy.js +14 -49
- package/dist/lambda/diagnostics-proxy.js.map +1 -1
- package/dist/lambda/e2e-sweeper.d.ts.map +1 -1
- package/dist/lambda/e2e-sweeper.js +30 -38
- package/dist/lambda/e2e-sweeper.js.map +1 -1
- package/dist/lambda/federation-outbox-worker.d.ts.map +1 -1
- package/dist/lambda/federation-outbox-worker.js +4 -6
- package/dist/lambda/federation-outbox-worker.js.map +1 -1
- package/dist/lambda/followers-events-worker.d.ts.map +1 -1
- package/dist/lambda/followers-events-worker.js +4 -6
- package/dist/lambda/followers-events-worker.js.map +1 -1
- package/dist/lambda/hourly-cron.d.ts.map +1 -1
- package/dist/lambda/hourly-cron.js +100 -32
- package/dist/lambda/hourly-cron.js.map +1 -1
- package/dist/lambda/link-check-worker.d.ts.map +1 -1
- package/dist/lambda/link-check-worker.js +4 -6
- package/dist/lambda/link-check-worker.js.map +1 -1
- package/dist/lambda/maintenance-cron.d.ts.map +1 -1
- package/dist/lambda/maintenance-cron.js +30 -63
- package/dist/lambda/maintenance-cron.js.map +1 -1
- package/dist/lambda/media-processing-worker.d.ts.map +1 -1
- package/dist/lambda/media-processing-worker.js +11 -46
- package/dist/lambda/media-processing-worker.js.map +1 -1
- package/dist/lambda/media-reconciliation-worker.d.ts.map +1 -1
- package/dist/lambda/media-reconciliation-worker.js +4 -6
- package/dist/lambda/media-reconciliation-worker.js.map +1 -1
- package/dist/lambda/nightly-cron.d.ts.map +1 -1
- package/dist/lambda/nightly-cron.js +67 -112
- package/dist/lambda/nightly-cron.js.map +1 -1
- package/dist/lambda/post-confirmation.d.ts.map +1 -1
- package/dist/lambda/post-confirmation.js +147 -45
- package/dist/lambda/post-confirmation.js.map +1 -1
- package/dist/lambda/pre-signup.js +7 -11
- package/dist/lambda/pre-signup.js.map +1 -1
- package/dist/lambda/pre-token-generation.d.ts.map +1 -1
- package/dist/lambda/pre-token-generation.js +27 -35
- package/dist/lambda/pre-token-generation.js.map +1 -1
- package/dist/lambda/tools/check-health.js +1 -5
- package/dist/lambda/tools/check-health.js.map +1 -1
- package/dist/lambda/tools/describe-services.js +4 -8
- package/dist/lambda/tools/describe-services.js.map +1 -1
- package/dist/lambda/tools/get-cost-report.js +4 -8
- package/dist/lambda/tools/get-cost-report.js.map +1 -1
- package/dist/lambda/tools/get-errors.js +5 -9
- package/dist/lambda/tools/get-errors.js.map +1 -1
- package/dist/lambda/tools/get-feature-flags.js +4 -8
- package/dist/lambda/tools/get-feature-flags.js.map +1 -1
- package/dist/lambda/tools/get-queue-status.js +5 -9
- package/dist/lambda/tools/get-queue-status.js.map +1 -1
- package/dist/lambda/tools/search-logs.js +5 -9
- package/dist/lambda/tools/search-logs.js.map +1 -1
- package/dist/lambda/tools/send-alert.js +4 -8
- package/dist/lambda/tools/send-alert.js.map +1 -1
- package/dist/lambda/verify-auth-challenge.d.ts.map +1 -1
- package/dist/lambda/verify-auth-challenge.js +10 -12
- package/dist/lambda/verify-auth-challenge.js.map +1 -1
- package/dist/lib/abuse-metrics.d.ts.map +1 -1
- package/dist/lib/abuse-metrics.js +10 -13
- package/dist/lib/abuse-metrics.js.map +1 -1
- package/dist/lib/activitypub/activity-processor.d.ts +1 -1
- package/dist/lib/activitypub/activity-processor.d.ts.map +1 -1
- package/dist/lib/activitypub/activity-processor.js +9 -43
- package/dist/lib/activitypub/activity-processor.js.map +1 -1
- package/dist/lib/activitypub/activity-service.js +1 -5
- package/dist/lib/activitypub/activity-service.js.map +1 -1
- package/dist/lib/activitypub/actor.d.ts +1 -1
- package/dist/lib/activitypub/actor.d.ts.map +1 -1
- package/dist/lib/activitypub/actor.js +1 -5
- package/dist/lib/activitypub/actor.js.map +1 -1
- package/dist/lib/activitypub/audience-service.d.ts +2 -2
- package/dist/lib/activitypub/audience-service.d.ts.map +1 -1
- package/dist/lib/activitypub/audience-service.js +8 -12
- package/dist/lib/activitypub/audience-service.js.map +1 -1
- package/dist/lib/activitypub/crypto.d.ts +1 -1
- package/dist/lib/activitypub/crypto.d.ts.map +1 -1
- package/dist/lib/activitypub/crypto.js +3 -41
- package/dist/lib/activitypub/crypto.js.map +1 -1
- package/dist/lib/activitypub/delivery-service.d.ts +5 -5
- package/dist/lib/activitypub/delivery-service.d.ts.map +1 -1
- package/dist/lib/activitypub/delivery-service.js +10 -47
- package/dist/lib/activitypub/delivery-service.js.map +1 -1
- package/dist/lib/activitypub/dispatchers/entity-actor.d.ts +3 -2
- package/dist/lib/activitypub/dispatchers/entity-actor.d.ts.map +1 -1
- package/dist/lib/activitypub/dispatchers/entity-actor.js +19 -23
- package/dist/lib/activitypub/dispatchers/entity-actor.js.map +1 -1
- package/dist/lib/activitypub/dispatchers/group-actor.d.ts +3 -2
- package/dist/lib/activitypub/dispatchers/group-actor.d.ts.map +1 -1
- package/dist/lib/activitypub/dispatchers/group-actor.js +19 -23
- package/dist/lib/activitypub/dispatchers/group-actor.js.map +1 -1
- package/dist/lib/activitypub/dispatchers/user-actor.d.ts +3 -2
- package/dist/lib/activitypub/dispatchers/user-actor.d.ts.map +1 -1
- package/dist/lib/activitypub/dispatchers/user-actor.js +16 -20
- package/dist/lib/activitypub/dispatchers/user-actor.js.map +1 -1
- package/dist/lib/activitypub/dm-service.js +1 -5
- package/dist/lib/activitypub/dm-service.js.map +1 -1
- package/dist/lib/activitypub/entity-profile-service.d.ts +1 -1
- package/dist/lib/activitypub/entity-profile-service.d.ts.map +1 -1
- package/dist/lib/activitypub/entity-profile-service.js +6 -10
- package/dist/lib/activitypub/entity-profile-service.js.map +1 -1
- package/dist/lib/activitypub/fedify/config.d.ts +3 -3
- package/dist/lib/activitypub/fedify/config.d.ts.map +1 -1
- package/dist/lib/activitypub/fedify/config.js +5 -8
- package/dist/lib/activitypub/fedify/config.js.map +1 -1
- package/dist/lib/activitypub/fedify/context.d.ts +1 -1
- package/dist/lib/activitypub/fedify/context.d.ts.map +1 -1
- package/dist/lib/activitypub/fedify/context.js +8 -12
- package/dist/lib/activitypub/fedify/context.js.map +1 -1
- package/dist/lib/activitypub/fedify/runtime.d.ts +1 -1
- package/dist/lib/activitypub/fedify/runtime.d.ts.map +1 -1
- package/dist/lib/activitypub/fedify/runtime.js +3 -6
- package/dist/lib/activitypub/fedify/runtime.js.map +1 -1
- package/dist/lib/activitypub/friendship-service.js +1 -5
- package/dist/lib/activitypub/friendship-service.js.map +1 -1
- package/dist/lib/activitypub/group-service.d.ts +1 -1
- package/dist/lib/activitypub/group-service.d.ts.map +1 -1
- package/dist/lib/activitypub/group-service.js +9 -46
- package/dist/lib/activitypub/group-service.js.map +1 -1
- package/dist/lib/activitypub/http-signatures.js +8 -45
- package/dist/lib/activitypub/http-signatures.js.map +1 -1
- package/dist/lib/activitypub/jsonld.d.ts +1 -1
- package/dist/lib/activitypub/jsonld.d.ts.map +1 -1
- package/dist/lib/activitypub/jsonld.js +1 -5
- package/dist/lib/activitypub/jsonld.js.map +1 -1
- package/dist/lib/activitypub/listeners/friends-collection.d.ts +1 -1
- package/dist/lib/activitypub/listeners/friends-collection.d.ts.map +1 -1
- package/dist/lib/activitypub/listeners/friends-collection.js +17 -20
- package/dist/lib/activitypub/listeners/friends-collection.js.map +1 -1
- package/dist/lib/activitypub/listeners/http-signatures.d.ts +1 -1
- package/dist/lib/activitypub/listeners/http-signatures.d.ts.map +1 -1
- package/dist/lib/activitypub/listeners/http-signatures.js +9 -46
- package/dist/lib/activitypub/listeners/http-signatures.js.map +1 -1
- package/dist/lib/activitypub/listeners/inbox.d.ts +2 -2
- package/dist/lib/activitypub/listeners/inbox.d.ts.map +1 -1
- package/dist/lib/activitypub/listeners/inbox.js +31 -35
- package/dist/lib/activitypub/listeners/inbox.js.map +1 -1
- package/dist/lib/activitypub/listeners/outbox.d.ts +1 -1
- package/dist/lib/activitypub/listeners/outbox.d.ts.map +1 -1
- package/dist/lib/activitypub/listeners/outbox.js +17 -20
- package/dist/lib/activitypub/listeners/outbox.js.map +1 -1
- package/dist/lib/activitypub/remote-fetch-service.d.ts +6 -6
- package/dist/lib/activitypub/remote-fetch-service.d.ts.map +1 -1
- package/dist/lib/activitypub/remote-fetch-service.js +6 -10
- package/dist/lib/activitypub/remote-fetch-service.js.map +1 -1
- package/dist/lib/activitypub/services/abuse-prevention.d.ts +1 -1
- package/dist/lib/activitypub/services/abuse-prevention.d.ts.map +1 -1
- package/dist/lib/activitypub/services/abuse-prevention.js +11 -17
- package/dist/lib/activitypub/services/abuse-prevention.js.map +1 -1
- package/dist/lib/activitypub/services/dm-service-fedify.d.ts +4 -4
- package/dist/lib/activitypub/services/dm-service-fedify.d.ts.map +1 -1
- package/dist/lib/activitypub/services/dm-service-fedify.js +24 -59
- package/dist/lib/activitypub/services/dm-service-fedify.js.map +1 -1
- package/dist/lib/activitypub/services/fedify-converters.d.ts +2 -2
- package/dist/lib/activitypub/services/fedify-converters.d.ts.map +1 -1
- package/dist/lib/activitypub/services/fedify-converters.js +3 -8
- package/dist/lib/activitypub/services/fedify-converters.js.map +1 -1
- package/dist/lib/activitypub/services/fedify-delivery.d.ts +2 -2
- package/dist/lib/activitypub/services/fedify-delivery.d.ts.map +1 -1
- package/dist/lib/activitypub/services/fedify-delivery.js +19 -56
- package/dist/lib/activitypub/services/fedify-delivery.js.map +1 -1
- package/dist/lib/activitypub/services/follow-activity-service.d.ts +2 -2
- package/dist/lib/activitypub/services/follow-activity-service.d.ts.map +1 -1
- package/dist/lib/activitypub/services/follow-activity-service.js +8 -12
- package/dist/lib/activitypub/services/follow-activity-service.js.map +1 -1
- package/dist/lib/activitypub/services/post-service-fedify.d.ts +2 -2
- package/dist/lib/activitypub/services/post-service-fedify.d.ts.map +1 -1
- package/dist/lib/activitypub/services/post-service-fedify.js +33 -65
- package/dist/lib/activitypub/services/post-service-fedify.js.map +1 -1
- package/dist/lib/activitypub/services/remote-activity-handler.d.ts +2 -2
- package/dist/lib/activitypub/services/remote-activity-handler.d.ts.map +1 -1
- package/dist/lib/activitypub/services/remote-activity-handler.js +25 -28
- package/dist/lib/activitypub/services/remote-activity-handler.js.map +1 -1
- package/dist/lib/activitypub/standalone-mode.d.ts +1 -1
- package/dist/lib/activitypub/standalone-mode.d.ts.map +1 -1
- package/dist/lib/activitypub/standalone-mode.js +13 -50
- package/dist/lib/activitypub/standalone-mode.js.map +1 -1
- package/dist/lib/activitypub/webfinger/server.d.ts +1 -1
- package/dist/lib/activitypub/webfinger/server.d.ts.map +1 -1
- package/dist/lib/activitypub/webfinger/server.js +18 -54
- package/dist/lib/activitypub/webfinger/server.js.map +1 -1
- package/dist/lib/age-gate-middleware.d.ts +4 -4
- package/dist/lib/age-gate-middleware.d.ts.map +1 -1
- package/dist/lib/age-gate-middleware.js +3 -6
- package/dist/lib/age-gate-middleware.js.map +1 -1
- package/dist/lib/age-gate.js +3 -8
- package/dist/lib/age-gate.js.map +1 -1
- package/dist/lib/age-tier-transition.d.ts +1 -1
- package/dist/lib/age-tier-transition.d.ts.map +1 -1
- package/dist/lib/age-tier-transition.js +7 -44
- package/dist/lib/age-tier-transition.js.map +1 -1
- package/dist/lib/app.d.ts +76 -0
- package/dist/lib/app.d.ts.map +1 -0
- package/dist/lib/app.js +400 -0
- package/dist/lib/app.js.map +1 -0
- package/dist/lib/audit/csv-export.js +6 -13
- package/dist/lib/audit/csv-export.js.map +1 -1
- package/dist/lib/audit/pii-filter.d.ts +9 -0
- package/dist/lib/audit/pii-filter.d.ts.map +1 -1
- package/dist/lib/audit/pii-filter.js +57 -7
- package/dist/lib/audit/pii-filter.js.map +1 -1
- package/dist/lib/audit-actions.d.ts +94 -0
- package/dist/lib/audit-actions.d.ts.map +1 -0
- package/dist/lib/audit-actions.js +107 -0
- package/dist/lib/audit-actions.js.map +1 -0
- package/dist/lib/audit-composer.d.ts +174 -0
- package/dist/lib/audit-composer.d.ts.map +1 -0
- package/dist/lib/audit-composer.js +421 -0
- package/dist/lib/audit-composer.js.map +1 -0
- package/dist/lib/auth/auth-context.d.ts +1 -1
- package/dist/lib/auth/auth-context.js +1 -2
- package/dist/lib/auth/auth-context.js.map +1 -1
- package/dist/lib/auth/auth-middleware.d.ts +16 -2
- package/dist/lib/auth/auth-middleware.d.ts.map +1 -1
- package/dist/lib/auth/auth-middleware.js +36 -45
- package/dist/lib/auth/auth-middleware.js.map +1 -1
- package/dist/lib/auth/capabilities.js +2 -5
- package/dist/lib/auth/capabilities.js.map +1 -1
- package/dist/lib/auth/claims-cache.d.ts +2 -2
- package/dist/lib/auth/claims-cache.js +19 -24
- package/dist/lib/auth/claims-cache.js.map +1 -1
- package/dist/lib/auth/cognito-jwt.d.ts +20 -2
- package/dist/lib/auth/cognito-jwt.d.ts.map +1 -1
- package/dist/lib/auth/cognito-jwt.js +83 -23
- package/dist/lib/auth/cognito-jwt.js.map +1 -1
- package/dist/lib/auth/idp-redirect-builder.d.ts +1 -1
- package/dist/lib/auth/idp-redirect-builder.d.ts.map +1 -1
- package/dist/lib/auth/idp-redirect-builder.js +4 -10
- package/dist/lib/auth/idp-redirect-builder.js.map +1 -1
- package/dist/lib/auth/require.d.ts +4 -4
- package/dist/lib/auth/require.d.ts.map +1 -1
- package/dist/lib/auth/require.js +11 -18
- package/dist/lib/auth/require.js.map +1 -1
- package/dist/lib/auth/role-grants.d.ts +1 -1
- package/dist/lib/auth/role-grants.d.ts.map +1 -1
- package/dist/lib/auth/role-grants.js +28 -31
- package/dist/lib/auth/role-grants.js.map +1 -1
- package/dist/lib/auth-context-manager.js +1 -5
- package/dist/lib/auth-context-manager.js.map +1 -1
- package/dist/lib/auth-handler.d.ts +5 -5
- package/dist/lib/auth-handler.d.ts.map +1 -1
- package/dist/lib/auth-handler.js +5 -9
- package/dist/lib/auth-handler.js.map +1 -1
- package/dist/lib/badge-handler.d.ts +1 -1
- package/dist/lib/badge-handler.d.ts.map +1 -1
- package/dist/lib/badge-handler.js +14 -52
- package/dist/lib/badge-handler.js.map +1 -1
- package/dist/lib/circle-handler.d.ts +10 -10
- package/dist/lib/circle-handler.d.ts.map +1 -1
- package/dist/lib/circle-handler.js +10 -47
- package/dist/lib/circle-handler.js.map +1 -1
- package/dist/lib/cognito/idp-sdk.js +11 -18
- package/dist/lib/cognito/idp-sdk.js.map +1 -1
- package/dist/lib/cognito/issuer-probe.js +9 -14
- package/dist/lib/cognito/issuer-probe.js.map +1 -1
- package/dist/lib/comment-handler.d.ts +10 -10
- package/dist/lib/comment-handler.d.ts.map +1 -1
- package/dist/lib/comment-handler.js +61 -97
- package/dist/lib/comment-handler.js.map +1 -1
- package/dist/lib/compliance/baseline.d.ts +2 -2
- package/dist/lib/compliance/baseline.d.ts.map +1 -1
- package/dist/lib/compliance/baseline.js +15 -18
- package/dist/lib/compliance/baseline.js.map +1 -1
- package/dist/lib/compliance/tenant-merge.d.ts +1 -1
- package/dist/lib/compliance/tenant-merge.d.ts.map +1 -1
- package/dist/lib/compliance/tenant-merge.js +1 -4
- package/dist/lib/compliance/tenant-merge.js.map +1 -1
- package/dist/lib/compliance/types.d.ts +1 -1
- package/dist/lib/compliance/types.js +2 -3
- package/dist/lib/compliance/types.js.map +1 -1
- package/dist/lib/connection-code-handler.d.ts +7 -7
- package/dist/lib/connection-code-handler.d.ts.map +1 -1
- package/dist/lib/connection-code-handler.js +13 -50
- package/dist/lib/connection-code-handler.js.map +1 -1
- package/dist/lib/content-discovery.d.ts +1 -1
- package/dist/lib/content-discovery.d.ts.map +1 -1
- package/dist/lib/content-discovery.js +15 -52
- package/dist/lib/content-discovery.js.map +1 -1
- package/dist/lib/context-aware-data-access.d.ts +1 -1
- package/dist/lib/context-aware-data-access.d.ts.map +1 -1
- package/dist/lib/context-aware-data-access.js +1 -5
- package/dist/lib/context-aware-data-access.js.map +1 -1
- package/dist/lib/cors-handler.d.ts +1 -1
- package/dist/lib/cors-handler.d.ts.map +1 -1
- package/dist/lib/cors-handler.js +13 -17
- package/dist/lib/cors-handler.js.map +1 -1
- package/dist/lib/cost-accumulator.d.ts.map +1 -1
- package/dist/lib/cost-accumulator.js +7 -11
- package/dist/lib/cost-accumulator.js.map +1 -1
- package/dist/lib/crypto/voting/elgamal-encryption.js +1 -5
- package/dist/lib/crypto/voting/elgamal-encryption.js.map +1 -1
- package/dist/lib/crypto/voting/encryption-scheme.js +1 -2
- package/dist/lib/crypto/voting/encryption-scheme.js.map +1 -1
- package/dist/lib/crypto/voting/hash-utils.js +6 -12
- package/dist/lib/crypto/voting/hash-utils.js.map +1 -1
- package/dist/lib/crypto/voting/hybrid-encryption.js +5 -9
- package/dist/lib/crypto/voting/hybrid-encryption.js.map +1 -1
- package/dist/lib/crypto/voting/index.js +4 -14
- package/dist/lib/crypto/voting/index.js.map +1 -1
- package/dist/lib/crypto/voting/post-quantum-encryption.js +1 -5
- package/dist/lib/crypto/voting/post-quantum-encryption.js.map +1 -1
- package/dist/lib/csrf.d.ts +2 -2
- package/dist/lib/csrf.d.ts.map +1 -1
- package/dist/lib/csrf.js +1 -5
- package/dist/lib/csrf.js.map +1 -1
- package/dist/lib/data-router.d.ts +5 -4
- package/dist/lib/data-router.d.ts.map +1 -1
- package/dist/lib/data-router.js +60 -90
- package/dist/lib/data-router.js.map +1 -1
- package/dist/lib/database-circuit-breaker.d.ts +61 -34
- package/dist/lib/database-circuit-breaker.d.ts.map +1 -1
- package/dist/lib/database-circuit-breaker.js +102 -109
- package/dist/lib/database-circuit-breaker.js.map +1 -1
- package/dist/lib/database-config.js +1 -4
- package/dist/lib/database-config.js.map +1 -1
- package/dist/lib/database-connection-manager.d.ts +42 -2
- package/dist/lib/database-connection-manager.d.ts.map +1 -1
- package/dist/lib/database-connection-manager.js +178 -74
- package/dist/lib/database-connection-manager.js.map +1 -1
- package/dist/lib/database-monitor.d.ts +1 -1
- package/dist/lib/database-monitor.d.ts.map +1 -1
- package/dist/lib/database-monitor.js +5 -9
- package/dist/lib/database-monitor.js.map +1 -1
- package/dist/lib/database-rate-limiter.d.ts +1 -1
- package/dist/lib/database-rate-limiter.d.ts.map +1 -1
- package/dist/lib/database-rate-limiter.js +3 -7
- package/dist/lib/database-rate-limiter.js.map +1 -1
- package/dist/lib/database-wrapper-helper.d.ts +2 -2
- package/dist/lib/database-wrapper-helper.d.ts.map +1 -1
- package/dist/lib/database-wrapper-helper.js +7 -11
- package/dist/lib/database-wrapper-helper.js.map +1 -1
- package/dist/lib/database-wrapper.d.ts +1 -1
- package/dist/lib/database-wrapper.d.ts.map +1 -1
- package/dist/lib/database-wrapper.js +5 -9
- package/dist/lib/database-wrapper.js.map +1 -1
- package/dist/lib/db-query-helper.d.ts +3 -3
- package/dist/lib/db-query-helper.d.ts.map +1 -1
- package/dist/lib/db-query-helper.js +4 -9
- package/dist/lib/db-query-helper.js.map +1 -1
- package/dist/lib/discovery-exposure.d.ts +42 -0
- package/dist/lib/discovery-exposure.d.ts.map +1 -0
- package/dist/lib/discovery-exposure.js +89 -0
- package/dist/lib/discovery-exposure.js.map +1 -0
- package/dist/lib/discovery-handler.d.ts +6 -6
- package/dist/lib/discovery-handler.d.ts.map +1 -1
- package/dist/lib/discovery-handler.js +10 -43
- package/dist/lib/discovery-handler.js.map +1 -1
- package/dist/lib/domain-reputation-service.d.ts +1 -1
- package/dist/lib/domain-reputation-service.d.ts.map +1 -1
- package/dist/lib/domain-reputation-service.js +12 -15
- package/dist/lib/domain-reputation-service.js.map +1 -1
- package/dist/lib/email-privacy.js +4 -8
- package/dist/lib/email-privacy.js.map +1 -1
- package/dist/lib/email-provider.d.ts +2 -2
- package/dist/lib/email-provider.d.ts.map +1 -1
- package/dist/lib/email-provider.js +8 -16
- package/dist/lib/email-provider.js.map +1 -1
- package/dist/lib/entity-handler.d.ts +5 -6
- package/dist/lib/entity-handler.d.ts.map +1 -1
- package/dist/lib/entity-handler.js +45 -80
- package/dist/lib/entity-handler.js.map +1 -1
- package/dist/lib/entity-relationship-handler.d.ts +9 -9
- package/dist/lib/entity-relationship-handler.d.ts.map +1 -1
- package/dist/lib/entity-relationship-handler.js +14 -51
- package/dist/lib/entity-relationship-handler.js.map +1 -1
- package/dist/lib/entity-tagging-errors.js +4 -11
- package/dist/lib/entity-tagging-errors.js.map +1 -1
- package/dist/lib/entity-tagging-validator.d.ts +3 -3
- package/dist/lib/entity-tagging-validator.d.ts.map +1 -1
- package/dist/lib/entity-tagging-validator.js +6 -11
- package/dist/lib/entity-tagging-validator.js.map +1 -1
- package/dist/lib/exif-stripper.js +1 -4
- package/dist/lib/exif-stripper.js.map +1 -1
- package/dist/lib/extension-context.d.ts +2 -2
- package/dist/lib/extension-context.d.ts.map +1 -1
- package/dist/lib/extension-context.js +1 -4
- package/dist/lib/extension-context.js.map +1 -1
- package/dist/lib/extension-route-wrapper.d.ts +1 -1
- package/dist/lib/extension-route-wrapper.d.ts.map +1 -1
- package/dist/lib/extension-route-wrapper.js +17 -55
- package/dist/lib/extension-route-wrapper.js.map +1 -1
- package/dist/lib/extension-validator.js +3 -6
- package/dist/lib/extension-validator.js.map +1 -1
- package/dist/lib/feature-flags.d.ts +5 -2
- package/dist/lib/feature-flags.d.ts.map +1 -1
- package/dist/lib/feature-flags.js +15 -48
- package/dist/lib/feature-flags.js.map +1 -1
- package/dist/lib/feature-toggle-global-client.d.ts +6 -0
- package/dist/lib/feature-toggle-global-client.d.ts.map +1 -0
- package/dist/lib/feature-toggle-global-client.js +73 -0
- package/dist/lib/feature-toggle-global-client.js.map +1 -0
- package/dist/lib/feature-toggle-service.d.ts +137 -27
- package/dist/lib/feature-toggle-service.d.ts.map +1 -1
- package/dist/lib/feature-toggle-service.js +302 -119
- package/dist/lib/feature-toggle-service.js.map +1 -1
- package/dist/lib/feed-handler.d.ts +8 -8
- package/dist/lib/feed-handler.d.ts.map +1 -1
- package/dist/lib/feed-handler.js +33 -62
- package/dist/lib/feed-handler.js.map +1 -1
- package/dist/lib/feed-pagination.d.ts +26 -0
- package/dist/lib/feed-pagination.d.ts.map +1 -1
- package/dist/lib/feed-pagination.js +31 -11
- package/dist/lib/feed-pagination.js.map +1 -1
- package/dist/lib/feed-personalization.d.ts +1 -1
- package/dist/lib/feed-personalization.d.ts.map +1 -1
- package/dist/lib/feed-personalization.js +6 -43
- package/dist/lib/feed-personalization.js.map +1 -1
- package/dist/lib/followers-events.js +8 -13
- package/dist/lib/followers-events.js.map +1 -1
- package/dist/lib/friends-handler.d.ts +2 -2
- package/dist/lib/friends-handler.d.ts.map +1 -1
- package/dist/lib/friends-handler.js +9 -46
- package/dist/lib/friends-handler.js.map +1 -1
- package/dist/lib/geo/entity-geo-repository.d.ts +67 -0
- package/dist/lib/geo/entity-geo-repository.d.ts.map +1 -0
- package/dist/lib/geo/entity-geo-repository.js +91 -0
- package/dist/lib/geo/entity-geo-repository.js.map +1 -0
- package/dist/lib/graph/errors.d.ts.map +1 -1
- package/dist/lib/graph/errors.js +13 -18
- package/dist/lib/graph/errors.js.map +1 -1
- package/dist/lib/graph/graph-factory.d.ts +12 -53
- package/dist/lib/graph/graph-factory.d.ts.map +1 -1
- package/dist/lib/graph/graph-factory.js +67 -162
- package/dist/lib/graph/graph-factory.js.map +1 -1
- package/dist/lib/graph/graph-service.d.ts +1 -1
- package/dist/lib/graph/graph-service.d.ts.map +1 -1
- package/dist/lib/graph/graph-service.js +1 -2
- package/dist/lib/graph/graph-service.js.map +1 -1
- package/dist/lib/graph/index.d.ts +10 -14
- package/dist/lib/graph/index.d.ts.map +1 -1
- package/dist/lib/graph/index.js +12 -46
- package/dist/lib/graph/index.js.map +1 -1
- package/dist/lib/graph/postgres/_shared.d.ts +18 -0
- package/dist/lib/graph/postgres/_shared.d.ts.map +1 -0
- package/dist/lib/graph/postgres/_shared.js +24 -0
- package/dist/lib/graph/postgres/_shared.js.map +1 -0
- package/dist/lib/graph/postgres/circles.d.ts +66 -0
- package/dist/lib/graph/postgres/circles.d.ts.map +1 -0
- package/dist/lib/graph/postgres/circles.js +513 -0
- package/dist/lib/graph/postgres/circles.js.map +1 -0
- package/dist/lib/graph/postgres/discovery.d.ts +165 -0
- package/dist/lib/graph/postgres/discovery.d.ts.map +1 -0
- package/dist/lib/graph/postgres/discovery.js +579 -0
- package/dist/lib/graph/postgres/discovery.js.map +1 -0
- package/dist/lib/graph/postgres/entity-relationships.d.ts +53 -0
- package/dist/lib/graph/postgres/entity-relationships.d.ts.map +1 -0
- package/dist/lib/graph/postgres/entity-relationships.js +304 -0
- package/dist/lib/graph/postgres/entity-relationships.js.map +1 -0
- package/dist/lib/graph/postgres/interaction-events.d.ts +106 -0
- package/dist/lib/graph/postgres/interaction-events.d.ts.map +1 -0
- package/dist/lib/graph/postgres/interaction-events.js +162 -0
- package/dist/lib/graph/postgres/interaction-events.js.map +1 -0
- package/dist/lib/graph/postgres/postgres-graph-service.d.ts +74 -0
- package/dist/lib/graph/postgres/postgres-graph-service.d.ts.map +1 -0
- package/dist/lib/graph/postgres/postgres-graph-service.js +167 -0
- package/dist/lib/graph/postgres/postgres-graph-service.js.map +1 -0
- package/dist/lib/graph/postgres/relationships.d.ts +58 -0
- package/dist/lib/graph/postgres/relationships.d.ts.map +1 -0
- package/dist/lib/graph/postgres/relationships.js +314 -0
- package/dist/lib/graph/postgres/relationships.js.map +1 -0
- package/dist/lib/graph/postgres/scoring.d.ts +74 -0
- package/dist/lib/graph/postgres/scoring.d.ts.map +1 -0
- package/dist/lib/graph/postgres/scoring.js +297 -0
- package/dist/lib/graph/postgres/scoring.js.map +1 -0
- package/dist/lib/graph/postgres/sync.d.ts +149 -0
- package/dist/lib/graph/postgres/sync.d.ts.map +1 -0
- package/dist/lib/graph/postgres/sync.js +269 -0
- package/dist/lib/graph/postgres/sync.js.map +1 -0
- package/dist/lib/graph/scoring-engine.d.ts +7 -1
- package/dist/lib/graph/scoring-engine.d.ts.map +1 -1
- package/dist/lib/graph/scoring-engine.js +29 -35
- package/dist/lib/graph/scoring-engine.js.map +1 -1
- package/dist/lib/graph/types.d.ts +18 -1
- package/dist/lib/graph/types.d.ts.map +1 -1
- package/dist/lib/graph/types.js +1 -2
- package/dist/lib/graph/types.js.map +1 -1
- package/dist/lib/hook-dispatcher.d.ts +1 -1
- package/dist/lib/hook-dispatcher.d.ts.map +1 -1
- package/dist/lib/hook-dispatcher.js +8 -12
- package/dist/lib/hook-dispatcher.js.map +1 -1
- package/dist/lib/input-sanitizer.js +1 -5
- package/dist/lib/input-sanitizer.js.map +1 -1
- package/dist/lib/internal-docs-handler.d.ts +2 -2
- package/dist/lib/internal-docs-handler.d.ts.map +1 -1
- package/dist/lib/internal-docs-handler.js +20 -28
- package/dist/lib/internal-docs-handler.js.map +1 -1
- package/dist/lib/internal-docs-navigation.js +2 -6
- package/dist/lib/internal-docs-navigation.js.map +1 -1
- package/dist/lib/invitation-handler.d.ts +2 -2
- package/dist/lib/invitation-handler.d.ts.map +1 -1
- package/dist/lib/invitation-handler.js +41 -82
- package/dist/lib/invitation-handler.js.map +1 -1
- package/dist/lib/ip-scrubber.js +3 -8
- package/dist/lib/ip-scrubber.js.map +1 -1
- package/dist/lib/link-security-handler.d.ts +3 -2
- package/dist/lib/link-security-handler.d.ts.map +1 -1
- package/dist/lib/link-security-handler.js +8 -44
- package/dist/lib/link-security-handler.js.map +1 -1
- package/dist/lib/logger.d.ts +31 -82
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +43 -185
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/media-cleanup-handler.d.ts +2 -2
- package/dist/lib/media-cleanup-handler.d.ts.map +1 -1
- package/dist/lib/media-cleanup-handler.js +7 -11
- package/dist/lib/media-cleanup-handler.js.map +1 -1
- package/dist/lib/media-handler.d.ts +1 -1
- package/dist/lib/media-handler.d.ts.map +1 -1
- package/dist/lib/media-handler.js +36 -73
- package/dist/lib/media-handler.js.map +1 -1
- package/dist/lib/media-metadata-extractor.d.ts +1 -1
- package/dist/lib/media-metadata-extractor.d.ts.map +1 -1
- package/dist/lib/media-metadata-extractor.js +3 -7
- package/dist/lib/media-metadata-extractor.js.map +1 -1
- package/dist/lib/media-metrics.d.ts +2 -2
- package/dist/lib/media-metrics.d.ts.map +1 -1
- package/dist/lib/media-metrics.js +3 -7
- package/dist/lib/media-metrics.js.map +1 -1
- package/dist/lib/metadata/index.d.ts +5 -5
- package/dist/lib/metadata/index.d.ts.map +1 -1
- package/dist/lib/metadata/index.js +5 -21
- package/dist/lib/metadata/index.js.map +1 -1
- package/dist/lib/metadata/metadata-config.js +2 -5
- package/dist/lib/metadata/metadata-config.js.map +1 -1
- package/dist/lib/metadata/metadata-errors.js +2 -7
- package/dist/lib/metadata/metadata-errors.js.map +1 -1
- package/dist/lib/metadata/metadata-extractor.d.ts +1 -1
- package/dist/lib/metadata/metadata-extractor.d.ts.map +1 -1
- package/dist/lib/metadata/metadata-extractor.js +42 -82
- package/dist/lib/metadata/metadata-extractor.js.map +1 -1
- package/dist/lib/metadata/metadata-sanitizer.js +17 -24
- package/dist/lib/metadata/metadata-sanitizer.js.map +1 -1
- package/dist/lib/metadata/metadata-schemas.d.ts +16 -100
- package/dist/lib/metadata/metadata-schemas.d.ts.map +1 -1
- package/dist/lib/metadata/metadata-schemas.js +31 -34
- package/dist/lib/metadata/metadata-schemas.js.map +1 -1
- package/dist/lib/mfa/mfa-handler.d.ts +1 -1
- package/dist/lib/mfa/mfa-handler.d.ts.map +1 -1
- package/dist/lib/mfa/mfa-handler.js +13 -17
- package/dist/lib/mfa/mfa-handler.js.map +1 -1
- package/dist/lib/mfa/totp-service.js +8 -18
- package/dist/lib/mfa/totp-service.js.map +1 -1
- package/dist/lib/middleware/comment-rate-limit.d.ts +1 -1
- package/dist/lib/middleware/comment-rate-limit.d.ts.map +1 -1
- package/dist/lib/middleware/comment-rate-limit.js +7 -10
- package/dist/lib/middleware/comment-rate-limit.js.map +1 -1
- package/dist/lib/middleware/feature-toggle-rate-limit.d.ts +1 -1
- package/dist/lib/middleware/feature-toggle-rate-limit.d.ts.map +1 -1
- package/dist/lib/middleware/feature-toggle-rate-limit.js +8 -13
- package/dist/lib/middleware/feature-toggle-rate-limit.js.map +1 -1
- package/dist/lib/middleware/idempotency-store.js +20 -26
- package/dist/lib/middleware/idempotency-store.js.map +1 -1
- package/dist/lib/middleware/idempotency.d.ts +2 -2
- package/dist/lib/middleware/idempotency.d.ts.map +1 -1
- package/dist/lib/middleware/idempotency.js +12 -50
- package/dist/lib/middleware/idempotency.js.map +1 -1
- package/dist/lib/middleware.d.ts +22 -9
- package/dist/lib/middleware.d.ts.map +1 -1
- package/dist/lib/middleware.js +72 -153
- package/dist/lib/middleware.js.map +1 -1
- package/dist/lib/moderation-handler.d.ts +1 -1
- package/dist/lib/moderation-handler.d.ts.map +1 -1
- package/dist/lib/moderation-handler.js +15 -54
- package/dist/lib/moderation-handler.js.map +1 -1
- package/dist/lib/net/trusted-client-ip.d.ts +8 -30
- package/dist/lib/net/trusted-client-ip.d.ts.map +1 -1
- package/dist/lib/net/trusted-client-ip.js +13 -94
- package/dist/lib/net/trusted-client-ip.js.map +1 -1
- package/dist/lib/notification-handler.d.ts +1 -1
- package/dist/lib/notification-handler.d.ts.map +1 -1
- package/dist/lib/notification-handler.js +10 -15
- package/dist/lib/notification-handler.js.map +1 -1
- package/dist/lib/notification-preferences-handler.d.ts +1 -1
- package/dist/lib/notification-preferences-handler.d.ts.map +1 -1
- package/dist/lib/notification-preferences-handler.js +7 -11
- package/dist/lib/notification-preferences-handler.js.map +1 -1
- package/dist/lib/oauth/cognito-issuer.d.ts +1 -1
- package/dist/lib/oauth/cognito-issuer.d.ts.map +1 -1
- package/dist/lib/oauth/cognito-issuer.js +5 -10
- package/dist/lib/oauth/cognito-issuer.js.map +1 -1
- package/dist/lib/oauth/device-authorization.d.ts +1 -1
- package/dist/lib/oauth/device-authorization.d.ts.map +1 -1
- package/dist/lib/oauth/device-authorization.js +62 -77
- package/dist/lib/oauth/device-authorization.js.map +1 -1
- package/dist/lib/oauth/envelope-crypto.d.ts +2 -2
- package/dist/lib/oauth/envelope-crypto.js +22 -34
- package/dist/lib/oauth/envelope-crypto.js.map +1 -1
- package/dist/lib/oauth/refresh-detection.js +42 -52
- package/dist/lib/oauth/refresh-detection.js.map +1 -1
- package/dist/lib/openai-budget.d.ts.map +1 -1
- package/dist/lib/openai-budget.js +7 -44
- package/dist/lib/openai-budget.js.map +1 -1
- package/dist/lib/openapi/generator.d.ts +1 -1
- package/dist/lib/openapi/generator.d.ts.map +1 -1
- package/dist/lib/openapi/generator.js +2 -6
- package/dist/lib/openapi/generator.js.map +1 -1
- package/dist/lib/orphaned-media-handler.d.ts +1 -1
- package/dist/lib/orphaned-media-handler.d.ts.map +1 -1
- package/dist/lib/orphaned-media-handler.js +9 -46
- package/dist/lib/orphaned-media-handler.js.map +1 -1
- package/dist/lib/parental-control-handler.d.ts +2 -2
- package/dist/lib/parental-control-handler.d.ts.map +1 -1
- package/dist/lib/parental-control-handler.js +18 -55
- package/dist/lib/parental-control-handler.js.map +1 -1
- package/dist/lib/parental-link-handler.d.ts +8 -8
- package/dist/lib/parental-link-handler.d.ts.map +1 -1
- package/dist/lib/parental-link-handler.js +10 -14
- package/dist/lib/parental-link-handler.js.map +1 -1
- package/dist/lib/performance-metrics.d.ts +1 -1
- package/dist/lib/performance-metrics.d.ts.map +1 -1
- package/dist/lib/performance-metrics.js +3 -6
- package/dist/lib/performance-metrics.js.map +1 -1
- package/dist/lib/post-handler.d.ts +9 -9
- package/dist/lib/post-handler.d.ts.map +1 -1
- package/dist/lib/post-handler.js +67 -101
- package/dist/lib/post-handler.js.map +1 -1
- package/dist/lib/privacy-defaults.js +3 -8
- package/dist/lib/privacy-defaults.js.map +1 -1
- package/dist/lib/privacy-handler.d.ts +2 -2
- package/dist/lib/privacy-handler.d.ts.map +1 -1
- package/dist/lib/privacy-handler.js +6 -10
- package/dist/lib/privacy-handler.js.map +1 -1
- package/dist/lib/pseudonym.d.ts +56 -0
- package/dist/lib/pseudonym.d.ts.map +1 -0
- package/dist/lib/pseudonym.js +85 -0
- package/dist/lib/pseudonym.js.map +1 -0
- package/dist/lib/queue-consumers/media-reconciliation-consumer.d.ts +2 -2
- package/dist/lib/queue-consumers/media-reconciliation-consumer.d.ts.map +1 -1
- package/dist/lib/queue-consumers/media-reconciliation-consumer.js +5 -8
- package/dist/lib/queue-consumers/media-reconciliation-consumer.js.map +1 -1
- package/dist/lib/quiet-hours.js +2 -6
- package/dist/lib/quiet-hours.js.map +1 -1
- package/dist/lib/rate-limit.d.ts +58 -47
- package/dist/lib/rate-limit.d.ts.map +1 -1
- package/dist/lib/rate-limit.js +168 -157
- package/dist/lib/rate-limit.js.map +1 -1
- package/dist/lib/reaction-handler.d.ts +10 -10
- package/dist/lib/reaction-handler.d.ts.map +1 -1
- package/dist/lib/reaction-handler.js +44 -80
- package/dist/lib/reaction-handler.js.map +1 -1
- package/dist/lib/recaptcha.js +6 -9
- package/dist/lib/recaptcha.js.map +1 -1
- package/dist/lib/redirect-resolver.d.ts +2 -2
- package/dist/lib/redirect-resolver.d.ts.map +1 -1
- package/dist/lib/redirect-resolver.js +5 -9
- package/dist/lib/redirect-resolver.js.map +1 -1
- package/dist/lib/region-config.d.ts +3 -3
- package/dist/lib/region-config.d.ts.map +1 -1
- package/dist/lib/region-config.js +15 -58
- package/dist/lib/region-config.js.map +1 -1
- package/dist/lib/region-detection.d.ts +55 -24
- package/dist/lib/region-detection.d.ts.map +1 -1
- package/dist/lib/region-detection.js +140 -199
- package/dist/lib/region-detection.js.map +1 -1
- package/dist/lib/region-registry.d.ts +49 -0
- package/dist/lib/region-registry.d.ts.map +1 -0
- package/dist/lib/region-registry.js +112 -0
- package/dist/lib/region-registry.js.map +1 -0
- package/dist/lib/relationship-handler.d.ts +9 -9
- package/dist/lib/relationship-handler.d.ts.map +1 -1
- package/dist/lib/relationship-handler.js +12 -49
- package/dist/lib/relationship-handler.js.map +1 -1
- package/dist/lib/request-context.d.ts +16 -16
- package/dist/lib/request-context.d.ts.map +1 -1
- package/dist/lib/request-context.js +14 -22
- package/dist/lib/request-context.js.map +1 -1
- package/dist/lib/route-helpers.d.ts +3 -4
- package/dist/lib/route-helpers.d.ts.map +1 -1
- package/dist/lib/route-helpers.js +20 -75
- package/dist/lib/route-helpers.js.map +1 -1
- package/dist/lib/routes/activitypub/actor.d.ts +1 -1
- package/dist/lib/routes/activitypub/actor.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/actor.js +20 -23
- package/dist/lib/routes/activitypub/actor.js.map +1 -1
- package/dist/lib/routes/activitypub/audiences.d.ts +1 -1
- package/dist/lib/routes/activitypub/audiences.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/audiences.js +76 -80
- package/dist/lib/routes/activitypub/audiences.js.map +1 -1
- package/dist/lib/routes/activitypub/collections.d.ts +1 -1
- package/dist/lib/routes/activitypub/collections.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/collections.js +24 -26
- package/dist/lib/routes/activitypub/collections.js.map +1 -1
- package/dist/lib/routes/activitypub/entity-profile.d.ts +1 -1
- package/dist/lib/routes/activitypub/entity-profile.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/entity-profile.js +36 -39
- package/dist/lib/routes/activitypub/entity-profile.js.map +1 -1
- package/dist/lib/routes/activitypub/friends.d.ts +1 -1
- package/dist/lib/routes/activitypub/friends.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/friends.js +9 -12
- package/dist/lib/routes/activitypub/friends.js.map +1 -1
- package/dist/lib/routes/activitypub/group.d.ts +1 -1
- package/dist/lib/routes/activitypub/group.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/group.js +91 -94
- package/dist/lib/routes/activitypub/group.js.map +1 -1
- package/dist/lib/routes/activitypub/inbox.d.ts +1 -1
- package/dist/lib/routes/activitypub/inbox.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/inbox.js +30 -33
- package/dist/lib/routes/activitypub/inbox.js.map +1 -1
- package/dist/lib/routes/activitypub/messages.d.ts +1 -1
- package/dist/lib/routes/activitypub/messages.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/messages.js +79 -83
- package/dist/lib/routes/activitypub/messages.js.map +1 -1
- package/dist/lib/routes/activitypub/outbox.d.ts +1 -1
- package/dist/lib/routes/activitypub/outbox.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/outbox.js +9 -12
- package/dist/lib/routes/activitypub/outbox.js.map +1 -1
- package/dist/lib/routes/activitypub/post.d.ts +1 -1
- package/dist/lib/routes/activitypub/post.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/post.js +32 -35
- package/dist/lib/routes/activitypub/post.js.map +1 -1
- package/dist/lib/routes/activitypub/webfinger.d.ts +1 -1
- package/dist/lib/routes/activitypub/webfinger.d.ts.map +1 -1
- package/dist/lib/routes/activitypub/webfinger.js +5 -8
- package/dist/lib/routes/activitypub/webfinger.js.map +1 -1
- package/dist/lib/routes/admin-costs.d.ts +1 -1
- package/dist/lib/routes/admin-costs.d.ts.map +1 -1
- package/dist/lib/routes/admin-costs.js +22 -26
- package/dist/lib/routes/admin-costs.js.map +1 -1
- package/dist/lib/routes/admin.d.ts +1 -1
- package/dist/lib/routes/admin.d.ts.map +1 -1
- package/dist/lib/routes/admin.js +290 -269
- package/dist/lib/routes/admin.js.map +1 -1
- package/dist/lib/routes/agent-authorize.d.ts +5 -5
- package/dist/lib/routes/agent-authorize.d.ts.map +1 -1
- package/dist/lib/routes/agent-authorize.js +68 -74
- package/dist/lib/routes/agent-authorize.js.map +1 -1
- package/dist/lib/routes/agent-sessions.d.ts +4 -4
- package/dist/lib/routes/agent-sessions.d.ts.map +1 -1
- package/dist/lib/routes/agent-sessions.js +30 -35
- package/dist/lib/routes/agent-sessions.js.map +1 -1
- package/dist/lib/routes/agent-surface.d.ts +2 -2
- package/dist/lib/routes/agent-surface.d.ts.map +1 -1
- package/dist/lib/routes/agent-surface.js +20 -24
- package/dist/lib/routes/agent-surface.js.map +1 -1
- package/dist/lib/routes/auth-discover.d.ts +1 -1
- package/dist/lib/routes/auth-discover.d.ts.map +1 -1
- package/dist/lib/routes/auth-discover.js +20 -56
- package/dist/lib/routes/auth-discover.js.map +1 -1
- package/dist/lib/routes/auth.d.ts +1 -1
- package/dist/lib/routes/auth.d.ts.map +1 -1
- package/dist/lib/routes/auth.js +13 -16
- package/dist/lib/routes/auth.js.map +1 -1
- package/dist/lib/routes/badges.d.ts +1 -1
- package/dist/lib/routes/badges.d.ts.map +1 -1
- package/dist/lib/routes/badges.js +20 -23
- package/dist/lib/routes/badges.js.map +1 -1
- package/dist/lib/routes/circles.d.ts +1 -1
- package/dist/lib/routes/circles.d.ts.map +1 -1
- package/dist/lib/routes/circles.js +40 -44
- package/dist/lib/routes/circles.js.map +1 -1
- package/dist/lib/routes/comments.d.ts +1 -1
- package/dist/lib/routes/comments.d.ts.map +1 -1
- package/dist/lib/routes/comments.js +67 -71
- package/dist/lib/routes/comments.js.map +1 -1
- package/dist/lib/routes/connection-codes.d.ts +1 -1
- package/dist/lib/routes/connection-codes.d.ts.map +1 -1
- package/dist/lib/routes/connection-codes.js +30 -34
- package/dist/lib/routes/connection-codes.js.map +1 -1
- package/dist/lib/routes/content-discovery.d.ts +1 -1
- package/dist/lib/routes/content-discovery.d.ts.map +1 -1
- package/dist/lib/routes/content-discovery.js +31 -34
- package/dist/lib/routes/content-discovery.js.map +1 -1
- package/dist/lib/routes/dashboard.d.ts +1 -1
- package/dist/lib/routes/dashboard.d.ts.map +1 -1
- package/dist/lib/routes/dashboard.js +251 -288
- package/dist/lib/routes/dashboard.js.map +1 -1
- package/dist/lib/routes/deletion.d.ts +1 -1
- package/dist/lib/routes/deletion.d.ts.map +1 -1
- package/dist/lib/routes/deletion.js +37 -74
- package/dist/lib/routes/deletion.js.map +1 -1
- package/dist/lib/routes/discovery.d.ts +1 -1
- package/dist/lib/routes/discovery.d.ts.map +1 -1
- package/dist/lib/routes/discovery.js +20 -24
- package/dist/lib/routes/discovery.js.map +1 -1
- package/dist/lib/routes/employees.d.ts +1 -1
- package/dist/lib/routes/employees.d.ts.map +1 -1
- package/dist/lib/routes/employees.js +15 -52
- package/dist/lib/routes/employees.js.map +1 -1
- package/dist/lib/routes/entities.d.ts +1 -1
- package/dist/lib/routes/entities.d.ts.map +1 -1
- package/dist/lib/routes/entities.js +133 -137
- package/dist/lib/routes/entities.js.map +1 -1
- package/dist/lib/routes/entity-relationships.d.ts +1 -1
- package/dist/lib/routes/entity-relationships.d.ts.map +1 -1
- package/dist/lib/routes/entity-relationships.js +35 -39
- package/dist/lib/routes/entity-relationships.js.map +1 -1
- package/dist/lib/routes/errors.d.ts +1 -1
- package/dist/lib/routes/errors.d.ts.map +1 -1
- package/dist/lib/routes/errors.js +4 -10
- package/dist/lib/routes/errors.js.map +1 -1
- package/dist/lib/routes/export.d.ts +1 -1
- package/dist/lib/routes/export.d.ts.map +1 -1
- package/dist/lib/routes/export.js +31 -35
- package/dist/lib/routes/export.js.map +1 -1
- package/dist/lib/routes/feature-flags.d.ts +1 -1
- package/dist/lib/routes/feature-flags.d.ts.map +1 -1
- package/dist/lib/routes/feature-flags.js +20 -23
- package/dist/lib/routes/feature-flags.js.map +1 -1
- package/dist/lib/routes/feeds.d.ts +1 -1
- package/dist/lib/routes/feeds.d.ts.map +1 -1
- package/dist/lib/routes/feeds.js +42 -46
- package/dist/lib/routes/feeds.js.map +1 -1
- package/dist/lib/routes/friends.d.ts +1 -1
- package/dist/lib/routes/friends.d.ts.map +1 -1
- package/dist/lib/routes/friends.js +35 -39
- package/dist/lib/routes/friends.js.map +1 -1
- package/dist/lib/routes/health.d.ts +1 -1
- package/dist/lib/routes/health.d.ts.map +1 -1
- package/dist/lib/routes/health.js +23 -27
- package/dist/lib/routes/health.js.map +1 -1
- package/dist/lib/routes/index.d.ts +2 -7
- package/dist/lib/routes/index.d.ts.map +1 -1
- package/dist/lib/routes/index.js +137 -158
- package/dist/lib/routes/index.js.map +1 -1
- package/dist/lib/routes/internal-docs.d.ts +1 -1
- package/dist/lib/routes/internal-docs.d.ts.map +1 -1
- package/dist/lib/routes/internal-docs.js +13 -16
- package/dist/lib/routes/internal-docs.js.map +1 -1
- package/dist/lib/routes/invitations.d.ts +1 -1
- package/dist/lib/routes/invitations.d.ts.map +1 -1
- package/dist/lib/routes/invitations.js +19 -22
- package/dist/lib/routes/invitations.js.map +1 -1
- package/dist/lib/routes/link-reports.d.ts +2 -2
- package/dist/lib/routes/link-reports.d.ts.map +1 -1
- package/dist/lib/routes/link-reports.js +86 -48
- package/dist/lib/routes/link-reports.js.map +1 -1
- package/dist/lib/routes/map.d.ts +1 -1
- package/dist/lib/routes/map.d.ts.map +1 -1
- package/dist/lib/routes/map.js +5 -8
- package/dist/lib/routes/map.js.map +1 -1
- package/dist/lib/routes/media-metadata-visibility.d.ts +1 -1
- package/dist/lib/routes/media-metadata-visibility.d.ts.map +1 -1
- package/dist/lib/routes/media-metadata-visibility.js +30 -67
- package/dist/lib/routes/media-metadata-visibility.js.map +1 -1
- package/dist/lib/routes/media.d.ts +1 -1
- package/dist/lib/routes/media.d.ts.map +1 -1
- package/dist/lib/routes/media.js +156 -193
- package/dist/lib/routes/media.js.map +1 -1
- package/dist/lib/routes/mfa.d.ts +1 -1
- package/dist/lib/routes/mfa.d.ts.map +1 -1
- package/dist/lib/routes/mfa.js +60 -64
- package/dist/lib/routes/mfa.js.map +1 -1
- package/dist/lib/routes/notifications.d.ts +1 -1
- package/dist/lib/routes/notifications.d.ts.map +1 -1
- package/dist/lib/routes/notifications.js +68 -72
- package/dist/lib/routes/notifications.js.map +1 -1
- package/dist/lib/routes/oauth.d.ts +1 -1
- package/dist/lib/routes/oauth.d.ts.map +1 -1
- package/dist/lib/routes/oauth.js +20 -23
- package/dist/lib/routes/oauth.js.map +1 -1
- package/dist/lib/routes/orphaned-media-health.d.ts +1 -1
- package/dist/lib/routes/orphaned-media-health.d.ts.map +1 -1
- package/dist/lib/routes/orphaned-media-health.js +10 -13
- package/dist/lib/routes/orphaned-media-health.js.map +1 -1
- package/dist/lib/routes/orphaned-media.d.ts +1 -1
- package/dist/lib/routes/orphaned-media.d.ts.map +1 -1
- package/dist/lib/routes/orphaned-media.js +20 -57
- package/dist/lib/routes/orphaned-media.js.map +1 -1
- package/dist/lib/routes/out.d.ts +1 -1
- package/dist/lib/routes/out.d.ts.map +1 -1
- package/dist/lib/routes/out.js +21 -24
- package/dist/lib/routes/out.js.map +1 -1
- package/dist/lib/routes/parental-controls.d.ts +1 -1
- package/dist/lib/routes/parental-controls.d.ts.map +1 -1
- package/dist/lib/routes/parental-controls.js +91 -95
- package/dist/lib/routes/parental-controls.js.map +1 -1
- package/dist/lib/routes/posts.d.ts +1 -1
- package/dist/lib/routes/posts.d.ts.map +1 -1
- package/dist/lib/routes/posts.js +101 -105
- package/dist/lib/routes/posts.js.map +1 -1
- package/dist/lib/routes/privacy.d.ts +1 -1
- package/dist/lib/routes/privacy.d.ts.map +1 -1
- package/dist/lib/routes/privacy.js +21 -25
- package/dist/lib/routes/privacy.js.map +1 -1
- package/dist/lib/routes/products.d.ts +1 -1
- package/dist/lib/routes/products.d.ts.map +1 -1
- package/dist/lib/routes/products.js +44 -48
- package/dist/lib/routes/products.js.map +1 -1
- package/dist/lib/routes/relationships.d.ts +1 -1
- package/dist/lib/routes/relationships.d.ts.map +1 -1
- package/dist/lib/routes/relationships.js +35 -39
- package/dist/lib/routes/relationships.js.map +1 -1
- package/dist/lib/routes/sentiments.d.ts +1 -1
- package/dist/lib/routes/sentiments.d.ts.map +1 -1
- package/dist/lib/routes/sentiments.js +71 -75
- package/dist/lib/routes/sentiments.js.map +1 -1
- package/dist/lib/routes/setup-status.d.ts +1 -1
- package/dist/lib/routes/setup-status.d.ts.map +1 -1
- package/dist/lib/routes/setup-status.js +17 -20
- package/dist/lib/routes/setup-status.js.map +1 -1
- package/dist/lib/routes/taxonomy-analytics.d.ts +1 -1
- package/dist/lib/routes/taxonomy-analytics.d.ts.map +1 -1
- package/dist/lib/routes/taxonomy-analytics.js +29 -33
- package/dist/lib/routes/taxonomy-analytics.js.map +1 -1
- package/dist/lib/routes/taxonomy.d.ts +1 -1
- package/dist/lib/routes/taxonomy.d.ts.map +1 -1
- package/dist/lib/routes/taxonomy.js +48 -51
- package/dist/lib/routes/taxonomy.js.map +1 -1
- package/dist/lib/routes/tenant-audit.d.ts +1 -1
- package/dist/lib/routes/tenant-audit.d.ts.map +1 -1
- package/dist/lib/routes/tenant-audit.js +35 -92
- package/dist/lib/routes/tenant-audit.js.map +1 -1
- package/dist/lib/routes/tenant-compliance.d.ts +1 -1
- package/dist/lib/routes/tenant-compliance.d.ts.map +1 -1
- package/dist/lib/routes/tenant-compliance.js +16 -52
- package/dist/lib/routes/tenant-compliance.js.map +1 -1
- package/dist/lib/routes/tenant-domains.d.ts +1 -1
- package/dist/lib/routes/tenant-domains.d.ts.map +1 -1
- package/dist/lib/routes/tenant-domains.js +27 -30
- package/dist/lib/routes/tenant-domains.js.map +1 -1
- package/dist/lib/routes/tenant-idp.d.ts +1 -1
- package/dist/lib/routes/tenant-idp.d.ts.map +1 -1
- package/dist/lib/routes/tenant-idp.js +27 -30
- package/dist/lib/routes/tenant-idp.js.map +1 -1
- package/dist/lib/routes/tenant-members.d.ts +1 -1
- package/dist/lib/routes/tenant-members.d.ts.map +1 -1
- package/dist/lib/routes/tenant-members.js +21 -24
- package/dist/lib/routes/tenant-members.js.map +1 -1
- package/dist/lib/routes/tenant-role-mappings.d.ts +1 -1
- package/dist/lib/routes/tenant-role-mappings.d.ts.map +1 -1
- package/dist/lib/routes/tenant-role-mappings.js +27 -30
- package/dist/lib/routes/tenant-role-mappings.js.map +1 -1
- package/dist/lib/routes/tenants.d.ts +1 -1
- package/dist/lib/routes/tenants.d.ts.map +1 -1
- package/dist/lib/routes/tenants.js +37 -40
- package/dist/lib/routes/tenants.js.map +1 -1
- package/dist/lib/routes/types.d.ts +10 -5
- package/dist/lib/routes/types.d.ts.map +1 -1
- package/dist/lib/routes/types.js +1 -2
- package/dist/lib/routes/types.js.map +1 -1
- package/dist/lib/routes/upload-sessions.d.ts +1 -1
- package/dist/lib/routes/upload-sessions.d.ts.map +1 -1
- package/dist/lib/routes/upload-sessions.js +57 -94
- package/dist/lib/routes/upload-sessions.js.map +1 -1
- package/dist/lib/routes/user.d.ts +1 -1
- package/dist/lib/routes/user.d.ts.map +1 -1
- package/dist/lib/routes/user.js +137 -85
- package/dist/lib/routes/user.js.map +1 -1
- package/dist/lib/routes.d.ts +2 -2
- package/dist/lib/routes.d.ts.map +1 -1
- package/dist/lib/routes.js +2 -7
- package/dist/lib/routes.js.map +1 -1
- package/dist/lib/scaling-health.d.ts.map +1 -1
- package/dist/lib/scaling-health.js +6 -9
- package/dist/lib/scaling-health.js.map +1 -1
- package/dist/lib/scheduled/media-stale-cleanup.js +5 -8
- package/dist/lib/scheduled/media-stale-cleanup.js.map +1 -1
- package/dist/lib/scheduled/orphaned-media-monitor.d.ts +1 -1
- package/dist/lib/scheduled/orphaned-media-monitor.d.ts.map +1 -1
- package/dist/lib/scheduled/orphaned-media-monitor.js +5 -42
- package/dist/lib/scheduled/orphaned-media-monitor.js.map +1 -1
- package/dist/lib/schemas.d.ts +85 -204
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +71 -74
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/secrets/idp-secrets.d.ts +1 -1
- package/dist/lib/secrets/idp-secrets.js +13 -19
- package/dist/lib/secrets/idp-secrets.js.map +1 -1
- package/dist/lib/security-event-cleaner.js +1 -5
- package/dist/lib/security-event-cleaner.js.map +1 -1
- package/dist/lib/security-headers.js +1 -5
- package/dist/lib/security-headers.js.map +1 -1
- package/dist/lib/security-monitor.d.ts +4 -2
- package/dist/lib/security-monitor.d.ts.map +1 -1
- package/dist/lib/security-monitor.js +16 -18
- package/dist/lib/security-monitor.js.map +1 -1
- package/dist/lib/sentiment-digest.d.ts +1 -1
- package/dist/lib/sentiment-digest.d.ts.map +1 -1
- package/dist/lib/sentiment-digest.js +5 -8
- package/dist/lib/sentiment-digest.js.map +1 -1
- package/dist/lib/sentiment-display.js +3 -7
- package/dist/lib/sentiment-display.js.map +1 -1
- package/dist/lib/services/image-normalizer.js +1 -5
- package/dist/lib/services/image-normalizer.js.map +1 -1
- package/dist/lib/services/media-reconciliation-service.d.ts +1 -1
- package/dist/lib/services/media-reconciliation-service.d.ts.map +1 -1
- package/dist/lib/services/media-reconciliation-service.js +7 -11
- package/dist/lib/services/media-reconciliation-service.js.map +1 -1
- package/dist/lib/services/media-upload-service.d.ts +1 -1
- package/dist/lib/services/media-upload-service.d.ts.map +1 -1
- package/dist/lib/services/media-upload-service.js +4 -8
- package/dist/lib/services/media-upload-service.js.map +1 -1
- package/dist/lib/services/user-data-deletion.d.ts +45 -2
- package/dist/lib/services/user-data-deletion.d.ts.map +1 -1
- package/dist/lib/services/user-data-deletion.js +87 -9
- package/dist/lib/services/user-data-deletion.js.map +1 -1
- package/dist/lib/session-awareness.js +2 -6
- package/dist/lib/session-awareness.js.map +1 -1
- package/dist/lib/session-config.js +8 -17
- package/dist/lib/session-config.js.map +1 -1
- package/dist/lib/{session-manager.d.ts → session-cookie.d.ts} +58 -15
- package/dist/lib/session-cookie.d.ts.map +1 -0
- package/dist/lib/session-cookie.js +0 -0
- package/dist/lib/session-cookie.js.map +1 -0
- package/dist/lib/signup-metadata.d.ts +129 -0
- package/dist/lib/signup-metadata.d.ts.map +1 -0
- package/dist/lib/signup-metadata.js +127 -0
- package/dist/lib/signup-metadata.js.map +1 -0
- package/dist/lib/sso-auth-handler.js +1 -5
- package/dist/lib/sso-auth-handler.js.map +1 -1
- package/dist/lib/tag-suggestions-handler.d.ts +1 -1
- package/dist/lib/tag-suggestions-handler.d.ts.map +1 -1
- package/dist/lib/tag-suggestions-handler.js +1 -5
- package/dist/lib/tag-suggestions-handler.js.map +1 -1
- package/dist/lib/taxonomy-handler-factory.d.ts +2 -2
- package/dist/lib/taxonomy-handler-factory.d.ts.map +1 -1
- package/dist/lib/taxonomy-handler-factory.js +7 -10
- package/dist/lib/taxonomy-handler-factory.js.map +1 -1
- package/dist/lib/taxonomy-handler.d.ts +2 -2
- package/dist/lib/taxonomy-handler.d.ts.map +1 -1
- package/dist/lib/taxonomy-handler.js +8 -8
- package/dist/lib/taxonomy-handler.js.map +1 -1
- package/dist/lib/taxonomy-metrics.js +5 -9
- package/dist/lib/taxonomy-metrics.js.map +1 -1
- package/dist/lib/taxonomy-search-metrics.d.ts +2 -2
- package/dist/lib/taxonomy-search-metrics.d.ts.map +1 -1
- package/dist/lib/taxonomy-search-metrics.js +3 -7
- package/dist/lib/taxonomy-search-metrics.js.map +1 -1
- package/dist/lib/tenant/audit-emit.d.ts +18 -8
- package/dist/lib/tenant/audit-emit.d.ts.map +1 -1
- package/dist/lib/tenant/audit-emit.js +50 -11
- package/dist/lib/tenant/audit-emit.js.map +1 -1
- package/dist/lib/tenant/derive-domain.js +1 -4
- package/dist/lib/tenant/derive-domain.js.map +1 -1
- package/dist/lib/tenant/domain-handler.d.ts +2 -2
- package/dist/lib/tenant/domain-handler.d.ts.map +1 -1
- package/dist/lib/tenant/domain-handler.js +50 -62
- package/dist/lib/tenant/domain-handler.js.map +1 -1
- package/dist/lib/tenant/domain-validator.d.ts +1 -1
- package/dist/lib/tenant/domain-validator.js +10 -13
- package/dist/lib/tenant/domain-validator.js.map +1 -1
- package/dist/lib/tenant/domain-verifier.d.ts +3 -3
- package/dist/lib/tenant/domain-verifier.js +8 -11
- package/dist/lib/tenant/domain-verifier.js.map +1 -1
- package/dist/lib/tenant/idp-handler.d.ts +4 -4
- package/dist/lib/tenant/idp-handler.d.ts.map +1 -1
- package/dist/lib/tenant/idp-handler.js +45 -82
- package/dist/lib/tenant/idp-handler.js.map +1 -1
- package/dist/lib/tenant/idp-name.js +1 -4
- package/dist/lib/tenant/idp-name.js.map +1 -1
- package/dist/lib/tenant/member-handler.d.ts +2 -2
- package/dist/lib/tenant/member-handler.d.ts.map +1 -1
- package/dist/lib/tenant/member-handler.js +30 -67
- package/dist/lib/tenant/member-handler.js.map +1 -1
- package/dist/lib/tenant/reserved-slugs.d.ts +1 -1
- package/dist/lib/tenant/reserved-slugs.d.ts.map +1 -1
- package/dist/lib/tenant/reserved-slugs.js +8 -14
- package/dist/lib/tenant/reserved-slugs.js.map +1 -1
- package/dist/lib/tenant/resolve-role.js +1 -4
- package/dist/lib/tenant/resolve-role.js.map +1 -1
- package/dist/lib/tenant/role-mapping-handler.d.ts +2 -2
- package/dist/lib/tenant/role-mapping-handler.d.ts.map +1 -1
- package/dist/lib/tenant/role-mapping-handler.js +24 -61
- package/dist/lib/tenant/role-mapping-handler.js.map +1 -1
- package/dist/lib/tenant/setup-status.d.ts +1 -1
- package/dist/lib/tenant/setup-status.d.ts.map +1 -1
- package/dist/lib/tenant/setup-status.js +3 -40
- package/dist/lib/tenant/setup-status.js.map +1 -1
- package/dist/lib/tenant/slug-validator.js +3 -6
- package/dist/lib/tenant/slug-validator.js.map +1 -1
- package/dist/lib/tenant/tenant-handler.d.ts +2 -2
- package/dist/lib/tenant/tenant-handler.d.ts.map +1 -1
- package/dist/lib/tenant/tenant-handler.js +31 -68
- package/dist/lib/tenant/tenant-handler.js.map +1 -1
- package/dist/lib/tenant/transfer-ownership.js +2 -6
- package/dist/lib/tenant/transfer-ownership.js.map +1 -1
- package/dist/lib/tenant-scope.d.ts +97 -0
- package/dist/lib/tenant-scope.d.ts.map +1 -0
- package/dist/lib/tenant-scope.js +270 -0
- package/dist/lib/tenant-scope.js.map +1 -0
- package/dist/lib/terminology.d.ts.map +1 -1
- package/dist/lib/terminology.js +7 -9
- package/dist/lib/terminology.js.map +1 -1
- package/dist/lib/theme.js +2 -6
- package/dist/lib/theme.js.map +1 -1
- package/dist/lib/threat-intel-service.d.ts +2 -2
- package/dist/lib/threat-intel-service.d.ts.map +1 -1
- package/dist/lib/threat-intel-service.js +3 -7
- package/dist/lib/threat-intel-service.js.map +1 -1
- package/dist/lib/types/media-reconciliation.js +1 -2
- package/dist/lib/types/media-reconciliation.js.map +1 -1
- package/dist/lib/upload-session-handler.d.ts +1 -1
- package/dist/lib/upload-session-handler.d.ts.map +1 -1
- package/dist/lib/upload-session-handler.js +13 -50
- package/dist/lib/upload-session-handler.js.map +1 -1
- package/dist/lib/user/derive-handle.js +2 -6
- package/dist/lib/user/derive-handle.js.map +1 -1
- package/dist/lib/user-badge.js +6 -14
- package/dist/lib/user-badge.js.map +1 -1
- package/dist/lib/user-deletion-handler-enhanced.d.ts +2 -2
- package/dist/lib/user-deletion-handler-enhanced.d.ts.map +1 -1
- package/dist/lib/user-deletion-handler-enhanced.js +16 -53
- package/dist/lib/user-deletion-handler-enhanced.js.map +1 -1
- package/dist/lib/user-deprovisioning.d.ts +1 -1
- package/dist/lib/user-deprovisioning.d.ts.map +1 -1
- package/dist/lib/user-deprovisioning.js +16 -20
- package/dist/lib/user-deprovisioning.js.map +1 -1
- package/dist/lib/user-export-handler.d.ts +4 -4
- package/dist/lib/user-export-handler.d.ts.map +1 -1
- package/dist/lib/user-export-handler.js +11 -15
- package/dist/lib/user-export-handler.js.map +1 -1
- package/dist/lib/validate-request.js +8 -13
- package/dist/lib/validate-request.js.map +1 -1
- package/dist/lib/validation/feature-toggle-schemas.d.ts +130 -249
- package/dist/lib/validation/feature-toggle-schemas.d.ts.map +1 -1
- package/dist/lib/validation/feature-toggle-schemas.js +50 -59
- package/dist/lib/validation/feature-toggle-schemas.js.map +1 -1
- package/dist/lib/validation/validate-request.d.ts.map +1 -1
- package/dist/lib/validation/validate-request.js +12 -23
- package/dist/lib/validation/validate-request.js.map +1 -1
- package/dist/lib/validation.js +1 -5
- package/dist/lib/validation.js.map +1 -1
- package/dist/lib/version.js +3 -8
- package/dist/lib/version.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +29 -69
- package/dist/server.js.map +1 -1
- package/dist/types/cloudflare-compat.d.ts +3 -93
- package/dist/types/cloudflare-compat.d.ts.map +1 -1
- package/dist/types/cloudflare-compat.js +1 -2
- package/dist/types/cloudflare-compat.js.map +1 -1
- package/dist/worker.d.ts +6 -6
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +6 -13
- package/dist/worker.js.map +1 -1
- package/package.json +30 -17
- package/prisma/migrations/20260602054730_add_entity_geo_and_pending_schema/migration.sql +113 -0
- package/prisma/migrations/20260602162901_research_foundations/migration.sql +65 -0
- package/prisma/migrations/20260604130000_surveillance_phase0_enablers/migration.sql +107 -0
- package/prisma/migrations/20260604140000_fold_link_reports_into_reports/migration.sql +23 -0
- package/prisma/migrations/20260604140000_fold_link_reports_into_reports/rollback.reference.sql +31 -0
- package/prisma/schema.prisma +419 -68
- package/src/lambda/cleanup-cron.ts +10 -7
- package/src/lambda/create-auth-challenge.ts +6 -3
- package/src/lambda/delete-account-worker.ts +17 -12
- package/src/lambda/diagnostics-proxy.ts +9 -6
- package/src/lambda/e2e-sweeper.ts +17 -23
- package/src/lambda/federation-outbox-worker.ts +4 -1
- package/src/lambda/followers-events-worker.ts +4 -1
- package/src/lambda/hourly-cron.ts +112 -20
- package/src/lambda/link-check-worker.ts +4 -1
- package/src/lambda/maintenance-cron.ts +24 -13
- package/src/lambda/media-processing-worker.ts +5 -2
- package/src/lambda/media-reconciliation-worker.ts +4 -1
- package/src/lambda/nightly-cron.ts +53 -54
- package/src/lambda/post-confirmation.ts +188 -62
- package/src/lambda/pre-token-generation.ts +39 -44
- package/src/lambda/verify-auth-challenge.ts +4 -1
- package/dist/lib/audit/emit.d.ts +0 -56
- package/dist/lib/audit/emit.d.ts.map +0 -1
- package/dist/lib/audit/emit.js +0 -124
- package/dist/lib/audit/emit.js.map +0 -1
- package/dist/lib/audit/event-types.d.ts +0 -36
- package/dist/lib/audit/event-types.d.ts.map +0 -1
- package/dist/lib/audit/event-types.js +0 -69
- package/dist/lib/audit/event-types.js.map +0 -1
- package/dist/lib/audit-logger.d.ts +0 -142
- package/dist/lib/audit-logger.d.ts.map +0 -1
- package/dist/lib/audit-logger.js +0 -326
- package/dist/lib/audit-logger.js.map +0 -1
- package/dist/lib/circuit-breaker.d.ts +0 -27
- package/dist/lib/circuit-breaker.d.ts.map +0 -1
- package/dist/lib/circuit-breaker.js +0 -63
- package/dist/lib/circuit-breaker.js.map +0 -1
- package/dist/lib/graph/dual-write-service.d.ts +0 -116
- package/dist/lib/graph/dual-write-service.d.ts.map +0 -1
- package/dist/lib/graph/dual-write-service.js +0 -332
- package/dist/lib/graph/dual-write-service.js.map +0 -1
- package/dist/lib/graph/dual-write.d.ts +0 -396
- package/dist/lib/graph/dual-write.d.ts.map +0 -1
- package/dist/lib/graph/dual-write.js +0 -53
- package/dist/lib/graph/dual-write.js.map +0 -1
- package/dist/lib/graph/graph-schema-init.d.ts +0 -31
- package/dist/lib/graph/graph-schema-init.d.ts.map +0 -1
- package/dist/lib/graph/graph-schema-init.js +0 -105
- package/dist/lib/graph/graph-schema-init.js.map +0 -1
- package/dist/lib/graph/neo4j-graph-service.d.ts +0 -186
- package/dist/lib/graph/neo4j-graph-service.d.ts.map +0 -1
- package/dist/lib/graph/neo4j-graph-service.js +0 -1625
- package/dist/lib/graph/neo4j-graph-service.js.map +0 -1
- package/dist/lib/graph/reconciliation-service.d.ts +0 -113
- package/dist/lib/graph/reconciliation-service.d.ts.map +0 -1
- package/dist/lib/graph/reconciliation-service.js +0 -533
- package/dist/lib/graph/reconciliation-service.js.map +0 -1
- package/dist/lib/id-generator.d.ts +0 -29
- package/dist/lib/id-generator.d.ts.map +0 -1
- package/dist/lib/id-generator.js +0 -51
- package/dist/lib/id-generator.js.map +0 -1
- package/dist/lib/kv/dynamodb-kv.d.ts +0 -39
- package/dist/lib/kv/dynamodb-kv.d.ts.map +0 -1
- package/dist/lib/kv/dynamodb-kv.js +0 -239
- package/dist/lib/kv/dynamodb-kv.js.map +0 -1
- package/dist/lib/queue/sqs-queue.d.ts +0 -16
- package/dist/lib/queue/sqs-queue.d.ts.map +0 -1
- package/dist/lib/queue/sqs-queue.js +0 -39
- package/dist/lib/queue/sqs-queue.js.map +0 -1
- package/dist/lib/route-matcher.d.ts +0 -24
- package/dist/lib/route-matcher.d.ts.map +0 -1
- package/dist/lib/route-matcher.js +0 -96
- package/dist/lib/route-matcher.js.map +0 -1
- package/dist/lib/router.d.ts +0 -26
- package/dist/lib/router.d.ts.map +0 -1
- package/dist/lib/router.js +0 -90
- package/dist/lib/router.js.map +0 -1
- package/dist/lib/routes-all.d.ts +0 -9
- package/dist/lib/routes-all.d.ts.map +0 -1
- package/dist/lib/routes-all.js +0 -170
- package/dist/lib/routes-all.js.map +0 -1
- package/dist/lib/secret-resolver.d.ts +0 -88
- package/dist/lib/secret-resolver.d.ts.map +0 -1
- package/dist/lib/secret-resolver.js +0 -183
- package/dist/lib/secret-resolver.js.map +0 -1
- package/dist/lib/session-manager.d.ts.map +0 -1
- package/dist/lib/session-manager.js +0 -492
- package/dist/lib/session-manager.js.map +0 -1
- package/dist/lib/storage/s3-storage.d.ts +0 -29
- package/dist/lib/storage/s3-storage.d.ts.map +0 -1
- package/dist/lib/storage/s3-storage.js +0 -135
- package/dist/lib/storage/s3-storage.js.map +0 -1
- package/dist/lib/tenant-context.d.ts +0 -35
- package/dist/lib/tenant-context.d.ts.map +0 -1
- package/dist/lib/tenant-context.js +0 -54
- package/dist/lib/tenant-context.js.map +0 -1
package/dist/lib/routes/admin.js
CHANGED
|
@@ -1,69 +1,32 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Admin Routes
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.adminRoutes = void 0;
|
|
40
|
-
const zod_1 = require("zod");
|
|
41
|
-
const db_1 = require("../../db");
|
|
42
|
-
const worker_1 = require("../../worker");
|
|
43
|
-
const data_router_1 = require("../data-router");
|
|
44
|
-
const database_connection_manager_1 = require("../database-connection-manager");
|
|
45
|
-
const db_query_helper_1 = require("../db-query-helper");
|
|
46
|
-
const domain_reputation_service_1 = require("../domain-reputation-service");
|
|
47
|
-
const feature_toggle_service_1 = require("../feature-toggle-service");
|
|
48
|
-
const logger_1 = require("../logger");
|
|
49
|
-
const middleware_1 = require("../middleware");
|
|
50
|
-
const feature_toggle_rate_limit_1 = require("../middleware/feature-toggle-rate-limit");
|
|
51
|
-
const region_detection_1 = require("../region-detection");
|
|
52
|
-
const secret_resolver_1 = require("../secret-resolver");
|
|
53
|
-
const security_headers_1 = require("../security-headers");
|
|
54
|
-
const session_manager_1 = require("../session-manager");
|
|
55
|
-
const feature_toggle_schemas_1 = require("../validation/feature-toggle-schemas");
|
|
56
|
-
const validate_request_1 = require("../validation/validate-request");
|
|
57
|
-
const version_1 = require("../version");
|
|
58
|
-
exports.adminRoutes = [
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { createPrisma } from "../../db.js";
|
|
6
|
+
import { addCorsHeaders } from "../../worker.js";
|
|
7
|
+
import { DataRouter } from "../data-router.js";
|
|
8
|
+
import { sharedDatabaseConnectionManager } from "../database-connection-manager.js";
|
|
9
|
+
import { QueryTimeoutPresets, withQueryTimeoutAndRetry, } from "../db-query-helper.js";
|
|
10
|
+
import { DomainReputationService } from "../domain-reputation-service.js";
|
|
11
|
+
import { FeatureToggleService } from "../feature-toggle-service.js";
|
|
12
|
+
import { getLogger } from "../logger.js";
|
|
13
|
+
import { corsMiddleware, csrfMiddleware } from "../middleware.js";
|
|
14
|
+
import { rateLimitAdminFeatureToggleAPI, rateLimitFeatureToggleAPI, } from "../middleware/feature-toggle-rate-limit.js";
|
|
15
|
+
import { detectRegionSync } from "../region-detection.js";
|
|
16
|
+
import { SecurityHeaders } from "../security-headers.js";
|
|
17
|
+
import { SessionManager } from "../session-cookie.js";
|
|
18
|
+
import { FeatureToggleKeySchema, PublicAPIQuerySchema, } from "../validation/feature-toggle-schemas.js";
|
|
19
|
+
import { validateBody, validatePathParam, validateQuery, ValidationError, } from "../validation/validate-request.js";
|
|
20
|
+
import { getAppVersion } from "../version.js";
|
|
21
|
+
export const adminRoutes = [
|
|
59
22
|
// Test-only endpoints (must be before wildcard routes)
|
|
60
23
|
// Test-only endpoint: Create test user (dev environment only, no auth required for tests)
|
|
61
24
|
{
|
|
62
25
|
path: "/api/admin/test/users",
|
|
63
26
|
method: "POST",
|
|
64
27
|
handler: async (request, env) => {
|
|
65
|
-
const securityHeaders = new
|
|
66
|
-
const logger =
|
|
28
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
29
|
+
const logger = getLogger();
|
|
67
30
|
// SECURITY: Only allow in dev/test environments
|
|
68
31
|
// Note: env.ENVIRONMENT falls back to NODE_ENV (which is "production" in Docker),
|
|
69
32
|
// so prefer env.STAGE which is explicitly set by CDK to the deployment stage.
|
|
@@ -74,7 +37,7 @@ exports.adminRoutes = [
|
|
|
74
37
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
75
38
|
error: "Forbidden: Test endpoints not available in production",
|
|
76
39
|
}), { status: 403, headers: { "content-type": "application/json" } });
|
|
77
|
-
return
|
|
40
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
78
41
|
}
|
|
79
42
|
try {
|
|
80
43
|
const body = (await request.json());
|
|
@@ -97,19 +60,19 @@ exports.adminRoutes = [
|
|
|
97
60
|
// 2. Test users are identified by email pattern
|
|
98
61
|
// 3. Tests need fast user creation without authentication overhead
|
|
99
62
|
if (!isTestUser && !isCI) {
|
|
100
|
-
const sessionManager = new
|
|
101
|
-
const sessionSecret =
|
|
63
|
+
const sessionManager = new SessionManager();
|
|
64
|
+
const sessionSecret = env.SESSION_SECRET;
|
|
102
65
|
const session = await sessionManager.getSession(request, sessionSecret, env);
|
|
103
66
|
if (session) {
|
|
104
67
|
// Use fast query with timeout for role check (non-blocking for test user creation)
|
|
105
|
-
const detectedRegion =
|
|
106
|
-
const user = await
|
|
68
|
+
const detectedRegion = detectRegionSync(request, env);
|
|
69
|
+
const user = await withQueryTimeoutAndRetry(sharedDatabaseConnectionManager, detectedRegion, env, async (db) => {
|
|
107
70
|
return await db.user.findUnique({
|
|
108
71
|
where: { id: session.userId },
|
|
109
72
|
select: { role: true },
|
|
110
73
|
});
|
|
111
74
|
}, {
|
|
112
|
-
...
|
|
75
|
+
...QueryTimeoutPresets.USER_FACING, // Fast timeout (1s + 1s retry)
|
|
113
76
|
defaultValue: null, // Return null on timeout (allow test user creation)
|
|
114
77
|
context: {
|
|
115
78
|
operation: "checkUserRoleForTestEndpoint",
|
|
@@ -123,7 +86,7 @@ exports.adminRoutes = [
|
|
|
123
86
|
status: 403,
|
|
124
87
|
headers: { "content-type": "application/json" },
|
|
125
88
|
});
|
|
126
|
-
return
|
|
89
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
127
90
|
}
|
|
128
91
|
}
|
|
129
92
|
}
|
|
@@ -143,10 +106,18 @@ exports.adminRoutes = [
|
|
|
143
106
|
const maxExpectedDbTime = dbTimeoutMs + dbRetryTimeoutMs * dbMaxRetries;
|
|
144
107
|
const safetyBufferMs = Math.ceil(maxExpectedDbTime * 0.5); // 50% buffer
|
|
145
108
|
const TEST_USER_CREATION_TIMEOUT_MS = maxExpectedDbTime + safetyBufferMs;
|
|
146
|
-
|
|
109
|
+
// Signup-metadata (P3): this dev/test-only seam creates users with no
|
|
110
|
+
// real request context. It gets a `signupMethod` (COGNITO) via the
|
|
111
|
+
// choke-point helper but NO fabricated IP/UA and no SecurityEvent —
|
|
112
|
+
// synthetic test accounts must not pollute the signup-cohort signal.
|
|
113
|
+
const { signupUserData } = await import("../signup-metadata.js");
|
|
114
|
+
const signupFields = signupUserData({ method: "COGNITO" });
|
|
115
|
+
const userCreationPromise = DataRouter.createUser({
|
|
147
116
|
id: userId,
|
|
148
117
|
email,
|
|
149
118
|
role,
|
|
119
|
+
signupMethod: signupFields.signupMethod,
|
|
120
|
+
invitationId: signupFields.invitationId,
|
|
150
121
|
}, region, env, isTestUser ? undefined : request);
|
|
151
122
|
const timeoutPromise = new Promise((_, reject) => {
|
|
152
123
|
setTimeout(() => {
|
|
@@ -168,8 +139,8 @@ exports.adminRoutes = [
|
|
|
168
139
|
isTestUser,
|
|
169
140
|
});
|
|
170
141
|
// Create a session for the test user so tests don't need to know SESSION_SECRET
|
|
171
|
-
const sessionManager = new
|
|
172
|
-
const sessionSecret =
|
|
142
|
+
const sessionManager = new SessionManager();
|
|
143
|
+
const sessionSecret = env.SESSION_SECRET;
|
|
173
144
|
const testSession = {
|
|
174
145
|
userId: createdUser.id,
|
|
175
146
|
email: createdUser.email,
|
|
@@ -192,17 +163,17 @@ exports.adminRoutes = [
|
|
|
192
163
|
}), { status: 201, headers: { "content-type": "application/json" } });
|
|
193
164
|
// Set session cookie on the response
|
|
194
165
|
response = await sessionManager.setSession(response, testSession, sessionSecret, undefined, env);
|
|
195
|
-
return
|
|
166
|
+
return addCorsHeaders(response, request, env);
|
|
196
167
|
}
|
|
197
168
|
catch (error) {
|
|
198
169
|
logger.error("[Admin Test] Error creating test user:", error);
|
|
199
170
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
200
171
|
error: error.message || "Failed to create test user",
|
|
201
172
|
}), { status: 500, headers: { "content-type": "application/json" } });
|
|
202
|
-
return
|
|
173
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
203
174
|
}
|
|
204
175
|
},
|
|
205
|
-
middleware: [
|
|
176
|
+
middleware: [corsMiddleware()], // No CSRF for test endpoints (unauthenticated in CI)
|
|
206
177
|
description: "Create test user (dev environment only)",
|
|
207
178
|
},
|
|
208
179
|
// Test-only endpoint: Delete test user (dev environment only)
|
|
@@ -210,9 +181,9 @@ exports.adminRoutes = [
|
|
|
210
181
|
path: "/api/admin/test/users/:userId",
|
|
211
182
|
method: "DELETE",
|
|
212
183
|
handler: async (request, env, { pathname }) => {
|
|
213
|
-
const sessionManager = new
|
|
214
|
-
const securityHeaders = new
|
|
215
|
-
const logger =
|
|
184
|
+
const sessionManager = new SessionManager();
|
|
185
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
186
|
+
const logger = getLogger();
|
|
216
187
|
// SECURITY: Only allow in dev/test environments
|
|
217
188
|
// Note: env.ENVIRONMENT falls back to NODE_ENV (which is "production" in Docker),
|
|
218
189
|
// so prefer env.STAGE which is explicitly set by CDK to the deployment stage.
|
|
@@ -223,16 +194,16 @@ exports.adminRoutes = [
|
|
|
223
194
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
224
195
|
error: "Forbidden: Test endpoints not available in production",
|
|
225
196
|
}), { status: 403, headers: { "content-type": "application/json" } });
|
|
226
|
-
return
|
|
197
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
227
198
|
}
|
|
228
199
|
// SECURITY: In test mode (CI), allow unauthenticated access for test user deletion
|
|
229
200
|
const isCI = env.CI === "true" || env.GITHUB_ACTIONS === "true";
|
|
230
201
|
// Optionally check for SUPER_ADMIN in local dev (but allow unauthenticated in CI)
|
|
231
202
|
if (!isCI) {
|
|
232
|
-
const sessionSecret =
|
|
203
|
+
const sessionSecret = env.SESSION_SECRET;
|
|
233
204
|
const session = await sessionManager.getSession(request, sessionSecret, env);
|
|
234
205
|
if (session) {
|
|
235
|
-
const db =
|
|
206
|
+
const db = createPrisma(env);
|
|
236
207
|
const user = await db.user.findUnique({
|
|
237
208
|
where: { id: session.userId },
|
|
238
209
|
select: { role: true },
|
|
@@ -241,7 +212,7 @@ exports.adminRoutes = [
|
|
|
241
212
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
242
213
|
error: "Forbidden: Super-admin access required",
|
|
243
214
|
}), { status: 403, headers: { "content-type": "application/json" } });
|
|
244
|
-
return
|
|
215
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
245
216
|
}
|
|
246
217
|
}
|
|
247
218
|
// If no session in local dev, still allow (for test convenience)
|
|
@@ -250,18 +221,18 @@ exports.adminRoutes = [
|
|
|
250
221
|
const userIdMatch = pathname.match(/\/api\/admin\/test\/users\/([^/]+)/);
|
|
251
222
|
if (!userIdMatch) {
|
|
252
223
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Invalid user ID" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
253
|
-
return
|
|
224
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
254
225
|
}
|
|
255
226
|
const userId = userIdMatch[1];
|
|
256
227
|
try {
|
|
257
228
|
// Delete user via DataRouter (uses API's database connection)
|
|
258
|
-
const region =
|
|
259
|
-
const dbManager =
|
|
260
|
-
await
|
|
261
|
-
const { deleteUserData } = await
|
|
229
|
+
const region = detectRegionSync(request, env);
|
|
230
|
+
const dbManager = sharedDatabaseConnectionManager;
|
|
231
|
+
await withQueryTimeoutAndRetry(dbManager, region, env, async (db) => {
|
|
232
|
+
const { deleteUserData } = await import("../services/user-data-deletion.js");
|
|
262
233
|
await deleteUserData(db, userId);
|
|
263
234
|
}, {
|
|
264
|
-
...
|
|
235
|
+
...QueryTimeoutPresets.STANDARD,
|
|
265
236
|
timeoutMs: 5000, // 5 seconds for cleanup (more time for multiple deletes)
|
|
266
237
|
retryTimeoutMs: 2000, // 2 seconds for retry
|
|
267
238
|
maxRetries: 1, // Allow 1 retry for cleanup operations
|
|
@@ -270,7 +241,7 @@ exports.adminRoutes = [
|
|
|
270
241
|
success: true,
|
|
271
242
|
message: "Test user deleted successfully",
|
|
272
243
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
273
|
-
return
|
|
244
|
+
return addCorsHeaders(response, request, env);
|
|
274
245
|
}
|
|
275
246
|
catch (error) {
|
|
276
247
|
// Ignore "Record to delete does not exist" errors
|
|
@@ -279,7 +250,7 @@ exports.adminRoutes = [
|
|
|
279
250
|
success: true,
|
|
280
251
|
message: "User already deleted or does not exist",
|
|
281
252
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
282
|
-
return
|
|
253
|
+
return addCorsHeaders(response, request, env);
|
|
283
254
|
}
|
|
284
255
|
// Ignore foreign key constraint violations - user may have already been deleted
|
|
285
256
|
// or related records may have been cleaned up by cascade deletes
|
|
@@ -287,16 +258,16 @@ exports.adminRoutes = [
|
|
|
287
258
|
error.message?.includes("foreign key constraint violated")) {
|
|
288
259
|
// Try to verify if user still exists
|
|
289
260
|
try {
|
|
290
|
-
const verifyRegion =
|
|
291
|
-
const verifyDbManager =
|
|
292
|
-
const userExists = await
|
|
261
|
+
const verifyRegion = detectRegionSync(request, env);
|
|
262
|
+
const verifyDbManager = sharedDatabaseConnectionManager;
|
|
263
|
+
const userExists = await withQueryTimeoutAndRetry(verifyDbManager, verifyRegion, env, async (db) => {
|
|
293
264
|
const user = await db.user.findUnique({
|
|
294
265
|
where: { id: userId },
|
|
295
266
|
select: { id: true },
|
|
296
267
|
});
|
|
297
268
|
return !!user;
|
|
298
269
|
}, {
|
|
299
|
-
...
|
|
270
|
+
...QueryTimeoutPresets.STANDARD,
|
|
300
271
|
defaultValue: false, // Assume deleted if query fails
|
|
301
272
|
});
|
|
302
273
|
if (!userExists) {
|
|
@@ -308,7 +279,7 @@ exports.adminRoutes = [
|
|
|
308
279
|
status: 200,
|
|
309
280
|
headers: { "content-type": "application/json" },
|
|
310
281
|
});
|
|
311
|
-
return
|
|
282
|
+
return addCorsHeaders(response, request, env);
|
|
312
283
|
}
|
|
313
284
|
}
|
|
314
285
|
catch (verifyError) {
|
|
@@ -320,52 +291,52 @@ exports.adminRoutes = [
|
|
|
320
291
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
321
292
|
error: error.message || "Failed to delete test user",
|
|
322
293
|
}), { status: 500, headers: { "content-type": "application/json" } });
|
|
323
|
-
return
|
|
294
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
324
295
|
}
|
|
325
296
|
},
|
|
326
|
-
middleware: [
|
|
297
|
+
middleware: [corsMiddleware()], // No CSRF for test endpoints (unauthenticated in CI)
|
|
327
298
|
description: "Delete test user (dev environment only)",
|
|
328
299
|
},
|
|
329
300
|
{
|
|
330
301
|
path: "/api/admin/super-admin/*",
|
|
331
302
|
method: "*",
|
|
332
303
|
handler: async (request, env, { pathname }) => {
|
|
333
|
-
const sessionManager = new
|
|
334
|
-
const securityHeaders = new
|
|
335
|
-
const logger =
|
|
304
|
+
const sessionManager = new SessionManager();
|
|
305
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
306
|
+
const logger = getLogger();
|
|
336
307
|
// Get session secret with error handling
|
|
337
308
|
let sessionSecret;
|
|
338
309
|
try {
|
|
339
310
|
logger.debug("[Admin] Getting session secret...");
|
|
340
|
-
sessionSecret =
|
|
311
|
+
sessionSecret = env.SESSION_SECRET;
|
|
341
312
|
logger.debug(`[Admin] Session secret retrieved, type: ${typeof sessionSecret}, length: ${sessionSecret?.length ?? "N/A"}`);
|
|
342
313
|
if (!sessionSecret || typeof sessionSecret !== "string") {
|
|
343
|
-
logger.error(`[Admin] Invalid session secret
|
|
314
|
+
logger.error(`[Admin] Invalid session secret: ${typeof sessionSecret}, ${sessionSecret ? "present but invalid" : "missing"}`);
|
|
344
315
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Server configuration error" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
345
|
-
return
|
|
316
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
346
317
|
}
|
|
347
318
|
logger.debug("[Admin] Session secret is valid, length:", sessionSecret.length);
|
|
348
319
|
}
|
|
349
320
|
catch (error) {
|
|
350
321
|
logger.error("[Admin] Error getting session secret:", error);
|
|
351
322
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Server configuration error" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
352
|
-
return
|
|
323
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
353
324
|
}
|
|
354
325
|
logger.debug("[Admin] Calling getSession with secret length:", sessionSecret.length);
|
|
355
326
|
const session = await sessionManager.getSession(request, sessionSecret, env);
|
|
356
327
|
logger.debug("[Admin] getSession returned:", session ? "session found" : "null (unauthorized)");
|
|
357
328
|
if (!session) {
|
|
358
329
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
359
|
-
return
|
|
330
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
360
331
|
}
|
|
361
|
-
const db =
|
|
332
|
+
const db = createPrisma(env);
|
|
362
333
|
const user = await db.user.findUnique({
|
|
363
334
|
where: { id: session.userId },
|
|
364
335
|
select: { role: true, email: true },
|
|
365
336
|
});
|
|
366
337
|
if (!user) {
|
|
367
338
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: User not found" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
368
|
-
return
|
|
339
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
369
340
|
}
|
|
370
341
|
const isSuperAdmin = user.role === "SUPER_ADMIN";
|
|
371
342
|
if (pathname === "/api/admin/super-admin/check" &&
|
|
@@ -376,31 +347,31 @@ exports.adminRoutes = [
|
|
|
376
347
|
isSuperAdmin,
|
|
377
348
|
});
|
|
378
349
|
const response = securityHeaders.createSecureResponse(JSON.stringify({ isSuperAdmin }), { status: 200, headers: { "content-type": "application/json" } });
|
|
379
|
-
return
|
|
350
|
+
return addCorsHeaders(response, request, env);
|
|
380
351
|
}
|
|
381
352
|
if (!isSuperAdmin) {
|
|
382
353
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Super-admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
383
|
-
return
|
|
354
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
384
355
|
}
|
|
385
|
-
const toggleService = new
|
|
356
|
+
const toggleService = new FeatureToggleService(db);
|
|
386
357
|
// Get all feature toggles
|
|
387
358
|
if (pathname === "/api/admin/super-admin/feature-toggles" &&
|
|
388
359
|
request.method === "GET") {
|
|
389
360
|
try {
|
|
390
361
|
// Use standard timeout presets (consistent with other endpoints)
|
|
391
362
|
// DatabaseConnectionManager handles connection health and stale connection cleanup
|
|
392
|
-
const dbManager =
|
|
393
|
-
const region =
|
|
363
|
+
const dbManager = sharedDatabaseConnectionManager;
|
|
364
|
+
const region = detectRegionSync(request, env);
|
|
394
365
|
// Use STANDARD preset (3s initial + 2s retry = 5s total)
|
|
395
366
|
// This is consistent with other user-facing endpoints and well below Worker limits
|
|
396
367
|
// Use defaultValue to return empty array on timeout/error (graceful degradation)
|
|
397
368
|
let toggles = [];
|
|
398
369
|
try {
|
|
399
|
-
toggles = await
|
|
400
|
-
const service = new
|
|
370
|
+
toggles = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
|
|
371
|
+
const service = new FeatureToggleService(client);
|
|
401
372
|
return await service.getAllToggles();
|
|
402
373
|
}, {
|
|
403
|
-
...
|
|
374
|
+
...QueryTimeoutPresets.STANDARD, // 1s initial, 0.5s retry (optimized)
|
|
404
375
|
defaultValue: [], // Return empty array on timeout/error (graceful degradation)
|
|
405
376
|
maxRetries: 1, // Only 1 retry to keep total time under 2s
|
|
406
377
|
context: {
|
|
@@ -438,7 +409,7 @@ exports.adminRoutes = [
|
|
|
438
409
|
description: toggle.description,
|
|
439
410
|
})),
|
|
440
411
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
441
|
-
return
|
|
412
|
+
return addCorsHeaders(response, request, env);
|
|
442
413
|
}
|
|
443
414
|
catch (error) {
|
|
444
415
|
logger.error("[SuperAdmin] Error getting all feature toggles:", error);
|
|
@@ -525,7 +496,7 @@ exports.adminRoutes = [
|
|
|
525
496
|
const response = securityHeaders.createSecureResponse(JSON.stringify({
|
|
526
497
|
toggles: [],
|
|
527
498
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
528
|
-
return
|
|
499
|
+
return addCorsHeaders(response, request, env);
|
|
529
500
|
}
|
|
530
501
|
}
|
|
531
502
|
// Create a new feature toggle
|
|
@@ -533,7 +504,7 @@ exports.adminRoutes = [
|
|
|
533
504
|
request.method === "POST") {
|
|
534
505
|
try {
|
|
535
506
|
// Rate limit admin API
|
|
536
|
-
const rateLimitResult = await
|
|
507
|
+
const rateLimitResult = await rateLimitAdminFeatureToggleAPI(request, env, user.email);
|
|
537
508
|
if (!rateLimitResult || !rateLimitResult.allowed) {
|
|
538
509
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
539
510
|
error: {
|
|
@@ -550,23 +521,58 @@ exports.adminRoutes = [
|
|
|
550
521
|
...(rateLimitResult?.headers || {}),
|
|
551
522
|
},
|
|
552
523
|
});
|
|
553
|
-
return
|
|
524
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
554
525
|
}
|
|
555
|
-
// Validate request body
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
526
|
+
// Validate request body. P5: an optional `tenantId` makes this a
|
|
527
|
+
// tenant-scoped OVERRIDE write instead of a global write.
|
|
528
|
+
const CreateToggleSchema = z.object({
|
|
529
|
+
key: FeatureToggleKeySchema,
|
|
530
|
+
enabled: z.boolean().default(false),
|
|
531
|
+
description: z.string().max(1000).optional(),
|
|
532
|
+
tenantId: z.string().min(1).max(64).optional(),
|
|
560
533
|
});
|
|
561
|
-
const { key, enabled, description } =
|
|
562
|
-
//
|
|
563
|
-
|
|
534
|
+
const { key, enabled, description, tenantId } = validateBody(CreateToggleSchema, await request.json());
|
|
535
|
+
// P5 authz: tenant-scoped writes require SUPER_ADMIN or the caller's
|
|
536
|
+
// own active tenant. This route is already SUPER_ADMIN-gated above;
|
|
537
|
+
// the explicit check keeps the authorization boundary fail-closed and
|
|
538
|
+
// future-proof if that gate is ever relaxed.
|
|
539
|
+
if (tenantId !== undefined) {
|
|
540
|
+
const { canWriteTenantToggle } = await import("../feature-toggle-service.js");
|
|
541
|
+
const allowed = canWriteTenantToggle({
|
|
542
|
+
role: user.role,
|
|
543
|
+
callerTenantId: undefined, // cookie-session admins carry no tenant
|
|
544
|
+
targetTenantId: tenantId,
|
|
545
|
+
});
|
|
546
|
+
if (!allowed) {
|
|
547
|
+
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
548
|
+
error: "Forbidden: cross-tenant toggle write",
|
|
549
|
+
}), {
|
|
550
|
+
status: 403,
|
|
551
|
+
headers: { "content-type": "application/json" },
|
|
552
|
+
});
|
|
553
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
// Check if toggle already exists (scoped to the same tenant target).
|
|
557
|
+
// Keep the global call arity unchanged (no trailing `undefined`) so
|
|
558
|
+
// the global path stays byte-identical to pre-P5.
|
|
559
|
+
const existing = tenantId === undefined
|
|
560
|
+
? await toggleService.getToggle(key)
|
|
561
|
+
: await toggleService.getToggle(key, tenantId);
|
|
564
562
|
if (existing) {
|
|
565
563
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Feature toggle already exists" }), { status: 409, headers: { "content-type": "application/json" } });
|
|
566
|
-
return
|
|
564
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
567
565
|
}
|
|
568
|
-
// Create the toggle
|
|
569
|
-
|
|
566
|
+
// Create the toggle (global when tenantId is undefined). Preserve the
|
|
567
|
+
// 5-arg global call shape; only the tenant path passes the 6th arg.
|
|
568
|
+
const auditCtx = {
|
|
569
|
+
userId: session.userId,
|
|
570
|
+
env,
|
|
571
|
+
region: detectRegionSync(request, env),
|
|
572
|
+
};
|
|
573
|
+
const toggle = tenantId === undefined
|
|
574
|
+
? await toggleService.setToggle(key, enabled, user.email, description, auditCtx)
|
|
575
|
+
: await toggleService.setToggle(key, enabled, user.email, description, auditCtx, tenantId);
|
|
570
576
|
const responseHeaders = {
|
|
571
577
|
"content-type": "application/json",
|
|
572
578
|
...rateLimitResult.headers,
|
|
@@ -581,16 +587,16 @@ exports.adminRoutes = [
|
|
|
581
587
|
description: description,
|
|
582
588
|
},
|
|
583
589
|
}), { status: 201, headers: responseHeaders });
|
|
584
|
-
return
|
|
590
|
+
return addCorsHeaders(response, request, env);
|
|
585
591
|
}
|
|
586
592
|
catch (error) {
|
|
587
|
-
if (error instanceof
|
|
593
|
+
if (error instanceof ValidationError) {
|
|
588
594
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: error.message }), { status: 400, headers: { "content-type": "application/json" } });
|
|
589
|
-
return
|
|
595
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
590
596
|
}
|
|
591
597
|
logger.error("[SuperAdmin] Error creating feature toggle:", error);
|
|
592
598
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to create feature toggle" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
593
|
-
return
|
|
599
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
594
600
|
}
|
|
595
601
|
}
|
|
596
602
|
if (pathname === "/api/admin/super-admin/settings" &&
|
|
@@ -626,17 +632,17 @@ exports.adminRoutes = [
|
|
|
626
632
|
},
|
|
627
633
|
systemInfo: {
|
|
628
634
|
environment: env.ENVIRONMENT || "unknown",
|
|
629
|
-
version:
|
|
635
|
+
version: getAppVersion(env),
|
|
630
636
|
superAdminCount,
|
|
631
637
|
},
|
|
632
638
|
};
|
|
633
639
|
const response = securityHeaders.createSecureResponse(JSON.stringify(settings), { status: 200, headers: { "content-type": "application/json" } });
|
|
634
|
-
return
|
|
640
|
+
return addCorsHeaders(response, request, env);
|
|
635
641
|
}
|
|
636
642
|
catch (error) {
|
|
637
643
|
logger.error("[SuperAdmin] Error getting settings:", error);
|
|
638
644
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to get settings" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
639
|
-
return
|
|
645
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
640
646
|
}
|
|
641
647
|
}
|
|
642
648
|
const toggleUpdateMatch = pathname.match(/^\/api\/admin\/super-admin\/feature-toggles\/(.+)$/);
|
|
@@ -649,9 +655,9 @@ exports.adminRoutes = [
|
|
|
649
655
|
// Ensure user.email is defined and is a string for rate limiting
|
|
650
656
|
if (!user.email || typeof user.email !== "string") {
|
|
651
657
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "User email not found or invalid" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
652
|
-
return
|
|
658
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
653
659
|
}
|
|
654
|
-
const rateLimitResult = await
|
|
660
|
+
const rateLimitResult = await rateLimitAdminFeatureToggleAPI(request, env, user.email);
|
|
655
661
|
if (!rateLimitResult || !rateLimitResult.allowed) {
|
|
656
662
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
657
663
|
error: {
|
|
@@ -668,7 +674,7 @@ exports.adminRoutes = [
|
|
|
668
674
|
...(rateLimitResult?.headers || {}),
|
|
669
675
|
},
|
|
670
676
|
});
|
|
671
|
-
return
|
|
677
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
672
678
|
}
|
|
673
679
|
// Validate path parameter (toggle key)
|
|
674
680
|
const pathParam = toggleUpdateMatch?.[1];
|
|
@@ -676,19 +682,19 @@ exports.adminRoutes = [
|
|
|
676
682
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
677
683
|
error: "Invalid path parameter: toggle key is required",
|
|
678
684
|
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
679
|
-
return
|
|
685
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
680
686
|
}
|
|
681
687
|
let toggleKey;
|
|
682
688
|
try {
|
|
683
|
-
toggleKey =
|
|
689
|
+
toggleKey = validatePathParam(FeatureToggleKeySchema, pathParam);
|
|
684
690
|
}
|
|
685
691
|
catch (error) {
|
|
686
|
-
if (error instanceof
|
|
692
|
+
if (error instanceof ValidationError) {
|
|
687
693
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify(error.toResponse()), {
|
|
688
694
|
status: 400,
|
|
689
695
|
headers: { "content-type": "application/json" },
|
|
690
696
|
});
|
|
691
|
-
return
|
|
697
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
692
698
|
}
|
|
693
699
|
throw error;
|
|
694
700
|
}
|
|
@@ -699,39 +705,40 @@ exports.adminRoutes = [
|
|
|
699
705
|
}
|
|
700
706
|
catch (error) {
|
|
701
707
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Invalid JSON in request body" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
702
|
-
return
|
|
708
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
703
709
|
}
|
|
704
710
|
// Ensure body is an object
|
|
705
711
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
706
712
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Request body must be an object" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
707
|
-
return
|
|
713
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
708
714
|
}
|
|
709
|
-
const UpdateToggleEnabledSchema =
|
|
710
|
-
enabled:
|
|
711
|
-
|
|
712
|
-
|
|
715
|
+
const UpdateToggleEnabledSchema = z.object({
|
|
716
|
+
enabled: z.boolean({
|
|
717
|
+
error: (issue) => issue.input === undefined
|
|
718
|
+
? "enabled is required"
|
|
719
|
+
: "enabled must be a boolean",
|
|
713
720
|
}),
|
|
714
721
|
});
|
|
715
722
|
let enabled;
|
|
716
723
|
try {
|
|
717
|
-
const validated =
|
|
724
|
+
const validated = validateBody(UpdateToggleEnabledSchema, body);
|
|
718
725
|
enabled = validated.enabled;
|
|
719
726
|
}
|
|
720
727
|
catch (error) {
|
|
721
|
-
if (error instanceof
|
|
728
|
+
if (error instanceof ValidationError) {
|
|
722
729
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify(error.toResponse()), {
|
|
723
730
|
status: 400,
|
|
724
731
|
headers: { "content-type": "application/json" },
|
|
725
732
|
});
|
|
726
|
-
return
|
|
733
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
727
734
|
}
|
|
728
735
|
// Log unexpected errors for debugging
|
|
729
736
|
logger.error("[Admin] Unexpected error in body validation:", error);
|
|
730
737
|
throw error;
|
|
731
738
|
}
|
|
732
739
|
// Use improved database connection manager with aggressive timeout handling
|
|
733
|
-
const dbManager =
|
|
734
|
-
const region =
|
|
740
|
+
const dbManager = sharedDatabaseConnectionManager;
|
|
741
|
+
const region = detectRegionSync(request, env);
|
|
735
742
|
// Top-level timeout wrapper to ensure we never hang for more than 3 seconds
|
|
736
743
|
// This is well below Cloudflare's 30-second limit and ensures we always return a response
|
|
737
744
|
// Aggressive timeout to fail fast if database is slow
|
|
@@ -749,14 +756,18 @@ exports.adminRoutes = [
|
|
|
749
756
|
try {
|
|
750
757
|
return await dbManager.executeWithRetry(region, env, async (client) => {
|
|
751
758
|
// Create a temporary service instance with the client from timeout helper
|
|
752
|
-
const service = new
|
|
759
|
+
const service = new FeatureToggleService(client);
|
|
753
760
|
// Ensure user.email is still defined (double-check before DB operation)
|
|
754
761
|
if (!user.email || typeof user.email !== "string") {
|
|
755
762
|
throw new Error("User email is required for toggle update");
|
|
756
763
|
}
|
|
757
764
|
return await service.setToggle(toggleKey, enabled, user.email, toggleKey === "global_public_posting_enabled"
|
|
758
765
|
? "Globally enable public posting for all users"
|
|
759
|
-
: undefined
|
|
766
|
+
: undefined, {
|
|
767
|
+
userId: session.userId,
|
|
768
|
+
env,
|
|
769
|
+
region,
|
|
770
|
+
});
|
|
760
771
|
}, {
|
|
761
772
|
timeoutMs: 1000, // 1 second initial timeout - fail fast
|
|
762
773
|
retryTimeoutMs: 500, // 0.5 seconds retry timeout - very fast retry
|
|
@@ -799,7 +810,7 @@ exports.adminRoutes = [
|
|
|
799
810
|
error: "Database operation timed out. Please try again in a moment.",
|
|
800
811
|
details: "The database connection is experiencing issues. This usually resolves quickly.",
|
|
801
812
|
}), { status: 503, headers: { "content-type": "application/json" } });
|
|
802
|
-
return
|
|
813
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
803
814
|
}
|
|
804
815
|
// Add rate limit headers to successful response
|
|
805
816
|
const responseHeaders = {
|
|
@@ -815,20 +826,20 @@ exports.adminRoutes = [
|
|
|
815
826
|
changedBy: toggle.changedBy,
|
|
816
827
|
},
|
|
817
828
|
}), { status: 200, headers: responseHeaders });
|
|
818
|
-
return
|
|
829
|
+
return addCorsHeaders(response, request, env);
|
|
819
830
|
}
|
|
820
831
|
catch (error) {
|
|
821
832
|
// Handle validation errors
|
|
822
|
-
if (error instanceof
|
|
833
|
+
if (error instanceof ValidationError) {
|
|
823
834
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify(error.toResponse()), {
|
|
824
835
|
status: error.getStatusCode(),
|
|
825
836
|
headers: { "content-type": "application/json" },
|
|
826
837
|
});
|
|
827
|
-
return
|
|
838
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
828
839
|
}
|
|
829
840
|
logger.error("[SuperAdmin] Error updating feature toggle:", error);
|
|
830
841
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to update feature toggle" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
831
|
-
return
|
|
842
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
832
843
|
}
|
|
833
844
|
}
|
|
834
845
|
if (pathname === "/api/admin/super-admin/signup-settings" &&
|
|
@@ -841,11 +852,15 @@ exports.adminRoutes = [
|
|
|
841
852
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
842
853
|
error: 'Invalid request: mode must be "open", "invitation_only", or "disabled"',
|
|
843
854
|
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
844
|
-
return
|
|
855
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
845
856
|
}
|
|
846
857
|
const enabled = mode !== "disabled";
|
|
847
858
|
const description = `user_signup_mode:${mode}`;
|
|
848
|
-
const toggle = await toggleService.setToggle("user_signup_mode", enabled, user.email, description
|
|
859
|
+
const toggle = await toggleService.setToggle("user_signup_mode", enabled, user.email, description, {
|
|
860
|
+
userId: session.userId,
|
|
861
|
+
env,
|
|
862
|
+
region: detectRegionSync(request, env),
|
|
863
|
+
});
|
|
849
864
|
const response = securityHeaders.createSecureResponse(JSON.stringify({
|
|
850
865
|
success: true,
|
|
851
866
|
signupSettings: {
|
|
@@ -854,34 +869,34 @@ exports.adminRoutes = [
|
|
|
854
869
|
changedBy: toggle.changedBy,
|
|
855
870
|
},
|
|
856
871
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
857
|
-
return
|
|
872
|
+
return addCorsHeaders(response, request, env);
|
|
858
873
|
}
|
|
859
874
|
catch (error) {
|
|
860
875
|
logger.error("[SuperAdmin] Error updating sign-up settings:", error);
|
|
861
876
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to update sign-up settings" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
862
|
-
return
|
|
877
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
863
878
|
}
|
|
864
879
|
}
|
|
865
880
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Not found" }), { status: 404, headers: { "content-type": "application/json" } });
|
|
866
|
-
return
|
|
881
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
867
882
|
},
|
|
868
|
-
middleware: [
|
|
883
|
+
middleware: [corsMiddleware(), csrfMiddleware()],
|
|
869
884
|
description: "Super-admin routes",
|
|
870
885
|
},
|
|
871
886
|
{
|
|
872
887
|
path: /^\/api\/feature-toggles\/(.+)$/,
|
|
873
888
|
method: "GET",
|
|
874
889
|
handler: async (request, env, { pathname }) => {
|
|
875
|
-
const logger =
|
|
876
|
-
const securityHeaders = new
|
|
890
|
+
const logger = getLogger();
|
|
891
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
877
892
|
const toggleKeyMatch = pathname.match(/^\/api\/feature-toggles\/(.+)$/);
|
|
878
893
|
if (!toggleKeyMatch) {
|
|
879
894
|
const response = securityHeaders.createSecureResponse(JSON.stringify({ enabled: false }), { status: 200, headers: { "content-type": "application/json" } });
|
|
880
|
-
return
|
|
895
|
+
return addCorsHeaders(response, request, env);
|
|
881
896
|
}
|
|
882
897
|
try {
|
|
883
898
|
// Rate limit public API (100 requests/minute per IP)
|
|
884
|
-
const rateLimitResult = await
|
|
899
|
+
const rateLimitResult = await rateLimitFeatureToggleAPI(request, env);
|
|
885
900
|
if (!rateLimitResult || !rateLimitResult.allowed) {
|
|
886
901
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
887
902
|
error: {
|
|
@@ -898,19 +913,19 @@ exports.adminRoutes = [
|
|
|
898
913
|
...(rateLimitResult?.headers || {}),
|
|
899
914
|
},
|
|
900
915
|
});
|
|
901
|
-
return
|
|
916
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
902
917
|
}
|
|
903
918
|
// Validate path parameter (toggle key)
|
|
904
|
-
const toggleKey =
|
|
919
|
+
const toggleKey = validatePathParam(FeatureToggleKeySchema, toggleKeyMatch[1]);
|
|
905
920
|
// Validate query parameters
|
|
906
921
|
const url = new URL(request.url);
|
|
907
922
|
const queryParams = {};
|
|
908
923
|
url.searchParams.forEach((value, key) => {
|
|
909
924
|
queryParams[key] = value;
|
|
910
925
|
});
|
|
911
|
-
const validatedQuery =
|
|
912
|
-
const db =
|
|
913
|
-
const toggleService = new
|
|
926
|
+
const validatedQuery = validateQuery(PublicAPIQuerySchema, queryParams);
|
|
927
|
+
const db = createPrisma(env);
|
|
928
|
+
const toggleService = new FeatureToggleService(db);
|
|
914
929
|
const toggle = await toggleService.getToggle(toggleKey);
|
|
915
930
|
if (!toggle) {
|
|
916
931
|
// Add rate limit headers even for not found responses
|
|
@@ -919,7 +934,7 @@ exports.adminRoutes = [
|
|
|
919
934
|
...rateLimitResult.headers,
|
|
920
935
|
};
|
|
921
936
|
const response = securityHeaders.createSecureResponse(JSON.stringify({ key: toggleKey, enabled: false }), { status: 200, headers: responseHeaders });
|
|
922
|
-
return
|
|
937
|
+
return addCorsHeaders(response, request, env);
|
|
923
938
|
}
|
|
924
939
|
// Add rate limit headers to successful response
|
|
925
940
|
const responseHeaders = {
|
|
@@ -932,7 +947,7 @@ exports.adminRoutes = [
|
|
|
932
947
|
lastChanged: toggle.lastChanged?.toISOString(),
|
|
933
948
|
changedBy: toggle.changedBy,
|
|
934
949
|
}), { status: 200, headers: responseHeaders });
|
|
935
|
-
return
|
|
950
|
+
return addCorsHeaders(response, request, env);
|
|
936
951
|
}
|
|
937
952
|
catch (error) {
|
|
938
953
|
logger.error(`[Admin] GET handler error: ${error instanceof Error ? error.message : String(error)}`, {
|
|
@@ -940,46 +955,46 @@ exports.adminRoutes = [
|
|
|
940
955
|
stack: error instanceof Error ? error.stack : "No stack",
|
|
941
956
|
});
|
|
942
957
|
// Handle validation errors
|
|
943
|
-
if (error instanceof
|
|
958
|
+
if (error instanceof ValidationError) {
|
|
944
959
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify(error.toResponse()), {
|
|
945
960
|
status: error.getStatusCode(),
|
|
946
961
|
headers: { "content-type": "application/json" },
|
|
947
962
|
});
|
|
948
|
-
return
|
|
963
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
949
964
|
}
|
|
950
965
|
// For other errors, return 500
|
|
951
966
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
952
967
|
error: "Internal server error",
|
|
953
968
|
message: error instanceof Error ? error.message : "Unknown error",
|
|
954
969
|
}), { status: 500, headers: { "content-type": "application/json" } });
|
|
955
|
-
return
|
|
970
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
956
971
|
}
|
|
957
972
|
},
|
|
958
|
-
middleware: [
|
|
973
|
+
middleware: [corsMiddleware()],
|
|
959
974
|
description: "Get feature toggle status",
|
|
960
975
|
},
|
|
961
976
|
{
|
|
962
977
|
path: "/api/roles/metadata",
|
|
963
978
|
method: "GET",
|
|
964
979
|
handler: async (request, env) => {
|
|
965
|
-
const logger =
|
|
966
|
-
const securityHeaders = new
|
|
980
|
+
const logger = getLogger();
|
|
981
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
967
982
|
try {
|
|
968
|
-
const db =
|
|
983
|
+
const db = createPrisma(env);
|
|
969
984
|
const roleMetadata = await db.roleMetadata.findMany({
|
|
970
985
|
where: { isActive: true },
|
|
971
986
|
orderBy: { role: "asc" },
|
|
972
987
|
});
|
|
973
988
|
const response = securityHeaders.createSecureResponse(JSON.stringify({ roles: roleMetadata }), { status: 200, headers: { "content-type": "application/json" } });
|
|
974
|
-
return
|
|
989
|
+
return addCorsHeaders(response, request, env);
|
|
975
990
|
}
|
|
976
991
|
catch (error) {
|
|
977
992
|
logger.error("Error fetching role metadata:", error);
|
|
978
993
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to fetch role metadata" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
979
|
-
return
|
|
994
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
980
995
|
}
|
|
981
996
|
},
|
|
982
|
-
middleware: [
|
|
997
|
+
middleware: [corsMiddleware()],
|
|
983
998
|
description: "Get role metadata",
|
|
984
999
|
},
|
|
985
1000
|
// Domain Management Endpoints
|
|
@@ -987,25 +1002,25 @@ exports.adminRoutes = [
|
|
|
987
1002
|
path: "/api/admin/domains",
|
|
988
1003
|
method: "GET",
|
|
989
1004
|
handler: async (request, env, { url, requestContext }) => {
|
|
990
|
-
const sessionManager = new
|
|
991
|
-
const securityHeaders = new
|
|
992
|
-
const logger =
|
|
1005
|
+
const sessionManager = new SessionManager();
|
|
1006
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
1007
|
+
const logger = getLogger();
|
|
993
1008
|
// Check authentication and authorization
|
|
994
|
-
const session = await sessionManager.getSession(request,
|
|
1009
|
+
const session = await sessionManager.getSession(request, env.SESSION_SECRET, env);
|
|
995
1010
|
if (!session) {
|
|
996
1011
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
997
|
-
return
|
|
1012
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
998
1013
|
}
|
|
999
1014
|
// Check if user is admin
|
|
1000
1015
|
const region = requestContext?.region || env.DEFAULT_REGION || "EU";
|
|
1001
|
-
const db =
|
|
1016
|
+
const db = DataRouter.getDatabaseForRegion(region, env);
|
|
1002
1017
|
const user = await db.user.findUnique({
|
|
1003
1018
|
where: { id: session.userId },
|
|
1004
1019
|
select: { role: true },
|
|
1005
1020
|
});
|
|
1006
1021
|
if (!user || (user.role !== "SUPER_ADMIN" && user.role !== "INTERNAL")) {
|
|
1007
1022
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
1008
|
-
return
|
|
1023
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1009
1024
|
}
|
|
1010
1025
|
try {
|
|
1011
1026
|
// Parse query parameters
|
|
@@ -1060,142 +1075,142 @@ exports.adminRoutes = [
|
|
|
1060
1075
|
hasMore,
|
|
1061
1076
|
nextCursor,
|
|
1062
1077
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
1063
|
-
return
|
|
1078
|
+
return addCorsHeaders(response, request, env);
|
|
1064
1079
|
}
|
|
1065
1080
|
catch (error) {
|
|
1066
1081
|
logger.error("[Admin] Error fetching domains:", error);
|
|
1067
1082
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to fetch domains" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1068
|
-
return
|
|
1083
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1069
1084
|
}
|
|
1070
1085
|
},
|
|
1071
|
-
middleware: [
|
|
1086
|
+
middleware: [corsMiddleware()],
|
|
1072
1087
|
description: "List domains with reputation",
|
|
1073
1088
|
},
|
|
1074
1089
|
{
|
|
1075
1090
|
path: /^\/api\/admin\/domains\/([^/]+)\/block$/,
|
|
1076
1091
|
method: "POST",
|
|
1077
1092
|
handler: async (request, env, { pathname, requestContext }) => {
|
|
1078
|
-
const sessionManager = new
|
|
1079
|
-
const securityHeaders = new
|
|
1080
|
-
const logger =
|
|
1093
|
+
const sessionManager = new SessionManager();
|
|
1094
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
1095
|
+
const logger = getLogger();
|
|
1081
1096
|
// Check authentication and authorization
|
|
1082
|
-
const session = await sessionManager.getSession(request,
|
|
1097
|
+
const session = await sessionManager.getSession(request, env.SESSION_SECRET, env);
|
|
1083
1098
|
if (!session) {
|
|
1084
1099
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
1085
|
-
return
|
|
1100
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1086
1101
|
}
|
|
1087
1102
|
// Check if user is admin
|
|
1088
1103
|
const region = requestContext?.region || env.DEFAULT_REGION || "EU";
|
|
1089
|
-
const db =
|
|
1104
|
+
const db = DataRouter.getDatabaseForRegion(region, env);
|
|
1090
1105
|
const user = await db.user.findUnique({
|
|
1091
1106
|
where: { id: session.userId },
|
|
1092
1107
|
select: { role: true },
|
|
1093
1108
|
});
|
|
1094
1109
|
if (!user || (user.role !== "SUPER_ADMIN" && user.role !== "INTERNAL")) {
|
|
1095
1110
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
1096
|
-
return
|
|
1111
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1097
1112
|
}
|
|
1098
1113
|
try {
|
|
1099
1114
|
// Extract domain from path
|
|
1100
1115
|
const match = pathname.match(/^\/api\/admin\/domains\/([^/]+)\/block$/);
|
|
1101
1116
|
if (!match) {
|
|
1102
1117
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Invalid URL format" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1103
|
-
return
|
|
1118
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1104
1119
|
}
|
|
1105
1120
|
const domain = decodeURIComponent(match[1]);
|
|
1106
1121
|
// Block domain
|
|
1107
|
-
const reputationService = new
|
|
1122
|
+
const reputationService = new DomainReputationService(env);
|
|
1108
1123
|
await reputationService.blockDomain(domain, region, env);
|
|
1109
1124
|
logger.info(`[Admin] Domain blocked: ${domain} by user ${session.userId}`);
|
|
1110
1125
|
const response = securityHeaders.createSecureResponse(JSON.stringify({
|
|
1111
1126
|
success: true,
|
|
1112
1127
|
message: `Domain ${domain} has been blocked`,
|
|
1113
1128
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
1114
|
-
return
|
|
1129
|
+
return addCorsHeaders(response, request, env);
|
|
1115
1130
|
}
|
|
1116
1131
|
catch (error) {
|
|
1117
1132
|
logger.error("[Admin] Error blocking domain:", error);
|
|
1118
1133
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to block domain" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1119
|
-
return
|
|
1134
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1120
1135
|
}
|
|
1121
1136
|
},
|
|
1122
|
-
middleware: [
|
|
1137
|
+
middleware: [corsMiddleware(), csrfMiddleware()],
|
|
1123
1138
|
description: "Block a domain",
|
|
1124
1139
|
},
|
|
1125
1140
|
{
|
|
1126
1141
|
path: /^\/api\/admin\/domains\/([^/]+)\/unblock$/,
|
|
1127
1142
|
method: "POST",
|
|
1128
1143
|
handler: async (request, env, { pathname, requestContext }) => {
|
|
1129
|
-
const sessionManager = new
|
|
1130
|
-
const securityHeaders = new
|
|
1131
|
-
const logger =
|
|
1144
|
+
const sessionManager = new SessionManager();
|
|
1145
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
1146
|
+
const logger = getLogger();
|
|
1132
1147
|
// Check authentication and authorization
|
|
1133
|
-
const session = await sessionManager.getSession(request,
|
|
1148
|
+
const session = await sessionManager.getSession(request, env.SESSION_SECRET, env);
|
|
1134
1149
|
if (!session) {
|
|
1135
1150
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
1136
|
-
return
|
|
1151
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1137
1152
|
}
|
|
1138
1153
|
// Check if user is admin
|
|
1139
1154
|
const region = requestContext?.region || env.DEFAULT_REGION || "EU";
|
|
1140
|
-
const db =
|
|
1155
|
+
const db = DataRouter.getDatabaseForRegion(region, env);
|
|
1141
1156
|
const user = await db.user.findUnique({
|
|
1142
1157
|
where: { id: session.userId },
|
|
1143
1158
|
select: { role: true },
|
|
1144
1159
|
});
|
|
1145
1160
|
if (!user || (user.role !== "SUPER_ADMIN" && user.role !== "INTERNAL")) {
|
|
1146
1161
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
1147
|
-
return
|
|
1162
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1148
1163
|
}
|
|
1149
1164
|
try {
|
|
1150
1165
|
// Extract domain from path
|
|
1151
1166
|
const match = pathname.match(/^\/api\/admin\/domains\/([^/]+)\/unblock$/);
|
|
1152
1167
|
if (!match) {
|
|
1153
1168
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Invalid URL format" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1154
|
-
return
|
|
1169
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1155
1170
|
}
|
|
1156
1171
|
const domain = decodeURIComponent(match[1]);
|
|
1157
1172
|
// Unblock domain
|
|
1158
|
-
const reputationService = new
|
|
1173
|
+
const reputationService = new DomainReputationService(env);
|
|
1159
1174
|
await reputationService.unblockDomain(domain, region, env);
|
|
1160
1175
|
logger.info(`[Admin] Domain unblocked: ${domain} by user ${session.userId}`);
|
|
1161
1176
|
const response = securityHeaders.createSecureResponse(JSON.stringify({
|
|
1162
1177
|
success: true,
|
|
1163
1178
|
message: `Domain ${domain} has been unblocked`,
|
|
1164
1179
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
1165
|
-
return
|
|
1180
|
+
return addCorsHeaders(response, request, env);
|
|
1166
1181
|
}
|
|
1167
1182
|
catch (error) {
|
|
1168
1183
|
logger.error("[Admin] Error unblocking domain:", error);
|
|
1169
1184
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to unblock domain" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1170
|
-
return
|
|
1185
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1171
1186
|
}
|
|
1172
1187
|
},
|
|
1173
|
-
middleware: [
|
|
1188
|
+
middleware: [corsMiddleware(), csrfMiddleware()],
|
|
1174
1189
|
description: "Unblock a domain",
|
|
1175
1190
|
},
|
|
1176
1191
|
{
|
|
1177
1192
|
path: "/api/admin/reports",
|
|
1178
1193
|
method: "GET",
|
|
1179
1194
|
handler: async (request, env, { url, requestContext }) => {
|
|
1180
|
-
const sessionManager = new
|
|
1181
|
-
const securityHeaders = new
|
|
1182
|
-
const logger =
|
|
1195
|
+
const sessionManager = new SessionManager();
|
|
1196
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
1197
|
+
const logger = getLogger();
|
|
1183
1198
|
// Check authentication and authorization
|
|
1184
|
-
const session = await sessionManager.getSession(request,
|
|
1199
|
+
const session = await sessionManager.getSession(request, env.SESSION_SECRET, env);
|
|
1185
1200
|
if (!session) {
|
|
1186
1201
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
1187
|
-
return
|
|
1202
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1188
1203
|
}
|
|
1189
1204
|
// Check if user is admin
|
|
1190
1205
|
const region = requestContext?.region || env.DEFAULT_REGION || "EU";
|
|
1191
|
-
const db =
|
|
1206
|
+
const db = DataRouter.getDatabaseForRegion(region, env);
|
|
1192
1207
|
const user = await db.user.findUnique({
|
|
1193
1208
|
where: { id: session.userId },
|
|
1194
1209
|
select: { role: true },
|
|
1195
1210
|
});
|
|
1196
1211
|
if (!user || (user.role !== "SUPER_ADMIN" && user.role !== "INTERNAL")) {
|
|
1197
1212
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
1198
|
-
return
|
|
1213
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1199
1214
|
}
|
|
1200
1215
|
try {
|
|
1201
1216
|
// Parse query parameters
|
|
@@ -1206,8 +1221,9 @@ exports.adminRoutes = [
|
|
|
1206
1221
|
const domain = queryParams.get("domain") || undefined;
|
|
1207
1222
|
const sortBy = queryParams.get("sortBy") || "createdAt";
|
|
1208
1223
|
const sortOrder = queryParams.get("sortOrder") || "desc";
|
|
1209
|
-
// Build query
|
|
1210
|
-
|
|
1224
|
+
// Build query (P4: link reports now live in the generalized Report
|
|
1225
|
+
// model — scope to reportType LINK so account reports never leak here).
|
|
1226
|
+
const where = { reportType: "LINK" };
|
|
1211
1227
|
if (cursor) {
|
|
1212
1228
|
where.id = { gt: cursor };
|
|
1213
1229
|
}
|
|
@@ -1228,12 +1244,12 @@ exports.adminRoutes = [
|
|
|
1228
1244
|
orderBy.createdAt = "desc"; // Default
|
|
1229
1245
|
}
|
|
1230
1246
|
// Get reports with pagination
|
|
1231
|
-
const reports = await db.
|
|
1247
|
+
const reports = await db.report.findMany({
|
|
1232
1248
|
where,
|
|
1233
1249
|
take: limit + 1,
|
|
1234
1250
|
orderBy,
|
|
1235
1251
|
include: {
|
|
1236
|
-
|
|
1252
|
+
reporter: {
|
|
1237
1253
|
select: {
|
|
1238
1254
|
id: true,
|
|
1239
1255
|
email: true,
|
|
@@ -1245,11 +1261,12 @@ exports.adminRoutes = [
|
|
|
1245
1261
|
const result = hasMore ? reports.slice(0, limit) : reports;
|
|
1246
1262
|
const nextCursor = hasMore ? result[result.length - 1].id : undefined;
|
|
1247
1263
|
const response = securityHeaders.createSecureResponse(JSON.stringify({
|
|
1264
|
+
// Response shape preserved (P4): resourceId is the reported url.
|
|
1248
1265
|
reports: result.map((r) => ({
|
|
1249
1266
|
id: r.id,
|
|
1250
|
-
userId: r.
|
|
1251
|
-
userEmail: r.
|
|
1252
|
-
linkUrl: r.
|
|
1267
|
+
userId: r.reporterUserId,
|
|
1268
|
+
userEmail: r.reporter.email,
|
|
1269
|
+
linkUrl: r.resourceId,
|
|
1253
1270
|
domain: r.domain,
|
|
1254
1271
|
reason: r.reason,
|
|
1255
1272
|
status: r.status,
|
|
@@ -1258,47 +1275,47 @@ exports.adminRoutes = [
|
|
|
1258
1275
|
hasMore,
|
|
1259
1276
|
nextCursor,
|
|
1260
1277
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
1261
|
-
return
|
|
1278
|
+
return addCorsHeaders(response, request, env);
|
|
1262
1279
|
}
|
|
1263
1280
|
catch (error) {
|
|
1264
1281
|
logger.error("[Admin] Error fetching reports:", error);
|
|
1265
1282
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to fetch reports" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1266
|
-
return
|
|
1283
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1267
1284
|
}
|
|
1268
1285
|
},
|
|
1269
|
-
middleware: [
|
|
1286
|
+
middleware: [corsMiddleware()],
|
|
1270
1287
|
description: "List link reports",
|
|
1271
1288
|
},
|
|
1272
1289
|
{
|
|
1273
1290
|
path: /^\/api\/admin\/reports\/([^/]+)\/review$/,
|
|
1274
1291
|
method: "POST",
|
|
1275
1292
|
handler: async (request, env, { pathname, requestContext }) => {
|
|
1276
|
-
const sessionManager = new
|
|
1277
|
-
const securityHeaders = new
|
|
1278
|
-
const logger =
|
|
1293
|
+
const sessionManager = new SessionManager();
|
|
1294
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
1295
|
+
const logger = getLogger();
|
|
1279
1296
|
// Check authentication and authorization
|
|
1280
|
-
const session = await sessionManager.getSession(request,
|
|
1297
|
+
const session = await sessionManager.getSession(request, env.SESSION_SECRET, env);
|
|
1281
1298
|
if (!session) {
|
|
1282
1299
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
1283
|
-
return
|
|
1300
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1284
1301
|
}
|
|
1285
1302
|
// Check if user is admin
|
|
1286
1303
|
const region = requestContext?.region || env.DEFAULT_REGION || "EU";
|
|
1287
|
-
const db =
|
|
1304
|
+
const db = DataRouter.getDatabaseForRegion(region, env);
|
|
1288
1305
|
const user = await db.user.findUnique({
|
|
1289
1306
|
where: { id: session.userId },
|
|
1290
1307
|
select: { role: true },
|
|
1291
1308
|
});
|
|
1292
1309
|
if (!user || (user.role !== "SUPER_ADMIN" && user.role !== "INTERNAL")) {
|
|
1293
1310
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
1294
|
-
return
|
|
1311
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1295
1312
|
}
|
|
1296
1313
|
try {
|
|
1297
1314
|
// Extract reportId from path
|
|
1298
1315
|
const match = pathname.match(/^\/api\/admin\/reports\/([^/]+)\/review$/);
|
|
1299
1316
|
if (!match) {
|
|
1300
1317
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Invalid URL format" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1301
|
-
return
|
|
1318
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1302
1319
|
}
|
|
1303
1320
|
const reportId = match[1];
|
|
1304
1321
|
// Parse request body
|
|
@@ -1308,23 +1325,27 @@ exports.adminRoutes = [
|
|
|
1308
1325
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
1309
1326
|
error: "Invalid action. Must be approve, reject, or dismiss",
|
|
1310
1327
|
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1311
|
-
return
|
|
1328
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1312
1329
|
}
|
|
1313
|
-
// Get report
|
|
1314
|
-
|
|
1315
|
-
|
|
1330
|
+
// Get report (P4: Report model, scoped to LINK so only link reports
|
|
1331
|
+
// are reviewable via this moderator route).
|
|
1332
|
+
const report = await db.report.findFirst({
|
|
1333
|
+
where: { id: reportId, reportType: "LINK" },
|
|
1316
1334
|
});
|
|
1317
1335
|
if (!report) {
|
|
1318
1336
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Report not found" }), { status: 404, headers: { "content-type": "application/json" } });
|
|
1319
|
-
return
|
|
1337
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1320
1338
|
}
|
|
1321
1339
|
// Update report status
|
|
1322
1340
|
let newStatus;
|
|
1323
1341
|
if (body.action === "approve") {
|
|
1324
1342
|
newStatus = "approved";
|
|
1325
|
-
// If approved, update domain reputation (negative signal)
|
|
1326
|
-
|
|
1327
|
-
|
|
1343
|
+
// If approved, update domain reputation (negative signal). domain is
|
|
1344
|
+
// nullable on Report; LINK reports always carry it, but guard anyway.
|
|
1345
|
+
if (report.domain) {
|
|
1346
|
+
const reputationService = new DomainReputationService(env);
|
|
1347
|
+
await reputationService.updateReputation(report.domain, "user_report", region, env);
|
|
1348
|
+
}
|
|
1328
1349
|
}
|
|
1329
1350
|
else if (body.action === "reject") {
|
|
1330
1351
|
newStatus = "rejected";
|
|
@@ -1332,7 +1353,7 @@ exports.adminRoutes = [
|
|
|
1332
1353
|
else {
|
|
1333
1354
|
newStatus = "dismissed";
|
|
1334
1355
|
}
|
|
1335
|
-
const updatedReport = await db.
|
|
1356
|
+
const updatedReport = await db.report.update({
|
|
1336
1357
|
where: { id: reportId },
|
|
1337
1358
|
data: {
|
|
1338
1359
|
status: newStatus,
|
|
@@ -1346,40 +1367,40 @@ exports.adminRoutes = [
|
|
|
1346
1367
|
status: updatedReport.status,
|
|
1347
1368
|
},
|
|
1348
1369
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
1349
|
-
return
|
|
1370
|
+
return addCorsHeaders(response, request, env);
|
|
1350
1371
|
}
|
|
1351
1372
|
catch (error) {
|
|
1352
1373
|
logger.error("[Admin] Error reviewing report:", error);
|
|
1353
1374
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to review report" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1354
|
-
return
|
|
1375
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1355
1376
|
}
|
|
1356
1377
|
},
|
|
1357
|
-
middleware: [
|
|
1378
|
+
middleware: [corsMiddleware(), csrfMiddleware()],
|
|
1358
1379
|
description: "Review a link report",
|
|
1359
1380
|
},
|
|
1360
1381
|
{
|
|
1361
1382
|
path: "/api/admin/domains/bulk",
|
|
1362
1383
|
method: "POST",
|
|
1363
1384
|
handler: async (request, env, { requestContext }) => {
|
|
1364
|
-
const sessionManager = new
|
|
1365
|
-
const securityHeaders = new
|
|
1366
|
-
const logger =
|
|
1385
|
+
const sessionManager = new SessionManager();
|
|
1386
|
+
const securityHeaders = new SecurityHeaders(env);
|
|
1387
|
+
const logger = getLogger();
|
|
1367
1388
|
// Check authentication and authorization
|
|
1368
|
-
const session = await sessionManager.getSession(request,
|
|
1389
|
+
const session = await sessionManager.getSession(request, env.SESSION_SECRET, env);
|
|
1369
1390
|
if (!session) {
|
|
1370
1391
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
|
|
1371
|
-
return
|
|
1392
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1372
1393
|
}
|
|
1373
1394
|
// Check if user is admin
|
|
1374
1395
|
const region = requestContext?.region || env.DEFAULT_REGION || "EU";
|
|
1375
|
-
const db =
|
|
1396
|
+
const db = DataRouter.getDatabaseForRegion(region, env);
|
|
1376
1397
|
const user = await db.user.findUnique({
|
|
1377
1398
|
where: { id: session.userId },
|
|
1378
1399
|
select: { role: true },
|
|
1379
1400
|
});
|
|
1380
1401
|
if (!user || (user.role !== "SUPER_ADMIN" && user.role !== "INTERNAL")) {
|
|
1381
1402
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Forbidden: Admin access required" }), { status: 403, headers: { "content-type": "application/json" } });
|
|
1382
|
-
return
|
|
1403
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1383
1404
|
}
|
|
1384
1405
|
try {
|
|
1385
1406
|
// Parse request body
|
|
@@ -1389,18 +1410,18 @@ exports.adminRoutes = [
|
|
|
1389
1410
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({
|
|
1390
1411
|
error: "Invalid action. Must be block, unblock, or allowlist",
|
|
1391
1412
|
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1392
|
-
return
|
|
1413
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1393
1414
|
}
|
|
1394
1415
|
if (!Array.isArray(body.domains) || body.domains.length === 0) {
|
|
1395
1416
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "domains must be a non-empty array" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1396
|
-
return
|
|
1417
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1397
1418
|
}
|
|
1398
1419
|
// Limit bulk operations to prevent abuse
|
|
1399
1420
|
if (body.domains.length > 100) {
|
|
1400
1421
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Maximum 100 domains per bulk operation" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1401
|
-
return
|
|
1422
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1402
1423
|
}
|
|
1403
|
-
const reputationService = new
|
|
1424
|
+
const reputationService = new DomainReputationService(env);
|
|
1404
1425
|
const results = [];
|
|
1405
1426
|
// Process each domain
|
|
1406
1427
|
for (const domain of body.domains) {
|
|
@@ -1435,15 +1456,15 @@ exports.adminRoutes = [
|
|
|
1435
1456
|
failed: body.domains.length - successCount,
|
|
1436
1457
|
results,
|
|
1437
1458
|
}), { status: 200, headers: { "content-type": "application/json" } });
|
|
1438
|
-
return
|
|
1459
|
+
return addCorsHeaders(response, request, env);
|
|
1439
1460
|
}
|
|
1440
1461
|
catch (error) {
|
|
1441
1462
|
logger.error("[Admin] Error performing bulk operation:", error);
|
|
1442
1463
|
const errorResponse = securityHeaders.createSecureResponse(JSON.stringify({ error: "Failed to perform bulk operation" }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1443
|
-
return
|
|
1464
|
+
return addCorsHeaders(errorResponse, request, env);
|
|
1444
1465
|
}
|
|
1445
1466
|
},
|
|
1446
|
-
middleware: [
|
|
1467
|
+
middleware: [corsMiddleware(), csrfMiddleware()],
|
|
1447
1468
|
description: "Bulk domain operations (block/unblock/allowlist)",
|
|
1448
1469
|
},
|
|
1449
1470
|
];
|