@_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,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared client-authentication helpers.
|
|
3
|
+
*
|
|
4
|
+
* `/token`, `/revoke`, `/introspect`, and refresh-token rotation all need
|
|
5
|
+
* to validate presented credentials against a `ClientConfig`. The logic is
|
|
6
|
+
* the same in every case:
|
|
7
|
+
*
|
|
8
|
+
* - **Public clients** MUST NOT present a `client_secret` (RFC 6749 §2.3).
|
|
9
|
+
* - **Confidential clients** MUST present a `client_secret`, hashed and
|
|
10
|
+
* compared in constant time against `ClientConfig.secretHash`.
|
|
11
|
+
*
|
|
12
|
+
* Credentials may ride either in the form body (`client_id`,
|
|
13
|
+
* `client_secret`) or in an `Authorization: Basic` header
|
|
14
|
+
* (RFC 6749 §2.3.1). Both encodings are accepted; the header takes
|
|
15
|
+
* precedence when both are present.
|
|
16
|
+
*
|
|
17
|
+
* The hashing function lives in `./token.ts` (`hashClientSecret`) to keep
|
|
18
|
+
* the legacy phase-2 SHA-256 / base64url format in one place; production
|
|
19
|
+
* deployments migrate to argon2id later in the rebuild.
|
|
20
|
+
*/
|
|
21
|
+
import { authError, type AuthError } from "../types/error"
|
|
22
|
+
import type { ClientConfig } from "../types/tenant"
|
|
23
|
+
|
|
24
|
+
import { timingSafeEqualStr } from "./crypto"
|
|
25
|
+
import { hashClientSecret } from "./token"
|
|
26
|
+
|
|
27
|
+
export type ClientCredentials = {
|
|
28
|
+
/** Client identifier (always present when credentials are presented). */
|
|
29
|
+
clientId: string
|
|
30
|
+
/** Confidential clients only. */
|
|
31
|
+
clientSecret?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Validate presented credentials against `client`. Returns `null` on
|
|
36
|
+
* success, `AuthError` on rejection.
|
|
37
|
+
*
|
|
38
|
+
* Public clients pass when no secret is presented. Confidential clients
|
|
39
|
+
* require both a secret and a matching `secretHash`.
|
|
40
|
+
*/
|
|
41
|
+
export async function verifyClientCredentials(
|
|
42
|
+
client: ClientConfig,
|
|
43
|
+
presentedSecret: string | undefined,
|
|
44
|
+
): Promise<AuthError | null> {
|
|
45
|
+
if (client.type === "public") {
|
|
46
|
+
if (presentedSecret) {
|
|
47
|
+
return authError.invalidClient(
|
|
48
|
+
"public clients must not present a client_secret",
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
if (!presentedSecret) {
|
|
54
|
+
return authError.invalidClient("confidential client requires client_secret")
|
|
55
|
+
}
|
|
56
|
+
const supplied = await hashClientSecret(presentedSecret)
|
|
57
|
+
if (!timingSafeEqualStr(supplied, client.secretHash)) {
|
|
58
|
+
return authError.invalidClient("client_secret mismatch")
|
|
59
|
+
}
|
|
60
|
+
return null
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Parse an `Authorization: Basic <base64>` header.
|
|
65
|
+
*
|
|
66
|
+
* Returns `null` for missing / non-Basic headers and for any decoding
|
|
67
|
+
* failure; callers fall back to form-body credentials.
|
|
68
|
+
*/
|
|
69
|
+
export function parseBasicAuth(
|
|
70
|
+
header: string | null,
|
|
71
|
+
): ClientCredentials | null {
|
|
72
|
+
if (!header) return null
|
|
73
|
+
const match = /^Basic\s+(.+)$/i.exec(header)
|
|
74
|
+
if (!match || !match[1]) return null
|
|
75
|
+
let decoded: string
|
|
76
|
+
try {
|
|
77
|
+
decoded = atob(match[1])
|
|
78
|
+
} catch {
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
const colon = decoded.indexOf(":")
|
|
82
|
+
if (colon === -1) return null
|
|
83
|
+
let clientId: string
|
|
84
|
+
let clientSecret: string
|
|
85
|
+
try {
|
|
86
|
+
clientId = decodeURIComponent(decoded.slice(0, colon))
|
|
87
|
+
clientSecret = decodeURIComponent(decoded.slice(colon + 1))
|
|
88
|
+
} catch {
|
|
89
|
+
return null
|
|
90
|
+
}
|
|
91
|
+
return { clientId, clientSecret }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Merge form-body credentials with an optional `Authorization: Basic`
|
|
96
|
+
* header. The header wins per RFC 6749 §2.3 when both are present.
|
|
97
|
+
*
|
|
98
|
+
* Returns `null` when neither source supplies a `client_id` — callers
|
|
99
|
+
* then decide whether that's permissible (anonymous revoke is OK; the
|
|
100
|
+
* token endpoint isn't).
|
|
101
|
+
*/
|
|
102
|
+
export function resolveClientCredentials(input: {
|
|
103
|
+
authorizationHeader: string | null
|
|
104
|
+
bodyClientId: string | undefined
|
|
105
|
+
bodyClientSecret: string | undefined
|
|
106
|
+
}): ClientCredentials | null {
|
|
107
|
+
const basic = parseBasicAuth(input.authorizationHeader)
|
|
108
|
+
if (basic) return basic
|
|
109
|
+
if (!input.bodyClientId) return null
|
|
110
|
+
return {
|
|
111
|
+
clientId: input.bodyClientId,
|
|
112
|
+
...(input.bodyClientSecret !== undefined
|
|
113
|
+
? { clientSecret: input.bodyClientSecret }
|
|
114
|
+
: {}),
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/token` endpoint logic for `grant_type=client_credentials` (RFC 6749 §4.4).
|
|
3
|
+
*
|
|
4
|
+
* Steps:
|
|
5
|
+
* 1. Authenticate the client. Must be confidential and must declare
|
|
6
|
+
* `client_credentials` in `grantTypes`.
|
|
7
|
+
* 2. Resolve the tenant's m2m method. The plan models m2m as a method
|
|
8
|
+
* with a `client` fn and no routes; we look for the unique
|
|
9
|
+
* `type === "m2m"` instance on the tenant. Zero or multiple → error.
|
|
10
|
+
* 3. Call `method.client({ clientID, clientSecret, params })`. On
|
|
11
|
+
* success the method returns the `P` properties it would have
|
|
12
|
+
* emitted on a `success` MethodResult.
|
|
13
|
+
* 4. Invoke the user's `success` callback to mint the subject claim
|
|
14
|
+
* with `methodKind = method.kind`, `methodId = method.id`.
|
|
15
|
+
* 5. `mintTokens` — access token only (no refresh per §4.4.3).
|
|
16
|
+
*
|
|
17
|
+
* The framework rejects requests presenting `scope` beyond what
|
|
18
|
+
* `ClientConfig.scopes` allows.
|
|
19
|
+
*/
|
|
20
|
+
import type { AuditLog } from "../ports/audit-log"
|
|
21
|
+
import type { ConfigStore } from "../ports/config-store"
|
|
22
|
+
import type { KeyStore } from "../ports/key-store"
|
|
23
|
+
import type { TokenStore } from "../ports/token-store"
|
|
24
|
+
import { authError, type AuthError } from "../types/error"
|
|
25
|
+
import type { PersistUpstreamTokens, SuccessMapInput } from "../types/idp"
|
|
26
|
+
import type { Result } from "../types/result"
|
|
27
|
+
import { err, isErr, ok } from "../types/result"
|
|
28
|
+
import type { SubjectClaim } from "../types/subject"
|
|
29
|
+
import type { TenantContext, TenantId } from "../types/tenant"
|
|
30
|
+
import type { TokenResponse } from "../types/token"
|
|
31
|
+
|
|
32
|
+
import { verifyClientCredentials } from "./client-auth"
|
|
33
|
+
import { randomId } from "./crypto"
|
|
34
|
+
import { mintTokens } from "./token"
|
|
35
|
+
import { MethodCache } from "./method-cache"
|
|
36
|
+
|
|
37
|
+
export type ClientCredentialsRequest = {
|
|
38
|
+
grantType: "client_credentials"
|
|
39
|
+
clientId: string
|
|
40
|
+
clientSecret: string
|
|
41
|
+
scope?: string
|
|
42
|
+
/** Extra params (audience, resource, etc.). Forwarded to `method.client`. */
|
|
43
|
+
params?: Record<string, string>
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type ClientCredentialsDeps = {
|
|
47
|
+
configStore: ConfigStore
|
|
48
|
+
tokenStore: TokenStore
|
|
49
|
+
keyStore: KeyStore
|
|
50
|
+
auditLog?: AuditLog
|
|
51
|
+
methodCache: MethodCache
|
|
52
|
+
success: (input: SuccessMapInput) => Promise<SubjectClaim>
|
|
53
|
+
persistUpstreamTokens?: PersistUpstreamTokens
|
|
54
|
+
issuerUrl: string
|
|
55
|
+
clock: () => number
|
|
56
|
+
newRefreshFamily?: () => string
|
|
57
|
+
/** See `IdPOptions.customScopeClaims`. Forwarded to `mintTokens`. */
|
|
58
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function clientCredentialsGrant(
|
|
62
|
+
req: ClientCredentialsRequest,
|
|
63
|
+
deps: ClientCredentialsDeps,
|
|
64
|
+
tenantId: TenantId,
|
|
65
|
+
): Promise<Result<TokenResponse, AuthError>> {
|
|
66
|
+
// 1. Tenant + client lookup.
|
|
67
|
+
const tenantCfg = await deps.configStore.getTenantConfig(tenantId)
|
|
68
|
+
if (isErr(tenantCfg)) return err(tenantCfg.error)
|
|
69
|
+
const client = tenantCfg.value.clients.find((c) => c.id === req.clientId)
|
|
70
|
+
if (!client) {
|
|
71
|
+
return err(authError.invalidClient(`unknown client "${req.clientId}"`))
|
|
72
|
+
}
|
|
73
|
+
if (client.type !== "confidential") {
|
|
74
|
+
return err(
|
|
75
|
+
authError.invalidClient(
|
|
76
|
+
"client_credentials requires confidential client",
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
if (!client.grantTypes.includes("client_credentials")) {
|
|
81
|
+
return err(
|
|
82
|
+
authError.unauthorizedClient(
|
|
83
|
+
`client "${client.id}" is not authorized for client_credentials`,
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
const authErr = await verifyClientCredentials(client, req.clientSecret)
|
|
88
|
+
if (authErr) return err(authErr)
|
|
89
|
+
|
|
90
|
+
// 2. Scope validation.
|
|
91
|
+
const requestedScopes = req.scope
|
|
92
|
+
? req.scope.split(" ").filter(Boolean)
|
|
93
|
+
: client.scopes
|
|
94
|
+
for (const s of requestedScopes) {
|
|
95
|
+
if (!client.scopes.includes(s)) {
|
|
96
|
+
return err(authError.invalidScope(`scope "${s}" not allowed for client`))
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 3. Resolve m2m method instance.
|
|
101
|
+
const m2mCfgs = tenantCfg.value.methods.filter(
|
|
102
|
+
(m) => m.type === "m2m" && m.enabled,
|
|
103
|
+
)
|
|
104
|
+
if (m2mCfgs.length === 0) {
|
|
105
|
+
return err(authError.methodNotFound("no enabled m2m method on tenant", {}))
|
|
106
|
+
}
|
|
107
|
+
if (m2mCfgs.length > 1) {
|
|
108
|
+
return err(
|
|
109
|
+
authError.methodNotFound(
|
|
110
|
+
"multiple m2m methods configured — only one supported",
|
|
111
|
+
{},
|
|
112
|
+
),
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
const methodCfg = m2mCfgs[0]!
|
|
116
|
+
const methodRes = await deps.methodCache.resolve(
|
|
117
|
+
tenantCfg.value,
|
|
118
|
+
methodCfg.id,
|
|
119
|
+
)
|
|
120
|
+
if (isErr(methodRes)) return err(methodRes.error)
|
|
121
|
+
const method = methodRes.value
|
|
122
|
+
if (!method.client) {
|
|
123
|
+
return err(
|
|
124
|
+
authError.methodNotFound(
|
|
125
|
+
`m2m method "${methodCfg.id}" did not register a client fn`,
|
|
126
|
+
{ methodId: methodCfg.id, methodKind: method.kind },
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 4. Dispatch the method's client fn.
|
|
132
|
+
const clientResult = await method.client({
|
|
133
|
+
clientID: req.clientId,
|
|
134
|
+
clientSecret: req.clientSecret,
|
|
135
|
+
params: req.params ?? {},
|
|
136
|
+
})
|
|
137
|
+
if (isErr(clientResult)) return err(clientResult.error)
|
|
138
|
+
|
|
139
|
+
// 5. Build subject claim via user's success callback.
|
|
140
|
+
const tenant: TenantContext = {
|
|
141
|
+
id: tenantCfg.value.id,
|
|
142
|
+
config: tenantCfg.value,
|
|
143
|
+
request: { raw: new Request("about:blank"), custom: {} },
|
|
144
|
+
}
|
|
145
|
+
let claim: SubjectClaim
|
|
146
|
+
try {
|
|
147
|
+
claim = await deps.success({
|
|
148
|
+
tenant,
|
|
149
|
+
methodId: method.id,
|
|
150
|
+
methodKind: method.kind,
|
|
151
|
+
providerSubject: req.clientId,
|
|
152
|
+
properties: clientResult.value,
|
|
153
|
+
context: null,
|
|
154
|
+
})
|
|
155
|
+
} catch (e) {
|
|
156
|
+
return err(authError.serverError("success callback threw", e))
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 6. Mint access only — RFC 6749 §4.4.3 says client_credentials SHOULD
|
|
160
|
+
// NOT issue a refresh token. `skipRefresh: true` keeps the token-
|
|
161
|
+
// store from accumulating orphaned rows that the response would
|
|
162
|
+
// otherwise strip.
|
|
163
|
+
const minted = await mintTokens({
|
|
164
|
+
tenant,
|
|
165
|
+
claim,
|
|
166
|
+
payload: {
|
|
167
|
+
tenantId: tenant.id,
|
|
168
|
+
clientId: client.id,
|
|
169
|
+
methodId: method.id,
|
|
170
|
+
methodKind: method.kind,
|
|
171
|
+
scopes: requestedScopes,
|
|
172
|
+
...(client.scopes.includes("audience") ? {} : {}),
|
|
173
|
+
},
|
|
174
|
+
family: (deps.newRefreshFamily ?? randomId)(),
|
|
175
|
+
skipRefresh: true,
|
|
176
|
+
deps,
|
|
177
|
+
})
|
|
178
|
+
if (isErr(minted)) return err(minted.error)
|
|
179
|
+
return ok(minted.value)
|
|
180
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level crypto + encoding helpers used across the domain.
|
|
3
|
+
*
|
|
4
|
+
* Web Crypto only. No `node:*` imports — domain code runs on every runtime
|
|
5
|
+
* we target (Node 18+, Bun, Workers, Lambda).
|
|
6
|
+
*/
|
|
7
|
+
import { base64url as joseB64u, CompactEncrypt, compactDecrypt } from "jose"
|
|
8
|
+
|
|
9
|
+
/** 256-bit random token, base64url-encoded. ~43 chars. */
|
|
10
|
+
export function randomToken(): string {
|
|
11
|
+
const buf = new Uint8Array(32)
|
|
12
|
+
crypto.getRandomValues(buf)
|
|
13
|
+
return joseB64u.encode(buf)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** 128-bit random id, base64url-encoded. ~22 chars. */
|
|
17
|
+
export function randomId(): string {
|
|
18
|
+
const buf = new Uint8Array(16)
|
|
19
|
+
crypto.getRandomValues(buf)
|
|
20
|
+
return joseB64u.encode(buf)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Cryptographic random hex string of `bytes` length. */
|
|
24
|
+
export function randomHex(bytes: number): string {
|
|
25
|
+
const buf = new Uint8Array(bytes)
|
|
26
|
+
crypto.getRandomValues(buf)
|
|
27
|
+
return Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Cryptographic random `Uint8Array` of `bytes` length. */
|
|
31
|
+
export function randomBytes(bytes: number): Uint8Array {
|
|
32
|
+
const buf = new Uint8Array(bytes)
|
|
33
|
+
crypto.getRandomValues(buf)
|
|
34
|
+
return buf
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Base64url encode raw bytes (jose alias for downstream consistency). */
|
|
38
|
+
export const base64url = {
|
|
39
|
+
encode: (data: Uint8Array | string): string => joseB64u.encode(data),
|
|
40
|
+
decode: (s: string): Uint8Array => joseB64u.decode(s),
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** UTF-8 helpers. */
|
|
44
|
+
export const utf8 = {
|
|
45
|
+
encode: (s: string): Uint8Array => new TextEncoder().encode(s),
|
|
46
|
+
decode: (b: Uint8Array): string => new TextDecoder().decode(b),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Constant-time byte-array compare. Returns false fast on length mismatch
|
|
51
|
+
* (length itself is not secret), then XORs every byte to avoid early exit.
|
|
52
|
+
*/
|
|
53
|
+
export function timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean {
|
|
54
|
+
if (a.length !== b.length) return false
|
|
55
|
+
let diff = 0
|
|
56
|
+
for (let i = 0; i < a.length; i++) diff |= a[i]! ^ b[i]!
|
|
57
|
+
return diff === 0
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Constant-time string compare (UTF-8 bytes). */
|
|
61
|
+
export function timingSafeEqualStr(a: string, b: string): boolean {
|
|
62
|
+
return timingSafeEqual(utf8.encode(a), utf8.encode(b))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** SHA-256 digest. */
|
|
66
|
+
export async function sha256(data: Uint8Array | string): Promise<Uint8Array> {
|
|
67
|
+
const bytes = typeof data === "string" ? utf8.encode(data) : data
|
|
68
|
+
const digest = await crypto.subtle.digest("SHA-256", bytes)
|
|
69
|
+
return new Uint8Array(digest)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Import a 32-byte HMAC-SHA-256 key for sign/verify use. */
|
|
73
|
+
export async function importHmacKey(
|
|
74
|
+
raw: Uint8Array,
|
|
75
|
+
usage: ReadonlyArray<"sign" | "verify"> = ["sign", "verify"],
|
|
76
|
+
): Promise<CryptoKey> {
|
|
77
|
+
return crypto.subtle.importKey(
|
|
78
|
+
"raw",
|
|
79
|
+
raw,
|
|
80
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
81
|
+
false,
|
|
82
|
+
[...usage],
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** HMAC-SHA-256 sign. */
|
|
87
|
+
export async function hmacSign(
|
|
88
|
+
key: CryptoKey,
|
|
89
|
+
message: Uint8Array,
|
|
90
|
+
): Promise<Uint8Array> {
|
|
91
|
+
const sig = await crypto.subtle.sign("HMAC", key, message)
|
|
92
|
+
return new Uint8Array(sig)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* HMAC-SHA-256 verify. `crypto.subtle.verify` is timing-safe by spec, which
|
|
97
|
+
* is why we use it instead of recomputing + comparing manually.
|
|
98
|
+
*/
|
|
99
|
+
export async function hmacVerify(
|
|
100
|
+
key: CryptoKey,
|
|
101
|
+
signature: Uint8Array,
|
|
102
|
+
message: Uint8Array,
|
|
103
|
+
): Promise<boolean> {
|
|
104
|
+
return crypto.subtle.verify("HMAC", key, signature, message)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Encrypt a JSON-serializable payload with AES-256-GCM under the supplied
|
|
109
|
+
* 256-bit key. Output is a compact JWE string (`{header}.{enc-key}.{iv}.{ct}.{tag}`).
|
|
110
|
+
*
|
|
111
|
+
* Used for `TokenStore.saveCode` — the auth-code payload is encrypted at
|
|
112
|
+
* rest. The compact-JWE format embeds the `kid` so `consumeCode` can pick
|
|
113
|
+
* the right key during overlap rotation.
|
|
114
|
+
*
|
|
115
|
+
* For symmetric direct encryption we use `dir` with `A256GCM`, so the
|
|
116
|
+
* supplied `keyBytes` is the content-encryption key itself.
|
|
117
|
+
*/
|
|
118
|
+
export async function encryptPayload(
|
|
119
|
+
payload: unknown,
|
|
120
|
+
kid: string,
|
|
121
|
+
keyBytes: Uint8Array,
|
|
122
|
+
): Promise<string> {
|
|
123
|
+
if (keyBytes.byteLength !== 32) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`encryptPayload: keyBytes must be 32 bytes (A256GCM); got ${keyBytes.byteLength}`,
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
const cek = await crypto.subtle.importKey(
|
|
129
|
+
"raw",
|
|
130
|
+
keyBytes,
|
|
131
|
+
{ name: "AES-GCM", length: 256 },
|
|
132
|
+
false,
|
|
133
|
+
["encrypt"],
|
|
134
|
+
)
|
|
135
|
+
const json = utf8.encode(JSON.stringify(payload))
|
|
136
|
+
return new CompactEncrypt(json)
|
|
137
|
+
.setProtectedHeader({ alg: "dir", enc: "A256GCM", kid })
|
|
138
|
+
.encrypt(cek)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Inverse of {@link encryptPayload}. Returns the parsed JSON payload. */
|
|
142
|
+
export async function decryptPayload<T = unknown>(
|
|
143
|
+
jwe: string,
|
|
144
|
+
resolveKey: (kid: string) => Promise<Uint8Array>,
|
|
145
|
+
): Promise<T> {
|
|
146
|
+
const { plaintext } = await compactDecrypt(jwe, async (header) => {
|
|
147
|
+
const kid = header.kid
|
|
148
|
+
if (typeof kid !== "string") {
|
|
149
|
+
throw new Error("decryptPayload: missing kid in JWE header")
|
|
150
|
+
}
|
|
151
|
+
const raw = await resolveKey(kid)
|
|
152
|
+
return crypto.subtle.importKey(
|
|
153
|
+
"raw",
|
|
154
|
+
raw,
|
|
155
|
+
{ name: "AES-GCM", length: 256 },
|
|
156
|
+
false,
|
|
157
|
+
["decrypt"],
|
|
158
|
+
)
|
|
159
|
+
})
|
|
160
|
+
return JSON.parse(utf8.decode(plaintext)) as T
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Generate a fresh 32-byte AES-256 / HMAC-SHA-256 key. */
|
|
164
|
+
export function generateSymmetricKey(): Uint8Array {
|
|
165
|
+
const buf = new Uint8Array(32)
|
|
166
|
+
crypto.getRandomValues(buf)
|
|
167
|
+
return buf
|
|
168
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata-document builders for `/.well-known/openid-configuration` and
|
|
3
|
+
* `/.well-known/jwks.json`.
|
|
4
|
+
*
|
|
5
|
+
* Pure functions over typed ports + a small options record.
|
|
6
|
+
*/
|
|
7
|
+
import type { KeyStore } from "../ports/key-store"
|
|
8
|
+
import type { AuthError } from "../types/error"
|
|
9
|
+
import type { Result } from "../types/result"
|
|
10
|
+
import { err, isErr, ok } from "../types/result"
|
|
11
|
+
|
|
12
|
+
import { buildJwksDocument } from "./jwt"
|
|
13
|
+
|
|
14
|
+
export type DiscoveryDocument = {
|
|
15
|
+
issuer: string
|
|
16
|
+
authorization_endpoint: string
|
|
17
|
+
token_endpoint: string
|
|
18
|
+
userinfo_endpoint: string
|
|
19
|
+
jwks_uri: string
|
|
20
|
+
revocation_endpoint: string
|
|
21
|
+
introspection_endpoint: string
|
|
22
|
+
/** OIDC RP-Initiated Logout 1.0 §2. */
|
|
23
|
+
end_session_endpoint: string
|
|
24
|
+
/** RFC 7591 §3.1. */
|
|
25
|
+
registration_endpoint: string
|
|
26
|
+
/** RFC 9126 §5. */
|
|
27
|
+
pushed_authorization_request_endpoint: string
|
|
28
|
+
/**
|
|
29
|
+
* RFC 9126 §5. True iff every client on this tenant is required to use
|
|
30
|
+
* PAR. We advertise `false` at the tenant level — the per-client toggle
|
|
31
|
+
* is read at request time.
|
|
32
|
+
*/
|
|
33
|
+
require_pushed_authorization_requests: boolean
|
|
34
|
+
/** RFC 9449 §5.1 — DPoP algorithms accepted on proof JWTs. */
|
|
35
|
+
dpop_signing_alg_values_supported: string[]
|
|
36
|
+
response_types_supported: string[]
|
|
37
|
+
grant_types_supported: string[]
|
|
38
|
+
subject_types_supported: string[]
|
|
39
|
+
id_token_signing_alg_values_supported: string[]
|
|
40
|
+
scopes_supported: string[]
|
|
41
|
+
/** OIDC Core §3 — registered claim names the IdP can return. */
|
|
42
|
+
claims_supported: string[]
|
|
43
|
+
/** OIDC Core §5.5 — `claims` request parameter is honored. */
|
|
44
|
+
claims_parameter_supported: boolean
|
|
45
|
+
/** OIDC Core §6.1 — JAR (`request` parameter). Not implemented. */
|
|
46
|
+
request_parameter_supported: boolean
|
|
47
|
+
/** OIDC Core §6.2 — JAR (`request_uri` parameter). Not implemented. */
|
|
48
|
+
request_uri_parameter_supported: boolean
|
|
49
|
+
/** OIDC Core §6.2 — whether `request_uri` values must be pre-registered. */
|
|
50
|
+
require_request_uri_registration: boolean
|
|
51
|
+
/** OIDC Core §3.1.2.1 — UI locales the OP can render. */
|
|
52
|
+
ui_locales_supported?: string[]
|
|
53
|
+
token_endpoint_auth_methods_supported: string[]
|
|
54
|
+
code_challenge_methods_supported: string[]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type DiscoveryDeps = {
|
|
58
|
+
issuerUrl: string
|
|
59
|
+
/** Override path defaults if mounted under a non-root prefix. */
|
|
60
|
+
paths?: Partial<{
|
|
61
|
+
authorize: string
|
|
62
|
+
token: string
|
|
63
|
+
userinfo: string
|
|
64
|
+
jwks: string
|
|
65
|
+
revoke: string
|
|
66
|
+
introspect: string
|
|
67
|
+
endSession: string
|
|
68
|
+
par: string
|
|
69
|
+
register: string
|
|
70
|
+
}>
|
|
71
|
+
/** Advertised scopes. Defaults to `["openid", "email", "profile"]`. */
|
|
72
|
+
scopes?: string[]
|
|
73
|
+
/** Advertised UI locales. Defaults to `["en"]`. */
|
|
74
|
+
uiLocales?: string[]
|
|
75
|
+
/**
|
|
76
|
+
* Host-supplied scope → claim-names map. Each key adds a scope to
|
|
77
|
+
* `scopes_supported`; the union of values augments `claims_supported`.
|
|
78
|
+
* Mirrors `IdPOptions.customScopeClaims`.
|
|
79
|
+
*/
|
|
80
|
+
customScopeClaims?: Record<string, ReadonlyArray<string>>
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function buildDiscoveryDocument(deps: DiscoveryDeps): DiscoveryDocument {
|
|
84
|
+
const base = deps.issuerUrl.replace(/\/+$/, "")
|
|
85
|
+
const p = deps.paths ?? {}
|
|
86
|
+
const customScopeKeys = Object.keys(deps.customScopeClaims ?? {})
|
|
87
|
+
const customClaimNames = new Set<string>()
|
|
88
|
+
for (const list of Object.values(deps.customScopeClaims ?? {})) {
|
|
89
|
+
for (const name of list) customClaimNames.add(name)
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
issuer: deps.issuerUrl,
|
|
93
|
+
authorization_endpoint: `${base}${p.authorize ?? "/authorize"}`,
|
|
94
|
+
token_endpoint: `${base}${p.token ?? "/token"}`,
|
|
95
|
+
userinfo_endpoint: `${base}${p.userinfo ?? "/userinfo"}`,
|
|
96
|
+
jwks_uri: `${base}${p.jwks ?? "/.well-known/jwks.json"}`,
|
|
97
|
+
revocation_endpoint: `${base}${p.revoke ?? "/revoke"}`,
|
|
98
|
+
introspection_endpoint: `${base}${p.introspect ?? "/introspect"}`,
|
|
99
|
+
end_session_endpoint: `${base}${p.endSession ?? "/end_session"}`,
|
|
100
|
+
registration_endpoint: `${base}${p.register ?? "/register"}`,
|
|
101
|
+
pushed_authorization_request_endpoint: `${base}${p.par ?? "/par"}`,
|
|
102
|
+
require_pushed_authorization_requests: false,
|
|
103
|
+
dpop_signing_alg_values_supported: ["ES256", "EdDSA"],
|
|
104
|
+
response_types_supported: ["code"],
|
|
105
|
+
grant_types_supported: [
|
|
106
|
+
"authorization_code",
|
|
107
|
+
"refresh_token",
|
|
108
|
+
"client_credentials",
|
|
109
|
+
],
|
|
110
|
+
subject_types_supported: ["public", "pairwise"],
|
|
111
|
+
id_token_signing_alg_values_supported: ["ES256", "EdDSA"],
|
|
112
|
+
scopes_supported: [
|
|
113
|
+
...(deps.scopes ?? ["openid", "email", "profile"]),
|
|
114
|
+
...customScopeKeys,
|
|
115
|
+
],
|
|
116
|
+
claims_supported: [
|
|
117
|
+
"sub",
|
|
118
|
+
"iss",
|
|
119
|
+
"aud",
|
|
120
|
+
"exp",
|
|
121
|
+
"iat",
|
|
122
|
+
"auth_time",
|
|
123
|
+
"nonce",
|
|
124
|
+
"amr",
|
|
125
|
+
"at_hash",
|
|
126
|
+
"email",
|
|
127
|
+
"email_verified",
|
|
128
|
+
"name",
|
|
129
|
+
"given_name",
|
|
130
|
+
"family_name",
|
|
131
|
+
"preferred_username",
|
|
132
|
+
"picture",
|
|
133
|
+
"locale",
|
|
134
|
+
"phone_number",
|
|
135
|
+
"phone_number_verified",
|
|
136
|
+
"address",
|
|
137
|
+
...customClaimNames,
|
|
138
|
+
],
|
|
139
|
+
claims_parameter_supported: true,
|
|
140
|
+
request_parameter_supported: false,
|
|
141
|
+
request_uri_parameter_supported: false,
|
|
142
|
+
require_request_uri_registration: false,
|
|
143
|
+
ui_locales_supported: deps.uiLocales ?? ["en"],
|
|
144
|
+
token_endpoint_auth_methods_supported: [
|
|
145
|
+
"client_secret_basic",
|
|
146
|
+
"client_secret_post",
|
|
147
|
+
"none",
|
|
148
|
+
],
|
|
149
|
+
code_challenge_methods_supported: ["S256"],
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type JwksDoc = ReturnType<typeof buildJwksDocument>
|
|
154
|
+
|
|
155
|
+
export async function buildJwks(
|
|
156
|
+
keyStore: KeyStore,
|
|
157
|
+
): Promise<Result<JwksDoc, AuthError>> {
|
|
158
|
+
const res = await keyStore.signingKeys()
|
|
159
|
+
if (isErr(res)) return err(res.error)
|
|
160
|
+
return ok(buildJwksDocument(res.value))
|
|
161
|
+
}
|