@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
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as jose from 'jose';
|
|
2
|
+
const ISSUER = 'actuate-cms';
|
|
3
|
+
const AUDIENCE = 'actuate-mfa-pending';
|
|
4
|
+
const TTL_SECONDS = 300; // 5 minutes
|
|
5
|
+
export async function createMfaPendingToken(payload, secret) {
|
|
6
|
+
const key = new TextEncoder().encode(secret);
|
|
7
|
+
return new jose.SignJWT({ ...payload })
|
|
8
|
+
.setProtectedHeader({ alg: 'HS256' })
|
|
9
|
+
.setIssuedAt()
|
|
10
|
+
.setIssuer(ISSUER)
|
|
11
|
+
.setAudience(AUDIENCE)
|
|
12
|
+
.setExpirationTime(`${TTL_SECONDS}s`)
|
|
13
|
+
.sign(key);
|
|
14
|
+
}
|
|
15
|
+
export async function verifyMfaPendingToken(token, secret) {
|
|
16
|
+
const key = new TextEncoder().encode(secret);
|
|
17
|
+
const { payload } = await jose.jwtVerify(token, key, {
|
|
18
|
+
issuer: ISSUER,
|
|
19
|
+
audience: AUDIENCE,
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
userId: String(payload.userId ?? ''),
|
|
23
|
+
fingerprint: String(payload.fingerprint ?? ''),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Compute a stable fingerprint of the request (IP + user-agent). Used so the
|
|
28
|
+
* MFA-pending token can only be redeemed from the same device that completed
|
|
29
|
+
* the password step.
|
|
30
|
+
*/
|
|
31
|
+
export async function computeRequestFingerprint(ip, userAgent) {
|
|
32
|
+
const data = new TextEncoder().encode(`${ip}::${userAgent ?? ''}`);
|
|
33
|
+
const digest = await crypto.subtle.digest('SHA-256', data);
|
|
34
|
+
return Array.from(new Uint8Array(digest))
|
|
35
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
36
|
+
.join('');
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=mfa-pending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-pending.js","sourceRoot":"","sources":["../../src/auth/mfa-pending.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAmB5B,MAAM,MAAM,GAAG,aAAa,CAAA;AAC5B,MAAM,QAAQ,GAAG,qBAAqB,CAAA;AACtC,MAAM,WAAW,GAAG,GAAG,CAAA,CAAC,YAAY;AAEpC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA0B,EAC1B,MAAc;IAEd,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5C,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;SACpC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,WAAW,EAAE;SACb,SAAS,CAAC,MAAM,CAAC;SACjB,WAAW,CAAC,QAAQ,CAAC;SACrB,iBAAiB,CAAC,GAAG,WAAW,GAAG,CAAC;SACpC,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAa,EACb,MAAc;IAEd,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE;QACnD,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,QAAQ;KACnB,CAAC,CAAA;IACF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QACpC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;KAC/C,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,EAAU,EACV,SAAwB;IAExB,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,EAAE,EAAE,CAAC,CAAA;IAClE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC1D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC"}
|
package/dist/auth/oauth.d.ts
CHANGED
|
@@ -13,6 +13,24 @@ export interface OAuthState {
|
|
|
13
13
|
provider: string;
|
|
14
14
|
codeVerifier: string;
|
|
15
15
|
returnTo: string;
|
|
16
|
+
/** Optional nonce that the callback compares against a cookie value to prevent state-replay. */
|
|
17
|
+
nonce?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface OAuthCallbackOptions {
|
|
20
|
+
/**
|
|
21
|
+
* When true, allow self-signup: an OAuth login with no matching local user
|
|
22
|
+
* creates a new CLIENT user. Defaults to false — without this flag, OAuth
|
|
23
|
+
* logins for unknown emails are rejected and an admin must invite the user.
|
|
24
|
+
*
|
|
25
|
+
* Even when enabled, the integrator should restrict provisioning further
|
|
26
|
+
* (for example, by checking the email domain) via the `onProvision` hook.
|
|
27
|
+
*/
|
|
28
|
+
allowSelfSignup?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Hook called immediately before a new user is created during self-signup.
|
|
31
|
+
* Throw to reject the signup with a custom error.
|
|
32
|
+
*/
|
|
33
|
+
onProvision?: (profile: OAuthUserProfile, provider: string) => Promise<void> | void;
|
|
16
34
|
}
|
|
17
35
|
export interface OAuthCallbackResult {
|
|
18
36
|
provider: string;
|
|
@@ -53,7 +71,9 @@ declare const PROVIDER_URLS: {
|
|
|
53
71
|
export type OAuthProviderType = keyof typeof PROVIDER_URLS;
|
|
54
72
|
export declare function generateCodeVerifier(): string;
|
|
55
73
|
export declare function generateCodeChallenge(codeVerifier: string): Promise<string>;
|
|
56
|
-
export declare function generateState(provider: string, codeVerifier: string, returnTo: string, secret: string): Promise<string>;
|
|
74
|
+
export declare function generateState(provider: string, codeVerifier: string, returnTo: string, secret: string, nonce?: string): Promise<string>;
|
|
75
|
+
/** Generate a random base64url nonce suitable for binding state to a browser cookie. */
|
|
76
|
+
export declare function generateOAuthNonce(): string;
|
|
57
77
|
export declare function verifyState(stateToken: string, secret: string): Promise<OAuthState>;
|
|
58
78
|
export declare function getAuthorizationUrl(provider: OAuthProviderType, config: OAuthProviderConfig, state: string, codeChallenge: string): string;
|
|
59
79
|
export declare function exchangeCodeForTokens(provider: OAuthProviderType, code: string, codeVerifier: string, config: OAuthProviderConfig): Promise<{
|
|
@@ -62,7 +82,9 @@ export declare function exchangeCodeForTokens(provider: OAuthProviderType, code:
|
|
|
62
82
|
refresh_token?: string;
|
|
63
83
|
}>;
|
|
64
84
|
export declare function getUserProfile(provider: OAuthProviderType, accessToken: string): Promise<OAuthUserProfile>;
|
|
65
|
-
export declare function handleOAuthCallback(provider: string, code: string, stateToken: string, providers: OAuthProviders, secret: string, db: any
|
|
85
|
+
export declare function handleOAuthCallback(provider: string, code: string, stateToken: string, providers: OAuthProviders, secret: string, db: any, options?: OAuthCallbackOptions & {
|
|
86
|
+
expectedNonce?: string | null;
|
|
87
|
+
}): Promise<{
|
|
66
88
|
token: string;
|
|
67
89
|
user: {
|
|
68
90
|
id: string;
|
|
@@ -78,7 +100,7 @@ export declare function initiateOAuth(_providerConfig: AuthProviderConfig, _call
|
|
|
78
100
|
}>;
|
|
79
101
|
/** @deprecated Use `handleOAuthCallback` — kept for backward compat with auth/index.ts re-exports */
|
|
80
102
|
export declare function handleCallback(_providerConfig: AuthProviderConfig, _code: string, _state: OAuthState): Promise<OAuthCallbackResult>;
|
|
81
|
-
/** Link an OAuth account to an existing user. */
|
|
103
|
+
/** Link an OAuth account to an existing, already-authenticated user. */
|
|
82
104
|
export declare function linkAccount(userId: string, result: OAuthCallbackResult, db: unknown): Promise<void>;
|
|
83
105
|
export {};
|
|
84
106
|
//# sourceMappingURL=oauth.d.ts.map
|
package/dist/auth/oauth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/oauth.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SignJWT, jwtVerify } from 'jose';
|
|
2
2
|
import { createSession } from './session.js';
|
|
3
|
+
import { encryptSecret } from '../security/secret-storage.js';
|
|
3
4
|
const PROVIDER_URLS = {
|
|
4
5
|
google: {
|
|
5
6
|
authorize: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
@@ -37,15 +38,23 @@ export async function generateCodeChallenge(codeVerifier) {
|
|
|
37
38
|
const digest = await crypto.subtle.digest('SHA-256', encoded);
|
|
38
39
|
return base64url(digest);
|
|
39
40
|
}
|
|
40
|
-
export async function generateState(provider, codeVerifier, returnTo, secret) {
|
|
41
|
+
export async function generateState(provider, codeVerifier, returnTo, secret, nonce) {
|
|
41
42
|
const secretKey = new TextEncoder().encode(secret);
|
|
42
|
-
|
|
43
|
+
const payload = nonce
|
|
44
|
+
? { provider, codeVerifier, returnTo, nonce }
|
|
45
|
+
: { provider, codeVerifier, returnTo };
|
|
46
|
+
return new SignJWT({ ...payload })
|
|
43
47
|
.setProtectedHeader({ alg: 'HS256' })
|
|
44
48
|
.setIssuedAt()
|
|
45
49
|
.setExpirationTime('10m')
|
|
46
50
|
.setIssuer('actuate-cms')
|
|
47
51
|
.sign(secretKey);
|
|
48
52
|
}
|
|
53
|
+
/** Generate a random base64url nonce suitable for binding state to a browser cookie. */
|
|
54
|
+
export function generateOAuthNonce() {
|
|
55
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
56
|
+
return base64url(bytes.buffer);
|
|
57
|
+
}
|
|
49
58
|
export async function verifyState(stateToken, secret) {
|
|
50
59
|
const secretKey = new TextEncoder().encode(secret);
|
|
51
60
|
const { payload } = await jwtVerify(stateToken, secretKey, { issuer: 'actuate-cms' });
|
|
@@ -106,7 +115,7 @@ export async function getUserProfile(provider, accessToken) {
|
|
|
106
115
|
},
|
|
107
116
|
});
|
|
108
117
|
if (emailRes.ok) {
|
|
109
|
-
const emails = await emailRes.json();
|
|
118
|
+
const emails = (await emailRes.json());
|
|
110
119
|
const primary = emails.find((e) => e.primary && e.verified) ?? emails.find((e) => e.verified);
|
|
111
120
|
if (primary)
|
|
112
121
|
email = primary.email;
|
|
@@ -134,11 +143,19 @@ export async function getUserProfile(provider, accessToken) {
|
|
|
134
143
|
avatar: data.picture,
|
|
135
144
|
};
|
|
136
145
|
}
|
|
137
|
-
export async function handleOAuthCallback(provider, code, stateToken, providers, secret, db) {
|
|
146
|
+
export async function handleOAuthCallback(provider, code, stateToken, providers, secret, db, options = {}) {
|
|
138
147
|
const state = await verifyState(stateToken, secret);
|
|
139
148
|
if (state.provider !== provider) {
|
|
140
149
|
throw new Error('Provider mismatch in OAuth state');
|
|
141
150
|
}
|
|
151
|
+
// Bind the state to the browser that initiated the flow. If the state was
|
|
152
|
+
// signed with a nonce, the same value must come back in the cookie that the
|
|
153
|
+
// /auth/oauth/:provider handler set.
|
|
154
|
+
if (state.nonce) {
|
|
155
|
+
if (!options.expectedNonce || options.expectedNonce !== state.nonce) {
|
|
156
|
+
throw new Error('OAuth state nonce mismatch — possible cross-site flow injection');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
142
159
|
const providerType = provider;
|
|
143
160
|
const providerConfig = providers[providerType];
|
|
144
161
|
if (!providerConfig) {
|
|
@@ -149,26 +166,83 @@ export async function handleOAuthCallback(provider, code, stateToken, providers,
|
|
|
149
166
|
if (!profile.email) {
|
|
150
167
|
throw new Error('OAuth provider did not return an email address');
|
|
151
168
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
169
|
+
const normalizedEmail = profile.email.toLowerCase().trim();
|
|
170
|
+
// Lookup precedence:
|
|
171
|
+
// 1. An existing OAuth account with the same (provider, providerAccountId).
|
|
172
|
+
// This is the only safe auto-link target — the provider asserted that
|
|
173
|
+
// this account is the same one the user previously linked.
|
|
174
|
+
// 2. Otherwise, an existing local user with the same email — but ONLY if
|
|
175
|
+
// they have no password set (i.e., this is a returning OAuth-only user
|
|
176
|
+
// whose account was provisioned by an earlier login). Linking a
|
|
177
|
+
// password-protected account requires the user to be already
|
|
178
|
+
// authenticated (use `linkAccount()` for that flow).
|
|
179
|
+
// 3. Otherwise, self-signup if `allowSelfSignup` is true; otherwise reject.
|
|
180
|
+
const oauthAccount = await db.oAuthAccount
|
|
181
|
+
?.findUnique?.({
|
|
182
|
+
where: { provider_providerAccountId: { provider, providerAccountId: profile.id } },
|
|
183
|
+
include: { user: true },
|
|
184
|
+
})
|
|
185
|
+
.catch(() => null);
|
|
186
|
+
let user = oauthAccount?.user ?? null;
|
|
187
|
+
if (!user) {
|
|
188
|
+
const candidate = await db.user.findFirst({
|
|
189
|
+
where: { email: { equals: normalizedEmail, mode: 'insensitive' } },
|
|
159
190
|
});
|
|
191
|
+
if (candidate) {
|
|
192
|
+
const hasPassword = typeof candidate.passwordHash === 'string' && candidate.passwordHash.length > 0;
|
|
193
|
+
if (hasPassword) {
|
|
194
|
+
// Refuse to silently link a password-protected account on the basis of
|
|
195
|
+
// a matched email. The legitimate user must explicitly link their
|
|
196
|
+
// account from inside the admin (an authenticated session).
|
|
197
|
+
throw new Error('An account already exists for this email. Sign in with your password and link your account from Settings to enable OAuth.');
|
|
198
|
+
}
|
|
199
|
+
user = candidate;
|
|
200
|
+
}
|
|
160
201
|
}
|
|
161
|
-
|
|
202
|
+
if (!user) {
|
|
203
|
+
if (!options.allowSelfSignup) {
|
|
204
|
+
throw new Error('No account found for this email. Ask an administrator to invite you before signing in with OAuth.');
|
|
205
|
+
}
|
|
206
|
+
if (options.onProvision) {
|
|
207
|
+
await options.onProvision(profile, provider);
|
|
208
|
+
}
|
|
162
209
|
user = await db.user.create({
|
|
163
210
|
data: {
|
|
164
|
-
email:
|
|
211
|
+
email: normalizedEmail,
|
|
165
212
|
name: profile.name,
|
|
166
213
|
role: 'CLIENT',
|
|
167
214
|
isActive: true,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
215
|
+
passwordHash: null,
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// Ensure an OAuthAccount row exists for this (provider, providerAccountId)
|
|
220
|
+
// and store the access/refresh tokens encrypted at rest. Use upsert against
|
|
221
|
+
// the unique compound index so we never overwrite a different user's link.
|
|
222
|
+
if (db.oAuthAccount?.upsert) {
|
|
223
|
+
const accessTokenEncrypted = tokens.access_token
|
|
224
|
+
? await encryptSecret(tokens.access_token)
|
|
225
|
+
: null;
|
|
226
|
+
const refreshTokenEncrypted = tokens.refresh_token
|
|
227
|
+
? await encryptSecret(tokens.refresh_token)
|
|
228
|
+
: null;
|
|
229
|
+
await db.oAuthAccount
|
|
230
|
+
.upsert({
|
|
231
|
+
where: { provider_providerAccountId: { provider, providerAccountId: profile.id } },
|
|
232
|
+
create: {
|
|
233
|
+
userId: user.id,
|
|
234
|
+
provider,
|
|
235
|
+
providerAccountId: profile.id,
|
|
236
|
+
accessToken: accessTokenEncrypted,
|
|
237
|
+
refreshToken: refreshTokenEncrypted,
|
|
238
|
+
},
|
|
239
|
+
update: {
|
|
240
|
+
accessToken: accessTokenEncrypted,
|
|
241
|
+
refreshToken: refreshTokenEncrypted,
|
|
171
242
|
},
|
|
243
|
+
})
|
|
244
|
+
.catch((err) => {
|
|
245
|
+
console.error('[actuate][oauth] Failed to persist OAuthAccount:', err instanceof Error ? err.message : err);
|
|
172
246
|
});
|
|
173
247
|
}
|
|
174
248
|
const oauthSession = await db.session.create({
|
|
@@ -191,11 +265,34 @@ export async function initiateOAuth(_providerConfig, _callbackUrl) {
|
|
|
191
265
|
export async function handleCallback(_providerConfig, _code, _state) {
|
|
192
266
|
throw new Error('Use handleOAuthCallback instead');
|
|
193
267
|
}
|
|
194
|
-
/** Link an OAuth account to an existing user. */
|
|
268
|
+
/** Link an OAuth account to an existing, already-authenticated user. */
|
|
195
269
|
export async function linkAccount(userId, result, db) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
270
|
+
const d = db;
|
|
271
|
+
const accessToken = result.accessToken ? await encryptSecret(result.accessToken) : null;
|
|
272
|
+
const refreshToken = result.refreshToken ? await encryptSecret(result.refreshToken) : null;
|
|
273
|
+
if (d.oAuthAccount?.upsert) {
|
|
274
|
+
await d.oAuthAccount.upsert({
|
|
275
|
+
where: {
|
|
276
|
+
provider_providerAccountId: {
|
|
277
|
+
provider: result.provider,
|
|
278
|
+
providerAccountId: result.providerAccountId,
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
create: {
|
|
282
|
+
userId,
|
|
283
|
+
provider: result.provider,
|
|
284
|
+
providerAccountId: result.providerAccountId,
|
|
285
|
+
accessToken,
|
|
286
|
+
refreshToken,
|
|
287
|
+
expiresAt: result.expiresAt ?? null,
|
|
288
|
+
},
|
|
289
|
+
update: {
|
|
290
|
+
userId,
|
|
291
|
+
accessToken,
|
|
292
|
+
refreshToken,
|
|
293
|
+
expiresAt: result.expiresAt ?? null,
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
}
|
|
200
297
|
}
|
|
201
298
|
//# sourceMappingURL=oauth.js.map
|
package/dist/auth/oauth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/password.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PasswordPolicy } from
|
|
1
|
+
import type { PasswordPolicy } from '../config/types.js';
|
|
2
2
|
/** Hash a password using Web Crypto API (PBKDF2). */
|
|
3
3
|
export declare function hashPassword(password: string): Promise<string>;
|
|
4
4
|
/** Verify a password against its stored hash. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGxD,qDAAqD;AACrD,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBpE;AAED,iDAAiD;AACjD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqB3F;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAoBtC;AAED,6EAA6E;AAC7E,OAAO,EAAE,aAAa,IAAI,mBAAmB,EAAE,MAAM,6BAA6B,CAAA"}
|
package/dist/auth/password.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { timingSafeEqual } from
|
|
1
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
2
2
|
/** Hash a password using Web Crypto API (PBKDF2). */
|
|
3
3
|
export async function hashPassword(password) {
|
|
4
4
|
const salt = crypto.getRandomValues(new Uint8Array(16));
|
|
5
|
-
const key = await crypto.subtle.importKey(
|
|
6
|
-
const derived = await crypto.subtle.deriveBits({ name:
|
|
7
|
-
const saltHex = Buffer.from(salt).toString(
|
|
8
|
-
const hashHex = Buffer.from(derived).toString(
|
|
5
|
+
const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveBits']);
|
|
6
|
+
const derived = await crypto.subtle.deriveBits({ name: 'PBKDF2', salt, iterations: 100_000, hash: 'SHA-256' }, key, 256);
|
|
7
|
+
const saltHex = Buffer.from(salt).toString('hex');
|
|
8
|
+
const hashHex = Buffer.from(derived).toString('hex');
|
|
9
9
|
return `pbkdf2:100000:${saltHex}:${hashHex}`;
|
|
10
10
|
}
|
|
11
11
|
/** Verify a password against its stored hash. */
|
|
12
12
|
export async function verifyPassword(password, storedHash) {
|
|
13
|
-
const [, , saltHex, hashHex] = storedHash.split(
|
|
13
|
+
const [, , saltHex, hashHex] = storedHash.split(':');
|
|
14
14
|
if (!saltHex || !hashHex)
|
|
15
15
|
return false;
|
|
16
|
-
const salt = Buffer.from(saltHex,
|
|
17
|
-
const key = await crypto.subtle.importKey(
|
|
18
|
-
const derived = await crypto.subtle.deriveBits({ name:
|
|
16
|
+
const salt = Buffer.from(saltHex, 'hex');
|
|
17
|
+
const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveBits']);
|
|
18
|
+
const derived = await crypto.subtle.deriveBits({ name: 'PBKDF2', salt, iterations: 100_000, hash: 'SHA-256' }, key, 256);
|
|
19
19
|
const derivedBuf = Buffer.from(derived);
|
|
20
|
-
const storedBuf = Buffer.from(hashHex,
|
|
20
|
+
const storedBuf = Buffer.from(hashHex, 'hex');
|
|
21
21
|
if (derivedBuf.length !== storedBuf.length)
|
|
22
22
|
return false;
|
|
23
23
|
return timingSafeEqual(derivedBuf, storedBuf);
|
|
@@ -29,16 +29,16 @@ export function validatePasswordPolicy(password, policy) {
|
|
|
29
29
|
errors.push(`Password must be at least ${policy.minLength} characters`);
|
|
30
30
|
}
|
|
31
31
|
if (policy.requireUppercase && !/[A-Z]/.test(password)) {
|
|
32
|
-
errors.push(
|
|
32
|
+
errors.push('Password must contain an uppercase letter');
|
|
33
33
|
}
|
|
34
34
|
if (policy.requireLowercase && !/[a-z]/.test(password)) {
|
|
35
|
-
errors.push(
|
|
35
|
+
errors.push('Password must contain a lowercase letter');
|
|
36
36
|
}
|
|
37
37
|
if (policy.requireNumbers && !/\d/.test(password)) {
|
|
38
|
-
errors.push(
|
|
38
|
+
errors.push('Password must contain a digit');
|
|
39
39
|
}
|
|
40
40
|
if (policy.requireSpecialChars && !/[^a-zA-Z0-9]/.test(password)) {
|
|
41
|
-
errors.push(
|
|
41
|
+
errors.push('Password must contain a special character');
|
|
42
42
|
}
|
|
43
43
|
return { valid: errors.length === 0, errors };
|
|
44
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,CAOjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../../src/auth/providers/github.ts"],"names":[],"mappings":"AAQA,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../../src/auth/providers/github.ts"],"names":[],"mappings":"AAQA,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/google.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/google.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,CAOjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/auth/providers/google.ts"],"names":[],"mappings":"AAQA,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/auth/providers/google.ts"],"names":[],"mappings":"AAQA,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"microsoft.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/microsoft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"microsoft.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/microsoft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,kBAAkB,CAQvF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** Create a Microsoft Entra ID (Azure AD) OAuth provider configuration. */
|
|
2
2
|
export function microsoftProvider(options) {
|
|
3
3
|
return {
|
|
4
|
-
id:
|
|
5
|
-
type:
|
|
4
|
+
id: 'microsoft',
|
|
5
|
+
type: 'microsoft',
|
|
6
6
|
clientId: options.clientId,
|
|
7
7
|
clientSecret: options.clientSecret,
|
|
8
8
|
tenantId: options.tenantId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"microsoft.js","sourceRoot":"","sources":["../../../src/auth/providers/microsoft.ts"],"names":[],"mappings":"AAQA,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,OAAiC;IACjE,OAAO;QACL,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,
|
|
1
|
+
{"version":3,"file":"microsoft.js","sourceRoot":"","sources":["../../../src/auth/providers/microsoft.ts"],"names":[],"mappings":"AAQA,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,OAAiC;IACjE,OAAO;QACL,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset-email.d.ts","sourceRoot":"","sources":["../../src/auth/reset-email.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"reset-email.d.ts","sourceRoot":"","sources":["../../src/auth/reset-email.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IACnF,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CA2BA"}
|
package/dist/auth/reset-email.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Generates a password reset email with a one-click reset link. */
|
|
2
2
|
export function passwordResetTemplate(args) {
|
|
3
3
|
return {
|
|
4
|
-
subject:
|
|
4
|
+
subject: 'Reset your password',
|
|
5
5
|
html: `<!DOCTYPE html>
|
|
6
6
|
<html>
|
|
7
7
|
<head><meta charset="utf-8"></head>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset-email.js","sourceRoot":"","sources":["../../src/auth/reset-email.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,UAAU,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"reset-email.js","sourceRoot":"","sources":["../../src/auth/reset-email.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,UAAU,qBAAqB,CAAC,IAA4C;IAKhF,OAAO;QACL,OAAO,EAAE,qBAAqB;QAC9B,IAAI,EAAE;;;;;;;;;eASK,IAAI,CAAC,QAAQ;;mBAET,IAAI,CAAC,QAAQ;;;;;;;;;;QAUxB;QACJ,IAAI,EAAE,MAAM,IAAI,CAAC,QAAQ,mGAAmG,IAAI,CAAC,QAAQ,gGAAgG;KAC1O,CAAA;AACH,CAAC"}
|
package/dist/auth/reset.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/auth/reset.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/auth/reset.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;CACb;AAID,4EAA4E;AAC5E,wBAAgB,kBAAkB,IAAI,UAAU,CAI/C;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,GAAG,EACP,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IACN,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE;YACN,IAAI,EAAE,CAAC,IAAI,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;SAC5F,CAAA;KACF,CAAA;CACF,GACA,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,GAAG,EACP,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuD/C"}
|