@udibo/oauth2 0.1.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/LICENSE +20 -0
- package/README.md +174 -0
- package/SECURITY.md +77 -0
- package/esm/_dnt.polyfills.d.ts +17 -0
- package/esm/_dnt.polyfills.js +15 -0
- package/esm/adapters/hono/_common.d.ts +66 -0
- package/esm/adapters/hono/_common.js +108 -0
- package/esm/adapters/hono/authorization-server.d.ts +211 -0
- package/esm/adapters/hono/authorization-server.js +214 -0
- package/esm/adapters/hono/bff/auth-request-store.d.ts +164 -0
- package/esm/adapters/hono/bff/auth-request-store.js +154 -0
- package/esm/adapters/hono/bff/bff.d.ts +852 -0
- package/esm/adapters/hono/bff/bff.js +1194 -0
- package/esm/adapters/hono/bff/cookie-prefix.d.ts +72 -0
- package/esm/adapters/hono/bff/cookie-prefix.js +85 -0
- package/esm/adapters/hono/bff/mod.d.ts +19 -0
- package/esm/adapters/hono/bff/mod.js +19 -0
- package/esm/adapters/hono/bff/proxy.d.ts +108 -0
- package/esm/adapters/hono/bff/proxy.js +314 -0
- package/esm/adapters/hono/bff/session-store.d.ts +250 -0
- package/esm/adapters/hono/bff/session-store.js +216 -0
- package/esm/adapters/hono/bff/testing.d.ts +165 -0
- package/esm/adapters/hono/bff/testing.js +254 -0
- package/esm/adapters/hono/identity.d.ts +117 -0
- package/esm/adapters/hono/identity.js +215 -0
- package/esm/adapters/hono/log.d.ts +49 -0
- package/esm/adapters/hono/log.js +66 -0
- package/esm/adapters/hono/resource-server.d.ts +101 -0
- package/esm/adapters/hono/resource-server.js +108 -0
- package/esm/client/_http.d.ts +91 -0
- package/esm/client/_http.js +303 -0
- package/esm/client/base.d.ts +184 -0
- package/esm/client/base.js +93 -0
- package/esm/client/bff-client.d.ts +235 -0
- package/esm/client/bff-client.js +280 -0
- package/esm/client/browser-storage.d.ts +152 -0
- package/esm/client/browser-storage.js +246 -0
- package/esm/client/check.d.ts +114 -0
- package/esm/client/check.js +97 -0
- package/esm/client/direct-client.d.ts +707 -0
- package/esm/client/direct-client.js +1237 -0
- package/esm/client/discovery-cache.d.ts +138 -0
- package/esm/client/discovery-cache.js +124 -0
- package/esm/client/events.d.ts +54 -0
- package/esm/client/events.js +37 -0
- package/esm/client/mod.d.ts +35 -0
- package/esm/client/mod.js +33 -0
- package/esm/client/storage.d.ts +127 -0
- package/esm/client/storage.js +81 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts +29 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.js +47 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts +28 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.js +65 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/assert.d.ts +16 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/assert.js +23 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts +25 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.js +30 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/equal.d.ts +24 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/equal.js +193 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/equals.d.ts +36 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/equals.js +61 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/exists.d.ts +17 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/exists.js +27 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/fail.d.ts +14 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/fail.js +20 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/false.d.ts +18 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/false.js +23 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater.d.ts +19 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater.js +29 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts +19 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.js +29 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts +22 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.js +52 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts +24 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.js +53 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/less.d.ts +18 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/less.js +28 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts +19 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.js +29 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/match.d.ts +17 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/match.js +26 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/mod.d.ts +43 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/mod.js +45 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts +26 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.js +39 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts +19 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.js +29 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts +17 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.js +26 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts +22 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.js +32 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts +28 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.js +177 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts +41 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.js +53 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts +23 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.js +58 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts +17 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.js +26 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/throws.d.ts +44 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/throws.js +44 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts +14 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.js +20 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts +14 -0
- package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.js +20 -0
- package/esm/deps/jsr.io/@std/async/1.5.0/delay.d.ts +44 -0
- package/esm/deps/jsr.io/@std/async/1.5.0/delay.js +84 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +39 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +61 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.d.ts +22 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.js +51 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.d.ts +34 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.js +192 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.d.ts +34 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.js +113 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.d.ts +3 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.js +13 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.d.ts +8 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.js +2 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.d.ts +1 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.js +26 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.d.ts +60 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.js +152 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.d.ts +39 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.js +87 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.d.ts +39 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.js +131 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.d.ts +39 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.js +82 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.d.ts +39 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.js +72 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.d.ts +38 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.js +87 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.d.ts +97 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.js +99 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.d.ts +119 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.js +209 -0
- package/esm/deps/jsr.io/@std/http/1.1.3/status.d.ts +343 -0
- package/esm/deps/jsr.io/@std/http/1.1.3/status.js +343 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.d.ts +159 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.js +223 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.d.ts +79 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.js +116 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff.d.ts +139 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff.js +277 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.d.ts +98 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.js +181 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/format.d.ts +29 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/format.js +68 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/styles.d.ts +158 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/styles.js +206 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/types.d.ts +24 -0
- package/esm/deps/jsr.io/@std/internal/1.0.14/types.js +3 -0
- package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.d.ts +91 -0
- package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.js +347 -0
- package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.d.ts +382 -0
- package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.js +1110 -0
- package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.d.ts +363 -0
- package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.js +616 -0
- package/esm/errors.d.ts +203 -0
- package/esm/errors.js +287 -0
- package/esm/identity/captcha.d.ts +147 -0
- package/esm/identity/captcha.js +64 -0
- package/esm/identity/delivery.d.ts +96 -0
- package/esm/identity/delivery.js +41 -0
- package/esm/identity/errors.d.ts +39 -0
- package/esm/identity/errors.js +46 -0
- package/esm/identity/events.d.ts +242 -0
- package/esm/identity/events.js +39 -0
- package/esm/identity/external/_shared.d.ts +86 -0
- package/esm/identity/external/_shared.js +107 -0
- package/esm/identity/external/_token-exchange.d.ts +61 -0
- package/esm/identity/external/_token-exchange.js +179 -0
- package/esm/identity/external/apple-client-secret.d.ts +82 -0
- package/esm/identity/external/apple-client-secret.js +133 -0
- package/esm/identity/external/apple.d.ts +64 -0
- package/esm/identity/external/apple.js +248 -0
- package/esm/identity/external/discord.d.ts +38 -0
- package/esm/identity/external/discord.js +62 -0
- package/esm/identity/external/errors.d.ts +48 -0
- package/esm/identity/external/errors.js +36 -0
- package/esm/identity/external/flow.d.ts +107 -0
- package/esm/identity/external/flow.js +158 -0
- package/esm/identity/external/github.d.ts +42 -0
- package/esm/identity/external/github.js +164 -0
- package/esm/identity/external/google.d.ts +52 -0
- package/esm/identity/external/google.js +38 -0
- package/esm/identity/external/mod.d.ts +63 -0
- package/esm/identity/external/mod.js +61 -0
- package/esm/identity/external/oauth2.d.ts +110 -0
- package/esm/identity/external/oauth2.js +158 -0
- package/esm/identity/external/oidc.d.ts +81 -0
- package/esm/identity/external/oidc.js +250 -0
- package/esm/identity/external/provider.d.ts +132 -0
- package/esm/identity/external/provider.js +12 -0
- package/esm/identity/hibp.d.ts +67 -0
- package/esm/identity/hibp.js +87 -0
- package/esm/identity/identifier.d.ts +44 -0
- package/esm/identity/identifier.js +47 -0
- package/esm/identity/lockout.d.ts +155 -0
- package/esm/identity/lockout.js +117 -0
- package/esm/identity/mfa/mod.d.ts +42 -0
- package/esm/identity/mfa/mod.js +42 -0
- package/esm/identity/mfa/recovery-codes.d.ts +96 -0
- package/esm/identity/mfa/recovery-codes.js +80 -0
- package/esm/identity/mfa/service.d.ts +338 -0
- package/esm/identity/mfa/service.js +351 -0
- package/esm/identity/mfa/totp.d.ts +186 -0
- package/esm/identity/mfa/totp.js +194 -0
- package/esm/identity/migration.d.ts +155 -0
- package/esm/identity/migration.js +243 -0
- package/esm/identity/mod.d.ts +65 -0
- package/esm/identity/mod.js +64 -0
- package/esm/identity/otp.d.ts +255 -0
- package/esm/identity/otp.js +245 -0
- package/esm/identity/password-policy.d.ts +45 -0
- package/esm/identity/password-policy.js +60 -0
- package/esm/identity/password.d.ts +171 -0
- package/esm/identity/password.js +160 -0
- package/esm/identity/rate-limit.d.ts +192 -0
- package/esm/identity/rate-limit.js +168 -0
- package/esm/identity/service.d.ts +579 -0
- package/esm/identity/service.js +835 -0
- package/esm/identity/session.d.ts +122 -0
- package/esm/identity/session.js +48 -0
- package/esm/identity/token-flow.d.ts +214 -0
- package/esm/identity/token-flow.js +173 -0
- package/esm/models/authentication.d.ts +24 -0
- package/esm/models/authentication.js +1 -0
- package/esm/models/authorization-code.d.ts +63 -0
- package/esm/models/authorization-code.js +1 -0
- package/esm/models/authorization.d.ts +165 -0
- package/esm/models/authorization.js +160 -0
- package/esm/models/client.d.ts +78 -0
- package/esm/models/client.js +1 -0
- package/esm/models/device-authorization.d.ts +30 -0
- package/esm/models/device-authorization.js +1 -0
- package/esm/models/responses.d.ts +93 -0
- package/esm/models/responses.js +1 -0
- package/esm/models/scope.d.ts +81 -0
- package/esm/models/scope.js +125 -0
- package/esm/models/token.d.ts +135 -0
- package/esm/models/token.js +1 -0
- package/esm/package.json +3 -0
- package/esm/react/callback.d.ts +52 -0
- package/esm/react/callback.js +71 -0
- package/esm/react/components/class-names.d.ts +91 -0
- package/esm/react/components/class-names.js +118 -0
- package/esm/react/components/internal.d.ts +62 -0
- package/esm/react/components/internal.js +102 -0
- package/esm/react/components/mfa-challenge-form.d.ts +66 -0
- package/esm/react/components/mfa-challenge-form.js +46 -0
- package/esm/react/components/mfa-enrollment-form.d.ts +83 -0
- package/esm/react/components/mfa-enrollment-form.js +41 -0
- package/esm/react/components/mod.d.ts +103 -0
- package/esm/react/components/mod.js +93 -0
- package/esm/react/components/request-password-reset-form.d.ts +61 -0
- package/esm/react/components/request-password-reset-form.js +41 -0
- package/esm/react/components/reset-password-form.d.ts +66 -0
- package/esm/react/components/reset-password-form.js +56 -0
- package/esm/react/components/sign-in-form.d.ts +74 -0
- package/esm/react/components/sign-in-form.js +43 -0
- package/esm/react/components/sign-up-form.d.ts +85 -0
- package/esm/react/components/sign-up-form.js +57 -0
- package/esm/react/components/types.d.ts +208 -0
- package/esm/react/components/types.js +14 -0
- package/esm/react/components/use-auth-form.d.ts +118 -0
- package/esm/react/components/use-auth-form.js +172 -0
- package/esm/react/components/user-menu.d.ts +79 -0
- package/esm/react/components/user-menu.js +73 -0
- package/esm/react/context.d.ts +51 -0
- package/esm/react/context.js +16 -0
- package/esm/react/mod.d.ts +26 -0
- package/esm/react/mod.js +26 -0
- package/esm/react/provider.d.ts +40 -0
- package/esm/react/provider.js +189 -0
- package/esm/react/require-auth.d.ts +31 -0
- package/esm/react/require-auth.js +37 -0
- package/esm/react/testing.d.ts +322 -0
- package/esm/react/testing.js +461 -0
- package/esm/react/use-authorization.d.ts +31 -0
- package/esm/react/use-authorization.js +36 -0
- package/esm/react/use-oauth2.d.ts +112 -0
- package/esm/react/use-oauth2.js +127 -0
- package/esm/server/authorization-server.d.ts +736 -0
- package/esm/server/authorization-server.js +1304 -0
- package/esm/server/client-authentication.d.ts +28 -0
- package/esm/server/client-authentication.js +51 -0
- package/esm/server/grants/authorization-code.d.ts +179 -0
- package/esm/server/grants/authorization-code.js +232 -0
- package/esm/server/grants/client-credentials.d.ts +52 -0
- package/esm/server/grants/client-credentials.js +53 -0
- package/esm/server/grants/device-authorization.d.ts +103 -0
- package/esm/server/grants/device-authorization.js +156 -0
- package/esm/server/grants/grant.d.ts +165 -0
- package/esm/server/grants/grant.js +173 -0
- package/esm/server/grants/password.d.ts +80 -0
- package/esm/server/grants/password.js +92 -0
- package/esm/server/grants/refresh-token.d.ts +80 -0
- package/esm/server/grants/refresh-token.js +136 -0
- package/esm/server/introspection-token-reader.d.ts +153 -0
- package/esm/server/introspection-token-reader.js +164 -0
- package/esm/server/jwks-token-reader.d.ts +263 -0
- package/esm/server/jwks-token-reader.js +508 -0
- package/esm/server/mod.d.ts +23 -0
- package/esm/server/mod.js +15 -0
- package/esm/server/public-suffix/mod.d.ts +62 -0
- package/esm/server/public-suffix/mod.js +103 -0
- package/esm/server/public-suffix/rules.d.ts +23 -0
- package/esm/server/public-suffix/rules.js +23 -0
- package/esm/server/redirect-uri.d.ts +187 -0
- package/esm/server/redirect-uri.js +331 -0
- package/esm/server/resource-server.d.ts +286 -0
- package/esm/server/resource-server.js +365 -0
- package/esm/server/services/authorization-code.d.ts +84 -0
- package/esm/server/services/authorization-code.js +35 -0
- package/esm/server/services/client.d.ts +35 -0
- package/esm/server/services/client.js +1 -0
- package/esm/server/services/device-authorization.d.ts +134 -0
- package/esm/server/services/device-authorization.js +7 -0
- package/esm/server/services/token.d.ts +242 -0
- package/esm/server/services/token.js +78 -0
- package/esm/server/services/user.d.ts +29 -0
- package/esm/server/services/user.js +7 -0
- package/esm/server/signing-keys.d.ts +201 -0
- package/esm/server/signing-keys.js +225 -0
- package/esm/server/utils/hash.d.ts +6 -0
- package/esm/server/utils/hash.js +11 -0
- package/esm/testing/contract/authorization-code.d.ts +37 -0
- package/esm/testing/contract/authorization-code.js +93 -0
- package/esm/testing/contract/client.d.ts +85 -0
- package/esm/testing/contract/client.js +126 -0
- package/esm/testing/contract/device-authorization.d.ts +37 -0
- package/esm/testing/contract/device-authorization.js +193 -0
- package/esm/testing/contract/lockout-store.d.ts +47 -0
- package/esm/testing/contract/lockout-store.js +122 -0
- package/esm/testing/contract/mfa-store.d.ts +50 -0
- package/esm/testing/contract/mfa-store.js +226 -0
- package/esm/testing/contract/mod.d.ts +39 -0
- package/esm/testing/contract/mod.js +39 -0
- package/esm/testing/contract/otp-store.d.ts +48 -0
- package/esm/testing/contract/otp-store.js +197 -0
- package/esm/testing/contract/rate-limit-store.d.ts +52 -0
- package/esm/testing/contract/rate-limit-store.js +105 -0
- package/esm/testing/contract/token-flow-store.d.ts +54 -0
- package/esm/testing/contract/token-flow-store.js +179 -0
- package/esm/testing/contract/token-reader.d.ts +77 -0
- package/esm/testing/contract/token-reader.js +78 -0
- package/esm/testing/contract/token.d.ts +61 -0
- package/esm/testing/contract/token.js +287 -0
- package/esm/testing/contract/user.d.ts +63 -0
- package/esm/testing/contract/user.js +75 -0
- package/esm/testing/mod.d.ts +34 -0
- package/esm/testing/mod.js +34 -0
- package/esm/testing/server.d.ts +197 -0
- package/esm/testing/server.js +193 -0
- package/esm/testing/services.d.ts +373 -0
- package/esm/testing/services.js +703 -0
- package/esm/utils/_buffer.d.ts +10 -0
- package/esm/utils/_buffer.js +12 -0
- package/esm/utils/_timing-safe.d.ts +13 -0
- package/esm/utils/_timing-safe.js +22 -0
- package/esm/utils/authentication-context.d.ts +3 -0
- package/esm/utils/authentication-context.js +14 -0
- package/esm/utils/basic-auth.d.ts +50 -0
- package/esm/utils/basic-auth.js +106 -0
- package/esm/utils/crypto.d.ts +97 -0
- package/esm/utils/crypto.js +162 -0
- package/esm/utils/pkce.d.ts +151 -0
- package/esm/utils/pkce.js +179 -0
- package/esm/utils/text.d.ts +24 -0
- package/esm/utils/text.js +28 -0
- package/esm/utils/url.d.ts +66 -0
- package/esm/utils/url.js +90 -0
- package/package.json +92 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token reader that validates tokens via an OAuth2 introspection endpoint.
|
|
3
|
+
*
|
|
4
|
+
* This is the standard way for resource servers to validate tokens when
|
|
5
|
+
* they are separate from the authorization server. The reader calls the
|
|
6
|
+
* authorization server's introspection endpoint (RFC 7662) to check
|
|
7
|
+
* whether a token is active and retrieve its metadata.
|
|
8
|
+
*
|
|
9
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7662
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { ServerError, TemporarilyUnavailableError } from "../errors.js";
|
|
13
|
+
import { BasicScope } from "../models/scope.js";
|
|
14
|
+
import { encodeBasicAuth } from "../utils/basic-auth.js";
|
|
15
|
+
/**
|
|
16
|
+
* Validates tokens by calling an OAuth2 introspection endpoint (RFC 7662).
|
|
17
|
+
*
|
|
18
|
+
* Use this with {@linkcode ResourceServer} when your resource server is
|
|
19
|
+
* separate from the authorization server. The reader authenticates with
|
|
20
|
+
* the introspection endpoint using client credentials (HTTP Basic Auth)
|
|
21
|
+
* and projects the response into the resource server's `Client` / `User`
|
|
22
|
+
* types via the {@linkcode IntrospectionTokenReaderOptions.getClient} and
|
|
23
|
+
* {@linkcode IntrospectionTokenReaderOptions.getUser} mappers.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import {
|
|
28
|
+
* IntrospectionTokenReader,
|
|
29
|
+
* ResourceServer,
|
|
30
|
+
* } from "@udibo/oauth2/server/resource";
|
|
31
|
+
*
|
|
32
|
+
* interface MyClient { id: string }
|
|
33
|
+
* interface MyUser { id: string; email?: string }
|
|
34
|
+
*
|
|
35
|
+
* const tokenReader = new IntrospectionTokenReader<MyClient, MyUser>({
|
|
36
|
+
* introspectionEndpoint: "https://auth.example.com/introspect",
|
|
37
|
+
* clientId: "my-api",
|
|
38
|
+
* clientSecret: "my-secret",
|
|
39
|
+
* getClient: (data) => ({ id: data.client_id! }),
|
|
40
|
+
* getUser: (data) =>
|
|
41
|
+
* data.sub
|
|
42
|
+
* ? { id: data.sub, email: data.email as string | undefined }
|
|
43
|
+
* : undefined,
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* const resourceServer = new ResourceServer<MyClient, MyUser>({
|
|
47
|
+
* resolve: () => ({ services: { tokenService: tokenReader } }),
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export class IntrospectionTokenReader {
|
|
52
|
+
introspectionEndpoint;
|
|
53
|
+
clientId;
|
|
54
|
+
clientSecret;
|
|
55
|
+
Scope;
|
|
56
|
+
getClient;
|
|
57
|
+
getUser;
|
|
58
|
+
fetchTimeoutMs;
|
|
59
|
+
customFetch;
|
|
60
|
+
/**
|
|
61
|
+
* `Scope` defaults to {@linkcode BasicScope}, `fetchTimeoutMs` to 5000, and
|
|
62
|
+
* `fetch` to the global `fetch` when omitted from `options`.
|
|
63
|
+
*/
|
|
64
|
+
constructor(options) {
|
|
65
|
+
this.introspectionEndpoint = options.introspectionEndpoint;
|
|
66
|
+
this.clientId = options.clientId;
|
|
67
|
+
this.clientSecret = options.clientSecret;
|
|
68
|
+
this.Scope = options.Scope ??
|
|
69
|
+
BasicScope;
|
|
70
|
+
this.getClient = options.getClient;
|
|
71
|
+
this.getUser = options.getUser;
|
|
72
|
+
this.fetchTimeoutMs = options.fetchTimeoutMs ?? 5_000;
|
|
73
|
+
this.customFetch = options.fetch;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Validates an access token by calling the introspection endpoint.
|
|
77
|
+
*
|
|
78
|
+
* Sends a POST request with the token to the configured introspection
|
|
79
|
+
* endpoint, authenticated with client credentials via HTTP Basic Auth.
|
|
80
|
+
*
|
|
81
|
+
* @returns The token with client/user/scope info, or `undefined` when the
|
|
82
|
+
* endpoint reports the token inactive (RFC 7662 `{ active: false }`) or
|
|
83
|
+
* does not identify it as a bearer access token.
|
|
84
|
+
* @throws {TemporarilyUnavailableError} If the introspection endpoint is
|
|
85
|
+
* unreachable, takes longer than
|
|
86
|
+
* {@linkcode IntrospectionTokenReaderOptions.fetchTimeoutMs} to answer, or
|
|
87
|
+
* returns a 5xx — a down authorization server must be distinguishable from
|
|
88
|
+
* a genuinely invalid token (which is `undefined` → `invalid_token`), not
|
|
89
|
+
* collapsed into it.
|
|
90
|
+
* @throws {ServerError} If the endpoint returns a 4xx (e.g. the reader's own
|
|
91
|
+
* introspection credentials are rejected) — a misconfiguration, not a
|
|
92
|
+
* verdict on the caller's token.
|
|
93
|
+
*
|
|
94
|
+
* An active response is only accepted when its `token_type` names a bearer
|
|
95
|
+
* token. RFC 7662 answers for refresh tokens too, and a refresh token's
|
|
96
|
+
* response is otherwise indistinguishable from an access token's — without
|
|
97
|
+
* this check a refresh token presented as `Authorization: Bearer …` would
|
|
98
|
+
* authenticate at the resource server, bypassing rotation and reuse
|
|
99
|
+
* detection. An authorization server that omits `token_type` from an active
|
|
100
|
+
* response cannot be read by this reader.
|
|
101
|
+
*/
|
|
102
|
+
async getToken(accessToken) {
|
|
103
|
+
const data = await this.#introspect(accessToken);
|
|
104
|
+
if (!data.active)
|
|
105
|
+
return undefined;
|
|
106
|
+
if (data.token_type?.toLowerCase() !== "bearer")
|
|
107
|
+
return undefined;
|
|
108
|
+
const [client, user] = await Promise.all([
|
|
109
|
+
this.getClient(data),
|
|
110
|
+
this.getUser?.(data),
|
|
111
|
+
]);
|
|
112
|
+
return {
|
|
113
|
+
accessToken,
|
|
114
|
+
accessTokenExpiresAt: data.exp ? new Date(data.exp * 1000) : undefined,
|
|
115
|
+
client,
|
|
116
|
+
user,
|
|
117
|
+
scope: data.scope
|
|
118
|
+
? new this.Scope(data.scope)
|
|
119
|
+
: undefined,
|
|
120
|
+
claims: data,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async #introspect(accessToken) {
|
|
124
|
+
const fetchImpl = this.customFetch ?? globalThis.fetch;
|
|
125
|
+
const controller = new AbortController();
|
|
126
|
+
const deadline = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
|
|
127
|
+
try {
|
|
128
|
+
let response;
|
|
129
|
+
try {
|
|
130
|
+
response = await fetchImpl(this.introspectionEndpoint, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: {
|
|
133
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
134
|
+
"Authorization": encodeBasicAuth(this.clientId, this.clientSecret),
|
|
135
|
+
},
|
|
136
|
+
body: new URLSearchParams({ token: accessToken }),
|
|
137
|
+
signal: controller.signal,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (cause) {
|
|
141
|
+
throw new TemporarilyUnavailableError("token introspection request failed", { cause });
|
|
142
|
+
}
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
await response.body?.cancel();
|
|
145
|
+
throw response.status >= 500
|
|
146
|
+
? new TemporarilyUnavailableError(`token introspection failed (HTTP ${response.status})`)
|
|
147
|
+
: new ServerError(`token introspection failed (HTTP ${response.status})`);
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
return await response.json();
|
|
151
|
+
}
|
|
152
|
+
catch (cause) {
|
|
153
|
+
throw controller.signal.aborted
|
|
154
|
+
? new TemporarilyUnavailableError("token introspection request failed", { cause })
|
|
155
|
+
: new ServerError("token introspection response was not JSON", {
|
|
156
|
+
cause,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
clearTimeout(deadline);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token reader that validates JWT access tokens locally against the
|
|
3
|
+
* issuer's published JWKS, with no per-request network hop.
|
|
4
|
+
*
|
|
5
|
+
* This is the validating half of RFC 9068 (`at+jwt`): the authorization
|
|
6
|
+
* server signs access tokens and publishes its public keys at a `jwks_uri`;
|
|
7
|
+
* the resource server fetches those keys once, caches them, and verifies
|
|
8
|
+
* every subsequent token in-process. Signature verification uses Web Crypto
|
|
9
|
+
* only — the package takes no JOSE dependency.
|
|
10
|
+
*
|
|
11
|
+
* @see https://datatracker.ietf.org/doc/html/rfc9068
|
|
12
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7517
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { ClientInterface } from "../models/client.js";
|
|
16
|
+
import type { AbstractScope, ScopeConstructor } from "../models/scope.js";
|
|
17
|
+
import { BasicScope } from "../models/scope.js";
|
|
18
|
+
import type { Token } from "../models/token.js";
|
|
19
|
+
import type { TokenReaderInterface } from "./services/token.js";
|
|
20
|
+
/**
|
|
21
|
+
* Claims of a validated JWT access token, as defined by RFC 9068 §2.2.
|
|
22
|
+
*
|
|
23
|
+
* Passed to the {@linkcode JwksTokenReaderOptions.getClient} and
|
|
24
|
+
* {@linkcode JwksTokenReaderOptions.getUser} mappers. Issuers routinely add
|
|
25
|
+
* their own claims (roles, tenant, email); the index signature exposes them.
|
|
26
|
+
*/
|
|
27
|
+
export interface JwtAccessTokenClaims {
|
|
28
|
+
/** Issuer that signed the token. Verified against the configured issuer. */
|
|
29
|
+
iss: string;
|
|
30
|
+
/** Subject — the end user, or the client itself for client-credentials tokens. */
|
|
31
|
+
sub?: string;
|
|
32
|
+
/** Audience(s) the token is intended for. Verified against the configured audience. */
|
|
33
|
+
aud: string | string[];
|
|
34
|
+
/** Expiration time, seconds since the epoch. */
|
|
35
|
+
exp: number;
|
|
36
|
+
/** Issued-at time, seconds since the epoch. */
|
|
37
|
+
iat?: number;
|
|
38
|
+
/** Not-before time, seconds since the epoch. */
|
|
39
|
+
nbf?: number;
|
|
40
|
+
/** Unique token identifier. */
|
|
41
|
+
jti?: string;
|
|
42
|
+
/** Client the token was issued to. */
|
|
43
|
+
client_id?: string;
|
|
44
|
+
/** Space-delimited granted scopes. */
|
|
45
|
+
scope?: string;
|
|
46
|
+
/** Granted scopes as an array or string — the variant some issuers emit instead of `scope`. */
|
|
47
|
+
scp?: string | string[];
|
|
48
|
+
/** Extension claims. Issuers may add anything. */
|
|
49
|
+
[claim: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Options for configuring the JWKS token reader.
|
|
53
|
+
*
|
|
54
|
+
* {@linkcode issuer} and {@linkcode audience} are required because RFC 9068
|
|
55
|
+
* §4 requires a resource server to reject tokens minted for a different
|
|
56
|
+
* issuer or a different audience — with local validation there is no
|
|
57
|
+
* authorization server in the request path to do it for you.
|
|
58
|
+
*/
|
|
59
|
+
export interface JwksTokenReaderOptions<Client extends ClientInterface, User, S extends AbstractScope = BasicScope> {
|
|
60
|
+
/**
|
|
61
|
+
* Expected `iss` claim. Also the discovery base when
|
|
62
|
+
* {@linkcode jwksUri} is omitted.
|
|
63
|
+
*/
|
|
64
|
+
issuer: string;
|
|
65
|
+
/**
|
|
66
|
+
* Accepted `aud` claim value(s) — this resource server's identifier. A
|
|
67
|
+
* token passes when its `aud` (string or array) includes at least one of
|
|
68
|
+
* these. Authorization servers that default `aud` to the client id
|
|
69
|
+
* require listing the client ids you accept.
|
|
70
|
+
*/
|
|
71
|
+
audience: string | string[];
|
|
72
|
+
/**
|
|
73
|
+
* URL of the issuer's JWKS. Omit to discover it from `issuer`, trying
|
|
74
|
+
* `/.well-known/oauth-authorization-server` then
|
|
75
|
+
* `/.well-known/openid-configuration` inserted before the issuer's path
|
|
76
|
+
* component (RFC 8414 §3.1), then the OIDC Core form with
|
|
77
|
+
* `/.well-known/openid-configuration` appended. For a path-less issuer the
|
|
78
|
+
* last two are the same URL and only one request is made.
|
|
79
|
+
*/
|
|
80
|
+
jwksUri?: string;
|
|
81
|
+
/**
|
|
82
|
+
* JWS algorithms accepted from the token header, intersected with what the
|
|
83
|
+
* matched key supports. Defaults to every asymmetric algorithm Web Crypto
|
|
84
|
+
* covers: `ES256`/`ES384`/`ES512`, `RS256`/`RS384`/`RS512`, and
|
|
85
|
+
* `PS256`/`PS384`/`PS512`. Pin it to what your issuer actually signs with
|
|
86
|
+
* when you can. Symmetric (`HS*`) and `none` are never accepted.
|
|
87
|
+
*/
|
|
88
|
+
algorithms?: string[];
|
|
89
|
+
/**
|
|
90
|
+
* Accepted `typ` header values, compared case-insensitively with an
|
|
91
|
+
* optional `application/` prefix. Defaults to `["at+jwt"]` per RFC 9068 §4.
|
|
92
|
+
*
|
|
93
|
+
* This is the first line of defense against another JWT the same issuer
|
|
94
|
+
* signs — an OIDC `id_token` above all — being replayed as an access
|
|
95
|
+
* token. Prefer configuring your issuer to stamp `at+jwt` over widening
|
|
96
|
+
* this. If you must widen it (`["at+jwt", "jwt"]`) or disable it (`[]`),
|
|
97
|
+
* give this API an {@linkcode audience} that is **not** one of your client
|
|
98
|
+
* ids, since an `id_token`'s `aud` is a client id. The
|
|
99
|
+
* {@linkcode clientIdClaim} requirement and the rejection of
|
|
100
|
+
* `id_token`-only claims still apply either way.
|
|
101
|
+
*/
|
|
102
|
+
types?: string[];
|
|
103
|
+
/**
|
|
104
|
+
* Claim carrying the client id, required on every accepted token (RFC 9068
|
|
105
|
+
* §2.2 makes `client_id` REQUIRED, and its absence is what tells an
|
|
106
|
+
* `id_token` apart from an access token). Defaults to `"client_id"`; point
|
|
107
|
+
* it at the vendor claim for issuers that deviate — Okta's `cid`, Azure
|
|
108
|
+
* AD v1's `appid`. There is deliberately no way to drop the requirement.
|
|
109
|
+
*/
|
|
110
|
+
clientIdClaim?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Leeway in seconds applied to `exp` and `nbf` to absorb clock drift
|
|
113
|
+
* between the issuer and this server. Defaults to 30.
|
|
114
|
+
*
|
|
115
|
+
* This governs this reader's own claim checks. The token it returns carries
|
|
116
|
+
* the issuer's `exp` verbatim, and {@linkcode ResourceServer} re-checks that
|
|
117
|
+
* against its own {@linkcode ResourceServerOptions.clockSkewSeconds}, which
|
|
118
|
+
* defaults to no leeway — so set that one too for a resource server that
|
|
119
|
+
* must tolerate an about-to-expire token.
|
|
120
|
+
*/
|
|
121
|
+
clockSkewSeconds?: number;
|
|
122
|
+
/**
|
|
123
|
+
* How long a fetched JWKS is served before the next validation refreshes
|
|
124
|
+
* it. Defaults to 600000 (10 minutes). A refresh that fails keeps serving
|
|
125
|
+
* the cached keys. Zero or negative makes every read refresh — supported,
|
|
126
|
+
* and the deterministic setting for tests, but it leans on
|
|
127
|
+
* {@link JwksTokenReaderOptions.minFetchIntervalMs} alone for rate limiting.
|
|
128
|
+
*/
|
|
129
|
+
cacheMaxAgeMs?: number;
|
|
130
|
+
/**
|
|
131
|
+
* Minimum interval between JWKS fetches. Defaults to 30000 (30 seconds).
|
|
132
|
+
* This is the guard that stops a flood of tokens bearing unknown `kid`s
|
|
133
|
+
* from turning this reader into a JWKS-endpoint DoS amplifier; the cost is
|
|
134
|
+
* that a key rotation is picked up at most one interval late. Zero or
|
|
135
|
+
* negative removes the throttle entirely — a test-only setting, never
|
|
136
|
+
* appropriate against a real endpoint.
|
|
137
|
+
*/
|
|
138
|
+
minFetchIntervalMs?: number;
|
|
139
|
+
/**
|
|
140
|
+
* Deadline in milliseconds for a JWKS or discovery request. Defaults to
|
|
141
|
+
* 5000. Without it a blackholed endpoint (dropped packets rather than a
|
|
142
|
+
* refused connection) would hang the refresh — and with it every request
|
|
143
|
+
* that joins the shared in-flight fetch. Ignored by an injected
|
|
144
|
+
* {@linkcode fetch} that doesn't honour `AbortSignal`.
|
|
145
|
+
*/
|
|
146
|
+
fetchTimeoutMs?: number;
|
|
147
|
+
/** Optional scope constructor for parsing scope strings. Defaults to BasicScope. */
|
|
148
|
+
Scope?: ScopeConstructor<S>;
|
|
149
|
+
/**
|
|
150
|
+
* Projects a validated token's claims into a typed `Client`. Required
|
|
151
|
+
* because the client shape is app-specific; `client_id` (RFC 9068) is the
|
|
152
|
+
* usual key.
|
|
153
|
+
*
|
|
154
|
+
* May be async — return a promise to enrich from a DB lookup.
|
|
155
|
+
*/
|
|
156
|
+
getClient: (claims: JwtAccessTokenClaims) => Client | Promise<Client>;
|
|
157
|
+
/**
|
|
158
|
+
* Projects a validated token's claims into a typed `User`. Return
|
|
159
|
+
* `undefined` when the token doesn't represent a user (e.g.
|
|
160
|
+
* client-credentials tokens). Omit entirely if your app never reads user
|
|
161
|
+
* info off the token.
|
|
162
|
+
*
|
|
163
|
+
* May be async — return a promise to enrich from a DB lookup or the
|
|
164
|
+
* issuer's UserInfo endpoint, using `claims.sub` as the lookup key.
|
|
165
|
+
*/
|
|
166
|
+
getUser?: (claims: JwtAccessTokenClaims) => User | undefined | Promise<User | undefined>;
|
|
167
|
+
/**
|
|
168
|
+
* `fetch` implementation used for JWKS and discovery requests. Defaults to
|
|
169
|
+
* the global `fetch`. Inject it to route through a custom client (mTLS,
|
|
170
|
+
* timeouts, retries) or to stub the network in tests.
|
|
171
|
+
*/
|
|
172
|
+
fetch?: typeof fetch;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Validates JWT access tokens (RFC 9068) against the issuer's remote JWKS.
|
|
176
|
+
*
|
|
177
|
+
* Use this with {@linkcode ResourceServer} when the authorization server
|
|
178
|
+
* issues **signed** access tokens: keys are fetched once and cached on the
|
|
179
|
+
* instance, so validation costs no network round-trip per request — the
|
|
180
|
+
* trade-off against {@linkcode IntrospectionTokenReader}, which sees
|
|
181
|
+
* revocation immediately but calls the authorization server every time. A
|
|
182
|
+
* revoked JWT stays valid here until it expires, so keep access-token
|
|
183
|
+
* lifetimes short, or introspect on the endpoints where revocation latency
|
|
184
|
+
* matters.
|
|
185
|
+
*
|
|
186
|
+
* A token is accepted only when its signature verifies against a published
|
|
187
|
+
* key whose algorithm the header matches, and its `typ`, `iss`, `aud`, `exp`
|
|
188
|
+
* and `nbf` all satisfy the configuration. Anything else is `undefined` —
|
|
189
|
+
* the same `invalid_token` surface as an unknown opaque token. Unreachable
|
|
190
|
+
* key material throws instead, so a down issuer is never reported as a bad
|
|
191
|
+
* token.
|
|
192
|
+
*
|
|
193
|
+
* **Token substitution.** An access token must never be confused with
|
|
194
|
+
* another JWT the same issuer signs. Three checks enforce that
|
|
195
|
+
* independently: `typ` must be `at+jwt`
|
|
196
|
+
* ({@linkcode JwksTokenReaderOptions.types}), the client-id claim must be
|
|
197
|
+
* present ({@linkcode JwksTokenReaderOptions.clientIdClaim}, REQUIRED by
|
|
198
|
+
* RFC 9068 §2.2 and absent from an `id_token`), and `id_token`-only claims
|
|
199
|
+
* (`nonce`, `at_hash`, `c_hash`, `s_hash`) are rejected outright.
|
|
200
|
+
* `auth_time`, `acr` and `amr` are **not** in that list — RFC 9068 §2.2.1
|
|
201
|
+
* permits them on an access token. A `crit` header is rejected per RFC 7515
|
|
202
|
+
* §4.1.11, since this reader understands no JWS extensions.
|
|
203
|
+
*
|
|
204
|
+
* The cache lives on the instance: construct one reader and reuse it.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* import { JwksTokenReader, ResourceServer } from "@udibo/oauth2/server/resource";
|
|
209
|
+
*
|
|
210
|
+
* interface MyClient { id: string }
|
|
211
|
+
* interface MyUser { id: string }
|
|
212
|
+
*
|
|
213
|
+
* const tokenReader = new JwksTokenReader<MyClient, MyUser>({
|
|
214
|
+
* issuer: "https://auth.example.com",
|
|
215
|
+
* audience: "https://api.example.com",
|
|
216
|
+
* getClient: (claims) => ({ id: String(claims.client_id) }),
|
|
217
|
+
* getUser: (claims) => claims.sub ? { id: claims.sub } : undefined,
|
|
218
|
+
* });
|
|
219
|
+
*
|
|
220
|
+
* const resourceServer = new ResourceServer<MyClient, MyUser>({
|
|
221
|
+
* resolve: () => ({ services: { tokenService: tokenReader } }),
|
|
222
|
+
* });
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export declare class JwksTokenReader<Client extends ClientInterface, User, S extends AbstractScope = BasicScope> implements TokenReaderInterface<Client, User, S> {
|
|
226
|
+
#private;
|
|
227
|
+
/**
|
|
228
|
+
* Defaults: every Web Crypto asymmetric algorithm accepted, `at+jwt`
|
|
229
|
+
* required as `typ`, `client_id` as the required client-id claim, 30
|
|
230
|
+
* seconds of clock skew, a 10-minute cache with a 30-second minimum
|
|
231
|
+
* between fetches, a 5-second request deadline, {@linkcode BasicScope},
|
|
232
|
+
* and the global `fetch`.
|
|
233
|
+
*
|
|
234
|
+
* @throws {TypeError} If `issuer` is not an absolute URL, `audience` is
|
|
235
|
+
* empty, or `algorithms` names an algorithm this package cannot verify
|
|
236
|
+
* (a silently ignored entry would read as a policy that isn't enforced).
|
|
237
|
+
*/
|
|
238
|
+
constructor(options: JwksTokenReaderOptions<Client, User, S>);
|
|
239
|
+
/**
|
|
240
|
+
* Validates a JWT access token against the cached JWKS.
|
|
241
|
+
*
|
|
242
|
+
* Refreshes the keys when no published key verifies the signature — at
|
|
243
|
+
* most one fetch per {@linkcode
|
|
244
|
+
* JwksTokenReaderOptions.minFetchIntervalMs}, shared by concurrent
|
|
245
|
+
* callers. A token whose `kid` matched a cached key and still failed
|
|
246
|
+
* verification is a forgery, not a rotation, and provokes no fetch. A
|
|
247
|
+
* stale cache refreshes in the background: requests are served from the
|
|
248
|
+
* cached keys rather than blocked on the issuer.
|
|
249
|
+
*
|
|
250
|
+
* @returns The token with client/user/scope info, or `undefined` when the
|
|
251
|
+
* token is malformed, signed by an unknown or unaccepted key, or fails
|
|
252
|
+
* any claim check.
|
|
253
|
+
* @throws {TemporarilyUnavailableError} If the JWKS (or discovery
|
|
254
|
+
* document) is unreachable or returns a 5xx **and** no cached keys are
|
|
255
|
+
* available — a down issuer must be distinguishable from a genuinely
|
|
256
|
+
* invalid token, not collapsed into it. Once keys are cached, a failed
|
|
257
|
+
* refresh is absorbed and the cached keys keep serving.
|
|
258
|
+
* @throws {ServerError} If the JWKS endpoint returns a 4xx or a body that
|
|
259
|
+
* is not a JWKS, or discovery reports no `jwks_uri` — a
|
|
260
|
+
* misconfiguration, not a verdict on the caller's token.
|
|
261
|
+
*/
|
|
262
|
+
getToken(accessToken: string): Promise<Token<Client, User, S> | undefined>;
|
|
263
|
+
}
|