@actuate-media/cms-core 0.10.4 → 0.11.1
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/dist/__tests__/actions/document-crud.test.js +5 -1
- package/dist/__tests__/actions/document-crud.test.js.map +1 -1
- package/dist/__tests__/api/admin-contracts.test.js +1 -0
- package/dist/__tests__/api/admin-contracts.test.js.map +1 -1
- package/dist/__tests__/api/public-globals.test.js +8 -4
- package/dist/__tests__/api/public-globals.test.js.map +1 -1
- package/dist/__tests__/auth/password.test.js.map +1 -1
- package/dist/__tests__/auth/session.test.js.map +1 -1
- package/dist/__tests__/codegen/generate-types.test.js.map +1 -1
- package/dist/__tests__/next.test.js +1 -3
- package/dist/__tests__/next.test.js.map +1 -1
- package/dist/__tests__/scheduling/scheduling.test.js +28 -4
- package/dist/__tests__/scheduling/scheduling.test.js.map +1 -1
- package/dist/__tests__/security/access.test.js +1 -1
- package/dist/__tests__/security/access.test.js.map +1 -1
- package/dist/__tests__/security/audit.test.d.ts +2 -0
- package/dist/__tests__/security/audit.test.d.ts.map +1 -0
- package/dist/__tests__/security/audit.test.js +50 -0
- package/dist/__tests__/security/audit.test.js.map +1 -0
- package/dist/__tests__/security/client-ip.test.d.ts +2 -0
- package/dist/__tests__/security/client-ip.test.d.ts.map +1 -0
- package/dist/__tests__/security/client-ip.test.js +37 -0
- package/dist/__tests__/security/client-ip.test.js.map +1 -0
- package/dist/__tests__/security/csrf.test.js.map +1 -1
- package/dist/__tests__/security/ip-allowlist.test.d.ts +2 -0
- package/dist/__tests__/security/ip-allowlist.test.d.ts.map +1 -0
- package/dist/__tests__/security/ip-allowlist.test.js +40 -0
- package/dist/__tests__/security/ip-allowlist.test.js.map +1 -0
- package/dist/__tests__/security/rate-limit.test.js.map +1 -1
- package/dist/__tests__/security/reauth.test.js.map +1 -1
- package/dist/__tests__/security/redact.test.d.ts +2 -0
- package/dist/__tests__/security/redact.test.d.ts.map +1 -0
- package/dist/__tests__/security/redact.test.js +31 -0
- package/dist/__tests__/security/redact.test.js.map +1 -0
- package/dist/__tests__/security/sanitize.test.js.map +1 -1
- package/dist/__tests__/security/secret-storage.test.d.ts +2 -0
- package/dist/__tests__/security/secret-storage.test.d.ts.map +1 -0
- package/dist/__tests__/security/secret-storage.test.js +42 -0
- package/dist/__tests__/security/secret-storage.test.js.map +1 -0
- package/dist/__tests__/security/upload-magic.test.d.ts +2 -0
- package/dist/__tests__/security/upload-magic.test.d.ts.map +1 -0
- package/dist/__tests__/security/upload-magic.test.js +55 -0
- package/dist/__tests__/security/upload-magic.test.js.map +1 -0
- package/dist/__tests__/server-site.test.d.ts +2 -0
- package/dist/__tests__/server-site.test.d.ts.map +1 -0
- package/dist/__tests__/server-site.test.js +123 -0
- package/dist/__tests__/server-site.test.js.map +1 -0
- package/dist/__tests__/site.test.js +5 -2
- package/dist/__tests__/site.test.js.map +1 -1
- package/dist/__tests__/webhooks/webhooks.test.js.map +1 -1
- package/dist/a11y/index.d.ts +1 -1
- package/dist/a11y/index.d.ts.map +1 -1
- package/dist/a11y/index.js +23 -20
- package/dist/a11y/index.js.map +1 -1
- package/dist/actions.d.ts +1 -1
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +211 -68
- package/dist/actions.js.map +1 -1
- package/dist/api/handler-factory.d.ts.map +1 -1
- package/dist/api/handler-factory.js +76 -14
- package/dist/api/handler-factory.js.map +1 -1
- package/dist/api/handlers.d.ts.map +1 -1
- package/dist/api/handlers.js +952 -220
- package/dist/api/handlers.js.map +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +182 -23
- package/dist/api/openapi.js.map +1 -1
- package/dist/api/router.d.ts +6 -6
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +27 -10
- package/dist/api/router.js.map +1 -1
- package/dist/auth/index.d.ts +12 -12
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +9 -9
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/mfa-pending.d.ts +24 -0
- package/dist/auth/mfa-pending.d.ts.map +1 -0
- package/dist/auth/mfa-pending.js +38 -0
- package/dist/auth/mfa-pending.js.map +1 -0
- package/dist/auth/oauth.d.ts +25 -3
- package/dist/auth/oauth.d.ts.map +1 -1
- package/dist/auth/oauth.js +118 -21
- package/dist/auth/oauth.js.map +1 -1
- package/dist/auth/password.d.ts +1 -1
- package/dist/auth/password.d.ts.map +1 -1
- package/dist/auth/password.js +14 -14
- package/dist/auth/password.js.map +1 -1
- package/dist/auth/providers/github.d.ts +1 -1
- package/dist/auth/providers/github.d.ts.map +1 -1
- package/dist/auth/providers/github.js +2 -2
- package/dist/auth/providers/github.js.map +1 -1
- package/dist/auth/providers/google.d.ts +1 -1
- package/dist/auth/providers/google.d.ts.map +1 -1
- package/dist/auth/providers/google.js +2 -2
- package/dist/auth/providers/google.js.map +1 -1
- package/dist/auth/providers/microsoft.d.ts +1 -1
- package/dist/auth/providers/microsoft.d.ts.map +1 -1
- package/dist/auth/providers/microsoft.js +2 -2
- package/dist/auth/providers/microsoft.js.map +1 -1
- package/dist/auth/reset-email.d.ts.map +1 -1
- package/dist/auth/reset-email.js +1 -1
- package/dist/auth/reset-email.js.map +1 -1
- package/dist/auth/reset.d.ts.map +1 -1
- package/dist/auth/reset.js +34 -10
- package/dist/auth/reset.js.map +1 -1
- package/dist/auth/session.d.ts +9 -2
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +26 -8
- package/dist/auth/session.js.map +1 -1
- package/dist/auth/totp.d.ts.map +1 -1
- package/dist/auth/totp.js +8 -2
- package/dist/auth/totp.js.map +1 -1
- package/dist/backup/index.d.ts +2 -2
- package/dist/backup/index.d.ts.map +1 -1
- package/dist/backup/index.js +5 -5
- package/dist/backup/index.js.map +1 -1
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -8
- package/dist/client.js.map +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/codegen/index.d.ts.map +1 -1
- package/dist/codegen/index.js +170 -174
- package/dist/codegen/index.js.map +1 -1
- package/dist/collections/index.d.ts +1 -1
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/collections/index.js.map +1 -1
- package/dist/config/define.d.ts +2 -2
- package/dist/config/define.d.ts.map +1 -1
- package/dist/config/define.js +1 -1
- package/dist/config/define.js.map +1 -1
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +32 -18
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +26 -26
- package/dist/config/types.d.ts.map +1 -1
- package/dist/content/ai-api.d.ts.map +1 -1
- package/dist/content/ai-api.js +8 -2
- package/dist/content/ai-api.js.map +1 -1
- package/dist/content/content-graph.d.ts +1 -1
- package/dist/content/content-graph.d.ts.map +1 -1
- package/dist/content/content-graph.js +7 -7
- package/dist/content/content-graph.js.map +1 -1
- package/dist/content/extract.js +13 -13
- package/dist/content/extract.js.map +1 -1
- package/dist/content/index.d.ts +7 -7
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +4 -4
- package/dist/content/index.js.map +1 -1
- package/dist/content/structured-data.d.ts +3 -3
- package/dist/content/structured-data.d.ts.map +1 -1
- package/dist/content/structured-data.js +65 -67
- package/dist/content/structured-data.js.map +1 -1
- package/dist/db/adapters/mysql.d.ts.map +1 -1
- package/dist/db/adapters/mysql.js.map +1 -1
- package/dist/db/adapters/postgres.d.ts.map +1 -1
- package/dist/db/adapters/postgres.js.map +1 -1
- package/dist/db/adapters/sqlite.d.ts.map +1 -1
- package/dist/db/adapters/sqlite.js.map +1 -1
- package/dist/db/create-adapter.d.ts.map +1 -1
- package/dist/db/create-adapter.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +1 -1
- package/dist/db.js.map +1 -1
- package/dist/fields/index.d.ts +2 -2
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js +51 -47
- package/dist/fields/index.js.map +1 -1
- package/dist/forms/analytics.d.ts.map +1 -1
- package/dist/forms/analytics.js.map +1 -1
- package/dist/forms/attribution.d.ts.map +1 -1
- package/dist/forms/attribution.js +7 -2
- package/dist/forms/attribution.js.map +1 -1
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js.map +1 -1
- package/dist/graphql/index.d.ts.map +1 -1
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/resolvers.d.ts.map +1 -1
- package/dist/graphql/resolvers.js +17 -21
- package/dist/graphql/resolvers.js.map +1 -1
- package/dist/graphql/schema-builder.d.ts.map +1 -1
- package/dist/graphql/schema-builder.js.map +1 -1
- package/dist/health/index.d.ts +2 -2
- package/dist/health/index.d.ts.map +1 -1
- package/dist/health/index.js +9 -9
- package/dist/health/index.js.map +1 -1
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.d.ts +78 -76
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -42
- package/dist/index.js.map +1 -1
- package/dist/media/index.d.ts +2 -2
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/optimize.d.ts.map +1 -1
- package/dist/media/optimize.js +7 -4
- package/dist/media/optimize.js.map +1 -1
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +21 -34
- package/dist/middleware.js.map +1 -1
- package/dist/multisite/index.d.ts.map +1 -1
- package/dist/multisite/index.js +4 -4
- package/dist/multisite/index.js.map +1 -1
- package/dist/next/preview.d.ts.map +1 -1
- package/dist/next/preview.js.map +1 -1
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +4 -5
- package/dist/next.js.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +5 -5
- package/dist/notifications/index.js.map +1 -1
- package/dist/page-builder/__tests__/a11y-fix.test.js +1 -5
- package/dist/page-builder/__tests__/a11y-fix.test.js.map +1 -1
- package/dist/page-builder/__tests__/blocks.test.js +108 -1
- package/dist/page-builder/__tests__/blocks.test.js.map +1 -1
- package/dist/page-builder/__tests__/design-scorer.test.js +44 -11
- package/dist/page-builder/__tests__/design-scorer.test.js.map +1 -1
- package/dist/page-builder/__tests__/schema.test.js +12 -12
- package/dist/page-builder/__tests__/schema.test.js.map +1 -1
- package/dist/page-builder/__tests__/seo-analyzer.test.js +27 -13
- package/dist/page-builder/__tests__/seo-analyzer.test.js.map +1 -1
- package/dist/page-builder/ai-pipeline.d.ts.map +1 -1
- package/dist/page-builder/ai-pipeline.js +1 -3
- package/dist/page-builder/ai-pipeline.js.map +1 -1
- package/dist/page-builder/blocks.d.ts +18 -1
- package/dist/page-builder/blocks.d.ts.map +1 -1
- package/dist/page-builder/blocks.js +67 -11
- package/dist/page-builder/blocks.js.map +1 -1
- package/dist/page-builder/design-scorer.d.ts.map +1 -1
- package/dist/page-builder/design-scorer.js +249 -41
- package/dist/page-builder/design-scorer.js.map +1 -1
- package/dist/page-builder/index.d.ts +3 -3
- package/dist/page-builder/index.d.ts.map +1 -1
- package/dist/page-builder/index.js +2 -2
- package/dist/page-builder/index.js.map +1 -1
- package/dist/page-builder/seo-analyzer.d.ts.map +1 -1
- package/dist/page-builder/seo-analyzer.js +252 -56
- package/dist/page-builder/seo-analyzer.js.map +1 -1
- package/dist/page-builder/templates.d.ts.map +1 -1
- package/dist/page-builder/templates.js +45 -16
- package/dist/page-builder/templates.js.map +1 -1
- package/dist/page-builder/tree.d.ts.map +1 -1
- package/dist/page-builder/tree.js.map +1 -1
- package/dist/page-builder/validate.js.map +1 -1
- package/dist/presence/index.d.ts.map +1 -1
- package/dist/presence/index.js +2 -2
- package/dist/presence/index.js.map +1 -1
- package/dist/preview/index.d.ts.map +1 -1
- package/dist/preview/index.js.map +1 -1
- package/dist/privacy/index.d.ts +1 -1
- package/dist/privacy/index.d.ts.map +1 -1
- package/dist/privacy/index.js +3 -3
- package/dist/privacy/index.js.map +1 -1
- package/dist/relationships/index.d.ts.map +1 -1
- package/dist/relationships/index.js +1 -1
- package/dist/relationships/index.js.map +1 -1
- package/dist/scheduling/index.d.ts +2 -2
- package/dist/scheduling/index.d.ts.map +1 -1
- package/dist/scheduling/index.js +3 -1
- package/dist/scheduling/index.js.map +1 -1
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -3
- package/dist/search/index.js.map +1 -1
- package/dist/security/access.d.ts +4 -4
- package/dist/security/access.d.ts.map +1 -1
- package/dist/security/access.js +11 -15
- package/dist/security/access.js.map +1 -1
- package/dist/security/anomaly-detection.d.ts.map +1 -1
- package/dist/security/anomaly-detection.js +5 -5
- package/dist/security/anomaly-detection.js.map +1 -1
- package/dist/security/api-key-enhanced.d.ts +2 -2
- package/dist/security/api-key-enhanced.d.ts.map +1 -1
- package/dist/security/api-key-enhanced.js +5 -5
- package/dist/security/api-key-enhanced.js.map +1 -1
- package/dist/security/audit.d.ts.map +1 -1
- package/dist/security/audit.js +8 -4
- package/dist/security/audit.js.map +1 -1
- package/dist/security/breach-check.js.map +1 -1
- package/dist/security/captcha.d.ts.map +1 -1
- package/dist/security/captcha.js.map +1 -1
- package/dist/security/client-ip.d.ts +33 -0
- package/dist/security/client-ip.d.ts.map +1 -0
- package/dist/security/client-ip.js +42 -0
- package/dist/security/client-ip.js.map +1 -0
- package/dist/security/cors.d.ts +1 -1
- package/dist/security/cors.d.ts.map +1 -1
- package/dist/security/cors.js +12 -12
- package/dist/security/cors.js.map +1 -1
- package/dist/security/csp-nonces.js +11 -11
- package/dist/security/csp-nonces.js.map +1 -1
- package/dist/security/csrf.js +2 -2
- package/dist/security/csrf.js.map +1 -1
- package/dist/security/encrypted-fields.d.ts.map +1 -1
- package/dist/security/encrypted-fields.js +7 -4
- package/dist/security/encrypted-fields.js.map +1 -1
- package/dist/security/headers.d.ts.map +1 -1
- package/dist/security/headers.js +12 -12
- package/dist/security/headers.js.map +1 -1
- package/dist/security/index.d.ts +39 -32
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +25 -20
- package/dist/security/index.js.map +1 -1
- package/dist/security/internal-keys.d.ts +15 -0
- package/dist/security/internal-keys.d.ts.map +1 -0
- package/dist/security/internal-keys.js +33 -0
- package/dist/security/internal-keys.js.map +1 -0
- package/dist/security/ip-allowlist.d.ts +13 -1
- package/dist/security/ip-allowlist.d.ts.map +1 -1
- package/dist/security/ip-allowlist.js +117 -11
- package/dist/security/ip-allowlist.js.map +1 -1
- package/dist/security/middleware.d.ts +2 -2
- package/dist/security/middleware.d.ts.map +1 -1
- package/dist/security/middleware.js +11 -11
- package/dist/security/middleware.js.map +1 -1
- package/dist/security/rate-limit.d.ts.map +1 -1
- package/dist/security/rate-limit.js +50 -18
- package/dist/security/rate-limit.js.map +1 -1
- package/dist/security/reauth.d.ts +1 -1
- package/dist/security/reauth.d.ts.map +1 -1
- package/dist/security/reauth.js.map +1 -1
- package/dist/security/redact.d.ts +12 -0
- package/dist/security/redact.d.ts.map +1 -0
- package/dist/security/redact.js +44 -0
- package/dist/security/redact.js.map +1 -0
- package/dist/security/safe-fetch.d.ts +35 -0
- package/dist/security/safe-fetch.d.ts.map +1 -0
- package/dist/security/safe-fetch.js +45 -0
- package/dist/security/safe-fetch.js.map +1 -0
- package/dist/security/sanitize.d.ts.map +1 -1
- package/dist/security/sanitize.js +40 -8
- package/dist/security/sanitize.js.map +1 -1
- package/dist/security/secret-storage.d.ts +22 -0
- package/dist/security/secret-storage.d.ts.map +1 -0
- package/dist/security/secret-storage.js +75 -0
- package/dist/security/secret-storage.js.map +1 -0
- package/dist/security/security-txt.d.ts.map +1 -1
- package/dist/security/security-txt.js +2 -2
- package/dist/security/security-txt.js.map +1 -1
- package/dist/security/session-limits.d.ts +1 -1
- package/dist/security/session-limits.d.ts.map +1 -1
- package/dist/security/session-limits.js +1 -1
- package/dist/security/session-limits.js.map +1 -1
- package/dist/security/upload.d.ts +23 -4
- package/dist/security/upload.d.ts.map +1 -1
- package/dist/security/upload.js +118 -23
- package/dist/security/upload.js.map +1 -1
- package/dist/security/webhook.d.ts.map +1 -1
- package/dist/security/webhook.js +12 -8
- package/dist/security/webhook.js.map +1 -1
- package/dist/seo/analysis.d.ts.map +1 -1
- package/dist/seo/analysis.js +25 -13
- package/dist/seo/analysis.js.map +1 -1
- package/dist/seo/index.d.ts +9 -9
- package/dist/seo/index.d.ts.map +1 -1
- package/dist/seo/index.js +4 -4
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/llms-txt.js +1 -3
- package/dist/seo/llms-txt.js.map +1 -1
- package/dist/server-site.d.ts +54 -0
- package/dist/server-site.d.ts.map +1 -0
- package/dist/server-site.js +147 -0
- package/dist/server-site.js.map +1 -0
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js.map +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +26 -4
- package/dist/site.js.map +1 -1
- package/dist/storage/index.d.ts +20 -10
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +6 -3
- package/dist/storage/index.js.map +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +3 -3
- package/dist/templates/index.js.map +1 -1
- package/dist/upgrade/changelog.d.ts +1 -1
- package/dist/upgrade/changelog.d.ts.map +1 -1
- package/dist/upgrade/changelog.js +12 -12
- package/dist/upgrade/changelog.js.map +1 -1
- package/dist/upgrade/index.d.ts +6 -6
- package/dist/upgrade/index.d.ts.map +1 -1
- package/dist/upgrade/index.js +3 -3
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/upgrade-pr.d.ts.map +1 -1
- package/dist/upgrade/upgrade-pr.js +36 -36
- package/dist/upgrade/upgrade-pr.js.map +1 -1
- package/dist/upgrade/version-check.d.ts +1 -1
- package/dist/upgrade/version-check.d.ts.map +1 -1
- package/dist/upgrade/version-check.js +13 -13
- package/dist/upgrade/version-check.js.map +1 -1
- package/dist/webhooks/index.d.ts +1 -1
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/index.js +24 -13
- package/dist/webhooks/index.js.map +1 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflows/index.d.ts +1 -1
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +3 -3
- package/dist/workflows/index.js.map +1 -1
- package/package.json +1 -1
- package/prisma/seed.ts +31 -31
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAGnD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEvD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAElE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAGjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAGzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAG5E,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAG1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAG1C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAGvD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAG3E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG9D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAG1D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAG7D,OAAO,EACL,aAAa,EACb,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralised list of "system" keys that may appear inside `Document.data`
|
|
3
|
+
* but are managed by the CMS rather than the user. Anything here is:
|
|
4
|
+
*
|
|
5
|
+
* - stripped from API responses (so internal scoring data isn't leaked)
|
|
6
|
+
* - allowed through field-level write access checks (so plugins can
|
|
7
|
+
* set them even when the field isn't declared in the collection)
|
|
8
|
+
*
|
|
9
|
+
* Keep this in lockstep with `actions.ts`/`access.ts` to avoid drift.
|
|
10
|
+
*/
|
|
11
|
+
export declare const INTERNAL_DATA_KEYS: Set<string>;
|
|
12
|
+
export declare function isInternalDataKey(key: string): boolean;
|
|
13
|
+
/** Return a shallow copy of `data` with all internal/system keys removed. */
|
|
14
|
+
export declare function stripInternalDataKeys<T extends Record<string, unknown>>(data: T): T;
|
|
15
|
+
//# sourceMappingURL=internal-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-keys.d.ts","sourceRoot":"","sources":["../../src/security/internal-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,aAQ7B,CAAA;AAEF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAOnF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralised list of "system" keys that may appear inside `Document.data`
|
|
3
|
+
* but are managed by the CMS rather than the user. Anything here is:
|
|
4
|
+
*
|
|
5
|
+
* - stripped from API responses (so internal scoring data isn't leaked)
|
|
6
|
+
* - allowed through field-level write access checks (so plugins can
|
|
7
|
+
* set them even when the field isn't declared in the collection)
|
|
8
|
+
*
|
|
9
|
+
* Keep this in lockstep with `actions.ts`/`access.ts` to avoid drift.
|
|
10
|
+
*/
|
|
11
|
+
export const INTERNAL_DATA_KEYS = new Set([
|
|
12
|
+
'_layout',
|
|
13
|
+
'_pageSettings',
|
|
14
|
+
'_aiScore',
|
|
15
|
+
'_embedding',
|
|
16
|
+
'_seoScore',
|
|
17
|
+
'_brandScore',
|
|
18
|
+
'_readabilityScore',
|
|
19
|
+
]);
|
|
20
|
+
export function isInternalDataKey(key) {
|
|
21
|
+
return key.startsWith('_') || INTERNAL_DATA_KEYS.has(key);
|
|
22
|
+
}
|
|
23
|
+
/** Return a shallow copy of `data` with all internal/system keys removed. */
|
|
24
|
+
export function stripInternalDataKeys(data) {
|
|
25
|
+
const out = {};
|
|
26
|
+
for (const [key, value] of Object.entries(data)) {
|
|
27
|
+
if (isInternalDataKey(key))
|
|
28
|
+
continue;
|
|
29
|
+
out[key] = value;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=internal-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-keys.js","sourceRoot":"","sources":["../../src/security/internal-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAS;IAChD,SAAS;IACT,eAAe;IACf,UAAU;IACV,YAAY;IACZ,WAAW;IACX,aAAa;IACb,mBAAmB;CACpB,CAAC,CAAA;AAEF,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAC3D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CAAoC,IAAO;IAC9E,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,iBAAiB,CAAC,GAAG,CAAC;YAAE,SAAQ;QACpC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAClB,CAAC;IACD,OAAO,GAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* IP allowlist matcher supporting both IPv4 and IPv6, including CIDR ranges.
|
|
3
|
+
*
|
|
4
|
+
* - Empty allowlist allows everything (the integrator opted out).
|
|
5
|
+
* - When the allowlist is non-empty, the literal `'unknown'` (the sentinel
|
|
6
|
+
* returned by the trusted-IP resolver when no proxy header was present)
|
|
7
|
+
* never matches.
|
|
8
|
+
* - IPv4 entries match IPv4 addresses (with optional `/n` CIDR mask, n=0..32).
|
|
9
|
+
* - IPv6 entries match IPv6 addresses (with optional `/n` CIDR mask, n=0..128).
|
|
10
|
+
* Two IPv6 strings are equal when their canonical 16-byte form matches —
|
|
11
|
+
* so `2001:db8::1` matches `2001:db8:0:0:0:0:0:1`.
|
|
12
|
+
* - Mapped IPv4-in-IPv6 addresses (`::ffff:1.2.3.4`) are normalised to IPv4.
|
|
13
|
+
*/
|
|
2
14
|
export declare function isIpAllowed(ip: string, allowlist: string[]): boolean;
|
|
3
15
|
//# sourceMappingURL=ip-allowlist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ip-allowlist.d.ts","sourceRoot":"","sources":["../../src/security/ip-allowlist.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ip-allowlist.d.ts","sourceRoot":"","sources":["../../src/security/ip-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAcpE"}
|
|
@@ -1,35 +1,141 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* IP allowlist matcher supporting both IPv4 and IPv6, including CIDR ranges.
|
|
3
|
+
*
|
|
4
|
+
* - Empty allowlist allows everything (the integrator opted out).
|
|
5
|
+
* - When the allowlist is non-empty, the literal `'unknown'` (the sentinel
|
|
6
|
+
* returned by the trusted-IP resolver when no proxy header was present)
|
|
7
|
+
* never matches.
|
|
8
|
+
* - IPv4 entries match IPv4 addresses (with optional `/n` CIDR mask, n=0..32).
|
|
9
|
+
* - IPv6 entries match IPv6 addresses (with optional `/n` CIDR mask, n=0..128).
|
|
10
|
+
* Two IPv6 strings are equal when their canonical 16-byte form matches —
|
|
11
|
+
* so `2001:db8::1` matches `2001:db8:0:0:0:0:0:1`.
|
|
12
|
+
* - Mapped IPv4-in-IPv6 addresses (`::ffff:1.2.3.4`) are normalised to IPv4.
|
|
13
|
+
*/
|
|
2
14
|
export function isIpAllowed(ip, allowlist) {
|
|
3
15
|
if (allowlist.length === 0)
|
|
4
16
|
return true;
|
|
17
|
+
if (!ip || ip === 'unknown')
|
|
18
|
+
return false;
|
|
19
|
+
const normalised = normaliseIp(ip);
|
|
5
20
|
for (const entry of allowlist) {
|
|
6
|
-
if (entry.includes(
|
|
7
|
-
if (isInCidr(
|
|
21
|
+
if (entry.includes('/')) {
|
|
22
|
+
if (isInCidr(normalised, entry))
|
|
8
23
|
return true;
|
|
9
24
|
}
|
|
10
|
-
else if (
|
|
25
|
+
else if (ipsEqual(normalised, normaliseIp(entry))) {
|
|
11
26
|
return true;
|
|
12
27
|
}
|
|
13
28
|
}
|
|
14
29
|
return false;
|
|
15
30
|
}
|
|
31
|
+
function ipsEqual(a, b) {
|
|
32
|
+
if (a === b)
|
|
33
|
+
return true;
|
|
34
|
+
// Compare IPv6 by canonical bytes so `2001:db8::1` === `2001:db8:0:0:0:0:0:1`.
|
|
35
|
+
if (a.includes(':') && b.includes(':')) {
|
|
36
|
+
const ca = canonicalIpv6(a);
|
|
37
|
+
const cb = canonicalIpv6(b);
|
|
38
|
+
return ca !== null && cb !== null && ca === cb;
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
function canonicalIpv6(ip) {
|
|
43
|
+
const bytes = ipv6ToBytes(ip);
|
|
44
|
+
if (!bytes)
|
|
45
|
+
return null;
|
|
46
|
+
let out = '';
|
|
47
|
+
for (let i = 0; i < 16; i++) {
|
|
48
|
+
out += (bytes[i] ?? 0).toString(16).padStart(2, '0');
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
function normaliseIp(ip) {
|
|
53
|
+
const trimmed = ip.trim();
|
|
54
|
+
// ::ffff:1.2.3.4 → 1.2.3.4
|
|
55
|
+
if (trimmed.toLowerCase().startsWith('::ffff:')) {
|
|
56
|
+
const v4 = trimmed.slice(7);
|
|
57
|
+
if (isValidIPv4(v4))
|
|
58
|
+
return v4;
|
|
59
|
+
}
|
|
60
|
+
return trimmed;
|
|
61
|
+
}
|
|
62
|
+
function isValidIPv4(s) {
|
|
63
|
+
const parts = s.split('.').map(Number);
|
|
64
|
+
return parts.length === 4 && parts.every((p) => Number.isInteger(p) && p >= 0 && p <= 255);
|
|
65
|
+
}
|
|
16
66
|
function isInCidr(ip, cidr) {
|
|
17
|
-
const [range, bitsStr] = cidr.split(
|
|
67
|
+
const [range, bitsStr] = cidr.split('/');
|
|
18
68
|
if (!range || !bitsStr)
|
|
19
69
|
return false;
|
|
20
70
|
const bits = parseInt(bitsStr, 10);
|
|
21
|
-
|
|
22
|
-
|
|
71
|
+
if (Number.isNaN(bits))
|
|
72
|
+
return false;
|
|
73
|
+
if (ip.includes(':') || range.includes(':')) {
|
|
74
|
+
return matchIpv6Cidr(ip, range, bits);
|
|
75
|
+
}
|
|
76
|
+
return matchIpv4Cidr(ip, range, bits);
|
|
77
|
+
}
|
|
78
|
+
function matchIpv4Cidr(ip, range, bits) {
|
|
79
|
+
if (bits < 0 || bits > 32)
|
|
80
|
+
return false;
|
|
81
|
+
const ipNum = ipv4ToNumber(ip);
|
|
82
|
+
const rangeNum = ipv4ToNumber(range);
|
|
23
83
|
if (ipNum === null || rangeNum === null)
|
|
24
84
|
return false;
|
|
85
|
+
if (bits === 0)
|
|
86
|
+
return true;
|
|
25
87
|
const mask = ~((1 << (32 - bits)) - 1) >>> 0;
|
|
26
88
|
return (ipNum & mask) === (rangeNum & mask);
|
|
27
89
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
if (parts.length !== 4 || parts.some((p) => isNaN(p) || p < 0 || p > 255)) {
|
|
90
|
+
function ipv4ToNumber(ip) {
|
|
91
|
+
if (!isValidIPv4(ip))
|
|
31
92
|
return null;
|
|
32
|
-
|
|
93
|
+
const parts = ip.split('.').map(Number);
|
|
33
94
|
return ((parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]) >>> 0;
|
|
34
95
|
}
|
|
96
|
+
function matchIpv6Cidr(ip, range, bits) {
|
|
97
|
+
if (bits < 0 || bits > 128)
|
|
98
|
+
return false;
|
|
99
|
+
const ipBytes = ipv6ToBytes(ip);
|
|
100
|
+
const rangeBytes = ipv6ToBytes(range);
|
|
101
|
+
if (!ipBytes || !rangeBytes)
|
|
102
|
+
return false;
|
|
103
|
+
let remaining = bits;
|
|
104
|
+
for (let i = 0; i < 16 && remaining > 0; i++) {
|
|
105
|
+
const take = Math.min(8, remaining);
|
|
106
|
+
const mask = (0xff << (8 - take)) & 0xff;
|
|
107
|
+
if ((ipBytes[i] & mask) !== (rangeBytes[i] & mask))
|
|
108
|
+
return false;
|
|
109
|
+
remaining -= take;
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
/** Expand the `::` shorthand and return 16 bytes; null when the input isn't a valid IPv6. */
|
|
114
|
+
function ipv6ToBytes(ip) {
|
|
115
|
+
// Reject IPv4-mapped form for the IPv6 path; caller normalises ::ffff:x.x.x.x first.
|
|
116
|
+
if (ip.includes('.'))
|
|
117
|
+
return null;
|
|
118
|
+
const halves = ip.split('::');
|
|
119
|
+
if (halves.length > 2)
|
|
120
|
+
return null;
|
|
121
|
+
const left = halves[0] ? halves[0].split(':') : [];
|
|
122
|
+
const groups = halves.length === 2 ? fillGroups(left, halves[1] ? halves[1].split(':') : []) : left;
|
|
123
|
+
if (groups.length !== 8)
|
|
124
|
+
return null;
|
|
125
|
+
const bytes = new Uint8Array(16);
|
|
126
|
+
for (let i = 0; i < 8; i++) {
|
|
127
|
+
const value = parseInt(groups[i] || '0', 16);
|
|
128
|
+
if (Number.isNaN(value) || value < 0 || value > 0xffff)
|
|
129
|
+
return null;
|
|
130
|
+
bytes[i * 2] = (value >> 8) & 0xff;
|
|
131
|
+
bytes[i * 2 + 1] = value & 0xff;
|
|
132
|
+
}
|
|
133
|
+
return bytes;
|
|
134
|
+
}
|
|
135
|
+
function fillGroups(left, right) {
|
|
136
|
+
const fill = 8 - left.length - right.length;
|
|
137
|
+
if (fill < 0)
|
|
138
|
+
return [];
|
|
139
|
+
return [...left, ...new Array(fill).fill('0'), ...right];
|
|
140
|
+
}
|
|
35
141
|
//# sourceMappingURL=ip-allowlist.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ip-allowlist.js","sourceRoot":"","sources":["../../src/security/ip-allowlist.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ip-allowlist.js","sourceRoot":"","sources":["../../src/security/ip-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,SAAmB;IACzD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACvC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAEzC,MAAM,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;IAElC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;QAC9C,CAAC;aAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACxB,+EAA+E;IAC/E,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;QAC3B,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;QAC3B,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,EAAE,CAAA;IAChD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;IAC7B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,EAAU;IAC7B,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;IACzB,2BAA2B;IAC3B,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChD,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC3B,IAAI,WAAW,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,CAAA;IAChC,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACtC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;AAC5F,CAAC;AAED,SAAS,QAAQ,CAAC,EAAU,EAAE,IAAY;IACxC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IAClC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAEpC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IACvC,CAAC;IACD,OAAO,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,EAAU,EAAE,KAAa,EAAE,IAAY;IAC5D,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,KAAK,CAAA;IACvC,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,CAAA;IAC9B,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IACrD,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;IAC5C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AAC7C,CAAC;AAED,SAAS,YAAY,CAAC,EAAU;IAC9B,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACvC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAA;AACrF,CAAC;AAED,SAAS,aAAa,CAAC,EAAU,EAAE,KAAa,EAAE,IAAY;IAC5D,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,GAAG;QAAE,OAAO,KAAK,CAAA;IACxC,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;IAC/B,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;IACrC,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAA;IACzC,IAAI,SAAS,GAAG,IAAI,CAAA;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAA;QACxC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QAClE,SAAS,IAAI,IAAI,CAAA;IACnB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,6FAA6F;AAC7F,SAAS,WAAW,CAAC,EAAU;IAC7B,qFAAqF;IACrF,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEjC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAElC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAClD,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAEtF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEpC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QAC5C,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,MAAM;YAAE,OAAO,IAAI,CAAA;QACnE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAA;QAClC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAA;IACjC,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,UAAU,CAAC,IAAc,EAAE,KAAe;IACjD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IAC3C,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IACvB,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,CAAA;AAC1D,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type SecurityHeadersConfig } from
|
|
2
|
-
import type { RateLimiter } from
|
|
1
|
+
import { type SecurityHeadersConfig } from './headers.js';
|
|
2
|
+
import type { RateLimiter } from './rate-limit.js';
|
|
3
3
|
export interface SecurityMiddlewareConfig {
|
|
4
4
|
headers?: SecurityHeadersConfig;
|
|
5
5
|
csrf?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/security/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/security/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAE7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,qBAAqB,CAAA;IAC/B,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,SAAS,CAAC,EAAE,WAAW,CAAA;IACvB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAA;CAC5C;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,4FAA4F;AAC5F,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CAiCnC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getSecurityHeaders } from
|
|
2
|
-
import { validateToken as validateCsrf } from
|
|
1
|
+
import { getSecurityHeaders } from './headers.js';
|
|
2
|
+
import { validateToken as validateCsrf } from './csrf.js';
|
|
3
3
|
/** Compose a security middleware pipeline that applies headers, CSRF, and rate limiting. */
|
|
4
4
|
export async function applySecurityMiddleware(request, config) {
|
|
5
5
|
const responseHeaders = getSecurityHeaders(config.headers);
|
|
@@ -10,22 +10,22 @@ export async function applySecurityMiddleware(request, config) {
|
|
|
10
10
|
return {
|
|
11
11
|
allowed: false,
|
|
12
12
|
headers: responseHeaders,
|
|
13
|
-
error:
|
|
13
|
+
error: 'Rate limit exceeded',
|
|
14
14
|
status: 429,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
-
responseHeaders[
|
|
18
|
-
responseHeaders[
|
|
17
|
+
responseHeaders['X-RateLimit-Remaining'] = String(result.remaining);
|
|
18
|
+
responseHeaders['X-RateLimit-Reset'] = result.resetAt.toISOString();
|
|
19
19
|
}
|
|
20
20
|
if (config.csrf?.enabled && isMutatingMethod(request.method)) {
|
|
21
|
-
const csrfToken = request.headers.get(
|
|
22
|
-
const cookieName = config.csrf.cookieName ??
|
|
23
|
-
const storedToken = parseCookie(request.headers.get(
|
|
21
|
+
const csrfToken = request.headers.get('x-csrf-token') ?? '';
|
|
22
|
+
const cookieName = config.csrf.cookieName ?? '__actuate_csrf';
|
|
23
|
+
const storedToken = parseCookie(request.headers.get('cookie') ?? '', cookieName);
|
|
24
24
|
if (!storedToken || !validateCsrf(csrfToken, storedToken)) {
|
|
25
25
|
return {
|
|
26
26
|
allowed: false,
|
|
27
27
|
headers: responseHeaders,
|
|
28
|
-
error:
|
|
28
|
+
error: 'Invalid CSRF token',
|
|
29
29
|
status: 403,
|
|
30
30
|
};
|
|
31
31
|
}
|
|
@@ -33,10 +33,10 @@ export async function applySecurityMiddleware(request, config) {
|
|
|
33
33
|
return { allowed: true, headers: responseHeaders };
|
|
34
34
|
}
|
|
35
35
|
function isMutatingMethod(method) {
|
|
36
|
-
return [
|
|
36
|
+
return ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method.toUpperCase());
|
|
37
37
|
}
|
|
38
38
|
function getClientIp(request) {
|
|
39
|
-
return request.headers.get(
|
|
39
|
+
return request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? 'unknown';
|
|
40
40
|
}
|
|
41
41
|
function parseCookie(cookieHeader, name) {
|
|
42
42
|
const match = cookieHeader.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/security/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA8B,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/security/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA8B,MAAM,cAAc,CAAA;AAC7E,OAAO,EAAE,aAAa,IAAI,YAAY,EAAE,MAAM,WAAW,CAAA;AAiBzD,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAgB,EAChB,MAAgC;IAEhC,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAE1D,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;QAClE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAChD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,eAAe;gBACxB,KAAK,EAAE,qBAAqB;gBAC5B,MAAM,EAAE,GAAG;aACZ,CAAA;QACH,CAAC;QACD,eAAe,CAAC,uBAAuB,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACnE,eAAe,CAAC,mBAAmB,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;IACrE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;QAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,gBAAgB,CAAA;QAC7D,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,UAAU,CAAC,CAAA;QAChF,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;YAC1D,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,eAAe;gBACxB,KAAK,EAAE,oBAAoB;gBAC3B,MAAM,EAAE,GAAG;aACZ,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,CAAA;AACpD,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc;IACtC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1E,CAAC;AAED,SAAS,WAAW,CAAC,OAAgB;IACnC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAA;AACnF,CAAC;AAED,SAAS,WAAW,CAAC,YAAoB,EAAE,IAAY;IACrD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,cAAc,IAAI,UAAU,CAAC,CAAC,CAAA;IAC1E,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/security/rate-limit.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/security/rate-limit.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,IAAI,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC5C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,4FAA4F;AAC5F,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CA4B9E;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAqF7E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAStE"}
|
|
@@ -31,38 +31,70 @@ export function createUpstashRateLimiter(config) {
|
|
|
31
31
|
if (!url || !token) {
|
|
32
32
|
throw new Error('UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN are required');
|
|
33
33
|
}
|
|
34
|
-
async function
|
|
35
|
-
|
|
34
|
+
async function redisPipeline(commands) {
|
|
35
|
+
// Upstash exposes pipelined commands via the /pipeline endpoint. Sending
|
|
36
|
+
// INCR + EXPIRE in a single round-trip eliminates the race where the
|
|
37
|
+
// process dies after INCR (or where EXPIRE silently fails) and leaves a
|
|
38
|
+
// counter that never resets — a subtle DoS where one unlucky user is
|
|
39
|
+
// permanently locked out.
|
|
40
|
+
const response = await fetch(`${url}/pipeline`, {
|
|
36
41
|
method: 'POST',
|
|
37
42
|
headers: {
|
|
38
43
|
Authorization: `Bearer ${token}`,
|
|
39
44
|
'Content-Type': 'application/json',
|
|
40
45
|
},
|
|
41
|
-
body: JSON.stringify(
|
|
46
|
+
body: JSON.stringify(commands),
|
|
42
47
|
});
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Upstash pipeline returned ${response.status}`);
|
|
50
|
+
}
|
|
51
|
+
const data = (await response.json());
|
|
52
|
+
return data.map((entry) => entry?.result);
|
|
45
53
|
}
|
|
46
54
|
const windowSec = Math.ceil(config.windowMs / 1000);
|
|
47
55
|
return {
|
|
48
56
|
async check(key) {
|
|
49
57
|
const redisKey = `ratelimit:${key}`;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
try {
|
|
59
|
+
const [count, _expireResult, ttl] = (await redisPipeline([
|
|
60
|
+
['INCR', redisKey],
|
|
61
|
+
['EXPIRE', redisKey, String(windowSec), 'NX'], // only set when no TTL exists
|
|
62
|
+
['TTL', redisKey],
|
|
63
|
+
]));
|
|
64
|
+
// Belt-and-braces: if Redis reports the key with no TTL, set one. This
|
|
65
|
+
// can only happen if the EXPIRE NX above wasn't supported, in which
|
|
66
|
+
// case we still want to bound the counter's lifetime.
|
|
67
|
+
if (ttl < 0) {
|
|
68
|
+
await redisPipeline([['EXPIRE', redisKey, String(windowSec)]]).catch(() => undefined);
|
|
69
|
+
}
|
|
70
|
+
const effectiveTtl = ttl > 0 ? ttl : windowSec;
|
|
71
|
+
const resetAt = new Date(Date.now() + effectiveTtl * 1000);
|
|
72
|
+
const allowed = count <= config.maxRequests;
|
|
73
|
+
return {
|
|
74
|
+
allowed,
|
|
75
|
+
remaining: Math.max(0, config.maxRequests - count),
|
|
76
|
+
resetAt,
|
|
77
|
+
retryAfter: allowed ? undefined : effectiveTtl,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
// Fail open with logging — a Redis outage should NOT take the entire
|
|
82
|
+
// CMS offline. Audit-level logging makes the degradation visible.
|
|
83
|
+
console.error('[actuate][rate-limit] Upstash request failed, allowing through:', err instanceof Error ? err.message : err);
|
|
84
|
+
return {
|
|
85
|
+
allowed: true,
|
|
86
|
+
remaining: Math.max(0, config.maxRequests - 1),
|
|
87
|
+
resetAt: new Date(Date.now() + config.windowMs),
|
|
88
|
+
};
|
|
53
89
|
}
|
|
54
|
-
const ttl = await redisCommand(['TTL', redisKey]);
|
|
55
|
-
const resetAt = new Date(Date.now() + (ttl > 0 ? ttl * 1000 : config.windowMs));
|
|
56
|
-
const allowed = count <= config.maxRequests;
|
|
57
|
-
return {
|
|
58
|
-
allowed,
|
|
59
|
-
remaining: Math.max(0, config.maxRequests - count),
|
|
60
|
-
resetAt,
|
|
61
|
-
retryAfter: allowed ? undefined : ttl > 0 ? ttl : Math.ceil(config.windowMs / 1000),
|
|
62
|
-
};
|
|
63
90
|
},
|
|
64
91
|
async reset(key) {
|
|
65
|
-
|
|
92
|
+
try {
|
|
93
|
+
await redisPipeline([['DEL', `ratelimit:${key}`]]);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
console.error('[actuate][rate-limit] Upstash reset failed:', err instanceof Error ? err.message : err);
|
|
97
|
+
}
|
|
66
98
|
},
|
|
67
99
|
};
|
|
68
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/security/rate-limit.ts"],"names":[],"mappings":"AAiBA,4FAA4F;AAC5F,MAAM,UAAU,yBAAyB,CAAC,MAAuB;IAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8C,
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/security/rate-limit.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ export interface ReauthContext {
|
|
|
9
9
|
/** Check whether a sensitive action requires re-authentication. */
|
|
10
10
|
export declare function requiresReauth(context: ReauthContext, config: ReauthConfig): boolean;
|
|
11
11
|
/** Verify re-authentication credentials (password or TOTP). */
|
|
12
|
-
export declare function verifyReauth(userId: string, credential: string, method:
|
|
12
|
+
export declare function verifyReauth(userId: string, credential: string, method: 'password' | 'totp', db?: any): Promise<boolean>;
|
|
13
13
|
/** Default configuration for sensitive actions requiring re-auth. */
|
|
14
14
|
export declare const DEFAULT_REAUTH_CONFIG: ReauthConfig;
|
|
15
15
|
//# sourceMappingURL=reauth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reauth.d.ts","sourceRoot":"","sources":["../../src/security/reauth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"reauth.d.ts","sourceRoot":"","sources":["../../src/security/reauth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,IAAI,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAIpF;AAED,+DAA+D;AAC/D,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,UAAU,GAAG,MAAM,EAC3B,EAAE,CAAC,EAAE,GAAG,GACP,OAAO,CAAC,OAAO,CAAC,CA8BlB;AAED,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,EAAE,YASnC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reauth.js","sourceRoot":"","sources":["../../src/security/reauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"reauth.js","sourceRoot":"","sources":["../../src/security/reauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAYpD,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,OAAsB,EAAE,MAAoB;IACzE,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IACrE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAA;IAClE,OAAO,OAAO,GAAG,MAAM,CAAC,aAAa,CAAA;AACvC,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,UAAkB,EAClB,MAA2B,EAC3B,EAAQ;IAER,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;QAC1C,EAAE,GAAG,KAAK,EAAE,CAAA;IACd,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC;YACpC,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;YACrB,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;SAChE,CAAC,CAAA;QAEF,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrE,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;QACtD,OAAO,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IAChD,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC;QACpC,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;QACrB,MAAM,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC/C,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;AACtD,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,aAAa,EAAE,GAAG;IAClB,kBAAkB,EAAE;QAClB,aAAa;QACb,kBAAkB;QAClB,iBAAiB;QACjB,aAAa;QACb,sBAAsB;KACvB;CACF,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort scrubber for secrets pasted into prompts, search queries, and
|
|
3
|
+
* other user-supplied text that ends up in audit logs. Replaces matched
|
|
4
|
+
* patterns with `[REDACTED]` so we don't store live keys/tokens in plain
|
|
5
|
+
* `details` JSON.
|
|
6
|
+
*
|
|
7
|
+
* This is defensive, not exhaustive — clients should never paste secrets
|
|
8
|
+
* into prompts in the first place. The patterns favour false negatives over
|
|
9
|
+
* false positives so we don't mangle legitimate content.
|
|
10
|
+
*/
|
|
11
|
+
export declare function redactSecrets(input: string): string;
|
|
12
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/security/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA4BH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort scrubber for secrets pasted into prompts, search queries, and
|
|
3
|
+
* other user-supplied text that ends up in audit logs. Replaces matched
|
|
4
|
+
* patterns with `[REDACTED]` so we don't store live keys/tokens in plain
|
|
5
|
+
* `details` JSON.
|
|
6
|
+
*
|
|
7
|
+
* This is defensive, not exhaustive — clients should never paste secrets
|
|
8
|
+
* into prompts in the first place. The patterns favour false negatives over
|
|
9
|
+
* false positives so we don't mangle legitimate content.
|
|
10
|
+
*/
|
|
11
|
+
const PATTERNS = [
|
|
12
|
+
// OpenAI / Anthropic / Google API keys
|
|
13
|
+
{ name: 'openai-key', regex: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
14
|
+
{ name: 'anthropic-key', regex: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g },
|
|
15
|
+
// Actuate API keys
|
|
16
|
+
{ name: 'actuate-key', regex: /\bact_[A-Za-z0-9_]{20,}\b/g },
|
|
17
|
+
// GitHub tokens
|
|
18
|
+
{ name: 'github-token', regex: /\bgh[opsu]_[A-Za-z0-9]{30,}\b/g },
|
|
19
|
+
// AWS access keys
|
|
20
|
+
{ name: 'aws-access-key', regex: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
21
|
+
// AWS secret access keys (40 char base64-ish, prefixed with common context words)
|
|
22
|
+
{
|
|
23
|
+
name: 'aws-secret',
|
|
24
|
+
regex: /\b(?:aws_secret_access_key|aws_secret|secret_key)\s*[:=]\s*["']?([A-Za-z0-9/+]{40})["']?/gi,
|
|
25
|
+
},
|
|
26
|
+
// JWTs (3 base64url segments)
|
|
27
|
+
{ name: 'jwt', regex: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
28
|
+
// Slack tokens
|
|
29
|
+
{ name: 'slack-token', regex: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g },
|
|
30
|
+
// Stripe keys
|
|
31
|
+
{ name: 'stripe-key', regex: /\b(?:sk|pk|rk)_(?:test|live)_[A-Za-z0-9]{20,}\b/g },
|
|
32
|
+
// Generic password assignment
|
|
33
|
+
{ name: 'password-assign', regex: /\b(?:password|passwd|pwd)\s*[:=]\s*["']([^"']{6,})["']/gi },
|
|
34
|
+
];
|
|
35
|
+
export function redactSecrets(input) {
|
|
36
|
+
if (!input)
|
|
37
|
+
return input;
|
|
38
|
+
let result = input;
|
|
39
|
+
for (const { regex } of PATTERNS) {
|
|
40
|
+
result = result.replace(regex, '[REDACTED]');
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/security/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,QAAQ,GAA2C;IACvD,uCAAuC;IACvC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,4BAA4B,EAAE;IAC3D,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,gCAAgC,EAAE;IAClE,mBAAmB;IACnB,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,4BAA4B,EAAE;IAC5D,gBAAgB;IAChB,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,gCAAgC,EAAE;IACjE,kBAAkB;IAClB,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,EAAE;IAC1D,kFAAkF;IAClF;QACE,IAAI,EAAE,YAAY;QAClB,KAAK,EACH,4FAA4F;KAC/F;IACD,8BAA8B;IAC9B,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,oEAAoE,EAAE;IAC5F,eAAe;IACf,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,mCAAmC,EAAE;IACnE,cAAc;IACd,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,kDAAkD,EAAE;IACjF,8BAA8B;IAC9B,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,0DAA0D,EAAE;CAC/F,CAAA;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,QAAQ,EAAE,CAAC;QACjC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Perform a `fetch()` with SSRF defenses applied:
|
|
3
|
+
*
|
|
4
|
+
* - Reject non-http/https URLs (no `file:`, `gopher:`, `data:`).
|
|
5
|
+
* - Reject hostnames that resolve to private/loopback IP literals
|
|
6
|
+
* (`10.x`, `127.x`, `169.254.x`, `192.168.x`, `::1`, …).
|
|
7
|
+
* - Reject `localhost` and `0.0.0.0`.
|
|
8
|
+
* - Disable HTTP redirects by default (`redirect: 'manual'`) — a 302 to an
|
|
9
|
+
* internal address would otherwise smuggle the request past the validator.
|
|
10
|
+
* - Apply a hard request timeout via `AbortSignal.timeout`.
|
|
11
|
+
*
|
|
12
|
+
* Use this for any internal `fetch()` call that targets a URL derived from
|
|
13
|
+
* user/admin input (webhooks, link health, image URL fetches, etc).
|
|
14
|
+
*
|
|
15
|
+
* Note: this guards against the URL **as written**. For full DNS-rebinding
|
|
16
|
+
* protection use `resolveAndCheck()` from `./webhook.js` to pre-resolve the
|
|
17
|
+
* hostname; on Node 20+ this can be combined with a custom dispatcher to bind
|
|
18
|
+
* the request to the resolved IP. The default policy here trades that
|
|
19
|
+
* protection for portability across runtimes (Edge, Bun, Workers).
|
|
20
|
+
*/
|
|
21
|
+
export interface SafeFetchOptions extends RequestInit {
|
|
22
|
+
/** Hard timeout applied via AbortSignal. Defaults to 5000ms. */
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
/** When true, allow following redirects. Each hop is re-validated. Default: false. */
|
|
25
|
+
followRedirects?: boolean;
|
|
26
|
+
/** Maximum number of redirect hops when followRedirects is true. Default: 3. */
|
|
27
|
+
maxRedirects?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare class SsrfBlockedError extends Error {
|
|
30
|
+
readonly url: string;
|
|
31
|
+
readonly reason: string;
|
|
32
|
+
constructor(url: string, reason: string);
|
|
33
|
+
}
|
|
34
|
+
export declare function safeFetch(url: string, options?: SafeFetchOptions): Promise<Response>;
|
|
35
|
+
//# sourceMappingURL=safe-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-fetch.d.ts","sourceRoot":"","sources":["../../src/security/safe-fetch.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sFAAsF;IACtF,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;gBACX,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAMxC;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsC9F"}
|