@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,461 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Testing helpers for the `@udibo/oauth2/react` adapter.
4
+ *
5
+ * Three mock clients and a provider:
6
+ *
7
+ * - {@link createMockOAuth2Client} — an `OAuth2ClientBase` with no HTTP,
8
+ * PKCE, or storage behind it. Use it for a component written against the
9
+ * shared surface.
10
+ * - {@link createMockBffClient} / {@link createMockDirectClient} — the same
11
+ * mock behavior on a real `BffClient` / `DirectClient` subclass, so
12
+ * `useBffClient()`, `useDirectClient()`, and `<OAuth2Callback>` accept them.
13
+ * Reach for these when the component under test narrows.
14
+ * - {@link MockOAuth2Provider} — drop-in replacement for `<OAuth2Provider>`
15
+ * that skips the initial session probe and accepts any of the three. Use it
16
+ * to unit-test components that consume `useOAuth2()` / `<RequireAuth>`
17
+ * without any network.
18
+ *
19
+ * Every mock emits on the same event bus the real clients use, so a subtree
20
+ * under a real `<OAuth2Provider>` re-renders just as it would in production.
21
+ * {@link MockOAuth2Provider} is not live: it seeds its context once from the
22
+ * client and keeps that snapshot, so a test that needs the state to *change*
23
+ * mid-render should mount a real `<OAuth2Provider>` around the mock client and
24
+ * call `signIn` / `signOut` on it. Configure `sessionExpiresIn` to exercise
25
+ * `<OAuth2Provider>`'s pre-expiry renew timer, and read
26
+ * {@link MockOAuth2Controls.renewCount} to assert it fired.
27
+ *
28
+ * **JSDOM recipes** for component tests in this adapter:
29
+ *
30
+ * - `window.location.assign` — the adapter's `login()` / `logout()` (via
31
+ * `useOAuth2()` and `<RequireAuth>`) navigate by calling
32
+ * `window.location.assign(url)`. JSDOM throws on unhandled navigation;
33
+ * stub it: `stub(window.location, "assign", () => {})` (or the
34
+ * equivalent for your runner).
35
+ * - `crypto.subtle` — required for PKCE in a real `DirectClient`. The mocks
36
+ * don't use it, so JSDOM tests of components-with-mock-client are
37
+ * safe out of the box.
38
+ * - `sessionStorage` — needed by
39
+ * `SessionStorageAuthRequestStorage`. JSDOM ships one; the mocks
40
+ * never touch it.
41
+ * - `history.replaceState` — `<OAuth2Callback>`'s default `onNavigate`
42
+ * uses it. JSDOM ships it.
43
+ *
44
+ * @module
45
+ */
46
+ import "../_dnt.polyfills.js";
47
+ import { useMemo } from "react";
48
+ import { BffClient, DirectClient, OAuth2ClientBase, } from "../client/mod.js";
49
+ import { OAuth2Context } from "./context.js";
50
+ /** The mock behavior each client class delegates to. */
51
+ class MockCore {
52
+ initialState;
53
+ renewCount = 0;
54
+ #user;
55
+ #isAuthenticated;
56
+ #logoutUrl;
57
+ #sessionExpiresIn;
58
+ #emit;
59
+ constructor(state, emit) {
60
+ this.#user = state.user ?? null;
61
+ this.#isAuthenticated = state.isAuthenticated ?? this.#user !== null;
62
+ this.#logoutUrl = state.logoutUrl ?? "/auth/logout";
63
+ this.#sessionExpiresIn = state.sessionExpiresIn ?? null;
64
+ this.#emit = emit;
65
+ this.initialState = {
66
+ isAuthenticated: this.#isAuthenticated,
67
+ user: this.#user,
68
+ };
69
+ }
70
+ session() {
71
+ return {
72
+ isAuthenticated: this.#isAuthenticated,
73
+ user: this.#isAuthenticated ? this.#user : null,
74
+ sessionExpiresIn: this.#isAuthenticated ? this.#sessionExpiresIn : null,
75
+ logoutUrl: this.#isAuthenticated ? this.#logoutUrl : null,
76
+ };
77
+ }
78
+ user() {
79
+ return this.#isAuthenticated ? this.#user : null;
80
+ }
81
+ renew() {
82
+ this.renewCount++;
83
+ return this.session();
84
+ }
85
+ signIn(user) {
86
+ this.#isAuthenticated = true;
87
+ this.#user = user ?? this.#user ?? { sub: "mock-user" };
88
+ this.#emit({ type: "authenticated", tokens: this.#tokens() });
89
+ }
90
+ signOut() {
91
+ this.#isAuthenticated = false;
92
+ this.#user = null;
93
+ this.#emit({ type: "logged_out", reason: "user" });
94
+ }
95
+ refreshTokens(expiresIn) {
96
+ if (expiresIn !== undefined)
97
+ this.#sessionExpiresIn = expiresIn;
98
+ this.#emit({ type: "token_refreshed", tokens: this.#tokens() });
99
+ }
100
+ setError(error) {
101
+ this.#emit({ type: "error", error });
102
+ }
103
+ setUser(user) {
104
+ this.#user = user;
105
+ }
106
+ setSessionExpiresIn(seconds) {
107
+ this.#sessionExpiresIn = seconds;
108
+ }
109
+ #tokens() {
110
+ return {
111
+ accessToken: "mock-access-token",
112
+ tokenType: "Bearer",
113
+ accessTokenExpiresAt: this.#sessionExpiresIn === null
114
+ ? undefined
115
+ : Date.now() + this.#sessionExpiresIn * 1000,
116
+ };
117
+ }
118
+ }
119
+ const MOCK_LOGIN_URL = "mock://login";
120
+ /**
121
+ * A client that satisfies the shared `OAuth2ClientBase` surface without making
122
+ * a single request.
123
+ *
124
+ * Neither a `BffClient` nor a `DirectClient`, so `useBffClient()` and
125
+ * `useDirectClient()` reject it — that is deliberate, and
126
+ * {@link createMockBffClient} / {@link createMockDirectClient} are what a
127
+ * narrowing component wants.
128
+ */
129
+ export class MockOAuth2Client extends OAuth2ClientBase {
130
+ #core;
131
+ /**
132
+ * Builds a mock client and snapshots its starting state.
133
+ *
134
+ * @param state Where the mock starts. Everything is optional; the default
135
+ * is a signed-out client.
136
+ */
137
+ constructor(state = {}) {
138
+ super();
139
+ this.#core = new MockCore(state, (event) => this.emit(event));
140
+ }
141
+ /** The starting state, defaults applied. */
142
+ get initialState() {
143
+ return this.#core.initialState;
144
+ }
145
+ /** How many times `renewSession()` has been called. */
146
+ get renewCount() {
147
+ return this.#core.renewCount;
148
+ }
149
+ /** Resolves a fixed `mock://login` URL without touching any network. */
150
+ login(_options) {
151
+ return Promise.resolve({ url: MOCK_LOGIN_URL });
152
+ }
153
+ /** Drops to signed out, emits `logged_out`, and returns no redirect URL. */
154
+ logout() {
155
+ this.signOut();
156
+ return Promise.resolve({});
157
+ }
158
+ /** The mock's current user, or `null` while signed out. */
159
+ getUser() {
160
+ return Promise.resolve(this.#core.user());
161
+ }
162
+ /** The mock's current state. */
163
+ getSession() {
164
+ return Promise.resolve(this.#core.session());
165
+ }
166
+ /** Counts the call and re-reads {@link getSession}. */
167
+ renewSession() {
168
+ return Promise.resolve(this.#core.renew());
169
+ }
170
+ /** Passes straight through to `globalThis.fetch` with no auth attached. */
171
+ fetch(input, init) {
172
+ return globalThis.fetch(input, init);
173
+ }
174
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
175
+ signIn(user) {
176
+ this.#core.signIn(user);
177
+ }
178
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
179
+ signOut() {
180
+ this.#core.signOut();
181
+ }
182
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
183
+ refreshTokens(expiresIn) {
184
+ this.#core.refreshTokens(expiresIn);
185
+ }
186
+ /** Surfaces an error through the event bus. */
187
+ setError(error) {
188
+ this.#core.setError(error);
189
+ }
190
+ /** Replaces the cached user without changing authentication status. */
191
+ setUser(user) {
192
+ this.#core.setUser(user);
193
+ }
194
+ /** Replaces the reported seconds-to-expiry. */
195
+ setSessionExpiresIn(seconds) {
196
+ this.#core.setSessionExpiresIn(seconds);
197
+ }
198
+ }
199
+ /**
200
+ * A real `BffClient` whose four session operations answer from mock state
201
+ * instead of the BFF. `useBffClient()` accepts it.
202
+ */
203
+ export class MockBffClient extends BffClient {
204
+ #core;
205
+ /**
206
+ * Builds a mock client and snapshots its starting state.
207
+ *
208
+ * @param state Where the mock starts. Everything is optional; the default
209
+ * is a signed-out client.
210
+ */
211
+ constructor(state = {}) {
212
+ super();
213
+ this.#core = new MockCore(state, (event) => this.emit(event));
214
+ }
215
+ /** The starting state, defaults applied. */
216
+ get initialState() {
217
+ return this.#core.initialState;
218
+ }
219
+ /** How many times `renewSession()` has been called. */
220
+ get renewCount() {
221
+ return this.#core.renewCount;
222
+ }
223
+ /** Resolves a fixed `mock://login` URL, bypassing the BFF's URL builder. */
224
+ login(_options) {
225
+ return Promise.resolve({ url: MOCK_LOGIN_URL });
226
+ }
227
+ /** Drops to signed out and returns no redirect URL. */
228
+ logout() {
229
+ this.signOut();
230
+ return Promise.resolve({});
231
+ }
232
+ /** The mock's current user, with no session probe. */
233
+ getUser() {
234
+ return Promise.resolve(this.#core.user());
235
+ }
236
+ /** The mock's current state, with no session probe. */
237
+ getSession() {
238
+ return Promise.resolve(this.#core.session());
239
+ }
240
+ /** Counts the call and re-reads {@link getSession}. */
241
+ renewSession() {
242
+ return Promise.resolve(this.#core.renew());
243
+ }
244
+ /** Passes straight through to `globalThis.fetch`. */
245
+ fetch(input, init) {
246
+ return globalThis.fetch(input, init);
247
+ }
248
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
249
+ signIn(user) {
250
+ this.#core.signIn(user);
251
+ }
252
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
253
+ signOut() {
254
+ this.#core.signOut();
255
+ }
256
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
257
+ refreshTokens(expiresIn) {
258
+ this.#core.refreshTokens(expiresIn);
259
+ }
260
+ /** Surfaces an error through the event bus. */
261
+ setError(error) {
262
+ this.#core.setError(error);
263
+ }
264
+ /** Replaces the cached user without changing authentication status. */
265
+ setUser(user) {
266
+ this.#core.setUser(user);
267
+ }
268
+ /** Replaces the reported seconds-to-expiry. */
269
+ setSessionExpiresIn(seconds) {
270
+ this.#core.setSessionExpiresIn(seconds);
271
+ }
272
+ }
273
+ /**
274
+ * A real `DirectClient` whose session operations answer from mock state
275
+ * instead of a token endpoint. `useDirectClient()` and `<OAuth2Callback>`
276
+ * accept it.
277
+ *
278
+ * The token-holding methods it does **not** override (`refresh`,
279
+ * `handleAuthorizationCallback`, `introspect`, …) still reach for the network.
280
+ * Stub the one your test drives, or point a real `DirectClient` at
281
+ * `createMemoryAuthorizationServer().fetch` instead.
282
+ */
283
+ export class MockDirectClient extends DirectClient {
284
+ #core;
285
+ /**
286
+ * Builds a mock client and snapshots its starting state.
287
+ *
288
+ * @param state Where the mock starts. Everything is optional; the default
289
+ * is a signed-out client.
290
+ */
291
+ constructor(state = {}) {
292
+ super({ clientId: "mock-client", endpoints: { token: "mock://token" } });
293
+ this.#core = new MockCore(state, (event) => this.emit(event));
294
+ }
295
+ /** The starting state, defaults applied. */
296
+ get initialState() {
297
+ return this.#core.initialState;
298
+ }
299
+ /** How many times `renewSession()` has been called. */
300
+ get renewCount() {
301
+ return this.#core.renewCount;
302
+ }
303
+ /** Resolves a fixed `mock://login` URL, skipping PKCE and storage. */
304
+ login(_options) {
305
+ return Promise.resolve({ url: MOCK_LOGIN_URL, state: "mock-state" });
306
+ }
307
+ /** Drops to signed out without revoking anything. */
308
+ logout() {
309
+ this.signOut();
310
+ return Promise.resolve({});
311
+ }
312
+ /** The mock's current user, with no token read. */
313
+ getUser() {
314
+ return Promise.resolve(this.#core.user());
315
+ }
316
+ /** The mock's current state, with no token read. */
317
+ getSession() {
318
+ return Promise.resolve(this.#core.session());
319
+ }
320
+ /** Counts the call and re-reads {@link getSession}. */
321
+ renewSession() {
322
+ return Promise.resolve(this.#core.renew());
323
+ }
324
+ /** Passes straight through to `globalThis.fetch`, attaching no bearer. */
325
+ fetch(input, init) {
326
+ return globalThis.fetch(input, init);
327
+ }
328
+ /** Resolves the mock access token without touching storage. */
329
+ getAccessToken() {
330
+ return Promise.resolve("mock-access-token");
331
+ }
332
+ /** Pushes the mock into an authenticated state and emits `authenticated`. */
333
+ signIn(user) {
334
+ this.#core.signIn(user);
335
+ }
336
+ /** Pushes the mock into an unauthenticated state and emits `logged_out`. */
337
+ signOut() {
338
+ this.#core.signOut();
339
+ }
340
+ /** Emits `token_refreshed` with a bundle expiring in `expiresIn` seconds. */
341
+ refreshTokens(expiresIn) {
342
+ this.#core.refreshTokens(expiresIn);
343
+ }
344
+ /** Surfaces an error through the event bus. */
345
+ setError(error) {
346
+ this.#core.setError(error);
347
+ }
348
+ /** Replaces the cached user without changing authentication status. */
349
+ setUser(user) {
350
+ this.#core.setUser(user);
351
+ }
352
+ /** Replaces the reported seconds-to-expiry. */
353
+ setSessionExpiresIn(seconds) {
354
+ this.#core.setSessionExpiresIn(seconds);
355
+ }
356
+ }
357
+ /**
358
+ * Builds a {@link MockOAuth2Client}. No HTTP, no storage, no PKCE — just
359
+ * state and an event bus that the React adapter reads through the provider.
360
+ *
361
+ * @param initialState Where the mock starts.
362
+ * @returns The mock client, ready to hand to a provider.
363
+ *
364
+ * @example
365
+ * ```tsx
366
+ * import { createMockOAuth2Client, MockOAuth2Provider } from
367
+ * "@udibo/oauth2/react/testing";
368
+ *
369
+ * const client = createMockOAuth2Client({ user: { sub: "u1" } });
370
+ * render(
371
+ * <MockOAuth2Provider client={client}>
372
+ * <Header />
373
+ * </MockOAuth2Provider>,
374
+ * );
375
+ * ```
376
+ */
377
+ export function createMockOAuth2Client(initialState = {}) {
378
+ return new MockOAuth2Client(initialState);
379
+ }
380
+ /**
381
+ * Builds a {@link MockBffClient} — mock state on a real `BffClient`, so a
382
+ * component that calls `useBffClient()` can be unit-tested.
383
+ *
384
+ * @param initialState Where the mock starts.
385
+ * @returns The mock client, ready to hand to a provider.
386
+ *
387
+ * @example
388
+ * ```tsx
389
+ * import { createMockBffClient, MockOAuth2Provider } from
390
+ * "@udibo/oauth2/react/testing";
391
+ *
392
+ * const client = createMockBffClient({ user: { sub: "u1" } });
393
+ * render(
394
+ * <MockOAuth2Provider client={client}>
395
+ * <SignInLink returnTo="/dashboard" />
396
+ * </MockOAuth2Provider>,
397
+ * );
398
+ * ```
399
+ */
400
+ export function createMockBffClient(initialState = {}) {
401
+ return new MockBffClient(initialState);
402
+ }
403
+ /**
404
+ * Builds a {@link MockDirectClient} — mock state on a real `DirectClient`, so
405
+ * a component that calls `useDirectClient()` (or mounts `<OAuth2Callback>`)
406
+ * can be unit-tested.
407
+ *
408
+ * @param initialState Where the mock starts.
409
+ * @returns The mock client, ready to hand to a provider.
410
+ *
411
+ * @example
412
+ * ```tsx
413
+ * import { createMockDirectClient, MockOAuth2Provider } from
414
+ * "@udibo/oauth2/react/testing";
415
+ *
416
+ * const client = createMockDirectClient({ user: { sub: "u1" } });
417
+ * render(
418
+ * <MockOAuth2Provider client={client}>
419
+ * <TokenReadout />
420
+ * </MockOAuth2Provider>,
421
+ * );
422
+ * ```
423
+ */
424
+ export function createMockDirectClient(initialState = {}) {
425
+ return new MockDirectClient(initialState);
426
+ }
427
+ /**
428
+ * Drop-in replacement for `<OAuth2Provider>` that skips the on-mount
429
+ * session probe (the mock clients don't issue one) and surfaces the
430
+ * mock state synchronously.
431
+ *
432
+ * The context it publishes is a snapshot of the client as it was built (plus
433
+ * any `state` overrides): it subscribes to nothing, so calling `signIn` /
434
+ * `signOut` on the client afterwards does not re-render the subtree. Render
435
+ * the state you want, or use a real `<OAuth2Provider>` when the test is about
436
+ * a transition.
437
+ *
438
+ * @param props A mock client, optional state overrides, and children.
439
+ * @returns The subtree wrapped in a pre-resolved OAuth2 context.
440
+ */
441
+ export function MockOAuth2Provider(props) {
442
+ const { client, state, children } = props;
443
+ const value = useMemo(() => {
444
+ const override = state ?? {};
445
+ const overrides = (key) => key in override;
446
+ return {
447
+ client,
448
+ isAuthenticated: overrides("isAuthenticated")
449
+ ? override.isAuthenticated === true
450
+ : client.initialState.isAuthenticated,
451
+ isLoading: override.isLoading ?? false,
452
+ user: overrides("user")
453
+ ? override.user ?? null
454
+ : client.initialState.user,
455
+ error: override.error ?? null,
456
+ sessionExpiresIn: override.sessionExpiresIn ?? null,
457
+ logoutUrl: override.logoutUrl ?? null,
458
+ };
459
+ }, [client, state]);
460
+ return (_jsx(OAuth2Context.Provider, { value: value, children: children }));
461
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * React hook exposing the signed-in user's {@link Authorization} — the same
3
+ * checkable object the resource server derives from an access token, built
4
+ * here from the session's id_token claims.
5
+ *
6
+ * @module
7
+ */
8
+ import { type Authorization } from "../models/authorization.js";
9
+ /**
10
+ * The signed-in user's authorization, derived from the session's claims.
11
+ *
12
+ * Browser checks are **rendering hints only** — show or hide an affordance,
13
+ * never gate the action itself; the API's middleware is the enforcement. An
14
+ * unauthenticated session yields an empty authorization (every predicate
15
+ * `false`), and id_token claims carry no OAuth2 scope, so
16
+ * {@link Authorization.hasScope} answers `false` here — scope is the API's
17
+ * check, not the browser's.
18
+ *
19
+ * @throws {Error} when called outside an `<OAuth2Provider>`.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * import { useAuthorization } from "@udibo/oauth2/react";
24
+ *
25
+ * function PostActions() {
26
+ * const authorization = useAuthorization();
27
+ * return authorization.can("posts:write") ? <button>Edit</button> : null;
28
+ * }
29
+ * ```
30
+ */
31
+ export declare function useAuthorization(): Authorization;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * React hook exposing the signed-in user's {@link Authorization} — the same
3
+ * checkable object the resource server derives from an access token, built
4
+ * here from the session's id_token claims.
5
+ *
6
+ * @module
7
+ */
8
+ import { useMemo } from "react";
9
+ import { authorizationFromClaims, } from "../models/authorization.js";
10
+ import { useOAuth2 } from "./use-oauth2.js";
11
+ /**
12
+ * The signed-in user's authorization, derived from the session's claims.
13
+ *
14
+ * Browser checks are **rendering hints only** — show or hide an affordance,
15
+ * never gate the action itself; the API's middleware is the enforcement. An
16
+ * unauthenticated session yields an empty authorization (every predicate
17
+ * `false`), and id_token claims carry no OAuth2 scope, so
18
+ * {@link Authorization.hasScope} answers `false` here — scope is the API's
19
+ * check, not the browser's.
20
+ *
21
+ * @throws {Error} when called outside an `<OAuth2Provider>`.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * import { useAuthorization } from "@udibo/oauth2/react";
26
+ *
27
+ * function PostActions() {
28
+ * const authorization = useAuthorization();
29
+ * return authorization.can("posts:write") ? <button>Edit</button> : null;
30
+ * }
31
+ * ```
32
+ */
33
+ export function useAuthorization() {
34
+ const { user } = useOAuth2();
35
+ return useMemo(() => authorizationFromClaims(user), [user]);
36
+ }
@@ -0,0 +1,112 @@
1
+ import { type BaseLoginOptions, BffClient, DirectClient, type LogoutOptions, type OAuth2ClientBase, type OAuth2Error, type UserInfoClaims } from "../client/mod.js";
2
+ /** Return value of {@link useOAuth2}. */
3
+ export interface UseOAuth2Result {
4
+ /** True iff a user is authenticated. */
5
+ isAuthenticated: boolean;
6
+ /** True during the initial probe / a refresh in progress. */
7
+ isLoading: boolean;
8
+ /** Current user claims, or `null`. */
9
+ user: UserInfoClaims | null;
10
+ /** Last error surfaced by the client, or `null`. */
11
+ error: OAuth2Error | null;
12
+ /**
13
+ * Seconds until the session's access token expires, or `null` when unknown.
14
+ * The provider renews shortly before this elapses.
15
+ */
16
+ sessionExpiresIn: number | null;
17
+ /** A URL that ends the session, or `null` when the client offers none. */
18
+ logoutUrl: string | null;
19
+ /**
20
+ * Start a login. Calls `client.login(opts)` and, in the browser, navigates
21
+ * to the returned URL (the BFF login endpoint, or the authorization
22
+ * endpoint). Returns the `{ url }` so non-browser callers (SSR) can
23
+ * navigate themselves.
24
+ *
25
+ * Takes only what both clients understand. For a `DirectClient`'s per-call
26
+ * `scope` / `prompt` / `extraParams`, go through
27
+ * {@link useDirectClient}`().login(...)` — those options have no meaning to
28
+ * a BFF, which builds its own authorize request server-side.
29
+ */
30
+ login(opts?: BaseLoginOptions): Promise<{
31
+ url?: string;
32
+ }>;
33
+ /**
34
+ * Start a logout. Calls `client.logout(opts)` and, in the browser,
35
+ * navigates to the returned URL if the flow needs a redirect (the BFF
36
+ * logout endpoint, or the IDP end-session URL). Returns `{ url }` for
37
+ * SSR callers.
38
+ */
39
+ logout(opts?: LogoutOptions): Promise<{
40
+ url?: string;
41
+ }>;
42
+ /** Bound `client.fetch` — the request-with-auth helper. */
43
+ fetch: typeof fetch;
44
+ /**
45
+ * The underlying client. Narrow it with {@link useBffClient} or
46
+ * {@link useDirectClient} to reach transport-specific methods.
47
+ */
48
+ client: OAuth2ClientBase;
49
+ }
50
+ /**
51
+ * Reads the OAuth2 context, returning the current state and bound convenience
52
+ * methods. Works with either client, so components written against it don't
53
+ * care whether a BFF or this process holds the tokens.
54
+ *
55
+ * @returns Auth state plus `login` / `logout` / `fetch` and the raw client.
56
+ * @throws {Error} when called outside an `<OAuth2Provider>`.
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * import { useOAuth2 } from "@udibo/oauth2/react";
61
+ *
62
+ * function Header() {
63
+ * const { isAuthenticated, user, login, logout } = useOAuth2();
64
+ * return isAuthenticated
65
+ * ? <button onClick={() => logout()}>Sign out {String(user?.sub)}</button>
66
+ * : <button onClick={() => login()}>Sign in</button>;
67
+ * }
68
+ * ```
69
+ */
70
+ export declare function useOAuth2(): UseOAuth2Result;
71
+ /**
72
+ * The context's client, narrowed to a `BffClient`. Use it for the BFF-only
73
+ * surface — chiefly `loginContinuation`, for a "Sign in" link from your own
74
+ * create-account or forgot-password page.
75
+ *
76
+ * @returns The provider's `BffClient`.
77
+ * @throws {Error} when called outside an `<OAuth2Provider>`, or when the
78
+ * provider was given a `DirectClient` — the BFF routes it targets don't exist
79
+ * in that deployment.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * import { useBffClient } from "@udibo/oauth2/react";
84
+ *
85
+ * function SignInLink({ returnTo }: { returnTo: string }) {
86
+ * const client = useBffClient();
87
+ * return <a href={client.loginContinuation(returnTo)}>Sign in</a>;
88
+ * }
89
+ * ```
90
+ */
91
+ export declare function useBffClient(): BffClient;
92
+ /**
93
+ * The context's client, narrowed to a `DirectClient`. Use it for the surface
94
+ * that only exists when this process holds the tokens — `getAccessToken`,
95
+ * `handleAuthorizationCallback`, `refresh`, `introspect`, `revoke`.
96
+ *
97
+ * @returns The provider's `DirectClient`.
98
+ * @throws {Error} when called outside an `<OAuth2Provider>`, or when the
99
+ * provider was given a `BffClient` — the browser never sees a token in that
100
+ * deployment, so there is none to hand back.
101
+ *
102
+ * @example
103
+ * ```tsx
104
+ * import { useDirectClient } from "@udibo/oauth2/react";
105
+ *
106
+ * function useBearer() {
107
+ * const client = useDirectClient();
108
+ * return () => client.getAccessToken();
109
+ * }
110
+ * ```
111
+ */
112
+ export declare function useDirectClient(): DirectClient;