@udibo/oauth2 0.14.0 → 0.15.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/README.md +45 -24
- package/{esm → dist}/adapters/hono/_common.d.ts +5 -5
- package/{esm → dist}/adapters/hono/_common.js +1 -1
- package/{esm → dist}/adapters/hono/authorization-server.d.ts +6 -7
- package/{esm → dist}/adapters/hono/authorization-server.js +0 -1
- package/{esm → dist}/adapters/hono/bff/auth-request-store.d.ts +2 -2
- package/{esm → dist}/adapters/hono/bff/auth-request-store.js +2 -2
- package/{esm → dist}/adapters/hono/bff/bff.d.ts +22 -12
- package/{esm → dist}/adapters/hono/bff/bff.js +35 -29
- package/{esm → dist}/adapters/hono/bff/cookie-prefix.js +1 -2
- package/{esm → dist}/adapters/hono/bff/mod.d.ts +5 -6
- package/{esm → dist}/adapters/hono/bff/mod.js +1 -2
- package/{esm → dist}/adapters/hono/bff/proxy.js +2 -1
- package/{esm → dist}/adapters/hono/bff/session-store.d.ts +2 -2
- package/{esm → dist}/adapters/hono/bff/session-store.js +7 -6
- package/{esm → dist}/adapters/hono/bff/testing.d.ts +7 -8
- package/{esm → dist}/adapters/hono/bff/testing.js +19 -22
- package/{esm → dist}/adapters/hono/identity.d.ts +1 -2
- package/{esm → dist}/adapters/hono/identity.js +10 -10
- package/{esm → dist}/adapters/hono/log.d.ts +0 -1
- package/{esm → dist}/adapters/hono/log.js +0 -6
- package/{esm → dist}/adapters/hono/resource-server.d.ts +5 -6
- package/{esm → dist}/adapters/hono/resource-server.js +0 -1
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +3 -0
- package/dist/cli/idp/config.d.ts +110 -0
- package/dist/cli/idp/config.js +269 -0
- package/dist/cli/idp/mod.d.ts +20 -0
- package/dist/cli/idp/mod.js +175 -0
- package/dist/cli/idp/pages.d.ts +56 -0
- package/dist/cli/idp/pages.js +190 -0
- package/dist/cli/idp/server.d.ts +93 -0
- package/dist/cli/idp/server.js +559 -0
- package/dist/cli/keygen.d.ts +13 -0
- package/dist/cli/keygen.js +30 -0
- package/dist/cli/mod.d.ts +34 -0
- package/dist/cli/mod.js +94 -0
- package/{esm → dist}/client/_http.d.ts +1 -1
- package/{esm → dist}/client/base.d.ts +1 -1
- package/{esm → dist}/client/bff-client.d.ts +1 -1
- package/{esm → dist}/client/bff-client.js +7 -6
- package/{esm → dist}/client/browser-storage.d.ts +1 -1
- package/{esm → dist}/client/check.js +1 -1
- package/{esm → dist}/client/direct-client.d.ts +6 -6
- package/{esm → dist}/client/direct-client.js +11 -13
- package/{esm → dist}/client/discovery-cache.d.ts +1 -1
- package/{esm → dist}/client/discovery-cache.js +2 -2
- package/{esm → dist}/client/events.d.ts +1 -1
- package/{esm → dist}/client/mod.d.ts +11 -12
- package/{esm → dist}/client/mod.js +1 -1
- package/{esm → dist}/errors.d.ts +1 -1
- package/{esm → dist}/errors.js +1 -1
- package/{esm → dist}/identity/events.d.ts +1 -1
- package/{esm → dist}/identity/external/_shared.d.ts +1 -1
- package/{esm → dist}/identity/external/_shared.js +1 -2
- package/{esm → dist}/identity/external/apple-client-secret.d.ts +1 -1
- package/{esm → dist}/identity/external/apple-client-secret.js +6 -7
- package/{esm → dist}/identity/external/apple.d.ts +5 -5
- package/{esm → dist}/identity/external/apple.js +10 -11
- package/{esm → dist}/identity/external/discord.d.ts +3 -3
- package/{esm → dist}/identity/external/discord.js +2 -2
- package/{esm → dist}/identity/external/flow.d.ts +1 -1
- package/{esm → dist}/identity/external/flow.js +2 -2
- package/{esm → dist}/identity/external/github.d.ts +3 -3
- package/{esm → dist}/identity/external/github.js +12 -17
- package/{esm → dist}/identity/external/google.d.ts +5 -5
- package/{esm → dist}/identity/external/google.js +2 -2
- package/{esm → dist}/identity/external/mod.d.ts +12 -13
- package/{esm → dist}/identity/external/mod.js +0 -1
- package/{esm → dist}/identity/external/oauth2.d.ts +1 -1
- package/{esm → dist}/identity/external/oauth2.js +8 -8
- package/{esm → dist}/identity/external/oidc.d.ts +4 -4
- package/{esm → dist}/identity/external/oidc.js +9 -8
- package/{esm → dist}/identity/hibp.d.ts +1 -1
- package/{esm → dist}/identity/hibp.js +1 -1
- package/{esm → dist}/identity/lockout.js +1 -2
- package/{esm → dist}/identity/mfa/mod.d.ts +4 -5
- package/{esm → dist}/identity/mfa/mod.js +1 -2
- package/{esm → dist}/identity/mfa/service.d.ts +3 -3
- package/{esm → dist}/identity/mfa/service.js +4 -3
- package/{esm → dist}/identity/mfa/totp.d.ts +1 -1
- package/{esm → dist}/identity/mfa/totp.js +2 -2
- package/{esm → dist}/identity/migration.d.ts +2 -3
- package/{esm → dist}/identity/migration.js +3 -4
- package/{esm → dist}/identity/mod.d.ts +14 -15
- package/{esm → dist}/identity/mod.js +0 -1
- package/{esm → dist}/identity/otp.d.ts +1 -1
- package/{esm → dist}/identity/otp.js +4 -2
- package/{esm → dist}/identity/password.js +8 -5
- package/{esm → dist}/identity/rate-limit.d.ts +1 -1
- package/{esm → dist}/identity/service.d.ts +10 -10
- package/{esm → dist}/identity/service.js +17 -18
- package/{esm → dist}/identity/session.js +2 -2
- package/{esm → dist}/identity/token-flow.js +3 -2
- package/{esm → dist}/models/authorization-code.d.ts +3 -3
- package/{esm → dist}/models/authorization.d.ts +1 -1
- package/{esm → dist}/models/authorization.js +1 -2
- package/{esm → dist}/models/device-authorization.d.ts +2 -2
- package/{esm → dist}/models/token.d.ts +3 -3
- package/{esm → dist}/react/callback.d.ts +1 -1
- package/{esm → dist}/react/callback.js +0 -1
- package/{esm → dist}/react/components/class-names.d.ts +1 -1
- package/{esm → dist}/react/components/class-names.js +3 -2
- package/{esm → dist}/react/components/internal.d.ts +2 -2
- package/{esm → dist}/react/components/internal.js +5 -11
- package/{esm → dist}/react/components/mfa-challenge-form.d.ts +2 -2
- package/{esm → dist}/react/components/mfa-challenge-form.js +4 -6
- package/{esm → dist}/react/components/mfa-enrollment-form.d.ts +2 -2
- package/{esm → dist}/react/components/mfa-enrollment-form.js +2 -6
- package/{esm → dist}/react/components/mod.d.ts +20 -21
- package/{esm → dist}/react/components/mod.js +1 -2
- package/{esm → dist}/react/components/request-password-reset-form.d.ts +2 -2
- package/{esm → dist}/react/components/request-password-reset-form.js +1 -3
- package/{esm → dist}/react/components/reset-password-form.d.ts +2 -2
- package/{esm → dist}/react/components/reset-password-form.js +2 -2
- package/{esm → dist}/react/components/sign-in-form.d.ts +2 -2
- package/{esm → dist}/react/components/sign-in-form.js +1 -5
- package/{esm → dist}/react/components/sign-up-form.d.ts +2 -2
- package/{esm → dist}/react/components/sign-up-form.js +4 -10
- package/{esm → dist}/react/components/types.d.ts +2 -2
- package/{esm → dist}/react/components/use-auth-form.d.ts +3 -3
- package/{esm → dist}/react/components/use-auth-form.js +4 -7
- package/{esm → dist}/react/components/user-menu.d.ts +2 -2
- package/{esm → dist}/react/components/user-menu.js +9 -14
- package/{esm → dist}/react/context.d.ts +1 -1
- package/{esm → dist}/react/mod.d.ts +6 -7
- package/{esm → dist}/react/mod.js +0 -1
- package/{esm → dist}/react/provider.d.ts +2 -2
- package/{esm → dist}/react/require-auth.js +1 -3
- package/{esm → dist}/react/testing.d.ts +2 -3
- package/{esm → dist}/react/testing.js +1 -2
- package/{esm → dist}/react/use-authorization.d.ts +1 -1
- package/{esm → dist}/react/use-oauth2.d.ts +8 -1
- package/{esm → dist}/react/use-oauth2.js +0 -1
- package/{esm → dist}/server/_clock-skew.js +2 -1
- package/{esm → dist}/server/authorization-server.d.ts +40 -41
- package/{esm → dist}/server/authorization-server.js +32 -42
- package/{esm → dist}/server/client-authentication.d.ts +2 -2
- package/{esm → dist}/server/grants/authorization-code.d.ts +9 -9
- package/{esm → dist}/server/grants/authorization-code.js +5 -6
- package/{esm → dist}/server/grants/client-credentials.d.ts +4 -4
- package/{esm → dist}/server/grants/device-authorization.d.ts +6 -6
- package/{esm → dist}/server/grants/device-authorization.js +4 -4
- package/{esm → dist}/server/grants/grant.d.ts +7 -7
- package/{esm → dist}/server/grants/grant.js +7 -7
- package/{esm → dist}/server/grants/password.d.ts +5 -5
- package/{esm → dist}/server/grants/refresh-token.d.ts +4 -4
- package/{esm → dist}/server/grants/refresh-token.js +5 -6
- package/{esm → dist}/server/introspection-token-reader.d.ts +5 -5
- package/{esm → dist}/server/introspection-token-reader.js +4 -4
- package/{esm → dist}/server/jwks-token-reader.d.ts +5 -5
- package/{esm → dist}/server/jwks-token-reader.js +4 -4
- package/{esm → dist}/server/mod.d.ts +12 -13
- package/{esm → dist}/server/mod.js +0 -1
- package/{esm → dist}/server/public-suffix/mod.d.ts +2 -3
- package/{esm → dist}/server/public-suffix/mod.js +1 -2
- package/{esm → dist}/server/public-suffix/rules.d.ts +1 -1
- package/{esm → dist}/server/public-suffix/rules.js +1 -1
- package/{esm → dist}/server/redirect-uri.js +5 -4
- package/{esm → dist}/server/resource-server.d.ts +11 -12
- package/{esm → dist}/server/resource-server.js +12 -14
- package/{esm → dist}/server/services/authorization-code.d.ts +5 -5
- package/{esm → dist}/server/services/client.d.ts +1 -1
- package/{esm → dist}/server/services/device-authorization.d.ts +3 -3
- package/{esm → dist}/server/services/token.d.ts +6 -6
- package/{esm → dist}/server/services/token.js +3 -1
- package/{esm → dist}/server/services/user.d.ts +1 -1
- package/{esm → dist}/server/signing-keys.d.ts +1 -1
- package/{esm → dist}/server/signing-keys.js +8 -2
- package/{esm → dist}/server/utils/hash.js +1 -1
- package/{esm → dist}/testing/contract/auth-request-storage.d.ts +1 -1
- package/{esm → dist}/testing/contract/auth-request-storage.js +24 -29
- package/{esm → dist}/testing/contract/authorization-code.d.ts +6 -6
- package/{esm → dist}/testing/contract/authorization-code.js +16 -17
- package/{esm → dist}/testing/contract/client.d.ts +4 -4
- package/{esm → dist}/testing/contract/client.js +14 -15
- package/{esm → dist}/testing/contract/device-authorization.d.ts +6 -6
- package/{esm → dist}/testing/contract/device-authorization.js +37 -39
- package/{esm → dist}/testing/contract/identity-session.d.ts +6 -1
- package/{esm → dist}/testing/contract/identity-session.js +44 -36
- package/{esm → dist}/testing/contract/identity-user-store.d.ts +8 -2
- package/{esm → dist}/testing/contract/identity-user-store.js +48 -46
- package/{esm → dist}/testing/contract/lockout-store.d.ts +1 -1
- package/{esm → dist}/testing/contract/lockout-store.js +23 -24
- package/{esm → dist}/testing/contract/mfa-store.d.ts +1 -1
- package/{esm → dist}/testing/contract/mfa-store.js +53 -54
- package/{esm → dist}/testing/contract/mod.d.ts +15 -16
- package/{esm → dist}/testing/contract/mod.js +0 -1
- package/{esm → dist}/testing/contract/otp-store.d.ts +1 -1
- package/{esm → dist}/testing/contract/otp-store.js +33 -34
- package/{esm → dist}/testing/contract/rate-limit-store.d.ts +1 -1
- package/{esm → dist}/testing/contract/rate-limit-store.js +15 -16
- package/{esm → dist}/testing/contract/tenant.js +361 -330
- package/{esm → dist}/testing/contract/token-flow-store.d.ts +1 -1
- package/{esm → dist}/testing/contract/token-flow-store.js +27 -32
- package/{esm → dist}/testing/contract/token-reader.d.ts +3 -3
- package/{esm → dist}/testing/contract/token-reader.js +6 -7
- package/{esm → dist}/testing/contract/token.d.ts +7 -7
- package/{esm → dist}/testing/contract/token.js +48 -53
- package/{esm → dist}/testing/contract/user.d.ts +2 -2
- package/{esm → dist}/testing/contract/user.js +8 -9
- package/{esm → dist}/testing/mod.d.ts +5 -6
- package/{esm → dist}/testing/mod.js +2 -3
- package/{esm → dist}/testing/server.d.ts +7 -6
- package/{esm → dist}/testing/server.js +2 -1
- package/{esm → dist}/testing/services.d.ts +11 -11
- package/{esm → dist}/testing/services.js +8 -8
- package/{esm → dist}/testing/tenant.d.ts +11 -7
- package/{esm → dist}/testing/tenant.js +109 -94
- package/dist/utils/_constant-time.d.ts +12 -0
- package/dist/utils/_constant-time.js +19 -0
- package/{esm → dist}/utils/_default-fetch.js +4 -1
- package/dist/utils/_delay.d.ts +13 -0
- package/dist/utils/_delay.js +28 -0
- package/dist/utils/_encoding.d.ts +39 -0
- package/dist/utils/_encoding.js +126 -0
- package/{esm → dist}/utils/authentication-context.d.ts +1 -1
- package/{esm → dist}/utils/crypto.d.ts +2 -3
- package/{esm → dist}/utils/crypto.js +3 -4
- package/{esm → dist}/utils/pkce.js +1 -1
- package/{esm → dist}/utils/text.js +1 -1
- package/{esm → dist}/utils/url.d.ts +0 -1
- package/{esm → dist}/utils/url.js +0 -1
- package/package.json +156 -33
- package/esm/_dnt.polyfills.d.ts +0 -31
- package/esm/_dnt.polyfills.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.js +0 -47
- package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts +0 -28
- package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.js +0 -65
- package/esm/deps/jsr.io/@std/assert/1.0.19/assert.d.ts +0 -16
- package/esm/deps/jsr.io/@std/assert/1.0.19/assert.js +0 -23
- package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts +0 -25
- package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.js +0 -30
- package/esm/deps/jsr.io/@std/assert/1.0.19/equal.d.ts +0 -24
- package/esm/deps/jsr.io/@std/assert/1.0.19/equal.js +0 -193
- package/esm/deps/jsr.io/@std/assert/1.0.19/equals.d.ts +0 -36
- package/esm/deps/jsr.io/@std/assert/1.0.19/equals.js +0 -61
- package/esm/deps/jsr.io/@std/assert/1.0.19/exists.d.ts +0 -17
- package/esm/deps/jsr.io/@std/assert/1.0.19/exists.js +0 -27
- package/esm/deps/jsr.io/@std/assert/1.0.19/fail.d.ts +0 -14
- package/esm/deps/jsr.io/@std/assert/1.0.19/fail.js +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.19/false.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.19/false.js +0 -23
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater.d.ts +0 -19
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts +0 -19
- package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts +0 -22
- package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.js +0 -52
- package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts +0 -24
- package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.js +0 -53
- package/esm/deps/jsr.io/@std/assert/1.0.19/less.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.19/less.js +0 -28
- package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts +0 -19
- package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.19/match.d.ts +0 -17
- package/esm/deps/jsr.io/@std/assert/1.0.19/match.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.19/mod.d.ts +0 -43
- package/esm/deps/jsr.io/@std/assert/1.0.19/mod.js +0 -45
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.js +0 -39
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts +0 -19
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts +0 -17
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts +0 -22
- package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.js +0 -32
- package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts +0 -28
- package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.js +0 -177
- package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts +0 -41
- package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.js +0 -53
- package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts +0 -23
- package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.js +0 -58
- package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts +0 -17
- package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.19/throws.d.ts +0 -44
- package/esm/deps/jsr.io/@std/assert/1.0.19/throws.js +0 -44
- package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts +0 -14
- package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.js +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts +0 -14
- package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.js +0 -20
- package/esm/deps/jsr.io/@std/async/1.5.0/delay.d.ts +0 -44
- package/esm/deps/jsr.io/@std/async/1.5.0/delay.js +0 -84
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +0 -39
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +0 -61
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.d.ts +0 -22
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.js +0 -51
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.d.ts +0 -34
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.js +0 -192
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.d.ts +0 -34
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.js +0 -113
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.d.ts +0 -3
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.js +0 -13
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.d.ts +0 -8
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.js +0 -2
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.d.ts +0 -1
- package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.js +0 -26
- package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.d.ts +0 -60
- package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.js +0 -152
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.d.ts +0 -39
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.js +0 -87
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.d.ts +0 -39
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.js +0 -131
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.d.ts +0 -39
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.js +0 -82
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.d.ts +0 -39
- package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.js +0 -72
- package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.d.ts +0 -38
- package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.js +0 -87
- package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.d.ts +0 -97
- package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.js +0 -99
- package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.d.ts +0 -119
- package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.js +0 -209
- package/esm/deps/jsr.io/@std/http/1.1.3/status.d.ts +0 -343
- package/esm/deps/jsr.io/@std/http/1.1.3/status.js +0 -343
- package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.d.ts +0 -159
- package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.js +0 -223
- package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.d.ts +0 -79
- package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.js +0 -116
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff.d.ts +0 -139
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff.js +0 -277
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.d.ts +0 -98
- package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.js +0 -181
- package/esm/deps/jsr.io/@std/internal/1.0.14/format.d.ts +0 -29
- package/esm/deps/jsr.io/@std/internal/1.0.14/format.js +0 -68
- package/esm/deps/jsr.io/@std/internal/1.0.14/styles.d.ts +0 -158
- package/esm/deps/jsr.io/@std/internal/1.0.14/styles.js +0 -206
- package/esm/deps/jsr.io/@std/internal/1.0.14/types.d.ts +0 -24
- package/esm/deps/jsr.io/@std/internal/1.0.14/types.js +0 -3
- package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.d.ts +0 -91
- package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.js +0 -347
- package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.d.ts +0 -382
- package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.js +0 -1110
- package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.d.ts +0 -363
- package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.js +0 -616
- package/esm/package.json +0 -3
- /package/{esm → dist}/adapters/hono/bff/cookie-prefix.d.ts +0 -0
- /package/{esm → dist}/adapters/hono/bff/proxy.d.ts +0 -0
- /package/{esm → dist}/client/_http.js +0 -0
- /package/{esm → dist}/client/base.js +0 -0
- /package/{esm → dist}/client/browser-storage.js +0 -0
- /package/{esm → dist}/client/check.d.ts +0 -0
- /package/{esm → dist}/client/events.js +0 -0
- /package/{esm → dist}/client/storage.d.ts +0 -0
- /package/{esm → dist}/client/storage.js +0 -0
- /package/{esm → dist}/identity/captcha.d.ts +0 -0
- /package/{esm → dist}/identity/captcha.js +0 -0
- /package/{esm → dist}/identity/delivery.d.ts +0 -0
- /package/{esm → dist}/identity/delivery.js +0 -0
- /package/{esm → dist}/identity/errors.d.ts +0 -0
- /package/{esm → dist}/identity/errors.js +0 -0
- /package/{esm → dist}/identity/events.js +0 -0
- /package/{esm → dist}/identity/external/_token-exchange.d.ts +0 -0
- /package/{esm → dist}/identity/external/_token-exchange.js +0 -0
- /package/{esm → dist}/identity/external/errors.d.ts +0 -0
- /package/{esm → dist}/identity/external/errors.js +0 -0
- /package/{esm → dist}/identity/external/provider.d.ts +0 -0
- /package/{esm → dist}/identity/external/provider.js +0 -0
- /package/{esm → dist}/identity/identifier.d.ts +0 -0
- /package/{esm → dist}/identity/identifier.js +0 -0
- /package/{esm → dist}/identity/lockout.d.ts +0 -0
- /package/{esm → dist}/identity/mfa/recovery-codes.d.ts +0 -0
- /package/{esm → dist}/identity/mfa/recovery-codes.js +0 -0
- /package/{esm → dist}/identity/password-policy.d.ts +0 -0
- /package/{esm → dist}/identity/password-policy.js +0 -0
- /package/{esm → dist}/identity/password.d.ts +0 -0
- /package/{esm → dist}/identity/rate-limit.js +0 -0
- /package/{esm → dist}/identity/session.d.ts +0 -0
- /package/{esm → dist}/identity/token-flow.d.ts +0 -0
- /package/{esm → dist}/models/authentication.d.ts +0 -0
- /package/{esm → dist}/models/authentication.js +0 -0
- /package/{esm → dist}/models/authorization-code.js +0 -0
- /package/{esm → dist}/models/client.d.ts +0 -0
- /package/{esm → dist}/models/client.js +0 -0
- /package/{esm → dist}/models/device-authorization.js +0 -0
- /package/{esm → dist}/models/responses.d.ts +0 -0
- /package/{esm → dist}/models/responses.js +0 -0
- /package/{esm → dist}/models/scope.d.ts +0 -0
- /package/{esm → dist}/models/scope.js +0 -0
- /package/{esm → dist}/models/token.js +0 -0
- /package/{esm → dist}/react/components/types.js +0 -0
- /package/{esm → dist}/react/context.js +0 -0
- /package/{esm → dist}/react/provider.js +0 -0
- /package/{esm → dist}/react/require-auth.d.ts +0 -0
- /package/{esm → dist}/react/use-authorization.js +0 -0
- /package/{esm → dist}/server/_clock-skew.d.ts +0 -0
- /package/{esm → dist}/server/client-authentication.js +0 -0
- /package/{esm → dist}/server/grants/client-credentials.js +0 -0
- /package/{esm → dist}/server/grants/password.js +0 -0
- /package/{esm → dist}/server/redirect-uri.d.ts +0 -0
- /package/{esm → dist}/server/services/authorization-code.js +0 -0
- /package/{esm → dist}/server/services/client.js +0 -0
- /package/{esm → dist}/server/services/device-authorization.js +0 -0
- /package/{esm → dist}/server/services/user.js +0 -0
- /package/{esm → dist}/server/utils/hash.d.ts +0 -0
- /package/{esm → dist}/testing/contract/_race.d.ts +0 -0
- /package/{esm → dist}/testing/contract/_race.js +0 -0
- /package/{esm → dist}/testing/contract/tenant.d.ts +0 -0
- /package/{esm → dist}/utils/_body.d.ts +0 -0
- /package/{esm → dist}/utils/_body.js +0 -0
- /package/{esm → dist}/utils/_buffer.d.ts +0 -0
- /package/{esm → dist}/utils/_buffer.js +0 -0
- /package/{esm → dist}/utils/_default-fetch.d.ts +0 -0
- /package/{esm → dist}/utils/_timing-safe.d.ts +0 -0
- /package/{esm → dist}/utils/_timing-safe.js +0 -0
- /package/{esm → dist}/utils/authentication-context.js +0 -0
- /package/{esm → dist}/utils/basic-auth.d.ts +0 -0
- /package/{esm → dist}/utils/basic-auth.js +0 -0
- /package/{esm → dist}/utils/pkce.d.ts +0 -0
- /package/{esm → dist}/utils/text.d.ts +0 -0
|
@@ -38,8 +38,7 @@
|
|
|
38
38
|
*
|
|
39
39
|
* @module
|
|
40
40
|
*/
|
|
41
|
-
import { assert,
|
|
42
|
-
import { beforeEach, describe, it } from "../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
|
|
41
|
+
import { assert, beforeEach, describe, expect, it } from "vitest";
|
|
43
42
|
import { CONCURRENT_CALLERS, race } from "./_race.js";
|
|
44
43
|
function record(overrides = {}) {
|
|
45
44
|
return {
|
|
@@ -69,33 +68,33 @@ export function runAuthRequestStorageContractTests(options) {
|
|
|
69
68
|
});
|
|
70
69
|
describe("set / get / delete / clear", () => {
|
|
71
70
|
it("returns null for an unknown state", async () => {
|
|
72
|
-
|
|
71
|
+
expect(await store.get("no-such-state")).toBe(null);
|
|
73
72
|
});
|
|
74
73
|
it("round-trips every field of a stored record", async () => {
|
|
75
74
|
const stored = record();
|
|
76
75
|
await store.set("state-1", stored);
|
|
77
|
-
|
|
76
|
+
expect(await store.get("state-1")).toStrictEqual(stored);
|
|
78
77
|
});
|
|
79
78
|
it("keeps records under different states independent", async () => {
|
|
80
79
|
await store.set("state-1", record({ codeVerifier: "verifier-1" }));
|
|
81
80
|
await store.set("state-2", record({ codeVerifier: "verifier-2" }));
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
expect((await store.get("state-1"))?.codeVerifier).toBe("verifier-1");
|
|
82
|
+
expect((await store.get("state-2"))?.codeVerifier).toBe("verifier-2");
|
|
84
83
|
});
|
|
85
84
|
it("deletes one record and leaves the others", async () => {
|
|
86
85
|
await store.set("state-1", record());
|
|
87
86
|
await store.set("state-2", record());
|
|
88
87
|
await store.delete("state-1");
|
|
89
|
-
|
|
90
|
-
assert(await store.get("state-2") !== null, "delete must remove only the named state");
|
|
88
|
+
expect(await store.get("state-1")).toBe(null);
|
|
89
|
+
assert((await store.get("state-2")) !== null, "delete must remove only the named state");
|
|
91
90
|
});
|
|
92
91
|
if (clearScope === "all") {
|
|
93
92
|
it("clears every record", async () => {
|
|
94
93
|
await store.set("state-1", record());
|
|
95
94
|
await store.set("state-2", record());
|
|
96
95
|
await store.clear();
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
expect(await store.get("state-1")).toBe(null);
|
|
97
|
+
expect(await store.get("state-2")).toBe(null);
|
|
99
98
|
});
|
|
100
99
|
}
|
|
101
100
|
else {
|
|
@@ -107,15 +106,15 @@ export function runAuthRequestStorageContractTests(options) {
|
|
|
107
106
|
await store.clear();
|
|
108
107
|
const message = "clear() on a shared store must not cancel another user's sign-in " +
|
|
109
108
|
"that is still in progress";
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
expect(await store.get("state-2"), message).toStrictEqual(second);
|
|
110
|
+
expect(expectTake
|
|
112
111
|
? await store.take("state-1")
|
|
113
|
-
: await store.get("state-1"),
|
|
112
|
+
: await store.get("state-1"), message).toStrictEqual(first);
|
|
114
113
|
});
|
|
115
114
|
it('removes a record past any lifetime (clear: "scoped")', async () => {
|
|
116
115
|
await store.set("expired", record({ createdAt: 0 }));
|
|
117
116
|
await store.clear();
|
|
118
|
-
|
|
117
|
+
expect(await store.get("expired"), "a scoped clear() must still remove expired records").toBe(null);
|
|
119
118
|
});
|
|
120
119
|
}
|
|
121
120
|
});
|
|
@@ -130,22 +129,22 @@ export function runAuthRequestStorageContractTests(options) {
|
|
|
130
129
|
it("returns the record and removes it", async () => {
|
|
131
130
|
const stored = record();
|
|
132
131
|
await store.set("state-1", stored);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
expect(await store.take("state-1")).toStrictEqual(stored);
|
|
133
|
+
expect(await store.get("state-1"), "a taken record must not be readable again").toBe(null);
|
|
134
|
+
expect(await store.take("state-1")).toBe(null);
|
|
136
135
|
});
|
|
137
136
|
it("returns null for an unknown state", async () => {
|
|
138
|
-
|
|
137
|
+
expect(await store.take("no-such-state")).toBe(null);
|
|
139
138
|
});
|
|
140
139
|
it(`hands one record to exactly one of ${CONCURRENT_CALLERS} concurrent takes`, async () => {
|
|
141
140
|
const stored = record();
|
|
142
141
|
await store.set("state-1", stored);
|
|
143
142
|
const results = await race(() => store.take("state-1"));
|
|
144
143
|
const winners = results.filter((result) => result !== null);
|
|
145
|
-
|
|
146
|
-
"receive the PKCE verifier");
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
expect(winners.length, "a state is single-use — callbacks racing on it must not each " +
|
|
145
|
+
"receive the PKCE verifier").toBe(1);
|
|
146
|
+
expect(winners[0]).toStrictEqual(stored);
|
|
147
|
+
expect(await store.get("state-1")).toBe(null);
|
|
149
148
|
});
|
|
150
149
|
it("hands each record to its own taker when two states are taken concurrently", async () => {
|
|
151
150
|
await store.set("state-1", record({ codeVerifier: "verifier-1" }));
|
|
@@ -154,17 +153,13 @@ export function runAuthRequestStorageContractTests(options) {
|
|
|
154
153
|
store.take("state-1"),
|
|
155
154
|
store.take("state-2"),
|
|
156
155
|
]);
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
expect(first?.codeVerifier).toBe("verifier-1");
|
|
157
|
+
expect(second?.codeVerifier).toBe("verifier-2");
|
|
159
158
|
});
|
|
160
159
|
});
|
|
161
160
|
}
|
|
162
161
|
else {
|
|
163
|
-
it({
|
|
164
|
-
name: "take is not implemented — two callbacks racing on one state can both redeem it (take: false)",
|
|
165
|
-
ignore: true,
|
|
166
|
-
fn: () => { },
|
|
167
|
-
});
|
|
162
|
+
it.skip("take is not implemented — two callbacks racing on one state can both redeem it (take: false)", () => { });
|
|
168
163
|
}
|
|
169
164
|
});
|
|
170
165
|
}
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import type { ClientInterface } from "../../models/client.
|
|
8
|
-
import type { AbstractScope, BasicScope } from "../../models/scope.
|
|
9
|
-
import type { AuthorizationCodeServiceInterface } from "../../server/services/authorization-code.
|
|
10
|
-
import type { ClientServiceInterface } from "../../server/services/client.
|
|
11
|
-
import type { UserServiceInterface } from "../../server/services/user.
|
|
12
|
-
import type { MemoryUserShape } from "../services.
|
|
7
|
+
import type { ClientInterface } from "../../models/client.ts";
|
|
8
|
+
import type { AbstractScope, BasicScope } from "../../models/scope.ts";
|
|
9
|
+
import type { AuthorizationCodeServiceInterface } from "../../server/services/authorization-code.ts";
|
|
10
|
+
import type { ClientServiceInterface } from "../../server/services/client.ts";
|
|
11
|
+
import type { UserServiceInterface } from "../../server/services/user.ts";
|
|
12
|
+
import type { MemoryUserShape } from "../services.ts";
|
|
13
13
|
/** Options for {@link runAuthorizationCodeServiceContractTests}. */
|
|
14
14
|
export interface AuthorizationCodeServiceContractOptions<C extends ClientInterface, U extends MemoryUserShape, S extends AbstractScope = BasicScope> {
|
|
15
15
|
/** Returns fresh services for each test. */
|
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import { beforeEach, describe, it } from "../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
|
|
7
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
9
8
|
const defaultMakeUser = (seq) => ({ id: `u${seq}`, username: `user${seq}` });
|
|
10
9
|
const defaultMakeClient = (seq) => ({ id: `client-${seq}`, grants: ["authorization_code"] });
|
|
11
10
|
/** Runs the {@link AuthorizationCodeServiceInterface} contract suite. */
|
|
12
11
|
export function runAuthorizationCodeServiceContractTests(options) {
|
|
13
|
-
const makeUser = options.makeUser ??
|
|
14
|
-
const makeClient = options.makeClient ??
|
|
12
|
+
const makeUser = options.makeUser ?? defaultMakeUser;
|
|
13
|
+
const makeClient = options.makeClient ?? defaultMakeClient;
|
|
15
14
|
describe(options.describeName ?? "AuthorizationCodeServiceInterface contract", () => {
|
|
16
15
|
let userService;
|
|
17
16
|
let clientService;
|
|
@@ -31,11 +30,11 @@ export function runAuthorizationCodeServiceContractTests(options) {
|
|
|
31
30
|
it("generateCode returns unique strings", async () => {
|
|
32
31
|
const a = await codeService.generateCode(client, user);
|
|
33
32
|
const b = await codeService.generateCode(client, user);
|
|
34
|
-
|
|
33
|
+
expect(a !== b).toStrictEqual(true);
|
|
35
34
|
});
|
|
36
35
|
it("expiresAt returns a future date", async () => {
|
|
37
36
|
const expires = await codeService.expiresAt(client, user);
|
|
38
|
-
|
|
37
|
+
expect(expires.getTime() > Date.now()).toStrictEqual(true);
|
|
39
38
|
});
|
|
40
39
|
it("save + get round-trips an authorization code", async () => {
|
|
41
40
|
const code = await codeService.generateCode(client, user);
|
|
@@ -52,14 +51,14 @@ export function runAuthorizationCodeServiceContractTests(options) {
|
|
|
52
51
|
};
|
|
53
52
|
await codeService.save(ac);
|
|
54
53
|
const fetched = await codeService.get(code);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
expect(fetched?.code).toStrictEqual(code);
|
|
55
|
+
expect(fetched?.client.id).toStrictEqual(client.id);
|
|
56
|
+
expect(fetched?.redirectUri).toStrictEqual("http://app/cb");
|
|
57
|
+
expect(fetched?.challenge).toStrictEqual("abc");
|
|
58
|
+
expect(fetched?.nonce).toStrictEqual("nonce-1");
|
|
60
59
|
});
|
|
61
60
|
it("get returns undefined for an unknown code", async () => {
|
|
62
|
-
|
|
61
|
+
expect(await codeService.get("missing")).toBe(undefined);
|
|
63
62
|
});
|
|
64
63
|
it("revoke deletes the code by string", async () => {
|
|
65
64
|
const code = await codeService.generateCode(client, user);
|
|
@@ -70,8 +69,8 @@ export function runAuthorizationCodeServiceContractTests(options) {
|
|
|
70
69
|
user,
|
|
71
70
|
});
|
|
72
71
|
const ok = await codeService.revoke(code);
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
expect(ok).toBe(true);
|
|
73
|
+
expect(await codeService.get(code)).toBe(undefined);
|
|
75
74
|
});
|
|
76
75
|
it("revoke deletes the code by object", async () => {
|
|
77
76
|
const code = await codeService.generateCode(client, user);
|
|
@@ -83,11 +82,11 @@ export function runAuthorizationCodeServiceContractTests(options) {
|
|
|
83
82
|
};
|
|
84
83
|
await codeService.save(ac);
|
|
85
84
|
const ok = await codeService.revoke(ac);
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
expect(ok).toBe(true);
|
|
86
|
+
expect(await codeService.get(code)).toBe(undefined);
|
|
88
87
|
});
|
|
89
88
|
it("revoke returns false for an unknown code", async () => {
|
|
90
|
-
|
|
89
|
+
expect(await codeService.revoke("missing")).toBe(false);
|
|
91
90
|
});
|
|
92
91
|
});
|
|
93
92
|
}
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
*
|
|
49
49
|
* @module
|
|
50
50
|
*/
|
|
51
|
-
import type { ClientInterface } from "../../models/client.
|
|
52
|
-
import type { ClientServiceInterface } from "../../server/services/client.
|
|
53
|
-
import type { UserServiceInterface } from "../../server/services/user.
|
|
54
|
-
import type { MemoryUserShape } from "../services.
|
|
51
|
+
import type { ClientInterface } from "../../models/client.ts";
|
|
52
|
+
import type { ClientServiceInterface } from "../../server/services/client.ts";
|
|
53
|
+
import type { UserServiceInterface } from "../../server/services/user.ts";
|
|
54
|
+
import type { MemoryUserShape } from "../services.ts";
|
|
55
55
|
/** Options for {@link runClientServiceContractTests}. */
|
|
56
56
|
export interface ClientServiceContractOptions<C extends ClientInterface, U extends MemoryUserShape> {
|
|
57
57
|
/**
|
|
@@ -48,14 +48,13 @@
|
|
|
48
48
|
*
|
|
49
49
|
* @module
|
|
50
50
|
*/
|
|
51
|
-
import {
|
|
52
|
-
import { beforeEach, describe, it } from "../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
|
|
51
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
53
52
|
const defaultMakeUser = (seq) => ({ id: `u${seq}`, username: `user${seq}` });
|
|
54
53
|
const defaultMakeClient = (seq) => ({ id: `client-${seq}`, grants: ["client_credentials"] });
|
|
55
54
|
/** Runs the {@link ClientServiceInterface} contract suite. */
|
|
56
55
|
export function runClientServiceContractTests(options) {
|
|
57
|
-
const makeUser = options.makeUser ??
|
|
58
|
-
const makeClient = options.makeClient ??
|
|
56
|
+
const makeUser = options.makeUser ?? defaultMakeUser;
|
|
57
|
+
const makeClient = options.makeClient ?? defaultMakeClient;
|
|
59
58
|
describe(options.describeName ?? "ClientServiceInterface contract", () => {
|
|
60
59
|
let userService;
|
|
61
60
|
let clientService;
|
|
@@ -66,13 +65,13 @@ export function runClientServiceContractTests(options) {
|
|
|
66
65
|
});
|
|
67
66
|
describe("get", () => {
|
|
68
67
|
it("returns undefined for an unknown id", async () => {
|
|
69
|
-
|
|
68
|
+
expect(await clientService.get("missing")).toBe(undefined);
|
|
70
69
|
});
|
|
71
70
|
it("returns the registered client", async () => {
|
|
72
71
|
const client = makeClient(1);
|
|
73
72
|
await options.addClient(clientService, client);
|
|
74
73
|
const fetched = await clientService.get(client.id);
|
|
75
|
-
|
|
74
|
+
expect(fetched?.id).toStrictEqual(client.id);
|
|
76
75
|
});
|
|
77
76
|
});
|
|
78
77
|
describe("getAuthenticated", () => {
|
|
@@ -80,41 +79,41 @@ export function runClientServiceContractTests(options) {
|
|
|
80
79
|
const client = makeClient(2);
|
|
81
80
|
await options.addClient(clientService, client);
|
|
82
81
|
const auth = await clientService.getAuthenticated(client.id);
|
|
83
|
-
|
|
82
|
+
expect(auth?.id).toStrictEqual(client.id);
|
|
84
83
|
});
|
|
85
84
|
it("returns undefined for a public client that presents a secret", async () => {
|
|
86
85
|
const client = makeClient(9);
|
|
87
86
|
await options.addClient(clientService, client);
|
|
88
|
-
|
|
87
|
+
expect(await clientService.getAuthenticated(client.id, "unissued")).toBe(undefined);
|
|
89
88
|
});
|
|
90
89
|
it("returns the public client when the presented secret is empty", async () => {
|
|
91
90
|
const client = makeClient(10);
|
|
92
91
|
await options.addClient(clientService, client);
|
|
93
92
|
const auth = await clientService.getAuthenticated(client.id, "");
|
|
94
|
-
|
|
93
|
+
expect(auth?.id).toStrictEqual(client.id);
|
|
95
94
|
});
|
|
96
95
|
it("returns undefined for a confidential client when no secret is supplied", async () => {
|
|
97
96
|
const client = makeClient(3);
|
|
98
97
|
await options.addClient(clientService, client, "secret");
|
|
99
|
-
|
|
98
|
+
expect(await clientService.getAuthenticated(client.id)).toBe(undefined);
|
|
100
99
|
});
|
|
101
100
|
it("returns undefined for a confidential client with a wrong secret", async () => {
|
|
102
101
|
const client = makeClient(4);
|
|
103
102
|
await options.addClient(clientService, client, "correct");
|
|
104
|
-
|
|
103
|
+
expect(await clientService.getAuthenticated(client.id, "wrong")).toBe(undefined);
|
|
105
104
|
});
|
|
106
105
|
it("returns the confidential client with a matching secret", async () => {
|
|
107
106
|
const client = makeClient(5);
|
|
108
107
|
await options.addClient(clientService, client, "matching");
|
|
109
108
|
const auth = await clientService.getAuthenticated(client.id, "matching");
|
|
110
|
-
|
|
109
|
+
expect(auth?.id).toStrictEqual(client.id);
|
|
111
110
|
});
|
|
112
111
|
});
|
|
113
112
|
describe("getUser", () => {
|
|
114
113
|
it("resolves nothing for a client registered without a user, rather than failing", async () => {
|
|
115
114
|
const client = makeClient(6);
|
|
116
115
|
await options.addClient(clientService, client);
|
|
117
|
-
|
|
116
|
+
expect(await clientService.getUser(client)).toBe(undefined);
|
|
118
117
|
});
|
|
119
118
|
it("returns the associated user when one was registered", async () => {
|
|
120
119
|
const user = makeUser(7);
|
|
@@ -122,7 +121,7 @@ export function runClientServiceContractTests(options) {
|
|
|
122
121
|
await options.addUser(userService, user, "pw");
|
|
123
122
|
await options.addClient(clientService, client, undefined, user.id);
|
|
124
123
|
const owner = await clientService.getUser(client);
|
|
125
|
-
|
|
124
|
+
expect(owner?.id).toStrictEqual(user.id);
|
|
126
125
|
});
|
|
127
126
|
it("accepts a client id (not just a client object)", async () => {
|
|
128
127
|
const user = makeUser(8);
|
|
@@ -130,7 +129,7 @@ export function runClientServiceContractTests(options) {
|
|
|
130
129
|
await options.addUser(userService, user, "pw");
|
|
131
130
|
await options.addClient(clientService, client, undefined, user.id);
|
|
132
131
|
const owner = await clientService.getUser(client.id);
|
|
133
|
-
|
|
132
|
+
expect(owner?.id).toStrictEqual(user.id);
|
|
134
133
|
});
|
|
135
134
|
});
|
|
136
135
|
});
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import type { ClientInterface } from "../../models/client.
|
|
8
|
-
import type { AbstractScope, BasicScope } from "../../models/scope.
|
|
9
|
-
import type { ClientServiceInterface } from "../../server/services/client.
|
|
10
|
-
import type { DeviceAuthorizationServiceInterface } from "../../server/services/device-authorization.
|
|
11
|
-
import type { UserServiceInterface } from "../../server/services/user.
|
|
12
|
-
import type { MemoryUserShape } from "../services.
|
|
7
|
+
import type { ClientInterface } from "../../models/client.ts";
|
|
8
|
+
import type { AbstractScope, BasicScope } from "../../models/scope.ts";
|
|
9
|
+
import type { ClientServiceInterface } from "../../server/services/client.ts";
|
|
10
|
+
import type { DeviceAuthorizationServiceInterface } from "../../server/services/device-authorization.ts";
|
|
11
|
+
import type { UserServiceInterface } from "../../server/services/user.ts";
|
|
12
|
+
import type { MemoryUserShape } from "../services.ts";
|
|
13
13
|
/** Options for {@link runDeviceAuthorizationServiceContractTests}. */
|
|
14
14
|
export interface DeviceAuthorizationServiceContractOptions<C extends ClientInterface, U extends MemoryUserShape, S extends AbstractScope = BasicScope> {
|
|
15
15
|
/** Returns fresh services for each test. */
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import { assert,
|
|
8
|
-
import { beforeEach, describe, it } from "../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
|
|
7
|
+
import { assert, beforeEach, describe, expect, it } from "vitest";
|
|
9
8
|
const defaultMakeUser = (seq) => ({ id: `u${seq}`, username: `user${seq}` });
|
|
10
9
|
const defaultMakeClient = (seq) => ({
|
|
11
10
|
id: `client-${seq}`,
|
|
@@ -13,10 +12,9 @@ const defaultMakeClient = (seq) => ({
|
|
|
13
12
|
});
|
|
14
13
|
/** Runs the {@link DeviceAuthorizationServiceInterface} contract suite. */
|
|
15
14
|
export function runDeviceAuthorizationServiceContractTests(options) {
|
|
16
|
-
const makeUser = options.makeUser ??
|
|
17
|
-
const makeClient = options.makeClient ??
|
|
18
|
-
describe(options.describeName ??
|
|
19
|
-
"DeviceAuthorizationServiceInterface contract", () => {
|
|
15
|
+
const makeUser = options.makeUser ?? defaultMakeUser;
|
|
16
|
+
const makeClient = options.makeClient ?? defaultMakeClient;
|
|
17
|
+
describe(options.describeName ?? "DeviceAuthorizationServiceInterface contract", () => {
|
|
20
18
|
let userService;
|
|
21
19
|
let clientService;
|
|
22
20
|
let deviceService;
|
|
@@ -53,35 +51,35 @@ export function runDeviceAuthorizationServiceContractTests(options) {
|
|
|
53
51
|
const auth = await makeDeviceAuth();
|
|
54
52
|
await deviceService.save(auth);
|
|
55
53
|
const fetched = await deviceService.getByDeviceCode(auth.deviceCode);
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
expect(fetched?.deviceCode).toStrictEqual(auth.deviceCode);
|
|
55
|
+
expect(fetched?.client.id).toStrictEqual(client.id);
|
|
58
56
|
});
|
|
59
57
|
it("save + lookup by user code", async () => {
|
|
60
58
|
const auth = await makeDeviceAuth();
|
|
61
59
|
await deviceService.save(auth);
|
|
62
60
|
const fetched = await deviceService.getByUserCode(auth.userCode);
|
|
63
|
-
|
|
61
|
+
expect(fetched?.userCode).toStrictEqual(auth.userCode);
|
|
64
62
|
});
|
|
65
63
|
it("getByDeviceCode / getByUserCode return undefined for unknown codes", async () => {
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
expect(await deviceService.getByDeviceCode("missing")).toBe(undefined);
|
|
65
|
+
expect(await deviceService.getByUserCode("missing")).toBe(undefined);
|
|
68
66
|
});
|
|
69
67
|
it("approve marks the authorization with the approving user", async () => {
|
|
70
68
|
const auth = await makeDeviceAuth();
|
|
71
69
|
await deviceService.save(auth);
|
|
72
70
|
const approved = await deviceService.approve(auth, user);
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
expect(approved.authorized).toBe(true);
|
|
72
|
+
expect(approved.user.id).toStrictEqual(user.id);
|
|
75
73
|
const refetched = await deviceService.getByDeviceCode(auth.deviceCode);
|
|
76
|
-
|
|
74
|
+
expect(refetched?.authorized).toBe(true);
|
|
77
75
|
});
|
|
78
76
|
it("deny marks the authorization as denied", async () => {
|
|
79
77
|
const auth = await makeDeviceAuth();
|
|
80
78
|
await deviceService.save(auth);
|
|
81
79
|
const denied = await deviceService.deny(auth);
|
|
82
|
-
|
|
80
|
+
expect(denied.denied).toBe(true);
|
|
83
81
|
const refetched = await deviceService.getByDeviceCode(auth.deviceCode);
|
|
84
|
-
|
|
82
|
+
expect(refetched?.denied).toBe(true);
|
|
85
83
|
});
|
|
86
84
|
it("updateLastPolled records a poll time", async () => {
|
|
87
85
|
const auth = await makeDeviceAuth();
|
|
@@ -94,19 +92,19 @@ export function runDeviceAuthorizationServiceContractTests(options) {
|
|
|
94
92
|
it("revoke deletes by object and by string", async () => {
|
|
95
93
|
const auth1 = await makeDeviceAuth();
|
|
96
94
|
await deviceService.save(auth1);
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
expect(await deviceService.revoke(auth1)).toBe(true);
|
|
96
|
+
expect(await deviceService.getByDeviceCode(auth1.deviceCode)).toBe(undefined);
|
|
99
97
|
const auth2 = await makeDeviceAuth();
|
|
100
98
|
await deviceService.save(auth2);
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
expect(await deviceService.revoke(auth2.deviceCode)).toBe(true);
|
|
100
|
+
expect(await deviceService.getByDeviceCode(auth2.deviceCode)).toBe(undefined);
|
|
103
101
|
});
|
|
104
102
|
it("revoke answers true only for the call that removed a live authorization", async () => {
|
|
105
103
|
const auth = await makeDeviceAuth();
|
|
106
104
|
await deviceService.save(auth);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
expect(await deviceService.revoke(auth)).toBe(true);
|
|
106
|
+
expect(await deviceService.revoke(auth)).toBe(false);
|
|
107
|
+
expect(await deviceService.revoke(auth.deviceCode)).toBe(false);
|
|
110
108
|
});
|
|
111
109
|
async function saveDeviceAuth() {
|
|
112
110
|
const auth = await makeDeviceAuth();
|
|
@@ -118,33 +116,33 @@ export function runDeviceAuthorizationServiceContractTests(options) {
|
|
|
118
116
|
return { auth, byDeviceCode, byUserCode };
|
|
119
117
|
}
|
|
120
118
|
async function assertUnreachableByEitherCode(auth) {
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
expect(await deviceService.getByDeviceCode(auth.deviceCode), "a revoked authorization must not resolve by its device code").toBe(undefined);
|
|
120
|
+
expect(await deviceService.getByUserCode(auth.userCode), "a revoked authorization must not resolve by its user code").toBe(undefined);
|
|
123
121
|
}
|
|
124
122
|
it("revoke by full record clears both the device-code and user-code lookups", async () => {
|
|
125
123
|
const { auth } = await saveDeviceAuth();
|
|
126
|
-
|
|
124
|
+
expect(await deviceService.revoke(auth)).toBe(true);
|
|
127
125
|
await assertUnreachableByEitherCode(auth);
|
|
128
126
|
});
|
|
129
127
|
it("revoke by raw device code clears both the device-code and user-code lookups", async () => {
|
|
130
128
|
const { auth } = await saveDeviceAuth();
|
|
131
|
-
|
|
129
|
+
expect(await deviceService.revoke(auth.deviceCode)).toBe(true);
|
|
132
130
|
await assertUnreachableByEitherCode(auth);
|
|
133
131
|
});
|
|
134
132
|
it("revoke accepts the record getByDeviceCode returns and clears both lookups", async () => {
|
|
135
133
|
const { auth, byDeviceCode } = await saveDeviceAuth();
|
|
136
|
-
|
|
134
|
+
expect(await deviceService.revoke(byDeviceCode)).toBe(true);
|
|
137
135
|
await assertUnreachableByEitherCode(auth);
|
|
138
136
|
});
|
|
139
137
|
it("revoke accepts the record getByUserCode returns and clears both lookups", async () => {
|
|
140
138
|
const { auth, byUserCode } = await saveDeviceAuth();
|
|
141
|
-
|
|
139
|
+
expect(await deviceService.revoke(byUserCode)).toBe(true);
|
|
142
140
|
await assertUnreachableByEitherCode(auth);
|
|
143
141
|
});
|
|
144
142
|
it("revoke answers true once across the hydrated shapes of one authorization", async () => {
|
|
145
143
|
const { byDeviceCode, byUserCode } = await saveDeviceAuth();
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
expect(await deviceService.revoke(byDeviceCode)).toBe(true);
|
|
145
|
+
expect(await deviceService.revoke(byUserCode)).toBe(false);
|
|
148
146
|
});
|
|
149
147
|
it("revoke answers true to exactly one of two concurrent claims", async () => {
|
|
150
148
|
const { auth, byDeviceCode } = await saveDeviceAuth();
|
|
@@ -152,35 +150,35 @@ export function runDeviceAuthorizationServiceContractTests(options) {
|
|
|
152
150
|
deviceService.revoke(byDeviceCode),
|
|
153
151
|
deviceService.revoke(byDeviceCode),
|
|
154
152
|
]);
|
|
155
|
-
|
|
153
|
+
expect(claims.filter(Boolean).length, "concurrent polls of one device code must not both be told they claimed it").toStrictEqual(1);
|
|
156
154
|
await assertUnreachableByEitherCode(auth);
|
|
157
155
|
});
|
|
158
156
|
it("revoke of a user-code-hydrated record consumes the device code", async () => {
|
|
159
157
|
const { auth, byUserCode } = await saveDeviceAuth();
|
|
160
158
|
await deviceService.approve(byUserCode, user);
|
|
161
159
|
await deviceService.revoke(byUserCode);
|
|
162
|
-
|
|
160
|
+
expect(await deviceService.getByDeviceCode(auth.deviceCode), "a cancelled authorization must not stay redeemable by its device code").toBe(undefined);
|
|
163
161
|
});
|
|
164
162
|
it("approve accepts the record getByUserCode returns", async () => {
|
|
165
163
|
const { auth, byUserCode } = await saveDeviceAuth();
|
|
166
164
|
const approved = await deviceService.approve(byUserCode, user);
|
|
167
|
-
|
|
165
|
+
expect(approved.authorized).toBe(true);
|
|
168
166
|
const refetched = await deviceService.getByDeviceCode(auth.deviceCode);
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
expect(refetched?.authorized).toBe(true);
|
|
168
|
+
expect(refetched?.user?.id).toStrictEqual(user.id);
|
|
171
169
|
});
|
|
172
170
|
it("approve accepts the record getByDeviceCode returns", async () => {
|
|
173
171
|
const { auth, byDeviceCode } = await saveDeviceAuth();
|
|
174
172
|
await deviceService.approve(byDeviceCode, user);
|
|
175
173
|
const refetched = await deviceService.getByUserCode(auth.userCode);
|
|
176
|
-
|
|
174
|
+
expect(refetched?.authorized).toBe(true);
|
|
177
175
|
});
|
|
178
176
|
it("deny accepts the record getByUserCode returns", async () => {
|
|
179
177
|
const { auth, byUserCode } = await saveDeviceAuth();
|
|
180
178
|
const denied = await deviceService.deny(byUserCode);
|
|
181
|
-
|
|
179
|
+
expect(denied.denied).toBe(true);
|
|
182
180
|
const refetched = await deviceService.getByDeviceCode(auth.deviceCode);
|
|
183
|
-
|
|
181
|
+
expect(refetched?.denied).toBe(true);
|
|
184
182
|
});
|
|
185
183
|
it("updateLastPolled accepts the record getByDeviceCode returns", async () => {
|
|
186
184
|
const { auth, byDeviceCode } = await saveDeviceAuth();
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Contract checks for app-owned identity-session revocation and display lists.
|
|
3
|
+
* These are distinct from the Hono BFF SessionStore contract.
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { ListableSessionService, RevocableSessionService, SessionSummary } from "../../identity/session.ts";
|
|
2
7
|
/** Session states the application translates into its own storage fields. */
|
|
3
8
|
export type IdentitySessionContractState = "live" | "revoked" | "expired" | "idle-timed-out";
|
|
4
9
|
/** Isolated revocation implementation and app-owned session setup helpers. */
|