@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,376 @@
|
|
|
1
|
+
-- Fortress migration 0002: initial Fortress schema (PostgreSQL)
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS fortress_user (
|
|
4
|
+
id SERIAL PRIMARY KEY,
|
|
5
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
6
|
+
name VARCHAR(255) NOT NULL,
|
|
7
|
+
password_hash TEXT,
|
|
8
|
+
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
9
|
+
email_verified BOOLEAN NOT NULL DEFAULT false,
|
|
10
|
+
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
11
|
+
updated_at TIMESTAMP NOT NULL DEFAULT now()
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE TABLE IF NOT EXISTS fortress_login_identifier (
|
|
15
|
+
id SERIAL PRIMARY KEY,
|
|
16
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
17
|
+
type VARCHAR(20) NOT NULL,
|
|
18
|
+
value VARCHAR(255) NOT NULL UNIQUE
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS fortress_refresh_token (
|
|
22
|
+
id BIGSERIAL PRIMARY KEY,
|
|
23
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
24
|
+
token_hash VARCHAR(64) NOT NULL UNIQUE,
|
|
25
|
+
token_family VARCHAR(64) NOT NULL,
|
|
26
|
+
is_revoked BOOLEAN NOT NULL DEFAULT false,
|
|
27
|
+
expires_at TIMESTAMP NOT NULL,
|
|
28
|
+
ip_address VARCHAR(45),
|
|
29
|
+
user_agent TEXT,
|
|
30
|
+
device_name TEXT,
|
|
31
|
+
last_active_at TIMESTAMP,
|
|
32
|
+
fingerprint_hash VARCHAR(64),
|
|
33
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE TABLE IF NOT EXISTS fortress_group (
|
|
37
|
+
id SERIAL PRIMARY KEY,
|
|
38
|
+
name VARCHAR(100) NOT NULL UNIQUE,
|
|
39
|
+
description TEXT
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
CREATE TABLE IF NOT EXISTS fortress_group_user (
|
|
43
|
+
group_id INTEGER NOT NULL REFERENCES fortress_group(id) ON DELETE CASCADE,
|
|
44
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
45
|
+
PRIMARY KEY (group_id, user_id)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
CREATE TABLE IF NOT EXISTS fortress_service_account (
|
|
49
|
+
id SERIAL PRIMARY KEY,
|
|
50
|
+
name VARCHAR(100) NOT NULL UNIQUE,
|
|
51
|
+
display_name VARCHAR(255),
|
|
52
|
+
description TEXT,
|
|
53
|
+
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
54
|
+
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
55
|
+
updated_at TIMESTAMP NOT NULL DEFAULT now()
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE TABLE IF NOT EXISTS fortress_resource (
|
|
59
|
+
name VARCHAR(100) PRIMARY KEY,
|
|
60
|
+
description TEXT
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
CREATE TABLE IF NOT EXISTS fortress_permission (
|
|
64
|
+
id SERIAL PRIMARY KEY,
|
|
65
|
+
resource VARCHAR(100) NOT NULL REFERENCES fortress_resource(name) ON DELETE CASCADE,
|
|
66
|
+
action VARCHAR(100) NOT NULL,
|
|
67
|
+
effect VARCHAR(10) NOT NULL DEFAULT 'ALLOW',
|
|
68
|
+
conditions JSONB,
|
|
69
|
+
description TEXT
|
|
70
|
+
);
|
|
71
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_permission_no_conditions
|
|
72
|
+
ON fortress_permission (resource, action, effect)
|
|
73
|
+
WHERE conditions IS NULL;
|
|
74
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_permission_with_conditions
|
|
75
|
+
ON fortress_permission (resource, action, effect, conditions)
|
|
76
|
+
WHERE conditions IS NOT NULL;
|
|
77
|
+
|
|
78
|
+
CREATE TABLE IF NOT EXISTS fortress_role (
|
|
79
|
+
id SERIAL PRIMARY KEY,
|
|
80
|
+
name VARCHAR(100) NOT NULL UNIQUE,
|
|
81
|
+
description TEXT,
|
|
82
|
+
is_system BOOLEAN NOT NULL DEFAULT false
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
CREATE TABLE IF NOT EXISTS fortress_role_permission (
|
|
86
|
+
role_id INTEGER NOT NULL REFERENCES fortress_role(id) ON DELETE CASCADE,
|
|
87
|
+
permission_id INTEGER NOT NULL REFERENCES fortress_permission(id) ON DELETE CASCADE,
|
|
88
|
+
PRIMARY KEY (role_id, permission_id)
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
CREATE TABLE IF NOT EXISTS fortress_role_binding (
|
|
92
|
+
id SERIAL PRIMARY KEY,
|
|
93
|
+
role_id INTEGER NOT NULL REFERENCES fortress_role(id) ON DELETE CASCADE,
|
|
94
|
+
subject_type VARCHAR(20) NOT NULL,
|
|
95
|
+
subject_id INTEGER NOT NULL,
|
|
96
|
+
tenant_id VARCHAR(100),
|
|
97
|
+
UNIQUE (role_id, subject_type, subject_id, tenant_id)
|
|
98
|
+
);
|
|
99
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_role_binding_global
|
|
100
|
+
ON fortress_role_binding (role_id, subject_type, subject_id)
|
|
101
|
+
WHERE tenant_id IS NULL;
|
|
102
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_role_binding_tenant
|
|
103
|
+
ON fortress_role_binding (role_id, subject_type, subject_id, tenant_id)
|
|
104
|
+
WHERE tenant_id IS NOT NULL;
|
|
105
|
+
|
|
106
|
+
CREATE TABLE IF NOT EXISTS fortress_direct_permission_binding (
|
|
107
|
+
id SERIAL PRIMARY KEY,
|
|
108
|
+
permission_id INTEGER NOT NULL REFERENCES fortress_permission(id) ON DELETE CASCADE,
|
|
109
|
+
subject_type VARCHAR(20) NOT NULL,
|
|
110
|
+
subject_id INTEGER NOT NULL,
|
|
111
|
+
tenant_id VARCHAR(100),
|
|
112
|
+
UNIQUE (permission_id, subject_type, subject_id, tenant_id)
|
|
113
|
+
);
|
|
114
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_direct_permission_binding_global
|
|
115
|
+
ON fortress_direct_permission_binding (permission_id, subject_type, subject_id)
|
|
116
|
+
WHERE tenant_id IS NULL;
|
|
117
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_direct_permission_binding_tenant
|
|
118
|
+
ON fortress_direct_permission_binding (permission_id, subject_type, subject_id, tenant_id)
|
|
119
|
+
WHERE tenant_id IS NOT NULL;
|
|
120
|
+
|
|
121
|
+
CREATE TABLE IF NOT EXISTS fortress_email_verification_token (
|
|
122
|
+
id BIGSERIAL PRIMARY KEY,
|
|
123
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
124
|
+
token TEXT NOT NULL,
|
|
125
|
+
email VARCHAR(255) NOT NULL,
|
|
126
|
+
expires_at TIMESTAMP NOT NULL,
|
|
127
|
+
used_at TIMESTAMP,
|
|
128
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
CREATE TABLE IF NOT EXISTS fortress_magic_link_token (
|
|
132
|
+
id BIGSERIAL PRIMARY KEY,
|
|
133
|
+
email VARCHAR(255) NOT NULL,
|
|
134
|
+
token VARCHAR(64) NOT NULL,
|
|
135
|
+
expires_at TIMESTAMP NOT NULL,
|
|
136
|
+
used_at TIMESTAMP,
|
|
137
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
CREATE TABLE IF NOT EXISTS fortress_api_key (
|
|
141
|
+
id SERIAL PRIMARY KEY,
|
|
142
|
+
subject_type VARCHAR(20) NOT NULL,
|
|
143
|
+
subject_id INTEGER NOT NULL,
|
|
144
|
+
name VARCHAR(255) NOT NULL,
|
|
145
|
+
key_hash VARCHAR(64) NOT NULL UNIQUE,
|
|
146
|
+
key_prefix VARCHAR(20) NOT NULL,
|
|
147
|
+
scopes TEXT,
|
|
148
|
+
expires_at TIMESTAMP,
|
|
149
|
+
last_used_at TIMESTAMP,
|
|
150
|
+
is_revoked BOOLEAN NOT NULL DEFAULT false,
|
|
151
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
152
|
+
);
|
|
153
|
+
CREATE INDEX IF NOT EXISTS api_key_subject_idx ON fortress_api_key (subject_type, subject_id);
|
|
154
|
+
|
|
155
|
+
CREATE TABLE IF NOT EXISTS fortress_two_factor_secret (
|
|
156
|
+
id SERIAL PRIMARY KEY,
|
|
157
|
+
user_id INTEGER NOT NULL UNIQUE REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
158
|
+
secret TEXT NOT NULL,
|
|
159
|
+
is_enabled BOOLEAN NOT NULL DEFAULT false,
|
|
160
|
+
last_used_counter INTEGER,
|
|
161
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
CREATE TABLE IF NOT EXISTS fortress_backup_code (
|
|
165
|
+
id SERIAL PRIMARY KEY,
|
|
166
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
167
|
+
code_hash TEXT NOT NULL,
|
|
168
|
+
is_used BOOLEAN NOT NULL DEFAULT false,
|
|
169
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
CREATE TABLE IF NOT EXISTS fortress_trusted_device (
|
|
173
|
+
id SERIAL PRIMARY KEY,
|
|
174
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
175
|
+
device_hash VARCHAR(64) NOT NULL,
|
|
176
|
+
expires_at TIMESTAMP NOT NULL,
|
|
177
|
+
last_used_at TIMESTAMP NOT NULL,
|
|
178
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
CREATE TABLE IF NOT EXISTS fortress_social_account (
|
|
182
|
+
id SERIAL PRIMARY KEY,
|
|
183
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
184
|
+
provider VARCHAR(50) NOT NULL,
|
|
185
|
+
provider_account_id VARCHAR(255) NOT NULL,
|
|
186
|
+
email VARCHAR(255),
|
|
187
|
+
access_token TEXT,
|
|
188
|
+
refresh_token TEXT,
|
|
189
|
+
token_expires_at TIMESTAMP,
|
|
190
|
+
profile JSONB,
|
|
191
|
+
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
192
|
+
updated_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
193
|
+
UNIQUE (user_id, provider),
|
|
194
|
+
UNIQUE (provider, provider_account_id)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
CREATE TABLE IF NOT EXISTS fortress_tenant (
|
|
198
|
+
id SERIAL PRIMARY KEY,
|
|
199
|
+
name VARCHAR(255) NOT NULL,
|
|
200
|
+
tax_id VARCHAR(100) NOT NULL UNIQUE,
|
|
201
|
+
description TEXT,
|
|
202
|
+
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
203
|
+
updated_at TIMESTAMP NOT NULL DEFAULT now()
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
CREATE TABLE IF NOT EXISTS fortress_tenant_user (
|
|
207
|
+
tenant_id INTEGER NOT NULL REFERENCES fortress_tenant(id) ON DELETE CASCADE,
|
|
208
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
209
|
+
is_default BOOLEAN NOT NULL DEFAULT false,
|
|
210
|
+
PRIMARY KEY (tenant_id, user_id)
|
|
211
|
+
);
|
|
212
|
+
CREATE UNIQUE INDEX IF NOT EXISTS fortress_tenant_user_one_default_idx
|
|
213
|
+
ON fortress_tenant_user (user_id) WHERE is_default = true;
|
|
214
|
+
|
|
215
|
+
CREATE TABLE IF NOT EXISTS fortress_oauth_client (
|
|
216
|
+
id SERIAL PRIMARY KEY,
|
|
217
|
+
client_id VARCHAR(255) NOT NULL UNIQUE,
|
|
218
|
+
client_secret_hash TEXT NOT NULL,
|
|
219
|
+
name VARCHAR(255) NOT NULL,
|
|
220
|
+
redirect_uris TEXT NOT NULL,
|
|
221
|
+
grant_types TEXT NOT NULL,
|
|
222
|
+
allowed_scopes TEXT,
|
|
223
|
+
token_endpoint_auth_method TEXT,
|
|
224
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
CREATE TABLE IF NOT EXISTS fortress_oauth_authorization_code (
|
|
228
|
+
id BIGSERIAL PRIMARY KEY,
|
|
229
|
+
code VARCHAR(255) NOT NULL UNIQUE,
|
|
230
|
+
client_id VARCHAR(255) NOT NULL,
|
|
231
|
+
user_id INTEGER NOT NULL,
|
|
232
|
+
redirect_uri TEXT NOT NULL,
|
|
233
|
+
scope TEXT,
|
|
234
|
+
code_challenge TEXT,
|
|
235
|
+
code_challenge_method VARCHAR(10),
|
|
236
|
+
nonce TEXT,
|
|
237
|
+
auth_time INTEGER,
|
|
238
|
+
expires_at TIMESTAMP NOT NULL,
|
|
239
|
+
used_at TIMESTAMP,
|
|
240
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
CREATE TABLE IF NOT EXISTS fortress_oauth_access_token (
|
|
244
|
+
id BIGSERIAL PRIMARY KEY,
|
|
245
|
+
token VARCHAR(255) NOT NULL UNIQUE,
|
|
246
|
+
client_id VARCHAR(255) NOT NULL,
|
|
247
|
+
user_id INTEGER,
|
|
248
|
+
scope TEXT,
|
|
249
|
+
expires_at TIMESTAMP NOT NULL,
|
|
250
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
CREATE TABLE IF NOT EXISTS fortress_oauth_refresh_token (
|
|
254
|
+
id BIGSERIAL PRIMARY KEY,
|
|
255
|
+
token VARCHAR(255) NOT NULL UNIQUE,
|
|
256
|
+
family_id VARCHAR(64) NOT NULL,
|
|
257
|
+
client_id VARCHAR(255) NOT NULL,
|
|
258
|
+
user_id INTEGER NOT NULL,
|
|
259
|
+
scope TEXT,
|
|
260
|
+
issued_at TIMESTAMP NOT NULL,
|
|
261
|
+
expires_at TIMESTAMP NOT NULL,
|
|
262
|
+
used_at TIMESTAMP,
|
|
263
|
+
parent_id INTEGER,
|
|
264
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
CREATE TABLE IF NOT EXISTS fortress_oauth_pending_flow (
|
|
268
|
+
id BIGSERIAL PRIMARY KEY,
|
|
269
|
+
flow_id TEXT NOT NULL UNIQUE,
|
|
270
|
+
client_id VARCHAR(255) NOT NULL,
|
|
271
|
+
redirect_uri TEXT NOT NULL,
|
|
272
|
+
scope TEXT,
|
|
273
|
+
state VARCHAR(255) NOT NULL,
|
|
274
|
+
code_challenge TEXT,
|
|
275
|
+
code_challenge_method VARCHAR(10),
|
|
276
|
+
nonce TEXT,
|
|
277
|
+
user_id INTEGER,
|
|
278
|
+
used_at TIMESTAMP,
|
|
279
|
+
expires_at TIMESTAMP NOT NULL,
|
|
280
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
CREATE TABLE IF NOT EXISTS fortress_oauth_signing_key (
|
|
284
|
+
id SERIAL PRIMARY KEY,
|
|
285
|
+
kid VARCHAR(64) NOT NULL UNIQUE,
|
|
286
|
+
alg VARCHAR(16) NOT NULL,
|
|
287
|
+
public_jwk TEXT NOT NULL,
|
|
288
|
+
private_jwk TEXT NOT NULL,
|
|
289
|
+
rotated_at TIMESTAMP,
|
|
290
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
CREATE TABLE IF NOT EXISTS fortress_user_scope_assignment (
|
|
294
|
+
id SERIAL PRIMARY KEY,
|
|
295
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
296
|
+
scope_name VARCHAR(100) NOT NULL,
|
|
297
|
+
scope_value VARCHAR(255) NOT NULL,
|
|
298
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
CREATE TABLE IF NOT EXISTS fortress_account_lockout (
|
|
302
|
+
id SERIAL PRIMARY KEY,
|
|
303
|
+
identifier VARCHAR(255) NOT NULL UNIQUE,
|
|
304
|
+
failed_attempts INTEGER NOT NULL DEFAULT 0,
|
|
305
|
+
last_failed_at TIMESTAMP,
|
|
306
|
+
locked_until TIMESTAMP,
|
|
307
|
+
lockout_count INTEGER NOT NULL DEFAULT 0,
|
|
308
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
CREATE TABLE IF NOT EXISTS fortress_audit_log (
|
|
312
|
+
id BIGSERIAL PRIMARY KEY,
|
|
313
|
+
timestamp TIMESTAMP NOT NULL DEFAULT now(),
|
|
314
|
+
event_type VARCHAR(100) NOT NULL,
|
|
315
|
+
actor_id INTEGER,
|
|
316
|
+
actor_type VARCHAR(20) NOT NULL DEFAULT 'USER',
|
|
317
|
+
target_id INTEGER,
|
|
318
|
+
target_type VARCHAR(50),
|
|
319
|
+
ip_address VARCHAR(45),
|
|
320
|
+
user_agent TEXT,
|
|
321
|
+
outcome VARCHAR(20) NOT NULL DEFAULT 'SUCCESS',
|
|
322
|
+
metadata JSONB,
|
|
323
|
+
previous_hash TEXT,
|
|
324
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
CREATE TABLE IF NOT EXISTS fortress_webhook_endpoint (
|
|
328
|
+
id SERIAL PRIMARY KEY,
|
|
329
|
+
url TEXT NOT NULL,
|
|
330
|
+
events TEXT NOT NULL,
|
|
331
|
+
secret TEXT NOT NULL,
|
|
332
|
+
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
333
|
+
deactivated_reason TEXT,
|
|
334
|
+
consecutive_failures INTEGER NOT NULL DEFAULT 0,
|
|
335
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
CREATE TABLE IF NOT EXISTS fortress_webhook_delivery (
|
|
339
|
+
id BIGSERIAL PRIMARY KEY,
|
|
340
|
+
endpoint_id INTEGER NOT NULL REFERENCES fortress_webhook_endpoint(id) ON DELETE CASCADE,
|
|
341
|
+
event_type VARCHAR(100) NOT NULL,
|
|
342
|
+
payload TEXT NOT NULL,
|
|
343
|
+
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
344
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
345
|
+
idempotency_key TEXT,
|
|
346
|
+
last_attempt_at TIMESTAMP,
|
|
347
|
+
next_retry_at TIMESTAMP,
|
|
348
|
+
response_status INTEGER,
|
|
349
|
+
response_body TEXT,
|
|
350
|
+
error_kind TEXT,
|
|
351
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uniq_webhook_delivery_idempotency
|
|
355
|
+
ON fortress_webhook_delivery (endpoint_id, idempotency_key)
|
|
356
|
+
WHERE idempotency_key IS NOT NULL;
|
|
357
|
+
|
|
358
|
+
CREATE TABLE IF NOT EXISTS fortress_webauthn_credential (
|
|
359
|
+
id SERIAL PRIMARY KEY,
|
|
360
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
361
|
+
credential_id TEXT NOT NULL UNIQUE,
|
|
362
|
+
public_key TEXT NOT NULL,
|
|
363
|
+
counter INTEGER NOT NULL DEFAULT 0,
|
|
364
|
+
device_type VARCHAR(20) NOT NULL,
|
|
365
|
+
backed_up BOOLEAN NOT NULL DEFAULT false,
|
|
366
|
+
transports TEXT,
|
|
367
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
CREATE TABLE IF NOT EXISTS fortress_webauthn_challenge (
|
|
371
|
+
id BIGSERIAL PRIMARY KEY,
|
|
372
|
+
challenge TEXT NOT NULL UNIQUE,
|
|
373
|
+
user_id INTEGER,
|
|
374
|
+
expires_at TIMESTAMP NOT NULL,
|
|
375
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
376
|
+
);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- Fortress migration 0003 rollback: auth continuation + refresh-session metadata (PostgreSQL)
|
|
2
|
+
|
|
3
|
+
DROP TABLE IF EXISTS fortress_auth_continuation CASCADE;
|
|
4
|
+
ALTER TABLE fortress_refresh_token DROP COLUMN rotated_at;
|
|
5
|
+
ALTER TABLE fortress_refresh_token DROP COLUMN successor_token_hash;
|
|
6
|
+
ALTER TABLE fortress_refresh_token DROP COLUMN family_created_at;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- Fortress migration 0003: auth continuation + refresh-session metadata (PostgreSQL)
|
|
2
|
+
|
|
3
|
+
ALTER TABLE fortress_refresh_token
|
|
4
|
+
ADD COLUMN family_created_at TIMESTAMP;
|
|
5
|
+
UPDATE fortress_refresh_token AS token
|
|
6
|
+
SET family_created_at = family.created_at
|
|
7
|
+
FROM (
|
|
8
|
+
SELECT token_family, MIN(created_at) AS created_at
|
|
9
|
+
FROM fortress_refresh_token
|
|
10
|
+
GROUP BY token_family
|
|
11
|
+
) AS family
|
|
12
|
+
WHERE token.token_family = family.token_family;
|
|
13
|
+
ALTER TABLE fortress_refresh_token
|
|
14
|
+
ALTER COLUMN family_created_at SET NOT NULL;
|
|
15
|
+
ALTER TABLE fortress_refresh_token
|
|
16
|
+
ALTER COLUMN family_created_at SET DEFAULT now();
|
|
17
|
+
ALTER TABLE fortress_refresh_token
|
|
18
|
+
ADD COLUMN successor_token_hash VARCHAR(64);
|
|
19
|
+
ALTER TABLE fortress_refresh_token
|
|
20
|
+
ADD COLUMN rotated_at TIMESTAMP;
|
|
21
|
+
|
|
22
|
+
CREATE TABLE fortress_auth_continuation (
|
|
23
|
+
id BIGSERIAL PRIMARY KEY,
|
|
24
|
+
user_id INTEGER NOT NULL REFERENCES fortress_user(id) ON DELETE CASCADE,
|
|
25
|
+
token_hash VARCHAR(64) NOT NULL UNIQUE,
|
|
26
|
+
reason VARCHAR(32) NOT NULL,
|
|
27
|
+
expires_at TIMESTAMP NOT NULL,
|
|
28
|
+
consumed_at TIMESTAMP,
|
|
29
|
+
created_at TIMESTAMP NOT NULL DEFAULT now()
|
|
30
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DROP INDEX IF EXISTS fortress_tenant_user_one_default_idx;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
WITH ranked_defaults AS (
|
|
2
|
+
SELECT ctid, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY tenant_id) AS position
|
|
3
|
+
FROM fortress_tenant_user
|
|
4
|
+
WHERE is_default = true
|
|
5
|
+
)
|
|
6
|
+
UPDATE fortress_tenant_user AS membership
|
|
7
|
+
SET is_default = false
|
|
8
|
+
FROM ranked_defaults
|
|
9
|
+
WHERE membership.ctid = ranked_defaults.ctid
|
|
10
|
+
AND ranked_defaults.position > 1;
|
|
11
|
+
|
|
12
|
+
CREATE UNIQUE INDEX IF NOT EXISTS fortress_tenant_user_one_default_idx
|
|
13
|
+
ON fortress_tenant_user (user_id)
|
|
14
|
+
WHERE is_default = true;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
ALTER TABLE fortress_schema_version ALTER COLUMN applied_at TYPE TIMESTAMP USING applied_at AT TIME ZONE 'UTC';
|
|
2
|
+
ALTER TABLE fortress_user ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
3
|
+
ALTER TABLE fortress_user ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
|
4
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN family_created_at TYPE TIMESTAMP USING family_created_at AT TIME ZONE 'UTC';
|
|
5
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN rotated_at TYPE TIMESTAMP USING rotated_at AT TIME ZONE 'UTC';
|
|
6
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
7
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN last_active_at TYPE TIMESTAMP USING last_active_at AT TIME ZONE 'UTC';
|
|
8
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
9
|
+
ALTER TABLE fortress_auth_continuation ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
10
|
+
ALTER TABLE fortress_auth_continuation ALTER COLUMN consumed_at TYPE TIMESTAMP USING consumed_at AT TIME ZONE 'UTC';
|
|
11
|
+
ALTER TABLE fortress_auth_continuation ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
12
|
+
ALTER TABLE fortress_service_account ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
13
|
+
ALTER TABLE fortress_service_account ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
|
14
|
+
ALTER TABLE fortress_email_verification_token ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
15
|
+
ALTER TABLE fortress_email_verification_token ALTER COLUMN used_at TYPE TIMESTAMP USING used_at AT TIME ZONE 'UTC';
|
|
16
|
+
ALTER TABLE fortress_email_verification_token ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
17
|
+
ALTER TABLE fortress_magic_link_token ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
18
|
+
ALTER TABLE fortress_magic_link_token ALTER COLUMN used_at TYPE TIMESTAMP USING used_at AT TIME ZONE 'UTC';
|
|
19
|
+
ALTER TABLE fortress_magic_link_token ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
20
|
+
ALTER TABLE fortress_api_key ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
21
|
+
ALTER TABLE fortress_api_key ALTER COLUMN last_used_at TYPE TIMESTAMP USING last_used_at AT TIME ZONE 'UTC';
|
|
22
|
+
ALTER TABLE fortress_api_key ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
23
|
+
ALTER TABLE fortress_two_factor_secret ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
24
|
+
ALTER TABLE fortress_backup_code ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
25
|
+
ALTER TABLE fortress_trusted_device ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
26
|
+
ALTER TABLE fortress_trusted_device ALTER COLUMN last_used_at TYPE TIMESTAMP USING last_used_at AT TIME ZONE 'UTC';
|
|
27
|
+
ALTER TABLE fortress_trusted_device ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
28
|
+
ALTER TABLE fortress_social_account ALTER COLUMN token_expires_at TYPE TIMESTAMP USING token_expires_at AT TIME ZONE 'UTC';
|
|
29
|
+
ALTER TABLE fortress_social_account ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
30
|
+
ALTER TABLE fortress_social_account ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
|
31
|
+
ALTER TABLE fortress_tenant ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
32
|
+
ALTER TABLE fortress_tenant ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC';
|
|
33
|
+
ALTER TABLE fortress_oauth_client ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
34
|
+
ALTER TABLE fortress_oauth_authorization_code ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
35
|
+
ALTER TABLE fortress_oauth_authorization_code ALTER COLUMN used_at TYPE TIMESTAMP USING used_at AT TIME ZONE 'UTC';
|
|
36
|
+
ALTER TABLE fortress_oauth_authorization_code ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
37
|
+
ALTER TABLE fortress_oauth_access_token ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
38
|
+
ALTER TABLE fortress_oauth_access_token ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
39
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN issued_at TYPE TIMESTAMP USING issued_at AT TIME ZONE 'UTC';
|
|
40
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
41
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN used_at TYPE TIMESTAMP USING used_at AT TIME ZONE 'UTC';
|
|
42
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
43
|
+
ALTER TABLE fortress_oauth_pending_flow ALTER COLUMN used_at TYPE TIMESTAMP USING used_at AT TIME ZONE 'UTC';
|
|
44
|
+
ALTER TABLE fortress_oauth_pending_flow ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
45
|
+
ALTER TABLE fortress_oauth_pending_flow ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
46
|
+
ALTER TABLE fortress_oauth_signing_key ALTER COLUMN rotated_at TYPE TIMESTAMP USING rotated_at AT TIME ZONE 'UTC';
|
|
47
|
+
ALTER TABLE fortress_oauth_signing_key ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
48
|
+
ALTER TABLE fortress_user_scope_assignment ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
49
|
+
ALTER TABLE fortress_account_lockout ALTER COLUMN last_failed_at TYPE TIMESTAMP USING last_failed_at AT TIME ZONE 'UTC';
|
|
50
|
+
ALTER TABLE fortress_account_lockout ALTER COLUMN locked_until TYPE TIMESTAMP USING locked_until AT TIME ZONE 'UTC';
|
|
51
|
+
ALTER TABLE fortress_account_lockout ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
52
|
+
ALTER TABLE fortress_audit_log ALTER COLUMN timestamp TYPE TIMESTAMP USING timestamp AT TIME ZONE 'UTC';
|
|
53
|
+
ALTER TABLE fortress_audit_log ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
54
|
+
ALTER TABLE fortress_webhook_endpoint ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
55
|
+
ALTER TABLE fortress_webhook_delivery ALTER COLUMN last_attempt_at TYPE TIMESTAMP USING last_attempt_at AT TIME ZONE 'UTC';
|
|
56
|
+
ALTER TABLE fortress_webhook_delivery ALTER COLUMN next_retry_at TYPE TIMESTAMP USING next_retry_at AT TIME ZONE 'UTC';
|
|
57
|
+
ALTER TABLE fortress_webhook_delivery ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
58
|
+
ALTER TABLE fortress_webauthn_credential ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
59
|
+
ALTER TABLE fortress_webauthn_challenge ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC';
|
|
60
|
+
ALTER TABLE fortress_webauthn_challenge ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC';
|
|
61
|
+
|
|
62
|
+
DROP INDEX IF EXISTS audit_log_timestamp_idx;
|
|
63
|
+
DROP INDEX IF EXISTS webhook_delivery_retry_idx;
|
|
64
|
+
DROP INDEX IF EXISTS trusted_device_user_idx;
|
|
65
|
+
DROP INDEX IF EXISTS backup_code_user_idx;
|
|
66
|
+
DROP INDEX IF EXISTS direct_permission_binding_subject_idx;
|
|
67
|
+
DROP INDEX IF EXISTS role_binding_subject_idx;
|
|
68
|
+
DROP INDEX IF EXISTS magic_link_token_token_idx;
|
|
69
|
+
DROP INDEX IF EXISTS email_verification_token_token_idx;
|
|
70
|
+
DROP INDEX IF EXISTS refresh_token_user_idx;
|
|
71
|
+
DROP INDEX IF EXISTS refresh_token_family_idx;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
CREATE INDEX refresh_token_family_idx ON fortress_refresh_token (token_family);
|
|
2
|
+
CREATE INDEX refresh_token_user_idx ON fortress_refresh_token (user_id);
|
|
3
|
+
CREATE INDEX email_verification_token_token_idx ON fortress_email_verification_token (token);
|
|
4
|
+
CREATE INDEX magic_link_token_token_idx ON fortress_magic_link_token (token);
|
|
5
|
+
CREATE INDEX role_binding_subject_idx ON fortress_role_binding (subject_type, subject_id);
|
|
6
|
+
CREATE INDEX direct_permission_binding_subject_idx ON fortress_direct_permission_binding (subject_type, subject_id);
|
|
7
|
+
CREATE INDEX backup_code_user_idx ON fortress_backup_code (user_id);
|
|
8
|
+
CREATE INDEX trusted_device_user_idx ON fortress_trusted_device (user_id);
|
|
9
|
+
CREATE INDEX webhook_delivery_retry_idx ON fortress_webhook_delivery (status, next_retry_at);
|
|
10
|
+
CREATE INDEX audit_log_timestamp_idx ON fortress_audit_log (timestamp);
|
|
11
|
+
|
|
12
|
+
ALTER TABLE fortress_schema_version ALTER COLUMN applied_at TYPE TIMESTAMPTZ USING applied_at AT TIME ZONE 'UTC';
|
|
13
|
+
ALTER TABLE fortress_user ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
14
|
+
ALTER TABLE fortress_user ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
|
15
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN family_created_at TYPE TIMESTAMPTZ USING family_created_at AT TIME ZONE 'UTC';
|
|
16
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN rotated_at TYPE TIMESTAMPTZ USING rotated_at AT TIME ZONE 'UTC';
|
|
17
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
18
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN last_active_at TYPE TIMESTAMPTZ USING last_active_at AT TIME ZONE 'UTC';
|
|
19
|
+
ALTER TABLE fortress_refresh_token ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
20
|
+
ALTER TABLE fortress_auth_continuation ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
21
|
+
ALTER TABLE fortress_auth_continuation ALTER COLUMN consumed_at TYPE TIMESTAMPTZ USING consumed_at AT TIME ZONE 'UTC';
|
|
22
|
+
ALTER TABLE fortress_auth_continuation ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
23
|
+
ALTER TABLE fortress_service_account ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
24
|
+
ALTER TABLE fortress_service_account ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
|
25
|
+
ALTER TABLE fortress_email_verification_token ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
26
|
+
ALTER TABLE fortress_email_verification_token ALTER COLUMN used_at TYPE TIMESTAMPTZ USING used_at AT TIME ZONE 'UTC';
|
|
27
|
+
ALTER TABLE fortress_email_verification_token ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
28
|
+
ALTER TABLE fortress_magic_link_token ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
29
|
+
ALTER TABLE fortress_magic_link_token ALTER COLUMN used_at TYPE TIMESTAMPTZ USING used_at AT TIME ZONE 'UTC';
|
|
30
|
+
ALTER TABLE fortress_magic_link_token ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
31
|
+
ALTER TABLE fortress_api_key ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
32
|
+
ALTER TABLE fortress_api_key ALTER COLUMN last_used_at TYPE TIMESTAMPTZ USING last_used_at AT TIME ZONE 'UTC';
|
|
33
|
+
ALTER TABLE fortress_api_key ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
34
|
+
ALTER TABLE fortress_two_factor_secret ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
35
|
+
ALTER TABLE fortress_backup_code ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
36
|
+
ALTER TABLE fortress_trusted_device ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
37
|
+
ALTER TABLE fortress_trusted_device ALTER COLUMN last_used_at TYPE TIMESTAMPTZ USING last_used_at AT TIME ZONE 'UTC';
|
|
38
|
+
ALTER TABLE fortress_trusted_device ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
39
|
+
ALTER TABLE fortress_social_account ALTER COLUMN token_expires_at TYPE TIMESTAMPTZ USING token_expires_at AT TIME ZONE 'UTC';
|
|
40
|
+
ALTER TABLE fortress_social_account ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
41
|
+
ALTER TABLE fortress_social_account ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
|
42
|
+
ALTER TABLE fortress_tenant ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
43
|
+
ALTER TABLE fortress_tenant ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC';
|
|
44
|
+
ALTER TABLE fortress_oauth_client ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
45
|
+
ALTER TABLE fortress_oauth_authorization_code ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
46
|
+
ALTER TABLE fortress_oauth_authorization_code ALTER COLUMN used_at TYPE TIMESTAMPTZ USING used_at AT TIME ZONE 'UTC';
|
|
47
|
+
ALTER TABLE fortress_oauth_authorization_code ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
48
|
+
ALTER TABLE fortress_oauth_access_token ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
49
|
+
ALTER TABLE fortress_oauth_access_token ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
50
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN issued_at TYPE TIMESTAMPTZ USING issued_at AT TIME ZONE 'UTC';
|
|
51
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
52
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN used_at TYPE TIMESTAMPTZ USING used_at AT TIME ZONE 'UTC';
|
|
53
|
+
ALTER TABLE fortress_oauth_refresh_token ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
54
|
+
ALTER TABLE fortress_oauth_pending_flow ALTER COLUMN used_at TYPE TIMESTAMPTZ USING used_at AT TIME ZONE 'UTC';
|
|
55
|
+
ALTER TABLE fortress_oauth_pending_flow ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
56
|
+
ALTER TABLE fortress_oauth_pending_flow ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
57
|
+
ALTER TABLE fortress_oauth_signing_key ALTER COLUMN rotated_at TYPE TIMESTAMPTZ USING rotated_at AT TIME ZONE 'UTC';
|
|
58
|
+
ALTER TABLE fortress_oauth_signing_key ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
59
|
+
ALTER TABLE fortress_user_scope_assignment ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
60
|
+
ALTER TABLE fortress_account_lockout ALTER COLUMN last_failed_at TYPE TIMESTAMPTZ USING last_failed_at AT TIME ZONE 'UTC';
|
|
61
|
+
ALTER TABLE fortress_account_lockout ALTER COLUMN locked_until TYPE TIMESTAMPTZ USING locked_until AT TIME ZONE 'UTC';
|
|
62
|
+
ALTER TABLE fortress_account_lockout ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
63
|
+
ALTER TABLE fortress_audit_log ALTER COLUMN timestamp TYPE TIMESTAMPTZ USING timestamp AT TIME ZONE 'UTC';
|
|
64
|
+
ALTER TABLE fortress_audit_log ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
65
|
+
ALTER TABLE fortress_webhook_endpoint ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
66
|
+
ALTER TABLE fortress_webhook_delivery ALTER COLUMN last_attempt_at TYPE TIMESTAMPTZ USING last_attempt_at AT TIME ZONE 'UTC';
|
|
67
|
+
ALTER TABLE fortress_webhook_delivery ALTER COLUMN next_retry_at TYPE TIMESTAMPTZ USING next_retry_at AT TIME ZONE 'UTC';
|
|
68
|
+
ALTER TABLE fortress_webhook_delivery ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
69
|
+
ALTER TABLE fortress_webauthn_credential ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
70
|
+
ALTER TABLE fortress_webauthn_challenge ALTER COLUMN expires_at TYPE TIMESTAMPTZ USING expires_at AT TIME ZONE 'UTC';
|
|
71
|
+
ALTER TABLE fortress_webauthn_challenge ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- This sentinel is created only by the Fortress migration engine after its
|
|
2
|
+
-- Unicode-aware data step. Applying this SQL directly fails closed.
|
|
3
|
+
INSERT INTO fortress_email_migration_ready (id) VALUES (1);
|
|
4
|
+
CREATE UNIQUE INDEX user_email_ci_unique ON fortress_user (lower(email));
|
|
5
|
+
CREATE UNIQUE INDEX login_identifier_email_ci_unique
|
|
6
|
+
ON fortress_login_identifier (lower(value))
|
|
7
|
+
WHERE type = 'email';
|
|
8
|
+
DROP TABLE fortress_email_migration_ready;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DROP TABLE IF EXISTS fortress_audit_chain_state;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
CREATE TABLE fortress_audit_chain_state (
|
|
2
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
3
|
+
last_hash VARCHAR(64),
|
|
4
|
+
entry_count INTEGER NOT NULL CHECK (entry_count >= 0),
|
|
5
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
6
|
+
CHECK ((entry_count = 0 AND last_hash IS NULL) OR (entry_count > 0 AND last_hash IS NOT NULL))
|
|
7
|
+
);
|
|
8
|
+
INSERT INTO fortress_audit_chain_state (id, last_hash, entry_count) VALUES (1, NULL, 0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- Fortress migration 0008 rollback.
|
|
2
|
+
DROP INDEX IF EXISTS auth_continuation_failure_idx;
|
|
3
|
+
ALTER TABLE fortress_auth_continuation
|
|
4
|
+
DROP COLUMN cooldown_seconds,
|
|
5
|
+
DROP COLUMN max_attempts,
|
|
6
|
+
DROP COLUMN invalidated_at,
|
|
7
|
+
DROP COLUMN last_failed_at,
|
|
8
|
+
DROP COLUMN failed_attempts;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- Fortress migration 0008: bounded MFA continuation attempts.
|
|
2
|
+
ALTER TABLE fortress_auth_continuation
|
|
3
|
+
ADD COLUMN failed_attempts INTEGER NOT NULL DEFAULT 0,
|
|
4
|
+
ADD COLUMN last_failed_at TIMESTAMPTZ,
|
|
5
|
+
ADD COLUMN invalidated_at TIMESTAMPTZ,
|
|
6
|
+
ADD COLUMN max_attempts INTEGER NOT NULL DEFAULT 5,
|
|
7
|
+
ADD COLUMN cooldown_seconds INTEGER NOT NULL DEFAULT 1;
|
|
8
|
+
CREATE INDEX auth_continuation_failure_idx ON fortress_auth_continuation (user_id, reason, last_failed_at);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- Existing TOTP seeds were stored in plaintext. SQL migrations cannot encrypt
|
|
2
|
+
-- them with the application-held key, so fail securely by requiring re-enrolment.
|
|
3
|
+
DELETE FROM fortress_backup_code;
|
|
4
|
+
DELETE FROM fortress_trusted_device;
|
|
5
|
+
DELETE FROM fortress_two_factor_secret;
|