@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
package/esm/errors.d.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 error classes following RFC 6749.
|
|
3
|
+
*
|
|
4
|
+
* These error classes map to the OAuth2 error codes defined in:
|
|
5
|
+
* - RFC 6749 Section 4.1.2.1 (Authorization errors)
|
|
6
|
+
* - RFC 6749 Section 5.2 (Token errors)
|
|
7
|
+
* - RFC 6750 Section 3.1 (Bearer token errors)
|
|
8
|
+
* - RFC 8628 Section 3.5 (Device flow errors)
|
|
9
|
+
*
|
|
10
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
11
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { HttpError, type HttpErrorOptions } from "./deps/jsr.io/@udibo/http-error/0.11.1/mod.js";
|
|
15
|
+
/**
|
|
16
|
+
* Problem Details extension members carried by every {@linkcode OAuth2Error}.
|
|
17
|
+
*
|
|
18
|
+
* These map the standard OAuth2 error response fields (RFC 6749 Section 5.2)
|
|
19
|
+
* onto the error's `extensions` bag so they can be serialized in either the
|
|
20
|
+
* OAuth2 error format or the RFC 9457 Problem Details format.
|
|
21
|
+
*/
|
|
22
|
+
export interface OAuth2ProblemDetailsExtensions {
|
|
23
|
+
/** An ASCII error code. */
|
|
24
|
+
error?: string;
|
|
25
|
+
/** Human-readable error description. */
|
|
26
|
+
error_description?: string;
|
|
27
|
+
/** A URI identifying a human readable web page with information about the error. */
|
|
28
|
+
error_uri?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Constructor type for OAuth2 error classes produced by
|
|
32
|
+
* `createHttpErrorClass`. Declared explicitly so the exported error classes
|
|
33
|
+
* have a JSR-fast public type (the inferred type spans multiple constructor
|
|
34
|
+
* overloads and trips the `no-slow-types` rule).
|
|
35
|
+
*/
|
|
36
|
+
export type OAuth2ErrorClass<Extensions extends OAuth2ProblemDetailsExtensions = OAuth2ProblemDetailsExtensions> = {
|
|
37
|
+
new <E extends Extensions = Extensions>(status?: number, message?: string, options?: HttpErrorOptions<E>): HttpError<E>;
|
|
38
|
+
new <E extends Extensions = Extensions>(status?: number, options?: HttpErrorOptions<E>): HttpError<E>;
|
|
39
|
+
new <E extends Extensions = Extensions>(message?: string, options?: HttpErrorOptions<E>): HttpError<E>;
|
|
40
|
+
new <E extends Extensions = Extensions>(options?: HttpErrorOptions<E>): HttpError<E>;
|
|
41
|
+
prototype: HttpError<Extensions>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* An OAuth2 error: an {@linkcode HttpError} whose `extensions` carry the
|
|
45
|
+
* OAuth2 error fields described by {@linkcode OAuth2ProblemDetailsExtensions}.
|
|
46
|
+
* This is the common type for every error class in this module.
|
|
47
|
+
*/
|
|
48
|
+
export type OAuth2Error = HttpError<OAuth2ProblemDetailsExtensions>;
|
|
49
|
+
/**
|
|
50
|
+
* The base OAuth2 error class, an {@linkcode HttpError} subclass that defaults
|
|
51
|
+
* to the `server_error` code. Used as a catch-all and as the value-side
|
|
52
|
+
* companion of the {@linkcode OAuth2Error} type; prefer a specific subclass
|
|
53
|
+
* (e.g. {@linkcode InvalidRequestError}) when the condition is known.
|
|
54
|
+
*/
|
|
55
|
+
export declare const OAuth2Error: OAuth2ErrorClass;
|
|
56
|
+
/** Type guard for OAuth2 errors. */
|
|
57
|
+
export declare function isOAuth2Error(value: unknown): value is OAuth2Error;
|
|
58
|
+
/**
|
|
59
|
+
* Converts an arbitrary error into an {@link OAuth2Error}.
|
|
60
|
+
*
|
|
61
|
+
* If the input is already an OAuth2Error it is returned as-is; otherwise it is
|
|
62
|
+
* wrapped in a {@link ServerError} with the original error attached as `cause`.
|
|
63
|
+
*
|
|
64
|
+
* The returned error also has its `type` and `extensions.error_uri` synced so
|
|
65
|
+
* that if one is set the other is too. This lets both the standard OAuth2
|
|
66
|
+
* error format (which emits `error_uri`) and the RFC 9457 Problem Details
|
|
67
|
+
* format (which emits `type`) carry the same URI without the handler having to
|
|
68
|
+
* set both fields.
|
|
69
|
+
*/
|
|
70
|
+
export declare function toOAuth2Error(error: unknown): OAuth2Error;
|
|
71
|
+
/**
|
|
72
|
+
* The request is missing a required parameter, includes an unsupported parameter value,
|
|
73
|
+
* repeats a parameter, includes multiple credentials, utilizes more than one mechanism
|
|
74
|
+
* for authenticating the client, or is otherwise malformed.
|
|
75
|
+
*
|
|
76
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
77
|
+
*/
|
|
78
|
+
export declare const InvalidRequestError: OAuth2ErrorClass;
|
|
79
|
+
/**
|
|
80
|
+
* Client authentication failed.
|
|
81
|
+
*
|
|
82
|
+
* The authorization server MAY return an HTTP 401 (Unauthorized) status code
|
|
83
|
+
* to indicate which HTTP authentication schemes are supported.
|
|
84
|
+
*
|
|
85
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
86
|
+
*/
|
|
87
|
+
export declare const InvalidClientError: OAuth2ErrorClass;
|
|
88
|
+
/**
|
|
89
|
+
* The provided authorization grant or refresh token is invalid, expired, revoked,
|
|
90
|
+
* does not match the redirection URI used in the authorization request, or was issued to another client.
|
|
91
|
+
*
|
|
92
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
93
|
+
*/
|
|
94
|
+
export declare const InvalidGrantError: OAuth2ErrorClass;
|
|
95
|
+
/**
|
|
96
|
+
* The authenticated client is not authorized to use this authorization grant type.
|
|
97
|
+
*
|
|
98
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
99
|
+
*/
|
|
100
|
+
export declare const UnauthorizedClientError: OAuth2ErrorClass;
|
|
101
|
+
/**
|
|
102
|
+
* The token type is not supported by the authorization server.
|
|
103
|
+
*
|
|
104
|
+
* Used by the revocation endpoint (RFC 7009) when the server doesn't
|
|
105
|
+
* support revoking the presented token type.
|
|
106
|
+
*
|
|
107
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7009#section-2.2.1
|
|
108
|
+
*/
|
|
109
|
+
export declare const UnsupportedTokenTypeError: OAuth2ErrorClass;
|
|
110
|
+
/**
|
|
111
|
+
* The authorization grant type is not supported by the authorization server.
|
|
112
|
+
*
|
|
113
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
114
|
+
*/
|
|
115
|
+
export declare const UnsupportedGrantTypeError: OAuth2ErrorClass;
|
|
116
|
+
/**
|
|
117
|
+
* The resource owner or authorization server denied the request.
|
|
118
|
+
*
|
|
119
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
120
|
+
*/
|
|
121
|
+
export declare const AccessDeniedError: OAuth2ErrorClass;
|
|
122
|
+
/**
|
|
123
|
+
* The access token provided is expired, revoked, malformed, or invalid.
|
|
124
|
+
*
|
|
125
|
+
* Per RFC 6750, this error uses HTTP 401 status and should trigger
|
|
126
|
+
* a WWW-Authenticate header with the "invalid_token" error code.
|
|
127
|
+
*
|
|
128
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
129
|
+
*/
|
|
130
|
+
export declare const InvalidTokenError: OAuth2ErrorClass;
|
|
131
|
+
/**
|
|
132
|
+
* The request requires higher privileges than provided by the access token.
|
|
133
|
+
*
|
|
134
|
+
* Per RFC 6750, this error uses HTTP 403 status and should trigger
|
|
135
|
+
* a WWW-Authenticate header with the "insufficient_scope" error code
|
|
136
|
+
* and optionally a "requiredScope" extension indicating required scope.
|
|
137
|
+
*
|
|
138
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
139
|
+
*/
|
|
140
|
+
export declare const InsufficientScopeError: OAuth2ErrorClass<OAuth2ProblemDetailsExtensions & {
|
|
141
|
+
requiredScope?: string;
|
|
142
|
+
}>;
|
|
143
|
+
/**
|
|
144
|
+
* The request requires an authorization the subject does not hold — a
|
|
145
|
+
* permission, role, or organization context check failed on an otherwise
|
|
146
|
+
* valid token. HTTP 403 with a bare `realm` challenge: RFC 6750 registers no
|
|
147
|
+
* challenge code for this, so unlike {@link InsufficientScopeError} the
|
|
148
|
+
* `WWW-Authenticate` header names no error — the body carries
|
|
149
|
+
* `insufficient_permissions`.
|
|
150
|
+
*/
|
|
151
|
+
export declare const InsufficientPermissionsError: OAuth2ErrorClass;
|
|
152
|
+
/**
|
|
153
|
+
* The authorization server does not support obtaining an authorization code using this method.
|
|
154
|
+
*
|
|
155
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
156
|
+
*/
|
|
157
|
+
export declare const UnsupportedResponseTypeError: OAuth2ErrorClass;
|
|
158
|
+
/**
|
|
159
|
+
* The requested scope is invalid, unknown, or malformed.
|
|
160
|
+
*
|
|
161
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
162
|
+
*/
|
|
163
|
+
export declare const InvalidScopeError: OAuth2ErrorClass;
|
|
164
|
+
/**
|
|
165
|
+
* The authorization server encountered an unexpected condition that prevented it from fulfilling the request.
|
|
166
|
+
*
|
|
167
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
168
|
+
*/
|
|
169
|
+
export declare const ServerError: OAuth2ErrorClass;
|
|
170
|
+
/**
|
|
171
|
+
* The authorization server is currently unable to handle the request due to a temporary overloading or maintenance.
|
|
172
|
+
*
|
|
173
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
174
|
+
*/
|
|
175
|
+
export declare const TemporarilyUnavailableError: OAuth2ErrorClass;
|
|
176
|
+
/**
|
|
177
|
+
* The authorization request is still pending user approval.
|
|
178
|
+
*
|
|
179
|
+
* Used in the device authorization flow (RFC 8628) when the user
|
|
180
|
+
* has not yet authorized the request.
|
|
181
|
+
*
|
|
182
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
183
|
+
*/
|
|
184
|
+
export declare const AuthorizationPendingError: OAuth2ErrorClass;
|
|
185
|
+
/**
|
|
186
|
+
* The client is polling too frequently.
|
|
187
|
+
*
|
|
188
|
+
* Used in the device authorization flow (RFC 8628) when the client
|
|
189
|
+
* polls faster than the allowed interval. The client should increase
|
|
190
|
+
* its polling interval by 5 seconds.
|
|
191
|
+
*
|
|
192
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
193
|
+
*/
|
|
194
|
+
export declare const SlowDownError: OAuth2ErrorClass;
|
|
195
|
+
/**
|
|
196
|
+
* The device_code has expired.
|
|
197
|
+
*
|
|
198
|
+
* Used in the device authorization flow (RFC 8628) when the
|
|
199
|
+
* device code expires before the user authorizes the request.
|
|
200
|
+
*
|
|
201
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
202
|
+
*/
|
|
203
|
+
export declare const ExpiredTokenError: OAuth2ErrorClass;
|
package/esm/errors.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 error classes following RFC 6749.
|
|
3
|
+
*
|
|
4
|
+
* These error classes map to the OAuth2 error codes defined in:
|
|
5
|
+
* - RFC 6749 Section 4.1.2.1 (Authorization errors)
|
|
6
|
+
* - RFC 6749 Section 5.2 (Token errors)
|
|
7
|
+
* - RFC 6750 Section 3.1 (Bearer token errors)
|
|
8
|
+
* - RFC 8628 Section 3.5 (Device flow errors)
|
|
9
|
+
*
|
|
10
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
11
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { createHttpErrorClass, HttpError, } from "./deps/jsr.io/@udibo/http-error/0.11.1/mod.js";
|
|
15
|
+
/**
|
|
16
|
+
* The base OAuth2 error class, an {@linkcode HttpError} subclass that defaults
|
|
17
|
+
* to the `server_error` code. Used as a catch-all and as the value-side
|
|
18
|
+
* companion of the {@linkcode OAuth2Error} type; prefer a specific subclass
|
|
19
|
+
* (e.g. {@linkcode InvalidRequestError}) when the condition is known.
|
|
20
|
+
*/
|
|
21
|
+
export const OAuth2Error = createHttpErrorClass({
|
|
22
|
+
name: "OAuth2 Error",
|
|
23
|
+
extensions: {
|
|
24
|
+
error: "server_error",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
/** Type guard for OAuth2 errors. */
|
|
28
|
+
export function isOAuth2Error(value) {
|
|
29
|
+
return value instanceof HttpError && value.extensions.error !== undefined;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Converts an arbitrary error into an {@link OAuth2Error}.
|
|
33
|
+
*
|
|
34
|
+
* If the input is already an OAuth2Error it is returned as-is; otherwise it is
|
|
35
|
+
* wrapped in a {@link ServerError} with the original error attached as `cause`.
|
|
36
|
+
*
|
|
37
|
+
* The returned error also has its `type` and `extensions.error_uri` synced so
|
|
38
|
+
* that if one is set the other is too. This lets both the standard OAuth2
|
|
39
|
+
* error format (which emits `error_uri`) and the RFC 9457 Problem Details
|
|
40
|
+
* format (which emits `type`) carry the same URI without the handler having to
|
|
41
|
+
* set both fields.
|
|
42
|
+
*/
|
|
43
|
+
export function toOAuth2Error(error) {
|
|
44
|
+
const oauth2Error = isOAuth2Error(error)
|
|
45
|
+
? error
|
|
46
|
+
: new ServerError("unexpected error", { cause: error });
|
|
47
|
+
if (oauth2Error.type && !oauth2Error.extensions.error_uri) {
|
|
48
|
+
oauth2Error.extensions.error_uri = oauth2Error.type;
|
|
49
|
+
}
|
|
50
|
+
else if (oauth2Error.extensions.error_uri && !oauth2Error.type) {
|
|
51
|
+
oauth2Error.type = oauth2Error.extensions.error_uri;
|
|
52
|
+
}
|
|
53
|
+
return oauth2Error;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The request is missing a required parameter, includes an unsupported parameter value,
|
|
57
|
+
* repeats a parameter, includes multiple credentials, utilizes more than one mechanism
|
|
58
|
+
* for authenticating the client, or is otherwise malformed.
|
|
59
|
+
*
|
|
60
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
61
|
+
*/
|
|
62
|
+
export const InvalidRequestError = createHttpErrorClass({
|
|
63
|
+
name: "Invalid Request",
|
|
64
|
+
status: 400,
|
|
65
|
+
extensions: {
|
|
66
|
+
error: "invalid_request",
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* Client authentication failed.
|
|
71
|
+
*
|
|
72
|
+
* The authorization server MAY return an HTTP 401 (Unauthorized) status code
|
|
73
|
+
* to indicate which HTTP authentication schemes are supported.
|
|
74
|
+
*
|
|
75
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
76
|
+
*/
|
|
77
|
+
export const InvalidClientError = createHttpErrorClass({
|
|
78
|
+
name: "Invalid Client",
|
|
79
|
+
status: 401,
|
|
80
|
+
extensions: {
|
|
81
|
+
error: "invalid_client",
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* The provided authorization grant or refresh token is invalid, expired, revoked,
|
|
86
|
+
* does not match the redirection URI used in the authorization request, or was issued to another client.
|
|
87
|
+
*
|
|
88
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
89
|
+
*/
|
|
90
|
+
export const InvalidGrantError = createHttpErrorClass({
|
|
91
|
+
name: "Invalid Grant",
|
|
92
|
+
status: 400,
|
|
93
|
+
extensions: {
|
|
94
|
+
error: "invalid_grant",
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* The authenticated client is not authorized to use this authorization grant type.
|
|
99
|
+
*
|
|
100
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
101
|
+
*/
|
|
102
|
+
export const UnauthorizedClientError = createHttpErrorClass({
|
|
103
|
+
name: "Unauthorized Client",
|
|
104
|
+
status: 401,
|
|
105
|
+
extensions: {
|
|
106
|
+
error: "unauthorized_client",
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
/**
|
|
110
|
+
* The token type is not supported by the authorization server.
|
|
111
|
+
*
|
|
112
|
+
* Used by the revocation endpoint (RFC 7009) when the server doesn't
|
|
113
|
+
* support revoking the presented token type.
|
|
114
|
+
*
|
|
115
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7009#section-2.2.1
|
|
116
|
+
*/
|
|
117
|
+
export const UnsupportedTokenTypeError = createHttpErrorClass({
|
|
118
|
+
name: "Unsupported Token Type",
|
|
119
|
+
status: 400,
|
|
120
|
+
extensions: {
|
|
121
|
+
error: "unsupported_token_type",
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
125
|
+
* The authorization grant type is not supported by the authorization server.
|
|
126
|
+
*
|
|
127
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
128
|
+
*/
|
|
129
|
+
export const UnsupportedGrantTypeError = createHttpErrorClass({
|
|
130
|
+
name: "Unsupported Grant Type",
|
|
131
|
+
status: 400,
|
|
132
|
+
extensions: {
|
|
133
|
+
error: "unsupported_grant_type",
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* The resource owner or authorization server denied the request.
|
|
138
|
+
*
|
|
139
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
140
|
+
*/
|
|
141
|
+
export const AccessDeniedError = createHttpErrorClass({
|
|
142
|
+
name: "Access Denied",
|
|
143
|
+
status: 401,
|
|
144
|
+
extensions: {
|
|
145
|
+
error: "access_denied",
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
/**
|
|
149
|
+
* The access token provided is expired, revoked, malformed, or invalid.
|
|
150
|
+
*
|
|
151
|
+
* Per RFC 6750, this error uses HTTP 401 status and should trigger
|
|
152
|
+
* a WWW-Authenticate header with the "invalid_token" error code.
|
|
153
|
+
*
|
|
154
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
155
|
+
*/
|
|
156
|
+
export const InvalidTokenError = createHttpErrorClass({
|
|
157
|
+
name: "Invalid Token",
|
|
158
|
+
status: 401,
|
|
159
|
+
extensions: {
|
|
160
|
+
error: "invalid_token",
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
/**
|
|
164
|
+
* The request requires higher privileges than provided by the access token.
|
|
165
|
+
*
|
|
166
|
+
* Per RFC 6750, this error uses HTTP 403 status and should trigger
|
|
167
|
+
* a WWW-Authenticate header with the "insufficient_scope" error code
|
|
168
|
+
* and optionally a "requiredScope" extension indicating required scope.
|
|
169
|
+
*
|
|
170
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
171
|
+
*/
|
|
172
|
+
export const InsufficientScopeError = createHttpErrorClass({
|
|
173
|
+
name: "Insufficient Scope",
|
|
174
|
+
status: 403,
|
|
175
|
+
extensions: {
|
|
176
|
+
error: "insufficient_scope",
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
/**
|
|
180
|
+
* The request requires an authorization the subject does not hold — a
|
|
181
|
+
* permission, role, or organization context check failed on an otherwise
|
|
182
|
+
* valid token. HTTP 403 with a bare `realm` challenge: RFC 6750 registers no
|
|
183
|
+
* challenge code for this, so unlike {@link InsufficientScopeError} the
|
|
184
|
+
* `WWW-Authenticate` header names no error — the body carries
|
|
185
|
+
* `insufficient_permissions`.
|
|
186
|
+
*/
|
|
187
|
+
export const InsufficientPermissionsError = createHttpErrorClass({
|
|
188
|
+
name: "Insufficient Permissions",
|
|
189
|
+
status: 403,
|
|
190
|
+
extensions: {
|
|
191
|
+
error: "insufficient_permissions",
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
/**
|
|
195
|
+
* The authorization server does not support obtaining an authorization code using this method.
|
|
196
|
+
*
|
|
197
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
198
|
+
*/
|
|
199
|
+
export const UnsupportedResponseTypeError = createHttpErrorClass({
|
|
200
|
+
name: "Unsupported Response Type",
|
|
201
|
+
status: 400,
|
|
202
|
+
extensions: {
|
|
203
|
+
error: "unsupported_response_type",
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
/**
|
|
207
|
+
* The requested scope is invalid, unknown, or malformed.
|
|
208
|
+
*
|
|
209
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
210
|
+
*/
|
|
211
|
+
export const InvalidScopeError = createHttpErrorClass({
|
|
212
|
+
name: "Invalid Scope",
|
|
213
|
+
status: 400,
|
|
214
|
+
extensions: {
|
|
215
|
+
error: "invalid_scope",
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
/**
|
|
219
|
+
* The authorization server encountered an unexpected condition that prevented it from fulfilling the request.
|
|
220
|
+
*
|
|
221
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
222
|
+
*/
|
|
223
|
+
export const ServerError = createHttpErrorClass({
|
|
224
|
+
name: "Server Error",
|
|
225
|
+
status: 500,
|
|
226
|
+
extensions: {
|
|
227
|
+
error: "server_error",
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
/**
|
|
231
|
+
* The authorization server is currently unable to handle the request due to a temporary overloading or maintenance.
|
|
232
|
+
*
|
|
233
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
234
|
+
*/
|
|
235
|
+
export const TemporarilyUnavailableError = createHttpErrorClass({
|
|
236
|
+
name: "Temporarily Unavailable",
|
|
237
|
+
status: 503,
|
|
238
|
+
extensions: {
|
|
239
|
+
error: "temporarily_unavailable",
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
/**
|
|
243
|
+
* The authorization request is still pending user approval.
|
|
244
|
+
*
|
|
245
|
+
* Used in the device authorization flow (RFC 8628) when the user
|
|
246
|
+
* has not yet authorized the request.
|
|
247
|
+
*
|
|
248
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
249
|
+
*/
|
|
250
|
+
export const AuthorizationPendingError = createHttpErrorClass({
|
|
251
|
+
name: "Authorization Pending",
|
|
252
|
+
status: 400,
|
|
253
|
+
extensions: {
|
|
254
|
+
error: "authorization_pending",
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
/**
|
|
258
|
+
* The client is polling too frequently.
|
|
259
|
+
*
|
|
260
|
+
* Used in the device authorization flow (RFC 8628) when the client
|
|
261
|
+
* polls faster than the allowed interval. The client should increase
|
|
262
|
+
* its polling interval by 5 seconds.
|
|
263
|
+
*
|
|
264
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
265
|
+
*/
|
|
266
|
+
export const SlowDownError = createHttpErrorClass({
|
|
267
|
+
name: "Slow Down",
|
|
268
|
+
status: 400,
|
|
269
|
+
extensions: {
|
|
270
|
+
error: "slow_down",
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
/**
|
|
274
|
+
* The device_code has expired.
|
|
275
|
+
*
|
|
276
|
+
* Used in the device authorization flow (RFC 8628) when the
|
|
277
|
+
* device code expires before the user authorizes the request.
|
|
278
|
+
*
|
|
279
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
280
|
+
*/
|
|
281
|
+
export const ExpiredTokenError = createHttpErrorClass({
|
|
282
|
+
name: "Expired Token",
|
|
283
|
+
status: 400,
|
|
284
|
+
extensions: {
|
|
285
|
+
error: "expired_token",
|
|
286
|
+
},
|
|
287
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bring-your-own bot-challenge verification for auth endpoints — the CAPTCHA
|
|
3
|
+
* analogue of the {@link RateLimiterLike} seam. {@link CaptchaProvider} is the
|
|
4
|
+
* contract a client-issued challenge token is verified against server-side;
|
|
5
|
+
* Cloudflare Turnstile, hCaptcha, and reCAPTCHA all satisfy it, so nothing here
|
|
6
|
+
* depends on a vendor SDK. {@link verifyCaptcha} composes a provider with the
|
|
7
|
+
* fail-open/closed discipline a login flow needs: a missing or rejected token
|
|
8
|
+
* is a refusal, but a provider *outage* degrades to your existing rate-limit and
|
|
9
|
+
* lockout floor rather than locking everyone out.
|
|
10
|
+
*
|
|
11
|
+
* Tenant-agnostic: scope by passing whatever `action` and `ip` your provider
|
|
12
|
+
* scores on. **No provider means no challenge** — {@link verifyCaptcha} passes
|
|
13
|
+
* every request, so wiring the seam without configuring a provider changes
|
|
14
|
+
* nothing about existing behavior.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
/** What a {@link CaptchaProvider} is told about the request it is scoring. */
|
|
19
|
+
export interface CaptchaVerifyContext {
|
|
20
|
+
/**
|
|
21
|
+
* The caller's IP, for providers that fold network reputation into the score
|
|
22
|
+
* (Turnstile's `remoteip`, reCAPTCHA's `remoteip`). Omit when unknown.
|
|
23
|
+
*/
|
|
24
|
+
ip?: string;
|
|
25
|
+
/**
|
|
26
|
+
* The flow the token was issued for (`"signup"`, `"signin"`, …). Providers
|
|
27
|
+
* that bind a token to an action (reCAPTCHA v3, Turnstile `action`) verify it
|
|
28
|
+
* against this; providers that don't may ignore it.
|
|
29
|
+
*/
|
|
30
|
+
action?: string;
|
|
31
|
+
}
|
|
32
|
+
/** The outcome of a {@link CaptchaProvider.verify}. */
|
|
33
|
+
export interface CaptchaVerifyResult {
|
|
34
|
+
/**
|
|
35
|
+
* Whether the token is a valid, unspent solution to a real challenge. `false`
|
|
36
|
+
* is a genuine rejection (forged, replayed, or expired token) — the caller
|
|
37
|
+
* refuses the request. Reserve *throwing* for the provider being unreachable
|
|
38
|
+
* so {@link verifyCaptcha} can tell a rejection apart from an outage.
|
|
39
|
+
*/
|
|
40
|
+
success: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* The provider's confidence in `[0, 1]` when it scores (reCAPTCHA v3,
|
|
43
|
+
* Turnstile enterprise), higher meaning more likely human. Omit for
|
|
44
|
+
* pass/fail providers. Surfaced for score-threshold tuning; {@link
|
|
45
|
+
* verifyCaptcha} decides purely on `success`.
|
|
46
|
+
*/
|
|
47
|
+
score?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The seam a bot-challenge vendor plugs into: verify one client-issued token
|
|
51
|
+
* server-side and report pass/fail. The package ships **no** provider — bring
|
|
52
|
+
* your own: implement this against your provider's siteverify endpoint (a
|
|
53
|
+
* single HTTPS POST, as in the example below — Turnstile, hCaptcha, and
|
|
54
|
+
* reCAPTCHA all take that shape) or against an enterprise bot-detection service
|
|
55
|
+
* you already run. Wire the result through {@link verifyCaptcha} for the
|
|
56
|
+
* fail-open/closed handling, and reject a `"fail"` decision with
|
|
57
|
+
* `IdentityError` `captcha_failed`.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const provider: CaptchaProvider = {
|
|
62
|
+
* async verify(token, context) {
|
|
63
|
+
* const body = new URLSearchParams({ secret, response: token });
|
|
64
|
+
* if (context?.ip) body.set("remoteip", context.ip);
|
|
65
|
+
* const res = await fetch(SITEVERIFY, { method: "POST", body });
|
|
66
|
+
* if (!res.ok) throw new Error(`siteverify ${res.status}`); // outage
|
|
67
|
+
* const data = await res.json() as { success: boolean };
|
|
68
|
+
* return { success: data.success };
|
|
69
|
+
* },
|
|
70
|
+
* };
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export interface CaptchaProvider {
|
|
74
|
+
/**
|
|
75
|
+
* Verify `token` server-side. Resolve `{ success: false }` for a genuine
|
|
76
|
+
* rejection; **throw** when the provider cannot be reached (network error,
|
|
77
|
+
* non-2xx) so an outage is distinguishable from a rejection.
|
|
78
|
+
*/
|
|
79
|
+
verify(token: string, context?: CaptchaVerifyContext): Promise<CaptchaVerifyResult>;
|
|
80
|
+
}
|
|
81
|
+
/** The decision {@link verifyCaptcha} returns. */
|
|
82
|
+
export interface CaptchaOutcome {
|
|
83
|
+
/** `"pass"` lets the flow proceed; `"fail"` is a refusal. */
|
|
84
|
+
decision: "pass" | "fail";
|
|
85
|
+
/**
|
|
86
|
+
* Whether a provider actually evaluated a token. `false` means no provider
|
|
87
|
+
* was configured (the request passes unchallenged) — distinct from a `"pass"`
|
|
88
|
+
* a provider granted.
|
|
89
|
+
*/
|
|
90
|
+
challenged: boolean;
|
|
91
|
+
/** The provider's {@link CaptchaVerifyResult.score}, when it returned one. */
|
|
92
|
+
score?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Whether the provider could not be reached, so this outcome came from the
|
|
95
|
+
* `failOpen` policy rather than a real evaluation — `true` on both the
|
|
96
|
+
* fail-open `"pass"` and the fail-closed `"fail"`. Audit it: a degraded pass
|
|
97
|
+
* is the window where only your rate-limit/lockout floor is protecting the
|
|
98
|
+
* endpoint, and a run of degraded fails is an outage locking users out.
|
|
99
|
+
*/
|
|
100
|
+
degraded: boolean;
|
|
101
|
+
}
|
|
102
|
+
/** Options for {@link verifyCaptcha}. */
|
|
103
|
+
export interface VerifyCaptchaOptions {
|
|
104
|
+
/**
|
|
105
|
+
* The provider to verify against. `undefined` disables the challenge
|
|
106
|
+
* entirely — {@link verifyCaptcha} returns an unchallenged `"pass"`.
|
|
107
|
+
*/
|
|
108
|
+
provider: CaptchaProvider | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* The client-issued token from the request. A missing/empty token with a
|
|
111
|
+
* provider configured is a `"fail"` (the challenge was required and not
|
|
112
|
+
* answered).
|
|
113
|
+
*/
|
|
114
|
+
token: string | null | undefined;
|
|
115
|
+
/** Passed through to {@link CaptchaProvider.verify}. */
|
|
116
|
+
context?: CaptchaVerifyContext;
|
|
117
|
+
/**
|
|
118
|
+
* What to do when the provider throws (an outage). `true` (the default)
|
|
119
|
+
* fails open — the request passes with `degraded: true` — so a provider
|
|
120
|
+
* outage falls back to your rate-limit/lockout floor instead of blocking
|
|
121
|
+
* every user. `false` fails closed for a tenant that would rather refuse than
|
|
122
|
+
* degrade.
|
|
123
|
+
*/
|
|
124
|
+
failOpen?: boolean;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Verify a client-issued CAPTCHA token with the fail-open/closed discipline an
|
|
128
|
+
* auth endpoint needs, and return a {@link CaptchaOutcome}.
|
|
129
|
+
*
|
|
130
|
+
* - **No provider** → unchallenged `"pass"` (`challenged: false`).
|
|
131
|
+
* - **Missing/empty token** → `"fail"` (the challenge went unanswered).
|
|
132
|
+
* - **Provider `{ success }`** → `"pass"`/`"fail"` accordingly.
|
|
133
|
+
* - **Provider throws (outage)** → `failOpen` decides `"pass"` or `"fail"`;
|
|
134
|
+
* either way the outcome is `degraded: true`, because no token was really
|
|
135
|
+
* evaluated.
|
|
136
|
+
*
|
|
137
|
+
* Never throws — a broken provider becomes a decision, not an exception the
|
|
138
|
+
* route must catch. Compose the result with your rate limiter and lockout; this
|
|
139
|
+
* does not replace them.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* const outcome = await verifyCaptcha({ provider, token, context: { ip, action: "signin" } });
|
|
144
|
+
* if (outcome.decision === "fail") return uniformRejection();
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare function verifyCaptcha(options: VerifyCaptchaOptions): Promise<CaptchaOutcome>;
|