@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,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot factory that wires the {@link MemoryUserService},
|
|
3
|
+
* {@link MemoryClientService}, {@link MemoryTokenService},
|
|
4
|
+
* {@link MemoryAuthorizationCodeService}, and
|
|
5
|
+
* {@link MemoryDeviceAuthorizationService} into a real
|
|
6
|
+
* {@link AuthorizationServer}, seeds it from the supplied users / clients,
|
|
7
|
+
* and returns a harness whose `fetch` you pass to a `DirectClient`
|
|
8
|
+
* constructor's `fetch` option for tests that need an end-to-end OAuth2
|
|
9
|
+
* protocol surface.
|
|
10
|
+
*
|
|
11
|
+
* The point of this factory is that **the test exercises the same
|
|
12
|
+
* code paths as production**. There is no parallel mock implementation of
|
|
13
|
+
* the OAuth2 wire protocol — the responses come from the real
|
|
14
|
+
* {@link AuthorizationServer}, just dispatched in-process via
|
|
15
|
+
* {@link localAuthServerFetch} instead of over a socket.
|
|
16
|
+
*
|
|
17
|
+
* Construct the test app's `DirectClient` (or `HonoBff` whose underlying
|
|
18
|
+
* client you control) with `fetch: oauth.fetch`. We deliberately do
|
|
19
|
+
* **not** recommend `stub(globalThis, "fetch", oauth.fetch)` — a global
|
|
20
|
+
* stub silently captures every outbound request the app makes, not just
|
|
21
|
+
* the OAuth2 ones, and that's a common source of mysterious test
|
|
22
|
+
* cross-talk in consumer projects.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { DirectClient } from "@udibo/oauth2/client";
|
|
27
|
+
* import { createMemoryAuthorizationServer } from "@udibo/oauth2/testing";
|
|
28
|
+
*
|
|
29
|
+
* Deno.test("client credentials grant", async () => {
|
|
30
|
+
* const oauth = await createMemoryAuthorizationServer({
|
|
31
|
+
* issuer: "http://localhost",
|
|
32
|
+
* clients: [{
|
|
33
|
+
* client: { id: "m2m", grants: ["client_credentials"] },
|
|
34
|
+
* secret: "s",
|
|
35
|
+
* }],
|
|
36
|
+
* });
|
|
37
|
+
* const client = new DirectClient({
|
|
38
|
+
* clientId: "m2m",
|
|
39
|
+
* clientSecret: "s",
|
|
40
|
+
* endpoints: { token: "http://localhost/oauth2/token" },
|
|
41
|
+
* fetch: oauth.fetch,
|
|
42
|
+
* });
|
|
43
|
+
* const tokens = await client.getClientCredentialsToken();
|
|
44
|
+
* // ...assert against the real token response.
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @module
|
|
49
|
+
*/
|
|
50
|
+
import type { ClientInterface } from "../models/client.js";
|
|
51
|
+
import type { AbstractScope, BasicScope, ScopeConstructor } from "../models/scope.js";
|
|
52
|
+
import { AuthorizationServer } from "../server/authorization-server.js";
|
|
53
|
+
import type { AuthenticateUserFn, HandleConsentFn } from "../server/authorization-server.js";
|
|
54
|
+
import { MemoryAuthorizationCodeService, MemoryClientService, MemoryDeviceAuthorizationService, MemoryTokenService, MemoryUserService, type MemoryUserShape } from "./services.js";
|
|
55
|
+
/** Which OAuth2 grants the memory authorization server enables. */
|
|
56
|
+
export interface MemoryAuthorizationServerGrants {
|
|
57
|
+
/**
|
|
58
|
+
* Authorization code grant. Default `true`. PKCE is required (OAuth 2.1) and
|
|
59
|
+
* this factory exposes no opt-out: a hand-rolled authorize URL must carry
|
|
60
|
+
* `code_challenge`, and the token exchange the matching `code_verifier`.
|
|
61
|
+
*/
|
|
62
|
+
authorization_code?: boolean;
|
|
63
|
+
/** Client credentials grant (M2M). Default `true`. */
|
|
64
|
+
client_credentials?: boolean;
|
|
65
|
+
/** Refresh token grant. Default `true`. */
|
|
66
|
+
refresh_token?: boolean;
|
|
67
|
+
/** Resource owner password credentials grant. Default `false` (legacy / discouraged). */
|
|
68
|
+
password?: boolean;
|
|
69
|
+
/** Device authorization grant (RFC 8628). Default `true`. */
|
|
70
|
+
device_code?: boolean;
|
|
71
|
+
}
|
|
72
|
+
/** Seed entry for a user. */
|
|
73
|
+
export interface MemoryAuthorizationServerUserSeed<U extends MemoryUserShape> {
|
|
74
|
+
/** The user record to seed into the memory user service. */
|
|
75
|
+
user: U;
|
|
76
|
+
/** Plaintext password registered for the user; used by the password grant and login. */
|
|
77
|
+
password: string;
|
|
78
|
+
}
|
|
79
|
+
/** Seed entry for a registered OAuth2 client. */
|
|
80
|
+
export interface MemoryAuthorizationServerClientSeed<C extends ClientInterface> {
|
|
81
|
+
/** The client record to register with the memory client service. */
|
|
82
|
+
client: C;
|
|
83
|
+
/** Omit for a public client; supply for a confidential client. */
|
|
84
|
+
secret?: string;
|
|
85
|
+
/**
|
|
86
|
+
* User returned by `clientService.getUser(client)` (client-credentials
|
|
87
|
+
* grant). Omit it to seed a client whose machine token carries no user.
|
|
88
|
+
*/
|
|
89
|
+
ownerUserId?: string;
|
|
90
|
+
}
|
|
91
|
+
/** Options for {@link createMemoryAuthorizationServer}. */
|
|
92
|
+
export interface CreateMemoryAuthorizationServerOptions<C extends ClientInterface, U extends MemoryUserShape, S extends AbstractScope = BasicScope> {
|
|
93
|
+
/** Issuer identifier. Defaults to `"http://localhost"`. */
|
|
94
|
+
issuer?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Endpoint URLs. Each defaults to `${issuer}${defaultPath}`. Setting any
|
|
97
|
+
* to `null` removes it from the advertised metadata. (Note: this only
|
|
98
|
+
* affects the metadata document — {@link localAuthServerFetch} never
|
|
99
|
+
* dispatches the `authorization` endpoint regardless; drive that leg with
|
|
100
|
+
* the harness's {@link MemoryAuthorizationServerHarness.authorize} helper.)
|
|
101
|
+
*/
|
|
102
|
+
endpoints?: {
|
|
103
|
+
token?: string | null;
|
|
104
|
+
authorization?: string | null;
|
|
105
|
+
revocation?: string | null;
|
|
106
|
+
introspection?: string | null;
|
|
107
|
+
deviceAuthorization?: string | null;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* URL users visit to enter their device code (RFC 8628). Defaults to
|
|
111
|
+
* `${issuer}/device`. Required by the device-authorization endpoint, so the
|
|
112
|
+
* default keeps the device flow drivable through {@link fetch}.
|
|
113
|
+
*/
|
|
114
|
+
verificationUri?: string;
|
|
115
|
+
/** Scope vocabulary advertised in metadata. */
|
|
116
|
+
scopesSupported?: string[];
|
|
117
|
+
/** Custom scope constructor. Defaults to {@link BasicScope}. */
|
|
118
|
+
Scope?: ScopeConstructor<S>;
|
|
119
|
+
/** Realm reported on `WWW-Authenticate` headers. */
|
|
120
|
+
realm?: string;
|
|
121
|
+
/** Which grants to enable. */
|
|
122
|
+
grants?: MemoryAuthorizationServerGrants;
|
|
123
|
+
/** Users to seed before the server is returned. */
|
|
124
|
+
users?: ReadonlyArray<MemoryAuthorizationServerUserSeed<U>>;
|
|
125
|
+
/** Clients to seed before the server is returned. */
|
|
126
|
+
clients?: ReadonlyArray<MemoryAuthorizationServerClientSeed<C>>;
|
|
127
|
+
}
|
|
128
|
+
/** Harness returned by {@link createMemoryAuthorizationServer}. */
|
|
129
|
+
export interface MemoryAuthorizationServerHarness<C extends ClientInterface, U extends MemoryUserShape, S extends AbstractScope = BasicScope> {
|
|
130
|
+
/** The composed authorization server. Use it directly when you want full control. */
|
|
131
|
+
server: AuthorizationServer<C, U, S>;
|
|
132
|
+
/** The Memory* services, exposed for fixture seeding mid-test. */
|
|
133
|
+
services: {
|
|
134
|
+
userService: MemoryUserService<U>;
|
|
135
|
+
clientService: MemoryClientService<C, U>;
|
|
136
|
+
tokenService: MemoryTokenService<C, U, S>;
|
|
137
|
+
authorizationCodeService: MemoryAuthorizationCodeService<C, U, S>;
|
|
138
|
+
deviceAuthorizationService: MemoryDeviceAuthorizationService<C, U, S>;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* `fetch`-compatible function that dispatches OAuth2 requests directly
|
|
142
|
+
* into {@link server} without a socket. Pass this as the `fetch` option
|
|
143
|
+
* to a `DirectClient` (or to `HonoBff`'s underlying client) under test
|
|
144
|
+
* so outbound OAuth2 traffic is rerouted in-process — there is no need
|
|
145
|
+
* to stub `globalThis.fetch`, which would also intercept unrelated
|
|
146
|
+
* outbound requests the app may issue.
|
|
147
|
+
*/
|
|
148
|
+
fetch: typeof fetch;
|
|
149
|
+
/**
|
|
150
|
+
* Drives the browser-facing authorization leg (`GET /authorize`)
|
|
151
|
+
* in-process and returns the resulting `Response` (a 302 redirect carrying
|
|
152
|
+
* the `code` on success). This can't go through {@link fetch} because the
|
|
153
|
+
* authorize endpoint needs an `authenticateUser`/`handleConsent` callback.
|
|
154
|
+
*
|
|
155
|
+
* With no options it authenticates as the first seeded user. Pass `user`
|
|
156
|
+
* to authenticate as a specific user, or `authenticateUser`/`handleConsent`
|
|
157
|
+
* for full control. Read the `code` from the returned response's `Location`
|
|
158
|
+
* header, then exchange it with a `DirectClient` wired to {@link fetch}.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* import type { ClientInterface } from "@udibo/oauth2/server";
|
|
163
|
+
* import type {
|
|
164
|
+
* MemoryAuthorizationServerHarness,
|
|
165
|
+
* MemoryUserShape,
|
|
166
|
+
* } from "@udibo/oauth2/testing";
|
|
167
|
+
*
|
|
168
|
+
* declare const oauth: MemoryAuthorizationServerHarness<
|
|
169
|
+
* ClientInterface,
|
|
170
|
+
* MemoryUserShape
|
|
171
|
+
* >;
|
|
172
|
+
* declare const beginUrl: string;
|
|
173
|
+
*
|
|
174
|
+
* const res = await oauth.authorize(beginUrl);
|
|
175
|
+
* const code = new URL(res.headers.get("Location")!).searchParams
|
|
176
|
+
* .get("code")!;
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
authorize(url: string | URL, options?: {
|
|
180
|
+
authenticateUser?: AuthenticateUserFn<U>;
|
|
181
|
+
handleConsent?: HandleConsentFn<C, S>;
|
|
182
|
+
user?: U;
|
|
183
|
+
}): Promise<Response>;
|
|
184
|
+
/**
|
|
185
|
+
* Adds a user and, when no user has been seeded yet, makes it the one
|
|
186
|
+
* {@linkcode authorize} authenticates as by default. Adding through
|
|
187
|
+
* {@linkcode services}.userService instead skips that.
|
|
188
|
+
*/
|
|
189
|
+
addUser(user: U, password: string): Promise<void>;
|
|
190
|
+
/** Convenience wrapper around `services.clientService.add`. */
|
|
191
|
+
addClient(client: C, secret?: string, ownerUserId?: string): Promise<void>;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Returns a {@link MemoryAuthorizationServerHarness} ready to drop into a
|
|
195
|
+
* test. See the module-level example for usage.
|
|
196
|
+
*/
|
|
197
|
+
export declare function createMemoryAuthorizationServer<C extends ClientInterface = ClientInterface, U extends MemoryUserShape = MemoryUserShape, S extends AbstractScope = BasicScope>(options?: CreateMemoryAuthorizationServerOptions<C, U, S>): Promise<MemoryAuthorizationServerHarness<C, U, S>>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot factory that wires the {@link MemoryUserService},
|
|
3
|
+
* {@link MemoryClientService}, {@link MemoryTokenService},
|
|
4
|
+
* {@link MemoryAuthorizationCodeService}, and
|
|
5
|
+
* {@link MemoryDeviceAuthorizationService} into a real
|
|
6
|
+
* {@link AuthorizationServer}, seeds it from the supplied users / clients,
|
|
7
|
+
* and returns a harness whose `fetch` you pass to a `DirectClient`
|
|
8
|
+
* constructor's `fetch` option for tests that need an end-to-end OAuth2
|
|
9
|
+
* protocol surface.
|
|
10
|
+
*
|
|
11
|
+
* The point of this factory is that **the test exercises the same
|
|
12
|
+
* code paths as production**. There is no parallel mock implementation of
|
|
13
|
+
* the OAuth2 wire protocol — the responses come from the real
|
|
14
|
+
* {@link AuthorizationServer}, just dispatched in-process via
|
|
15
|
+
* {@link localAuthServerFetch} instead of over a socket.
|
|
16
|
+
*
|
|
17
|
+
* Construct the test app's `DirectClient` (or `HonoBff` whose underlying
|
|
18
|
+
* client you control) with `fetch: oauth.fetch`. We deliberately do
|
|
19
|
+
* **not** recommend `stub(globalThis, "fetch", oauth.fetch)` — a global
|
|
20
|
+
* stub silently captures every outbound request the app makes, not just
|
|
21
|
+
* the OAuth2 ones, and that's a common source of mysterious test
|
|
22
|
+
* cross-talk in consumer projects.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { DirectClient } from "@udibo/oauth2/client";
|
|
27
|
+
* import { createMemoryAuthorizationServer } from "@udibo/oauth2/testing";
|
|
28
|
+
*
|
|
29
|
+
* Deno.test("client credentials grant", async () => {
|
|
30
|
+
* const oauth = await createMemoryAuthorizationServer({
|
|
31
|
+
* issuer: "http://localhost",
|
|
32
|
+
* clients: [{
|
|
33
|
+
* client: { id: "m2m", grants: ["client_credentials"] },
|
|
34
|
+
* secret: "s",
|
|
35
|
+
* }],
|
|
36
|
+
* });
|
|
37
|
+
* const client = new DirectClient({
|
|
38
|
+
* clientId: "m2m",
|
|
39
|
+
* clientSecret: "s",
|
|
40
|
+
* endpoints: { token: "http://localhost/oauth2/token" },
|
|
41
|
+
* fetch: oauth.fetch,
|
|
42
|
+
* });
|
|
43
|
+
* const tokens = await client.getClientCredentialsToken();
|
|
44
|
+
* // ...assert against the real token response.
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @module
|
|
49
|
+
*/
|
|
50
|
+
import { AuthorizationServer, localAuthServerFetch, } from "../server/authorization-server.js";
|
|
51
|
+
import { AuthorizationCodeGrant } from "../server/grants/authorization-code.js";
|
|
52
|
+
import { ClientCredentialsGrant } from "../server/grants/client-credentials.js";
|
|
53
|
+
import { DeviceAuthorizationGrant } from "../server/grants/device-authorization.js";
|
|
54
|
+
import { PasswordGrant } from "../server/grants/password.js";
|
|
55
|
+
import { RefreshTokenGrant } from "../server/grants/refresh-token.js";
|
|
56
|
+
import { MemoryAuthorizationCodeService, MemoryClientService, MemoryDeviceAuthorizationService, MemoryTokenService, MemoryUserService, } from "./services.js";
|
|
57
|
+
const DEFAULT_PATHS = {
|
|
58
|
+
token: "/oauth2/token",
|
|
59
|
+
authorization: "/oauth2/authorize",
|
|
60
|
+
revocation: "/oauth2/revoke",
|
|
61
|
+
introspection: "/oauth2/introspect",
|
|
62
|
+
deviceAuthorization: "/oauth2/device_authorization",
|
|
63
|
+
};
|
|
64
|
+
const DEFAULT_GRANTS = {
|
|
65
|
+
authorization_code: true,
|
|
66
|
+
client_credentials: true,
|
|
67
|
+
refresh_token: true,
|
|
68
|
+
password: false,
|
|
69
|
+
device_code: true,
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Returns a {@link MemoryAuthorizationServerHarness} ready to drop into a
|
|
73
|
+
* test. See the module-level example for usage.
|
|
74
|
+
*/
|
|
75
|
+
export async function createMemoryAuthorizationServer(options = {}) {
|
|
76
|
+
const issuer = options.issuer ?? "http://localhost";
|
|
77
|
+
const enabledGrants = { ...DEFAULT_GRANTS, ...options.grants };
|
|
78
|
+
const userService = new MemoryUserService();
|
|
79
|
+
const clientService = new MemoryClientService(userService);
|
|
80
|
+
const tokenService = new MemoryTokenService({
|
|
81
|
+
clientService,
|
|
82
|
+
userService,
|
|
83
|
+
});
|
|
84
|
+
const authorizationCodeService = new MemoryAuthorizationCodeService({
|
|
85
|
+
clientService,
|
|
86
|
+
userService,
|
|
87
|
+
});
|
|
88
|
+
const deviceAuthorizationService = new MemoryDeviceAuthorizationService({ clientService, userService });
|
|
89
|
+
const grants = {};
|
|
90
|
+
if (enabledGrants.authorization_code) {
|
|
91
|
+
grants.authorization_code = new AuthorizationCodeGrant({
|
|
92
|
+
resolve: () => ({
|
|
93
|
+
clientService,
|
|
94
|
+
tokenService,
|
|
95
|
+
authorizationCodeService,
|
|
96
|
+
}),
|
|
97
|
+
Scope: options.Scope,
|
|
98
|
+
allowRefreshToken: enabledGrants.refresh_token,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (enabledGrants.client_credentials) {
|
|
102
|
+
grants.client_credentials = new ClientCredentialsGrant({
|
|
103
|
+
resolve: () => ({ clientService, tokenService }),
|
|
104
|
+
Scope: options.Scope,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (enabledGrants.refresh_token) {
|
|
108
|
+
grants.refresh_token = new RefreshTokenGrant({
|
|
109
|
+
resolve: () => ({ clientService, tokenService }),
|
|
110
|
+
Scope: options.Scope,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (enabledGrants.password) {
|
|
114
|
+
grants.password = new PasswordGrant({
|
|
115
|
+
resolve: () => ({ clientService, tokenService, userService }),
|
|
116
|
+
Scope: options.Scope,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (enabledGrants.device_code) {
|
|
120
|
+
grants["urn:ietf:params:oauth:grant-type:device_code"] =
|
|
121
|
+
new DeviceAuthorizationGrant({
|
|
122
|
+
resolve: () => ({
|
|
123
|
+
clientService,
|
|
124
|
+
tokenService,
|
|
125
|
+
deviceAuthorizationService,
|
|
126
|
+
}),
|
|
127
|
+
Scope: options.Scope,
|
|
128
|
+
allowRefreshToken: enabledGrants.refresh_token,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const endpointOverrides = options.endpoints ?? {};
|
|
132
|
+
const endpoint = (name) => {
|
|
133
|
+
const override = endpointOverrides[name];
|
|
134
|
+
if (override === null)
|
|
135
|
+
return undefined;
|
|
136
|
+
if (override !== undefined)
|
|
137
|
+
return override;
|
|
138
|
+
return `${issuer}${DEFAULT_PATHS[name]}`;
|
|
139
|
+
};
|
|
140
|
+
const verificationUri = options.verificationUri ?? `${issuer}/device`;
|
|
141
|
+
const server = new AuthorizationServer({
|
|
142
|
+
resolve: () => ({
|
|
143
|
+
services: { clientService, tokenService },
|
|
144
|
+
issuer,
|
|
145
|
+
tokenEndpoint: endpoint("token"),
|
|
146
|
+
authorizationEndpoint: endpoint("authorization"),
|
|
147
|
+
revocationEndpoint: endpoint("revocation"),
|
|
148
|
+
introspectionEndpoint: endpoint("introspection"),
|
|
149
|
+
deviceAuthorizationEndpoint: endpoint("deviceAuthorization"),
|
|
150
|
+
verificationUri,
|
|
151
|
+
}),
|
|
152
|
+
grants,
|
|
153
|
+
scopesSupported: options.scopesSupported,
|
|
154
|
+
Scope: options.Scope,
|
|
155
|
+
realm: options.realm,
|
|
156
|
+
});
|
|
157
|
+
let defaultUser;
|
|
158
|
+
for (const seed of options.users ?? []) {
|
|
159
|
+
await userService.add(seed.user, seed.password);
|
|
160
|
+
defaultUser ??= seed.user;
|
|
161
|
+
}
|
|
162
|
+
for (const seed of options.clients ?? []) {
|
|
163
|
+
await clientService.add(seed.client, seed.secret, seed.ownerUserId);
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
server,
|
|
167
|
+
services: {
|
|
168
|
+
userService,
|
|
169
|
+
clientService,
|
|
170
|
+
tokenService,
|
|
171
|
+
authorizationCodeService,
|
|
172
|
+
deviceAuthorizationService,
|
|
173
|
+
},
|
|
174
|
+
fetch: localAuthServerFetch(server),
|
|
175
|
+
authorize: (url, authorizeOptions = {}) => {
|
|
176
|
+
const authenticateUser = authorizeOptions.authenticateUser ??
|
|
177
|
+
(() => {
|
|
178
|
+
const user = authorizeOptions.user ?? defaultUser;
|
|
179
|
+
if (!user) {
|
|
180
|
+
return Promise.reject(new Error("authorize() has no user to authenticate as: seed a user, " +
|
|
181
|
+
"or pass `user`/`authenticateUser`"));
|
|
182
|
+
}
|
|
183
|
+
return Promise.resolve({ user });
|
|
184
|
+
});
|
|
185
|
+
return server.handleAuthorizeRequest(new Request(String(url)), authenticateUser, authorizeOptions.handleConsent);
|
|
186
|
+
},
|
|
187
|
+
addUser: async (user, password) => {
|
|
188
|
+
await userService.add(user, password);
|
|
189
|
+
defaultUser ??= user;
|
|
190
|
+
},
|
|
191
|
+
addClient: (client, secret, ownerUserId) => clientService.add(client, secret, ownerUserId),
|
|
192
|
+
};
|
|
193
|
+
}
|