@_mustachio/openauth 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/adapters/d1/audit-log.js +15 -0
- package/dist/esm/adapters/d1/config-store.js +45 -0
- package/dist/esm/adapters/d1/index.js +12 -0
- package/dist/esm/adapters/d1/key-store.js +116 -0
- package/dist/esm/adapters/d1/method-store.js +52 -0
- package/dist/esm/adapters/d1/migrations.js +77 -0
- package/dist/esm/adapters/d1/session-store.js +134 -0
- package/dist/esm/adapters/d1/session.js +18 -0
- package/dist/esm/adapters/d1/token-store.js +140 -0
- package/dist/esm/adapters/durable-object/index.js +3 -0
- package/dist/esm/adapters/durable-object/session-store.js +139 -0
- package/dist/esm/adapters/durable-object/types.js +0 -0
- package/dist/esm/adapters/dynamo/audit-log.js +23 -0
- package/dist/esm/adapters/dynamo/client.js +0 -0
- package/dist/esm/adapters/dynamo/config-store.js +57 -0
- package/dist/esm/adapters/dynamo/index.js +10 -0
- package/dist/esm/adapters/dynamo/key-store.js +188 -0
- package/dist/esm/adapters/dynamo/method-store.js +72 -0
- package/dist/esm/adapters/dynamo/passkey-credential-store.js +83 -0
- package/dist/esm/adapters/dynamo/sdk.js +128 -0
- package/dist/esm/adapters/dynamo/session-store.js +173 -0
- package/dist/esm/adapters/dynamo/token-store.js +178 -0
- package/dist/esm/adapters/kms/in-memory-backing.js +28 -0
- package/dist/esm/adapters/kms/index.js +5 -0
- package/dist/esm/adapters/kms/key-store.js +129 -0
- package/dist/esm/adapters/kms/sdk.js +23 -0
- package/dist/esm/adapters/kms/types.js +0 -0
- package/dist/esm/adapters/kv/audit-log.js +21 -0
- package/dist/esm/adapters/kv/config-store.js +43 -0
- package/dist/esm/adapters/kv/index.js +5 -0
- package/dist/esm/adapters/kv/method-store.js +63 -0
- package/dist/esm/adapters/kv/types.js +0 -0
- package/dist/esm/adapters/memory/audit-log.js +16 -0
- package/dist/esm/adapters/memory/clock.js +5 -0
- package/dist/esm/adapters/memory/config-store.js +31 -0
- package/dist/esm/adapters/memory/index.js +10 -0
- package/dist/esm/adapters/memory/key-store.js +78 -0
- package/dist/esm/adapters/memory/method-store.js +43 -0
- package/dist/esm/adapters/memory/passkey-credential-store.js +53 -0
- package/dist/esm/adapters/memory/session-store.js +82 -0
- package/dist/esm/adapters/memory/token-store.js +91 -0
- package/dist/esm/adapters/postgres/audit-log.js +16 -0
- package/dist/esm/adapters/postgres/config-store.js +48 -0
- package/dist/esm/adapters/postgres/executor.js +21 -0
- package/dist/esm/adapters/postgres/index.js +13 -0
- package/dist/esm/adapters/postgres/key-store.js +191 -0
- package/dist/esm/adapters/postgres/method-store.js +61 -0
- package/dist/esm/adapters/postgres/migrations.js +111 -0
- package/dist/esm/adapters/postgres/passkey-credential-store.js +80 -0
- package/dist/esm/adapters/postgres/session-store.js +135 -0
- package/dist/esm/adapters/postgres/token-store.js +151 -0
- package/dist/esm/client.js +26 -10
- package/dist/esm/domain/audit.js +13 -0
- package/dist/esm/domain/authorize.js +212 -0
- package/dist/esm/domain/callback.js +173 -0
- package/dist/esm/domain/client-auth.js +61 -0
- package/dist/esm/domain/client-credentials.js +91 -0
- package/dist/esm/domain/crypto.js +97 -0
- package/dist/esm/domain/discovery.js +41 -0
- package/dist/esm/domain/introspect.js +51 -0
- package/dist/esm/domain/jwt.js +43 -0
- package/dist/esm/domain/method-cache.js +136 -0
- package/dist/esm/domain/method-dispatch.js +36 -0
- package/dist/esm/domain/method-route.js +108 -0
- package/dist/esm/domain/pkce.js +16 -0
- package/dist/esm/domain/refresh.js +91 -0
- package/dist/esm/domain/revoke.js +81 -0
- package/dist/esm/domain/state-envelope.js +80 -0
- package/dist/esm/domain/token-exchange.js +101 -0
- package/dist/esm/domain/token.js +205 -0
- package/dist/esm/domain/userinfo.js +27 -0
- package/dist/esm/http/context.js +7 -0
- package/dist/esm/http/cookies.js +98 -0
- package/dist/esm/http/errors.js +71 -0
- package/dist/esm/http/handlers/authorize.js +163 -0
- package/dist/esm/http/handlers/callback.js +53 -0
- package/dist/esm/http/handlers/metadata.js +34 -0
- package/dist/esm/http/handlers/method-route.js +87 -0
- package/dist/esm/http/handlers/revocation.js +98 -0
- package/dist/esm/http/handlers/token.js +167 -0
- package/dist/esm/http/handlers/userinfo.js +54 -0
- package/dist/esm/http/middleware/error.js +15 -0
- package/dist/esm/http/middleware/tenant.js +102 -0
- package/dist/esm/http/resolver.js +15 -0
- package/dist/esm/http/router.js +35 -0
- package/dist/esm/http/schemas/authorize.js +24 -0
- package/dist/esm/http/schemas/revocation.js +18 -0
- package/dist/esm/http/schemas/token.js +57 -0
- package/dist/esm/index.js +121 -9
- package/dist/esm/methods/code.js +221 -0
- package/dist/esm/methods/m2m.js +41 -0
- package/dist/esm/methods/oauth2-factory.js +84 -0
- package/dist/esm/methods/oauth2-generic.js +196 -0
- package/dist/esm/methods/oidc-generic.js +53 -0
- package/dist/esm/methods/passkey.js +275 -0
- package/dist/esm/methods/password-hash.js +79 -0
- package/dist/esm/methods/password.js +166 -0
- package/dist/esm/methods/providers/apple.js +29 -0
- package/dist/esm/methods/providers/cognito.js +37 -0
- package/dist/esm/methods/providers/discord.js +28 -0
- package/dist/esm/methods/providers/facebook.js +42 -0
- package/dist/esm/methods/providers/github.js +29 -0
- package/dist/esm/methods/providers/google.js +29 -0
- package/dist/esm/methods/providers/index.js +17 -0
- package/dist/esm/methods/providers/jumpcloud.js +27 -0
- package/dist/esm/methods/providers/keycloak.js +32 -0
- package/dist/esm/methods/providers/linkedin.js +28 -0
- package/dist/esm/methods/providers/microsoft.js +28 -0
- package/dist/esm/methods/providers/slack.js +30 -0
- package/dist/esm/methods/providers/spotify.js +28 -0
- package/dist/esm/methods/providers/twitch.js +28 -0
- package/dist/esm/methods/providers/x.js +28 -0
- package/dist/esm/methods/providers/yahoo.js +27 -0
- package/dist/esm/pkce.js +4 -16
- package/dist/esm/ports/audit-log.js +0 -0
- package/dist/esm/ports/config-store.js +0 -0
- package/dist/esm/ports/key-store.js +0 -0
- package/dist/esm/ports/method-store.js +0 -0
- package/dist/esm/ports/session-store.js +0 -0
- package/dist/esm/ports/token-store.js +0 -0
- package/dist/esm/types/authorization.js +0 -0
- package/dist/esm/types/error.js +65 -0
- package/dist/esm/types/flow.js +0 -0
- package/dist/esm/types/idp.js +0 -0
- package/dist/esm/types/method.js +0 -0
- package/dist/esm/types/picker.js +0 -0
- package/dist/esm/types/result.js +11 -0
- package/dist/esm/types/subject.js +0 -0
- package/dist/esm/types/tenant.js +5 -0
- package/dist/esm/types/token.js +0 -0
- package/dist/esm/ui/forms.js +253 -0
- package/dist/esm/ui/index.js +8 -0
- package/dist/esm/ui/picker.js +49 -0
- package/dist/types/adapters/d1/audit-log.d.ts +19 -0
- package/dist/types/adapters/d1/audit-log.d.ts.map +1 -0
- package/dist/types/adapters/d1/config-store.d.ts +20 -0
- package/dist/types/adapters/d1/config-store.d.ts.map +1 -0
- package/dist/types/adapters/d1/index.d.ts +35 -0
- package/dist/types/adapters/d1/index.d.ts.map +1 -0
- package/dist/types/adapters/d1/key-store.d.ts +17 -0
- package/dist/types/adapters/d1/key-store.d.ts.map +1 -0
- package/dist/types/adapters/d1/method-store.d.ts +21 -0
- package/dist/types/adapters/d1/method-store.d.ts.map +1 -0
- package/dist/types/adapters/d1/migrations.d.ts +18 -0
- package/dist/types/adapters/d1/migrations.d.ts.map +1 -0
- package/dist/types/adapters/d1/session-store.d.ts +20 -0
- package/dist/types/adapters/d1/session-store.d.ts.map +1 -0
- package/dist/types/adapters/d1/session.d.ts +18 -0
- package/dist/types/adapters/d1/session.d.ts.map +1 -0
- package/dist/types/adapters/d1/token-store.d.ts +29 -0
- package/dist/types/adapters/d1/token-store.d.ts.map +1 -0
- package/dist/types/adapters/d1/types.d.ts +43 -0
- package/dist/types/adapters/d1/types.d.ts.map +1 -0
- package/dist/types/adapters/durable-object/index.d.ts +17 -0
- package/dist/types/adapters/durable-object/index.d.ts.map +1 -0
- package/dist/types/adapters/durable-object/session-store.d.ts +21 -0
- package/dist/types/adapters/durable-object/session-store.d.ts.map +1 -0
- package/dist/types/adapters/durable-object/types.d.ts +23 -0
- package/dist/types/adapters/durable-object/types.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/audit-log.d.ts +19 -0
- package/dist/types/adapters/dynamo/audit-log.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/client.d.ts +111 -0
- package/dist/types/adapters/dynamo/client.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/config-store.d.ts +21 -0
- package/dist/types/adapters/dynamo/config-store.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/index.d.ts +60 -0
- package/dist/types/adapters/dynamo/index.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/key-store.d.ts +23 -0
- package/dist/types/adapters/dynamo/key-store.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/method-store.d.ts +20 -0
- package/dist/types/adapters/dynamo/method-store.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/passkey-credential-store.d.ts +47 -0
- package/dist/types/adapters/dynamo/passkey-credential-store.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/sdk.d.ts +23 -0
- package/dist/types/adapters/dynamo/sdk.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/session-store.d.ts +20 -0
- package/dist/types/adapters/dynamo/session-store.d.ts.map +1 -0
- package/dist/types/adapters/dynamo/token-store.d.ts +29 -0
- package/dist/types/adapters/dynamo/token-store.d.ts.map +1 -0
- package/dist/types/adapters/kms/in-memory-backing.d.ts +9 -0
- package/dist/types/adapters/kms/in-memory-backing.d.ts.map +1 -0
- package/dist/types/adapters/kms/index.d.ts +35 -0
- package/dist/types/adapters/kms/index.d.ts.map +1 -0
- package/dist/types/adapters/kms/key-store.d.ts +20 -0
- package/dist/types/adapters/kms/key-store.d.ts.map +1 -0
- package/dist/types/adapters/kms/sdk.d.ts +16 -0
- package/dist/types/adapters/kms/sdk.d.ts.map +1 -0
- package/dist/types/adapters/kms/types.d.ts +58 -0
- package/dist/types/adapters/kms/types.d.ts.map +1 -0
- package/dist/types/adapters/kv/audit-log.d.ts +22 -0
- package/dist/types/adapters/kv/audit-log.d.ts.map +1 -0
- package/dist/types/adapters/kv/config-store.d.ts +25 -0
- package/dist/types/adapters/kv/config-store.d.ts.map +1 -0
- package/dist/types/adapters/kv/index.d.ts +21 -0
- package/dist/types/adapters/kv/index.d.ts.map +1 -0
- package/dist/types/adapters/kv/method-store.d.ts +23 -0
- package/dist/types/adapters/kv/method-store.d.ts.map +1 -0
- package/dist/types/adapters/kv/types.d.ts +28 -0
- package/dist/types/adapters/kv/types.d.ts.map +1 -0
- package/dist/types/adapters/memory/audit-log.d.ts +18 -0
- package/dist/types/adapters/memory/audit-log.d.ts.map +1 -0
- package/dist/types/adapters/memory/clock.d.ts +7 -0
- package/dist/types/adapters/memory/clock.d.ts.map +1 -0
- package/dist/types/adapters/memory/config-store.d.ts +19 -0
- package/dist/types/adapters/memory/config-store.d.ts.map +1 -0
- package/dist/types/adapters/memory/index.d.ts +15 -0
- package/dist/types/adapters/memory/index.d.ts.map +1 -0
- package/dist/types/adapters/memory/key-store.d.ts +17 -0
- package/dist/types/adapters/memory/key-store.d.ts.map +1 -0
- package/dist/types/adapters/memory/method-store.d.ts +26 -0
- package/dist/types/adapters/memory/method-store.d.ts.map +1 -0
- package/dist/types/adapters/memory/passkey-credential-store.d.ts +43 -0
- package/dist/types/adapters/memory/passkey-credential-store.d.ts.map +1 -0
- package/dist/types/adapters/memory/session-store.d.ts +19 -0
- package/dist/types/adapters/memory/session-store.d.ts.map +1 -0
- package/dist/types/adapters/memory/token-store.d.ts +28 -0
- package/dist/types/adapters/memory/token-store.d.ts.map +1 -0
- package/dist/types/adapters/postgres/audit-log.d.ts +18 -0
- package/dist/types/adapters/postgres/audit-log.d.ts.map +1 -0
- package/dist/types/adapters/postgres/config-store.d.ts +21 -0
- package/dist/types/adapters/postgres/config-store.d.ts.map +1 -0
- package/dist/types/adapters/postgres/executor.d.ts +48 -0
- package/dist/types/adapters/postgres/executor.d.ts.map +1 -0
- package/dist/types/adapters/postgres/index.d.ts +39 -0
- package/dist/types/adapters/postgres/index.d.ts.map +1 -0
- package/dist/types/adapters/postgres/key-store.d.ts +23 -0
- package/dist/types/adapters/postgres/key-store.d.ts.map +1 -0
- package/dist/types/adapters/postgres/method-store.d.ts +21 -0
- package/dist/types/adapters/postgres/method-store.d.ts.map +1 -0
- package/dist/types/adapters/postgres/migrations.d.ts +22 -0
- package/dist/types/adapters/postgres/migrations.d.ts.map +1 -0
- package/dist/types/adapters/postgres/passkey-credential-store.d.ts +48 -0
- package/dist/types/adapters/postgres/passkey-credential-store.d.ts.map +1 -0
- package/dist/types/adapters/postgres/session-store.d.ts +20 -0
- package/dist/types/adapters/postgres/session-store.d.ts.map +1 -0
- package/dist/types/adapters/postgres/token-store.d.ts +30 -0
- package/dist/types/adapters/postgres/token-store.d.ts.map +1 -0
- package/dist/types/client.d.ts +1 -1
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/domain/audit.d.ts +17 -0
- package/dist/types/domain/audit.d.ts.map +1 -0
- package/dist/types/domain/authorize.d.ts +125 -0
- package/dist/types/domain/authorize.d.ts.map +1 -0
- package/dist/types/domain/callback.d.ts +70 -0
- package/dist/types/domain/callback.d.ts.map +1 -0
- package/dist/types/domain/client-auth.d.ts +57 -0
- package/dist/types/domain/client-auth.d.ts.map +1 -0
- package/dist/types/domain/client-credentials.d.ts +52 -0
- package/dist/types/domain/client-credentials.d.ts.map +1 -0
- package/dist/types/domain/crypto.d.ts +53 -0
- package/dist/types/domain/crypto.d.ts.map +1 -0
- package/dist/types/domain/discovery.d.ts +44 -0
- package/dist/types/domain/discovery.d.ts.map +1 -0
- package/dist/types/domain/introspect.d.ts +71 -0
- package/dist/types/domain/introspect.d.ts.map +1 -0
- package/dist/types/domain/jwt.d.ts +48 -0
- package/dist/types/domain/jwt.d.ts.map +1 -0
- package/dist/types/domain/method-cache.d.ts +42 -0
- package/dist/types/domain/method-cache.d.ts.map +1 -0
- package/dist/types/domain/method-dispatch.d.ts +37 -0
- package/dist/types/domain/method-dispatch.d.ts.map +1 -0
- package/dist/types/domain/method-route.d.ts +77 -0
- package/dist/types/domain/method-route.d.ts.map +1 -0
- package/dist/types/domain/pkce.d.ts +15 -0
- package/dist/types/domain/pkce.d.ts.map +1 -0
- package/dist/types/domain/refresh.d.ts +43 -0
- package/dist/types/domain/refresh.d.ts.map +1 -0
- package/dist/types/domain/revoke.d.ts +61 -0
- package/dist/types/domain/revoke.d.ts.map +1 -0
- package/dist/types/domain/state-envelope.d.ts +30 -0
- package/dist/types/domain/state-envelope.d.ts.map +1 -0
- package/dist/types/domain/token-exchange.d.ts +67 -0
- package/dist/types/domain/token-exchange.d.ts.map +1 -0
- package/dist/types/domain/token.d.ts +100 -0
- package/dist/types/domain/token.d.ts.map +1 -0
- package/dist/types/domain/userinfo.d.ts +22 -0
- package/dist/types/domain/userinfo.d.ts.map +1 -0
- package/dist/types/http/context.d.ts +63 -0
- package/dist/types/http/context.d.ts.map +1 -0
- package/dist/types/http/cookies.d.ts +45 -0
- package/dist/types/http/cookies.d.ts.map +1 -0
- package/dist/types/http/errors.d.ts +36 -0
- package/dist/types/http/errors.d.ts.map +1 -0
- package/dist/types/http/handlers/authorize.d.ts +3 -0
- package/dist/types/http/handlers/authorize.d.ts.map +1 -0
- package/dist/types/http/handlers/callback.d.ts +3 -0
- package/dist/types/http/handlers/callback.d.ts.map +1 -0
- package/dist/types/http/handlers/metadata.d.ts +4 -0
- package/dist/types/http/handlers/metadata.d.ts.map +1 -0
- package/dist/types/http/handlers/method-route.d.ts +3 -0
- package/dist/types/http/handlers/method-route.d.ts.map +1 -0
- package/dist/types/http/handlers/revocation.d.ts +4 -0
- package/dist/types/http/handlers/revocation.d.ts.map +1 -0
- package/dist/types/http/handlers/token.d.ts +3 -0
- package/dist/types/http/handlers/token.d.ts.map +1 -0
- package/dist/types/http/handlers/userinfo.d.ts +3 -0
- package/dist/types/http/handlers/userinfo.d.ts.map +1 -0
- package/dist/types/http/middleware/error.d.ts +9 -0
- package/dist/types/http/middleware/error.d.ts.map +1 -0
- package/dist/types/http/middleware/tenant.d.ts +30 -0
- package/dist/types/http/middleware/tenant.d.ts.map +1 -0
- package/dist/types/http/resolver.d.ts +22 -0
- package/dist/types/http/resolver.d.ts.map +1 -0
- package/dist/types/http/router.d.ts +21 -0
- package/dist/types/http/router.d.ts.map +1 -0
- package/dist/types/http/schemas/authorize.d.ts +52 -0
- package/dist/types/http/schemas/authorize.d.ts.map +1 -0
- package/dist/types/http/schemas/revocation.d.ts +41 -0
- package/dist/types/http/schemas/revocation.d.ts.map +1 -0
- package/dist/types/http/schemas/token.d.ts +227 -0
- package/dist/types/http/schemas/token.d.ts.map +1 -0
- package/dist/types/index.d.ts +63 -13
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/methods/code.d.ts +96 -0
- package/dist/types/methods/code.d.ts.map +1 -0
- package/dist/types/methods/m2m.d.ts +41 -0
- package/dist/types/methods/m2m.d.ts.map +1 -0
- package/dist/types/methods/oauth2-factory.d.ts +133 -0
- package/dist/types/methods/oauth2-factory.d.ts.map +1 -0
- package/dist/types/methods/oauth2-generic.d.ts +75 -0
- package/dist/types/methods/oauth2-generic.d.ts.map +1 -0
- package/dist/types/methods/oidc-generic.d.ts +26 -0
- package/dist/types/methods/oidc-generic.d.ts.map +1 -0
- package/dist/types/methods/passkey.d.ts +106 -0
- package/dist/types/methods/passkey.d.ts.map +1 -0
- package/dist/types/methods/password-hash.d.ts +25 -0
- package/dist/types/methods/password-hash.d.ts.map +1 -0
- package/dist/types/methods/password.d.ts +70 -0
- package/dist/types/methods/password.d.ts.map +1 -0
- package/dist/types/methods/providers/apple.d.ts +29 -0
- package/dist/types/methods/providers/apple.d.ts.map +1 -0
- package/dist/types/methods/providers/cognito.d.ts +36 -0
- package/dist/types/methods/providers/cognito.d.ts.map +1 -0
- package/dist/types/methods/providers/discord.d.ts +22 -0
- package/dist/types/methods/providers/discord.d.ts.map +1 -0
- package/dist/types/methods/providers/facebook.d.ts +29 -0
- package/dist/types/methods/providers/facebook.d.ts.map +1 -0
- package/dist/types/methods/providers/github.d.ts +25 -0
- package/dist/types/methods/providers/github.d.ts.map +1 -0
- package/dist/types/methods/providers/google.d.ts +28 -0
- package/dist/types/methods/providers/google.d.ts.map +1 -0
- package/dist/types/methods/providers/index.d.ts +24 -0
- package/dist/types/methods/providers/index.d.ts.map +1 -0
- package/dist/types/methods/providers/jumpcloud.d.ts +22 -0
- package/dist/types/methods/providers/jumpcloud.d.ts.map +1 -0
- package/dist/types/methods/providers/keycloak.d.ts +30 -0
- package/dist/types/methods/providers/keycloak.d.ts.map +1 -0
- package/dist/types/methods/providers/linkedin.d.ts +22 -0
- package/dist/types/methods/providers/linkedin.d.ts.map +1 -0
- package/dist/types/methods/providers/microsoft.d.ts +30 -0
- package/dist/types/methods/providers/microsoft.d.ts.map +1 -0
- package/dist/types/methods/providers/slack.d.ts +25 -0
- package/dist/types/methods/providers/slack.d.ts.map +1 -0
- package/dist/types/methods/providers/spotify.d.ts +22 -0
- package/dist/types/methods/providers/spotify.d.ts.map +1 -0
- package/dist/types/methods/providers/twitch.d.ts +23 -0
- package/dist/types/methods/providers/twitch.d.ts.map +1 -0
- package/dist/types/methods/providers/x.d.ts +25 -0
- package/dist/types/methods/providers/x.d.ts.map +1 -0
- package/dist/types/methods/providers/yahoo.d.ts +22 -0
- package/dist/types/methods/providers/yahoo.d.ts.map +1 -0
- package/dist/types/pkce.d.ts +1 -2
- package/dist/types/pkce.d.ts.map +1 -1
- package/dist/types/ports/audit-log.d.ts +139 -0
- package/dist/types/ports/audit-log.d.ts.map +1 -0
- package/dist/types/ports/config-store.d.ts +32 -0
- package/dist/types/ports/config-store.d.ts.map +1 -0
- package/dist/types/ports/key-store.d.ts +98 -0
- package/dist/types/ports/key-store.d.ts.map +1 -0
- package/dist/types/ports/method-store.d.ts +29 -0
- package/dist/types/ports/method-store.d.ts.map +1 -0
- package/dist/types/ports/session-store.d.ts +82 -0
- package/dist/types/ports/session-store.d.ts.map +1 -0
- package/dist/types/ports/token-store.d.ts +93 -0
- package/dist/types/ports/token-store.d.ts.map +1 -0
- package/dist/types/types/authorization.d.ts +52 -0
- package/dist/types/types/authorization.d.ts.map +1 -0
- package/dist/types/types/error.d.ts +92 -0
- package/dist/types/types/error.d.ts.map +1 -0
- package/dist/types/types/flow.d.ts +87 -0
- package/dist/types/types/flow.d.ts.map +1 -0
- package/dist/types/types/idp.d.ts +234 -0
- package/dist/types/types/idp.d.ts.map +1 -0
- package/dist/types/types/method.d.ts +256 -0
- package/dist/types/types/method.d.ts.map +1 -0
- package/dist/types/types/picker.d.ts +31 -0
- package/dist/types/types/picker.d.ts.map +1 -0
- package/dist/types/types/result.d.ts +29 -0
- package/dist/types/types/result.d.ts.map +1 -0
- package/dist/types/types/subject.d.ts +47 -0
- package/dist/types/types/subject.d.ts.map +1 -0
- package/dist/types/types/tenant.d.ts +239 -0
- package/dist/types/types/tenant.d.ts.map +1 -0
- package/dist/types/types/token.d.ts +103 -0
- package/dist/types/types/token.d.ts.map +1 -0
- package/dist/types/ui/forms.d.ts +35 -0
- package/dist/types/ui/forms.d.ts.map +1 -0
- package/dist/types/ui/index.d.ts +14 -0
- package/dist/types/ui/index.d.ts.map +1 -0
- package/dist/types/ui/picker.d.ts +18 -0
- package/dist/types/ui/picker.d.ts.map +1 -0
- package/package.json +41 -6
- package/src/adapters/d1/audit-log.ts +32 -0
- package/src/adapters/d1/config-store.ts +67 -0
- package/src/adapters/d1/index.ts +41 -0
- package/src/adapters/d1/key-store.ts +218 -0
- package/src/adapters/d1/method-store.ts +103 -0
- package/src/adapters/d1/migrations.ts +89 -0
- package/src/adapters/d1/session-store.ts +230 -0
- package/src/adapters/d1/session.ts +38 -0
- package/src/adapters/d1/token-store.ts +251 -0
- package/src/adapters/d1/types.ts +53 -0
- package/src/adapters/durable-object/index.ts +23 -0
- package/src/adapters/durable-object/session-store.ts +227 -0
- package/src/adapters/durable-object/types.ts +25 -0
- package/src/adapters/dynamo/audit-log.ts +35 -0
- package/src/adapters/dynamo/client.ts +118 -0
- package/src/adapters/dynamo/config-store.ts +72 -0
- package/src/adapters/dynamo/index.ts +81 -0
- package/src/adapters/dynamo/key-store.ts +267 -0
- package/src/adapters/dynamo/method-store.ts +105 -0
- package/src/adapters/dynamo/passkey-credential-store.ts +132 -0
- package/src/adapters/dynamo/sdk.ts +189 -0
- package/src/adapters/dynamo/session-store.ts +229 -0
- package/src/adapters/dynamo/token-store.ts +248 -0
- package/src/adapters/kms/in-memory-backing.ts +36 -0
- package/src/adapters/kms/index.ts +39 -0
- package/src/adapters/kms/key-store.ts +176 -0
- package/src/adapters/kms/sdk.ts +39 -0
- package/src/adapters/kms/types.ts +61 -0
- package/src/adapters/kv/audit-log.ts +40 -0
- package/src/adapters/kv/config-store.ts +63 -0
- package/src/adapters/kv/index.ts +20 -0
- package/src/adapters/kv/method-store.ts +98 -0
- package/src/adapters/kv/types.ts +26 -0
- package/src/adapters/memory/audit-log.ts +28 -0
- package/src/adapters/memory/clock.ts +7 -0
- package/src/adapters/memory/config-store.ts +41 -0
- package/src/adapters/memory/index.ts +26 -0
- package/src/adapters/memory/key-store.ts +102 -0
- package/src/adapters/memory/method-store.ts +75 -0
- package/src/adapters/memory/passkey-credential-store.ts +97 -0
- package/src/adapters/memory/session-store.ts +128 -0
- package/src/adapters/memory/token-store.ts +165 -0
- package/src/adapters/postgres/audit-log.ts +34 -0
- package/src/adapters/postgres/config-store.ts +72 -0
- package/src/adapters/postgres/executor.ts +76 -0
- package/src/adapters/postgres/index.ts +60 -0
- package/src/adapters/postgres/key-store.ts +334 -0
- package/src/adapters/postgres/method-store.ts +104 -0
- package/src/adapters/postgres/migrations.ts +131 -0
- package/src/adapters/postgres/passkey-credential-store.ts +150 -0
- package/src/adapters/postgres/session-store.ts +216 -0
- package/src/adapters/postgres/token-store.ts +263 -0
- package/src/client.ts +50 -16
- package/src/domain/audit.ts +28 -0
- package/src/domain/authorize.ts +405 -0
- package/src/domain/callback.ts +263 -0
- package/src/domain/client-auth.ts +116 -0
- package/src/domain/client-credentials.ts +178 -0
- package/src/domain/crypto.ts +168 -0
- package/src/domain/discovery.ts +83 -0
- package/src/domain/introspect.ts +145 -0
- package/src/domain/jwt.ts +106 -0
- package/src/domain/method-cache.ts +220 -0
- package/src/domain/method-dispatch.ts +95 -0
- package/src/domain/method-route.ts +208 -0
- package/src/domain/pkce.ts +37 -0
- package/src/domain/refresh.ts +169 -0
- package/src/domain/revoke.ts +161 -0
- package/src/domain/state-envelope.ts +142 -0
- package/src/domain/token-exchange.ts +232 -0
- package/src/domain/token.ts +357 -0
- package/src/domain/userinfo.ts +56 -0
- package/src/http/context.ts +86 -0
- package/src/http/cookies.ts +167 -0
- package/src/http/errors.ts +98 -0
- package/src/http/handlers/authorize.ts +221 -0
- package/src/http/handlers/callback.ts +77 -0
- package/src/http/handlers/metadata.ts +44 -0
- package/src/http/handlers/method-route.ts +115 -0
- package/src/http/handlers/revocation.ts +151 -0
- package/src/http/handlers/token.ts +244 -0
- package/src/http/handlers/userinfo.ts +66 -0
- package/src/http/middleware/error.ts +26 -0
- package/src/http/middleware/tenant.ts +165 -0
- package/src/http/resolver.ts +34 -0
- package/src/http/router.ts +66 -0
- package/src/http/schemas/authorize.ts +58 -0
- package/src/http/schemas/revocation.ts +23 -0
- package/src/http/schemas/token.ts +85 -0
- package/src/index.ts +266 -20
- package/src/methods/code.ts +359 -0
- package/src/methods/m2m.ts +82 -0
- package/src/methods/oauth2-factory.ts +151 -0
- package/src/methods/oauth2-generic.ts +360 -0
- package/src/methods/oidc-generic.ts +109 -0
- package/src/methods/passkey.ts +419 -0
- package/src/methods/password-hash.ts +134 -0
- package/src/methods/password.ts +298 -0
- package/src/methods/providers/apple.ts +42 -0
- package/src/methods/providers/cognito.ts +55 -0
- package/src/methods/providers/discord.ts +37 -0
- package/src/methods/providers/facebook.ts +54 -0
- package/src/methods/providers/github.ts +42 -0
- package/src/methods/providers/google.ts +43 -0
- package/src/methods/providers/index.ts +23 -0
- package/src/methods/providers/jumpcloud.ts +36 -0
- package/src/methods/providers/keycloak.ts +42 -0
- package/src/methods/providers/linkedin.ts +37 -0
- package/src/methods/providers/microsoft.ts +42 -0
- package/src/methods/providers/slack.ts +42 -0
- package/src/methods/providers/spotify.ts +37 -0
- package/src/methods/providers/twitch.ts +38 -0
- package/src/methods/providers/x.ts +40 -0
- package/src/methods/providers/yahoo.ts +36 -0
- package/src/pkce.ts +20 -21
- package/src/ports/CONSISTENCY.md +88 -0
- package/src/ports/audit-log.ts +148 -0
- package/src/ports/config-store.ts +34 -0
- package/src/ports/key-store.ts +106 -0
- package/src/ports/method-store.ts +41 -0
- package/src/ports/session-store.ts +98 -0
- package/src/ports/token-store.ts +103 -0
- package/src/types/authorization.ts +53 -0
- package/src/types/error.ts +123 -0
- package/src/types/flow.ts +89 -0
- package/src/types/idp.ts +269 -0
- package/src/types/method.ts +270 -0
- package/src/types/picker.ts +32 -0
- package/src/types/result.ts +23 -0
- package/src/types/subject.ts +50 -0
- package/src/types/tenant.ts +248 -0
- package/src/types/token.ts +101 -0
- package/src/ui/forms.ts +289 -0
- package/src/ui/index.ts +14 -0
- package/src/ui/picker.ts +63 -0
- package/dist/esm/issuer.js +0 -691
- package/dist/esm/jwt.js +0 -16
- package/dist/esm/keys.js +0 -113
- package/dist/esm/provider/apple.js +0 -28
- package/dist/esm/provider/arctic.js +0 -43
- package/dist/esm/provider/code.js +0 -58
- package/dist/esm/provider/cognito.js +0 -16
- package/dist/esm/provider/discord.js +0 -15
- package/dist/esm/provider/facebook.js +0 -24
- package/dist/esm/provider/github.js +0 -15
- package/dist/esm/provider/google.js +0 -25
- package/dist/esm/provider/index.js +0 -3
- package/dist/esm/provider/jumpcloud.js +0 -15
- package/dist/esm/provider/keycloak.js +0 -15
- package/dist/esm/provider/linkedin.js +0 -15
- package/dist/esm/provider/m2m.js +0 -16
- package/dist/esm/provider/microsoft.js +0 -24
- package/dist/esm/provider/oauth2.js +0 -119
- package/dist/esm/provider/oidc.js +0 -69
- package/dist/esm/provider/passkey.js +0 -315
- package/dist/esm/provider/password.js +0 -306
- package/dist/esm/provider/provider.js +0 -10
- package/dist/esm/provider/slack.js +0 -15
- package/dist/esm/provider/spotify.js +0 -15
- package/dist/esm/provider/twitch.js +0 -15
- package/dist/esm/provider/x.js +0 -16
- package/dist/esm/provider/yahoo.js +0 -15
- package/dist/esm/random.js +0 -27
- package/dist/esm/storage/aws.js +0 -39
- package/dist/esm/storage/cloudflare.js +0 -42
- package/dist/esm/storage/dynamo.js +0 -116
- package/dist/esm/storage/memory.js +0 -88
- package/dist/esm/storage/storage.js +0 -36
- package/dist/esm/subject.js +0 -7
- package/dist/esm/ui/base.js +0 -407
- package/dist/esm/ui/code.js +0 -151
- package/dist/esm/ui/form.js +0 -43
- package/dist/esm/ui/icon.js +0 -92
- package/dist/esm/ui/passkey.js +0 -329
- package/dist/esm/ui/password.js +0 -338
- package/dist/esm/ui/select.js +0 -187
- package/dist/esm/ui/theme.js +0 -115
- package/dist/esm/util.js +0 -54
- package/dist/types/issuer.d.ts +0 -607
- package/dist/types/issuer.d.ts.map +0 -1
- package/dist/types/jwt.d.ts +0 -6
- package/dist/types/jwt.d.ts.map +0 -1
- package/dist/types/keys.d.ts +0 -18
- package/dist/types/keys.d.ts.map +0 -1
- package/dist/types/provider/apple.d.ts +0 -108
- package/dist/types/provider/apple.d.ts.map +0 -1
- package/dist/types/provider/arctic.d.ts +0 -16
- package/dist/types/provider/arctic.d.ts.map +0 -1
- package/dist/types/provider/code.d.ts +0 -74
- package/dist/types/provider/code.d.ts.map +0 -1
- package/dist/types/provider/cognito.d.ts +0 -64
- package/dist/types/provider/cognito.d.ts.map +0 -1
- package/dist/types/provider/discord.d.ts +0 -38
- package/dist/types/provider/discord.d.ts.map +0 -1
- package/dist/types/provider/facebook.d.ts +0 -74
- package/dist/types/provider/facebook.d.ts.map +0 -1
- package/dist/types/provider/github.d.ts +0 -38
- package/dist/types/provider/github.d.ts.map +0 -1
- package/dist/types/provider/google.d.ts +0 -74
- package/dist/types/provider/google.d.ts.map +0 -1
- package/dist/types/provider/index.d.ts +0 -4
- package/dist/types/provider/index.d.ts.map +0 -1
- package/dist/types/provider/jumpcloud.d.ts +0 -38
- package/dist/types/provider/jumpcloud.d.ts.map +0 -1
- package/dist/types/provider/keycloak.d.ts +0 -67
- package/dist/types/provider/keycloak.d.ts.map +0 -1
- package/dist/types/provider/linkedin.d.ts +0 -6
- package/dist/types/provider/linkedin.d.ts.map +0 -1
- package/dist/types/provider/m2m.d.ts +0 -34
- package/dist/types/provider/m2m.d.ts.map +0 -1
- package/dist/types/provider/microsoft.d.ts +0 -89
- package/dist/types/provider/microsoft.d.ts.map +0 -1
- package/dist/types/provider/oauth2.d.ts +0 -133
- package/dist/types/provider/oauth2.d.ts.map +0 -1
- package/dist/types/provider/oidc.d.ts +0 -91
- package/dist/types/provider/oidc.d.ts.map +0 -1
- package/dist/types/provider/passkey.d.ts +0 -143
- package/dist/types/provider/passkey.d.ts.map +0 -1
- package/dist/types/provider/password.d.ts +0 -210
- package/dist/types/provider/password.d.ts.map +0 -1
- package/dist/types/provider/provider.d.ts +0 -29
- package/dist/types/provider/provider.d.ts.map +0 -1
- package/dist/types/provider/slack.d.ts +0 -59
- package/dist/types/provider/slack.d.ts.map +0 -1
- package/dist/types/provider/spotify.d.ts +0 -38
- package/dist/types/provider/spotify.d.ts.map +0 -1
- package/dist/types/provider/twitch.d.ts +0 -38
- package/dist/types/provider/twitch.d.ts.map +0 -1
- package/dist/types/provider/x.d.ts +0 -38
- package/dist/types/provider/x.d.ts.map +0 -1
- package/dist/types/provider/yahoo.d.ts +0 -38
- package/dist/types/provider/yahoo.d.ts.map +0 -1
- package/dist/types/random.d.ts +0 -3
- package/dist/types/random.d.ts.map +0 -1
- package/dist/types/storage/aws.d.ts +0 -4
- package/dist/types/storage/aws.d.ts.map +0 -1
- package/dist/types/storage/cloudflare.d.ts +0 -34
- package/dist/types/storage/cloudflare.d.ts.map +0 -1
- package/dist/types/storage/dynamo.d.ts +0 -65
- package/dist/types/storage/dynamo.d.ts.map +0 -1
- package/dist/types/storage/memory.d.ts +0 -49
- package/dist/types/storage/memory.d.ts.map +0 -1
- package/dist/types/storage/storage.d.ts +0 -15
- package/dist/types/storage/storage.d.ts.map +0 -1
- package/dist/types/subject.d.ts +0 -122
- package/dist/types/subject.d.ts.map +0 -1
- package/dist/types/ui/base.d.ts +0 -5
- package/dist/types/ui/base.d.ts.map +0 -1
- package/dist/types/ui/code.d.ts +0 -104
- package/dist/types/ui/code.d.ts.map +0 -1
- package/dist/types/ui/form.d.ts +0 -6
- package/dist/types/ui/form.d.ts.map +0 -1
- package/dist/types/ui/icon.d.ts +0 -6
- package/dist/types/ui/icon.d.ts.map +0 -1
- package/dist/types/ui/passkey.d.ts +0 -5
- package/dist/types/ui/passkey.d.ts.map +0 -1
- package/dist/types/ui/password.d.ts +0 -139
- package/dist/types/ui/password.d.ts.map +0 -1
- package/dist/types/ui/select.d.ts +0 -55
- package/dist/types/ui/select.d.ts.map +0 -1
- package/dist/types/ui/theme.d.ts +0 -207
- package/dist/types/ui/theme.d.ts.map +0 -1
- package/dist/types/util.d.ts +0 -8
- package/dist/types/util.d.ts.map +0 -1
- package/src/css.d.ts +0 -4
- package/src/issuer.ts +0 -1628
- package/src/jwt.ts +0 -17
- package/src/keys.ts +0 -139
- package/src/provider/apple.ts +0 -127
- package/src/provider/arctic.ts +0 -66
- package/src/provider/code.ts +0 -227
- package/src/provider/cognito.ts +0 -74
- package/src/provider/discord.ts +0 -45
- package/src/provider/facebook.ts +0 -84
- package/src/provider/github.ts +0 -45
- package/src/provider/google.ts +0 -85
- package/src/provider/index.ts +0 -3
- package/src/provider/jumpcloud.ts +0 -45
- package/src/provider/keycloak.ts +0 -75
- package/src/provider/linkedin.ts +0 -12
- package/src/provider/m2m.ts +0 -56
- package/src/provider/microsoft.ts +0 -100
- package/src/provider/oauth2.ts +0 -297
- package/src/provider/oidc.ts +0 -179
- package/src/provider/passkey.ts +0 -655
- package/src/provider/password.ts +0 -672
- package/src/provider/provider.ts +0 -33
- package/src/provider/slack.ts +0 -67
- package/src/provider/spotify.ts +0 -45
- package/src/provider/twitch.ts +0 -45
- package/src/provider/x.ts +0 -46
- package/src/provider/yahoo.ts +0 -45
- package/src/random.ts +0 -24
- package/src/storage/aws.ts +0 -59
- package/src/storage/cloudflare.ts +0 -77
- package/src/storage/dynamo.ts +0 -193
- package/src/storage/memory.ts +0 -135
- package/src/storage/storage.ts +0 -46
- package/src/subject.ts +0 -130
- package/src/ui/base.tsx +0 -118
- package/src/ui/code.tsx +0 -215
- package/src/ui/form.tsx +0 -40
- package/src/ui/icon.tsx +0 -95
- package/src/ui/passkey.tsx +0 -321
- package/src/ui/password.tsx +0 -405
- package/src/ui/select.tsx +0 -221
- package/src/ui/theme.ts +0 -319
- package/src/ui/ui.css +0 -252
- package/src/util.ts +0 -58
- /package/dist/esm/{css.d.js → adapters/d1/types.js} +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres `PasskeyCredentialStore`.
|
|
3
|
+
*
|
|
4
|
+
* Schema (created by `migrate()` in `./migrations.ts`):
|
|
5
|
+
*
|
|
6
|
+
* openauth_passkey_credentials
|
|
7
|
+
* tenant_id text NOT NULL
|
|
8
|
+
* credential_id text NOT NULL
|
|
9
|
+
* user_id text NOT NULL
|
|
10
|
+
* public_key text NOT NULL
|
|
11
|
+
* counter bigint NOT NULL DEFAULT 0
|
|
12
|
+
* transports jsonb
|
|
13
|
+
* created_at bigint NOT NULL
|
|
14
|
+
* PRIMARY KEY (tenant_id, credential_id)
|
|
15
|
+
* INDEX (tenant_id, user_id) -- findByUsername path
|
|
16
|
+
*
|
|
17
|
+
* The reference adapter treats `userId` as the username lookup key —
|
|
18
|
+
* matching the bundled `passkeyMethod` which sets `userId =
|
|
19
|
+
* parsed.data.username` at registration. Hosts that want a separate
|
|
20
|
+
* username dimension implement `PasskeyCredentialStore` directly
|
|
21
|
+
* against their own user table.
|
|
22
|
+
*/
|
|
23
|
+
import type {
|
|
24
|
+
PasskeyCredentialStore,
|
|
25
|
+
StoredCredential,
|
|
26
|
+
} from "../../methods/passkey"
|
|
27
|
+
|
|
28
|
+
import type { PostgresExecutor } from "./executor"
|
|
29
|
+
|
|
30
|
+
export type PostgresPasskeyCredentialStoreOptions = {
|
|
31
|
+
exec: PostgresExecutor
|
|
32
|
+
clock?: () => number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type Row = {
|
|
36
|
+
credential_id: string
|
|
37
|
+
user_id: string
|
|
38
|
+
public_key: string
|
|
39
|
+
counter: string | number
|
|
40
|
+
transports: unknown
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class PostgresPasskeyCredentialStore implements PasskeyCredentialStore {
|
|
44
|
+
#exec: PostgresExecutor
|
|
45
|
+
#clock: () => number
|
|
46
|
+
|
|
47
|
+
constructor(opts: PostgresPasskeyCredentialStoreOptions) {
|
|
48
|
+
this.#exec = opts.exec
|
|
49
|
+
this.#clock = opts.clock ?? (() => Date.now())
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async findByUsername(
|
|
53
|
+
username: string,
|
|
54
|
+
tenantId: string,
|
|
55
|
+
): Promise<{ userId: string; credentials: StoredCredential[] } | null> {
|
|
56
|
+
const result = await this.#exec.query<Row>(
|
|
57
|
+
`SELECT credential_id, user_id, public_key, counter, transports
|
|
58
|
+
FROM openauth_passkey_credentials
|
|
59
|
+
WHERE tenant_id = $1 AND user_id = $2`,
|
|
60
|
+
[tenantId, username],
|
|
61
|
+
)
|
|
62
|
+
if (result.rows.length === 0) return null
|
|
63
|
+
return {
|
|
64
|
+
userId: username,
|
|
65
|
+
credentials: result.rows.map(rowToCredential),
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async findById(
|
|
70
|
+
credentialId: string,
|
|
71
|
+
tenantId: string,
|
|
72
|
+
): Promise<StoredCredential | null> {
|
|
73
|
+
const result = await this.#exec.query<Row>(
|
|
74
|
+
`SELECT credential_id, user_id, public_key, counter, transports
|
|
75
|
+
FROM openauth_passkey_credentials
|
|
76
|
+
WHERE tenant_id = $1 AND credential_id = $2`,
|
|
77
|
+
[tenantId, credentialId],
|
|
78
|
+
)
|
|
79
|
+
const row = result.rows[0]
|
|
80
|
+
if (!row) return null
|
|
81
|
+
return rowToCredential(row)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async updateCounter(input: {
|
|
85
|
+
credentialId: string
|
|
86
|
+
counter: number
|
|
87
|
+
tenantId: string
|
|
88
|
+
}): Promise<void> {
|
|
89
|
+
await this.#exec.query(
|
|
90
|
+
`UPDATE openauth_passkey_credentials
|
|
91
|
+
SET counter = $1
|
|
92
|
+
WHERE tenant_id = $2 AND credential_id = $3`,
|
|
93
|
+
[input.counter, input.tenantId, input.credentialId],
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async create(input: {
|
|
98
|
+
userId: string
|
|
99
|
+
credential: StoredCredential
|
|
100
|
+
tenantId: string
|
|
101
|
+
}): Promise<void> {
|
|
102
|
+
await this.#exec.query(
|
|
103
|
+
`INSERT INTO openauth_passkey_credentials
|
|
104
|
+
(tenant_id, credential_id, user_id, public_key, counter, transports, created_at)
|
|
105
|
+
VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7)
|
|
106
|
+
ON CONFLICT (tenant_id, credential_id) DO UPDATE
|
|
107
|
+
SET public_key = EXCLUDED.public_key,
|
|
108
|
+
counter = EXCLUDED.counter,
|
|
109
|
+
transports = EXCLUDED.transports,
|
|
110
|
+
user_id = EXCLUDED.user_id`,
|
|
111
|
+
[
|
|
112
|
+
input.tenantId,
|
|
113
|
+
input.credential.credentialId,
|
|
114
|
+
input.userId,
|
|
115
|
+
input.credential.publicKey,
|
|
116
|
+
input.credential.counter,
|
|
117
|
+
input.credential.transports
|
|
118
|
+
? JSON.stringify(input.credential.transports)
|
|
119
|
+
: null,
|
|
120
|
+
this.#clock(),
|
|
121
|
+
],
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function rowToCredential(row: Row): StoredCredential {
|
|
127
|
+
const credential: StoredCredential = {
|
|
128
|
+
credentialId: row.credential_id,
|
|
129
|
+
publicKey: row.public_key,
|
|
130
|
+
counter: Number(row.counter),
|
|
131
|
+
userId: row.user_id,
|
|
132
|
+
}
|
|
133
|
+
if (row.transports != null) {
|
|
134
|
+
credential.transports = parseTransports(row.transports)
|
|
135
|
+
}
|
|
136
|
+
return credential
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function parseTransports(raw: unknown): string[] {
|
|
140
|
+
if (Array.isArray(raw)) return raw.map(String)
|
|
141
|
+
if (typeof raw === "string") {
|
|
142
|
+
try {
|
|
143
|
+
const parsed: unknown = JSON.parse(raw)
|
|
144
|
+
return Array.isArray(parsed) ? parsed.map(String) : []
|
|
145
|
+
} catch {
|
|
146
|
+
return []
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return []
|
|
150
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres `SessionStore` — flow records + optional long-lived sessions.
|
|
3
|
+
*
|
|
4
|
+
* `consumeFlow` is `DELETE … RETURNING payload, expires_at` — atomic
|
|
5
|
+
* single-winner, returns the full record so the framework can snapshot
|
|
6
|
+
* fields into the auth-code payload before disposal.
|
|
7
|
+
*
|
|
8
|
+
* `updateFlowMethodState` merges new state into the existing JSONB blob via
|
|
9
|
+
* a single UPDATE (no read-modify-write race).
|
|
10
|
+
*/
|
|
11
|
+
import { authError } from "../../types/error"
|
|
12
|
+
import type { FlowRecord } from "../../types/flow"
|
|
13
|
+
import type { SessionRecord, SessionStore } from "../../ports/session-store"
|
|
14
|
+
import type { Result } from "../../types/result"
|
|
15
|
+
import { err, ok } from "../../types/result"
|
|
16
|
+
|
|
17
|
+
import type { PostgresExecutor } from "./executor"
|
|
18
|
+
|
|
19
|
+
export type PostgresSessionStoreOptions = {
|
|
20
|
+
exec: PostgresExecutor
|
|
21
|
+
clock?: () => number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class PostgresSessionStore implements SessionStore {
|
|
25
|
+
#exec: PostgresExecutor
|
|
26
|
+
#clock: () => number
|
|
27
|
+
|
|
28
|
+
constructor(opts: PostgresSessionStoreOptions) {
|
|
29
|
+
this.#exec = opts.exec
|
|
30
|
+
this.#clock = opts.clock ?? (() => Date.now())
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async saveFlow(
|
|
34
|
+
flowId: string,
|
|
35
|
+
payload: FlowRecord,
|
|
36
|
+
ttl: number,
|
|
37
|
+
): Promise<Result<void>> {
|
|
38
|
+
if (ttl <= 0) {
|
|
39
|
+
return err(
|
|
40
|
+
authError.internalError(`saveFlow: ttl must be positive, got ${ttl}`),
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
const expiresAt = this.#clock() + ttl
|
|
44
|
+
try {
|
|
45
|
+
await this.#exec.query(
|
|
46
|
+
`INSERT INTO openauth_flows (flow_id, payload, expires_at)
|
|
47
|
+
VALUES ($1, $2::jsonb, $3)`,
|
|
48
|
+
[flowId, JSON.stringify(payload), expiresAt],
|
|
49
|
+
)
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return err(authError.internalError("saveFlow: insert failed", e))
|
|
52
|
+
}
|
|
53
|
+
return ok(undefined)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async updateFlowMethodState(
|
|
57
|
+
flowId: string,
|
|
58
|
+
methodState: unknown,
|
|
59
|
+
): Promise<Result<void>> {
|
|
60
|
+
const now = this.#clock()
|
|
61
|
+
let row: { exists: boolean } | undefined
|
|
62
|
+
try {
|
|
63
|
+
// jsonb_set patches the nested key without a read-modify-write race.
|
|
64
|
+
const result = await this.#exec.query<{ exists: boolean }>(
|
|
65
|
+
`UPDATE openauth_flows
|
|
66
|
+
SET payload = jsonb_set(payload, '{methodState}', $1::jsonb, true)
|
|
67
|
+
WHERE flow_id = $2 AND expires_at > $3
|
|
68
|
+
RETURNING true AS exists`,
|
|
69
|
+
[JSON.stringify(methodState), flowId, now],
|
|
70
|
+
)
|
|
71
|
+
row = result.rows[0]
|
|
72
|
+
} catch (e) {
|
|
73
|
+
return err(
|
|
74
|
+
authError.internalError("updateFlowMethodState: update failed", e),
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
if (!row) {
|
|
78
|
+
return err(authError.unknownState(`flow "${flowId}" unknown or expired`))
|
|
79
|
+
}
|
|
80
|
+
return ok(undefined)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async readFlow(flowId: string): Promise<Result<FlowRecord>> {
|
|
84
|
+
let row: { payload: unknown; expires_at: string | number } | undefined
|
|
85
|
+
try {
|
|
86
|
+
const result = await this.#exec.query<{
|
|
87
|
+
payload: unknown
|
|
88
|
+
expires_at: string | number
|
|
89
|
+
}>(`SELECT payload, expires_at FROM openauth_flows WHERE flow_id = $1`, [
|
|
90
|
+
flowId,
|
|
91
|
+
])
|
|
92
|
+
row = result.rows[0]
|
|
93
|
+
} catch (e) {
|
|
94
|
+
return err(authError.internalError("readFlow: query failed", e))
|
|
95
|
+
}
|
|
96
|
+
if (!row) {
|
|
97
|
+
return err(authError.unknownState(`flow "${flowId}" unknown`))
|
|
98
|
+
}
|
|
99
|
+
if (this.#clock() >= Number(row.expires_at)) {
|
|
100
|
+
// Lazy GC — best-effort delete, don't fail the read if the delete races.
|
|
101
|
+
try {
|
|
102
|
+
await this.#exec.query(
|
|
103
|
+
`DELETE FROM openauth_flows WHERE flow_id = $1`,
|
|
104
|
+
[flowId],
|
|
105
|
+
)
|
|
106
|
+
} catch {}
|
|
107
|
+
return err(authError.unknownState(`flow "${flowId}" expired`))
|
|
108
|
+
}
|
|
109
|
+
return ok(parseFlowRecord(row.payload))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async consumeFlow(flowId: string): Promise<Result<FlowRecord>> {
|
|
113
|
+
let row: { payload: unknown; expires_at: string | number } | undefined
|
|
114
|
+
try {
|
|
115
|
+
// Atomic delete-on-read — single-winner under concurrent presentations.
|
|
116
|
+
const result = await this.#exec.query<{
|
|
117
|
+
payload: unknown
|
|
118
|
+
expires_at: string | number
|
|
119
|
+
}>(
|
|
120
|
+
`DELETE FROM openauth_flows
|
|
121
|
+
WHERE flow_id = $1
|
|
122
|
+
RETURNING payload, expires_at`,
|
|
123
|
+
[flowId],
|
|
124
|
+
)
|
|
125
|
+
row = result.rows[0]
|
|
126
|
+
} catch (e) {
|
|
127
|
+
return err(authError.internalError("consumeFlow: query failed", e))
|
|
128
|
+
}
|
|
129
|
+
if (!row) {
|
|
130
|
+
return err(
|
|
131
|
+
authError.unknownState(`flow "${flowId}" unknown or already consumed`),
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
if (this.#clock() >= Number(row.expires_at)) {
|
|
135
|
+
return err(authError.unknownState(`flow "${flowId}" expired`))
|
|
136
|
+
}
|
|
137
|
+
return ok(parseFlowRecord(row.payload))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async createSession(
|
|
141
|
+
sessionId: string,
|
|
142
|
+
payload: SessionRecord,
|
|
143
|
+
ttl: number,
|
|
144
|
+
): Promise<Result<void>> {
|
|
145
|
+
if (ttl <= 0) {
|
|
146
|
+
return err(
|
|
147
|
+
authError.internalError(
|
|
148
|
+
`createSession: ttl must be positive, got ${ttl}`,
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
const expiresAt = this.#clock() + ttl
|
|
153
|
+
try {
|
|
154
|
+
await this.#exec.query(
|
|
155
|
+
`INSERT INTO openauth_sessions (session_id, payload, expires_at)
|
|
156
|
+
VALUES ($1, $2::jsonb, $3)
|
|
157
|
+
ON CONFLICT (session_id) DO UPDATE SET payload = EXCLUDED.payload, expires_at = EXCLUDED.expires_at`,
|
|
158
|
+
[sessionId, JSON.stringify(payload), expiresAt],
|
|
159
|
+
)
|
|
160
|
+
} catch (e) {
|
|
161
|
+
return err(authError.internalError("createSession: insert failed", e))
|
|
162
|
+
}
|
|
163
|
+
return ok(undefined)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async readSession(sessionId: string): Promise<Result<SessionRecord>> {
|
|
167
|
+
let row: { payload: unknown; expires_at: string | number } | undefined
|
|
168
|
+
try {
|
|
169
|
+
const result = await this.#exec.query<{
|
|
170
|
+
payload: unknown
|
|
171
|
+
expires_at: string | number
|
|
172
|
+
}>(
|
|
173
|
+
`SELECT payload, expires_at FROM openauth_sessions WHERE session_id = $1`,
|
|
174
|
+
[sessionId],
|
|
175
|
+
)
|
|
176
|
+
row = result.rows[0]
|
|
177
|
+
} catch (e) {
|
|
178
|
+
return err(authError.internalError("readSession: query failed", e))
|
|
179
|
+
}
|
|
180
|
+
if (!row) {
|
|
181
|
+
return err(authError.invalidRequest(`session "${sessionId}" unknown`))
|
|
182
|
+
}
|
|
183
|
+
if (this.#clock() >= Number(row.expires_at)) {
|
|
184
|
+
try {
|
|
185
|
+
await this.#exec.query(
|
|
186
|
+
`DELETE FROM openauth_sessions WHERE session_id = $1`,
|
|
187
|
+
[sessionId],
|
|
188
|
+
)
|
|
189
|
+
} catch {}
|
|
190
|
+
return err(authError.invalidRequest(`session "${sessionId}" expired`))
|
|
191
|
+
}
|
|
192
|
+
return ok(parseSession(row.payload))
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async revokeSession(sessionId: string): Promise<Result<void>> {
|
|
196
|
+
try {
|
|
197
|
+
await this.#exec.query(
|
|
198
|
+
`DELETE FROM openauth_sessions WHERE session_id = $1`,
|
|
199
|
+
[sessionId],
|
|
200
|
+
)
|
|
201
|
+
} catch (e) {
|
|
202
|
+
return err(authError.internalError("revokeSession: delete failed", e))
|
|
203
|
+
}
|
|
204
|
+
return ok(undefined)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function parseFlowRecord(raw: unknown): FlowRecord {
|
|
209
|
+
if (typeof raw === "string") return JSON.parse(raw) as FlowRecord
|
|
210
|
+
return raw as FlowRecord
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function parseSession(raw: unknown): SessionRecord {
|
|
214
|
+
if (typeof raw === "string") return JSON.parse(raw) as SessionRecord
|
|
215
|
+
return raw as SessionRecord
|
|
216
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres `TokenStore`.
|
|
3
|
+
*
|
|
4
|
+
* - `consumeCode` is an atomic `DELETE … RETURNING` so concurrent
|
|
5
|
+
* presentations of the same code resolve to exactly one winner. The
|
|
6
|
+
* ciphertext blob is stored verbatim — `domain/authorize.ts` encrypts
|
|
7
|
+
* payloads before they reach the adapter (M1), and `domain/token.ts`
|
|
8
|
+
* decrypts after consume. The DB never sees plaintext.
|
|
9
|
+
* - `consumeRefresh` does an atomic `UPDATE … WHERE consumed_at IS NULL
|
|
10
|
+
* RETURNING payload` so a refresh chain has a single live winner per
|
|
11
|
+
* generation. Reuse-detection within the configurable window auto-revokes
|
|
12
|
+
* the family.
|
|
13
|
+
*
|
|
14
|
+
* On reuse-detection the adapter returns `invalid_grant` and populates
|
|
15
|
+
* the structured `reuseSignal` carrier on the error (family / tenantId /
|
|
16
|
+
* subjectId), per the `TokenStore` port contract. The domain's audit
|
|
17
|
+
* emission consumes the typed signal directly — no string parsing.
|
|
18
|
+
*/
|
|
19
|
+
import { AUTH_CODE_TTL_MS } from "../../domain/authorize"
|
|
20
|
+
import type { KeyStore } from "../../ports/key-store"
|
|
21
|
+
import type { TokenStore } from "../../ports/token-store"
|
|
22
|
+
import { authError } from "../../types/error"
|
|
23
|
+
import type { Result } from "../../types/result"
|
|
24
|
+
import { err, ok } from "../../types/result"
|
|
25
|
+
import type { TenantId } from "../../types/tenant"
|
|
26
|
+
import type { RefreshTokenPayload } from "../../types/token"
|
|
27
|
+
|
|
28
|
+
import type { PostgresExecutor } from "./executor"
|
|
29
|
+
|
|
30
|
+
export type PostgresTokenStoreOptions = {
|
|
31
|
+
exec: PostgresExecutor
|
|
32
|
+
/**
|
|
33
|
+
* Optional — retained for API stability after M1 moved code-payload
|
|
34
|
+
* encryption to the domain layer. The adapter no longer touches it.
|
|
35
|
+
*/
|
|
36
|
+
keyStore?: KeyStore
|
|
37
|
+
/** Injectable clock — defaults to `Date.now`. Tests advance it. */
|
|
38
|
+
clock?: () => number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class PostgresTokenStore implements TokenStore {
|
|
42
|
+
#exec: PostgresExecutor
|
|
43
|
+
#clock: () => number
|
|
44
|
+
|
|
45
|
+
constructor(opts: PostgresTokenStoreOptions) {
|
|
46
|
+
this.#exec = opts.exec
|
|
47
|
+
this.#clock = opts.clock ?? (() => Date.now())
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async saveCode(
|
|
51
|
+
code: string,
|
|
52
|
+
ciphertext: string,
|
|
53
|
+
ttl: number,
|
|
54
|
+
): Promise<Result<void>> {
|
|
55
|
+
if (ttl <= 0 || ttl > AUTH_CODE_TTL_MS) {
|
|
56
|
+
return err(
|
|
57
|
+
authError.internalError(
|
|
58
|
+
`saveCode: ttl ${ttl} outside (0, ${AUTH_CODE_TTL_MS}] (auth-code TTL is fixed at 60s by OAuth 2.1 BCP)`,
|
|
59
|
+
),
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
const expiresAt = this.#clock() + ttl
|
|
63
|
+
try {
|
|
64
|
+
await this.#exec.query(
|
|
65
|
+
`INSERT INTO openauth_codes (code, ciphertext, expires_at) VALUES ($1, $2, $3)`,
|
|
66
|
+
[code, ciphertext, expiresAt],
|
|
67
|
+
)
|
|
68
|
+
} catch (e) {
|
|
69
|
+
return err(authError.internalError("saveCode: insert failed", e))
|
|
70
|
+
}
|
|
71
|
+
return ok(undefined)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async consumeCode(code: string): Promise<Result<string>> {
|
|
75
|
+
let row: { ciphertext: string; expires_at: string | number } | undefined
|
|
76
|
+
try {
|
|
77
|
+
const result = await this.#exec.query<{
|
|
78
|
+
ciphertext: string
|
|
79
|
+
expires_at: string | number
|
|
80
|
+
}>(
|
|
81
|
+
`DELETE FROM openauth_codes WHERE code = $1 RETURNING ciphertext, expires_at`,
|
|
82
|
+
[code],
|
|
83
|
+
)
|
|
84
|
+
row = result.rows[0]
|
|
85
|
+
} catch (e) {
|
|
86
|
+
return err(authError.internalError("consumeCode: query failed", e))
|
|
87
|
+
}
|
|
88
|
+
if (!row) {
|
|
89
|
+
return err(
|
|
90
|
+
authError.invalidGrant("auth code unknown or already consumed"),
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
if (this.#clock() >= Number(row.expires_at)) {
|
|
94
|
+
return err(authError.invalidGrant("auth code expired"))
|
|
95
|
+
}
|
|
96
|
+
return ok(row.ciphertext)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async saveRefresh(
|
|
100
|
+
refresh: string,
|
|
101
|
+
payload: RefreshTokenPayload,
|
|
102
|
+
): Promise<Result<void>> {
|
|
103
|
+
try {
|
|
104
|
+
await this.#exec.query(
|
|
105
|
+
`INSERT INTO openauth_refresh_tokens
|
|
106
|
+
(token, tenant_id, client_id, subject_id, family, expires_at, payload)
|
|
107
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
|
|
108
|
+
[
|
|
109
|
+
refresh,
|
|
110
|
+
payload.tenantId,
|
|
111
|
+
payload.clientId,
|
|
112
|
+
payload.subjectId,
|
|
113
|
+
payload.family,
|
|
114
|
+
payload.expiresAt,
|
|
115
|
+
JSON.stringify(payload),
|
|
116
|
+
],
|
|
117
|
+
)
|
|
118
|
+
} catch (e) {
|
|
119
|
+
return err(authError.internalError("saveRefresh: insert failed", e))
|
|
120
|
+
}
|
|
121
|
+
return ok(undefined)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async consumeRefresh(
|
|
125
|
+
refresh: string,
|
|
126
|
+
options: { reuseWindowMs?: number } = {},
|
|
127
|
+
): Promise<Result<RefreshTokenPayload>> {
|
|
128
|
+
const reuseWindow = options.reuseWindowMs ?? 60_000
|
|
129
|
+
const now = this.#clock()
|
|
130
|
+
// First try to atomically claim the token — exactly one concurrent caller
|
|
131
|
+
// gets a row back. The UPDATE bounds-checks expiry under the same row
|
|
132
|
+
// lock so an expired token won't be marked consumed under us.
|
|
133
|
+
let claimed: { payload: unknown } | undefined
|
|
134
|
+
try {
|
|
135
|
+
const result = await this.#exec.query<{ payload: unknown }>(
|
|
136
|
+
`UPDATE openauth_refresh_tokens
|
|
137
|
+
SET consumed_at = $1
|
|
138
|
+
WHERE token = $2
|
|
139
|
+
AND consumed_at IS NULL
|
|
140
|
+
AND expires_at > $1
|
|
141
|
+
RETURNING payload`,
|
|
142
|
+
[now, refresh],
|
|
143
|
+
)
|
|
144
|
+
claimed = result.rows[0]
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return err(authError.internalError("consumeRefresh: claim failed", e))
|
|
147
|
+
}
|
|
148
|
+
if (claimed) {
|
|
149
|
+
return ok(parseRefreshPayload(claimed.payload))
|
|
150
|
+
}
|
|
151
|
+
// No row claimed. Find out why — unknown, expired, or already consumed.
|
|
152
|
+
let existing:
|
|
153
|
+
| {
|
|
154
|
+
consumed_at: string | number | null
|
|
155
|
+
expires_at: string | number
|
|
156
|
+
payload: unknown
|
|
157
|
+
}
|
|
158
|
+
| undefined
|
|
159
|
+
try {
|
|
160
|
+
const result = await this.#exec.query<{
|
|
161
|
+
consumed_at: string | number | null
|
|
162
|
+
expires_at: string | number
|
|
163
|
+
payload: unknown
|
|
164
|
+
}>(
|
|
165
|
+
`SELECT consumed_at, expires_at, payload
|
|
166
|
+
FROM openauth_refresh_tokens
|
|
167
|
+
WHERE token = $1`,
|
|
168
|
+
[refresh],
|
|
169
|
+
)
|
|
170
|
+
existing = result.rows[0]
|
|
171
|
+
} catch (e) {
|
|
172
|
+
return err(authError.internalError("consumeRefresh: lookup failed", e))
|
|
173
|
+
}
|
|
174
|
+
if (!existing) {
|
|
175
|
+
return err(authError.invalidGrant("refresh token unknown"))
|
|
176
|
+
}
|
|
177
|
+
if (existing.consumed_at !== null && existing.consumed_at !== undefined) {
|
|
178
|
+
const consumedAt = Number(existing.consumed_at)
|
|
179
|
+
const withinWindow = now - consumedAt <= reuseWindow
|
|
180
|
+
if (withinWindow) {
|
|
181
|
+
const payload = parseRefreshPayload(existing.payload)
|
|
182
|
+
await this.revokeFamily(payload.family)
|
|
183
|
+
return err(
|
|
184
|
+
authError.invalidGrant(
|
|
185
|
+
`refresh token reuse detected (family=${payload.family})`,
|
|
186
|
+
{
|
|
187
|
+
family: payload.family,
|
|
188
|
+
tenantId: payload.tenantId,
|
|
189
|
+
subjectId: payload.subjectId,
|
|
190
|
+
},
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
return err(authError.invalidGrant("refresh token already consumed"))
|
|
195
|
+
}
|
|
196
|
+
if (now >= Number(existing.expires_at)) {
|
|
197
|
+
return err(authError.invalidGrant("refresh token expired"))
|
|
198
|
+
}
|
|
199
|
+
// Should be unreachable — the UPDATE matched neither, but the row is
|
|
200
|
+
// unconsumed and unexpired. Surface as internal so we notice.
|
|
201
|
+
return err(authError.internalError("consumeRefresh: unexplained miss"))
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async peekRefresh(refresh: string): Promise<Result<RefreshTokenPayload>> {
|
|
205
|
+
let row: { expires_at: string | number; payload: unknown } | undefined
|
|
206
|
+
try {
|
|
207
|
+
const result = await this.#exec.query<{
|
|
208
|
+
expires_at: string | number
|
|
209
|
+
payload: unknown
|
|
210
|
+
}>(
|
|
211
|
+
`SELECT expires_at, payload
|
|
212
|
+
FROM openauth_refresh_tokens
|
|
213
|
+
WHERE token = $1`,
|
|
214
|
+
[refresh],
|
|
215
|
+
)
|
|
216
|
+
row = result.rows[0]
|
|
217
|
+
} catch (e) {
|
|
218
|
+
return err(authError.internalError("peekRefresh: lookup failed", e))
|
|
219
|
+
}
|
|
220
|
+
if (!row) {
|
|
221
|
+
return err(authError.invalidGrant("refresh token unknown"))
|
|
222
|
+
}
|
|
223
|
+
if (this.#clock() >= Number(row.expires_at)) {
|
|
224
|
+
return err(authError.invalidGrant("refresh token expired"))
|
|
225
|
+
}
|
|
226
|
+
return ok(parseRefreshPayload(row.payload))
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async revokeFamily(family: string): Promise<Result<void>> {
|
|
230
|
+
try {
|
|
231
|
+
await this.#exec.query(
|
|
232
|
+
`DELETE FROM openauth_refresh_tokens WHERE family = $1`,
|
|
233
|
+
[family],
|
|
234
|
+
)
|
|
235
|
+
} catch (e) {
|
|
236
|
+
return err(authError.internalError("revokeFamily: delete failed", e))
|
|
237
|
+
}
|
|
238
|
+
return ok(undefined)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async revokeBySubject(
|
|
242
|
+
tenantId: TenantId,
|
|
243
|
+
subjectId: string,
|
|
244
|
+
): Promise<Result<void>> {
|
|
245
|
+
try {
|
|
246
|
+
await this.#exec.query(
|
|
247
|
+
`DELETE FROM openauth_refresh_tokens
|
|
248
|
+
WHERE tenant_id = $1 AND subject_id = $2`,
|
|
249
|
+
[tenantId, subjectId],
|
|
250
|
+
)
|
|
251
|
+
} catch (e) {
|
|
252
|
+
return err(authError.internalError("revokeBySubject: delete failed", e))
|
|
253
|
+
}
|
|
254
|
+
return ok(undefined)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function parseRefreshPayload(raw: unknown): RefreshTokenPayload {
|
|
259
|
+
// PGlite returns parsed JSON; postgres-js may return a string depending on
|
|
260
|
+
// pool config. Be tolerant of both.
|
|
261
|
+
if (typeof raw === "string") return JSON.parse(raw) as RefreshTokenPayload
|
|
262
|
+
return raw as RefreshTokenPayload
|
|
263
|
+
}
|