@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,118 @@
1
+ /**
2
+ * {@link useAuthForm} — the headless hook backing every default auth form
3
+ * component in `@udibo/oauth2/react/components`.
4
+ *
5
+ * It owns field values, per-field and form-level errors, and the submit
6
+ * lifecycle, and stays entirely presentation-free: no markup, no styling, no
7
+ * router or network assumptions. The action is injected as `onSubmit`, so the
8
+ * same hook drives a client-side `fetch` in a plain React Router app or a
9
+ * router-action submit in Juniper. Reach for it directly when you want to own
10
+ * the markup completely (the "eject to headless" path); otherwise use a
11
+ * default component, which is built on this hook.
12
+ *
13
+ * @module
14
+ */
15
+ import { type ChangeEvent } from "react";
16
+ import type { AuthFormErrors, AuthFormValues, AuthSubmitHandler } from "./types.js";
17
+ /** Lifecycle status of an {@link useAuthForm} instance. */
18
+ export type AuthFormStatus = "idle" | "submitting" | "success" | "error";
19
+ /**
20
+ * Props spread onto a field's `<input>` to wire value, change handling, and
21
+ * accessibility. Produced by {@link AuthFormState.getFieldProps}.
22
+ */
23
+ export interface AuthFieldProps {
24
+ /** The input's `id`, also referenced by its label's `htmlFor`. */
25
+ id: string;
26
+ /** The field name (form key). */
27
+ name: string;
28
+ /** Current string value (checkboxes read `checked` instead — see below). */
29
+ value: string;
30
+ /** Whether a checkbox field is checked (omitted for text fields). */
31
+ checked?: boolean;
32
+ /** Change handler that reads `value`/`checked` and updates form state. */
33
+ onChange: (event: ChangeEvent<HTMLInputElement>) => void;
34
+ /** `true` when the field currently has an error, else `undefined`. */
35
+ "aria-invalid"?: true;
36
+ /** The id of this field's error element when errored, else `undefined`. */
37
+ "aria-describedby"?: string;
38
+ }
39
+ /** Options for {@link useAuthForm}. */
40
+ export interface UseAuthFormOptions<V extends AuthFormValues> {
41
+ /** Starting values; also defines the set of fields. */
42
+ initialValues: V;
43
+ /** The injected action that performs the submit. */
44
+ onSubmit: AuthSubmitHandler<V>;
45
+ /**
46
+ * Optional synchronous client-side validation run before `onSubmit`. Return
47
+ * a map of field errors to block submission, or `null`/`undefined` to allow.
48
+ * A throw is trapped like an `onSubmit` throw — surfaced as a form-level
49
+ * error (`status: "error"`) rather than an unhandled rejection.
50
+ */
51
+ validate?: (values: V) => AuthFormErrors<V> | null | undefined;
52
+ /**
53
+ * Called after a successful submit (no `error`/`fieldErrors` returned). A
54
+ * promise it returns is awaited, but a throw or rejection is caught and
55
+ * logged to `console.error` rather than surfaced: `status` stays `"success"`
56
+ * and no form error appears.
57
+ */
58
+ onSuccess?: (values: V) => void;
59
+ }
60
+ /**
61
+ * The live state and actions returned by {@link useAuthForm}. This is also the
62
+ * value passed to a form component's render-prop `children`.
63
+ */
64
+ export interface AuthFormState<V extends AuthFormValues> {
65
+ /** Current field values. */
66
+ values: V;
67
+ /** Current per-field errors. */
68
+ errors: AuthFormErrors<V>;
69
+ /** Current form-level error, or `null`. */
70
+ formError: string | null;
71
+ /** Lifecycle status. */
72
+ status: AuthFormStatus;
73
+ /** `true` while a submit is in flight (`status === "submitting"`). */
74
+ isSubmitting: boolean;
75
+ /** `true` once a submit has completed successfully. */
76
+ succeeded: boolean;
77
+ /** Increments on every submit attempt; useful as a focus-effect trigger. */
78
+ submitCount: number;
79
+ /** Set a single field's value. */
80
+ setValue<K extends keyof V & string>(name: K, value: V[K]): void;
81
+ /** Merge a partial set of field values. */
82
+ setValues(next: Partial<V>): void;
83
+ /** Reset values to `initialValues` and clear all errors/status. */
84
+ reset(): void;
85
+ /** Submit handler for a `<form onSubmit>` (calls `preventDefault`). */
86
+ handleSubmit(event?: {
87
+ preventDefault(): void;
88
+ }): Promise<void>;
89
+ /** Build the props to spread onto a field's `<input>`. */
90
+ getFieldProps<K extends keyof V & string>(name: K): AuthFieldProps;
91
+ }
92
+ /**
93
+ * Headless form engine: owns values, errors, and the submit lifecycle for an
94
+ * auth form, delegating the actual action to the injected `onSubmit`.
95
+ *
96
+ * @example Eject to fully custom markup
97
+ * ```tsx
98
+ * const form = useAuthForm({
99
+ * initialValues: { identifier: "", password: "" },
100
+ * onSubmit: async (values) => {
101
+ * const res = await fetch("/auth/sign-in", {
102
+ * method: "POST",
103
+ * body: JSON.stringify(values),
104
+ * });
105
+ * if (!res.ok) return { error: "Invalid credentials" };
106
+ * },
107
+ * });
108
+ * return (
109
+ * <form onSubmit={form.handleSubmit}>
110
+ * <input {...form.getFieldProps("identifier")} />
111
+ * <input {...form.getFieldProps("password")} type="password" />
112
+ * {form.formError ? <p role="alert">{form.formError}</p> : null}
113
+ * <button type="submit" disabled={form.isSubmitting}>Sign in</button>
114
+ * </form>
115
+ * );
116
+ * ```
117
+ */
118
+ export declare function useAuthForm<V extends AuthFormValues>(options: UseAuthFormOptions<V>): AuthFormState<V>;
@@ -0,0 +1,172 @@
1
+ /**
2
+ * {@link useAuthForm} — the headless hook backing every default auth form
3
+ * component in `@udibo/oauth2/react/components`.
4
+ *
5
+ * It owns field values, per-field and form-level errors, and the submit
6
+ * lifecycle, and stays entirely presentation-free: no markup, no styling, no
7
+ * router or network assumptions. The action is injected as `onSubmit`, so the
8
+ * same hook drives a client-side `fetch` in a plain React Router app or a
9
+ * router-action submit in Juniper. Reach for it directly when you want to own
10
+ * the markup completely (the "eject to headless" path); otherwise use a
11
+ * default component, which is built on this hook.
12
+ *
13
+ * @module
14
+ */
15
+ import { useCallback, useId, useMemo, useRef, useState, } from "react";
16
+ /**
17
+ * Headless form engine: owns values, errors, and the submit lifecycle for an
18
+ * auth form, delegating the actual action to the injected `onSubmit`.
19
+ *
20
+ * @example Eject to fully custom markup
21
+ * ```tsx
22
+ * const form = useAuthForm({
23
+ * initialValues: { identifier: "", password: "" },
24
+ * onSubmit: async (values) => {
25
+ * const res = await fetch("/auth/sign-in", {
26
+ * method: "POST",
27
+ * body: JSON.stringify(values),
28
+ * });
29
+ * if (!res.ok) return { error: "Invalid credentials" };
30
+ * },
31
+ * });
32
+ * return (
33
+ * <form onSubmit={form.handleSubmit}>
34
+ * <input {...form.getFieldProps("identifier")} />
35
+ * <input {...form.getFieldProps("password")} type="password" />
36
+ * {form.formError ? <p role="alert">{form.formError}</p> : null}
37
+ * <button type="submit" disabled={form.isSubmitting}>Sign in</button>
38
+ * </form>
39
+ * );
40
+ * ```
41
+ */
42
+ export function useAuthForm(options) {
43
+ const { initialValues, onSubmit, validate, onSuccess } = options;
44
+ const idBase = useId();
45
+ const [values, setValuesState] = useState(initialValues);
46
+ const [errors, setErrors] = useState({});
47
+ const [formError, setFormError] = useState(null);
48
+ const [status, setStatus] = useState("idle");
49
+ const [submitCount, setSubmitCount] = useState(0);
50
+ // Synchronous re-entrancy lock: `status` is a render-closure value, so it
51
+ // can't block a same-tick double submit (Enter racing autofill, etc.).
52
+ const submittingRef = useRef(false);
53
+ const setValue = useCallback((name, value) => {
54
+ setValuesState((prev) => ({ ...prev, [name]: value }));
55
+ }, []);
56
+ const setValues = useCallback((next) => {
57
+ setValuesState((prev) => ({ ...prev, ...next }));
58
+ }, []);
59
+ const reset = useCallback(() => {
60
+ setValuesState(initialValues);
61
+ setErrors({});
62
+ setFormError(null);
63
+ setStatus("idle");
64
+ }, [initialValues]);
65
+ const handleSubmit = useCallback(async (event) => {
66
+ event?.preventDefault();
67
+ if (submittingRef.current)
68
+ return;
69
+ submittingRef.current = true;
70
+ try {
71
+ setSubmitCount((count) => count + 1);
72
+ setFormError(null);
73
+ setErrors({});
74
+ if (validate) {
75
+ let validationErrors;
76
+ try {
77
+ validationErrors = validate(values);
78
+ }
79
+ catch (error) {
80
+ setFormError(error instanceof Error ? error.message : "Something went wrong.");
81
+ setStatus("error");
82
+ return;
83
+ }
84
+ if (validationErrors && Object.keys(validationErrors).length > 0) {
85
+ setErrors(validationErrors);
86
+ setStatus("error");
87
+ return;
88
+ }
89
+ }
90
+ setStatus("submitting");
91
+ let result;
92
+ try {
93
+ result = await onSubmit(values);
94
+ }
95
+ catch (error) {
96
+ setFormError(error instanceof Error ? error.message : "Something went wrong.");
97
+ setStatus("error");
98
+ return;
99
+ }
100
+ const fieldErrors = result?.fieldErrors;
101
+ const hasFieldErrors = fieldErrors &&
102
+ Object.keys(fieldErrors).length > 0;
103
+ if (result?.error || hasFieldErrors) {
104
+ if (result?.error)
105
+ setFormError(result.error);
106
+ if (hasFieldErrors)
107
+ setErrors(fieldErrors);
108
+ setStatus("error");
109
+ return;
110
+ }
111
+ setStatus("success");
112
+ // An integrator's onSuccess side effect must not become an unhandled
113
+ // rejection (form onSubmit doesn't await handleSubmit).
114
+ try {
115
+ await onSuccess?.(values);
116
+ }
117
+ catch (error) {
118
+ console.error("[@udibo/oauth2] auth form onSuccess failed:", error);
119
+ }
120
+ }
121
+ finally {
122
+ submittingRef.current = false;
123
+ }
124
+ }, [values, validate, onSubmit, onSuccess]);
125
+ const getFieldProps = useCallback((name) => {
126
+ const raw = values[name];
127
+ const hasError = Boolean(errors[name]);
128
+ const id = `${idBase}-${name}`;
129
+ const base = {
130
+ id,
131
+ name,
132
+ value: typeof raw === "boolean" ? "" : String(raw ?? ""),
133
+ onChange: (event) => {
134
+ const target = event.target;
135
+ const next = target.type === "checkbox"
136
+ ? target.checked
137
+ : target.value;
138
+ setValue(name, next);
139
+ },
140
+ "aria-invalid": hasError ? true : undefined,
141
+ "aria-describedby": hasError ? `${id}-error` : undefined,
142
+ };
143
+ if (typeof raw === "boolean")
144
+ base.checked = raw;
145
+ return base;
146
+ }, [values, errors, idBase, setValue]);
147
+ return useMemo(() => ({
148
+ values,
149
+ errors,
150
+ formError,
151
+ status,
152
+ isSubmitting: status === "submitting",
153
+ succeeded: status === "success",
154
+ submitCount,
155
+ setValue,
156
+ setValues,
157
+ reset,
158
+ handleSubmit,
159
+ getFieldProps,
160
+ }), [
161
+ values,
162
+ errors,
163
+ formError,
164
+ status,
165
+ submitCount,
166
+ setValue,
167
+ setValues,
168
+ reset,
169
+ handleSubmit,
170
+ getFieldProps,
171
+ ]);
172
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * {@link UserMenu} — a default, accessible, unstyled signed-in user menu. Reads
3
+ * the current user and `logout` from {@link useOAuth2}, renders a disclosure
4
+ * button showing the user's name, and exposes a logout action plus a slot for
5
+ * your own menu items.
6
+ *
7
+ * Renders `null` (or a `signedOut` slot) when no user is authenticated, so it
8
+ * is safe to mount unconditionally in a nav bar.
9
+ *
10
+ * The claims type its `renderUser` / `children` callbacks receive is
11
+ * `UserInfoClaims`, imported from `@udibo/oauth2/client` — it belongs to the
12
+ * client, not to this component.
13
+ *
14
+ * @module
15
+ */
16
+ import { type ReactNode } from "react";
17
+ import type { UserInfoClaims } from "../../client/mod.js";
18
+ import type { BaseClassNames } from "./types.js";
19
+ /**
20
+ * Per-slot class hooks for {@link UserMenu}: the shared {@link BaseClassNames}
21
+ * `root` plus the menu's own slots.
22
+ */
23
+ export interface UserMenuClassNames extends BaseClassNames {
24
+ /** The disclosure trigger button (`data-oauth2-user-trigger`). */
25
+ trigger?: string;
26
+ /** The display-name element inside the trigger. */
27
+ name?: string;
28
+ /** The menu panel revealed on open (`data-oauth2-user-panel`). */
29
+ menu?: string;
30
+ /** Each menu item wrapper. */
31
+ menuItem?: string;
32
+ /** The logout button (`data-oauth2-logout`). */
33
+ logout?: string;
34
+ }
35
+ /** Visible text overrides for {@link UserMenu}. */
36
+ export interface UserMenuLabels {
37
+ /** Logout action text. Default: `"Sign out"`. */
38
+ logout?: string;
39
+ }
40
+ /** Props for {@link UserMenu}. */
41
+ export interface UserMenuProps {
42
+ /** Extra menu content rendered above the logout action (links, etc.). */
43
+ items?: ReactNode;
44
+ /**
45
+ * Override the logout behaviour. Defaults to `useOAuth2().logout()`, which
46
+ * ends the session and (in the browser) navigates to the logout URL.
47
+ */
48
+ onLogout?: () => void | Promise<void>;
49
+ /** Custom renderer for the trigger's user display. */
50
+ renderUser?: (user: UserInfoClaims) => ReactNode;
51
+ /** Rendered when no user is authenticated. Default: `null`. */
52
+ signedOut?: ReactNode;
53
+ /** Class for the root wrapper (merged with `classNames.root`). */
54
+ className?: string;
55
+ /** Per-slot class hooks for theming. */
56
+ classNames?: UserMenuClassNames;
57
+ /** Text overrides. */
58
+ labels?: UserMenuLabels;
59
+ /**
60
+ * Render-prop escape hatch. Receives the current user and a `logout`
61
+ * callback so you can render an entirely custom menu.
62
+ */
63
+ children?: (state: {
64
+ user: UserInfoClaims;
65
+ logout: () => void | Promise<void>;
66
+ }) => ReactNode;
67
+ }
68
+ /**
69
+ * A ready-to-use signed-in user menu. Mount it in your nav; it reads auth
70
+ * state from the surrounding `<OAuth2Provider>`.
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <UserMenu
75
+ * items={<a href="/profile">Profile</a>}
76
+ * />
77
+ * ```
78
+ */
79
+ export declare function UserMenu(props: UserMenuProps): ReactNode;
@@ -0,0 +1,73 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * {@link UserMenu} — a default, accessible, unstyled signed-in user menu. Reads
4
+ * the current user and `logout` from {@link useOAuth2}, renders a disclosure
5
+ * button showing the user's name, and exposes a logout action plus a slot for
6
+ * your own menu items.
7
+ *
8
+ * Renders `null` (or a `signedOut` slot) when no user is authenticated, so it
9
+ * is safe to mount unconditionally in a nav bar.
10
+ *
11
+ * The claims type its `renderUser` / `children` callbacks receive is
12
+ * `UserInfoClaims`, imported from `@udibo/oauth2/client` — it belongs to the
13
+ * client, not to this component.
14
+ *
15
+ * @module
16
+ */
17
+ import { useEffect, useId, useRef, useState } from "react";
18
+ import { useOAuth2 } from "../use-oauth2.js";
19
+ import { combineClassNames, displayName } from "./internal.js";
20
+ /**
21
+ * A ready-to-use signed-in user menu. Mount it in your nav; it reads auth
22
+ * state from the surrounding `<OAuth2Provider>`.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <UserMenu
27
+ * items={<a href="/profile">Profile</a>}
28
+ * />
29
+ * ```
30
+ */
31
+ export function UserMenu(props) {
32
+ const { items, onLogout, renderUser, signedOut = null, className, classNames, labels, children, } = props;
33
+ const { user, logout } = useOAuth2();
34
+ const [open, setOpen] = useState(false);
35
+ const panelId = useId();
36
+ const rootRef = useRef(null);
37
+ useEffect(() => {
38
+ if (!open)
39
+ return;
40
+ const onKeyDown = (event) => {
41
+ if (event.key === "Escape")
42
+ setOpen(false);
43
+ };
44
+ const onPointerDown = (event) => {
45
+ if (!rootRef.current?.contains(event.target))
46
+ setOpen(false);
47
+ };
48
+ document.addEventListener("keydown", onKeyDown);
49
+ document.addEventListener("pointerdown", onPointerDown);
50
+ return () => {
51
+ document.removeEventListener("keydown", onKeyDown);
52
+ document.removeEventListener("pointerdown", onPointerDown);
53
+ };
54
+ }, [open]);
55
+ if (!user)
56
+ return _jsx(_Fragment, { children: signedOut });
57
+ const runLogout = onLogout ?? (async () => {
58
+ await logout();
59
+ });
60
+ if (children)
61
+ return _jsx(_Fragment, { children: children({ user, logout: runLogout }) });
62
+ return (_jsxs("div", { ref: rootRef, "data-oauth2-user-menu": "", className: combineClassNames(className, classNames?.root), children: [_jsx("button", { type: "button", "aria-expanded": open, "aria-controls": panelId, onClick: () => setOpen((value) => !value), "data-oauth2-user-trigger": "", className: classNames?.trigger, children: renderUser
63
+ ? renderUser(user)
64
+ : (_jsx("span", { "data-oauth2-user-name": "", className: classNames?.name, children: displayName(user) })) }), open
65
+ ? (_jsxs("div", { id: panelId, "data-oauth2-user-panel": "", className: classNames?.menu, children: [items
66
+ ? (_jsx("div", { "data-oauth2-user-items": "", className: classNames?.menuItem, children: items }))
67
+ : null, _jsx("button", { type: "button", onClick: () => {
68
+ void Promise.resolve(runLogout()).catch((error) => {
69
+ console.error("[@udibo/oauth2] logout failed:", error);
70
+ });
71
+ }, "data-oauth2-logout": "", className: classNames?.logout, children: labels?.logout ?? "Sign out" })] }))
72
+ : null] }));
73
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * React context wiring for the OAuth2 client.
3
+ *
4
+ * Internal — consumers should reach for {@link useOAuth2} (the hook),
5
+ * {@link OAuth2Provider}, {@link RequireAuth}, and {@link OAuth2Callback}
6
+ * rather than the context object directly.
7
+ *
8
+ * @module
9
+ */
10
+ import { type Context } from "react";
11
+ import type { OAuth2ClientBase, OAuth2Error, UserInfoClaims } from "../client/mod.js";
12
+ /** Shape exposed by `useOAuth2()`. */
13
+ export interface OAuth2State {
14
+ /** Whether a user is currently authenticated. */
15
+ isAuthenticated: boolean;
16
+ /**
17
+ * `true` during the initial session probe and during a token refresh
18
+ * with no currently valid access token. Settles to `false` once
19
+ * authentication state is known.
20
+ */
21
+ isLoading: boolean;
22
+ /**
23
+ * Current user claims, or `null` when unauthenticated. From
24
+ * `GET /auth/session` behind a `BffClient`; the decoded `id_token` claims
25
+ * (or the `userinfo_endpoint` body) behind a `DirectClient`.
26
+ */
27
+ user: UserInfoClaims | null;
28
+ /** Last error surfaced by the client, or `null`. */
29
+ error: OAuth2Error | null;
30
+ /**
31
+ * Seconds until the session's access token expires, or `null` when unknown.
32
+ * The provider calls `client.renewSession()` shortly before this elapses.
33
+ */
34
+ sessionExpiresIn: number | null;
35
+ /**
36
+ * A URL that ends the session, or `null` when the client has none to offer.
37
+ * Lets a UI render a sign-out link without hardcoding the path.
38
+ */
39
+ logoutUrl: string | null;
40
+ }
41
+ /** Internal context value shared by the provider and consumers. */
42
+ export interface OAuth2ContextValue extends OAuth2State {
43
+ /** The underlying client — a `BffClient` or a `DirectClient`. */
44
+ client: OAuth2ClientBase;
45
+ }
46
+ /**
47
+ * Internal context — providers wire up the value, consumers read it
48
+ * through `useOAuth2()`. Default `null` so `useOAuth2()` can throw a
49
+ * clear error when called outside any provider.
50
+ */
51
+ export declare const OAuth2Context: Context<OAuth2ContextValue | null>;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * React context wiring for the OAuth2 client.
3
+ *
4
+ * Internal — consumers should reach for {@link useOAuth2} (the hook),
5
+ * {@link OAuth2Provider}, {@link RequireAuth}, and {@link OAuth2Callback}
6
+ * rather than the context object directly.
7
+ *
8
+ * @module
9
+ */
10
+ import { createContext } from "react";
11
+ /**
12
+ * Internal context — providers wire up the value, consumers read it
13
+ * through `useOAuth2()`. Default `null` so `useOAuth2()` can throw a
14
+ * clear error when called outside any provider.
15
+ */
16
+ export const OAuth2Context = createContext(null);
@@ -0,0 +1,26 @@
1
+ /**
2
+ * React adapter for `@udibo/oauth2/client`.
3
+ *
4
+ * Wraps a `BffClient` or a `DirectClient` in a React context and ships
5
+ * components / hooks for the common SPA patterns:
6
+ *
7
+ * - {@link OAuth2Provider} — install once near the app root.
8
+ * - {@link useOAuth2} — read state and bound auth helpers.
9
+ * - {@link RequireAuth} — gate a subtree behind authentication.
10
+ * - {@link OAuth2Callback} — callback route for a `DirectClient` app.
11
+ *
12
+ * The adapter is framework- and server-neutral: it works against any
13
+ * RFC 6749-compliant authorization server, and everything above is written
14
+ * against the clients' shared base, so the same components and hooks work
15
+ * whichever one the app is wired with. Reach for {@link useBffClient} or
16
+ * {@link useDirectClient} when a component needs one transport's specifics.
17
+ *
18
+ * @module
19
+ */
20
+ import "../_dnt.polyfills.js";
21
+ export { OAuth2Context, type OAuth2ContextValue, type OAuth2State, } from "./context.js";
22
+ export { OAuth2Provider, type OAuth2ProviderProps } from "./provider.js";
23
+ export { useBffClient, useDirectClient, useOAuth2, type UseOAuth2Result, } from "./use-oauth2.js";
24
+ export { useAuthorization } from "./use-authorization.js";
25
+ export { RequireAuth, type RequireAuthProps } from "./require-auth.js";
26
+ export { OAuth2Callback, type OAuth2CallbackProps } from "./callback.js";
@@ -0,0 +1,26 @@
1
+ /**
2
+ * React adapter for `@udibo/oauth2/client`.
3
+ *
4
+ * Wraps a `BffClient` or a `DirectClient` in a React context and ships
5
+ * components / hooks for the common SPA patterns:
6
+ *
7
+ * - {@link OAuth2Provider} — install once near the app root.
8
+ * - {@link useOAuth2} — read state and bound auth helpers.
9
+ * - {@link RequireAuth} — gate a subtree behind authentication.
10
+ * - {@link OAuth2Callback} — callback route for a `DirectClient` app.
11
+ *
12
+ * The adapter is framework- and server-neutral: it works against any
13
+ * RFC 6749-compliant authorization server, and everything above is written
14
+ * against the clients' shared base, so the same components and hooks work
15
+ * whichever one the app is wired with. Reach for {@link useBffClient} or
16
+ * {@link useDirectClient} when a component needs one transport's specifics.
17
+ *
18
+ * @module
19
+ */
20
+ import "../_dnt.polyfills.js";
21
+ export { OAuth2Context, } from "./context.js";
22
+ export { OAuth2Provider } from "./provider.js";
23
+ export { useBffClient, useDirectClient, useOAuth2, } from "./use-oauth2.js";
24
+ export { useAuthorization } from "./use-authorization.js";
25
+ export { RequireAuth } from "./require-auth.js";
26
+ export { OAuth2Callback } from "./callback.js";
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `<OAuth2Provider>` — wraps the app, wires an {@link OAuth2ClientBase} into
3
+ * a React context, and re-renders subscribers when the client emits
4
+ * authentication state changes.
5
+ *
6
+ * @module
7
+ */
8
+ import { type ReactNode } from "react";
9
+ import type { OAuth2ClientBase } from "../client/mod.js";
10
+ import { type OAuth2State } from "./context.js";
11
+ /** Props for {@link OAuth2Provider}. */
12
+ export interface OAuth2ProviderProps {
13
+ /**
14
+ * The OAuth2 client driving the flows — a `BffClient` or a `DirectClient`.
15
+ * Construct once per app.
16
+ */
17
+ client: OAuth2ClientBase;
18
+ /**
19
+ * Optional pre-resolved auth state (typically from a server-side
20
+ * session probe). Populating this skips the on-mount session probe
21
+ * and renders the authenticated tree on the first paint — no
22
+ * hydration flash. Pass a stable reference (don't construct it inline
23
+ * in render) so the on-mount effect doesn't re-run.
24
+ */
25
+ initialState?: Partial<OAuth2State>;
26
+ /** The app subtree that reads auth state via `useOAuth2()`. */
27
+ children: ReactNode;
28
+ }
29
+ /**
30
+ * Provider — install once near the root of your app. Children read the
31
+ * state via `useOAuth2()`.
32
+ *
33
+ * While authenticated it renews the session on a timer shortly before the
34
+ * access token expires, re-arming after each renew. Renewal is per tab and
35
+ * uncoordinated: a `DirectClient` given a refresh-token storage shared across
36
+ * tabs (e.g. `IndexedDBRefreshTokenStorage`) against a server that
37
+ * rotates refresh tokens can still have two tabs redeem the same token, which
38
+ * reuse detection may answer by ending the session everywhere.
39
+ */
40
+ export declare function OAuth2Provider(props: OAuth2ProviderProps): ReactNode;