@_mustachio/openauth 0.9.1 → 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,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DynamoExecutor` — the operation surface the adapters depend on.
|
|
3
|
+
*
|
|
4
|
+
* Keeps the AWS SDK out of the adapter's import graph. Production users
|
|
5
|
+
* wire the executor via `fromDynamoDBClient(docClient, tableName)`; tests
|
|
6
|
+
* supply an in-memory implementation (`test/helpers/dynamo-shim.ts`).
|
|
7
|
+
*
|
|
8
|
+
* All operations target a single table (the adapter is single-table by
|
|
9
|
+
* design — pk + sk + optional GSIs). The executor knows the table name; the
|
|
10
|
+
* adapter only passes keys + data.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type DynamoKey = { pk: string; sk: string }
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Strong read by primary key. `consistentRead` MUST be honoured for every
|
|
17
|
+
* security-critical read (`getCode`, `getRefresh`, `getFlow`) — DynamoDB
|
|
18
|
+
* defaults to eventually consistent reads which violate the contracts in
|
|
19
|
+
* `ports/CONSISTENCY.md`.
|
|
20
|
+
*/
|
|
21
|
+
export type DynamoGetInput = {
|
|
22
|
+
key: DynamoKey
|
|
23
|
+
consistentRead: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Insert (`condition: "not-exists"`) or unconditional put. The adapter uses:
|
|
28
|
+
* - `"not-exists"` for code / refresh / flow inserts so a duplicate token
|
|
29
|
+
* never silently overwrites.
|
|
30
|
+
* - `"exists"` for read-modify-write paths (e.g. `updateFlowMethodState`)
|
|
31
|
+
* so the put fails if a concurrent `consumeFlow` deleted the row between
|
|
32
|
+
* the prior `get` and this `put`. The executor surfaces a
|
|
33
|
+
* `ConditionalCheckFailedException` that callers translate into a typed
|
|
34
|
+
* failure.
|
|
35
|
+
*/
|
|
36
|
+
export type DynamoPutInput = {
|
|
37
|
+
item: Record<string, unknown> & DynamoKey
|
|
38
|
+
condition?: "not-exists" | "exists"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Atomic delete-on-read — equivalent to `DeleteItem` with
|
|
43
|
+
* `ReturnValues=ALL_OLD`. Concurrent calls resolve to exactly one winner
|
|
44
|
+
* that gets the row back; losers get `undefined`.
|
|
45
|
+
*/
|
|
46
|
+
export type DynamoDeleteInput = {
|
|
47
|
+
key: DynamoKey
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Conditional UPDATE used for the refresh-token rotation. Sets `consumed_at`
|
|
52
|
+
* iff it is currently absent. Returns the post-update item on success;
|
|
53
|
+
* resolves with `null` if the condition failed (`ConditionalCheckFailed`).
|
|
54
|
+
*/
|
|
55
|
+
export type DynamoUpdateConsumeRefreshInput = {
|
|
56
|
+
key: DynamoKey
|
|
57
|
+
now: number
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Query items by partition key (and optionally a sort-key prefix). Strongly
|
|
62
|
+
* consistent for the refresh-revoke paths.
|
|
63
|
+
*/
|
|
64
|
+
export type DynamoQueryInput = {
|
|
65
|
+
pk: string
|
|
66
|
+
/** Sort-key prefix filter — emits `begins_with(sk, prefix)`. */
|
|
67
|
+
skBeginsWith?: string
|
|
68
|
+
consistentRead: boolean
|
|
69
|
+
/** Filter by an attribute (e.g. `family = :v` for `revokeFamily` via GSI). */
|
|
70
|
+
filter?: {
|
|
71
|
+
attribute: string
|
|
72
|
+
equals: string
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type DynamoQueryByGsiInput = {
|
|
77
|
+
/**
|
|
78
|
+
* GSI name configured on the table. Each entry corresponds to a GSI
|
|
79
|
+
* the bundled adapters need:
|
|
80
|
+
* - `family-index` (refresh-token family revocation)
|
|
81
|
+
* - `subject-index` (revokeBySubject)
|
|
82
|
+
* - `passkey-user-index` (PasskeyCredentialStore.findByUsername)
|
|
83
|
+
*/
|
|
84
|
+
indexName: "family-index" | "subject-index" | "passkey-user-index"
|
|
85
|
+
/** Hash key value on the GSI. */
|
|
86
|
+
hashKey: string
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Update a single item's attributes — equivalent to DynamoDB's
|
|
91
|
+
* `UpdateItem` with a `SET` expression over each provided attribute.
|
|
92
|
+
*
|
|
93
|
+
* Used by passkey-counter updates today; future Phase 8 features
|
|
94
|
+
* (DPoP jti replay, etc.) may reuse it.
|
|
95
|
+
*/
|
|
96
|
+
export type DynamoUpdateItemInput = {
|
|
97
|
+
key: DynamoKey
|
|
98
|
+
/** Attribute name → new value. Top-level only, no nested updates. */
|
|
99
|
+
set: Record<string, unknown>
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type DynamoExecutor = {
|
|
103
|
+
get(input: DynamoGetInput): Promise<Record<string, unknown> | undefined>
|
|
104
|
+
put(input: DynamoPutInput): Promise<void>
|
|
105
|
+
/** Returns the deleted item if one was deleted; `undefined` otherwise. */
|
|
106
|
+
delete(input: DynamoDeleteInput): Promise<Record<string, unknown> | undefined>
|
|
107
|
+
/**
|
|
108
|
+
* Atomic refresh-token claim. Returns the post-update item on success;
|
|
109
|
+
* `null` if the condition failed (already-consumed race).
|
|
110
|
+
*/
|
|
111
|
+
consumeRefresh(
|
|
112
|
+
input: DynamoUpdateConsumeRefreshInput,
|
|
113
|
+
): Promise<Record<string, unknown> | null>
|
|
114
|
+
query(input: DynamoQueryInput): Promise<Record<string, unknown>[]>
|
|
115
|
+
queryByGsi(input: DynamoQueryByGsiInput): Promise<Record<string, unknown>[]>
|
|
116
|
+
/** Generic attribute update. No-op if the item does not exist. */
|
|
117
|
+
updateItem(input: DynamoUpdateItemInput): Promise<void>
|
|
118
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynamoDB `ConfigStore`. `pk="tenant"`, `sk=<tenantId>`. Read-eventual
|
|
3
|
+
* by default (config is read-heavy, write-rare); the invalidation hook
|
|
4
|
+
* fires on every `putTenantConfig` so in-process caches drop stale values
|
|
5
|
+
* immediately.
|
|
6
|
+
*/
|
|
7
|
+
import type { ConfigStore } from "../../ports/config-store"
|
|
8
|
+
import { authError } from "../../types/error"
|
|
9
|
+
import type { Result } from "../../types/result"
|
|
10
|
+
import { err, ok } from "../../types/result"
|
|
11
|
+
import type { TenantConfig, TenantId } from "../../types/tenant"
|
|
12
|
+
|
|
13
|
+
import type { DynamoExecutor } from "./client"
|
|
14
|
+
|
|
15
|
+
export type DynamoConfigStoreOptions = {
|
|
16
|
+
exec: DynamoExecutor
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class DynamoConfigStore implements ConfigStore {
|
|
20
|
+
#exec: DynamoExecutor
|
|
21
|
+
#listeners = new Set<(id: TenantId) => void>()
|
|
22
|
+
|
|
23
|
+
constructor(opts: DynamoConfigStoreOptions) {
|
|
24
|
+
this.#exec = opts.exec
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async getTenantConfig(id: TenantId): Promise<Result<TenantConfig>> {
|
|
28
|
+
let row: Record<string, unknown> | undefined
|
|
29
|
+
try {
|
|
30
|
+
row = await this.#exec.get({
|
|
31
|
+
key: { pk: "tenant", sk: id },
|
|
32
|
+
consistentRead: false,
|
|
33
|
+
})
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return err(authError.internalError("getTenantConfig: get failed", e))
|
|
36
|
+
}
|
|
37
|
+
if (!row) {
|
|
38
|
+
return err(authError.tenantNotFound(`tenant "${id}" not found`, id))
|
|
39
|
+
}
|
|
40
|
+
return ok(parseConfig(row.config))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async putTenantConfig(config: TenantConfig): Promise<Result<void>> {
|
|
44
|
+
try {
|
|
45
|
+
await this.#exec.put({
|
|
46
|
+
item: {
|
|
47
|
+
pk: "tenant",
|
|
48
|
+
sk: config.id,
|
|
49
|
+
config: JSON.stringify(config),
|
|
50
|
+
updated_at: Date.now(),
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return err(authError.internalError("putTenantConfig: put failed", e))
|
|
55
|
+
}
|
|
56
|
+
for (const fn of this.#listeners) {
|
|
57
|
+
try {
|
|
58
|
+
fn(config.id)
|
|
59
|
+
} catch {}
|
|
60
|
+
}
|
|
61
|
+
return ok(undefined)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
onInvalidate(handler: (id: TenantId) => void): void {
|
|
65
|
+
this.#listeners.add(handler)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function parseConfig(raw: unknown): TenantConfig {
|
|
70
|
+
if (typeof raw === "string") return JSON.parse(raw) as TenantConfig
|
|
71
|
+
return raw as TenantConfig
|
|
72
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS DynamoDB adapter set.
|
|
3
|
+
*
|
|
4
|
+
* Single-table design with `pk` / `sk` primary key plus three GSIs:
|
|
5
|
+
*
|
|
6
|
+
* `family-index` hash = `family` (revokeFamily)
|
|
7
|
+
* `subject-index` hash = `subject_key` (revokeBySubject) — value is `<tenantId>#<subjectId>`
|
|
8
|
+
* `passkey-user-index` hash = `user_key` (PasskeyCredentialStore.findByUsername) — value is `<tenantId>#<userId>`
|
|
9
|
+
*
|
|
10
|
+
* The adapter satisfies every contract in `ports/CONSISTENCY.md` provided
|
|
11
|
+
* the underlying calls use `ConsistentRead=true` on the strong reads and
|
|
12
|
+
* `ConditionExpression` on the rotation `UpdateItem` — both are handled by
|
|
13
|
+
* `fromDynamoDBClient`.
|
|
14
|
+
*
|
|
15
|
+
* Wiring:
|
|
16
|
+
* @example
|
|
17
|
+
* import { DynamoDBClient } from "@aws-sdk/client-dynamodb"
|
|
18
|
+
* import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb"
|
|
19
|
+
* import {
|
|
20
|
+
* fromDynamoDBClient,
|
|
21
|
+
* DynamoTokenStore,
|
|
22
|
+
* DynamoSessionStore,
|
|
23
|
+
* // ...
|
|
24
|
+
* } from "@_mustachio/openauth/adapters/dynamo"
|
|
25
|
+
*
|
|
26
|
+
* const docClient = DynamoDBDocumentClient.from(new DynamoDBClient({ region: "us-east-1" }))
|
|
27
|
+
* const exec = fromDynamoDBClient(docClient, "openauth")
|
|
28
|
+
* const keyStore = new DynamoKeyStore({ exec })
|
|
29
|
+
* const tokenStore = new DynamoTokenStore({ exec, keyStore })
|
|
30
|
+
*
|
|
31
|
+
* Table creation is left to the operator (Terraform / CDK / `aws dynamodb
|
|
32
|
+
* create-table`). The schema you need:
|
|
33
|
+
*
|
|
34
|
+
* Table: openauth (or any name you choose)
|
|
35
|
+
* Hash key: pk (S)
|
|
36
|
+
* Range key: sk (S)
|
|
37
|
+
* TTL attribute: `ttl` (epoch seconds)
|
|
38
|
+
*
|
|
39
|
+
* GSI: family-index
|
|
40
|
+
* Hash key: family (S)
|
|
41
|
+
* Projection: ALL
|
|
42
|
+
*
|
|
43
|
+
* GSI: subject-index
|
|
44
|
+
* Hash key: subject_key (S)
|
|
45
|
+
* Projection: ALL
|
|
46
|
+
*
|
|
47
|
+
* GSI: passkey-user-index
|
|
48
|
+
* Hash key: user_key (S)
|
|
49
|
+
* Projection: ALL
|
|
50
|
+
*/
|
|
51
|
+
export { DynamoAuditLog, type DynamoAuditLogOptions } from "./audit-log"
|
|
52
|
+
export {
|
|
53
|
+
DynamoConfigStore,
|
|
54
|
+
type DynamoConfigStoreOptions,
|
|
55
|
+
} from "./config-store"
|
|
56
|
+
export { DynamoKeyStore, type DynamoKeyStoreOptions } from "./key-store"
|
|
57
|
+
export {
|
|
58
|
+
DynamoMethodStore,
|
|
59
|
+
type DynamoMethodStoreOptions,
|
|
60
|
+
} from "./method-store"
|
|
61
|
+
export {
|
|
62
|
+
DynamoSessionStore,
|
|
63
|
+
type DynamoSessionStoreOptions,
|
|
64
|
+
} from "./session-store"
|
|
65
|
+
export { DynamoTokenStore, type DynamoTokenStoreOptions } from "./token-store"
|
|
66
|
+
export {
|
|
67
|
+
DynamoPasskeyCredentialStore,
|
|
68
|
+
type DynamoPasskeyCredentialStoreOptions,
|
|
69
|
+
} from "./passkey-credential-store"
|
|
70
|
+
export { fromDynamoDBClient } from "./sdk"
|
|
71
|
+
export type {
|
|
72
|
+
DynamoDeleteInput,
|
|
73
|
+
DynamoExecutor,
|
|
74
|
+
DynamoGetInput,
|
|
75
|
+
DynamoKey,
|
|
76
|
+
DynamoPutInput,
|
|
77
|
+
DynamoQueryByGsiInput,
|
|
78
|
+
DynamoQueryInput,
|
|
79
|
+
DynamoUpdateConsumeRefreshInput,
|
|
80
|
+
DynamoUpdateItemInput,
|
|
81
|
+
} from "./client"
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynamoDB `KeyStore`. Single-table — signing keys under `pk="signing-key"`,
|
|
3
|
+
* encryption keys under `pk="encryption-key"`. Private JWKs are stored as
|
|
4
|
+
* JSON strings; encryption key material as base64url. Auto-generates an
|
|
5
|
+
* active key pair on first read.
|
|
6
|
+
*
|
|
7
|
+
* **At-rest protection.** Pass `wrapper: { wrap, unwrap }` to encrypt the
|
|
8
|
+
* private JWK and the encryption-key bytes under a host-controlled master
|
|
9
|
+
* key (typically a KMS Encrypt/Decrypt round trip). Without a wrapper the
|
|
10
|
+
* adapter stores private material in plaintext at rest — acceptable for
|
|
11
|
+
* dev / local use, **not** acceptable for production. See `INTEGRATION.md`
|
|
12
|
+
* §4. The `private_jwk_wrapped` / `key_material_wrapped` attributes record
|
|
13
|
+
* which representation each item uses.
|
|
14
|
+
*/
|
|
15
|
+
import type { JWK } from "jose"
|
|
16
|
+
import { exportJWK, generateKeyPair, importJWK } from "jose"
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
base64url,
|
|
20
|
+
generateSymmetricKey,
|
|
21
|
+
randomId,
|
|
22
|
+
utf8,
|
|
23
|
+
} from "../../domain/crypto"
|
|
24
|
+
import type {
|
|
25
|
+
EncryptionKey,
|
|
26
|
+
KeyStore,
|
|
27
|
+
KeyWrapper,
|
|
28
|
+
SigningKey,
|
|
29
|
+
} from "../../ports/key-store"
|
|
30
|
+
import { authError } from "../../types/error"
|
|
31
|
+
import type { Result } from "../../types/result"
|
|
32
|
+
import { err, ok } from "../../types/result"
|
|
33
|
+
|
|
34
|
+
import type { DynamoExecutor } from "./client"
|
|
35
|
+
|
|
36
|
+
export type DynamoKeyStoreOptions = {
|
|
37
|
+
exec: DynamoExecutor
|
|
38
|
+
clock?: () => number
|
|
39
|
+
signingAlg?: "ES256" | "EdDSA"
|
|
40
|
+
/**
|
|
41
|
+
* Optional envelope that encrypts private JWKs and encryption-key bytes
|
|
42
|
+
* before they leave the process. STRONGLY RECOMMENDED in production.
|
|
43
|
+
* Pair with a cloud KMS or HSM-backed implementation.
|
|
44
|
+
*/
|
|
45
|
+
wrapper?: KeyWrapper
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class DynamoKeyStore implements KeyStore {
|
|
49
|
+
#exec: DynamoExecutor
|
|
50
|
+
#clock: () => number
|
|
51
|
+
#signingAlg: "ES256" | "EdDSA"
|
|
52
|
+
#wrapper: KeyWrapper | undefined
|
|
53
|
+
#privateKeyCache = new Map<string, unknown>()
|
|
54
|
+
|
|
55
|
+
constructor(opts: DynamoKeyStoreOptions) {
|
|
56
|
+
this.#exec = opts.exec
|
|
57
|
+
this.#clock = opts.clock ?? (() => Date.now())
|
|
58
|
+
this.#signingAlg = opts.signingAlg ?? "ES256"
|
|
59
|
+
this.#wrapper = opts.wrapper
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async currentSigningKey(): Promise<Result<SigningKey>> {
|
|
63
|
+
await this.#ensureSigningKey()
|
|
64
|
+
const items = await this.#exec.query({
|
|
65
|
+
pk: "signing-key",
|
|
66
|
+
consistentRead: true,
|
|
67
|
+
filter: { attribute: "status", equals: "active" },
|
|
68
|
+
})
|
|
69
|
+
const row = items[0]
|
|
70
|
+
if (!row) {
|
|
71
|
+
return err(
|
|
72
|
+
authError.internalError(
|
|
73
|
+
"no active signing key (should be unreachable)",
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
return ok(await this.#hydrateSigning(row))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async signingKeys(): Promise<Result<SigningKey[]>> {
|
|
81
|
+
await this.#ensureSigningKey()
|
|
82
|
+
const items = await this.#exec.query({
|
|
83
|
+
pk: "signing-key",
|
|
84
|
+
consistentRead: false,
|
|
85
|
+
})
|
|
86
|
+
const keys = await Promise.all(items.map((r) => this.#hydrateSigning(r)))
|
|
87
|
+
return ok(keys)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async currentEncryptionKey(): Promise<Result<EncryptionKey>> {
|
|
91
|
+
await this.#ensureEncryptionKey()
|
|
92
|
+
const items = await this.#exec.query({
|
|
93
|
+
pk: "encryption-key",
|
|
94
|
+
consistentRead: true,
|
|
95
|
+
filter: { attribute: "status", equals: "active" },
|
|
96
|
+
})
|
|
97
|
+
const row = items[0]
|
|
98
|
+
if (!row) {
|
|
99
|
+
return err(
|
|
100
|
+
authError.internalError(
|
|
101
|
+
"no active encryption key (should be unreachable)",
|
|
102
|
+
),
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
return ok(await this.#hydrateEncryption(row))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async getEncryptionKey(kid: string): Promise<Result<EncryptionKey>> {
|
|
109
|
+
const row = await this.#exec.get({
|
|
110
|
+
key: { pk: "encryption-key", sk: kid },
|
|
111
|
+
consistentRead: true,
|
|
112
|
+
})
|
|
113
|
+
if (!row) {
|
|
114
|
+
return err(authError.internalError(`encryption key "${kid}" not found`))
|
|
115
|
+
}
|
|
116
|
+
return ok(await this.#hydrateEncryption(row))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async #ensureSigningKey(): Promise<void> {
|
|
120
|
+
const items = await this.#exec.query({
|
|
121
|
+
pk: "signing-key",
|
|
122
|
+
consistentRead: true,
|
|
123
|
+
filter: { attribute: "status", equals: "active" },
|
|
124
|
+
})
|
|
125
|
+
if (items.length > 0) return
|
|
126
|
+
const { publicKey, privateKey } = await generateKeyPair(this.#signingAlg, {
|
|
127
|
+
extractable: true,
|
|
128
|
+
})
|
|
129
|
+
const publicJwk = await exportJWK(publicKey)
|
|
130
|
+
const privateJwk = await exportJWK(privateKey)
|
|
131
|
+
const kid = randomId()
|
|
132
|
+
const privateJwkStored = await this.#encodePrivateJwk(privateJwk)
|
|
133
|
+
try {
|
|
134
|
+
await this.#exec.put({
|
|
135
|
+
item: {
|
|
136
|
+
pk: "signing-key",
|
|
137
|
+
sk: kid,
|
|
138
|
+
alg: this.#signingAlg,
|
|
139
|
+
crv: publicJwk.crv ?? null,
|
|
140
|
+
public_jwk: JSON.stringify(publicJwk),
|
|
141
|
+
private_jwk: privateJwkStored,
|
|
142
|
+
private_jwk_wrapped: this.#wrapper !== undefined,
|
|
143
|
+
status: "active",
|
|
144
|
+
created_at: this.#clock(),
|
|
145
|
+
},
|
|
146
|
+
condition: "not-exists",
|
|
147
|
+
})
|
|
148
|
+
} catch {
|
|
149
|
+
// Lost a race against another instance — fine; their key now exists.
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async #ensureEncryptionKey(): Promise<void> {
|
|
154
|
+
const items = await this.#exec.query({
|
|
155
|
+
pk: "encryption-key",
|
|
156
|
+
consistentRead: true,
|
|
157
|
+
filter: { attribute: "status", equals: "active" },
|
|
158
|
+
})
|
|
159
|
+
if (items.length > 0) return
|
|
160
|
+
const kid = randomId()
|
|
161
|
+
const raw = generateSymmetricKey()
|
|
162
|
+
// DynamoDB stores bytes as Buffer/Uint8Array; base64url-encoded string is
|
|
163
|
+
// portable, supports `aws-sdk-client-mock`, and is marshalled back the
|
|
164
|
+
// same way. Wrapped bytes are encoded the same way after KMS encrypt.
|
|
165
|
+
const stored = this.#wrapper
|
|
166
|
+
? base64url.encode(await this.#wrapper.wrap(raw))
|
|
167
|
+
: base64url.encode(raw)
|
|
168
|
+
try {
|
|
169
|
+
await this.#exec.put({
|
|
170
|
+
item: {
|
|
171
|
+
pk: "encryption-key",
|
|
172
|
+
sk: kid,
|
|
173
|
+
alg: "A256GCM",
|
|
174
|
+
key_material: stored,
|
|
175
|
+
key_material_wrapped: this.#wrapper !== undefined,
|
|
176
|
+
status: "active",
|
|
177
|
+
created_at: this.#clock(),
|
|
178
|
+
},
|
|
179
|
+
condition: "not-exists",
|
|
180
|
+
})
|
|
181
|
+
} catch {}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async #hydrateSigning(row: Record<string, unknown>): Promise<SigningKey> {
|
|
185
|
+
const kid = String(row.sk)
|
|
186
|
+
let imported = this.#privateKeyCache.get(kid)
|
|
187
|
+
if (!imported) {
|
|
188
|
+
const privateJwk = await this.#decodePrivateJwk(
|
|
189
|
+
String(row.private_jwk),
|
|
190
|
+
row.private_jwk_wrapped === true,
|
|
191
|
+
)
|
|
192
|
+
imported = await importJWK(privateJwk, String(row.alg))
|
|
193
|
+
this.#privateKeyCache.set(kid, imported)
|
|
194
|
+
}
|
|
195
|
+
const publicJwk = JSON.parse(String(row.public_jwk)) as Record<
|
|
196
|
+
string,
|
|
197
|
+
unknown
|
|
198
|
+
>
|
|
199
|
+
return {
|
|
200
|
+
kid,
|
|
201
|
+
alg: String(row.alg),
|
|
202
|
+
...(row.crv ? { crv: String(row.crv) } : {}),
|
|
203
|
+
publicJwk,
|
|
204
|
+
privateKeyRef: imported,
|
|
205
|
+
status: String(row.status) as SigningKey["status"],
|
|
206
|
+
createdAt: Number(row.created_at),
|
|
207
|
+
...(row.rotated_at !== undefined && row.rotated_at !== null
|
|
208
|
+
? { rotatedAt: Number(row.rotated_at) }
|
|
209
|
+
: {}),
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async #hydrateEncryption(
|
|
214
|
+
row: Record<string, unknown>,
|
|
215
|
+
): Promise<EncryptionKey> {
|
|
216
|
+
const stored = base64url.decode(String(row.key_material))
|
|
217
|
+
let keyRef = stored
|
|
218
|
+
if (row.key_material_wrapped === true) {
|
|
219
|
+
if (!this.#wrapper) {
|
|
220
|
+
throw new Error(
|
|
221
|
+
"DynamoKeyStore: encryption key item is wrapped but no `wrapper` was supplied — refusing to read",
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
keyRef = await this.#wrapper.unwrap(stored)
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
kid: String(row.sk),
|
|
228
|
+
alg: String(row.alg),
|
|
229
|
+
keyRef,
|
|
230
|
+
status: String(row.status) as EncryptionKey["status"],
|
|
231
|
+
createdAt: Number(row.created_at),
|
|
232
|
+
...(row.rotated_at !== undefined && row.rotated_at !== null
|
|
233
|
+
? { rotatedAt: Number(row.rotated_at) }
|
|
234
|
+
: {}),
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Encode a private JWK for the `private_jwk` attribute. With a wrapper,
|
|
240
|
+
* the JWK bytes are encrypted and stored as `{"ct": <base64url>}` —
|
|
241
|
+
* never as a recognizable JWK at rest. Without one, the JWK is JSON-
|
|
242
|
+
* stringified verbatim (legacy path).
|
|
243
|
+
*/
|
|
244
|
+
async #encodePrivateJwk(jwk: JWK): Promise<string> {
|
|
245
|
+
if (!this.#wrapper) return JSON.stringify(jwk)
|
|
246
|
+
const ciphertext = await this.#wrapper.wrap(
|
|
247
|
+
utf8.encode(JSON.stringify(jwk)),
|
|
248
|
+
)
|
|
249
|
+
return JSON.stringify({ ct: base64url.encode(ciphertext) })
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async #decodePrivateJwk(raw: string, wrapped: boolean): Promise<JWK> {
|
|
253
|
+
const parsed = JSON.parse(raw) as Record<string, unknown>
|
|
254
|
+
if (!wrapped) return parsed as unknown as JWK
|
|
255
|
+
if (!this.#wrapper) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
"DynamoKeyStore: signing key item is wrapped but no `wrapper` was supplied — refusing to read",
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
const ct = typeof parsed.ct === "string" ? parsed.ct : ""
|
|
261
|
+
if (!ct) {
|
|
262
|
+
throw new Error("DynamoKeyStore: wrapped signing key item missing `ct`")
|
|
263
|
+
}
|
|
264
|
+
const plaintext = await this.#wrapper.unwrap(base64url.decode(ct))
|
|
265
|
+
return JSON.parse(utf8.decode(plaintext)) as JWK
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynamoDB `MethodStore`. `pk="tenant-methods:<tenantId>"`, `sk=<methodId>`.
|
|
3
|
+
* Co-locating methods per-tenant lets `listMethods` use a single Query.
|
|
4
|
+
*/
|
|
5
|
+
import type { MethodStore } from "../../ports/method-store"
|
|
6
|
+
import { authError } from "../../types/error"
|
|
7
|
+
import type { Result } from "../../types/result"
|
|
8
|
+
import { err, ok } from "../../types/result"
|
|
9
|
+
import type { MethodConfig, TenantId } from "../../types/tenant"
|
|
10
|
+
|
|
11
|
+
import type { DynamoExecutor } from "./client"
|
|
12
|
+
|
|
13
|
+
const partitionKey = (tenantId: TenantId) => `tenant-methods:${tenantId}`
|
|
14
|
+
|
|
15
|
+
export type DynamoMethodStoreOptions = {
|
|
16
|
+
exec: DynamoExecutor
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class DynamoMethodStore implements MethodStore {
|
|
20
|
+
#exec: DynamoExecutor
|
|
21
|
+
|
|
22
|
+
constructor(opts: DynamoMethodStoreOptions) {
|
|
23
|
+
this.#exec = opts.exec
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async listMethods(tenantId: TenantId): Promise<Result<MethodConfig[]>> {
|
|
27
|
+
let items: Record<string, unknown>[]
|
|
28
|
+
try {
|
|
29
|
+
items = await this.#exec.query({
|
|
30
|
+
pk: partitionKey(tenantId),
|
|
31
|
+
consistentRead: false,
|
|
32
|
+
})
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return err(authError.internalError("listMethods: query failed", e))
|
|
35
|
+
}
|
|
36
|
+
const methods = items
|
|
37
|
+
.map((r) => parseMethod(r.config))
|
|
38
|
+
.sort((a, b) => a.id.localeCompare(b.id))
|
|
39
|
+
return ok(methods)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async getMethodConfig(
|
|
43
|
+
tenantId: TenantId,
|
|
44
|
+
methodId: string,
|
|
45
|
+
): Promise<Result<MethodConfig>> {
|
|
46
|
+
let row: Record<string, unknown> | undefined
|
|
47
|
+
try {
|
|
48
|
+
row = await this.#exec.get({
|
|
49
|
+
key: { pk: partitionKey(tenantId), sk: methodId },
|
|
50
|
+
consistentRead: false,
|
|
51
|
+
})
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return err(authError.internalError("getMethodConfig: get failed", e))
|
|
54
|
+
}
|
|
55
|
+
if (!row) {
|
|
56
|
+
return err(
|
|
57
|
+
authError.methodNotFound(
|
|
58
|
+
`method "${methodId}" not found for tenant "${tenantId}"`,
|
|
59
|
+
{ methodId },
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
return ok(parseMethod(row.config))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async putMethodConfig(
|
|
67
|
+
tenantId: TenantId,
|
|
68
|
+
method: MethodConfig,
|
|
69
|
+
): Promise<Result<void>> {
|
|
70
|
+
try {
|
|
71
|
+
await this.#exec.put({
|
|
72
|
+
item: {
|
|
73
|
+
pk: partitionKey(tenantId),
|
|
74
|
+
sk: method.id,
|
|
75
|
+
config: JSON.stringify(method),
|
|
76
|
+
updated_at: Date.now(),
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
} catch (e) {
|
|
80
|
+
return err(authError.internalError("putMethodConfig: put failed", e))
|
|
81
|
+
}
|
|
82
|
+
return ok(undefined)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async deleteMethodConfig(
|
|
86
|
+
tenantId: TenantId,
|
|
87
|
+
methodId: string,
|
|
88
|
+
): Promise<Result<void>> {
|
|
89
|
+
try {
|
|
90
|
+
await this.#exec.delete({
|
|
91
|
+
key: { pk: partitionKey(tenantId), sk: methodId },
|
|
92
|
+
})
|
|
93
|
+
} catch (e) {
|
|
94
|
+
return err(
|
|
95
|
+
authError.internalError("deleteMethodConfig: delete failed", e),
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
return ok(undefined)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function parseMethod(raw: unknown): MethodConfig {
|
|
103
|
+
if (typeof raw === "string") return JSON.parse(raw) as MethodConfig
|
|
104
|
+
return raw as MethodConfig
|
|
105
|
+
}
|