@bajustone/fortress 1.0.0-rc.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/CHANGELOG.md +1011 -0
- package/LICENSE +21 -0
- package/README.md +760 -0
- package/SECURITY.md +197 -0
- package/bin/fortress.ts +667 -0
- package/dist/auth-service-BcyQ2PuZ.d.cts +307 -0
- package/dist/auth-service-BkzZkWfH.d.ts +307 -0
- package/dist/config-B2366s_G.d.ts +665 -0
- package/dist/config-GtlVt6ZD.d.cts +665 -0
- package/dist/convert-routes-BLCQT57f.d.ts +72 -0
- package/dist/convert-routes-BdMvP2_X.d.cts +72 -0
- package/dist/crypto.cjs +61 -0
- package/dist/crypto.d.cts +36 -0
- package/dist/crypto.d.ts +36 -0
- package/dist/crypto.js +35 -0
- package/dist/drift-BT1wtMDJ.d.cts +22 -0
- package/dist/drift-k9LiYpRP.d.ts +22 -0
- package/dist/drizzle/pg.cjs +481 -0
- package/dist/drizzle/pg.d.cts +15 -0
- package/dist/drizzle/pg.d.ts +15 -0
- package/dist/drizzle/pg.js +454 -0
- package/dist/drizzle.cjs +1442 -0
- package/dist/drizzle.d.cts +85 -0
- package/dist/drizzle.d.ts +85 -0
- package/dist/drizzle.js +1411 -0
- package/dist/express.cjs +1357 -0
- package/dist/express.d.cts +333 -0
- package/dist/express.d.ts +333 -0
- package/dist/express.js +1314 -0
- package/dist/fetcher.cjs +77 -0
- package/dist/fetcher.d.cts +7 -0
- package/dist/fetcher.d.ts +7 -0
- package/dist/fetcher.js +41 -0
- package/dist/fortress-BmSvFfqK.d.cts +1089 -0
- package/dist/fortress-uA-_cheR.d.ts +1089 -0
- package/dist/hono.cjs +1530 -0
- package/dist/hono.d.cts +514 -0
- package/dist/hono.d.ts +514 -0
- package/dist/hono.js +1483 -0
- package/dist/index-CxEkfCA0.d.cts +77 -0
- package/dist/index-CxEkfCA0.d.ts +77 -0
- package/dist/index-D054pcb-.d.cts +146 -0
- package/dist/index-jAMbbUAY.d.ts +146 -0
- package/dist/index.cjs +9046 -0
- package/dist/index.d.cts +717 -0
- package/dist/index.d.ts +717 -0
- package/dist/index.js +8935 -0
- package/dist/jwt.cjs +255 -0
- package/dist/jwt.d.cts +90 -0
- package/dist/jwt.d.ts +90 -0
- package/dist/jwt.js +227 -0
- package/dist/otel.cjs +108 -0
- package/dist/otel.d.cts +62 -0
- package/dist/otel.d.ts +62 -0
- package/dist/otel.js +73 -0
- package/dist/plugins/account-lockout.cjs +322 -0
- package/dist/plugins/account-lockout.d.cts +42 -0
- package/dist/plugins/account-lockout.d.ts +42 -0
- package/dist/plugins/account-lockout.js +295 -0
- package/dist/plugins/admin.cjs +2378 -0
- package/dist/plugins/admin.d.cts +72 -0
- package/dist/plugins/admin.d.ts +72 -0
- package/dist/plugins/admin.js +2351 -0
- package/dist/plugins/api-key.cjs +792 -0
- package/dist/plugins/api-key.d.cts +121 -0
- package/dist/plugins/api-key.d.ts +121 -0
- package/dist/plugins/api-key.js +765 -0
- package/dist/plugins/audit-log.cjs +493 -0
- package/dist/plugins/audit-log.d.cts +86 -0
- package/dist/plugins/audit-log.d.ts +86 -0
- package/dist/plugins/audit-log.js +468 -0
- package/dist/plugins/data-isolation.cjs +211 -0
- package/dist/plugins/data-isolation.d.cts +49 -0
- package/dist/plugins/data-isolation.d.ts +49 -0
- package/dist/plugins/data-isolation.js +186 -0
- package/dist/plugins/email-verification.cjs +273 -0
- package/dist/plugins/email-verification.d.cts +44 -0
- package/dist/plugins/email-verification.d.ts +44 -0
- package/dist/plugins/email-verification.js +246 -0
- package/dist/plugins/magic-link.cjs +231 -0
- package/dist/plugins/magic-link.d.cts +39 -0
- package/dist/plugins/magic-link.d.ts +39 -0
- package/dist/plugins/magic-link.js +204 -0
- package/dist/plugins/oauth.cjs +1696 -0
- package/dist/plugins/oauth.d.cts +406 -0
- package/dist/plugins/oauth.d.ts +406 -0
- package/dist/plugins/oauth.js +1669 -0
- package/dist/plugins/openapi.cjs +1185 -0
- package/dist/plugins/openapi.d.cts +6 -0
- package/dist/plugins/openapi.d.ts +6 -0
- package/dist/plugins/openapi.js +1158 -0
- package/dist/plugins/rate-limit/express.cjs +55 -0
- package/dist/plugins/rate-limit/express.d.cts +64 -0
- package/dist/plugins/rate-limit/express.d.ts +64 -0
- package/dist/plugins/rate-limit/express.js +30 -0
- package/dist/plugins/rate-limit/hono.cjs +51 -0
- package/dist/plugins/rate-limit/hono.d.cts +59 -0
- package/dist/plugins/rate-limit/hono.d.ts +59 -0
- package/dist/plugins/rate-limit/hono.js +26 -0
- package/dist/plugins/rate-limit/sveltekit.cjs +49 -0
- package/dist/plugins/rate-limit/sveltekit.d.cts +59 -0
- package/dist/plugins/rate-limit/sveltekit.d.ts +59 -0
- package/dist/plugins/rate-limit/sveltekit.js +24 -0
- package/dist/plugins/rate-limit.cjs +354 -0
- package/dist/plugins/rate-limit.d.cts +140 -0
- package/dist/plugins/rate-limit.d.ts +140 -0
- package/dist/plugins/rate-limit.js +325 -0
- package/dist/plugins/social-login.cjs +905 -0
- package/dist/plugins/social-login.d.cts +114 -0
- package/dist/plugins/social-login.d.ts +114 -0
- package/dist/plugins/social-login.js +880 -0
- package/dist/plugins/tenancy.cjs +780 -0
- package/dist/plugins/tenancy.d.cts +108 -0
- package/dist/plugins/tenancy.d.ts +108 -0
- package/dist/plugins/tenancy.js +753 -0
- package/dist/plugins/two-factor.cjs +555 -0
- package/dist/plugins/two-factor.d.cts +67 -0
- package/dist/plugins/two-factor.d.ts +67 -0
- package/dist/plugins/two-factor.js +526 -0
- package/dist/plugins/webauthn.cjs +786 -0
- package/dist/plugins/webauthn.d.cts +72 -0
- package/dist/plugins/webauthn.d.ts +72 -0
- package/dist/plugins/webauthn.js +766 -0
- package/dist/plugins/webhook.cjs +819 -0
- package/dist/plugins/webhook.d.cts +254 -0
- package/dist/plugins/webhook.d.ts +254 -0
- package/dist/plugins/webhook.js +789 -0
- package/dist/protect-D1v_0upK.d.cts +123 -0
- package/dist/protect-DsxV_-dJ.d.ts +123 -0
- package/dist/sveltekit.cjs +1258 -0
- package/dist/sveltekit.d.cts +420 -0
- package/dist/sveltekit.d.ts +420 -0
- package/dist/sveltekit.js +1207 -0
- package/dist/testing.cjs +4294 -0
- package/dist/testing.d.cts +197 -0
- package/dist/testing.d.ts +197 -0
- package/dist/testing.js +4264 -0
- package/dist/types-et0R8tsC.d.cts +217 -0
- package/dist/types-et0R8tsC.d.ts +217 -0
- package/docs/adapter-typed-helpers.md +192 -0
- package/docs/admin-recipes.md +227 -0
- package/docs/architecture.md +434 -0
- package/docs/ci/github-actions.yml +59 -0
- package/docs/ci.md +109 -0
- package/docs/compatibility.md +115 -0
- package/docs/deployment.md +305 -0
- package/docs/hardening.md +118 -0
- package/docs/host-owned-routes.md +154 -0
- package/docs/migrations/0001-schema-version.md +54 -0
- package/docs/migrations/0002-initial-schema.md +84 -0
- package/docs/migrations/upgrade-guide.md +160 -0
- package/docs/observability.md +394 -0
- package/docs/plugins/account-lockout.md +131 -0
- package/docs/plugins/admin.md +402 -0
- package/docs/plugins/api-key.md +327 -0
- package/docs/plugins/audit-log.md +261 -0
- package/docs/plugins/data-isolation.md +186 -0
- package/docs/plugins/email-verification.md +121 -0
- package/docs/plugins/magic-link.md +123 -0
- package/docs/plugins/oauth.md +544 -0
- package/docs/plugins/openapi.md +250 -0
- package/docs/plugins/rate-limit.md +223 -0
- package/docs/plugins/social-login.md +337 -0
- package/docs/plugins/tenancy.md +122 -0
- package/docs/plugins/two-factor.md +191 -0
- package/docs/plugins/webauthn.md +188 -0
- package/docs/plugins/webhook.md +242 -0
- package/docs/policy-as-code.md +156 -0
- package/docs/route-manifest.md +46 -0
- package/docs/security.md +261 -0
- package/docs/threat-model.md +161 -0
- package/examples/README.md +119 -0
- package/examples/express-app/index.ts +747 -0
- package/examples/hono-app/docker-compose.yml +14 -0
- package/examples/hono-app/index.ts +1009 -0
- package/examples/policy/fortress.policy.json +47 -0
- package/examples/sveltekit-app/README.md +125 -0
- package/examples/sveltekit-app/src/app.d.ts +16 -0
- package/examples/sveltekit-app/src/hooks.server.ts +23 -0
- package/examples/sveltekit-app/src/lib/server/fortress.ts +81 -0
- package/examples/sveltekit-app/src/routes/api/echo/[id]/+server.ts +32 -0
- package/examples/sveltekit-app/src/routes/api/fortress/[...path]/+server.ts +15 -0
- package/examples/sveltekit-app/src/routes/dashboard/+page.server.ts +20 -0
- package/examples/sveltekit-app/src/routes/login/+page.server.ts +48 -0
- package/examples/sveltekit-app/src/routes/oauth/consent/+page.server.ts +69 -0
- package/examples/sveltekit-app/src/routes/oauth/consent/+page.svelte +83 -0
- package/migrations/pg/0001_schema_version.down.sql +2 -0
- package/migrations/pg/0001_schema_version.sql +8 -0
- package/migrations/pg/0002_initial_schema.down.sql +36 -0
- package/migrations/pg/0002_initial_schema.sql +376 -0
- package/migrations/pg/0003_auth_continuation.down.sql +6 -0
- package/migrations/pg/0003_auth_continuation.sql +30 -0
- package/migrations/pg/0004_tenant_default_unique.down.sql +1 -0
- package/migrations/pg/0004_tenant_default_unique.sql +14 -0
- package/migrations/pg/0005_hot_indexes_timestamptz.down.sql +71 -0
- package/migrations/pg/0005_hot_indexes_timestamptz.sql +71 -0
- package/migrations/pg/0006_canonical_email.down.sql +3 -0
- package/migrations/pg/0006_canonical_email.sql +8 -0
- package/migrations/pg/0007_audit_chain_anchor.down.sql +1 -0
- package/migrations/pg/0007_audit_chain_anchor.sql +8 -0
- package/migrations/pg/0008_two_factor_hardening.down.sql +8 -0
- package/migrations/pg/0008_two_factor_hardening.sql +8 -0
- package/migrations/pg/0009_encrypt_totp_secrets.down.sql +2 -0
- package/migrations/pg/0009_encrypt_totp_secrets.sql +5 -0
- package/migrations/pg/0010_bigint_append_only_ids.down.sql +2 -0
- package/migrations/pg/0010_bigint_append_only_ids.sql +23 -0
- package/migrations/sqlite/0001_schema_version.down.sql +2 -0
- package/migrations/sqlite/0001_schema_version.sql +8 -0
- package/migrations/sqlite/0002_initial_schema.down.sql +36 -0
- package/migrations/sqlite/0002_initial_schema.sql +376 -0
- package/migrations/sqlite/0003_auth_continuation.down.sql +27 -0
- package/migrations/sqlite/0003_auth_continuation.sql +45 -0
- package/migrations/sqlite/0004_tenant_default_unique.down.sql +1 -0
- package/migrations/sqlite/0004_tenant_default_unique.sql +13 -0
- package/migrations/sqlite/0005_hot_indexes_timestamptz.down.sql +10 -0
- package/migrations/sqlite/0005_hot_indexes_timestamptz.sql +10 -0
- package/migrations/sqlite/0006_canonical_email.down.sql +3 -0
- package/migrations/sqlite/0006_canonical_email.sql +8 -0
- package/migrations/sqlite/0007_audit_chain_anchor.down.sql +1 -0
- package/migrations/sqlite/0007_audit_chain_anchor.sql +8 -0
- package/migrations/sqlite/0008_two_factor_hardening.down.sql +14 -0
- package/migrations/sqlite/0008_two_factor_hardening.sql +7 -0
- package/migrations/sqlite/0009_encrypt_totp_secrets.down.sql +2 -0
- package/migrations/sqlite/0009_encrypt_totp_secrets.sql +5 -0
- package/migrations/sqlite/0010_bigint_append_only_ids.down.sql +1 -0
- package/migrations/sqlite/0010_bigint_append_only_ids.sql +2 -0
- package/package.json +398 -0
- package/src/adapters/database/index.ts +63 -0
- package/src/adapters/database/types.ts +22 -0
- package/src/changelog-script.test.ts +21 -0
- package/src/cli.test.ts +79 -0
- package/src/core/auth/auth-admin.test.ts +247 -0
- package/src/core/auth/auth-endpoints.ts +558 -0
- package/src/core/auth/auth-observer.test.ts +191 -0
- package/src/core/auth/auth-service.ts +1464 -0
- package/src/core/auth/email.test.ts +17 -0
- package/src/core/auth/email.ts +11 -0
- package/src/core/auth/hooks.test.ts +251 -0
- package/src/core/auth/impersonation.test.ts +179 -0
- package/src/core/auth/jwt.test.ts +184 -0
- package/src/core/auth/jwt.ts +239 -0
- package/src/core/auth/login-timing.test.ts +77 -0
- package/src/core/auth/password-policy.test.ts +253 -0
- package/src/core/auth/password-policy.ts +220 -0
- package/src/core/auth/password.test.ts +42 -0
- package/src/core/auth/password.ts +62 -0
- package/src/core/auth/post-auth-gate.test.ts +258 -0
- package/src/core/auth/post-auth-gate.ts +228 -0
- package/src/core/auth/refresh-token.test.ts +86 -0
- package/src/core/auth/refresh-token.ts +105 -0
- package/src/core/auth/timing-safe.ts +23 -0
- package/src/core/config.ts +212 -0
- package/src/core/endpoint.ts +149 -0
- package/src/core/errors.ts +199 -0
- package/src/core/fetcher-interop.test.ts +106 -0
- package/src/core/fortress.test.ts +354 -0
- package/src/core/fortress.ts +550 -0
- package/src/core/http/call.test.ts +148 -0
- package/src/core/http/call.ts +149 -0
- package/src/core/http/cookie-serialize.test.ts +198 -0
- package/src/core/http/cookie-serialize.ts +107 -0
- package/src/core/http/csrf.test.ts +140 -0
- package/src/core/http/csrf.ts +173 -0
- package/src/core/http/dispatch.ts +652 -0
- package/src/core/http/error-response.test.ts +69 -0
- package/src/core/http/error-response.ts +93 -0
- package/src/core/http/fortress-rbac.test.ts +43 -0
- package/src/core/http/fortress-rbac.ts +127 -0
- package/src/core/http/handle-request.test.ts +441 -0
- package/src/core/http/handle-request.ts +354 -0
- package/src/core/http/match.test.ts +122 -0
- package/src/core/http/match.ts +126 -0
- package/src/core/http/outbound.test.ts +34 -0
- package/src/core/http/outbound.ts +105 -0
- package/src/core/http/plugin-middleware.ts +67 -0
- package/src/core/http/principal.test.ts +345 -0
- package/src/core/http/principal.ts +86 -0
- package/src/core/http/protect.test.ts +220 -0
- package/src/core/http/protect.ts +394 -0
- package/src/core/http/token-extraction.test.ts +59 -0
- package/src/core/http/token-extraction.ts +53 -0
- package/src/core/iam/explain.test.ts +177 -0
- package/src/core/iam/explain.ts +302 -0
- package/src/core/iam/iam-endpoints.ts +779 -0
- package/src/core/iam/iam-service.test.ts +829 -0
- package/src/core/iam/iam-service.ts +1137 -0
- package/src/core/iam/permission-cache.test.ts +115 -0
- package/src/core/iam/permission-cache.ts +71 -0
- package/src/core/iam/permission-check-observer.test.ts +90 -0
- package/src/core/iam/permission-evaluator.test.ts +291 -0
- package/src/core/iam/permission-evaluator.ts +198 -0
- package/src/core/iam/permission-sync.test.ts +166 -0
- package/src/core/iam/permission-sync.ts +192 -0
- package/src/core/iam/resource-sync.test.ts +70 -0
- package/src/core/iam/resource-sync.ts +182 -0
- package/src/core/iam/service-account-http.test.ts +529 -0
- package/src/core/iam/service-account.test.ts +282 -0
- package/src/core/internal-adapter.test.ts +389 -0
- package/src/core/internal-adapter.ts +435 -0
- package/src/core/json-schema.ts +50 -0
- package/src/core/manifest/__snapshots__/route-manifest.test.ts.snap +192 -0
- package/src/core/manifest/drift.ts +103 -0
- package/src/core/manifest/route-manifest.test.ts +142 -0
- package/src/core/manifest/route-manifest.ts +154 -0
- package/src/core/migrate.test.ts +72 -0
- package/src/core/migrations/engine.test.ts +308 -0
- package/src/core/migrations/engine.ts +548 -0
- package/src/core/migrations/migrations.ts +1771 -0
- package/src/core/migrations/pg-migration.integration-test.ts +353 -0
- package/src/core/migrations/upgrade-fixture.test.ts +378 -0
- package/src/core/observability/db-instrumentation.ts +205 -0
- package/src/core/observability/listener-list.test.ts +124 -0
- package/src/core/observability/listener-list.ts +73 -0
- package/src/core/observability/logger.test.ts +43 -0
- package/src/core/observability/logger.ts +49 -0
- package/src/core/observability/spans.test.ts +193 -0
- package/src/core/observability/types.ts +80 -0
- package/src/core/openapi-drift.test.ts +41 -0
- package/src/core/openapi.ts +47 -0
- package/src/core/plugin-methods-map.ts +75 -0
- package/src/core/plugin-runner.test.ts +233 -0
- package/src/core/plugin-runner.ts +276 -0
- package/src/core/plugin.ts +210 -0
- package/src/core/policy/apply.ts +272 -0
- package/src/core/policy/diff.ts +288 -0
- package/src/core/policy/loader.test.ts +63 -0
- package/src/core/policy/loader.ts +214 -0
- package/src/core/policy/policy.test.ts +232 -0
- package/src/core/policy/types.ts +105 -0
- package/src/core/schema-builder.test.ts +660 -0
- package/src/core/schema-builder.ts +881 -0
- package/src/core/standard-schema.ts +56 -0
- package/src/core/types.ts +258 -0
- package/src/core/validation.test.ts +195 -0
- package/src/core/validation.ts +192 -0
- package/src/drizzle/adapter.test.ts +425 -0
- package/src/drizzle/adapter.ts +474 -0
- package/src/drizzle/index.ts +31 -0
- package/src/drizzle/pg/adapter.integration-test.ts +456 -0
- package/src/drizzle/pg/index.ts +13 -0
- package/src/drizzle/pg/pg.integration-test.ts +1539 -0
- package/src/drizzle/pg/schema.ts +539 -0
- package/src/drizzle/pg-error-map.test.ts +218 -0
- package/src/drizzle/pg-error-map.ts +151 -0
- package/src/drizzle/schema.ts +544 -0
- package/src/drizzle/sqlite-serialization.test.ts +106 -0
- package/src/express/express-api-key-user-routes.test.ts +241 -0
- package/src/express/express.test.ts +442 -0
- package/src/express/handle.ts +191 -0
- package/src/express/index.ts +62 -0
- package/src/express/middleware.ts +551 -0
- package/src/express/protect.ts +154 -0
- package/src/express/validated.test.ts +86 -0
- package/src/express/validated.ts +99 -0
- package/src/fetcher/index.ts +81 -0
- package/src/hono/convert-routes.test.ts +220 -0
- package/src/hono/convert-routes.ts +196 -0
- package/src/hono/converters.test.ts +50 -0
- package/src/hono/converters.ts +43 -0
- package/src/hono/handle.ts +79 -0
- package/src/hono/helpers.ts +2 -0
- package/src/hono/hono-api-key-user-routes.test.ts +225 -0
- package/src/hono/hono-handlers.test.ts +861 -0
- package/src/hono/hono.test.ts +454 -0
- package/src/hono/index.ts +101 -0
- package/src/hono/middleware/auth.ts +236 -0
- package/src/hono/middleware/auth.types.test.ts +94 -0
- package/src/hono/middleware/csrf.test.ts +127 -0
- package/src/hono/middleware/csrf.ts +68 -0
- package/src/hono/middleware/error-handler.ts +12 -0
- package/src/hono/middleware/plugin-middleware.ts +35 -0
- package/src/hono/middleware/rbac.ts +131 -0
- package/src/hono/middleware/security-headers.test.ts +88 -0
- package/src/hono/middleware/security-headers.ts +68 -0
- package/src/hono/openapi.ts +237 -0
- package/src/hono/protect.ts +87 -0
- package/src/hono/validated.test.ts +123 -0
- package/src/hono/validated.ts +62 -0
- package/src/index.ts +309 -0
- package/src/integration.test.ts +718 -0
- package/src/internal/changelog.ts +56 -0
- package/src/otel/index.ts +158 -0
- package/src/otel/otel-types.test.ts +35 -0
- package/src/otel/otel.test.ts +235 -0
- package/src/plugins/account-lockout/account-lockout.test.ts +367 -0
- package/src/plugins/account-lockout/index.ts +267 -0
- package/src/plugins/admin/admin-api-key.test.ts +438 -0
- package/src/plugins/admin/index.ts +1612 -0
- package/src/plugins/api-key/api-key.test.ts +684 -0
- package/src/plugins/api-key/core.ts +336 -0
- package/src/plugins/api-key/index.ts +315 -0
- package/src/plugins/audit-log/audit-log.test.ts +749 -0
- package/src/plugins/audit-log/index.ts +680 -0
- package/src/plugins/data-isolation/data-isolation.test.ts +197 -0
- package/src/plugins/data-isolation/index.ts +157 -0
- package/src/plugins/email-verification/email-verification.test.ts +199 -0
- package/src/plugins/email-verification/index.ts +190 -0
- package/src/plugins/magic-link/index.ts +129 -0
- package/src/plugins/magic-link/magic-link.test.ts +156 -0
- package/src/plugins/oauth/id-token.ts +86 -0
- package/src/plugins/oauth/index.ts +2145 -0
- package/src/plugins/oauth/jwks.test.ts +32 -0
- package/src/plugins/oauth/jwks.ts +182 -0
- package/src/plugins/oauth/oauth.test.ts +2220 -0
- package/src/plugins/oauth/pkce.ts +58 -0
- package/src/plugins/openapi/index.ts +298 -0
- package/src/plugins/openapi/openapi.test.ts +425 -0
- package/src/plugins/openapi/spec-builder.ts +287 -0
- package/src/plugins/rate-limit/express.test.ts +89 -0
- package/src/plugins/rate-limit/express.ts +86 -0
- package/src/plugins/rate-limit/hono.test.ts +60 -0
- package/src/plugins/rate-limit/hono.ts +74 -0
- package/src/plugins/rate-limit/index.ts +383 -0
- package/src/plugins/rate-limit/memory-store.ts +61 -0
- package/src/plugins/rate-limit/rate-limit.test.ts +756 -0
- package/src/plugins/rate-limit/sveltekit.test.ts +58 -0
- package/src/plugins/rate-limit/sveltekit.ts +66 -0
- package/src/plugins/social-login/index.ts +715 -0
- package/src/plugins/social-login/providers/apple.ts +34 -0
- package/src/plugins/social-login/providers/discord.ts +26 -0
- package/src/plugins/social-login/providers/github.ts +54 -0
- package/src/plugins/social-login/providers/google.ts +23 -0
- package/src/plugins/social-login/providers/index.ts +22 -0
- package/src/plugins/social-login/providers/microsoft.ts +35 -0
- package/src/plugins/social-login/providers/oidc.ts +37 -0
- package/src/plugins/social-login/providers/providers.test.ts +211 -0
- package/src/plugins/social-login/social-login.test.ts +675 -0
- package/src/plugins/social-login/types.ts +80 -0
- package/src/plugins/tenancy/index.ts +544 -0
- package/src/plugins/tenancy/tenancy.test.ts +323 -0
- package/src/plugins/two-factor/index.ts +569 -0
- package/src/plugins/two-factor/two-factor.test.ts +235 -0
- package/src/plugins/webauthn/index.ts +554 -0
- package/src/plugins/webauthn/webauthn.test.ts +472 -0
- package/src/plugins/webhook/builtin-events.ts +29 -0
- package/src/plugins/webhook/delivery.test.ts +51 -0
- package/src/plugins/webhook/delivery.ts +154 -0
- package/src/plugins/webhook/hooks.ts +89 -0
- package/src/plugins/webhook/index.ts +445 -0
- package/src/plugins/webhook/queue/database.ts +67 -0
- package/src/plugins/webhook/queue/in-memory.test.ts +48 -0
- package/src/plugins/webhook/queue/in-memory.ts +71 -0
- package/src/plugins/webhook/queue/types.ts +51 -0
- package/src/plugins/webhook/registry.test.ts +48 -0
- package/src/plugins/webhook/registry.ts +64 -0
- package/src/plugins/webhook/signing.ts +45 -0
- package/src/plugins/webhook/ssrf.ts +198 -0
- package/src/plugins/webhook/types.ts +138 -0
- package/src/plugins/webhook/webhook.test.ts +324 -0
- package/src/sveltekit/actions.ts +233 -0
- package/src/sveltekit/catch-all.ts +43 -0
- package/src/sveltekit/cookies.ts +136 -0
- package/src/sveltekit/handle.ts +356 -0
- package/src/sveltekit/helpers.ts +69 -0
- package/src/sveltekit/index.ts +74 -0
- package/src/sveltekit/protect.ts +80 -0
- package/src/sveltekit/sveltekit-types.test.ts +31 -0
- package/src/sveltekit/sveltekit.test.ts +799 -0
- package/src/sveltekit/types.ts +134 -0
- package/src/sveltekit/validated.test.ts +117 -0
- package/src/sveltekit/validated.ts +78 -0
- package/src/testing/adapter-conformance.test.ts +408 -0
- package/src/testing/checks.test.ts +124 -0
- package/src/testing/checks.ts +304 -0
- package/src/testing/index.ts +107 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
export { C as ConvertRoutesOptions, E as ExternalRoute, T as ToJSONSchemaConverter, c as convertRoutes } from './convert-routes-BdMvP2_X.cjs';
|
|
2
|
+
import { F as Fortress } from './fortress-BmSvFfqK.cjs';
|
|
3
|
+
import { D as DatabaseAdapter } from './index-CxEkfCA0.cjs';
|
|
4
|
+
import { M as MiddlewareDefinition, E as EndpointDefinition, S as StandardSchemaV1 } from './config-GtlVt6ZD.cjs';
|
|
5
|
+
import { S as Subject, T as TokenClaims } from './types-et0R8tsC.cjs';
|
|
6
|
+
import { P as ProtectedRouteContext, a as ProtectOptions } from './protect-D1v_0upK.cjs';
|
|
7
|
+
export { b as ProtectedRouteTarget } from './protect-D1v_0upK.cjs';
|
|
8
|
+
import './index-D054pcb-.cjs';
|
|
9
|
+
import './auth-service-BcyQ2PuZ.cjs';
|
|
10
|
+
import './plugins/api-key.cjs';
|
|
11
|
+
import './jwt.cjs';
|
|
12
|
+
import './plugins/audit-log.cjs';
|
|
13
|
+
import './plugins/data-isolation.cjs';
|
|
14
|
+
import './plugins/email-verification.cjs';
|
|
15
|
+
import './plugins/magic-link.cjs';
|
|
16
|
+
import './plugins/oauth.cjs';
|
|
17
|
+
import './plugins/social-login.cjs';
|
|
18
|
+
import './plugins/tenancy.cjs';
|
|
19
|
+
import './plugins/two-factor.cjs';
|
|
20
|
+
import './plugins/webauthn.cjs';
|
|
21
|
+
import '@simplewebauthn/server';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Fortress-specific fields attached to the Express `Request` by
|
|
25
|
+
* {@link createAuthMiddleware}. Exported so host apps can declaration-merge
|
|
26
|
+
* them into express's native `Request` type for typed access without casts.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* // src/types/express.d.ts
|
|
31
|
+
* import type { FortressExpressFields } from '@bajustone/fortress/express';
|
|
32
|
+
*
|
|
33
|
+
* declare module 'express-serve-static-core' {
|
|
34
|
+
* interface Request extends FortressExpressFields {}
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
interface FortressExpressFields {
|
|
39
|
+
/**
|
|
40
|
+
* The resolved principal — set for every authenticated request regardless
|
|
41
|
+
* of credential type (JWT, api-key, future OAuth client_credentials, mTLS).
|
|
42
|
+
*/
|
|
43
|
+
fortressSubject?: Subject;
|
|
44
|
+
/**
|
|
45
|
+
* Convenience alias — populated **only** when the subject is a `USER`.
|
|
46
|
+
* Non-USER subjects (e.g. `SERVICE_ACCOUNT` via api-key) leave this
|
|
47
|
+
* undefined; fall back to {@link fortressSubject}.
|
|
48
|
+
*/
|
|
49
|
+
fortressUserId?: string;
|
|
50
|
+
fortressClaims?: TokenClaims;
|
|
51
|
+
fortressScopes?: string[] | null;
|
|
52
|
+
fortressDb?: DatabaseAdapter;
|
|
53
|
+
fortressGetScopedDb?: (model: string) => Promise<DatabaseAdapter>;
|
|
54
|
+
}
|
|
55
|
+
/** Minimal Express request shape fortress reads from. Compatible with any modern Express version. */
|
|
56
|
+
interface ExpressRequest extends FortressExpressFields {
|
|
57
|
+
headers: Record<string, string | string[] | undefined>;
|
|
58
|
+
method: string;
|
|
59
|
+
/** Express's route path without the query string. */
|
|
60
|
+
path: string;
|
|
61
|
+
/** Original path including query string, when supplied by Express. */
|
|
62
|
+
originalUrl?: string;
|
|
63
|
+
/** Node/Express request URL fallback, usually including the query string. */
|
|
64
|
+
url?: string;
|
|
65
|
+
/** Resolved request protocol (`http`/`https`) when supplied by Express. */
|
|
66
|
+
protocol?: string;
|
|
67
|
+
/** Parsed request body, if body middleware ran before this slot. */
|
|
68
|
+
body?: unknown;
|
|
69
|
+
}
|
|
70
|
+
/** Minimal Express response shape fortress writes to. */
|
|
71
|
+
interface ExpressResponse {
|
|
72
|
+
status: (code: number) => ExpressResponse;
|
|
73
|
+
json: (body: unknown) => void;
|
|
74
|
+
setHeader: (name: string, value: string) => void;
|
|
75
|
+
}
|
|
76
|
+
/** The `next(err?)` callback Express middleware signs off with. */
|
|
77
|
+
type ExpressNextFunction = (err?: unknown) => void;
|
|
78
|
+
/** Express middleware signature fortress's adapter exports use. */
|
|
79
|
+
type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
|
|
80
|
+
/** A `(resource, action)` IAM mapping for an HTTP route. */
|
|
81
|
+
interface RouteMapping {
|
|
82
|
+
resource: string;
|
|
83
|
+
action: string;
|
|
84
|
+
}
|
|
85
|
+
/** Options accepted by {@link createRbacMiddleware} (and the express adapter factory). */
|
|
86
|
+
interface RbacOptions {
|
|
87
|
+
routeMap?: Record<string, RouteMapping>;
|
|
88
|
+
mapRequest?: (method: string, path: string) => RouteMapping | null;
|
|
89
|
+
skipPaths?: string[];
|
|
90
|
+
/**
|
|
91
|
+
* Behavior when a non-skipped route matches no `routeMap`/`mapRequest`
|
|
92
|
+
* entry. `'allow'` (default) treats it as public; `'deny'` fails closed
|
|
93
|
+
* with a 403 so a forgotten mapping can't silently expose a user route.
|
|
94
|
+
* List genuinely public routes in {@link RbacOptions.skipPaths} when using
|
|
95
|
+
* `'deny'`.
|
|
96
|
+
*/
|
|
97
|
+
unmappedRoutes?: 'allow' | 'deny';
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Build the Express auth middleware. Resolves the request principal via
|
|
101
|
+
* `fortress.resolvePrincipal`, which tries plugin `resolvePrincipal` hooks
|
|
102
|
+
* (api-key, future OAuth client_credentials, mTLS) first and then falls
|
|
103
|
+
* back to the JWT bearer token (cookie-first, `Authorization: Bearer`
|
|
104
|
+
* second). Populates `fortressSubject`, `fortressUserId` (USER alias),
|
|
105
|
+
* `fortressClaims`, `fortressDb`, and `fortressGetScopedDb` on the request.
|
|
106
|
+
*/
|
|
107
|
+
declare function createAuthMiddleware(fortress: Fortress): ExpressMiddleware;
|
|
108
|
+
/** Options accepted by {@link createCsrfMiddleware}. */
|
|
109
|
+
interface CsrfConfig {
|
|
110
|
+
/** Header name required on unsafe methods. Default: `X-Fortress-CSRF`. */
|
|
111
|
+
headerName?: string;
|
|
112
|
+
/** Paths/subtrees exempt from CSRF checking. A trailing `/*` is accepted. */
|
|
113
|
+
skipPaths?: string[];
|
|
114
|
+
/** Methods exempt from CSRF checking. Default: GET, HEAD, OPTIONS. */
|
|
115
|
+
safeMethods?: string[];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Build standalone Express CSRF middleware for host-owned routes. Fortress-
|
|
119
|
+
* managed routes already enforce cookie-aware CSRF inside `handleRequest`.
|
|
120
|
+
* This middleware uses the custom-header strategy and rejects cross-site
|
|
121
|
+
* browser requests on unsafe methods.
|
|
122
|
+
*/
|
|
123
|
+
declare function createCsrfMiddleware(config?: CsrfConfig): ExpressMiddleware;
|
|
124
|
+
/**
|
|
125
|
+
* Build the Express RBAC middleware for **user-owned routes**. Resolves a
|
|
126
|
+
* `(resource, action)` mapping via `routeMap` / `mapRequest` and enforces
|
|
127
|
+
* the IAM permission check. Fortress-managed routes (`/auth/*`, `/iam/*`,
|
|
128
|
+
* plugin paths) are protected automatically inside `fortress.handleRequest`
|
|
129
|
+
* — this middleware only handles routes the caller registered themselves.
|
|
130
|
+
*/
|
|
131
|
+
declare function createRbacMiddleware(fortress: Fortress, options?: RbacOptions): ExpressMiddleware;
|
|
132
|
+
/**
|
|
133
|
+
* Build the Express error handler. Translates {@link FortressError} into the
|
|
134
|
+
* appropriate HTTP response with `Retry-After` for rate-limited responses,
|
|
135
|
+
* and returns a generic 500 for everything else.
|
|
136
|
+
*
|
|
137
|
+
* Stays synchronous so it composes naturally with Express's `(err, req,
|
|
138
|
+
* res, next)` signature. Shares the response *shape* with core's
|
|
139
|
+
* `errorToResponse` via {@link FortressError.toJSON}. When a `Fortress`
|
|
140
|
+
* instance is provided, unhandled errors are routed to its configured
|
|
141
|
+
* {@link FortressLogger}; otherwise they're silently swallowed (matching
|
|
142
|
+
* the silent-by-default posture of the library).
|
|
143
|
+
*/
|
|
144
|
+
declare function createErrorHandler(fortress?: Fortress): (err: unknown, req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Express middleware that executes plugin-defined middleware for a given
|
|
147
|
+
* position (`before-auth`, `after-auth`, `after-rbac`). Used internally by
|
|
148
|
+
* {@link createExpressMiddleware}; expose if you want to mount the plugin
|
|
149
|
+
* middleware slots manually.
|
|
150
|
+
*/
|
|
151
|
+
declare function createExpressPluginMiddleware(fortress: Fortress, position: MiddlewareDefinition['position']): ExpressMiddleware;
|
|
152
|
+
/** Options for {@link createExpressMiddleware}. Extends {@link RbacOptions}. */
|
|
153
|
+
interface ExpressAdapterOptions extends RbacOptions {
|
|
154
|
+
/** Standalone CSRF middleware options for host-owned Express routes. */
|
|
155
|
+
csrf?: CsrfConfig;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build the full set of fortress Express middleware: auth, CSRF, RBAC, error
|
|
159
|
+
* handler, and the three plugin middleware slots (`beforeAuth`, `afterAuth`,
|
|
160
|
+
* `afterRbac`). Mount each in the corresponding place in your Express app.
|
|
161
|
+
*/
|
|
162
|
+
declare function createExpressMiddleware(fortress: Fortress, options?: ExpressAdapterOptions): {
|
|
163
|
+
authMiddleware: ExpressMiddleware;
|
|
164
|
+
csrfMiddleware: ExpressMiddleware;
|
|
165
|
+
rbacMiddleware: ExpressMiddleware;
|
|
166
|
+
errorHandler: ReturnType<typeof createErrorHandler>;
|
|
167
|
+
pluginMiddleware: {
|
|
168
|
+
beforeAuth: ExpressMiddleware;
|
|
169
|
+
afterAuth: ExpressMiddleware;
|
|
170
|
+
afterRbac: ExpressMiddleware;
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Read the resolved request principal. Works for every subject kind
|
|
175
|
+
* (`USER`, `SERVICE_ACCOUNT`, ...). Throws 401 if the auth middleware did
|
|
176
|
+
* not run or no credential was present.
|
|
177
|
+
*/
|
|
178
|
+
declare function getSubject(req: ExpressRequest): Subject;
|
|
179
|
+
/**
|
|
180
|
+
* Read the authenticated user ID. Throws 401 if the request was
|
|
181
|
+
* authenticated by a non-USER subject (e.g. a service account via
|
|
182
|
+
* api-key) — use {@link getSubject} for handlers that accept any
|
|
183
|
+
* principal.
|
|
184
|
+
*/
|
|
185
|
+
declare function getUserId(req: ExpressRequest): string;
|
|
186
|
+
/**
|
|
187
|
+
* Read the verified JWT claims. Only populated when the request was
|
|
188
|
+
* authenticated via a JWT — api-key principals have no JWT claims and
|
|
189
|
+
* this helper throws 401.
|
|
190
|
+
*/
|
|
191
|
+
declare function getClaims(req: ExpressRequest): TokenClaims;
|
|
192
|
+
/** Read the per-request fortress database adapter (with plugin wrappers applied). */
|
|
193
|
+
declare function getDb(req: ExpressRequest): DatabaseAdapter;
|
|
194
|
+
/** Read the per-request fortress database adapter scoped to a specific model (applies any active row-level scope rules). */
|
|
195
|
+
declare function getScopedDb(req: ExpressRequest, model: string): Promise<DatabaseAdapter>;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Modern entry point for the Express adapter: register a single fortress
|
|
199
|
+
* middleware that detects Fortress-managed paths and delegates to
|
|
200
|
+
* `fortress.handleRequest`.
|
|
201
|
+
*
|
|
202
|
+
* Bridges Express's `(req, res, next)` callback style to/from web-standard
|
|
203
|
+
* `Request`/`Response`. User routes registered before `mountFortress` keep
|
|
204
|
+
* working — Express's middleware order means earlier handlers win.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* import express from 'express';
|
|
209
|
+
* import { mountFortress } from '@bajustone/fortress/express';
|
|
210
|
+
*
|
|
211
|
+
* const app = express();
|
|
212
|
+
* app.use(express.json());
|
|
213
|
+
* mountFortress(app, fortress);
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
interface ExpressApp {
|
|
218
|
+
use: (path: string | ExpressMiddleware, handler?: ExpressMiddleware) => void;
|
|
219
|
+
}
|
|
220
|
+
/** Options for {@link mountFortress}. */
|
|
221
|
+
interface MountFortressOptions {
|
|
222
|
+
/** Optional path prefix (e.g. `/api`). Stripped before delegating to core. */
|
|
223
|
+
prefix?: string;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Mount a single Express middleware that delegates Fortress-managed paths to
|
|
227
|
+
* `fortress.handleRequest` and otherwise calls `next()` so user routes run
|
|
228
|
+
* normally.
|
|
229
|
+
*
|
|
230
|
+
* Cookies emitted by login/refresh/impersonate are passed through verbatim
|
|
231
|
+
* via `Set-Cookie` headers, the way the browser expects them.
|
|
232
|
+
*/
|
|
233
|
+
declare function mountFortress(app: ExpressApp, fortress: Fortress, options?: MountFortressOptions): void;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Express-flavoured host callback. `E` flows in from the endpoint passed to
|
|
237
|
+
* `protectedRoute()`, so `ctx.body` / `ctx.query` / `ctx.params` / `ctx.input`
|
|
238
|
+
* are typed from the endpoint's phantom generics. String targets degrade to
|
|
239
|
+
* the loose default.
|
|
240
|
+
*/
|
|
241
|
+
type ExpressProtectedRouteHandler<E extends EndpointDefinition<any, any, any, any> = EndpointDefinition, TResult = unknown> = (req: ExpressRequest, res: ExpressResponse, ctx: ProtectedRouteContext<E>) => TResult | Response | Promise<TResult | Response>;
|
|
242
|
+
/**
|
|
243
|
+
* Wrap a host-owned Express route in Fortress's protection pipeline.
|
|
244
|
+
*
|
|
245
|
+
* Two overloads, mirroring `protect()`:
|
|
246
|
+
*
|
|
247
|
+
* - **Typed target** — passing an `EndpointDefinition` flows its phantom
|
|
248
|
+
* generics through `ctx`.
|
|
249
|
+
* - **String target** — passing a unique `handler` name keeps the loose
|
|
250
|
+
* `Record<string, unknown>` / `unknown` typing.
|
|
251
|
+
*/
|
|
252
|
+
declare function protectedRoute<E extends EndpointDefinition<any, any, any, any>, TResult = unknown>(fortress: Fortress, target: E, handler: ExpressProtectedRouteHandler<E, TResult>, options?: ProtectOptions): ExpressMiddleware;
|
|
253
|
+
declare function protectedRoute<TResult = unknown>(fortress: Fortress, target: string, handler: ExpressProtectedRouteHandler<EndpointDefinition, TResult>, options?: ProtectOptions): ExpressMiddleware;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Typed extraction-and-validation helpers for Express handlers.
|
|
257
|
+
*
|
|
258
|
+
* These helpers extract request data (body, params, query) **and validate
|
|
259
|
+
* it at runtime** against the supplied Standard Schema. On success they
|
|
260
|
+
* return the parsed value with full TypeScript inference; on failure they
|
|
261
|
+
* throw `FortressError('VALIDATION_ERROR', 422)` — the same shape every
|
|
262
|
+
* fortress-managed endpoint produces — so the existing Express error
|
|
263
|
+
* handler (`createErrorHandler`) formats it identically.
|
|
264
|
+
*
|
|
265
|
+
* Works with any Standard Schema V1 library: Zod, Valibot, ArkType, or
|
|
266
|
+
* fortress's built-in schema builders.
|
|
267
|
+
*
|
|
268
|
+
* Assumes body-parsing middleware (e.g. `app.use(express.json())`) has
|
|
269
|
+
* already populated `req.body` for `vBody` to read.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```ts
|
|
273
|
+
* import express from 'express';
|
|
274
|
+
* import { vBody, vParam, vQuery, createErrorHandler } from '@bajustone/fortress/express';
|
|
275
|
+
* import { obj, str } from '@bajustone/fortress';
|
|
276
|
+
*
|
|
277
|
+
* const app = express();
|
|
278
|
+
* app.use(express.json());
|
|
279
|
+
*
|
|
280
|
+
* const Body = obj({ name: str() }, 'name');
|
|
281
|
+
* const Param = obj({ id: str() }, 'id');
|
|
282
|
+
*
|
|
283
|
+
* app.patch('/users/:id', async (req, res, next) => {
|
|
284
|
+
* try {
|
|
285
|
+
* const { id } = await vParam(req, Param);
|
|
286
|
+
* const { name } = await vBody(req, Body);
|
|
287
|
+
* res.json({ id, name });
|
|
288
|
+
* }
|
|
289
|
+
* catch (err) { next(err); }
|
|
290
|
+
* });
|
|
291
|
+
*
|
|
292
|
+
* app.use(createErrorHandler());
|
|
293
|
+
* ```
|
|
294
|
+
*
|
|
295
|
+
* Validation runs per call, so the first failing helper throws and any
|
|
296
|
+
* downstream helpers in the same handler do not run. If you need to
|
|
297
|
+
* aggregate body+query+params issues into a single response, use the
|
|
298
|
+
* framework-agnostic `validateRequest` from `@bajustone/fortress` instead.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/** Infer the output type of a Standard Schema V1 schema. */
|
|
302
|
+
type InferOutput<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
|
|
303
|
+
/**
|
|
304
|
+
* Structural shape of an Express `Request` accepted by these helpers.
|
|
305
|
+
* Defined locally instead of importing from `express` so fortress can ship
|
|
306
|
+
* without a hard `express` dependency. Compatible by structural typing with
|
|
307
|
+
* the real `express.Request` — consumers pass their `req` directly.
|
|
308
|
+
*/
|
|
309
|
+
interface ExpressRequestLike {
|
|
310
|
+
body?: unknown;
|
|
311
|
+
params?: unknown;
|
|
312
|
+
query?: unknown;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Extract and validate the request body. Assumes body-parsing middleware
|
|
316
|
+
* (e.g. `express.json()`) populated `req.body`. Returns the parsed value
|
|
317
|
+
* typed as `InferOutput<T>`, or throws `FortressError('VALIDATION_ERROR', 422)`.
|
|
318
|
+
*/
|
|
319
|
+
declare function vBody<T extends StandardSchemaV1>(req: ExpressRequestLike, schema: T): Promise<InferOutput<T>>;
|
|
320
|
+
/**
|
|
321
|
+
* Extract and validate route parameters from `req.params`. Returns the
|
|
322
|
+
* parsed value typed as `InferOutput<T>`, or throws
|
|
323
|
+
* `FortressError('VALIDATION_ERROR', 422)`.
|
|
324
|
+
*/
|
|
325
|
+
declare function vParam<T extends StandardSchemaV1>(req: ExpressRequestLike, schema: T): Promise<InferOutput<T>>;
|
|
326
|
+
/**
|
|
327
|
+
* Extract and validate query parameters from `req.query`. Returns the
|
|
328
|
+
* parsed value typed as `InferOutput<T>`, or throws
|
|
329
|
+
* `FortressError('VALIDATION_ERROR', 422)`.
|
|
330
|
+
*/
|
|
331
|
+
declare function vQuery<T extends StandardSchemaV1>(req: ExpressRequestLike, schema: T): Promise<InferOutput<T>>;
|
|
332
|
+
|
|
333
|
+
export { type CsrfConfig, type ExpressAdapterOptions, type ExpressMiddleware, type ExpressNextFunction, type ExpressProtectedRouteHandler, type ExpressRequest, type ExpressRequestLike, type ExpressResponse, type FortressExpressFields, type InferOutput, type MountFortressOptions, ProtectOptions, ProtectedRouteContext, type RbacOptions, type RouteMapping, createAuthMiddleware, createCsrfMiddleware, createErrorHandler, createExpressMiddleware, createExpressPluginMiddleware, createRbacMiddleware, getClaims, getDb, getScopedDb, getSubject, getUserId, mountFortress, protectedRoute, vBody, vParam, vQuery };
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
export { C as ConvertRoutesOptions, E as ExternalRoute, T as ToJSONSchemaConverter, c as convertRoutes } from './convert-routes-BLCQT57f.js';
|
|
2
|
+
import { F as Fortress } from './fortress-uA-_cheR.js';
|
|
3
|
+
import { D as DatabaseAdapter } from './index-CxEkfCA0.js';
|
|
4
|
+
import { M as MiddlewareDefinition, E as EndpointDefinition, S as StandardSchemaV1 } from './config-B2366s_G.js';
|
|
5
|
+
import { S as Subject, T as TokenClaims } from './types-et0R8tsC.js';
|
|
6
|
+
import { P as ProtectedRouteContext, a as ProtectOptions } from './protect-DsxV_-dJ.js';
|
|
7
|
+
export { b as ProtectedRouteTarget } from './protect-DsxV_-dJ.js';
|
|
8
|
+
import './index-jAMbbUAY.js';
|
|
9
|
+
import './auth-service-BkzZkWfH.js';
|
|
10
|
+
import './plugins/api-key.js';
|
|
11
|
+
import './jwt.js';
|
|
12
|
+
import './plugins/audit-log.js';
|
|
13
|
+
import './plugins/data-isolation.js';
|
|
14
|
+
import './plugins/email-verification.js';
|
|
15
|
+
import './plugins/magic-link.js';
|
|
16
|
+
import './plugins/oauth.js';
|
|
17
|
+
import './plugins/social-login.js';
|
|
18
|
+
import './plugins/tenancy.js';
|
|
19
|
+
import './plugins/two-factor.js';
|
|
20
|
+
import './plugins/webauthn.js';
|
|
21
|
+
import '@simplewebauthn/server';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Fortress-specific fields attached to the Express `Request` by
|
|
25
|
+
* {@link createAuthMiddleware}. Exported so host apps can declaration-merge
|
|
26
|
+
* them into express's native `Request` type for typed access without casts.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* // src/types/express.d.ts
|
|
31
|
+
* import type { FortressExpressFields } from '@bajustone/fortress/express';
|
|
32
|
+
*
|
|
33
|
+
* declare module 'express-serve-static-core' {
|
|
34
|
+
* interface Request extends FortressExpressFields {}
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
interface FortressExpressFields {
|
|
39
|
+
/**
|
|
40
|
+
* The resolved principal — set for every authenticated request regardless
|
|
41
|
+
* of credential type (JWT, api-key, future OAuth client_credentials, mTLS).
|
|
42
|
+
*/
|
|
43
|
+
fortressSubject?: Subject;
|
|
44
|
+
/**
|
|
45
|
+
* Convenience alias — populated **only** when the subject is a `USER`.
|
|
46
|
+
* Non-USER subjects (e.g. `SERVICE_ACCOUNT` via api-key) leave this
|
|
47
|
+
* undefined; fall back to {@link fortressSubject}.
|
|
48
|
+
*/
|
|
49
|
+
fortressUserId?: string;
|
|
50
|
+
fortressClaims?: TokenClaims;
|
|
51
|
+
fortressScopes?: string[] | null;
|
|
52
|
+
fortressDb?: DatabaseAdapter;
|
|
53
|
+
fortressGetScopedDb?: (model: string) => Promise<DatabaseAdapter>;
|
|
54
|
+
}
|
|
55
|
+
/** Minimal Express request shape fortress reads from. Compatible with any modern Express version. */
|
|
56
|
+
interface ExpressRequest extends FortressExpressFields {
|
|
57
|
+
headers: Record<string, string | string[] | undefined>;
|
|
58
|
+
method: string;
|
|
59
|
+
/** Express's route path without the query string. */
|
|
60
|
+
path: string;
|
|
61
|
+
/** Original path including query string, when supplied by Express. */
|
|
62
|
+
originalUrl?: string;
|
|
63
|
+
/** Node/Express request URL fallback, usually including the query string. */
|
|
64
|
+
url?: string;
|
|
65
|
+
/** Resolved request protocol (`http`/`https`) when supplied by Express. */
|
|
66
|
+
protocol?: string;
|
|
67
|
+
/** Parsed request body, if body middleware ran before this slot. */
|
|
68
|
+
body?: unknown;
|
|
69
|
+
}
|
|
70
|
+
/** Minimal Express response shape fortress writes to. */
|
|
71
|
+
interface ExpressResponse {
|
|
72
|
+
status: (code: number) => ExpressResponse;
|
|
73
|
+
json: (body: unknown) => void;
|
|
74
|
+
setHeader: (name: string, value: string) => void;
|
|
75
|
+
}
|
|
76
|
+
/** The `next(err?)` callback Express middleware signs off with. */
|
|
77
|
+
type ExpressNextFunction = (err?: unknown) => void;
|
|
78
|
+
/** Express middleware signature fortress's adapter exports use. */
|
|
79
|
+
type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
|
|
80
|
+
/** A `(resource, action)` IAM mapping for an HTTP route. */
|
|
81
|
+
interface RouteMapping {
|
|
82
|
+
resource: string;
|
|
83
|
+
action: string;
|
|
84
|
+
}
|
|
85
|
+
/** Options accepted by {@link createRbacMiddleware} (and the express adapter factory). */
|
|
86
|
+
interface RbacOptions {
|
|
87
|
+
routeMap?: Record<string, RouteMapping>;
|
|
88
|
+
mapRequest?: (method: string, path: string) => RouteMapping | null;
|
|
89
|
+
skipPaths?: string[];
|
|
90
|
+
/**
|
|
91
|
+
* Behavior when a non-skipped route matches no `routeMap`/`mapRequest`
|
|
92
|
+
* entry. `'allow'` (default) treats it as public; `'deny'` fails closed
|
|
93
|
+
* with a 403 so a forgotten mapping can't silently expose a user route.
|
|
94
|
+
* List genuinely public routes in {@link RbacOptions.skipPaths} when using
|
|
95
|
+
* `'deny'`.
|
|
96
|
+
*/
|
|
97
|
+
unmappedRoutes?: 'allow' | 'deny';
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Build the Express auth middleware. Resolves the request principal via
|
|
101
|
+
* `fortress.resolvePrincipal`, which tries plugin `resolvePrincipal` hooks
|
|
102
|
+
* (api-key, future OAuth client_credentials, mTLS) first and then falls
|
|
103
|
+
* back to the JWT bearer token (cookie-first, `Authorization: Bearer`
|
|
104
|
+
* second). Populates `fortressSubject`, `fortressUserId` (USER alias),
|
|
105
|
+
* `fortressClaims`, `fortressDb`, and `fortressGetScopedDb` on the request.
|
|
106
|
+
*/
|
|
107
|
+
declare function createAuthMiddleware(fortress: Fortress): ExpressMiddleware;
|
|
108
|
+
/** Options accepted by {@link createCsrfMiddleware}. */
|
|
109
|
+
interface CsrfConfig {
|
|
110
|
+
/** Header name required on unsafe methods. Default: `X-Fortress-CSRF`. */
|
|
111
|
+
headerName?: string;
|
|
112
|
+
/** Paths/subtrees exempt from CSRF checking. A trailing `/*` is accepted. */
|
|
113
|
+
skipPaths?: string[];
|
|
114
|
+
/** Methods exempt from CSRF checking. Default: GET, HEAD, OPTIONS. */
|
|
115
|
+
safeMethods?: string[];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Build standalone Express CSRF middleware for host-owned routes. Fortress-
|
|
119
|
+
* managed routes already enforce cookie-aware CSRF inside `handleRequest`.
|
|
120
|
+
* This middleware uses the custom-header strategy and rejects cross-site
|
|
121
|
+
* browser requests on unsafe methods.
|
|
122
|
+
*/
|
|
123
|
+
declare function createCsrfMiddleware(config?: CsrfConfig): ExpressMiddleware;
|
|
124
|
+
/**
|
|
125
|
+
* Build the Express RBAC middleware for **user-owned routes**. Resolves a
|
|
126
|
+
* `(resource, action)` mapping via `routeMap` / `mapRequest` and enforces
|
|
127
|
+
* the IAM permission check. Fortress-managed routes (`/auth/*`, `/iam/*`,
|
|
128
|
+
* plugin paths) are protected automatically inside `fortress.handleRequest`
|
|
129
|
+
* — this middleware only handles routes the caller registered themselves.
|
|
130
|
+
*/
|
|
131
|
+
declare function createRbacMiddleware(fortress: Fortress, options?: RbacOptions): ExpressMiddleware;
|
|
132
|
+
/**
|
|
133
|
+
* Build the Express error handler. Translates {@link FortressError} into the
|
|
134
|
+
* appropriate HTTP response with `Retry-After` for rate-limited responses,
|
|
135
|
+
* and returns a generic 500 for everything else.
|
|
136
|
+
*
|
|
137
|
+
* Stays synchronous so it composes naturally with Express's `(err, req,
|
|
138
|
+
* res, next)` signature. Shares the response *shape* with core's
|
|
139
|
+
* `errorToResponse` via {@link FortressError.toJSON}. When a `Fortress`
|
|
140
|
+
* instance is provided, unhandled errors are routed to its configured
|
|
141
|
+
* {@link FortressLogger}; otherwise they're silently swallowed (matching
|
|
142
|
+
* the silent-by-default posture of the library).
|
|
143
|
+
*/
|
|
144
|
+
declare function createErrorHandler(fortress?: Fortress): (err: unknown, req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Express middleware that executes plugin-defined middleware for a given
|
|
147
|
+
* position (`before-auth`, `after-auth`, `after-rbac`). Used internally by
|
|
148
|
+
* {@link createExpressMiddleware}; expose if you want to mount the plugin
|
|
149
|
+
* middleware slots manually.
|
|
150
|
+
*/
|
|
151
|
+
declare function createExpressPluginMiddleware(fortress: Fortress, position: MiddlewareDefinition['position']): ExpressMiddleware;
|
|
152
|
+
/** Options for {@link createExpressMiddleware}. Extends {@link RbacOptions}. */
|
|
153
|
+
interface ExpressAdapterOptions extends RbacOptions {
|
|
154
|
+
/** Standalone CSRF middleware options for host-owned Express routes. */
|
|
155
|
+
csrf?: CsrfConfig;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build the full set of fortress Express middleware: auth, CSRF, RBAC, error
|
|
159
|
+
* handler, and the three plugin middleware slots (`beforeAuth`, `afterAuth`,
|
|
160
|
+
* `afterRbac`). Mount each in the corresponding place in your Express app.
|
|
161
|
+
*/
|
|
162
|
+
declare function createExpressMiddleware(fortress: Fortress, options?: ExpressAdapterOptions): {
|
|
163
|
+
authMiddleware: ExpressMiddleware;
|
|
164
|
+
csrfMiddleware: ExpressMiddleware;
|
|
165
|
+
rbacMiddleware: ExpressMiddleware;
|
|
166
|
+
errorHandler: ReturnType<typeof createErrorHandler>;
|
|
167
|
+
pluginMiddleware: {
|
|
168
|
+
beforeAuth: ExpressMiddleware;
|
|
169
|
+
afterAuth: ExpressMiddleware;
|
|
170
|
+
afterRbac: ExpressMiddleware;
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Read the resolved request principal. Works for every subject kind
|
|
175
|
+
* (`USER`, `SERVICE_ACCOUNT`, ...). Throws 401 if the auth middleware did
|
|
176
|
+
* not run or no credential was present.
|
|
177
|
+
*/
|
|
178
|
+
declare function getSubject(req: ExpressRequest): Subject;
|
|
179
|
+
/**
|
|
180
|
+
* Read the authenticated user ID. Throws 401 if the request was
|
|
181
|
+
* authenticated by a non-USER subject (e.g. a service account via
|
|
182
|
+
* api-key) — use {@link getSubject} for handlers that accept any
|
|
183
|
+
* principal.
|
|
184
|
+
*/
|
|
185
|
+
declare function getUserId(req: ExpressRequest): string;
|
|
186
|
+
/**
|
|
187
|
+
* Read the verified JWT claims. Only populated when the request was
|
|
188
|
+
* authenticated via a JWT — api-key principals have no JWT claims and
|
|
189
|
+
* this helper throws 401.
|
|
190
|
+
*/
|
|
191
|
+
declare function getClaims(req: ExpressRequest): TokenClaims;
|
|
192
|
+
/** Read the per-request fortress database adapter (with plugin wrappers applied). */
|
|
193
|
+
declare function getDb(req: ExpressRequest): DatabaseAdapter;
|
|
194
|
+
/** Read the per-request fortress database adapter scoped to a specific model (applies any active row-level scope rules). */
|
|
195
|
+
declare function getScopedDb(req: ExpressRequest, model: string): Promise<DatabaseAdapter>;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Modern entry point for the Express adapter: register a single fortress
|
|
199
|
+
* middleware that detects Fortress-managed paths and delegates to
|
|
200
|
+
* `fortress.handleRequest`.
|
|
201
|
+
*
|
|
202
|
+
* Bridges Express's `(req, res, next)` callback style to/from web-standard
|
|
203
|
+
* `Request`/`Response`. User routes registered before `mountFortress` keep
|
|
204
|
+
* working — Express's middleware order means earlier handlers win.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* import express from 'express';
|
|
209
|
+
* import { mountFortress } from '@bajustone/fortress/express';
|
|
210
|
+
*
|
|
211
|
+
* const app = express();
|
|
212
|
+
* app.use(express.json());
|
|
213
|
+
* mountFortress(app, fortress);
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
interface ExpressApp {
|
|
218
|
+
use: (path: string | ExpressMiddleware, handler?: ExpressMiddleware) => void;
|
|
219
|
+
}
|
|
220
|
+
/** Options for {@link mountFortress}. */
|
|
221
|
+
interface MountFortressOptions {
|
|
222
|
+
/** Optional path prefix (e.g. `/api`). Stripped before delegating to core. */
|
|
223
|
+
prefix?: string;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Mount a single Express middleware that delegates Fortress-managed paths to
|
|
227
|
+
* `fortress.handleRequest` and otherwise calls `next()` so user routes run
|
|
228
|
+
* normally.
|
|
229
|
+
*
|
|
230
|
+
* Cookies emitted by login/refresh/impersonate are passed through verbatim
|
|
231
|
+
* via `Set-Cookie` headers, the way the browser expects them.
|
|
232
|
+
*/
|
|
233
|
+
declare function mountFortress(app: ExpressApp, fortress: Fortress, options?: MountFortressOptions): void;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Express-flavoured host callback. `E` flows in from the endpoint passed to
|
|
237
|
+
* `protectedRoute()`, so `ctx.body` / `ctx.query` / `ctx.params` / `ctx.input`
|
|
238
|
+
* are typed from the endpoint's phantom generics. String targets degrade to
|
|
239
|
+
* the loose default.
|
|
240
|
+
*/
|
|
241
|
+
type ExpressProtectedRouteHandler<E extends EndpointDefinition<any, any, any, any> = EndpointDefinition, TResult = unknown> = (req: ExpressRequest, res: ExpressResponse, ctx: ProtectedRouteContext<E>) => TResult | Response | Promise<TResult | Response>;
|
|
242
|
+
/**
|
|
243
|
+
* Wrap a host-owned Express route in Fortress's protection pipeline.
|
|
244
|
+
*
|
|
245
|
+
* Two overloads, mirroring `protect()`:
|
|
246
|
+
*
|
|
247
|
+
* - **Typed target** — passing an `EndpointDefinition` flows its phantom
|
|
248
|
+
* generics through `ctx`.
|
|
249
|
+
* - **String target** — passing a unique `handler` name keeps the loose
|
|
250
|
+
* `Record<string, unknown>` / `unknown` typing.
|
|
251
|
+
*/
|
|
252
|
+
declare function protectedRoute<E extends EndpointDefinition<any, any, any, any>, TResult = unknown>(fortress: Fortress, target: E, handler: ExpressProtectedRouteHandler<E, TResult>, options?: ProtectOptions): ExpressMiddleware;
|
|
253
|
+
declare function protectedRoute<TResult = unknown>(fortress: Fortress, target: string, handler: ExpressProtectedRouteHandler<EndpointDefinition, TResult>, options?: ProtectOptions): ExpressMiddleware;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Typed extraction-and-validation helpers for Express handlers.
|
|
257
|
+
*
|
|
258
|
+
* These helpers extract request data (body, params, query) **and validate
|
|
259
|
+
* it at runtime** against the supplied Standard Schema. On success they
|
|
260
|
+
* return the parsed value with full TypeScript inference; on failure they
|
|
261
|
+
* throw `FortressError('VALIDATION_ERROR', 422)` — the same shape every
|
|
262
|
+
* fortress-managed endpoint produces — so the existing Express error
|
|
263
|
+
* handler (`createErrorHandler`) formats it identically.
|
|
264
|
+
*
|
|
265
|
+
* Works with any Standard Schema V1 library: Zod, Valibot, ArkType, or
|
|
266
|
+
* fortress's built-in schema builders.
|
|
267
|
+
*
|
|
268
|
+
* Assumes body-parsing middleware (e.g. `app.use(express.json())`) has
|
|
269
|
+
* already populated `req.body` for `vBody` to read.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```ts
|
|
273
|
+
* import express from 'express';
|
|
274
|
+
* import { vBody, vParam, vQuery, createErrorHandler } from '@bajustone/fortress/express';
|
|
275
|
+
* import { obj, str } from '@bajustone/fortress';
|
|
276
|
+
*
|
|
277
|
+
* const app = express();
|
|
278
|
+
* app.use(express.json());
|
|
279
|
+
*
|
|
280
|
+
* const Body = obj({ name: str() }, 'name');
|
|
281
|
+
* const Param = obj({ id: str() }, 'id');
|
|
282
|
+
*
|
|
283
|
+
* app.patch('/users/:id', async (req, res, next) => {
|
|
284
|
+
* try {
|
|
285
|
+
* const { id } = await vParam(req, Param);
|
|
286
|
+
* const { name } = await vBody(req, Body);
|
|
287
|
+
* res.json({ id, name });
|
|
288
|
+
* }
|
|
289
|
+
* catch (err) { next(err); }
|
|
290
|
+
* });
|
|
291
|
+
*
|
|
292
|
+
* app.use(createErrorHandler());
|
|
293
|
+
* ```
|
|
294
|
+
*
|
|
295
|
+
* Validation runs per call, so the first failing helper throws and any
|
|
296
|
+
* downstream helpers in the same handler do not run. If you need to
|
|
297
|
+
* aggregate body+query+params issues into a single response, use the
|
|
298
|
+
* framework-agnostic `validateRequest` from `@bajustone/fortress` instead.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/** Infer the output type of a Standard Schema V1 schema. */
|
|
302
|
+
type InferOutput<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
|
|
303
|
+
/**
|
|
304
|
+
* Structural shape of an Express `Request` accepted by these helpers.
|
|
305
|
+
* Defined locally instead of importing from `express` so fortress can ship
|
|
306
|
+
* without a hard `express` dependency. Compatible by structural typing with
|
|
307
|
+
* the real `express.Request` — consumers pass their `req` directly.
|
|
308
|
+
*/
|
|
309
|
+
interface ExpressRequestLike {
|
|
310
|
+
body?: unknown;
|
|
311
|
+
params?: unknown;
|
|
312
|
+
query?: unknown;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Extract and validate the request body. Assumes body-parsing middleware
|
|
316
|
+
* (e.g. `express.json()`) populated `req.body`. Returns the parsed value
|
|
317
|
+
* typed as `InferOutput<T>`, or throws `FortressError('VALIDATION_ERROR', 422)`.
|
|
318
|
+
*/
|
|
319
|
+
declare function vBody<T extends StandardSchemaV1>(req: ExpressRequestLike, schema: T): Promise<InferOutput<T>>;
|
|
320
|
+
/**
|
|
321
|
+
* Extract and validate route parameters from `req.params`. Returns the
|
|
322
|
+
* parsed value typed as `InferOutput<T>`, or throws
|
|
323
|
+
* `FortressError('VALIDATION_ERROR', 422)`.
|
|
324
|
+
*/
|
|
325
|
+
declare function vParam<T extends StandardSchemaV1>(req: ExpressRequestLike, schema: T): Promise<InferOutput<T>>;
|
|
326
|
+
/**
|
|
327
|
+
* Extract and validate query parameters from `req.query`. Returns the
|
|
328
|
+
* parsed value typed as `InferOutput<T>`, or throws
|
|
329
|
+
* `FortressError('VALIDATION_ERROR', 422)`.
|
|
330
|
+
*/
|
|
331
|
+
declare function vQuery<T extends StandardSchemaV1>(req: ExpressRequestLike, schema: T): Promise<InferOutput<T>>;
|
|
332
|
+
|
|
333
|
+
export { type CsrfConfig, type ExpressAdapterOptions, type ExpressMiddleware, type ExpressNextFunction, type ExpressProtectedRouteHandler, type ExpressRequest, type ExpressRequestLike, type ExpressResponse, type FortressExpressFields, type InferOutput, type MountFortressOptions, ProtectOptions, ProtectedRouteContext, type RbacOptions, type RouteMapping, createAuthMiddleware, createCsrfMiddleware, createErrorHandler, createExpressMiddleware, createExpressPluginMiddleware, createRbacMiddleware, getClaims, getDb, getScopedDb, getSubject, getUserId, mountFortress, protectedRoute, vBody, vParam, vQuery };
|