@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,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PKCE (Proof Key for Code Exchange) utilities for OAuth2.
|
|
3
|
+
*
|
|
4
|
+
* Implements RFC 7636 for preventing authorization code interception attacks.
|
|
5
|
+
*
|
|
6
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { encodeBase64Url } from "../deps/jsr.io/@std/encoding/1.0.11/base64url.js";
|
|
10
|
+
/**
|
|
11
|
+
* Minimum length for code verifier per RFC 7636 Section 4.1.
|
|
12
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
|
13
|
+
*/
|
|
14
|
+
export const CODE_VERIFIER_MIN_LENGTH = 43;
|
|
15
|
+
/**
|
|
16
|
+
* Maximum length for code verifier per RFC 7636 Section 4.1.
|
|
17
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
|
18
|
+
*/
|
|
19
|
+
export const CODE_VERIFIER_MAX_LENGTH = 128;
|
|
20
|
+
/**
|
|
21
|
+
* Pattern for valid code verifier characters per RFC 7636 Section 4.1.
|
|
22
|
+
* Allowed characters: [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
|
|
23
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
|
24
|
+
*/
|
|
25
|
+
export const CODE_VERIFIER_PATTERN = /^[A-Za-z0-9\-._~]+$/;
|
|
26
|
+
/**
|
|
27
|
+
* The default allowed PKCE code challenge methods.
|
|
28
|
+
*
|
|
29
|
+
* Per RFC 7636 and OAuth 2.1, clients SHOULD use the S256 method.
|
|
30
|
+
* The "plain" method is NOT included by default as it provides
|
|
31
|
+
* weaker security guarantees.
|
|
32
|
+
*
|
|
33
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.2
|
|
34
|
+
* @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-2.1.1
|
|
35
|
+
*/
|
|
36
|
+
export const challengeMethods = {
|
|
37
|
+
S256: async (verifier) => {
|
|
38
|
+
const data = new TextEncoder().encode(verifier);
|
|
39
|
+
const buffer = await crypto.subtle.digest("SHA-256", data);
|
|
40
|
+
return encodeBase64Url(new Uint8Array(buffer));
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Validates a code verifier per RFC 7636 Section 4.1.
|
|
45
|
+
*
|
|
46
|
+
* The code verifier must:
|
|
47
|
+
* - Be between 43 and 128 characters long
|
|
48
|
+
* - Contain only unreserved characters: [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
|
|
49
|
+
*
|
|
50
|
+
* @param verifier The code verifier to validate
|
|
51
|
+
* @returns true if the verifier is valid
|
|
52
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
|
53
|
+
*/
|
|
54
|
+
export function validateCodeVerifier(verifier) {
|
|
55
|
+
if (verifier.length < CODE_VERIFIER_MIN_LENGTH ||
|
|
56
|
+
verifier.length > CODE_VERIFIER_MAX_LENGTH) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return CODE_VERIFIER_PATTERN.test(verifier);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Generates a random code verifier with a minimum of 256 bits of entropy.
|
|
63
|
+
*
|
|
64
|
+
* This is done by generating a random 32-octet sequence then base64url encoding it
|
|
65
|
+
* to produce a 43 character URL-safe string.
|
|
66
|
+
*
|
|
67
|
+
* @returns A cryptographically random code verifier
|
|
68
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
|
69
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-7.1
|
|
70
|
+
*/
|
|
71
|
+
export function generateCodeVerifier() {
|
|
72
|
+
const sequence = new Uint8Array(32);
|
|
73
|
+
crypto.getRandomValues(sequence);
|
|
74
|
+
return encodeBase64Url(sequence);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Generates a code challenge from a code verifier using the S256 method.
|
|
78
|
+
*
|
|
79
|
+
* The S256 challenge is: BASE64URL(SHA256(ASCII(code_verifier)))
|
|
80
|
+
*
|
|
81
|
+
* @param verifier The code verifier to transform
|
|
82
|
+
* @returns The code challenge
|
|
83
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.2
|
|
84
|
+
*/
|
|
85
|
+
export async function generateCodeChallenge(verifier) {
|
|
86
|
+
return await challengeMethods.S256(verifier);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Validates a `code_challenge` per RFC 7636 Section 4.2, for the challenge
|
|
90
|
+
* methods whose output shape that section fixes.
|
|
91
|
+
*
|
|
92
|
+
* `S256` and `plain` are the only methods the PKCE registry defines, and both
|
|
93
|
+
* produce a challenge drawn from the same 43-128 unreserved characters as a
|
|
94
|
+
* code verifier, so an authorization endpoint can reject a malformed challenge
|
|
95
|
+
* before it is ever stored. Any other `method` — one a server registered in its
|
|
96
|
+
* own {@link ChallengeMethods} map — may legitimately produce any shape, so
|
|
97
|
+
* this returns `true` for it rather than imposing a format its author never
|
|
98
|
+
* agreed to. Check the name is allowed with {@linkcode getChallengeMethod}
|
|
99
|
+
* first; this answers only for the format.
|
|
100
|
+
*
|
|
101
|
+
* @param challenge The client-supplied `code_challenge`
|
|
102
|
+
* @param method The client-supplied `code_challenge_method`; defaults to `S256`
|
|
103
|
+
* @returns true when the challenge is acceptable for that method
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* validateCodeChallenge("a".repeat(43)); // → true
|
|
107
|
+
* validateCodeChallenge("short"); // → false
|
|
108
|
+
* validateCodeChallenge("short", "custom-method"); // → true
|
|
109
|
+
* ```
|
|
110
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.2
|
|
111
|
+
*/
|
|
112
|
+
export function validateCodeChallenge(challenge, method) {
|
|
113
|
+
const name = method ?? "S256";
|
|
114
|
+
if (name !== "S256" && name !== "plain")
|
|
115
|
+
return true;
|
|
116
|
+
return validateCodeVerifier(challenge);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolves a client-supplied `code_challenge_method` name against the methods
|
|
120
|
+
* a server allows.
|
|
121
|
+
*
|
|
122
|
+
* Reach for this instead of indexing a {@link ChallengeMethods} map directly.
|
|
123
|
+
* The name comes off the wire, and a map written as a plain object literal
|
|
124
|
+
* also inherits `toString`, `valueOf`, `constructor` and friends from
|
|
125
|
+
* `Object.prototype` — a bare lookup hands those back as if the server had
|
|
126
|
+
* allowed them, which downgrades PKCE to a value any verifier satisfies. Only
|
|
127
|
+
* own, callable properties of `methods` resolve here; every other name is
|
|
128
|
+
* `undefined`, including names inherited from a prototype.
|
|
129
|
+
*
|
|
130
|
+
* @param methods The challenge methods the server allows
|
|
131
|
+
* @param method The client-supplied method name; defaults to `S256`
|
|
132
|
+
* @returns The transform for that method, or `undefined` when it is not allowed
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* getChallengeMethod(challengeMethods, "S256"); // → the S256 transform
|
|
136
|
+
* getChallengeMethod(challengeMethods); // → the S256 transform
|
|
137
|
+
* getChallengeMethod(challengeMethods, "toString"); // → undefined
|
|
138
|
+
* getChallengeMethod(challengeMethods, "__proto__"); // → undefined
|
|
139
|
+
* ```
|
|
140
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.3
|
|
141
|
+
*/
|
|
142
|
+
export function getChallengeMethod(methods, method) {
|
|
143
|
+
const name = method ?? "S256";
|
|
144
|
+
if (!Object.hasOwn(methods, name))
|
|
145
|
+
return undefined;
|
|
146
|
+
const challengeMethod = methods[name];
|
|
147
|
+
return typeof challengeMethod === "function" ? challengeMethod : undefined;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Verifies that a code verifier matches a code challenge.
|
|
151
|
+
*
|
|
152
|
+
* Fails closed against the default {@link challengeMethods} map only: a
|
|
153
|
+
* `method` that map does not hold — `"plain"`, a name inherited from
|
|
154
|
+
* `Object.prototype` such as `"toString"`, or one registered on a grant via
|
|
155
|
+
* its own `challengeMethods` — resolves `false` rather than throwing, so it is
|
|
156
|
+
* indistinguishable from a mismatched verifier.
|
|
157
|
+
*
|
|
158
|
+
* @param verifier The code verifier provided by the client
|
|
159
|
+
* @param challenge The code challenge stored from the authorization request
|
|
160
|
+
* @param method The challenge method used (defaults to S256)
|
|
161
|
+
* @returns true if the verifier matches the challenge
|
|
162
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.6
|
|
163
|
+
*/
|
|
164
|
+
export async function verifyCodeChallenge(verifier, challenge, method = "S256") {
|
|
165
|
+
const challengeMethod = getChallengeMethod(challengeMethods, method);
|
|
166
|
+
if (!challengeMethod)
|
|
167
|
+
return false;
|
|
168
|
+
const expected = await challengeMethod(verifier);
|
|
169
|
+
return expected === challenge;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Generates a random state parameter for CSRF protection.
|
|
173
|
+
*
|
|
174
|
+
* @returns A random UUID to use as the state parameter
|
|
175
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-10.12
|
|
176
|
+
*/
|
|
177
|
+
export function generateState() {
|
|
178
|
+
return crypto.randomUUID();
|
|
179
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounding and flattening for text a remote server chose.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `utils/` rather than beside either caller because both ladders that
|
|
5
|
+
* turn a server's bytes into an error message — the client's `_http.ts` and
|
|
6
|
+
* the connectors' `_token-exchange.ts` — must sanitize identically, and the
|
|
7
|
+
* client cannot reach up into `identity/external/`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
/** Characters of remote-supplied text kept in an error message. */
|
|
12
|
+
export declare const PROVIDER_TEXT_MAX_LENGTH = 200;
|
|
13
|
+
/**
|
|
14
|
+
* Bounds and flattens a remote-supplied string for inclusion in an error
|
|
15
|
+
* message. Control characters become spaces so a hostile `error_description`
|
|
16
|
+
* cannot forge a log line or inject an ANSI escape in a consumer's console,
|
|
17
|
+
* the result is capped at {@link PROVIDER_TEXT_MAX_LENGTH}, and a surrogate
|
|
18
|
+
* pair split by that cap is repaired rather than left lone. Use this on
|
|
19
|
+
* every byte a remote server chose that reaches a message.
|
|
20
|
+
*
|
|
21
|
+
* @param value The remote-supplied text.
|
|
22
|
+
* @returns The flattened, capped, well-formed text.
|
|
23
|
+
*/
|
|
24
|
+
export declare function sanitizeProviderText(value: string): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounding and flattening for text a remote server chose.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `utils/` rather than beside either caller because both ladders that
|
|
5
|
+
* turn a server's bytes into an error message — the client's `_http.ts` and
|
|
6
|
+
* the connectors' `_token-exchange.ts` — must sanitize identically, and the
|
|
7
|
+
* client cannot reach up into `identity/external/`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
/** Characters of remote-supplied text kept in an error message. */
|
|
12
|
+
export const PROVIDER_TEXT_MAX_LENGTH = 200;
|
|
13
|
+
/**
|
|
14
|
+
* Bounds and flattens a remote-supplied string for inclusion in an error
|
|
15
|
+
* message. Control characters become spaces so a hostile `error_description`
|
|
16
|
+
* cannot forge a log line or inject an ANSI escape in a consumer's console,
|
|
17
|
+
* the result is capped at {@link PROVIDER_TEXT_MAX_LENGTH}, and a surrogate
|
|
18
|
+
* pair split by that cap is repaired rather than left lone. Use this on
|
|
19
|
+
* every byte a remote server chose that reaches a message.
|
|
20
|
+
*
|
|
21
|
+
* @param value The remote-supplied text.
|
|
22
|
+
* @returns The flattened, capped, well-formed text.
|
|
23
|
+
*/
|
|
24
|
+
export function sanitizeProviderText(value) {
|
|
25
|
+
// deno-lint-ignore no-control-regex
|
|
26
|
+
const flattened = value.replace(/[\u0000-\u001F\u007F-\u009F]+/g, " ");
|
|
27
|
+
return flattened.trim().slice(0, PROVIDER_TEXT_MAX_LENGTH).toWellFormed();
|
|
28
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL safety helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import "../_dnt.polyfills.js";
|
|
7
|
+
/**
|
|
8
|
+
* Open-redirect guard for a `return_to` / redirect target.
|
|
9
|
+
*
|
|
10
|
+
* Returns `value` only when it is a safe in-app destination: a path beginning
|
|
11
|
+
* with a single `/` that still resolves to the current origin. This rejects
|
|
12
|
+
* absolute URLs, protocol-relative `//evil.com`, backslash `/\evil.com` tricks
|
|
13
|
+
* that some browsers resolve as a host, and any value containing a C0 control
|
|
14
|
+
* character or `DEL` — browsers strip TAB/CR/LF before parsing a URL, so
|
|
15
|
+
* `/<TAB>/evil.com` would otherwise navigate to `evil.com`. Anything else
|
|
16
|
+
* collapses to `fallback` (default `/`).
|
|
17
|
+
*
|
|
18
|
+
* Percent-encoded control characters (`/%09/x`) are safe and pass through: a
|
|
19
|
+
* browser does not decode them before parsing, so they stay on the origin.
|
|
20
|
+
*
|
|
21
|
+
* Use this anywhere a user-influenced value — a `return_to` / `redirect` query
|
|
22
|
+
* param or form field — is fed into a redirect `Location`, so a crafted
|
|
23
|
+
* absolute target can't turn the (often post-authentication) redirect into an
|
|
24
|
+
* open redirect.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* safeReturnTo("/dashboard"); // → "/dashboard"
|
|
29
|
+
* safeReturnTo("https://evil.com"); // → "/"
|
|
30
|
+
* safeReturnTo("//evil.com"); // → "/"
|
|
31
|
+
* safeReturnTo("/\\evil.com"); // → "/"
|
|
32
|
+
* safeReturnTo("/\t/evil.com"); // → "/"
|
|
33
|
+
* safeReturnTo(undefined, "/home"); // → "/home"
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function safeReturnTo(value: string | null | undefined, fallback?: string): string;
|
|
37
|
+
/** Options for {@link loginContinuation}. */
|
|
38
|
+
export interface LoginContinuationOptions {
|
|
39
|
+
/**
|
|
40
|
+
* The authorization endpoint (absolute URL or path). When `returnTo` points at
|
|
41
|
+
* it, the flow is **resumed** (the in-flight authorize request already has a
|
|
42
|
+
* PKCE `state`). Omit it and every `returnTo` starts a fresh login.
|
|
43
|
+
*/
|
|
44
|
+
authorizeEndpoint?: string;
|
|
45
|
+
/** The login path to start a fresh login. Defaults to `"/auth/login"`. */
|
|
46
|
+
loginPath?: string;
|
|
47
|
+
/** Fallback when `returnTo` is missing/unsafe. Defaults to `"/"`. */
|
|
48
|
+
defaultReturnTo?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The URL that (re)starts sign-in toward `returnTo`, for an app that owns its
|
|
52
|
+
* login surface and needs to hand back to the OAuth2/BFF flow after it
|
|
53
|
+
* authenticates a user.
|
|
54
|
+
*
|
|
55
|
+
* - When `returnTo` is an **in-flight authorize URL** (its path equals
|
|
56
|
+
* `authorizeEndpoint`'s path — the user was bounced mid-authorize with `state`
|
|
57
|
+
* already minted), it is returned unchanged so the flow **resumes** without a
|
|
58
|
+
* redundant login hop.
|
|
59
|
+
* - Otherwise it returns `${loginPath}?return_to=<returnTo>` to **start** a fresh
|
|
60
|
+
* login.
|
|
61
|
+
*
|
|
62
|
+
* Pure and client-safe — the same logic behind `HonoBff.loginContinuation`
|
|
63
|
+
* (server) and `BffClient.loginContinuation` (browser). `returnTo` is
|
|
64
|
+
* open-redirect-guarded via {@link safeReturnTo}.
|
|
65
|
+
*/
|
|
66
|
+
export declare function loginContinuation(returnTo: string | null | undefined, options?: LoginContinuationOptions): string;
|
package/esm/utils/url.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL safety helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import "../_dnt.polyfills.js";
|
|
7
|
+
const RESOLUTION_ORIGIN = "http://safe-return-to.invalid";
|
|
8
|
+
function hasControlCharacter(value) {
|
|
9
|
+
for (let index = 0; index < value.length; index++) {
|
|
10
|
+
const code = value.charCodeAt(index);
|
|
11
|
+
if (code <= 0x1f || code === 0x7f)
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Open-redirect guard for a `return_to` / redirect target.
|
|
18
|
+
*
|
|
19
|
+
* Returns `value` only when it is a safe in-app destination: a path beginning
|
|
20
|
+
* with a single `/` that still resolves to the current origin. This rejects
|
|
21
|
+
* absolute URLs, protocol-relative `//evil.com`, backslash `/\evil.com` tricks
|
|
22
|
+
* that some browsers resolve as a host, and any value containing a C0 control
|
|
23
|
+
* character or `DEL` — browsers strip TAB/CR/LF before parsing a URL, so
|
|
24
|
+
* `/<TAB>/evil.com` would otherwise navigate to `evil.com`. Anything else
|
|
25
|
+
* collapses to `fallback` (default `/`).
|
|
26
|
+
*
|
|
27
|
+
* Percent-encoded control characters (`/%09/x`) are safe and pass through: a
|
|
28
|
+
* browser does not decode them before parsing, so they stay on the origin.
|
|
29
|
+
*
|
|
30
|
+
* Use this anywhere a user-influenced value — a `return_to` / `redirect` query
|
|
31
|
+
* param or form field — is fed into a redirect `Location`, so a crafted
|
|
32
|
+
* absolute target can't turn the (often post-authentication) redirect into an
|
|
33
|
+
* open redirect.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* safeReturnTo("/dashboard"); // → "/dashboard"
|
|
38
|
+
* safeReturnTo("https://evil.com"); // → "/"
|
|
39
|
+
* safeReturnTo("//evil.com"); // → "/"
|
|
40
|
+
* safeReturnTo("/\\evil.com"); // → "/"
|
|
41
|
+
* safeReturnTo("/\t/evil.com"); // → "/"
|
|
42
|
+
* safeReturnTo(undefined, "/home"); // → "/home"
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function safeReturnTo(value, fallback = "/") {
|
|
46
|
+
if (!value || !value.startsWith("/"))
|
|
47
|
+
return fallback;
|
|
48
|
+
if (hasControlCharacter(value))
|
|
49
|
+
return fallback;
|
|
50
|
+
let resolved;
|
|
51
|
+
try {
|
|
52
|
+
resolved = new URL(value, RESOLUTION_ORIGIN);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return fallback;
|
|
56
|
+
}
|
|
57
|
+
if (resolved.origin !== RESOLUTION_ORIGIN)
|
|
58
|
+
return fallback;
|
|
59
|
+
if (resolved.pathname.startsWith("//"))
|
|
60
|
+
return fallback;
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The URL that (re)starts sign-in toward `returnTo`, for an app that owns its
|
|
65
|
+
* login surface and needs to hand back to the OAuth2/BFF flow after it
|
|
66
|
+
* authenticates a user.
|
|
67
|
+
*
|
|
68
|
+
* - When `returnTo` is an **in-flight authorize URL** (its path equals
|
|
69
|
+
* `authorizeEndpoint`'s path — the user was bounced mid-authorize with `state`
|
|
70
|
+
* already minted), it is returned unchanged so the flow **resumes** without a
|
|
71
|
+
* redundant login hop.
|
|
72
|
+
* - Otherwise it returns `${loginPath}?return_to=<returnTo>` to **start** a fresh
|
|
73
|
+
* login.
|
|
74
|
+
*
|
|
75
|
+
* Pure and client-safe — the same logic behind `HonoBff.loginContinuation`
|
|
76
|
+
* (server) and `BffClient.loginContinuation` (browser). `returnTo` is
|
|
77
|
+
* open-redirect-guarded via {@link safeReturnTo}.
|
|
78
|
+
*/
|
|
79
|
+
export function loginContinuation(returnTo, options = {}) {
|
|
80
|
+
const safe = safeReturnTo(returnTo, options.defaultReturnTo ?? "/");
|
|
81
|
+
if (options.authorizeEndpoint) {
|
|
82
|
+
// Compare path only so the in-flight authorize query (client_id, state, …)
|
|
83
|
+
// is preserved; the base lets absolute and relative inputs both resolve.
|
|
84
|
+
const base = "http://login.continuation.local";
|
|
85
|
+
const authorizePath = new URL(options.authorizeEndpoint, base).pathname;
|
|
86
|
+
if (new URL(safe, base).pathname === authorizePath)
|
|
87
|
+
return safe;
|
|
88
|
+
}
|
|
89
|
+
return `${options.loginPath ?? "/auth/login"}?return_to=${encodeURIComponent(safe)}`;
|
|
90
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@udibo/oauth2",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A flexible OAuth2 toolkit: framework-agnostic authorization & resource servers, a typed client, Hono adapters (including a backend-for-frontend), and React bindings.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/udibo/oauth2.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/udibo/oauth2/issues"
|
|
12
|
+
},
|
|
13
|
+
"module": "./esm/server/mod.js",
|
|
14
|
+
"exports": {
|
|
15
|
+
"./server": {
|
|
16
|
+
"import": "./esm/server/mod.js"
|
|
17
|
+
},
|
|
18
|
+
"./server/authorization": {
|
|
19
|
+
"import": "./esm/server/authorization-server.js"
|
|
20
|
+
},
|
|
21
|
+
"./server/resource": {
|
|
22
|
+
"import": "./esm/server/resource-server.js"
|
|
23
|
+
},
|
|
24
|
+
"./server/public-suffix": {
|
|
25
|
+
"import": "./esm/server/public-suffix/mod.js"
|
|
26
|
+
},
|
|
27
|
+
"./client": {
|
|
28
|
+
"import": "./esm/client/mod.js"
|
|
29
|
+
},
|
|
30
|
+
"./identity": {
|
|
31
|
+
"import": "./esm/identity/mod.js"
|
|
32
|
+
},
|
|
33
|
+
"./identity/external": {
|
|
34
|
+
"import": "./esm/identity/external/mod.js"
|
|
35
|
+
},
|
|
36
|
+
"./identity/mfa": {
|
|
37
|
+
"import": "./esm/identity/mfa/mod.js"
|
|
38
|
+
},
|
|
39
|
+
"./identity/migration": {
|
|
40
|
+
"import": "./esm/identity/migration.js"
|
|
41
|
+
},
|
|
42
|
+
"./hono/resource-server": {
|
|
43
|
+
"import": "./esm/adapters/hono/resource-server.js"
|
|
44
|
+
},
|
|
45
|
+
"./hono/authorization-server": {
|
|
46
|
+
"import": "./esm/adapters/hono/authorization-server.js"
|
|
47
|
+
},
|
|
48
|
+
"./hono/bff": {
|
|
49
|
+
"import": "./esm/adapters/hono/bff/mod.js"
|
|
50
|
+
},
|
|
51
|
+
"./hono/bff/testing": {
|
|
52
|
+
"import": "./esm/adapters/hono/bff/testing.js"
|
|
53
|
+
},
|
|
54
|
+
"./hono/identity": {
|
|
55
|
+
"import": "./esm/adapters/hono/identity.js"
|
|
56
|
+
},
|
|
57
|
+
"./hono/log": {
|
|
58
|
+
"import": "./esm/adapters/hono/log.js"
|
|
59
|
+
},
|
|
60
|
+
"./react": {
|
|
61
|
+
"import": "./esm/react/mod.js"
|
|
62
|
+
},
|
|
63
|
+
"./react/components": {
|
|
64
|
+
"import": "./esm/react/components/mod.js"
|
|
65
|
+
},
|
|
66
|
+
"./react/testing": {
|
|
67
|
+
"import": "./esm/react/testing.js"
|
|
68
|
+
},
|
|
69
|
+
"./testing": {
|
|
70
|
+
"import": "./esm/testing/mod.js"
|
|
71
|
+
},
|
|
72
|
+
"./testing/contract": {
|
|
73
|
+
"import": "./esm/testing/contract/mod.js"
|
|
74
|
+
},
|
|
75
|
+
"./crypto": {
|
|
76
|
+
"import": "./esm/utils/crypto.js"
|
|
77
|
+
},
|
|
78
|
+
"./url": {
|
|
79
|
+
"import": "./esm/utils/url.js"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"scripts": {},
|
|
83
|
+
"publishConfig": {
|
|
84
|
+
"access": "public"
|
|
85
|
+
},
|
|
86
|
+
"dependencies": {
|
|
87
|
+
"@types/react": "^19.2.17",
|
|
88
|
+
"hono": "^4.7.0",
|
|
89
|
+
"react": "^19.0.0"
|
|
90
|
+
},
|
|
91
|
+
"_generatedBy": "dnt@0.43.2"
|
|
92
|
+
}
|