@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,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The surface {@link BffClient} and {@link DirectClient} share: subscribing to
|
|
3
|
+
* authentication events, starting and ending a login, reading the current
|
|
4
|
+
* session, and issuing authenticated requests.
|
|
5
|
+
*
|
|
6
|
+
* Program against {@link OAuth2ClientBase} when the code shouldn't care which
|
|
7
|
+
* transport holds the tokens — the React adapter's `<OAuth2Provider>` does
|
|
8
|
+
* exactly this. Reach for the concrete class when you need transport-specific
|
|
9
|
+
* capability: {@link BffClient.loginContinuation} or
|
|
10
|
+
* {@link DirectClient.getAccessToken}.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { type OAuth2ClientEvent, type OAuth2ClientEventListener } from "./events.js";
|
|
15
|
+
/** Generic user-info claims returned by the userinfo or `id_token` helpers. */
|
|
16
|
+
export type UserInfoClaims = Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* The headers a wrapped `fetch` should send for `(input, init)`: the ones
|
|
19
|
+
* already on a `Request` input, overlaid with `init.headers`.
|
|
20
|
+
*
|
|
21
|
+
* Both client `fetch` wrappers need this because passing `headers` in an init
|
|
22
|
+
* *replaces* a `Request` input's header list rather than adding to it, which
|
|
23
|
+
* silently drops every header a caller set on the `Request`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mergedHeaders(input: RequestInfo | URL, init: RequestInit): Headers;
|
|
26
|
+
/** Options accepted by every client. */
|
|
27
|
+
export interface BaseOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Optional fetch implementation. Defaults to `globalThis.fetch`.
|
|
30
|
+
*
|
|
31
|
+
* Inject a custom `fetch` for:
|
|
32
|
+
*
|
|
33
|
+
* - **Co-located auth servers** — pass `localAuthServerFetch(authServer)`
|
|
34
|
+
* to dispatch token-endpoint calls directly into an in-process
|
|
35
|
+
* `AuthorizationServer` without a socket round-trip.
|
|
36
|
+
* - **Tests** — pass the `fetch` from `createMemoryAuthorizationServer()`
|
|
37
|
+
* (or any other `fetch`-compatible responder) so the client talks to
|
|
38
|
+
* an in-memory server. Preferred over stubbing `globalThis.fetch`,
|
|
39
|
+
* which would also intercept unrelated outbound requests the app may
|
|
40
|
+
* make.
|
|
41
|
+
*/
|
|
42
|
+
fetch?: typeof fetch;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The `login` options every client understands.
|
|
46
|
+
*
|
|
47
|
+
* Named apart from {@link LoginOptions} — which keeps the richer
|
|
48
|
+
* `DirectClient` shape it has always had — so that a consumer importing
|
|
49
|
+
* `LoginOptions` and passing `scope` still compiles. Reach for this one only
|
|
50
|
+
* when writing against {@link OAuth2ClientBase}.
|
|
51
|
+
*/
|
|
52
|
+
export interface BaseLoginOptions {
|
|
53
|
+
/** Path or URL to return to after a successful login. */
|
|
54
|
+
returnTo?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Options every client's `logout` accepts. */
|
|
57
|
+
export interface LogoutOptions {
|
|
58
|
+
/** Path or URL to return to after logout. */
|
|
59
|
+
returnTo?: string;
|
|
60
|
+
}
|
|
61
|
+
/** A URL the caller must navigate the browser to. */
|
|
62
|
+
export interface LoginRedirect {
|
|
63
|
+
/** Where to send the browser to start (or resume) sign-in. */
|
|
64
|
+
url: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Where to send the browser to finish signing out, if anywhere. `url` is
|
|
68
|
+
* absent when the sign-out completed locally with nothing left to visit.
|
|
69
|
+
*/
|
|
70
|
+
export interface LogoutRedirect {
|
|
71
|
+
/** The logout / end-session URL, when the flow needs a redirect. */
|
|
72
|
+
url?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The signed-out {@link SessionState}, frozen because it is returned by
|
|
76
|
+
* reference from every client's `getSession`.
|
|
77
|
+
*/
|
|
78
|
+
export declare const SIGNED_OUT: Readonly<SessionState>;
|
|
79
|
+
/** A snapshot of who is signed in, as the client currently understands it. */
|
|
80
|
+
export interface SessionState {
|
|
81
|
+
/** True iff a session is active. */
|
|
82
|
+
isAuthenticated: boolean;
|
|
83
|
+
/** Cached user claims, or `null`. */
|
|
84
|
+
user: UserInfoClaims | null;
|
|
85
|
+
/**
|
|
86
|
+
* Seconds until the session's access token expires, or `null` when unknown.
|
|
87
|
+
* A UI can use it to schedule {@link OAuth2ClientBase.renewSession} before
|
|
88
|
+
* expiry.
|
|
89
|
+
*/
|
|
90
|
+
sessionExpiresIn: number | null;
|
|
91
|
+
/**
|
|
92
|
+
* A URL that ends the session, or `null` when the client has no such URL to
|
|
93
|
+
* offer (a direct client revokes locally instead — see
|
|
94
|
+
* {@link OAuth2ClientBase.logout}).
|
|
95
|
+
*/
|
|
96
|
+
logoutUrl: string | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Base class for the OAuth2 clients. Owns the event bus and the resolved
|
|
100
|
+
* `fetch`; subclasses supply the transport.
|
|
101
|
+
*
|
|
102
|
+
* Not constructible on its own — build a {@link BffClient} (tokens live
|
|
103
|
+
* server-side behind a session cookie) or a {@link DirectClient} (this
|
|
104
|
+
* process holds the tokens) and pass it wherever an `OAuth2ClientBase` is
|
|
105
|
+
* accepted.
|
|
106
|
+
*
|
|
107
|
+
* @example Accept either client
|
|
108
|
+
* ```ts
|
|
109
|
+
* import type { OAuth2ClientBase } from "@udibo/oauth2/client";
|
|
110
|
+
*
|
|
111
|
+
* async function greet(client: OAuth2ClientBase): Promise<string> {
|
|
112
|
+
* const { isAuthenticated, user } = await client.getSession();
|
|
113
|
+
* return isAuthenticated ? `hello ${user?.sub}` : "hello stranger";
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare abstract class OAuth2ClientBase {
|
|
118
|
+
#private;
|
|
119
|
+
/**
|
|
120
|
+
* Called by the concrete clients; there is nothing to construct here on its
|
|
121
|
+
* own.
|
|
122
|
+
*
|
|
123
|
+
* @param options Only `fetch` is read at this level — subclasses consume
|
|
124
|
+
* the rest of their own options.
|
|
125
|
+
*/
|
|
126
|
+
protected constructor(options?: BaseOptions);
|
|
127
|
+
/**
|
|
128
|
+
* Subscribes to `authenticated` / `logged_out` / `token_refreshed` /
|
|
129
|
+
* `error` events. Returns a function that removes the listener.
|
|
130
|
+
*
|
|
131
|
+
* @param listener Called for every event, in subscription order. One
|
|
132
|
+
* listener throwing does not stop delivery to the rest.
|
|
133
|
+
*/
|
|
134
|
+
subscribe(listener: OAuth2ClientEventListener): () => void;
|
|
135
|
+
/** Publishes an event to every subscriber. */
|
|
136
|
+
protected emit(event: OAuth2ClientEvent): void;
|
|
137
|
+
/**
|
|
138
|
+
* The configured fetch, resolved at call time so the client picks up a
|
|
139
|
+
* polyfilled global if the runtime installs one after construction.
|
|
140
|
+
*/
|
|
141
|
+
protected fetchImpl(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
142
|
+
/**
|
|
143
|
+
* Builds the URL that starts sign-in. The caller navigates the browser
|
|
144
|
+
* there; nothing is signed in until that round trip completes.
|
|
145
|
+
*/
|
|
146
|
+
abstract login(options?: BaseLoginOptions): Promise<LoginRedirect>;
|
|
147
|
+
/**
|
|
148
|
+
* Ends the session and returns the URL to finish signing out, if the flow
|
|
149
|
+
* needs one. Emits `logged_out`.
|
|
150
|
+
*/
|
|
151
|
+
abstract logout(options?: LogoutOptions): Promise<LogoutRedirect>;
|
|
152
|
+
/**
|
|
153
|
+
* The claims of the signed-in user, or `null` when nobody is signed in.
|
|
154
|
+
* Use {@link getSession} when you also need expiry or the logout URL.
|
|
155
|
+
*/
|
|
156
|
+
abstract getUser(): Promise<UserInfoClaims | null>;
|
|
157
|
+
/**
|
|
158
|
+
* The current {@link SessionState}, as this client can determine it.
|
|
159
|
+
*
|
|
160
|
+
* **Never rejects.** A transport failure, an unreadable response, or claims
|
|
161
|
+
* that cannot be decoded all report a signed-out session and emit an `error`
|
|
162
|
+
* event instead of throwing, so a caller holding an `OAuth2ClientBase` needs
|
|
163
|
+
* no per-subclass `try`/`catch` to ask who is signed in. Rejection is
|
|
164
|
+
* reserved for a programming error, never a remote one.
|
|
165
|
+
*/
|
|
166
|
+
abstract getSession(): Promise<SessionState>;
|
|
167
|
+
/**
|
|
168
|
+
* Brings the session up to date — renewing credentials where this client
|
|
169
|
+
* owns them — and returns the resulting {@link SessionState}. Call it
|
|
170
|
+
* shortly before {@link SessionState.sessionExpiresIn} elapses.
|
|
171
|
+
*
|
|
172
|
+
* **Never rejects**, on the same terms as {@link getSession}. Because this
|
|
173
|
+
* runs on a background timer, a transport failure emits no `error` event
|
|
174
|
+
* either: a blip that will simply be retried must not surface as a
|
|
175
|
+
* user-visible error over a session that is still valid. A session that has
|
|
176
|
+
* genuinely ended still emits `logged_out`.
|
|
177
|
+
*/
|
|
178
|
+
abstract renewSession(): Promise<SessionState>;
|
|
179
|
+
/**
|
|
180
|
+
* Drop-in `fetch` that authenticates the request the way this client's
|
|
181
|
+
* transport requires, and recovers from a `401` where it can.
|
|
182
|
+
*/
|
|
183
|
+
abstract fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
184
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The surface {@link BffClient} and {@link DirectClient} share: subscribing to
|
|
3
|
+
* authentication events, starting and ending a login, reading the current
|
|
4
|
+
* session, and issuing authenticated requests.
|
|
5
|
+
*
|
|
6
|
+
* Program against {@link OAuth2ClientBase} when the code shouldn't care which
|
|
7
|
+
* transport holds the tokens — the React adapter's `<OAuth2Provider>` does
|
|
8
|
+
* exactly this. Reach for the concrete class when you need transport-specific
|
|
9
|
+
* capability: {@link BffClient.loginContinuation} or
|
|
10
|
+
* {@link DirectClient.getAccessToken}.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { EventBus, } from "./events.js";
|
|
15
|
+
/**
|
|
16
|
+
* The headers a wrapped `fetch` should send for `(input, init)`: the ones
|
|
17
|
+
* already on a `Request` input, overlaid with `init.headers`.
|
|
18
|
+
*
|
|
19
|
+
* Both client `fetch` wrappers need this because passing `headers` in an init
|
|
20
|
+
* *replaces* a `Request` input's header list rather than adding to it, which
|
|
21
|
+
* silently drops every header a caller set on the `Request`.
|
|
22
|
+
*/
|
|
23
|
+
export function mergedHeaders(input, init) {
|
|
24
|
+
const headers = new Headers(input instanceof Request ? input.headers : undefined);
|
|
25
|
+
for (const [name, value] of new Headers(init.headers)) {
|
|
26
|
+
headers.set(name, value);
|
|
27
|
+
}
|
|
28
|
+
return headers;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The signed-out {@link SessionState}, frozen because it is returned by
|
|
32
|
+
* reference from every client's `getSession`.
|
|
33
|
+
*/
|
|
34
|
+
export const SIGNED_OUT = Object.freeze({
|
|
35
|
+
isAuthenticated: false,
|
|
36
|
+
user: null,
|
|
37
|
+
sessionExpiresIn: null,
|
|
38
|
+
logoutUrl: null,
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* Base class for the OAuth2 clients. Owns the event bus and the resolved
|
|
42
|
+
* `fetch`; subclasses supply the transport.
|
|
43
|
+
*
|
|
44
|
+
* Not constructible on its own — build a {@link BffClient} (tokens live
|
|
45
|
+
* server-side behind a session cookie) or a {@link DirectClient} (this
|
|
46
|
+
* process holds the tokens) and pass it wherever an `OAuth2ClientBase` is
|
|
47
|
+
* accepted.
|
|
48
|
+
*
|
|
49
|
+
* @example Accept either client
|
|
50
|
+
* ```ts
|
|
51
|
+
* import type { OAuth2ClientBase } from "@udibo/oauth2/client";
|
|
52
|
+
*
|
|
53
|
+
* async function greet(client: OAuth2ClientBase): Promise<string> {
|
|
54
|
+
* const { isAuthenticated, user } = await client.getSession();
|
|
55
|
+
* return isAuthenticated ? `hello ${user?.sub}` : "hello stranger";
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export class OAuth2ClientBase {
|
|
60
|
+
#events = new EventBus();
|
|
61
|
+
#customFetch;
|
|
62
|
+
/**
|
|
63
|
+
* Called by the concrete clients; there is nothing to construct here on its
|
|
64
|
+
* own.
|
|
65
|
+
*
|
|
66
|
+
* @param options Only `fetch` is read at this level — subclasses consume
|
|
67
|
+
* the rest of their own options.
|
|
68
|
+
*/
|
|
69
|
+
constructor(options = {}) {
|
|
70
|
+
this.#customFetch = options.fetch;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Subscribes to `authenticated` / `logged_out` / `token_refreshed` /
|
|
74
|
+
* `error` events. Returns a function that removes the listener.
|
|
75
|
+
*
|
|
76
|
+
* @param listener Called for every event, in subscription order. One
|
|
77
|
+
* listener throwing does not stop delivery to the rest.
|
|
78
|
+
*/
|
|
79
|
+
subscribe(listener) {
|
|
80
|
+
return this.#events.subscribe(listener);
|
|
81
|
+
}
|
|
82
|
+
/** Publishes an event to every subscriber. */
|
|
83
|
+
emit(event) {
|
|
84
|
+
this.#events.emit(event);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The configured fetch, resolved at call time so the client picks up a
|
|
88
|
+
* polyfilled global if the runtime installs one after construction.
|
|
89
|
+
*/
|
|
90
|
+
fetchImpl(input, init) {
|
|
91
|
+
return (this.#customFetch ?? globalThis.fetch)(input, init);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser client for an app fronted by a Backend-for-Frontend.
|
|
3
|
+
*
|
|
4
|
+
* The BFF holds the tokens; this client only ever talks to the BFF's
|
|
5
|
+
* `/auth/*` routes with the session cookie attached, so no token reaches the
|
|
6
|
+
* browser. Pair it with the `@udibo/oauth2/hono/bff` adapter, or any BFF
|
|
7
|
+
* serving the same four routes.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { type BaseLoginOptions, type BaseOptions, type LoginRedirect, type LogoutOptions, type LogoutRedirect, OAuth2ClientBase, type SessionState, type UserInfoClaims } from "./base.js";
|
|
12
|
+
/** Paths (or absolute URLs) for the BFF session endpoints. */
|
|
13
|
+
export interface BffEndpoints {
|
|
14
|
+
/** Base URL the BFF is mounted under (e.g. `""` for same-origin). */
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
/** Path to the BFF's login route. Defaults to `/auth/login`. */
|
|
17
|
+
login?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Path to the BFF's logout route. Defaults to `/auth/logout`.
|
|
20
|
+
*
|
|
21
|
+
* {@link BffClient.logout} only builds this URL; the caller navigates to it,
|
|
22
|
+
* so sign-out travels the BFF's `GET` route and is guarded by its
|
|
23
|
+
* same-origin check rather than the `x-csrf` header. Post to this path
|
|
24
|
+
* yourself, with that header, for the stronger check.
|
|
25
|
+
*/
|
|
26
|
+
logout?: string;
|
|
27
|
+
/** Path to `GET /auth/session`. Defaults to `/auth/session`. */
|
|
28
|
+
session?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Options accepted by {@link BffClient}. */
|
|
31
|
+
export interface BffClientOptions extends BaseOptions {
|
|
32
|
+
/** Override the default `/auth/*` BFF session endpoint paths. */
|
|
33
|
+
endpoints?: BffEndpoints;
|
|
34
|
+
/**
|
|
35
|
+
* Path (or URL) of the authorization endpoint the BFF redirects to (e.g.
|
|
36
|
+
* `"/api/oauth2/authorize"`). Lets {@link BffClient.loginContinuation}
|
|
37
|
+
* recognize an in-flight authorize URL to resume. Optional — without it,
|
|
38
|
+
* `loginContinuation` always starts a fresh login.
|
|
39
|
+
*/
|
|
40
|
+
authorizePath?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Custom header sent on credentialed BFF requests — the `GET /auth/session`
|
|
43
|
+
* probe and the wrapped {@link BffClient.fetch} — so the BFF's CSRF guard
|
|
44
|
+
* accepts them. The header makes the request "non-simple", forcing a CORS
|
|
45
|
+
* preflight a cross-site page cannot pass.
|
|
46
|
+
*
|
|
47
|
+
* Defaults to `{ name: "x-csrf", value: "1" }`, matching `HonoBff`'s
|
|
48
|
+
* default. Set `false` to send no header (only if the BFF disables its
|
|
49
|
+
* CSRF check).
|
|
50
|
+
*/
|
|
51
|
+
csrfHeader?: {
|
|
52
|
+
name?: string;
|
|
53
|
+
value?: string;
|
|
54
|
+
} | false;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* OAuth2 client for a browser app whose sessions live in a
|
|
58
|
+
* Backend-for-Frontend.
|
|
59
|
+
*
|
|
60
|
+
* Every method here is a same-origin call to the BFF with `credentials:
|
|
61
|
+
* "include"`, never a call to the authorization server. There is no token
|
|
62
|
+
* storage, no PKCE, and no access token to read — if you need one, the app
|
|
63
|
+
* wants a {@link DirectClient} instead.
|
|
64
|
+
*
|
|
65
|
+
* @example Same-origin BFF
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
68
|
+
*
|
|
69
|
+
* const client = new BffClient();
|
|
70
|
+
*
|
|
71
|
+
* const session = await client.getSession();
|
|
72
|
+
* if (!session.isAuthenticated) {
|
|
73
|
+
* const { url } = await client.login({ returnTo: location.pathname });
|
|
74
|
+
* location.assign(url);
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* const res = await client.fetch("/api/items");
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @example BFF mounted elsewhere, with a custom CSRF header
|
|
81
|
+
* ```ts
|
|
82
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
83
|
+
*
|
|
84
|
+
* const client = new BffClient({
|
|
85
|
+
* endpoints: { baseUrl: "https://api.example.com", login: "/session/start" },
|
|
86
|
+
* csrfHeader: { name: "x-requested-with", value: "spa" },
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare class BffClient extends OAuth2ClientBase {
|
|
91
|
+
#private;
|
|
92
|
+
/**
|
|
93
|
+
* Builds a client against the BFF's `/auth/*` routes.
|
|
94
|
+
*
|
|
95
|
+
* @param options Endpoint overrides, the CSRF header to send, and the
|
|
96
|
+
* `fetch` to use. Every field is optional; the defaults match `HonoBff`
|
|
97
|
+
* mounted at `/auth` on the same origin.
|
|
98
|
+
*/
|
|
99
|
+
constructor(options?: BffClientOptions);
|
|
100
|
+
/**
|
|
101
|
+
* Builds the BFF login URL. Navigate the browser there; the BFF runs the
|
|
102
|
+
* authorization-code flow and drops the session cookie before redirecting
|
|
103
|
+
* back to `returnTo`.
|
|
104
|
+
*
|
|
105
|
+
* @param options `returnTo` is passed through as the `return_to` query
|
|
106
|
+
* parameter. The BFF is responsible for validating it against open
|
|
107
|
+
* redirects.
|
|
108
|
+
* @returns The URL to navigate to.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
113
|
+
*
|
|
114
|
+
* const client = new BffClient();
|
|
115
|
+
* const { url } = await client.login({ returnTo: "/dashboard" });
|
|
116
|
+
* location.assign(url);
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
login(options?: BaseLoginOptions): Promise<LoginRedirect>;
|
|
120
|
+
/**
|
|
121
|
+
* Builds the BFF logout URL and emits `logged_out` so the UI can render
|
|
122
|
+
* signed-out immediately. Navigate the browser to the returned URL; the BFF
|
|
123
|
+
* destroys the session and clears the cookie.
|
|
124
|
+
*
|
|
125
|
+
* @param options `returnTo` is passed through as the `return_to` query
|
|
126
|
+
* parameter.
|
|
127
|
+
* @returns The URL to navigate to.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
132
|
+
*
|
|
133
|
+
* const client = new BffClient();
|
|
134
|
+
* const { url } = await client.logout({ returnTo: "/" });
|
|
135
|
+
* location.assign(url!);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
logout(options?: LogoutOptions): Promise<LogoutRedirect>;
|
|
139
|
+
/**
|
|
140
|
+
* Probes `GET /auth/session` and returns the full {@link SessionState} —
|
|
141
|
+
* `isAuthenticated`, `user`, plus the `sessionExpiresIn` and `logoutUrl` a
|
|
142
|
+
* SPA uses to schedule a re-probe and render a sign-out link.
|
|
143
|
+
*
|
|
144
|
+
* **Never rejects**, per {@link OAuth2ClientBase.getSession}: an
|
|
145
|
+
* unreachable BFF, a non-OK status, and a body that is not a JSON object
|
|
146
|
+
* (an HTML error page from a misrouted path is the common one) all read as
|
|
147
|
+
* signed out. A failure that was not simply "nobody is signed in" — anything
|
|
148
|
+
* other than a `401` — also emits an `error` event so a UI can tell the two
|
|
149
|
+
* apart. The read is bounded and deadlined like every other call this
|
|
150
|
+
* package makes.
|
|
151
|
+
*
|
|
152
|
+
* Only `isAuthenticated: true` carries `user` / `sessionExpiresIn` /
|
|
153
|
+
* `logoutUrl` through; an anonymous payload always reports them as `null`,
|
|
154
|
+
* whatever the BFF put in the body.
|
|
155
|
+
*
|
|
156
|
+
* @returns The session as the BFF reports it. Tokens are never included.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
161
|
+
*
|
|
162
|
+
* const { isAuthenticated, logoutUrl } = await new BffClient().getSession();
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
getSession(): Promise<SessionState>;
|
|
166
|
+
/**
|
|
167
|
+
* The signed-in user's claims from the session probe, or `null`.
|
|
168
|
+
*
|
|
169
|
+
* @returns The `user` field of {@link getSession}.
|
|
170
|
+
*/
|
|
171
|
+
getUser(): Promise<UserInfoClaims | null>;
|
|
172
|
+
/**
|
|
173
|
+
* Re-probes `GET /auth/session`.
|
|
174
|
+
*
|
|
175
|
+
* The BFF owns credential renewal — its `attachToken` middleware refreshes
|
|
176
|
+
* the access token server-side when a proxied call needs one — so this
|
|
177
|
+
* reports the current state rather than driving a refresh itself. Call it
|
|
178
|
+
* shortly before {@link SessionState.sessionExpiresIn} elapses to keep the
|
|
179
|
+
* UI honest about whether the session is still alive.
|
|
180
|
+
*
|
|
181
|
+
* Emits no `error` event, per {@link OAuth2ClientBase.renewSession}: this
|
|
182
|
+
* runs on a background timer, where a failed probe means "ask again shortly",
|
|
183
|
+
* not "show the user a problem".
|
|
184
|
+
*
|
|
185
|
+
* @returns The refreshed {@link SessionState}.
|
|
186
|
+
*/
|
|
187
|
+
renewSession(): Promise<SessionState>;
|
|
188
|
+
/**
|
|
189
|
+
* Fetches with the session cookie and the CSRF header attached, so the BFF
|
|
190
|
+
* authenticates the call and its CSRF guard accepts it.
|
|
191
|
+
*
|
|
192
|
+
* A `401` emits `logged_out` with reason `session_expired` and is returned
|
|
193
|
+
* as-is — the BFF, not the browser, decides whether a refresh is possible.
|
|
194
|
+
*
|
|
195
|
+
* @param input Request target, as for `fetch`. A `Request` keeps the headers
|
|
196
|
+
* and body it was built with.
|
|
197
|
+
* @param init Request options. A caller-set CSRF header is left alone, and
|
|
198
|
+
* `init.headers` override same-named headers on a `Request` input.
|
|
199
|
+
* @returns The BFF's response, unmodified.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
204
|
+
*
|
|
205
|
+
* const res = await new BffClient().fetch("/api/items");
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
209
|
+
/**
|
|
210
|
+
* Builds the URL that (re)starts sign-in toward `returnTo`, for an app whose
|
|
211
|
+
* own login surface (a sign-in form, create-account, forgot-password) hands
|
|
212
|
+
* back to the BFF flow after authenticating a user: resume an in-flight
|
|
213
|
+
* authorize URL, or start a fresh BFF login.
|
|
214
|
+
*
|
|
215
|
+
* Pure and synchronous — safe in render. The mirror of
|
|
216
|
+
* `HonoBff.loginContinuation`, so both sides of the app agree on where
|
|
217
|
+
* "sign in" goes.
|
|
218
|
+
*
|
|
219
|
+
* Recognizing an in-flight authorize URL requires `authorizePath` in the
|
|
220
|
+
* constructor options; without it every `returnTo` starts a fresh login.
|
|
221
|
+
*
|
|
222
|
+
* @param returnTo Where the user was headed. `null` / `undefined` fall back
|
|
223
|
+
* to `/`.
|
|
224
|
+
* @returns The URL to redirect to.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* import { BffClient } from "@udibo/oauth2/client";
|
|
229
|
+
*
|
|
230
|
+
* const client = new BffClient({ authorizePath: "/api/oauth2/authorize" });
|
|
231
|
+
* const href = client.loginContinuation("/api/oauth2/authorize?client_id=a");
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
loginContinuation(returnTo: string | null | undefined): string;
|
|
235
|
+
}
|