@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.
Files changed (375) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +174 -0
  3. package/SECURITY.md +77 -0
  4. package/esm/_dnt.polyfills.d.ts +17 -0
  5. package/esm/_dnt.polyfills.js +15 -0
  6. package/esm/adapters/hono/_common.d.ts +66 -0
  7. package/esm/adapters/hono/_common.js +108 -0
  8. package/esm/adapters/hono/authorization-server.d.ts +211 -0
  9. package/esm/adapters/hono/authorization-server.js +214 -0
  10. package/esm/adapters/hono/bff/auth-request-store.d.ts +164 -0
  11. package/esm/adapters/hono/bff/auth-request-store.js +154 -0
  12. package/esm/adapters/hono/bff/bff.d.ts +852 -0
  13. package/esm/adapters/hono/bff/bff.js +1194 -0
  14. package/esm/adapters/hono/bff/cookie-prefix.d.ts +72 -0
  15. package/esm/adapters/hono/bff/cookie-prefix.js +85 -0
  16. package/esm/adapters/hono/bff/mod.d.ts +19 -0
  17. package/esm/adapters/hono/bff/mod.js +19 -0
  18. package/esm/adapters/hono/bff/proxy.d.ts +108 -0
  19. package/esm/adapters/hono/bff/proxy.js +314 -0
  20. package/esm/adapters/hono/bff/session-store.d.ts +250 -0
  21. package/esm/adapters/hono/bff/session-store.js +216 -0
  22. package/esm/adapters/hono/bff/testing.d.ts +165 -0
  23. package/esm/adapters/hono/bff/testing.js +254 -0
  24. package/esm/adapters/hono/identity.d.ts +117 -0
  25. package/esm/adapters/hono/identity.js +215 -0
  26. package/esm/adapters/hono/log.d.ts +49 -0
  27. package/esm/adapters/hono/log.js +66 -0
  28. package/esm/adapters/hono/resource-server.d.ts +101 -0
  29. package/esm/adapters/hono/resource-server.js +108 -0
  30. package/esm/client/_http.d.ts +91 -0
  31. package/esm/client/_http.js +303 -0
  32. package/esm/client/base.d.ts +184 -0
  33. package/esm/client/base.js +93 -0
  34. package/esm/client/bff-client.d.ts +235 -0
  35. package/esm/client/bff-client.js +280 -0
  36. package/esm/client/browser-storage.d.ts +152 -0
  37. package/esm/client/browser-storage.js +246 -0
  38. package/esm/client/check.d.ts +114 -0
  39. package/esm/client/check.js +97 -0
  40. package/esm/client/direct-client.d.ts +707 -0
  41. package/esm/client/direct-client.js +1237 -0
  42. package/esm/client/discovery-cache.d.ts +138 -0
  43. package/esm/client/discovery-cache.js +124 -0
  44. package/esm/client/events.d.ts +54 -0
  45. package/esm/client/events.js +37 -0
  46. package/esm/client/mod.d.ts +35 -0
  47. package/esm/client/mod.js +33 -0
  48. package/esm/client/storage.d.ts +127 -0
  49. package/esm/client/storage.js +81 -0
  50. package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.d.ts +29 -0
  51. package/esm/deps/jsr.io/@std/assert/1.0.19/almost_equals.js +47 -0
  52. package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.d.ts +28 -0
  53. package/esm/deps/jsr.io/@std/assert/1.0.19/array_includes.js +65 -0
  54. package/esm/deps/jsr.io/@std/assert/1.0.19/assert.d.ts +16 -0
  55. package/esm/deps/jsr.io/@std/assert/1.0.19/assert.js +23 -0
  56. package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.d.ts +25 -0
  57. package/esm/deps/jsr.io/@std/assert/1.0.19/assertion_error.js +30 -0
  58. package/esm/deps/jsr.io/@std/assert/1.0.19/equal.d.ts +24 -0
  59. package/esm/deps/jsr.io/@std/assert/1.0.19/equal.js +193 -0
  60. package/esm/deps/jsr.io/@std/assert/1.0.19/equals.d.ts +36 -0
  61. package/esm/deps/jsr.io/@std/assert/1.0.19/equals.js +61 -0
  62. package/esm/deps/jsr.io/@std/assert/1.0.19/exists.d.ts +17 -0
  63. package/esm/deps/jsr.io/@std/assert/1.0.19/exists.js +27 -0
  64. package/esm/deps/jsr.io/@std/assert/1.0.19/fail.d.ts +14 -0
  65. package/esm/deps/jsr.io/@std/assert/1.0.19/fail.js +20 -0
  66. package/esm/deps/jsr.io/@std/assert/1.0.19/false.d.ts +18 -0
  67. package/esm/deps/jsr.io/@std/assert/1.0.19/false.js +23 -0
  68. package/esm/deps/jsr.io/@std/assert/1.0.19/greater.d.ts +19 -0
  69. package/esm/deps/jsr.io/@std/assert/1.0.19/greater.js +29 -0
  70. package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.d.ts +19 -0
  71. package/esm/deps/jsr.io/@std/assert/1.0.19/greater_or_equal.js +29 -0
  72. package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.d.ts +22 -0
  73. package/esm/deps/jsr.io/@std/assert/1.0.19/instance_of.js +52 -0
  74. package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.d.ts +24 -0
  75. package/esm/deps/jsr.io/@std/assert/1.0.19/is_error.js +53 -0
  76. package/esm/deps/jsr.io/@std/assert/1.0.19/less.d.ts +18 -0
  77. package/esm/deps/jsr.io/@std/assert/1.0.19/less.js +28 -0
  78. package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.d.ts +19 -0
  79. package/esm/deps/jsr.io/@std/assert/1.0.19/less_or_equal.js +29 -0
  80. package/esm/deps/jsr.io/@std/assert/1.0.19/match.d.ts +17 -0
  81. package/esm/deps/jsr.io/@std/assert/1.0.19/match.js +26 -0
  82. package/esm/deps/jsr.io/@std/assert/1.0.19/mod.d.ts +43 -0
  83. package/esm/deps/jsr.io/@std/assert/1.0.19/mod.js +45 -0
  84. package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.d.ts +26 -0
  85. package/esm/deps/jsr.io/@std/assert/1.0.19/not_equals.js +39 -0
  86. package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.d.ts +19 -0
  87. package/esm/deps/jsr.io/@std/assert/1.0.19/not_instance_of.js +29 -0
  88. package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.d.ts +17 -0
  89. package/esm/deps/jsr.io/@std/assert/1.0.19/not_match.js +26 -0
  90. package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.d.ts +22 -0
  91. package/esm/deps/jsr.io/@std/assert/1.0.19/not_strict_equals.js +32 -0
  92. package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.d.ts +28 -0
  93. package/esm/deps/jsr.io/@std/assert/1.0.19/object_match.js +177 -0
  94. package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.d.ts +41 -0
  95. package/esm/deps/jsr.io/@std/assert/1.0.19/rejects.js +53 -0
  96. package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.d.ts +23 -0
  97. package/esm/deps/jsr.io/@std/assert/1.0.19/strict_equals.js +58 -0
  98. package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.d.ts +17 -0
  99. package/esm/deps/jsr.io/@std/assert/1.0.19/string_includes.js +26 -0
  100. package/esm/deps/jsr.io/@std/assert/1.0.19/throws.d.ts +44 -0
  101. package/esm/deps/jsr.io/@std/assert/1.0.19/throws.js +44 -0
  102. package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.d.ts +14 -0
  103. package/esm/deps/jsr.io/@std/assert/1.0.19/unimplemented.js +20 -0
  104. package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.d.ts +14 -0
  105. package/esm/deps/jsr.io/@std/assert/1.0.19/unreachable.js +20 -0
  106. package/esm/deps/jsr.io/@std/async/1.5.0/delay.d.ts +44 -0
  107. package/esm/deps/jsr.io/@std/async/1.5.0/delay.js +84 -0
  108. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +39 -0
  109. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +61 -0
  110. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.d.ts +22 -0
  111. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common16.js +51 -0
  112. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.d.ts +34 -0
  113. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common32.js +192 -0
  114. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.d.ts +34 -0
  115. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common64.js +113 -0
  116. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.d.ts +3 -0
  117. package/esm/deps/jsr.io/@std/encoding/1.0.11/_common_detach.js +13 -0
  118. package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.d.ts +8 -0
  119. package/esm/deps/jsr.io/@std/encoding/1.0.11/_types.js +2 -0
  120. package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.d.ts +1 -0
  121. package/esm/deps/jsr.io/@std/encoding/1.0.11/_validate_binary_like.js +26 -0
  122. package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.d.ts +60 -0
  123. package/esm/deps/jsr.io/@std/encoding/1.0.11/ascii85.js +152 -0
  124. package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.d.ts +39 -0
  125. package/esm/deps/jsr.io/@std/encoding/1.0.11/base32.js +87 -0
  126. package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.d.ts +39 -0
  127. package/esm/deps/jsr.io/@std/encoding/1.0.11/base58.js +131 -0
  128. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.d.ts +39 -0
  129. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64.js +82 -0
  130. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.d.ts +39 -0
  131. package/esm/deps/jsr.io/@std/encoding/1.0.11/base64url.js +72 -0
  132. package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.d.ts +38 -0
  133. package/esm/deps/jsr.io/@std/encoding/1.0.11/hex.js +87 -0
  134. package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.d.ts +97 -0
  135. package/esm/deps/jsr.io/@std/encoding/1.0.11/mod.js +99 -0
  136. package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.d.ts +119 -0
  137. package/esm/deps/jsr.io/@std/encoding/1.0.11/varint.js +209 -0
  138. package/esm/deps/jsr.io/@std/http/1.1.3/status.d.ts +343 -0
  139. package/esm/deps/jsr.io/@std/http/1.1.3/status.js +343 -0
  140. package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.d.ts +159 -0
  141. package/esm/deps/jsr.io/@std/internal/1.0.14/assertion_state.js +223 -0
  142. package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.d.ts +79 -0
  143. package/esm/deps/jsr.io/@std/internal/1.0.14/build_message.js +116 -0
  144. package/esm/deps/jsr.io/@std/internal/1.0.14/diff.d.ts +139 -0
  145. package/esm/deps/jsr.io/@std/internal/1.0.14/diff.js +277 -0
  146. package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.d.ts +98 -0
  147. package/esm/deps/jsr.io/@std/internal/1.0.14/diff_str.js +181 -0
  148. package/esm/deps/jsr.io/@std/internal/1.0.14/format.d.ts +29 -0
  149. package/esm/deps/jsr.io/@std/internal/1.0.14/format.js +68 -0
  150. package/esm/deps/jsr.io/@std/internal/1.0.14/styles.d.ts +158 -0
  151. package/esm/deps/jsr.io/@std/internal/1.0.14/styles.js +206 -0
  152. package/esm/deps/jsr.io/@std/internal/1.0.14/types.d.ts +24 -0
  153. package/esm/deps/jsr.io/@std/internal/1.0.14/types.js +3 -0
  154. package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.d.ts +91 -0
  155. package/esm/deps/jsr.io/@std/testing/1.0.20/_test_suite.js +347 -0
  156. package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.d.ts +382 -0
  157. package/esm/deps/jsr.io/@std/testing/1.0.20/bdd.js +1110 -0
  158. package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.d.ts +363 -0
  159. package/esm/deps/jsr.io/@udibo/http-error/0.11.1/mod.js +616 -0
  160. package/esm/errors.d.ts +203 -0
  161. package/esm/errors.js +287 -0
  162. package/esm/identity/captcha.d.ts +147 -0
  163. package/esm/identity/captcha.js +64 -0
  164. package/esm/identity/delivery.d.ts +96 -0
  165. package/esm/identity/delivery.js +41 -0
  166. package/esm/identity/errors.d.ts +39 -0
  167. package/esm/identity/errors.js +46 -0
  168. package/esm/identity/events.d.ts +242 -0
  169. package/esm/identity/events.js +39 -0
  170. package/esm/identity/external/_shared.d.ts +86 -0
  171. package/esm/identity/external/_shared.js +107 -0
  172. package/esm/identity/external/_token-exchange.d.ts +61 -0
  173. package/esm/identity/external/_token-exchange.js +179 -0
  174. package/esm/identity/external/apple-client-secret.d.ts +82 -0
  175. package/esm/identity/external/apple-client-secret.js +133 -0
  176. package/esm/identity/external/apple.d.ts +64 -0
  177. package/esm/identity/external/apple.js +248 -0
  178. package/esm/identity/external/discord.d.ts +38 -0
  179. package/esm/identity/external/discord.js +62 -0
  180. package/esm/identity/external/errors.d.ts +48 -0
  181. package/esm/identity/external/errors.js +36 -0
  182. package/esm/identity/external/flow.d.ts +107 -0
  183. package/esm/identity/external/flow.js +158 -0
  184. package/esm/identity/external/github.d.ts +42 -0
  185. package/esm/identity/external/github.js +164 -0
  186. package/esm/identity/external/google.d.ts +52 -0
  187. package/esm/identity/external/google.js +38 -0
  188. package/esm/identity/external/mod.d.ts +63 -0
  189. package/esm/identity/external/mod.js +61 -0
  190. package/esm/identity/external/oauth2.d.ts +110 -0
  191. package/esm/identity/external/oauth2.js +158 -0
  192. package/esm/identity/external/oidc.d.ts +81 -0
  193. package/esm/identity/external/oidc.js +250 -0
  194. package/esm/identity/external/provider.d.ts +132 -0
  195. package/esm/identity/external/provider.js +12 -0
  196. package/esm/identity/hibp.d.ts +67 -0
  197. package/esm/identity/hibp.js +87 -0
  198. package/esm/identity/identifier.d.ts +44 -0
  199. package/esm/identity/identifier.js +47 -0
  200. package/esm/identity/lockout.d.ts +155 -0
  201. package/esm/identity/lockout.js +117 -0
  202. package/esm/identity/mfa/mod.d.ts +42 -0
  203. package/esm/identity/mfa/mod.js +42 -0
  204. package/esm/identity/mfa/recovery-codes.d.ts +96 -0
  205. package/esm/identity/mfa/recovery-codes.js +80 -0
  206. package/esm/identity/mfa/service.d.ts +338 -0
  207. package/esm/identity/mfa/service.js +351 -0
  208. package/esm/identity/mfa/totp.d.ts +186 -0
  209. package/esm/identity/mfa/totp.js +194 -0
  210. package/esm/identity/migration.d.ts +155 -0
  211. package/esm/identity/migration.js +243 -0
  212. package/esm/identity/mod.d.ts +65 -0
  213. package/esm/identity/mod.js +64 -0
  214. package/esm/identity/otp.d.ts +255 -0
  215. package/esm/identity/otp.js +245 -0
  216. package/esm/identity/password-policy.d.ts +45 -0
  217. package/esm/identity/password-policy.js +60 -0
  218. package/esm/identity/password.d.ts +171 -0
  219. package/esm/identity/password.js +160 -0
  220. package/esm/identity/rate-limit.d.ts +192 -0
  221. package/esm/identity/rate-limit.js +168 -0
  222. package/esm/identity/service.d.ts +579 -0
  223. package/esm/identity/service.js +835 -0
  224. package/esm/identity/session.d.ts +122 -0
  225. package/esm/identity/session.js +48 -0
  226. package/esm/identity/token-flow.d.ts +214 -0
  227. package/esm/identity/token-flow.js +173 -0
  228. package/esm/models/authentication.d.ts +24 -0
  229. package/esm/models/authentication.js +1 -0
  230. package/esm/models/authorization-code.d.ts +63 -0
  231. package/esm/models/authorization-code.js +1 -0
  232. package/esm/models/authorization.d.ts +165 -0
  233. package/esm/models/authorization.js +160 -0
  234. package/esm/models/client.d.ts +78 -0
  235. package/esm/models/client.js +1 -0
  236. package/esm/models/device-authorization.d.ts +30 -0
  237. package/esm/models/device-authorization.js +1 -0
  238. package/esm/models/responses.d.ts +93 -0
  239. package/esm/models/responses.js +1 -0
  240. package/esm/models/scope.d.ts +81 -0
  241. package/esm/models/scope.js +125 -0
  242. package/esm/models/token.d.ts +135 -0
  243. package/esm/models/token.js +1 -0
  244. package/esm/package.json +3 -0
  245. package/esm/react/callback.d.ts +52 -0
  246. package/esm/react/callback.js +71 -0
  247. package/esm/react/components/class-names.d.ts +91 -0
  248. package/esm/react/components/class-names.js +118 -0
  249. package/esm/react/components/internal.d.ts +62 -0
  250. package/esm/react/components/internal.js +102 -0
  251. package/esm/react/components/mfa-challenge-form.d.ts +66 -0
  252. package/esm/react/components/mfa-challenge-form.js +46 -0
  253. package/esm/react/components/mfa-enrollment-form.d.ts +83 -0
  254. package/esm/react/components/mfa-enrollment-form.js +41 -0
  255. package/esm/react/components/mod.d.ts +103 -0
  256. package/esm/react/components/mod.js +93 -0
  257. package/esm/react/components/request-password-reset-form.d.ts +61 -0
  258. package/esm/react/components/request-password-reset-form.js +41 -0
  259. package/esm/react/components/reset-password-form.d.ts +66 -0
  260. package/esm/react/components/reset-password-form.js +56 -0
  261. package/esm/react/components/sign-in-form.d.ts +74 -0
  262. package/esm/react/components/sign-in-form.js +43 -0
  263. package/esm/react/components/sign-up-form.d.ts +85 -0
  264. package/esm/react/components/sign-up-form.js +57 -0
  265. package/esm/react/components/types.d.ts +208 -0
  266. package/esm/react/components/types.js +14 -0
  267. package/esm/react/components/use-auth-form.d.ts +118 -0
  268. package/esm/react/components/use-auth-form.js +172 -0
  269. package/esm/react/components/user-menu.d.ts +79 -0
  270. package/esm/react/components/user-menu.js +73 -0
  271. package/esm/react/context.d.ts +51 -0
  272. package/esm/react/context.js +16 -0
  273. package/esm/react/mod.d.ts +26 -0
  274. package/esm/react/mod.js +26 -0
  275. package/esm/react/provider.d.ts +40 -0
  276. package/esm/react/provider.js +189 -0
  277. package/esm/react/require-auth.d.ts +31 -0
  278. package/esm/react/require-auth.js +37 -0
  279. package/esm/react/testing.d.ts +322 -0
  280. package/esm/react/testing.js +461 -0
  281. package/esm/react/use-authorization.d.ts +31 -0
  282. package/esm/react/use-authorization.js +36 -0
  283. package/esm/react/use-oauth2.d.ts +112 -0
  284. package/esm/react/use-oauth2.js +127 -0
  285. package/esm/server/authorization-server.d.ts +736 -0
  286. package/esm/server/authorization-server.js +1304 -0
  287. package/esm/server/client-authentication.d.ts +28 -0
  288. package/esm/server/client-authentication.js +51 -0
  289. package/esm/server/grants/authorization-code.d.ts +179 -0
  290. package/esm/server/grants/authorization-code.js +232 -0
  291. package/esm/server/grants/client-credentials.d.ts +52 -0
  292. package/esm/server/grants/client-credentials.js +53 -0
  293. package/esm/server/grants/device-authorization.d.ts +103 -0
  294. package/esm/server/grants/device-authorization.js +156 -0
  295. package/esm/server/grants/grant.d.ts +165 -0
  296. package/esm/server/grants/grant.js +173 -0
  297. package/esm/server/grants/password.d.ts +80 -0
  298. package/esm/server/grants/password.js +92 -0
  299. package/esm/server/grants/refresh-token.d.ts +80 -0
  300. package/esm/server/grants/refresh-token.js +136 -0
  301. package/esm/server/introspection-token-reader.d.ts +153 -0
  302. package/esm/server/introspection-token-reader.js +164 -0
  303. package/esm/server/jwks-token-reader.d.ts +263 -0
  304. package/esm/server/jwks-token-reader.js +508 -0
  305. package/esm/server/mod.d.ts +23 -0
  306. package/esm/server/mod.js +15 -0
  307. package/esm/server/public-suffix/mod.d.ts +62 -0
  308. package/esm/server/public-suffix/mod.js +103 -0
  309. package/esm/server/public-suffix/rules.d.ts +23 -0
  310. package/esm/server/public-suffix/rules.js +23 -0
  311. package/esm/server/redirect-uri.d.ts +187 -0
  312. package/esm/server/redirect-uri.js +331 -0
  313. package/esm/server/resource-server.d.ts +286 -0
  314. package/esm/server/resource-server.js +365 -0
  315. package/esm/server/services/authorization-code.d.ts +84 -0
  316. package/esm/server/services/authorization-code.js +35 -0
  317. package/esm/server/services/client.d.ts +35 -0
  318. package/esm/server/services/client.js +1 -0
  319. package/esm/server/services/device-authorization.d.ts +134 -0
  320. package/esm/server/services/device-authorization.js +7 -0
  321. package/esm/server/services/token.d.ts +242 -0
  322. package/esm/server/services/token.js +78 -0
  323. package/esm/server/services/user.d.ts +29 -0
  324. package/esm/server/services/user.js +7 -0
  325. package/esm/server/signing-keys.d.ts +201 -0
  326. package/esm/server/signing-keys.js +225 -0
  327. package/esm/server/utils/hash.d.ts +6 -0
  328. package/esm/server/utils/hash.js +11 -0
  329. package/esm/testing/contract/authorization-code.d.ts +37 -0
  330. package/esm/testing/contract/authorization-code.js +93 -0
  331. package/esm/testing/contract/client.d.ts +85 -0
  332. package/esm/testing/contract/client.js +126 -0
  333. package/esm/testing/contract/device-authorization.d.ts +37 -0
  334. package/esm/testing/contract/device-authorization.js +193 -0
  335. package/esm/testing/contract/lockout-store.d.ts +47 -0
  336. package/esm/testing/contract/lockout-store.js +122 -0
  337. package/esm/testing/contract/mfa-store.d.ts +50 -0
  338. package/esm/testing/contract/mfa-store.js +226 -0
  339. package/esm/testing/contract/mod.d.ts +39 -0
  340. package/esm/testing/contract/mod.js +39 -0
  341. package/esm/testing/contract/otp-store.d.ts +48 -0
  342. package/esm/testing/contract/otp-store.js +197 -0
  343. package/esm/testing/contract/rate-limit-store.d.ts +52 -0
  344. package/esm/testing/contract/rate-limit-store.js +105 -0
  345. package/esm/testing/contract/token-flow-store.d.ts +54 -0
  346. package/esm/testing/contract/token-flow-store.js +179 -0
  347. package/esm/testing/contract/token-reader.d.ts +77 -0
  348. package/esm/testing/contract/token-reader.js +78 -0
  349. package/esm/testing/contract/token.d.ts +61 -0
  350. package/esm/testing/contract/token.js +287 -0
  351. package/esm/testing/contract/user.d.ts +63 -0
  352. package/esm/testing/contract/user.js +75 -0
  353. package/esm/testing/mod.d.ts +34 -0
  354. package/esm/testing/mod.js +34 -0
  355. package/esm/testing/server.d.ts +197 -0
  356. package/esm/testing/server.js +193 -0
  357. package/esm/testing/services.d.ts +373 -0
  358. package/esm/testing/services.js +703 -0
  359. package/esm/utils/_buffer.d.ts +10 -0
  360. package/esm/utils/_buffer.js +12 -0
  361. package/esm/utils/_timing-safe.d.ts +13 -0
  362. package/esm/utils/_timing-safe.js +22 -0
  363. package/esm/utils/authentication-context.d.ts +3 -0
  364. package/esm/utils/authentication-context.js +14 -0
  365. package/esm/utils/basic-auth.d.ts +50 -0
  366. package/esm/utils/basic-auth.js +106 -0
  367. package/esm/utils/crypto.d.ts +97 -0
  368. package/esm/utils/crypto.js +162 -0
  369. package/esm/utils/pkce.d.ts +151 -0
  370. package/esm/utils/pkce.js +179 -0
  371. package/esm/utils/text.d.ts +24 -0
  372. package/esm/utils/text.js +28 -0
  373. package/esm/utils/url.d.ts +66 -0
  374. package/esm/utils/url.js +90 -0
  375. package/package.json +92 -0
@@ -0,0 +1,189 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * `<OAuth2Provider>` — wraps the app, wires an {@link OAuth2ClientBase} into
4
+ * a React context, and re-renders subscribers when the client emits
5
+ * authentication state changes.
6
+ *
7
+ * @module
8
+ */
9
+ import { useEffect, useMemo, useState } from "react";
10
+ import { toOAuth2Error } from "../errors.js";
11
+ import { OAuth2Context, } from "./context.js";
12
+ const DEFAULT_STATE = {
13
+ isAuthenticated: false,
14
+ isLoading: true,
15
+ user: null,
16
+ error: null,
17
+ sessionExpiresIn: null,
18
+ logoutUrl: null,
19
+ };
20
+ const RENEW_SKEW_SECONDS = 30;
21
+ const MIN_RENEW_MS = 5_000;
22
+ /**
23
+ * Fraction of the renew delay given up to jitter, applied one-sided so a renew
24
+ * never lands later than the un-jittered schedule.
25
+ */
26
+ const RENEW_JITTER = 0.1;
27
+ const isBrowser = () => typeof window !== "undefined";
28
+ /**
29
+ * Delay before renewing a session that expires in `expiresIn` seconds.
30
+ *
31
+ * Floors at {@link MIN_RENEW_MS}, so `0` — which a `DirectClient` reports for
32
+ * an already-expired token a refresh token can still revive — schedules a
33
+ * near-immediate renew rather than nothing at all.
34
+ */
35
+ function renewDelayMs(expiresIn) {
36
+ const base = Math.max(MIN_RENEW_MS, (expiresIn - RENEW_SKEW_SECONDS) * 1000);
37
+ return base * (1 - RENEW_JITTER * Math.random());
38
+ }
39
+ /** Seconds until `tokens` expires, or `null` when the server said nothing. */
40
+ function expiresInFrom(tokens) {
41
+ if (!tokens.accessTokenExpiresAt)
42
+ return null;
43
+ return Math.max(0, Math.round((tokens.accessTokenExpiresAt - Date.now()) / 1000));
44
+ }
45
+ /**
46
+ * Provider — install once near the root of your app. Children read the
47
+ * state via `useOAuth2()`.
48
+ *
49
+ * While authenticated it renews the session on a timer shortly before the
50
+ * access token expires, re-arming after each renew. Renewal is per tab and
51
+ * uncoordinated: a `DirectClient` given a refresh-token storage shared across
52
+ * tabs (e.g. `IndexedDBRefreshTokenStorage`) against a server that
53
+ * rotates refresh tokens can still have two tabs redeem the same token, which
54
+ * reuse detection may answer by ending the session everywhere.
55
+ */
56
+ export function OAuth2Provider(props) {
57
+ const { client, children, initialState } = props;
58
+ const [state, setState] = useState(() => ({
59
+ ...DEFAULT_STATE,
60
+ isLoading: initialState ? false : true,
61
+ ...initialState,
62
+ }));
63
+ const [renewCount, setRenewCount] = useState(0);
64
+ useEffect(() => {
65
+ let cancelled = false;
66
+ const handle = (event) => {
67
+ setState((prev) => reduce(prev, event));
68
+ // The `authenticated` event carries tokens only, so refetch user claims.
69
+ if (event.type === "authenticated") {
70
+ client.getUser().then((user) => {
71
+ if (!cancelled)
72
+ setState((prev) => ({ ...prev, user }));
73
+ }, () => { });
74
+ }
75
+ };
76
+ const unsubscribe = client.subscribe(handle);
77
+ return () => {
78
+ cancelled = true;
79
+ unsubscribe();
80
+ };
81
+ }, [client]);
82
+ // Re-sync when the server-resolved state changes (the only signal in BFF
83
+ // mode, whose callback completes server-side). Keyed on an identity
84
+ // signature, not the often-inline `initialState` reference, to avoid thrash.
85
+ const seededAuthenticated = initialState?.isAuthenticated ?? null;
86
+ const seededUserSub = initialState?.user?.sub ?? null;
87
+ useEffect(() => {
88
+ if (!initialState)
89
+ return;
90
+ setState((prev) => {
91
+ const next = {
92
+ ...DEFAULT_STATE,
93
+ isLoading: false,
94
+ ...initialState,
95
+ };
96
+ if (prev.isAuthenticated === next.isAuthenticated &&
97
+ (prev.user?.sub ?? null) === (next.user?.sub ?? null) &&
98
+ prev.isLoading === next.isLoading) {
99
+ return prev;
100
+ }
101
+ return next;
102
+ });
103
+ }, [client, seededAuthenticated, seededUserSub]);
104
+ useEffect(() => {
105
+ if (initialState)
106
+ return;
107
+ if (!isBrowser())
108
+ return;
109
+ let cancelled = false;
110
+ setState((prev) => ({ ...prev, isLoading: true }));
111
+ client.getSession().then((session) => {
112
+ if (!cancelled)
113
+ setState({ ...session, isLoading: false, error: null });
114
+ }, (error) => {
115
+ if (cancelled)
116
+ return;
117
+ setState({
118
+ ...DEFAULT_STATE,
119
+ isLoading: false,
120
+ error: toOAuth2Error(error),
121
+ });
122
+ });
123
+ return () => {
124
+ cancelled = true;
125
+ };
126
+ }, [client, initialState]);
127
+ useEffect(() => {
128
+ if (!isBrowser())
129
+ return;
130
+ if (!state.isAuthenticated)
131
+ return;
132
+ const expiresIn = state.sessionExpiresIn;
133
+ if (expiresIn == null || !Number.isFinite(expiresIn) || expiresIn < 0) {
134
+ return;
135
+ }
136
+ let cancelled = false;
137
+ const delayMs = renewDelayMs(expiresIn);
138
+ const timer = setTimeout(() => {
139
+ client.renewSession().then((session) => {
140
+ if (cancelled)
141
+ return;
142
+ setState((prev) => ({ ...prev, ...session }));
143
+ setRenewCount((count) => count + 1);
144
+ }, () => {
145
+ if (!cancelled)
146
+ setRenewCount((count) => count + 1);
147
+ });
148
+ }, delayMs);
149
+ return () => {
150
+ cancelled = true;
151
+ clearTimeout(timer);
152
+ };
153
+ }, [client, state.isAuthenticated, state.sessionExpiresIn, renewCount]);
154
+ const value = useMemo(() => ({
155
+ client,
156
+ ...state,
157
+ }), [client, state]);
158
+ return (_jsx(OAuth2Context.Provider, { value: value, children: children }));
159
+ }
160
+ function reduce(prev, event) {
161
+ switch (event.type) {
162
+ case "authenticated":
163
+ return {
164
+ ...prev,
165
+ isAuthenticated: true,
166
+ isLoading: false,
167
+ error: null,
168
+ sessionExpiresIn: expiresInFrom(event.tokens),
169
+ };
170
+ case "logged_out":
171
+ return {
172
+ isAuthenticated: false,
173
+ isLoading: false,
174
+ user: null,
175
+ error: null,
176
+ sessionExpiresIn: null,
177
+ logoutUrl: null,
178
+ };
179
+ case "token_refreshed":
180
+ return {
181
+ ...prev,
182
+ isLoading: false,
183
+ error: null,
184
+ sessionExpiresIn: expiresInFrom(event.tokens),
185
+ };
186
+ case "error":
187
+ return { ...prev, error: toOAuth2Error(event.error) };
188
+ }
189
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `<RequireAuth>` — gate a subtree behind authentication. If the user is
3
+ * not authenticated, calls `login({ returnTo })` (the {@link useOAuth2}
4
+ * action, which navigates the browser to the login / authorize URL) with
5
+ * `returnTo` set to the current path, and renders a configurable
6
+ * `fallback` while the redirect is in flight.
7
+ *
8
+ * Avoids the `withAuthenticationRequired` re-mount footgun (the HOC
9
+ * isn't created in render; this component just gates its children).
10
+ *
11
+ * @module
12
+ */
13
+ import { type ReactNode } from "react";
14
+ /** Props for {@link RequireAuth}. */
15
+ export interface RequireAuthProps {
16
+ /** Children rendered when authenticated. */
17
+ children: ReactNode;
18
+ /**
19
+ * What to render while the redirect is being kicked off / the
20
+ * initial probe is in flight. Defaults to `null` (nothing).
21
+ */
22
+ fallback?: ReactNode;
23
+ /** Optional explicit `returnTo`. Defaults to `window.location.pathname + window.location.search`. */
24
+ returnTo?: string;
25
+ }
26
+ /**
27
+ * Render `children` only when authenticated. Otherwise call
28
+ * `login({ returnTo })` once and render `fallback` while the redirect
29
+ * is in flight.
30
+ */
31
+ export declare function RequireAuth(props: RequireAuthProps): ReactNode;
@@ -0,0 +1,37 @@
1
+ // deno-lint-ignore-file no-window -- browser-only; `window` used only after isBrowser() guards
2
+ /**
3
+ * `<RequireAuth>` — gate a subtree behind authentication. If the user is
4
+ * not authenticated, calls `login({ returnTo })` (the {@link useOAuth2}
5
+ * action, which navigates the browser to the login / authorize URL) with
6
+ * `returnTo` set to the current path, and renders a configurable
7
+ * `fallback` while the redirect is in flight.
8
+ *
9
+ * Avoids the `withAuthenticationRequired` re-mount footgun (the HOC
10
+ * isn't created in render; this component just gates its children).
11
+ *
12
+ * @module
13
+ */
14
+ import { useEffect } from "react";
15
+ import { useOAuth2 } from "./use-oauth2.js";
16
+ const isBrowser = () => typeof window !== "undefined";
17
+ /**
18
+ * Render `children` only when authenticated. Otherwise call
19
+ * `login({ returnTo })` once and render `fallback` while the redirect
20
+ * is in flight.
21
+ */
22
+ export function RequireAuth(props) {
23
+ const { children, fallback = null, returnTo } = props;
24
+ const { isAuthenticated, isLoading, login } = useOAuth2();
25
+ useEffect(() => {
26
+ if (isLoading || isAuthenticated)
27
+ return;
28
+ if (!isBrowser())
29
+ return;
30
+ const target = returnTo ??
31
+ `${window.location.pathname}${window.location.search}`;
32
+ login({ returnTo: target }).catch(() => { });
33
+ }, [isLoading, isAuthenticated, login, returnTo]);
34
+ if (isLoading || !isAuthenticated)
35
+ return fallback;
36
+ return children;
37
+ }
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Testing helpers for the `@udibo/oauth2/react` adapter.
3
+ *
4
+ * Three mock clients and a provider:
5
+ *
6
+ * - {@link createMockOAuth2Client} — an `OAuth2ClientBase` with no HTTP,
7
+ * PKCE, or storage behind it. Use it for a component written against the
8
+ * shared surface.
9
+ * - {@link createMockBffClient} / {@link createMockDirectClient} — the same
10
+ * mock behavior on a real `BffClient` / `DirectClient` subclass, so
11
+ * `useBffClient()`, `useDirectClient()`, and `<OAuth2Callback>` accept them.
12
+ * Reach for these when the component under test narrows.
13
+ * - {@link MockOAuth2Provider} — drop-in replacement for `<OAuth2Provider>`
14
+ * that skips the initial session probe and accepts any of the three. Use it
15
+ * to unit-test components that consume `useOAuth2()` / `<RequireAuth>`
16
+ * without any network.
17
+ *
18
+ * Every mock emits on the same event bus the real clients use, so a subtree
19
+ * under a real `<OAuth2Provider>` re-renders just as it would in production.
20
+ * {@link MockOAuth2Provider} is not live: it seeds its context once from the
21
+ * client and keeps that snapshot, so a test that needs the state to *change*
22
+ * mid-render should mount a real `<OAuth2Provider>` around the mock client and
23
+ * call `signIn` / `signOut` on it. Configure `sessionExpiresIn` to exercise
24
+ * `<OAuth2Provider>`'s pre-expiry renew timer, and read
25
+ * {@link MockOAuth2Controls.renewCount} to assert it fired.
26
+ *
27
+ * **JSDOM recipes** for component tests in this adapter:
28
+ *
29
+ * - `window.location.assign` — the adapter's `login()` / `logout()` (via
30
+ * `useOAuth2()` and `<RequireAuth>`) navigate by calling
31
+ * `window.location.assign(url)`. JSDOM throws on unhandled navigation;
32
+ * stub it: `stub(window.location, "assign", () => {})` (or the
33
+ * equivalent for your runner).
34
+ * - `crypto.subtle` — required for PKCE in a real `DirectClient`. The mocks
35
+ * don't use it, so JSDOM tests of components-with-mock-client are
36
+ * safe out of the box.
37
+ * - `sessionStorage` — needed by
38
+ * `SessionStorageAuthRequestStorage`. JSDOM ships one; the mocks
39
+ * never touch it.
40
+ * - `history.replaceState` — `<OAuth2Callback>`'s default `onNavigate`
41
+ * uses it. JSDOM ships it.
42
+ *
43
+ * @module
44
+ */
45
+ import "../_dnt.polyfills.js";
46
+ import { type ReactNode } from "react";
47
+ import { type AuthorizationRedirect, type BaseLoginOptions, BffClient, DirectClient, type LoginRedirect, type LogoutRedirect, OAuth2ClientBase, type OAuth2Error, type SessionState, type UserInfoClaims } from "../client/mod.js";
48
+ import { type OAuth2State } from "./context.js";
49
+ /** Where a mock client starts. */
50
+ export interface MockOAuth2ClientState {
51
+ /** Whether the mock starts signed in. Defaults to `user !== null`. */
52
+ isAuthenticated?: boolean;
53
+ /** The cached user claims the mock starts with. Defaults to `null`. */
54
+ user?: UserInfoClaims | null;
55
+ /** The `logoutUrl` the mock reports while signed in. Defaults to `/auth/logout`. */
56
+ logoutUrl?: string | null;
57
+ /**
58
+ * Seconds the mock reports until expiry. Defaults to `null` (no expiry, so
59
+ * `<OAuth2Provider>` schedules no renew). Set it to arm the renew timer.
60
+ */
61
+ sessionExpiresIn?: number | null;
62
+ }
63
+ /** The state knobs every mock client exposes, whatever it subclasses. */
64
+ export interface MockOAuth2Controls {
65
+ /**
66
+ * The starting state the mock was built with, defaults applied — what
67
+ * {@link MockOAuth2Provider} seeds its context from, so configuring the
68
+ * client is enough. A snapshot taken at construction: later
69
+ * `signIn`/`signOut` calls drive the event bus and do not change it.
70
+ */
71
+ readonly initialState: Pick<OAuth2State, "isAuthenticated" | "user">;
72
+ /** How many times `renewSession()` has been called. */
73
+ readonly renewCount: number;
74
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
75
+ signIn(user?: UserInfoClaims): void;
76
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
77
+ signOut(): void;
78
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
79
+ refreshTokens(expiresIn?: number | null): void;
80
+ /** Surfaces an error through the event bus. */
81
+ setError(error: OAuth2Error | unknown): void;
82
+ /** Replaces the cached user without changing authentication status. */
83
+ setUser(user: UserInfoClaims | null): void;
84
+ /** Replaces the reported seconds-to-expiry. */
85
+ setSessionExpiresIn(seconds: number | null): void;
86
+ }
87
+ /**
88
+ * A client that satisfies the shared `OAuth2ClientBase` surface without making
89
+ * a single request.
90
+ *
91
+ * Neither a `BffClient` nor a `DirectClient`, so `useBffClient()` and
92
+ * `useDirectClient()` reject it — that is deliberate, and
93
+ * {@link createMockBffClient} / {@link createMockDirectClient} are what a
94
+ * narrowing component wants.
95
+ */
96
+ export declare class MockOAuth2Client extends OAuth2ClientBase implements MockOAuth2Controls {
97
+ #private;
98
+ /**
99
+ * Builds a mock client and snapshots its starting state.
100
+ *
101
+ * @param state Where the mock starts. Everything is optional; the default
102
+ * is a signed-out client.
103
+ */
104
+ constructor(state?: MockOAuth2ClientState);
105
+ /** The starting state, defaults applied. */
106
+ get initialState(): Pick<OAuth2State, "isAuthenticated" | "user">;
107
+ /** How many times `renewSession()` has been called. */
108
+ get renewCount(): number;
109
+ /** Resolves a fixed `mock://login` URL without touching any network. */
110
+ login(_options?: BaseLoginOptions): Promise<LoginRedirect>;
111
+ /** Drops to signed out, emits `logged_out`, and returns no redirect URL. */
112
+ logout(): Promise<LogoutRedirect>;
113
+ /** The mock's current user, or `null` while signed out. */
114
+ getUser(): Promise<UserInfoClaims | null>;
115
+ /** The mock's current state. */
116
+ getSession(): Promise<SessionState>;
117
+ /** Counts the call and re-reads {@link getSession}. */
118
+ renewSession(): Promise<SessionState>;
119
+ /** Passes straight through to `globalThis.fetch` with no auth attached. */
120
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
121
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
122
+ signIn(user?: UserInfoClaims): void;
123
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
124
+ signOut(): void;
125
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
126
+ refreshTokens(expiresIn?: number | null): void;
127
+ /** Surfaces an error through the event bus. */
128
+ setError(error: OAuth2Error | unknown): void;
129
+ /** Replaces the cached user without changing authentication status. */
130
+ setUser(user: UserInfoClaims | null): void;
131
+ /** Replaces the reported seconds-to-expiry. */
132
+ setSessionExpiresIn(seconds: number | null): void;
133
+ }
134
+ /**
135
+ * A real `BffClient` whose four session operations answer from mock state
136
+ * instead of the BFF. `useBffClient()` accepts it.
137
+ */
138
+ export declare class MockBffClient extends BffClient implements MockOAuth2Controls {
139
+ #private;
140
+ /**
141
+ * Builds a mock client and snapshots its starting state.
142
+ *
143
+ * @param state Where the mock starts. Everything is optional; the default
144
+ * is a signed-out client.
145
+ */
146
+ constructor(state?: MockOAuth2ClientState);
147
+ /** The starting state, defaults applied. */
148
+ get initialState(): Pick<OAuth2State, "isAuthenticated" | "user">;
149
+ /** How many times `renewSession()` has been called. */
150
+ get renewCount(): number;
151
+ /** Resolves a fixed `mock://login` URL, bypassing the BFF's URL builder. */
152
+ login(_options?: BaseLoginOptions): Promise<LoginRedirect>;
153
+ /** Drops to signed out and returns no redirect URL. */
154
+ logout(): Promise<LogoutRedirect>;
155
+ /** The mock's current user, with no session probe. */
156
+ getUser(): Promise<UserInfoClaims | null>;
157
+ /** The mock's current state, with no session probe. */
158
+ getSession(): Promise<SessionState>;
159
+ /** Counts the call and re-reads {@link getSession}. */
160
+ renewSession(): Promise<SessionState>;
161
+ /** Passes straight through to `globalThis.fetch`. */
162
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
163
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
164
+ signIn(user?: UserInfoClaims): void;
165
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
166
+ signOut(): void;
167
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
168
+ refreshTokens(expiresIn?: number | null): void;
169
+ /** Surfaces an error through the event bus. */
170
+ setError(error: OAuth2Error | unknown): void;
171
+ /** Replaces the cached user without changing authentication status. */
172
+ setUser(user: UserInfoClaims | null): void;
173
+ /** Replaces the reported seconds-to-expiry. */
174
+ setSessionExpiresIn(seconds: number | null): void;
175
+ }
176
+ /**
177
+ * A real `DirectClient` whose session operations answer from mock state
178
+ * instead of a token endpoint. `useDirectClient()` and `<OAuth2Callback>`
179
+ * accept it.
180
+ *
181
+ * The token-holding methods it does **not** override (`refresh`,
182
+ * `handleAuthorizationCallback`, `introspect`, …) still reach for the network.
183
+ * Stub the one your test drives, or point a real `DirectClient` at
184
+ * `createMemoryAuthorizationServer().fetch` instead.
185
+ */
186
+ export declare class MockDirectClient extends DirectClient implements MockOAuth2Controls {
187
+ #private;
188
+ /**
189
+ * Builds a mock client and snapshots its starting state.
190
+ *
191
+ * @param state Where the mock starts. Everything is optional; the default
192
+ * is a signed-out client.
193
+ */
194
+ constructor(state?: MockOAuth2ClientState);
195
+ /** The starting state, defaults applied. */
196
+ get initialState(): Pick<OAuth2State, "isAuthenticated" | "user">;
197
+ /** How many times `renewSession()` has been called. */
198
+ get renewCount(): number;
199
+ /** Resolves a fixed `mock://login` URL, skipping PKCE and storage. */
200
+ login(_options?: BaseLoginOptions): Promise<AuthorizationRedirect>;
201
+ /** Drops to signed out without revoking anything. */
202
+ logout(): Promise<LogoutRedirect>;
203
+ /** The mock's current user, with no token read. */
204
+ getUser(): Promise<UserInfoClaims | null>;
205
+ /** The mock's current state, with no token read. */
206
+ getSession(): Promise<SessionState>;
207
+ /** Counts the call and re-reads {@link getSession}. */
208
+ renewSession(): Promise<SessionState>;
209
+ /** Passes straight through to `globalThis.fetch`, attaching no bearer. */
210
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
211
+ /** Resolves the mock access token without touching storage. */
212
+ getAccessToken(): Promise<string>;
213
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
214
+ signIn(user?: UserInfoClaims): void;
215
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
216
+ signOut(): void;
217
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
218
+ refreshTokens(expiresIn?: number | null): void;
219
+ /** Surfaces an error through the event bus. */
220
+ setError(error: OAuth2Error | unknown): void;
221
+ /** Replaces the cached user without changing authentication status. */
222
+ setUser(user: UserInfoClaims | null): void;
223
+ /** Replaces the reported seconds-to-expiry. */
224
+ setSessionExpiresIn(seconds: number | null): void;
225
+ }
226
+ /**
227
+ * Builds a {@link MockOAuth2Client}. No HTTP, no storage, no PKCE — just
228
+ * state and an event bus that the React adapter reads through the provider.
229
+ *
230
+ * @param initialState Where the mock starts.
231
+ * @returns The mock client, ready to hand to a provider.
232
+ *
233
+ * @example
234
+ * ```tsx
235
+ * import { createMockOAuth2Client, MockOAuth2Provider } from
236
+ * "@udibo/oauth2/react/testing";
237
+ *
238
+ * const client = createMockOAuth2Client({ user: { sub: "u1" } });
239
+ * render(
240
+ * <MockOAuth2Provider client={client}>
241
+ * <Header />
242
+ * </MockOAuth2Provider>,
243
+ * );
244
+ * ```
245
+ */
246
+ export declare function createMockOAuth2Client(initialState?: MockOAuth2ClientState): MockOAuth2Client;
247
+ /**
248
+ * Builds a {@link MockBffClient} — mock state on a real `BffClient`, so a
249
+ * component that calls `useBffClient()` can be unit-tested.
250
+ *
251
+ * @param initialState Where the mock starts.
252
+ * @returns The mock client, ready to hand to a provider.
253
+ *
254
+ * @example
255
+ * ```tsx
256
+ * import { createMockBffClient, MockOAuth2Provider } from
257
+ * "@udibo/oauth2/react/testing";
258
+ *
259
+ * const client = createMockBffClient({ user: { sub: "u1" } });
260
+ * render(
261
+ * <MockOAuth2Provider client={client}>
262
+ * <SignInLink returnTo="/dashboard" />
263
+ * </MockOAuth2Provider>,
264
+ * );
265
+ * ```
266
+ */
267
+ export declare function createMockBffClient(initialState?: MockOAuth2ClientState): MockBffClient;
268
+ /**
269
+ * Builds a {@link MockDirectClient} — mock state on a real `DirectClient`, so
270
+ * a component that calls `useDirectClient()` (or mounts `<OAuth2Callback>`)
271
+ * can be unit-tested.
272
+ *
273
+ * @param initialState Where the mock starts.
274
+ * @returns The mock client, ready to hand to a provider.
275
+ *
276
+ * @example
277
+ * ```tsx
278
+ * import { createMockDirectClient, MockOAuth2Provider } from
279
+ * "@udibo/oauth2/react/testing";
280
+ *
281
+ * const client = createMockDirectClient({ user: { sub: "u1" } });
282
+ * render(
283
+ * <MockOAuth2Provider client={client}>
284
+ * <TokenReadout />
285
+ * </MockOAuth2Provider>,
286
+ * );
287
+ * ```
288
+ */
289
+ export declare function createMockDirectClient(initialState?: MockOAuth2ClientState): MockDirectClient;
290
+ /** Props for {@link MockOAuth2Provider}. */
291
+ export interface MockOAuth2ProviderProps {
292
+ /**
293
+ * Built via {@link createMockOAuth2Client}, {@link createMockBffClient}, or
294
+ * {@link createMockDirectClient}.
295
+ */
296
+ client: OAuth2ClientBase & MockOAuth2Controls;
297
+ /**
298
+ * Optional initial state override, applied key by key: a key you pass wins
299
+ * (including `user: null`), a key you omit falls back to the mock client's
300
+ * {@link MockOAuth2Controls.initialState} for `isAuthenticated` / `user` and
301
+ * to the signed-out default for the rest. So a test configures the client
302
+ * once instead of restating the same user here.
303
+ */
304
+ state?: Partial<OAuth2State>;
305
+ /** The subtree rendered under the mock provider. */
306
+ children: ReactNode;
307
+ }
308
+ /**
309
+ * Drop-in replacement for `<OAuth2Provider>` that skips the on-mount
310
+ * session probe (the mock clients don't issue one) and surfaces the
311
+ * mock state synchronously.
312
+ *
313
+ * The context it publishes is a snapshot of the client as it was built (plus
314
+ * any `state` overrides): it subscribes to nothing, so calling `signIn` /
315
+ * `signOut` on the client afterwards does not re-render the subtree. Render
316
+ * the state you want, or use a real `<OAuth2Provider>` when the test is about
317
+ * a transition.
318
+ *
319
+ * @param props A mock client, optional state overrides, and children.
320
+ * @returns The subtree wrapped in a pre-resolved OAuth2 context.
321
+ */
322
+ export declare function MockOAuth2Provider(props: MockOAuth2ProviderProps): ReactNode;