@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,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The authorization a verified credential carries, as one checkable object.
|
|
3
|
+
*
|
|
4
|
+
* {@link Authorization} is built from a token's verified claims (an RFC 9068
|
|
5
|
+
* JWT's payload, an introspection response, or an id_token's claims) and
|
|
6
|
+
* answers the checks an application makes: `scope` for what the **client**
|
|
7
|
+
* was delegated, `permissions`/`roles` for what the **person** holds, and the
|
|
8
|
+
* active organization context. The same object is exposed on the resource
|
|
9
|
+
* server's authenticated context, and can be built anywhere claims are held
|
|
10
|
+
* (a BFF session's user, a browser client's session) so every surface checks
|
|
11
|
+
* authorization the same way.
|
|
12
|
+
*
|
|
13
|
+
* Predicates never throw — they return booleans, so conditional rendering and
|
|
14
|
+
* branching never need try/catch. Enforcement (turning a failed check into a
|
|
15
|
+
* response) belongs to the resource server and its middleware.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import type { AbstractScope } from "./scope.js";
|
|
20
|
+
/**
|
|
21
|
+
* The active organization a credential was issued in: the one organization
|
|
22
|
+
* whose roles and permissions the credential carries. Absent (`null` on
|
|
23
|
+
* {@link Authorization.organization}) when the subject acts outside any
|
|
24
|
+
* organization; anything about an organization the credential does not name
|
|
25
|
+
* is answered by a check endpoint, never by the token.
|
|
26
|
+
*/
|
|
27
|
+
export interface OrganizationContext {
|
|
28
|
+
/** The organization's id (the `org_id` claim). */
|
|
29
|
+
id: string;
|
|
30
|
+
/** The organization's stable handle (the `org_slug` claim), when issued. */
|
|
31
|
+
slug?: string;
|
|
32
|
+
/** Roles the subject holds in this organization (the `org_roles` claim). */
|
|
33
|
+
roles: ReadonlySet<string>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Conditions for {@link Authorization.unmet} and the resource servers'
|
|
37
|
+
* `require()` middleware. Every named condition must hold (AND semantics),
|
|
38
|
+
* and an array value means **all of** its entries — any-of checks are
|
|
39
|
+
* deliberately not expressible here; branch on the {@link Authorization}
|
|
40
|
+
* object in a handler instead, where the semantics stay visible.
|
|
41
|
+
*/
|
|
42
|
+
export interface RequireConditions {
|
|
43
|
+
/**
|
|
44
|
+
* Scope the client must have been granted. A space-delimited string or an
|
|
45
|
+
* array both mean all of the named scopes.
|
|
46
|
+
*/
|
|
47
|
+
scope?: string | string[];
|
|
48
|
+
/** Permission(s) the subject must hold ({@link Authorization.can}). */
|
|
49
|
+
permission?: string | string[];
|
|
50
|
+
/** Tenant-wide role(s) the subject must hold ({@link Authorization.hasRole}). */
|
|
51
|
+
role?: string | string[];
|
|
52
|
+
/**
|
|
53
|
+
* Role(s) the subject must hold in the active organization
|
|
54
|
+
* ({@link Authorization.hasOrgRole}).
|
|
55
|
+
*/
|
|
56
|
+
orgRole?: string | string[];
|
|
57
|
+
/**
|
|
58
|
+
* Organization context required: `true` for "any active organization", or
|
|
59
|
+
* an id/slug the active organization must match
|
|
60
|
+
* ({@link Authorization.inOrganization}).
|
|
61
|
+
*/
|
|
62
|
+
organization?: true | string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The first condition of a {@link RequireConditions} the authorization does
|
|
66
|
+
* not satisfy — `kind` names which check failed and `required` what it asked
|
|
67
|
+
* for. Scope conditions are not reported here: the resource server enforces
|
|
68
|
+
* them through its scope assertion so the RFC 6750 `insufficient_scope`
|
|
69
|
+
* challenge stays identical to `requireScope`'s.
|
|
70
|
+
*/
|
|
71
|
+
export interface AuthorizationFailure {
|
|
72
|
+
/** Which check failed. */
|
|
73
|
+
kind: "organization" | "role" | "orgRole" | "permission";
|
|
74
|
+
/** The condition value that was not met. */
|
|
75
|
+
required: string | true;
|
|
76
|
+
}
|
|
77
|
+
/** The parts an {@link Authorization} is constructed from. */
|
|
78
|
+
export interface AuthorizationInit {
|
|
79
|
+
/** The scope granted to the client, when known. */
|
|
80
|
+
scope?: AbstractScope | null;
|
|
81
|
+
/** Tenant-wide role slugs the subject holds. */
|
|
82
|
+
roles?: Iterable<string>;
|
|
83
|
+
/** Permissions the subject holds (tenant-level plus the active organization's). */
|
|
84
|
+
permissions?: Iterable<string>;
|
|
85
|
+
/** The active organization context, when the credential carries one. */
|
|
86
|
+
organization?: OrganizationContext | null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Checkable authorization derived from a credential's verified claims.
|
|
90
|
+
*
|
|
91
|
+
* Build one with {@link authorizationFromClaims}, or construct directly when
|
|
92
|
+
* your claims use different names. A machine token (no resource owner) yields
|
|
93
|
+
* empty roles/permissions and no organization — only its scope answers.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { authorizationFromClaims } from "@udibo/oauth2/server";
|
|
98
|
+
*
|
|
99
|
+
* const authorization = authorizationFromClaims({
|
|
100
|
+
* roles: ["editor"],
|
|
101
|
+
* permissions: ["posts:write"],
|
|
102
|
+
* org_id: "org-1",
|
|
103
|
+
* org_slug: "acme",
|
|
104
|
+
* org_roles: ["admin"],
|
|
105
|
+
* });
|
|
106
|
+
* authorization.can("posts:write"); // true
|
|
107
|
+
* authorization.inOrganization("acme"); // true
|
|
108
|
+
* authorization.hasRole("admin"); // false — that role is org-scoped
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export declare class Authorization {
|
|
112
|
+
/** The scope granted to the client, or `null` when unknown. */
|
|
113
|
+
readonly scope: AbstractScope | null;
|
|
114
|
+
/** Tenant-wide role slugs the subject holds. */
|
|
115
|
+
readonly roles: ReadonlySet<string>;
|
|
116
|
+
/** Permissions the subject holds in the credential's scope of issue. */
|
|
117
|
+
readonly permissions: ReadonlySet<string>;
|
|
118
|
+
/** The active organization, or `null` when the credential names none. */
|
|
119
|
+
readonly organization: OrganizationContext | null;
|
|
120
|
+
/** Builds an authorization from already-parsed parts. */
|
|
121
|
+
constructor(init?: AuthorizationInit);
|
|
122
|
+
/**
|
|
123
|
+
* Whether the client was granted `scope` — the delegation check, distinct
|
|
124
|
+
* from what the person may do. A space-delimited string means all of the
|
|
125
|
+
* named scopes. `false` when the granted scope is unknown.
|
|
126
|
+
*/
|
|
127
|
+
hasScope(scope: string): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Whether the subject holds `permission` — the recommended check: a
|
|
130
|
+
* permission is the contract, role names are presentation.
|
|
131
|
+
*/
|
|
132
|
+
can(permission: string): boolean;
|
|
133
|
+
/** Whether the subject holds the tenant-wide role `role`. */
|
|
134
|
+
hasRole(role: string): boolean;
|
|
135
|
+
/** Whether the subject holds `role` in the active organization. */
|
|
136
|
+
hasOrgRole(role: string): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Whether the credential was issued in an active organization — any one
|
|
139
|
+
* when called without an argument, or the one whose id or slug matches
|
|
140
|
+
* `idOrSlug`.
|
|
141
|
+
*/
|
|
142
|
+
inOrganization(idOrSlug?: string): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* The first non-scope condition this authorization does not satisfy, or
|
|
145
|
+
* `undefined` when every one holds. Scope conditions are ignored here —
|
|
146
|
+
* the resource server asserts them separately so the RFC 6750 challenge
|
|
147
|
+
* semantics stay intact. Checked in order: organization, role, orgRole,
|
|
148
|
+
* permission.
|
|
149
|
+
*/
|
|
150
|
+
unmet(conditions: RequireConditions): AuthorizationFailure | undefined;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Build an {@link Authorization} from a credential's verified claims — an
|
|
154
|
+
* RFC 9068 access token's payload, an RFC 7662 introspection response, or an
|
|
155
|
+
* id_token's claims. Reads the `roles`, `permissions`, `org_id`, `org_slug`,
|
|
156
|
+
* and `org_roles` claims; anything malformed is treated as absent rather
|
|
157
|
+
* than thrown on, since claim shapes vary by issuer. There is no active
|
|
158
|
+
* organization unless `org_id` is a string — its presence is the whole
|
|
159
|
+
* question.
|
|
160
|
+
*
|
|
161
|
+
* Verify claims before building from them: this function trusts its input.
|
|
162
|
+
* `scope` is passed separately because access-token scope arrives as the
|
|
163
|
+
* token's own granted scope object, and id_token claims carry none.
|
|
164
|
+
*/
|
|
165
|
+
export declare function authorizationFromClaims(claims: Record<string, unknown> | null | undefined, scope?: AbstractScope | null): Authorization;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The authorization a verified credential carries, as one checkable object.
|
|
3
|
+
*
|
|
4
|
+
* {@link Authorization} is built from a token's verified claims (an RFC 9068
|
|
5
|
+
* JWT's payload, an introspection response, or an id_token's claims) and
|
|
6
|
+
* answers the checks an application makes: `scope` for what the **client**
|
|
7
|
+
* was delegated, `permissions`/`roles` for what the **person** holds, and the
|
|
8
|
+
* active organization context. The same object is exposed on the resource
|
|
9
|
+
* server's authenticated context, and can be built anywhere claims are held
|
|
10
|
+
* (a BFF session's user, a browser client's session) so every surface checks
|
|
11
|
+
* authorization the same way.
|
|
12
|
+
*
|
|
13
|
+
* Predicates never throw — they return booleans, so conditional rendering and
|
|
14
|
+
* branching never need try/catch. Enforcement (turning a failed check into a
|
|
15
|
+
* response) belongs to the resource server and its middleware.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Checkable authorization derived from a credential's verified claims.
|
|
21
|
+
*
|
|
22
|
+
* Build one with {@link authorizationFromClaims}, or construct directly when
|
|
23
|
+
* your claims use different names. A machine token (no resource owner) yields
|
|
24
|
+
* empty roles/permissions and no organization — only its scope answers.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { authorizationFromClaims } from "@udibo/oauth2/server";
|
|
29
|
+
*
|
|
30
|
+
* const authorization = authorizationFromClaims({
|
|
31
|
+
* roles: ["editor"],
|
|
32
|
+
* permissions: ["posts:write"],
|
|
33
|
+
* org_id: "org-1",
|
|
34
|
+
* org_slug: "acme",
|
|
35
|
+
* org_roles: ["admin"],
|
|
36
|
+
* });
|
|
37
|
+
* authorization.can("posts:write"); // true
|
|
38
|
+
* authorization.inOrganization("acme"); // true
|
|
39
|
+
* authorization.hasRole("admin"); // false — that role is org-scoped
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class Authorization {
|
|
43
|
+
/** The scope granted to the client, or `null` when unknown. */
|
|
44
|
+
scope;
|
|
45
|
+
/** Tenant-wide role slugs the subject holds. */
|
|
46
|
+
roles;
|
|
47
|
+
/** Permissions the subject holds in the credential's scope of issue. */
|
|
48
|
+
permissions;
|
|
49
|
+
/** The active organization, or `null` when the credential names none. */
|
|
50
|
+
organization;
|
|
51
|
+
/** Builds an authorization from already-parsed parts. */
|
|
52
|
+
constructor(init = {}) {
|
|
53
|
+
this.scope = init.scope ?? null;
|
|
54
|
+
this.roles = new Set(init.roles ?? []);
|
|
55
|
+
this.permissions = new Set(init.permissions ?? []);
|
|
56
|
+
this.organization = init.organization ?? null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Whether the client was granted `scope` — the delegation check, distinct
|
|
60
|
+
* from what the person may do. A space-delimited string means all of the
|
|
61
|
+
* named scopes. `false` when the granted scope is unknown.
|
|
62
|
+
*/
|
|
63
|
+
hasScope(scope) {
|
|
64
|
+
return this.scope?.has(scope) ?? false;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Whether the subject holds `permission` — the recommended check: a
|
|
68
|
+
* permission is the contract, role names are presentation.
|
|
69
|
+
*/
|
|
70
|
+
can(permission) {
|
|
71
|
+
return this.permissions.has(permission);
|
|
72
|
+
}
|
|
73
|
+
/** Whether the subject holds the tenant-wide role `role`. */
|
|
74
|
+
hasRole(role) {
|
|
75
|
+
return this.roles.has(role);
|
|
76
|
+
}
|
|
77
|
+
/** Whether the subject holds `role` in the active organization. */
|
|
78
|
+
hasOrgRole(role) {
|
|
79
|
+
return this.organization?.roles.has(role) ?? false;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Whether the credential was issued in an active organization — any one
|
|
83
|
+
* when called without an argument, or the one whose id or slug matches
|
|
84
|
+
* `idOrSlug`.
|
|
85
|
+
*/
|
|
86
|
+
inOrganization(idOrSlug) {
|
|
87
|
+
if (!this.organization)
|
|
88
|
+
return false;
|
|
89
|
+
if (idOrSlug === undefined)
|
|
90
|
+
return true;
|
|
91
|
+
return this.organization.id === idOrSlug ||
|
|
92
|
+
this.organization.slug === idOrSlug;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The first non-scope condition this authorization does not satisfy, or
|
|
96
|
+
* `undefined` when every one holds. Scope conditions are ignored here —
|
|
97
|
+
* the resource server asserts them separately so the RFC 6750 challenge
|
|
98
|
+
* semantics stay intact. Checked in order: organization, role, orgRole,
|
|
99
|
+
* permission.
|
|
100
|
+
*/
|
|
101
|
+
unmet(conditions) {
|
|
102
|
+
if (conditions.organization !== undefined &&
|
|
103
|
+
!this.inOrganization(conditions.organization === true ? undefined : conditions.organization)) {
|
|
104
|
+
return { kind: "organization", required: conditions.organization };
|
|
105
|
+
}
|
|
106
|
+
for (const role of listOf(conditions.role)) {
|
|
107
|
+
if (!this.hasRole(role))
|
|
108
|
+
return { kind: "role", required: role };
|
|
109
|
+
}
|
|
110
|
+
for (const role of listOf(conditions.orgRole)) {
|
|
111
|
+
if (!this.hasOrgRole(role))
|
|
112
|
+
return { kind: "orgRole", required: role };
|
|
113
|
+
}
|
|
114
|
+
for (const permission of listOf(conditions.permission)) {
|
|
115
|
+
if (!this.can(permission)) {
|
|
116
|
+
return { kind: "permission", required: permission };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function listOf(value) {
|
|
123
|
+
if (value === undefined)
|
|
124
|
+
return [];
|
|
125
|
+
return typeof value === "string" ? [value] : value;
|
|
126
|
+
}
|
|
127
|
+
function stringsOf(value) {
|
|
128
|
+
if (!Array.isArray(value))
|
|
129
|
+
return [];
|
|
130
|
+
return value.filter((entry) => typeof entry === "string");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build an {@link Authorization} from a credential's verified claims — an
|
|
134
|
+
* RFC 9068 access token's payload, an RFC 7662 introspection response, or an
|
|
135
|
+
* id_token's claims. Reads the `roles`, `permissions`, `org_id`, `org_slug`,
|
|
136
|
+
* and `org_roles` claims; anything malformed is treated as absent rather
|
|
137
|
+
* than thrown on, since claim shapes vary by issuer. There is no active
|
|
138
|
+
* organization unless `org_id` is a string — its presence is the whole
|
|
139
|
+
* question.
|
|
140
|
+
*
|
|
141
|
+
* Verify claims before building from them: this function trusts its input.
|
|
142
|
+
* `scope` is passed separately because access-token scope arrives as the
|
|
143
|
+
* token's own granted scope object, and id_token claims carry none.
|
|
144
|
+
*/
|
|
145
|
+
export function authorizationFromClaims(claims, scope) {
|
|
146
|
+
const orgId = claims?.org_id;
|
|
147
|
+
const orgSlug = claims?.org_slug;
|
|
148
|
+
return new Authorization({
|
|
149
|
+
scope,
|
|
150
|
+
roles: stringsOf(claims?.roles),
|
|
151
|
+
permissions: stringsOf(claims?.permissions),
|
|
152
|
+
organization: typeof orgId === "string"
|
|
153
|
+
? {
|
|
154
|
+
id: orgId,
|
|
155
|
+
slug: typeof orgSlug === "string" ? orgSlug : undefined,
|
|
156
|
+
roles: new Set(stringsOf(claims?.org_roles)),
|
|
157
|
+
}
|
|
158
|
+
: null,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 client configuration — the minimum surface the framework reads.
|
|
3
|
+
*
|
|
4
|
+
* Only includes fields the framework actually inspects. Users are expected
|
|
5
|
+
* to extend this interface (or the class that implements it) with
|
|
6
|
+
* application-specific fields: display name, client secret hashes, token
|
|
7
|
+
* lifetimes, scope vocabulary, confidentiality flags, rate limits, etc.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* interface MyClient extends ClientInterface {
|
|
12
|
+
* name: string;
|
|
13
|
+
* confidential: boolean;
|
|
14
|
+
* tenantId: string;
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export interface ClientInterface {
|
|
19
|
+
/** Unique client identifier. */
|
|
20
|
+
id: string;
|
|
21
|
+
/**
|
|
22
|
+
* OAuth2 grant type identifiers this client is allowed to use (e.g.
|
|
23
|
+
* `"authorization_code"`, `"client_credentials"`,
|
|
24
|
+
* `"urn:ietf:params:oauth:grant-type:device_code"`). The framework
|
|
25
|
+
* rejects grant-type requests where the identifier is not in this list.
|
|
26
|
+
* When omitted, the client cannot use any grant type.
|
|
27
|
+
*/
|
|
28
|
+
grants?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Allowed redirect URIs for the authorization code flow. An authorization
|
|
31
|
+
* request's `redirect_uri` is authorized by `matchRedirectUri` from
|
|
32
|
+
* `@udibo/oauth2/server`, which compares it against these entries and rejects
|
|
33
|
+
* the request when none authorizes it.
|
|
34
|
+
*
|
|
35
|
+
* An ordinary entry is a **literal**, compared by exact string match (RFC
|
|
36
|
+
* 6749 §3.1.2.3), and an exact match always wins. An entry may instead be a
|
|
37
|
+
* **pattern** — one `*` in the leftmost host label, `https` only, over a
|
|
38
|
+
* single registrable domain (`https://myapp-*.myorg.deno.net/cb`) — so one
|
|
39
|
+
* registration covers the per-deploy hostnames a preview environment
|
|
40
|
+
* produces. `matchRedirectUri` needs `isPublicSuffix` (from
|
|
41
|
+
* `@udibo/oauth2/server/public-suffix`) to decide that last rule: without it
|
|
42
|
+
* every pattern entry is **inert** and only literals match. The list proves
|
|
43
|
+
* the domain is registrable, not that *this* client registered it, so
|
|
44
|
+
* deciding which clients may hold a pattern stays your policy — see
|
|
45
|
+
* `matchRedirectUri` and `checkRedirectUriPattern` for the full rules.
|
|
46
|
+
*
|
|
47
|
+
* An authorization request that omits `redirect_uri` falls back to the first
|
|
48
|
+
* **literal** entry, so order the array with that default first. When omitted
|
|
49
|
+
* or empty, no redirect URI is authorized at all.
|
|
50
|
+
*
|
|
51
|
+
* A legacy literal entry containing a `*` (registrable before patterns
|
|
52
|
+
* existed) now matches **nothing** — the value reads as a pattern and fails
|
|
53
|
+
* the rules. That fails closed, but silently: re-register such a client.
|
|
54
|
+
*/
|
|
55
|
+
redirectUris?: string[];
|
|
56
|
+
/**
|
|
57
|
+
* Where the authorization server may send the browser after an RP-initiated
|
|
58
|
+
* logout (OpenID Connect RP-Initiated Logout 1.0 §2). A logout request's
|
|
59
|
+
* `post_logout_redirect_uri` is authorized against this list by **exact
|
|
60
|
+
* string match only** — no patterns, no prefix matching. Unlike
|
|
61
|
+
* {@link ClientInterface.redirectUris}, a logout redirect carries no
|
|
62
|
+
* credential and so has no code to steal, but it is still an open redirect
|
|
63
|
+
* wearing your domain, which is a phishing primitive.
|
|
64
|
+
*
|
|
65
|
+
* When omitted or empty, no post-logout redirect is authorized: the logout
|
|
66
|
+
* still ends the session, it just answers directly instead of bouncing the
|
|
67
|
+
* browser onward. That is the safe failure, so a client that never registers
|
|
68
|
+
* one is not broken, only less convenient.
|
|
69
|
+
*/
|
|
70
|
+
postLogoutRedirectUris?: string[];
|
|
71
|
+
}
|
|
72
|
+
/** Client credentials from a request. */
|
|
73
|
+
export interface ClientCredentials {
|
|
74
|
+
/** Client identifier presented by the request. */
|
|
75
|
+
clientId: string;
|
|
76
|
+
/** Client secret, present only for confidential clients. */
|
|
77
|
+
clientSecret?: string;
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ClientInterface } from "./client.js";
|
|
2
|
+
import type { AbstractScope, BasicScope } from "./scope.js";
|
|
3
|
+
/**
|
|
4
|
+
* Device authorization request stored by the service.
|
|
5
|
+
*
|
|
6
|
+
* Contains all the information needed to complete the device flow
|
|
7
|
+
* once the user has authorized the request.
|
|
8
|
+
*/
|
|
9
|
+
export interface DeviceAuthorization<Client extends ClientInterface, User, Scope extends AbstractScope = BasicScope> {
|
|
10
|
+
/** The device verification code. */
|
|
11
|
+
deviceCode: string;
|
|
12
|
+
/** The user verification code (displayed to the user). */
|
|
13
|
+
userCode: string;
|
|
14
|
+
/** When the codes expire. */
|
|
15
|
+
expiresAt: Date;
|
|
16
|
+
/** The client that initiated the request. */
|
|
17
|
+
client: Client;
|
|
18
|
+
/** The scope requested by the client. */
|
|
19
|
+
scope?: Scope | null;
|
|
20
|
+
/** The minimum polling interval in seconds. */
|
|
21
|
+
interval: number;
|
|
22
|
+
/** Whether the user has authorized the request. */
|
|
23
|
+
authorized?: boolean;
|
|
24
|
+
/** The user who authorized the request (set after authorization). */
|
|
25
|
+
user?: User;
|
|
26
|
+
/** Whether the request was denied. */
|
|
27
|
+
denied?: boolean;
|
|
28
|
+
/** The last time the client polled for this code. */
|
|
29
|
+
lastPolled?: Date;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 error codes as defined in RFC 6749 and extensions.
|
|
3
|
+
*
|
|
4
|
+
* Includes the RFC 6750 Section 3.1 bearer-token error codes
|
|
5
|
+
* (`invalid_token`, `insufficient_scope`) emitted by resource servers, in
|
|
6
|
+
* addition to the RFC 6749 Section 5.2 / Section 4.1.2.1 codes and the RFC
|
|
7
|
+
* 8628 device-flow codes.
|
|
8
|
+
*
|
|
9
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
10
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
11
|
+
*/
|
|
12
|
+
export type OAuth2ErrorCode = "invalid_request" | "invalid_client" | "invalid_grant" | "unauthorized_client" | "unsupported_grant_type" | "unsupported_response_type" | "unsupported_token_type" | "invalid_scope" | "invalid_token" | "insufficient_scope" | "access_denied" | "server_error" | "temporarily_unavailable" | "authorization_pending" | "slow_down" | "expired_token";
|
|
13
|
+
/**
|
|
14
|
+
* Standard OAuth2 error response.
|
|
15
|
+
*
|
|
16
|
+
* Returned by OAuth2 endpoints when an error occurs.
|
|
17
|
+
*
|
|
18
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
19
|
+
*/
|
|
20
|
+
export interface ErrorResponse {
|
|
21
|
+
/** Error code from {@linkcode OAuth2ErrorCode}. */
|
|
22
|
+
error: OAuth2ErrorCode;
|
|
23
|
+
/** Human-readable error description. */
|
|
24
|
+
error_description?: string;
|
|
25
|
+
/** URI to a page with additional error information. */
|
|
26
|
+
error_uri?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* OAuth2 Authorization Server Metadata as defined in RFC 8414.
|
|
30
|
+
*
|
|
31
|
+
* Describes the configuration of an OAuth2 authorization server,
|
|
32
|
+
* typically served at `/.well-known/oauth-authorization-server`.
|
|
33
|
+
*
|
|
34
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8414#section-2
|
|
35
|
+
*/
|
|
36
|
+
export interface AuthorizationServerMetadata {
|
|
37
|
+
/** Authorization server's issuer identifier (URL). */
|
|
38
|
+
issuer: string;
|
|
39
|
+
/** URL of the authorization endpoint. */
|
|
40
|
+
authorization_endpoint?: string;
|
|
41
|
+
/** URL of the token endpoint. */
|
|
42
|
+
token_endpoint?: string;
|
|
43
|
+
/** Supported client authentication methods at the token endpoint. */
|
|
44
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* URL of the token introspection endpoint (RFC 7662). Named
|
|
47
|
+
* `introspection_endpoint` per the RFC 8414 / IANA metadata registry.
|
|
48
|
+
*/
|
|
49
|
+
introspection_endpoint?: string;
|
|
50
|
+
/** URL of the token revocation endpoint (RFC 7009). */
|
|
51
|
+
revocation_endpoint?: string;
|
|
52
|
+
/** URL of the device authorization endpoint (RFC 8628). */
|
|
53
|
+
device_authorization_endpoint?: string;
|
|
54
|
+
/** URL of the OIDC userinfo endpoint (OpenID Connect Discovery). */
|
|
55
|
+
userinfo_endpoint?: string;
|
|
56
|
+
/** URL of the OIDC RP-initiated logout (end-session) endpoint. */
|
|
57
|
+
end_session_endpoint?: string;
|
|
58
|
+
/** Supported PKCE code challenge methods. */
|
|
59
|
+
code_challenge_methods_supported?: string[];
|
|
60
|
+
/** Scopes supported by the authorization server. */
|
|
61
|
+
scopes_supported?: string[];
|
|
62
|
+
/** Supported response types. */
|
|
63
|
+
response_types_supported?: string[];
|
|
64
|
+
/** Supported grant types. */
|
|
65
|
+
grant_types_supported?: string[];
|
|
66
|
+
/** URL of the JWKS document (OIDC Discovery / RFC 8414). */
|
|
67
|
+
jwks_uri?: string;
|
|
68
|
+
/** JWS algorithms supported for id_token signing (OIDC Discovery). */
|
|
69
|
+
id_token_signing_alg_values_supported?: string[];
|
|
70
|
+
/** Subject identifier types supported (OIDC Discovery). */
|
|
71
|
+
subject_types_supported?: string[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Device authorization response as defined in RFC 8628.
|
|
75
|
+
*
|
|
76
|
+
* Returned by the device authorization endpoint for the device flow.
|
|
77
|
+
*
|
|
78
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
|
79
|
+
*/
|
|
80
|
+
export interface DeviceAuthorizationResponse {
|
|
81
|
+
/** Device verification code. */
|
|
82
|
+
device_code: string;
|
|
83
|
+
/** User verification code to be displayed to the user. */
|
|
84
|
+
user_code: string;
|
|
85
|
+
/** Verification URI the user should visit. */
|
|
86
|
+
verification_uri: string;
|
|
87
|
+
/** Verification URI with user_code embedded (optional convenience). */
|
|
88
|
+
verification_uri_complete?: string;
|
|
89
|
+
/** Lifetime in seconds of the device and user codes. */
|
|
90
|
+
expires_in: number;
|
|
91
|
+
/** Minimum polling interval in seconds. */
|
|
92
|
+
interval?: number;
|
|
93
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** NQCHAR as defined in RFC 6749. */
|
|
2
|
+
export declare const NQCHAR: RegExp;
|
|
3
|
+
/** Regex for validating a scope string. */
|
|
4
|
+
export declare const SCOPE: RegExp;
|
|
5
|
+
/** Regex for extracting scope tokens. */
|
|
6
|
+
export declare const SCOPE_TOKEN: RegExp;
|
|
7
|
+
/**
|
|
8
|
+
* Base class for OAuth2 scope implementations.
|
|
9
|
+
*
|
|
10
|
+
* Provides the contract that the authorization server, grants, and adapters
|
|
11
|
+
* rely on. Users who want a custom scope type (e.g. one that enforces a
|
|
12
|
+
* fixed vocabulary, or one that encodes hierarchical scopes) can extend
|
|
13
|
+
* this class; the framework only requires a constructor that accepts an
|
|
14
|
+
* optional scope string and the instance methods declared here.
|
|
15
|
+
*
|
|
16
|
+
* The default implementation is {@link BasicScope}; it stores a set of
|
|
17
|
+
* space-delimited NQCHAR tokens per RFC 6749 Section 3.3.
|
|
18
|
+
*/
|
|
19
|
+
export declare abstract class AbstractScope {
|
|
20
|
+
/** Deletes all scope tokens from this scope. */
|
|
21
|
+
abstract clear(): this;
|
|
22
|
+
/** Adds all scope tokens in the passed in scope to this scope. */
|
|
23
|
+
abstract add(scope: AbstractScope | string): this;
|
|
24
|
+
/** Removes all scope tokens in the passed in scope from this scope. */
|
|
25
|
+
abstract remove(scope: AbstractScope | string): this;
|
|
26
|
+
/** Checks that this scope has all scope tokens in the passed in scope. */
|
|
27
|
+
abstract has(scope: AbstractScope | string): boolean;
|
|
28
|
+
/** Checks that this scope is equal to the passed in scope. */
|
|
29
|
+
abstract equals(scope: AbstractScope | string): boolean;
|
|
30
|
+
/** Returns the number of scope tokens. */
|
|
31
|
+
abstract get size(): number;
|
|
32
|
+
/** Converts the scope to a string representation. */
|
|
33
|
+
abstract toString(): string;
|
|
34
|
+
/** Converts the scope to a JSON representation. */
|
|
35
|
+
abstract toJSON(): string;
|
|
36
|
+
/** Returns an iterator over the scope's tokens in insertion order. */
|
|
37
|
+
abstract [Symbol.iterator](): IterableIterator<string>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Constructor for a scope type. The framework only needs `new Scope(text)`
|
|
41
|
+
* to parse scope strings from incoming requests; static helpers like
|
|
42
|
+
* `from` / `union` / `intersection` remain specific to {@link BasicScope}
|
|
43
|
+
* and are not part of this contract.
|
|
44
|
+
*/
|
|
45
|
+
export type ScopeConstructor<S extends AbstractScope = BasicScope> = new (scope?: string) => S;
|
|
46
|
+
/** A basic implementation of OAuth2 scope. */
|
|
47
|
+
export declare class BasicScope extends AbstractScope {
|
|
48
|
+
private stringCache?;
|
|
49
|
+
private tokens;
|
|
50
|
+
/**
|
|
51
|
+
* Parses a space-delimited scope string into its tokens.
|
|
52
|
+
*
|
|
53
|
+
* @throws {InvalidScopeError} If `scope` contains characters outside the
|
|
54
|
+
* RFC 6749 NQCHAR set.
|
|
55
|
+
*/
|
|
56
|
+
constructor(scope?: string);
|
|
57
|
+
/** Creates a new scope from a scope. */
|
|
58
|
+
static from(scope: BasicScope | string): BasicScope;
|
|
59
|
+
/** Creates a new scope with all scope tokens from both scopes. */
|
|
60
|
+
static union(a: BasicScope | string, b: BasicScope | string): BasicScope;
|
|
61
|
+
/** Creates a new scope with all scope tokens that are present in both scopes. */
|
|
62
|
+
static intersection(a: BasicScope | string, b: BasicScope | string): BasicScope;
|
|
63
|
+
/** Deletes all scope tokens from this scope. */
|
|
64
|
+
clear(): this;
|
|
65
|
+
/** Adds all scope tokens in the passed in scope to this scope. */
|
|
66
|
+
add(scope: AbstractScope | string): this;
|
|
67
|
+
/** Removes all scope tokens in the passed in scope from this scope. */
|
|
68
|
+
remove(scope: AbstractScope | string): this;
|
|
69
|
+
/** Checks that this scope has all scope tokens in the passed in scope. */
|
|
70
|
+
has(scope: AbstractScope | string): boolean;
|
|
71
|
+
/** Checks that this scope is equal to the passed in scope. */
|
|
72
|
+
equals(scope: AbstractScope | string): boolean;
|
|
73
|
+
/** Returns the number of scope tokens. */
|
|
74
|
+
get size(): number;
|
|
75
|
+
/** Converts the scope to a string representation. */
|
|
76
|
+
toString(): string;
|
|
77
|
+
/** Converts the scope to a JSON representation. */
|
|
78
|
+
toJSON(): string;
|
|
79
|
+
/** Iterates the scope's tokens in insertion order. */
|
|
80
|
+
[Symbol.iterator](): IterableIterator<string>;
|
|
81
|
+
}
|