@_mustachio/openauth 0.9.2 → 0.11.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 +104 -0
- package/dist/esm/adapters/memory/token-store.js +104 -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 +35 -12
- package/dist/esm/domain/audit.js +13 -0
- package/dist/esm/domain/authorize.js +217 -0
- package/dist/esm/domain/callback.js +176 -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 +83 -0
- package/dist/esm/domain/dpop.js +122 -0
- package/dist/esm/domain/id-token.js +94 -0
- package/dist/esm/domain/introspect.js +55 -0
- package/dist/esm/domain/jwt.js +71 -0
- package/dist/esm/domain/logout.js +75 -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 +111 -0
- package/dist/esm/domain/par.js +51 -0
- package/dist/esm/domain/pkce.js +16 -0
- package/dist/esm/domain/refresh.js +102 -0
- package/dist/esm/domain/register.js +74 -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 +102 -0
- package/dist/esm/domain/token.js +246 -0
- package/dist/esm/domain/userinfo.js +62 -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 +250 -0
- package/dist/esm/http/handlers/callback.js +53 -0
- package/dist/esm/http/handlers/end-session.js +64 -0
- package/dist/esm/http/handlers/metadata.js +37 -0
- package/dist/esm/http/handlers/method-route.js +87 -0
- package/dist/esm/http/handlers/par.js +53 -0
- package/dist/esm/http/handlers/register.js +46 -0
- package/dist/esm/http/handlers/revocation.js +98 -0
- package/dist/esm/http/handlers/token.js +197 -0
- package/dist/esm/http/handlers/userinfo.js +60 -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 +45 -0
- package/dist/esm/http/schemas/authorize.js +30 -0
- package/dist/esm/http/schemas/end-session.js +13 -0
- package/dist/esm/http/schemas/par.js +9 -0
- package/dist/esm/http/schemas/register.js +16 -0
- package/dist/esm/http/schemas/revocation.js +18 -0
- package/dist/esm/http/schemas/token.js +57 -0
- package/dist/esm/index.js +126 -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 +70 -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 +21 -0
- package/dist/types/adapters/memory/session-store.d.ts.map +1 -0
- package/dist/types/adapters/memory/token-store.d.ts +29 -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 +20 -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 +54 -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 +81 -0
- package/dist/types/domain/discovery.d.ts.map +1 -0
- package/dist/types/domain/dpop.d.ts +61 -0
- package/dist/types/domain/dpop.d.ts.map +1 -0
- package/dist/types/domain/id-token.d.ts +83 -0
- package/dist/types/domain/id-token.d.ts.map +1 -0
- package/dist/types/domain/introspect.d.ts +79 -0
- package/dist/types/domain/introspect.d.ts.map +1 -0
- package/dist/types/domain/jwt.d.ts +74 -0
- package/dist/types/domain/jwt.d.ts.map +1 -0
- package/dist/types/domain/logout.d.ts +69 -0
- package/dist/types/domain/logout.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/par.d.ts +62 -0
- package/dist/types/domain/par.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 +52 -0
- package/dist/types/domain/refresh.d.ts.map +1 -0
- package/dist/types/domain/register.d.ts +33 -0
- package/dist/types/domain/register.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 +69 -0
- package/dist/types/domain/token-exchange.d.ts.map +1 -0
- package/dist/types/domain/token.d.ts +140 -0
- package/dist/types/domain/token.d.ts.map +1 -0
- package/dist/types/domain/userinfo.d.ts +61 -0
- package/dist/types/domain/userinfo.d.ts.map +1 -0
- package/dist/types/http/context.d.ts +66 -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/end-session.d.ts +3 -0
- package/dist/types/http/handlers/end-session.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/par.d.ts +3 -0
- package/dist/types/http/handlers/par.d.ts.map +1 -0
- package/dist/types/http/handlers/register.d.ts +3 -0
- package/dist/types/http/handlers/register.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 +92 -0
- package/dist/types/http/schemas/authorize.d.ts.map +1 -0
- package/dist/types/http/schemas/end-session.d.ts +31 -0
- package/dist/types/http/schemas/end-session.d.ts.map +1 -0
- package/dist/types/http/schemas/par.d.ts +20 -0
- package/dist/types/http/schemas/par.d.ts.map +1 -0
- package/dist/types/http/schemas/register.d.ts +42 -0
- package/dist/types/http/schemas/register.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 +166 -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 +109 -0
- package/dist/types/ports/session-store.d.ts.map +1 -0
- package/dist/types/ports/token-store.d.ts +105 -0
- package/dist/types/ports/token-store.d.ts.map +1 -0
- package/dist/types/types/authorization.d.ts +75 -0
- package/dist/types/types/authorization.d.ts.map +1 -0
- package/dist/types/types/error.d.ts +101 -0
- package/dist/types/types/error.d.ts.map +1 -0
- package/dist/types/types/flow.d.ts +97 -0
- package/dist/types/types/flow.d.ts.map +1 -0
- package/dist/types/types/idp.d.ts +324 -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 +276 -0
- package/dist/types/types/tenant.d.ts.map +1 -0
- package/dist/types/types/token.d.ts +231 -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 +171 -0
- package/src/adapters/memory/token-store.ts +181 -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 +82 -16
- package/src/domain/audit.ts +28 -0
- package/src/domain/authorize.ts +414 -0
- package/src/domain/callback.ts +268 -0
- package/src/domain/client-auth.ts +116 -0
- package/src/domain/client-credentials.ts +180 -0
- package/src/domain/crypto.ts +168 -0
- package/src/domain/discovery.ts +161 -0
- package/src/domain/dpop.ts +293 -0
- package/src/domain/id-token.ts +213 -0
- package/src/domain/introspect.ts +155 -0
- package/src/domain/jwt.ts +185 -0
- package/src/domain/logout.ts +180 -0
- package/src/domain/method-cache.ts +220 -0
- package/src/domain/method-dispatch.ts +95 -0
- package/src/domain/method-route.ts +213 -0
- package/src/domain/par.ts +141 -0
- package/src/domain/pkce.ts +37 -0
- package/src/domain/refresh.ts +210 -0
- package/src/domain/register.ts +168 -0
- package/src/domain/revoke.ts +161 -0
- package/src/domain/state-envelope.ts +142 -0
- package/src/domain/token-exchange.ts +243 -0
- package/src/domain/token.ts +483 -0
- package/src/domain/userinfo.ts +171 -0
- package/src/http/context.ts +90 -0
- package/src/http/cookies.ts +167 -0
- package/src/http/errors.ts +98 -0
- package/src/http/handlers/authorize.ts +362 -0
- package/src/http/handlers/callback.ts +77 -0
- package/src/http/handlers/end-session.ts +106 -0
- package/src/http/handlers/metadata.ts +49 -0
- package/src/http/handlers/method-route.ts +115 -0
- package/src/http/handlers/par.ts +84 -0
- package/src/http/handlers/register.ts +70 -0
- package/src/http/handlers/revocation.ts +151 -0
- package/src/http/handlers/token.ts +300 -0
- package/src/http/handlers/userinfo.ts +90 -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 +85 -0
- package/src/http/schemas/authorize.ts +85 -0
- package/src/http/schemas/end-session.ts +23 -0
- package/src/http/schemas/par.ts +23 -0
- package/src/http/schemas/register.ts +29 -0
- package/src/http/schemas/revocation.ts +23 -0
- package/src/http/schemas/token.ts +85 -0
- package/src/index.ts +283 -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 +119 -0
- package/src/ports/audit-log.ts +177 -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 +131 -0
- package/src/ports/token-store.ts +116 -0
- package/src/types/authorization.ts +78 -0
- package/src/types/error.ts +146 -0
- package/src/types/flow.ts +99 -0
- package/src/types/idp.ts +365 -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 +285 -0
- package/src/types/token.ts +236 -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,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KMS-backed `KeyStore`.
|
|
3
|
+
*
|
|
4
|
+
* Envelope encryption: generate a JWK key pair (or AES key) locally, wrap
|
|
5
|
+
* the private material with AWS KMS `Encrypt`, store the ciphertext in the
|
|
6
|
+
* supplied `KmsBackingStore`. On read, unwrap with KMS `Decrypt` and
|
|
7
|
+
* `importJWK` so the framework receives a normal `CryptoKey` for JWT signing
|
|
8
|
+
* — no surgery in `domain/jwt.ts`.
|
|
9
|
+
*
|
|
10
|
+
* Hot-path KMS calls are cached: signing keys are imported once per
|
|
11
|
+
* `kid` and re-used (a `CryptoKey` is safe to share across signs). Encryption
|
|
12
|
+
* keys are cached in plaintext bytes per `kid` so `consumeCode` doesn't make
|
|
13
|
+
* a KMS call per request.
|
|
14
|
+
*
|
|
15
|
+
* Operators with strict no-cache-of-plaintext requirements can disable the
|
|
16
|
+
* cache via `cacheUnwrappedKeys: false` — every read then round-trips to
|
|
17
|
+
* KMS.
|
|
18
|
+
*/
|
|
19
|
+
import type { JWK } from "jose"
|
|
20
|
+
import { exportJWK, generateKeyPair, importJWK } from "jose"
|
|
21
|
+
|
|
22
|
+
import { generateSymmetricKey, randomId, utf8 } from "../../domain/crypto"
|
|
23
|
+
import type { EncryptionKey, KeyStore, SigningKey } from "../../ports/key-store"
|
|
24
|
+
import { authError } from "../../types/error"
|
|
25
|
+
import type { Result } from "../../types/result"
|
|
26
|
+
import { err, ok } from "../../types/result"
|
|
27
|
+
|
|
28
|
+
import type {
|
|
29
|
+
KmsBackingStore,
|
|
30
|
+
KmsClientLike,
|
|
31
|
+
WrappedEncryptionKey,
|
|
32
|
+
WrappedSigningKey,
|
|
33
|
+
} from "./types"
|
|
34
|
+
|
|
35
|
+
export type KmsKeyStoreOptions = {
|
|
36
|
+
kms: KmsClientLike
|
|
37
|
+
backing: KmsBackingStore
|
|
38
|
+
clock?: () => number
|
|
39
|
+
signingAlg?: "ES256" | "EdDSA"
|
|
40
|
+
/** Default `true`. Set false for strict no-plaintext-cache deployments. */
|
|
41
|
+
cacheUnwrappedKeys?: boolean
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class KmsKeyStore implements KeyStore {
|
|
45
|
+
#kms: KmsClientLike
|
|
46
|
+
#backing: KmsBackingStore
|
|
47
|
+
#clock: () => number
|
|
48
|
+
#signingAlg: "ES256" | "EdDSA"
|
|
49
|
+
#cacheUnwrapped: boolean
|
|
50
|
+
#signingCache = new Map<string, unknown>()
|
|
51
|
+
#encryptionCache = new Map<string, Uint8Array>()
|
|
52
|
+
|
|
53
|
+
constructor(opts: KmsKeyStoreOptions) {
|
|
54
|
+
this.#kms = opts.kms
|
|
55
|
+
this.#backing = opts.backing
|
|
56
|
+
this.#clock = opts.clock ?? (() => Date.now())
|
|
57
|
+
this.#signingAlg = opts.signingAlg ?? "ES256"
|
|
58
|
+
this.#cacheUnwrapped = opts.cacheUnwrappedKeys ?? true
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async currentSigningKey(): Promise<Result<SigningKey>> {
|
|
62
|
+
await this.#ensureSigningKey()
|
|
63
|
+
const all = await this.#backing.listSigningKeys()
|
|
64
|
+
const active = all.find((k) => k.status === "active")
|
|
65
|
+
if (!active) {
|
|
66
|
+
return err(
|
|
67
|
+
authError.internalError(
|
|
68
|
+
"no active signing key (should be unreachable)",
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
return ok(await this.#hydrateSigning(active))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async signingKeys(): Promise<Result<SigningKey[]>> {
|
|
76
|
+
await this.#ensureSigningKey()
|
|
77
|
+
const all = await this.#backing.listSigningKeys()
|
|
78
|
+
const keys = await Promise.all(all.map((row) => this.#hydrateSigning(row)))
|
|
79
|
+
return ok(keys)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async currentEncryptionKey(): Promise<Result<EncryptionKey>> {
|
|
83
|
+
await this.#ensureEncryptionKey()
|
|
84
|
+
const all = await this.#backing.listEncryptionKeys()
|
|
85
|
+
const active = all.find((k) => k.status === "active")
|
|
86
|
+
if (!active) {
|
|
87
|
+
return err(
|
|
88
|
+
authError.internalError(
|
|
89
|
+
"no active encryption key (should be unreachable)",
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
return ok(await this.#hydrateEncryption(active))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async getEncryptionKey(kid: string): Promise<Result<EncryptionKey>> {
|
|
97
|
+
const row = await this.#backing.getEncryptionKey(kid)
|
|
98
|
+
if (!row) {
|
|
99
|
+
return err(authError.internalError(`encryption key "${kid}" not found`))
|
|
100
|
+
}
|
|
101
|
+
return ok(await this.#hydrateEncryption(row))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async #ensureSigningKey(): Promise<void> {
|
|
105
|
+
const all = await this.#backing.listSigningKeys()
|
|
106
|
+
if (all.some((k) => k.status === "active")) return
|
|
107
|
+
const { publicKey, privateKey } = await generateKeyPair(this.#signingAlg, {
|
|
108
|
+
extractable: true,
|
|
109
|
+
})
|
|
110
|
+
const publicJwk = await exportJWK(publicKey)
|
|
111
|
+
const privateJwk = await exportJWK(privateKey)
|
|
112
|
+
const plaintext = utf8.encode(JSON.stringify(privateJwk))
|
|
113
|
+
const wrapped = await this.#kms.encrypt(plaintext)
|
|
114
|
+
const row: WrappedSigningKey = {
|
|
115
|
+
kid: randomId(),
|
|
116
|
+
alg: this.#signingAlg,
|
|
117
|
+
...(publicJwk.crv ? { crv: publicJwk.crv } : {}),
|
|
118
|
+
publicJwk: publicJwk as unknown as Record<string, unknown>,
|
|
119
|
+
wrappedPrivate: wrapped,
|
|
120
|
+
status: "active",
|
|
121
|
+
createdAt: this.#clock(),
|
|
122
|
+
}
|
|
123
|
+
await this.#backing.putSigningKey(row)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async #ensureEncryptionKey(): Promise<void> {
|
|
127
|
+
const all = await this.#backing.listEncryptionKeys()
|
|
128
|
+
if (all.some((k) => k.status === "active")) return
|
|
129
|
+
const raw = generateSymmetricKey()
|
|
130
|
+
const wrapped = await this.#kms.encrypt(raw)
|
|
131
|
+
const row: WrappedEncryptionKey = {
|
|
132
|
+
kid: randomId(),
|
|
133
|
+
alg: "A256GCM",
|
|
134
|
+
wrappedKey: wrapped,
|
|
135
|
+
status: "active",
|
|
136
|
+
createdAt: this.#clock(),
|
|
137
|
+
}
|
|
138
|
+
await this.#backing.putEncryptionKey(row)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async #hydrateSigning(row: WrappedSigningKey): Promise<SigningKey> {
|
|
142
|
+
let imported = this.#signingCache.get(row.kid)
|
|
143
|
+
if (!imported) {
|
|
144
|
+
const plaintext = await this.#kms.decrypt(row.wrappedPrivate)
|
|
145
|
+
const jwk = JSON.parse(utf8.decode(plaintext)) as JWK
|
|
146
|
+
imported = await importJWK(jwk, row.alg)
|
|
147
|
+
if (this.#cacheUnwrapped) this.#signingCache.set(row.kid, imported)
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
kid: row.kid,
|
|
151
|
+
alg: row.alg,
|
|
152
|
+
...(row.crv ? { crv: row.crv } : {}),
|
|
153
|
+
publicJwk: row.publicJwk,
|
|
154
|
+
privateKeyRef: imported,
|
|
155
|
+
status: row.status,
|
|
156
|
+
createdAt: row.createdAt,
|
|
157
|
+
...(row.rotatedAt !== undefined ? { rotatedAt: row.rotatedAt } : {}),
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async #hydrateEncryption(row: WrappedEncryptionKey): Promise<EncryptionKey> {
|
|
162
|
+
let bytes = this.#encryptionCache.get(row.kid)
|
|
163
|
+
if (!bytes) {
|
|
164
|
+
bytes = await this.#kms.decrypt(row.wrappedKey)
|
|
165
|
+
if (this.#cacheUnwrapped) this.#encryptionCache.set(row.kid, bytes)
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
kid: row.kid,
|
|
169
|
+
alg: row.alg,
|
|
170
|
+
keyRef: bytes,
|
|
171
|
+
status: row.status,
|
|
172
|
+
createdAt: row.createdAt,
|
|
173
|
+
...(row.rotatedAt !== undefined ? { rotatedAt: row.rotatedAt } : {}),
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fromKmsClient` — wires the `KmsClientLike` interface to a real AWS KMS
|
|
3
|
+
* client. The KMS SDK is imported only from this file to keep the rest of
|
|
4
|
+
* the adapter bundle KMS-agnostic.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { KMSClient } from "@aws-sdk/client-kms"
|
|
8
|
+
* const kmsClient = new KMSClient({ region: "us-east-1" })
|
|
9
|
+
* const kms = fromKmsClient(kmsClient, process.env.IDP_KMS_KEY_ARN!)
|
|
10
|
+
* const backing = new PostgresKmsBackingStore({ exec })
|
|
11
|
+
* const keyStore = new KmsKeyStore({ kms, backing })
|
|
12
|
+
*/
|
|
13
|
+
import type { KMSClient } from "@aws-sdk/client-kms"
|
|
14
|
+
import { DecryptCommand, EncryptCommand } from "@aws-sdk/client-kms"
|
|
15
|
+
|
|
16
|
+
import type { KmsClientLike } from "./types"
|
|
17
|
+
|
|
18
|
+
export function fromKmsClient(client: KMSClient, keyId: string): KmsClientLike {
|
|
19
|
+
return {
|
|
20
|
+
async encrypt(plaintext: Uint8Array): Promise<Uint8Array> {
|
|
21
|
+
const result = await client.send(
|
|
22
|
+
new EncryptCommand({ KeyId: keyId, Plaintext: plaintext }),
|
|
23
|
+
)
|
|
24
|
+
if (!result.CiphertextBlob) {
|
|
25
|
+
throw new Error("KMS Encrypt returned no ciphertext")
|
|
26
|
+
}
|
|
27
|
+
return new Uint8Array(result.CiphertextBlob)
|
|
28
|
+
},
|
|
29
|
+
async decrypt(ciphertext: Uint8Array): Promise<Uint8Array> {
|
|
30
|
+
const result = await client.send(
|
|
31
|
+
new DecryptCommand({ KeyId: keyId, CiphertextBlob: ciphertext }),
|
|
32
|
+
)
|
|
33
|
+
if (!result.Plaintext) {
|
|
34
|
+
throw new Error("KMS Decrypt returned no plaintext")
|
|
35
|
+
}
|
|
36
|
+
return new Uint8Array(result.Plaintext)
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KMS adapter interfaces.
|
|
3
|
+
*
|
|
4
|
+
* The KMS-backed `KeyStore` uses **envelope encryption** for private key
|
|
5
|
+
* material: the JWK private bytes (signing) and the raw AES key bytes
|
|
6
|
+
* (encryption) are wrapped under a KMS master key. The ciphertext blob is
|
|
7
|
+
* stored in a pluggable backing store; KMS Encrypt / Decrypt are the only
|
|
8
|
+
* KMS operations on the hot path.
|
|
9
|
+
*
|
|
10
|
+
* This shape keeps private material out of plaintext at rest while
|
|
11
|
+
* preserving the JWT signing path: the framework still receives a real
|
|
12
|
+
* `CryptoKey` (`importJWK` of the unwrapped JWK) so `domain/jwt.ts` doesn't
|
|
13
|
+
* need to know KMS exists.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Minimal KMS surface the adapter depends on. */
|
|
17
|
+
export type KmsClientLike = {
|
|
18
|
+
/** Encrypt up to ~4 KB of plaintext under the master key. */
|
|
19
|
+
encrypt(plaintext: Uint8Array): Promise<Uint8Array>
|
|
20
|
+
/** Decrypt a previously-issued ciphertext under the master key. */
|
|
21
|
+
decrypt(ciphertext: Uint8Array): Promise<Uint8Array>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Persistent storage for KMS-wrapped key envelopes. Adapters provide their
|
|
26
|
+
* own (Postgres, DynamoDB, file), or pass `inMemoryKmsBackingStore()` for
|
|
27
|
+
* tests / single-instance dev.
|
|
28
|
+
*
|
|
29
|
+
* `wrappedPrivate` is the KMS-wrapped private material (JWK bytes for
|
|
30
|
+
* signing keys, raw AES key bytes for encryption keys). `publicJwk` is the
|
|
31
|
+
* public material (never sensitive); it's kept plaintext alongside the
|
|
32
|
+
* ciphertext so JWKS lookups don't need a KMS round trip.
|
|
33
|
+
*/
|
|
34
|
+
export type KmsBackingStore = {
|
|
35
|
+
putSigningKey(row: WrappedSigningKey): Promise<void>
|
|
36
|
+
getSigningKey(kid: string): Promise<WrappedSigningKey | undefined>
|
|
37
|
+
listSigningKeys(): Promise<WrappedSigningKey[]>
|
|
38
|
+
putEncryptionKey(row: WrappedEncryptionKey): Promise<void>
|
|
39
|
+
getEncryptionKey(kid: string): Promise<WrappedEncryptionKey | undefined>
|
|
40
|
+
listEncryptionKeys(): Promise<WrappedEncryptionKey[]>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type WrappedSigningKey = {
|
|
44
|
+
kid: string
|
|
45
|
+
alg: string
|
|
46
|
+
crv?: string
|
|
47
|
+
publicJwk: Record<string, unknown>
|
|
48
|
+
wrappedPrivate: Uint8Array
|
|
49
|
+
status: "active" | "next" | "retired"
|
|
50
|
+
createdAt: number
|
|
51
|
+
rotatedAt?: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type WrappedEncryptionKey = {
|
|
55
|
+
kid: string
|
|
56
|
+
alg: string
|
|
57
|
+
wrappedKey: Uint8Array
|
|
58
|
+
status: "active" | "next" | "retired"
|
|
59
|
+
createdAt: number
|
|
60
|
+
rotatedAt?: number
|
|
61
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare KV `AuditLog`. Append-only with per-event keys of the shape
|
|
3
|
+
* `audit:<paddedTs>:<rand>` so KV's lexicographic list returns events in
|
|
4
|
+
* insertion order. Suitable for low-volume audit (the IdP) where reads are
|
|
5
|
+
* SIEM-style after-the-fact, not hot-path. High-volume deployments should
|
|
6
|
+
* ship events out-of-band to a real append-log.
|
|
7
|
+
*/
|
|
8
|
+
import type { AuditEvent, AuditLog } from "../../ports/audit-log"
|
|
9
|
+
|
|
10
|
+
import type { KVNamespaceLike } from "./types"
|
|
11
|
+
|
|
12
|
+
const PREFIX = "audit:"
|
|
13
|
+
|
|
14
|
+
export type KvAuditLogOptions = {
|
|
15
|
+
kv: KVNamespaceLike
|
|
16
|
+
/** Optional TTL (seconds). 90 days minimum per CONSISTENCY.md SOC 2 baseline. */
|
|
17
|
+
expirationTtl?: number
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class KvAuditLog implements AuditLog {
|
|
21
|
+
#kv: KVNamespaceLike
|
|
22
|
+
#ttl: number | undefined
|
|
23
|
+
|
|
24
|
+
constructor(opts: KvAuditLogOptions) {
|
|
25
|
+
this.#kv = opts.kv
|
|
26
|
+
this.#ttl = opts.expirationTtl
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async log(event: AuditEvent & { timestamp: number }): Promise<void> {
|
|
30
|
+
const padded = String(event.timestamp).padStart(16, "0")
|
|
31
|
+
const suffix = Math.random().toString(36).slice(2, 10)
|
|
32
|
+
try {
|
|
33
|
+
await this.#kv.put(
|
|
34
|
+
`${PREFIX}${padded}:${suffix}`,
|
|
35
|
+
JSON.stringify(event),
|
|
36
|
+
this.#ttl ? { expirationTtl: this.#ttl } : undefined,
|
|
37
|
+
)
|
|
38
|
+
} catch {}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare KV `ConfigStore`. JSON-serialized tenant config under
|
|
3
|
+
* `tenant:<id>`. Per `ports/CONSISTENCY.md`, KV is **only** acceptable for
|
|
4
|
+
* read-eventual paths — tenant config qualifies (read-heavy, write-rare,
|
|
5
|
+
* 60s bounded staleness is fine). Invalidation hook fires on every
|
|
6
|
+
* `putTenantConfig`.
|
|
7
|
+
*
|
|
8
|
+
* KV reads honor the cache hint via `cacheTtl` in the get options. The
|
|
9
|
+
* 60-second default matches the bounded-staleness contract.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConfigStore } from "../../ports/config-store"
|
|
12
|
+
import { authError } from "../../types/error"
|
|
13
|
+
import type { Result } from "../../types/result"
|
|
14
|
+
import { err, ok } from "../../types/result"
|
|
15
|
+
import type { TenantConfig, TenantId } from "../../types/tenant"
|
|
16
|
+
|
|
17
|
+
import type { KVNamespaceLike } from "./types"
|
|
18
|
+
|
|
19
|
+
const TENANT_PREFIX = "tenant:"
|
|
20
|
+
|
|
21
|
+
export type KvConfigStoreOptions = {
|
|
22
|
+
kv: KVNamespaceLike
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class KvConfigStore implements ConfigStore {
|
|
26
|
+
#kv: KVNamespaceLike
|
|
27
|
+
#listeners = new Set<(id: TenantId) => void>()
|
|
28
|
+
|
|
29
|
+
constructor(opts: KvConfigStoreOptions) {
|
|
30
|
+
this.#kv = opts.kv
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async getTenantConfig(id: TenantId): Promise<Result<TenantConfig>> {
|
|
34
|
+
let raw: string | null
|
|
35
|
+
try {
|
|
36
|
+
raw = await this.#kv.get(TENANT_PREFIX + id)
|
|
37
|
+
} catch (e) {
|
|
38
|
+
return err(authError.internalError("getTenantConfig: kv.get failed", e))
|
|
39
|
+
}
|
|
40
|
+
if (!raw) {
|
|
41
|
+
return err(authError.tenantNotFound(`tenant "${id}" not found`, id))
|
|
42
|
+
}
|
|
43
|
+
return ok(JSON.parse(raw) as TenantConfig)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async putTenantConfig(config: TenantConfig): Promise<Result<void>> {
|
|
47
|
+
try {
|
|
48
|
+
await this.#kv.put(TENANT_PREFIX + config.id, JSON.stringify(config))
|
|
49
|
+
} catch (e) {
|
|
50
|
+
return err(authError.internalError("putTenantConfig: kv.put failed", e))
|
|
51
|
+
}
|
|
52
|
+
for (const fn of this.#listeners) {
|
|
53
|
+
try {
|
|
54
|
+
fn(config.id)
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
return ok(undefined)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
onInvalidate(handler: (id: TenantId) => void): void {
|
|
61
|
+
this.#listeners.add(handler)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare KV adapters — **restricted use only**.
|
|
3
|
+
*
|
|
4
|
+
* Per `ports/CONSISTENCY.md`, KV's eventual consistency disqualifies it as
|
|
5
|
+
* a backing store for `TokenStore` (auth codes, refresh tokens) and
|
|
6
|
+
* `SessionStore` (flow records). Use D1 / Durable Objects / Postgres /
|
|
7
|
+
* DynamoDB for those. KV remains a great fit for the read-eventual paths
|
|
8
|
+
* exposed in this package:
|
|
9
|
+
*
|
|
10
|
+
* - `KvConfigStore` — tenant config blob keyed by id
|
|
11
|
+
* - `KvMethodStore` — per-tenant method configs
|
|
12
|
+
* - `KvAuditLog` — append-only audit events (low-volume only)
|
|
13
|
+
*
|
|
14
|
+
* Production users typically mix-and-match: KV for config + D1 for tokens
|
|
15
|
+
* + Durable Objects for sessions.
|
|
16
|
+
*/
|
|
17
|
+
export { KvAuditLog, type KvAuditLogOptions } from "./audit-log"
|
|
18
|
+
export { KvConfigStore, type KvConfigStoreOptions } from "./config-store"
|
|
19
|
+
export { KvMethodStore, type KvMethodStoreOptions } from "./method-store"
|
|
20
|
+
export type { KVNamespaceLike } from "./types"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare KV `MethodStore`. Per-method JSON under
|
|
3
|
+
* `method:<tenantId>:<methodId>`. `listMethods` uses the KV `list` cursor +
|
|
4
|
+
* follow-up `get` per key — fine for the read-rare console workflow but
|
|
5
|
+
* not for hot per-request paths (the IdP framework caches `MethodConfig`
|
|
6
|
+
* via `MethodCache` in-process).
|
|
7
|
+
*/
|
|
8
|
+
import type { MethodStore } from "../../ports/method-store"
|
|
9
|
+
import { authError } from "../../types/error"
|
|
10
|
+
import type { Result } from "../../types/result"
|
|
11
|
+
import { err, ok } from "../../types/result"
|
|
12
|
+
import type { MethodConfig, TenantId } from "../../types/tenant"
|
|
13
|
+
|
|
14
|
+
import type { KVNamespaceLike } from "./types"
|
|
15
|
+
|
|
16
|
+
const methodKey = (tenantId: TenantId, methodId: string) =>
|
|
17
|
+
`method:${tenantId}:${methodId}`
|
|
18
|
+
const methodPrefix = (tenantId: TenantId) => `method:${tenantId}:`
|
|
19
|
+
|
|
20
|
+
export type KvMethodStoreOptions = {
|
|
21
|
+
kv: KVNamespaceLike
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class KvMethodStore implements MethodStore {
|
|
25
|
+
#kv: KVNamespaceLike
|
|
26
|
+
|
|
27
|
+
constructor(opts: KvMethodStoreOptions) {
|
|
28
|
+
this.#kv = opts.kv
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async listMethods(tenantId: TenantId): Promise<Result<MethodConfig[]>> {
|
|
32
|
+
const prefix = methodPrefix(tenantId)
|
|
33
|
+
const methods: MethodConfig[] = []
|
|
34
|
+
let cursor: string | null | undefined
|
|
35
|
+
try {
|
|
36
|
+
do {
|
|
37
|
+
const page = await this.#kv.list({ prefix, cursor: cursor ?? null })
|
|
38
|
+
for (const k of page.keys) {
|
|
39
|
+
const value = await this.#kv.get(k.name)
|
|
40
|
+
if (value) methods.push(JSON.parse(value) as MethodConfig)
|
|
41
|
+
}
|
|
42
|
+
cursor = page.list_complete ? undefined : page.cursor
|
|
43
|
+
} while (cursor)
|
|
44
|
+
} catch (e) {
|
|
45
|
+
return err(authError.internalError("listMethods: kv.list failed", e))
|
|
46
|
+
}
|
|
47
|
+
// KV doesn't guarantee list order; the conformance suite sorts by id.
|
|
48
|
+
methods.sort((a, b) => a.id.localeCompare(b.id))
|
|
49
|
+
return ok(methods)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async getMethodConfig(
|
|
53
|
+
tenantId: TenantId,
|
|
54
|
+
methodId: string,
|
|
55
|
+
): Promise<Result<MethodConfig>> {
|
|
56
|
+
let raw: string | null
|
|
57
|
+
try {
|
|
58
|
+
raw = await this.#kv.get(methodKey(tenantId, methodId))
|
|
59
|
+
} catch (e) {
|
|
60
|
+
return err(authError.internalError("getMethodConfig: kv.get failed", e))
|
|
61
|
+
}
|
|
62
|
+
if (!raw) {
|
|
63
|
+
return err(
|
|
64
|
+
authError.methodNotFound(
|
|
65
|
+
`method "${methodId}" not found for tenant "${tenantId}"`,
|
|
66
|
+
{ methodId },
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
return ok(JSON.parse(raw) as MethodConfig)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async putMethodConfig(
|
|
74
|
+
tenantId: TenantId,
|
|
75
|
+
method: MethodConfig,
|
|
76
|
+
): Promise<Result<void>> {
|
|
77
|
+
try {
|
|
78
|
+
await this.#kv.put(methodKey(tenantId, method.id), JSON.stringify(method))
|
|
79
|
+
} catch (e) {
|
|
80
|
+
return err(authError.internalError("putMethodConfig: kv.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.#kv.delete(methodKey(tenantId, methodId))
|
|
91
|
+
} catch (e) {
|
|
92
|
+
return err(
|
|
93
|
+
authError.internalError("deleteMethodConfig: kv.delete failed", e),
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
return ok(undefined)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal `KVNamespace` shape the adapter depends on. Pinned locally so the
|
|
3
|
+
* adapter is testable without a real Workers runtime.
|
|
4
|
+
*
|
|
5
|
+
* Real `KVNamespace` instances satisfy this interface — pass `env.AUTH_KV`
|
|
6
|
+
* directly.
|
|
7
|
+
*/
|
|
8
|
+
export type KVNamespaceLike = {
|
|
9
|
+
get(key: string): Promise<string | null>
|
|
10
|
+
get<T>(key: string, type: "json"): Promise<T | null>
|
|
11
|
+
put(
|
|
12
|
+
key: string,
|
|
13
|
+
value: string,
|
|
14
|
+
options?: { expirationTtl?: number; expiration?: number },
|
|
15
|
+
): Promise<void>
|
|
16
|
+
delete(key: string): Promise<void>
|
|
17
|
+
list(options?: {
|
|
18
|
+
prefix?: string
|
|
19
|
+
cursor?: string | null
|
|
20
|
+
limit?: number
|
|
21
|
+
}): Promise<{
|
|
22
|
+
keys: Array<{ name: string }>
|
|
23
|
+
list_complete: boolean
|
|
24
|
+
cursor?: string
|
|
25
|
+
}>
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory `AuditLog`. Stores events in an array that tests can inspect.
|
|
3
|
+
* Production deployments use a real backend (Clickhouse, OTEL, etc.).
|
|
4
|
+
*/
|
|
5
|
+
import type { AuditEvent, AuditLog } from "../../ports/audit-log"
|
|
6
|
+
|
|
7
|
+
export type StoredAuditEvent = AuditEvent & { timestamp: number }
|
|
8
|
+
|
|
9
|
+
export class MemoryAuditLog implements AuditLog {
|
|
10
|
+
events: StoredAuditEvent[] = []
|
|
11
|
+
|
|
12
|
+
async log(event: StoredAuditEvent): Promise<void> {
|
|
13
|
+
this.events.push(event)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Test helper — find events of a given kind. */
|
|
17
|
+
byKind<K extends AuditEvent["kind"]>(
|
|
18
|
+
kind: K,
|
|
19
|
+
): Array<Extract<StoredAuditEvent, { kind: K }>> {
|
|
20
|
+
return this.events.filter((e) => e.kind === kind) as Array<
|
|
21
|
+
Extract<StoredAuditEvent, { kind: K }>
|
|
22
|
+
>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
clear(): void {
|
|
26
|
+
this.events = []
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory `ConfigStore`. Single-process; trivially satisfies the
|
|
3
|
+
* eventual + bounded-staleness contract (it's strong, which is a superset).
|
|
4
|
+
*/
|
|
5
|
+
import type { ConfigStore } from "../../ports/config-store"
|
|
6
|
+
import type { Result } from "../../types/result"
|
|
7
|
+
import { err, ok } from "../../types/result"
|
|
8
|
+
import { authError } from "../../types/error"
|
|
9
|
+
import type { TenantConfig, TenantId } from "../../types/tenant"
|
|
10
|
+
|
|
11
|
+
export type MemoryConfigStoreOptions = {
|
|
12
|
+
/** Seed tenants — useful for tests. */
|
|
13
|
+
seed?: ReadonlyArray<TenantConfig>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class MemoryConfigStore implements ConfigStore {
|
|
17
|
+
#tenants = new Map<TenantId, TenantConfig>()
|
|
18
|
+
#listeners = new Set<(id: TenantId) => void>()
|
|
19
|
+
|
|
20
|
+
constructor(opts: MemoryConfigStoreOptions = {}) {
|
|
21
|
+
for (const t of opts.seed ?? []) this.#tenants.set(t.id, t)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async getTenantConfig(id: TenantId): Promise<Result<TenantConfig>> {
|
|
25
|
+
const t = this.#tenants.get(id)
|
|
26
|
+
if (!t) {
|
|
27
|
+
return err(authError.tenantNotFound(`tenant "${id}" not found`, id))
|
|
28
|
+
}
|
|
29
|
+
return ok(t)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async putTenantConfig(config: TenantConfig): Promise<Result<void>> {
|
|
33
|
+
this.#tenants.set(config.id, config)
|
|
34
|
+
for (const fn of this.#listeners) fn(config.id)
|
|
35
|
+
return ok(undefined)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
onInvalidate(handler: (id: TenantId) => void): void {
|
|
39
|
+
this.#listeners.add(handler)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory adapter set. Map-backed. Suitable for tests and single-instance
|
|
3
|
+
* dev. Trivially satisfies all consistency contracts in
|
|
4
|
+
* `ports/CONSISTENCY.md` because there's no concurrent process / replica
|
|
5
|
+
* lag.
|
|
6
|
+
*/
|
|
7
|
+
export { MemoryAuditLog, type StoredAuditEvent } from "./audit-log"
|
|
8
|
+
export {
|
|
9
|
+
MemoryConfigStore,
|
|
10
|
+
type MemoryConfigStoreOptions,
|
|
11
|
+
} from "./config-store"
|
|
12
|
+
export { MemoryKeyStore, type MemoryKeyStoreOptions } from "./key-store"
|
|
13
|
+
export {
|
|
14
|
+
MemoryMethodStore,
|
|
15
|
+
type MemoryMethodStoreOptions,
|
|
16
|
+
} from "./method-store"
|
|
17
|
+
export {
|
|
18
|
+
MemorySessionStore,
|
|
19
|
+
type MemorySessionStoreOptions,
|
|
20
|
+
} from "./session-store"
|
|
21
|
+
export { MemoryTokenStore, type MemoryTokenStoreOptions } from "./token-store"
|
|
22
|
+
export {
|
|
23
|
+
MemoryPasskeyCredentialStore,
|
|
24
|
+
type MemoryPasskeyCredentialStoreOptions,
|
|
25
|
+
} from "./passkey-credential-store"
|
|
26
|
+
export { realClock, type Clock } from "./clock"
|