@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,287 @@
1
+ /**
2
+ * Contract test suite for {@link TokenServiceInterface} implementations.
3
+ *
4
+ * Verifies the methods the framework actually calls during the OAuth2
5
+ * flows: token persistence, refresh-token lookup, revocation by token
6
+ * value or by authorization code, and per-(client, user) lifetime/scope
7
+ * generation.
8
+ *
9
+ * Both a token with a user and a token without one are exercised. The client
10
+ * credentials grant (RFC 6749 §4.4) has no resource owner, so the framework
11
+ * calls `acceptedScope`, `generateAccessToken`, and `accessTokenExpiresAt`
12
+ * with `user: undefined` and persists a token whose `user` is unset — a store
13
+ * that requires a user cannot hold a machine token.
14
+ *
15
+ * @module
16
+ */
17
+ import { assert, assertEquals, assertStrictEquals } from "../../deps/jsr.io/@std/assert/1.0.19/mod.js";
18
+ import { beforeEach, describe, it } from "../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
19
+ import { BasicScope } from "../../models/scope.js";
20
+ const defaultMakeUser = (seq) => ({ id: `u${seq}`, username: `user${seq}` });
21
+ const defaultMakeClient = (seq) => ({
22
+ id: `client-${seq}`,
23
+ grants: ["authorization_code", "refresh_token"],
24
+ });
25
+ const defaultMakeScope = (value) => new BasicScope(value);
26
+ /** Runs the {@link TokenServiceInterface} contract suite. */
27
+ export function runTokenServiceContractTests(options) {
28
+ const makeUser = options.makeUser ?? (defaultMakeUser);
29
+ const makeClient = options.makeClient ?? (defaultMakeClient);
30
+ const makeScope = options.makeScope ?? (defaultMakeScope);
31
+ const expectReuseDetection = options.refreshTokenReuseDetection ?? true;
32
+ describe(options.describeName ?? "TokenServiceInterface contract", () => {
33
+ let userService;
34
+ let clientService;
35
+ let tokenService;
36
+ let user;
37
+ let client;
38
+ beforeEach(async () => {
39
+ const services = await options.makeServices();
40
+ userService = services.userService;
41
+ clientService = services.clientService;
42
+ tokenService = services.tokenService;
43
+ user = makeUser(1);
44
+ client = makeClient(1);
45
+ await options.addUser(userService, user, "pw");
46
+ await options.addClient(clientService, client);
47
+ });
48
+ describe("generateAccessToken / generateRefreshToken", () => {
49
+ it("produces unique access tokens", async () => {
50
+ const a = await tokenService.generateAccessToken(client, user);
51
+ const b = await tokenService.generateAccessToken(client, user);
52
+ assertEquals(typeof a, "string");
53
+ assertEquals(typeof b, "string");
54
+ assert(a !== b, "access tokens should not collide");
55
+ });
56
+ it("produces unique refresh tokens (or undefined to opt out)", async () => {
57
+ const a = await tokenService.generateRefreshToken(client, user);
58
+ const b = await tokenService.generateRefreshToken(client, user);
59
+ if (a !== undefined && b !== undefined) {
60
+ assert(a !== b, "refresh tokens should not collide");
61
+ }
62
+ });
63
+ });
64
+ describe("acceptedScope", () => {
65
+ it("returns the requested scope unchanged for the simple case", async () => {
66
+ const requested = makeScope("read");
67
+ const result = await tokenService.acceptedScope(client, user, requested);
68
+ assertEquals(result?.toString(), "read");
69
+ });
70
+ });
71
+ describe("save + getToken", () => {
72
+ it("round-trips an access-only token", async () => {
73
+ const accessToken = await tokenService.generateAccessToken(client, user);
74
+ const expiresAt = new Date(Date.now() + 60_000);
75
+ const token = {
76
+ accessToken,
77
+ accessTokenExpiresAt: expiresAt,
78
+ client,
79
+ user,
80
+ };
81
+ await tokenService.save(token);
82
+ const fetched = await tokenService.getToken(accessToken);
83
+ assertEquals(fetched?.client.id, client.id);
84
+ assertEquals(fetched?.user?.id, user.id);
85
+ assertStrictEquals(fetched?.accessTokenExpiresAt?.getTime(), expiresAt.getTime());
86
+ });
87
+ it("returns undefined for an unknown access token", async () => {
88
+ assertStrictEquals(await tokenService.getToken("nope"), undefined);
89
+ });
90
+ });
91
+ describe("tokens with no user", () => {
92
+ it("generates an access token for a client with no user", async () => {
93
+ const accessToken = await tokenService.generateAccessToken(client, undefined);
94
+ assertEquals(typeof accessToken, "string");
95
+ });
96
+ it("accepts scope for a client with no user", async () => {
97
+ const result = await tokenService.acceptedScope(client, undefined, makeScope("read"));
98
+ assert(result !== false, "scope must not be rejected for lack of a user");
99
+ });
100
+ it("dates the expiry of an access token with no user", async () => {
101
+ const expiresAt = await tokenService.accessTokenExpiresAt(client, undefined);
102
+ if (expiresAt)
103
+ assert(expiresAt.getTime() > Date.now());
104
+ });
105
+ it("round-trips a token with no user", async () => {
106
+ const accessToken = await tokenService.generateAccessToken(client, undefined);
107
+ await tokenService.save({ accessToken, client });
108
+ const fetched = await tokenService.getToken(accessToken);
109
+ assertEquals(fetched?.client.id, client.id);
110
+ assertStrictEquals(fetched?.user, undefined);
111
+ });
112
+ it("revokes a token with no user", async () => {
113
+ const accessToken = await tokenService.generateAccessToken(client, undefined);
114
+ await tokenService.save({ accessToken, client });
115
+ assertStrictEquals(await tokenService.revoke(accessToken), true);
116
+ assertStrictEquals(await tokenService.getToken(accessToken), undefined);
117
+ });
118
+ });
119
+ describe("save + getRefreshToken", () => {
120
+ it("round-trips a refresh token", async () => {
121
+ const accessToken = await tokenService.generateAccessToken(client, user);
122
+ const refreshToken = (await tokenService.generateRefreshToken(client, user));
123
+ const token = {
124
+ accessToken,
125
+ accessTokenExpiresAt: new Date(Date.now() + 60_000),
126
+ refreshToken,
127
+ refreshTokenExpiresAt: new Date(Date.now() + 600_000),
128
+ client,
129
+ user,
130
+ };
131
+ await tokenService.save(token);
132
+ const fetched = await tokenService.getRefreshToken(refreshToken);
133
+ assertEquals(fetched?.client.id, client.id);
134
+ });
135
+ it("returns undefined for an unknown refresh token", async () => {
136
+ assertStrictEquals(await tokenService.getRefreshToken("nope"), undefined);
137
+ });
138
+ });
139
+ describe("revoke", () => {
140
+ it("revokes by token object", async () => {
141
+ const accessToken = await tokenService.generateAccessToken(client, user);
142
+ const token = {
143
+ accessToken,
144
+ client,
145
+ user,
146
+ };
147
+ await tokenService.save(token);
148
+ const ok = await tokenService.revoke(token);
149
+ assertStrictEquals(ok, true);
150
+ assertStrictEquals(await tokenService.getToken(accessToken), undefined);
151
+ });
152
+ it("revokes by access token string", async () => {
153
+ const accessToken = await tokenService.generateAccessToken(client, user);
154
+ await tokenService.save({ accessToken, client, user });
155
+ const ok = await tokenService.revoke(accessToken);
156
+ assertStrictEquals(ok, true);
157
+ assertStrictEquals(await tokenService.getToken(accessToken), undefined);
158
+ });
159
+ it("revokes by refresh token string when hint='refresh_token'", async () => {
160
+ const accessToken = await tokenService.generateAccessToken(client, user);
161
+ const refreshToken = (await tokenService.generateRefreshToken(client, user));
162
+ await tokenService.save({
163
+ accessToken,
164
+ refreshToken,
165
+ client,
166
+ user,
167
+ });
168
+ const ok = await tokenService.revoke(refreshToken, "refresh_token");
169
+ assertStrictEquals(ok, true);
170
+ assertStrictEquals(await tokenService.getRefreshToken(refreshToken), undefined);
171
+ assertStrictEquals(await tokenService.getToken(accessToken), undefined);
172
+ });
173
+ it("returns false for an unknown token string", async () => {
174
+ assertStrictEquals(await tokenService.revoke("missing"), false);
175
+ });
176
+ it("answers true only for the call that removed a live token", async () => {
177
+ const accessToken = await tokenService.generateAccessToken(client, user);
178
+ const token = { accessToken, client, user };
179
+ assertStrictEquals(await tokenService.revoke(token), false, "a token that was never saved was not revoked by this call — " +
180
+ "answering true makes a single-use check built on the result inert");
181
+ await tokenService.save(token);
182
+ assertStrictEquals(await tokenService.revoke(token), true);
183
+ assertStrictEquals(await tokenService.revoke(token), false);
184
+ });
185
+ });
186
+ describe("revokeCode", () => {
187
+ it("revokes every token issued under a given authorization code", async () => {
188
+ const code = "shared-code";
189
+ const accessToken1 = await tokenService.generateAccessToken(client, user);
190
+ const accessToken2 = await tokenService.generateAccessToken(client, user);
191
+ await tokenService.save({
192
+ accessToken: accessToken1,
193
+ code,
194
+ client,
195
+ user,
196
+ });
197
+ await tokenService.save({
198
+ accessToken: accessToken2,
199
+ code,
200
+ client,
201
+ user,
202
+ });
203
+ const ok = await tokenService.revokeCode(code);
204
+ assertStrictEquals(ok, true);
205
+ assertStrictEquals(await tokenService.getToken(accessToken1), undefined);
206
+ assertStrictEquals(await tokenService.getToken(accessToken2), undefined);
207
+ });
208
+ it("returns false when no tokens were issued for the code", async () => {
209
+ assertStrictEquals(await tokenService.revokeCode("never-used"), false);
210
+ });
211
+ });
212
+ if (expectReuseDetection) {
213
+ describe("refresh-token rotation family", () => {
214
+ const FAMILY = "family-1";
215
+ const OTHER_FAMILY = "family-2";
216
+ async function saveFamilyMember(familyId) {
217
+ const accessToken = await tokenService.generateAccessToken(client, user);
218
+ const refreshToken = (await tokenService.generateRefreshToken(client, user));
219
+ const token = {
220
+ accessToken,
221
+ accessTokenExpiresAt: new Date(Date.now() + 60_000),
222
+ refreshToken,
223
+ refreshTokenExpiresAt: new Date(Date.now() + 600_000),
224
+ familyId,
225
+ familyCreatedAt: new Date(Date.now() - 60_000),
226
+ client,
227
+ user,
228
+ };
229
+ await tokenService.save(token);
230
+ return token;
231
+ }
232
+ it("implements both halves of reuse detection", () => {
233
+ assert(typeof tokenService.getRevokedRefreshToken === "function" &&
234
+ typeof tokenService.revokeFamily === "function", "getRevokedRefreshToken and revokeFamily are optional, but " +
235
+ "without both the refresh grant cannot tell a replayed " +
236
+ "rotated-out token from an unknown one and reuse detection is " +
237
+ "silently disabled. Implement them, or pass " +
238
+ "`refreshTokenReuseDetection: false` to record the gap.");
239
+ });
240
+ it("keeps a rotated-out refresh token findable, with its family", async () => {
241
+ const token = await saveFamilyMember(FAMILY);
242
+ await tokenService.revoke(token.refreshToken, "refresh_token");
243
+ assertStrictEquals(await tokenService.getRefreshToken(token.refreshToken), undefined, "a rotated-out token must no longer refresh");
244
+ const revoked = await tokenService.getRevokedRefreshToken(token.refreshToken);
245
+ assert(revoked !== undefined, "a revoked refresh token must stay findable — deleting the row " +
246
+ "is what turns a replay into an ordinary unknown token");
247
+ assertStrictEquals(revoked.familyId, FAMILY);
248
+ });
249
+ it("does not report a live refresh token as revoked", async () => {
250
+ const token = await saveFamilyMember(FAMILY);
251
+ assertStrictEquals(await tokenService.getRevokedRefreshToken(token.refreshToken), undefined, "reporting a live token as revoked turns every legitimate " +
252
+ "refresh into a detected replay");
253
+ });
254
+ it("returns undefined for a refresh token that was never issued", async () => {
255
+ assertStrictEquals(await tokenService.getRevokedRefreshToken("never-issued"), undefined);
256
+ });
257
+ it("revokes every live member of a replayed token's family", async () => {
258
+ const first = await saveFamilyMember(FAMILY);
259
+ const second = await saveFamilyMember(FAMILY);
260
+ assertStrictEquals(await tokenService.revokeFamily(FAMILY), true);
261
+ assertStrictEquals(await tokenService.getRefreshToken(first.refreshToken), undefined);
262
+ assertStrictEquals(await tokenService.getRefreshToken(second.refreshToken), undefined);
263
+ assertStrictEquals(await tokenService.getToken(second.accessToken), undefined, "the family's access tokens die with it — leaving them live " +
264
+ "keeps the thief's session alive for their remaining lifetime");
265
+ });
266
+ it("leaves other families untouched", async () => {
267
+ const mine = await saveFamilyMember(FAMILY);
268
+ const theirs = await saveFamilyMember(OTHER_FAMILY);
269
+ await tokenService.revokeFamily(FAMILY);
270
+ assertStrictEquals(await tokenService.getRefreshToken(mine.refreshToken), undefined);
271
+ assert(await tokenService.getRefreshToken(theirs.refreshToken) !==
272
+ undefined, "one compromised family must not sign every other session out");
273
+ });
274
+ it("returns false when the family has no live tokens", async () => {
275
+ assertStrictEquals(await tokenService.revokeFamily("never-issued"), false);
276
+ });
277
+ });
278
+ }
279
+ else {
280
+ it({
281
+ name: "refresh-token reuse detection is not implemented — a replayed rotated-out token cannot be detected (refreshTokenReuseDetection: false)",
282
+ ignore: true,
283
+ fn: () => { },
284
+ });
285
+ }
286
+ });
287
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Contract test suite for {@link UserServiceInterface} implementations.
3
+ *
4
+ * Apps that swap a `MemoryUserService` for a DB-backed implementation
5
+ * can run this suite against their factory to verify they satisfy what
6
+ * the framework expects.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { runUserServiceContractTests } from "@udibo/oauth2/testing/contract";
11
+ * import type { UserServiceInterface } from "@udibo/oauth2/server/authorization";
12
+ *
13
+ * interface AppUser {
14
+ * id: string;
15
+ * username: string;
16
+ * }
17
+ * interface DrizzleUserService extends UserServiceInterface<AppUser> {
18
+ * register(user: AppUser, password: string): Promise<void>;
19
+ * }
20
+ * declare function freshUserService(): Promise<DrizzleUserService>;
21
+ *
22
+ * runUserServiceContractTests<AppUser>({
23
+ * makeService: freshUserService,
24
+ * addUser: (svc, user, password) =>
25
+ * (svc as DrizzleUserService).register(user, password),
26
+ * });
27
+ * ```
28
+ *
29
+ * @module
30
+ */
31
+ import type { UserServiceInterface } from "../../server/services/user.js";
32
+ import type { MemoryUserShape } from "../services.js";
33
+ /** Options for {@link runUserServiceContractTests}. */
34
+ export interface UserServiceContractOptions<U extends MemoryUserShape> {
35
+ /**
36
+ * Returns a fresh service for each test. Must be isolated — one test
37
+ * leaking state into another defeats the contract guarantees.
38
+ */
39
+ makeService(): Promise<UserServiceInterface<U>> | UserServiceInterface<U>;
40
+ /**
41
+ * Adds a user with the given password to the service. Not part of the
42
+ * interface, so the consumer supplies it. For the framework's own
43
+ * `MemoryUserService` this is `(svc, user, pw) => svc.add(user, pw)`.
44
+ */
45
+ addUser(service: UserServiceInterface<U>, user: U, password: string): Promise<void>;
46
+ /**
47
+ * Optional factory for the test user. Defaults to a sequenced
48
+ * `{ id, username }` shape that satisfies {@link MemoryUserShape}.
49
+ * Override when your `User` requires extra fields.
50
+ */
51
+ makeUser?(seq: number): U;
52
+ /**
53
+ * Optional name for the inner `describe` block. Defaults to
54
+ * `"UserServiceInterface contract"`.
55
+ */
56
+ describeName?: string;
57
+ }
58
+ /**
59
+ * Runs the {@link UserServiceInterface} contract suite. Call from your
60
+ * own test file — the suite registers `describe` / `it` blocks that the
61
+ * runner picks up.
62
+ */
63
+ export declare function runUserServiceContractTests<U extends MemoryUserShape>(options: UserServiceContractOptions<U>): void;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Contract test suite for {@link UserServiceInterface} implementations.
3
+ *
4
+ * Apps that swap a `MemoryUserService` for a DB-backed implementation
5
+ * can run this suite against their factory to verify they satisfy what
6
+ * the framework expects.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { runUserServiceContractTests } from "@udibo/oauth2/testing/contract";
11
+ * import type { UserServiceInterface } from "@udibo/oauth2/server/authorization";
12
+ *
13
+ * interface AppUser {
14
+ * id: string;
15
+ * username: string;
16
+ * }
17
+ * interface DrizzleUserService extends UserServiceInterface<AppUser> {
18
+ * register(user: AppUser, password: string): Promise<void>;
19
+ * }
20
+ * declare function freshUserService(): Promise<DrizzleUserService>;
21
+ *
22
+ * runUserServiceContractTests<AppUser>({
23
+ * makeService: freshUserService,
24
+ * addUser: (svc, user, password) =>
25
+ * (svc as DrizzleUserService).register(user, password),
26
+ * });
27
+ * ```
28
+ *
29
+ * @module
30
+ */
31
+ import { assertEquals, assertStrictEquals } from "../../deps/jsr.io/@std/assert/1.0.19/mod.js";
32
+ import { beforeEach, describe, it } from "../../deps/jsr.io/@std/testing/1.0.20/bdd.js";
33
+ const defaultMakeUser = (seq) => ({ id: `u${seq}`, username: `user${seq}` });
34
+ /**
35
+ * Runs the {@link UserServiceInterface} contract suite. Call from your
36
+ * own test file — the suite registers `describe` / `it` blocks that the
37
+ * runner picks up.
38
+ */
39
+ export function runUserServiceContractTests(options) {
40
+ const makeUser = options.makeUser ?? (defaultMakeUser);
41
+ describe(options.describeName ?? "UserServiceInterface contract", () => {
42
+ let service;
43
+ beforeEach(async () => {
44
+ service = await options.makeService();
45
+ });
46
+ describe("get", () => {
47
+ it("returns undefined for an unknown id", async () => {
48
+ assertStrictEquals(await service.get("does-not-exist"), undefined);
49
+ });
50
+ it("returns the user for a known id", async () => {
51
+ const user = makeUser(1);
52
+ await options.addUser(service, user, "pw");
53
+ const fetched = await service.get(user.id);
54
+ assertEquals(fetched?.id, user.id);
55
+ assertEquals(fetched?.username, user.username);
56
+ });
57
+ });
58
+ describe("getAuthenticated", () => {
59
+ it("returns undefined for an unknown username", async () => {
60
+ assertStrictEquals(await service.getAuthenticated("nobody", "pw"), undefined);
61
+ });
62
+ it("returns undefined for a wrong password", async () => {
63
+ const user = makeUser(2);
64
+ await options.addUser(service, user, "correct");
65
+ assertStrictEquals(await service.getAuthenticated(user.username, "wrong"), undefined);
66
+ });
67
+ it("returns the user when username + password match", async () => {
68
+ const user = makeUser(3);
69
+ await options.addUser(service, user, "secret");
70
+ const auth = await service.getAuthenticated(user.username, "secret");
71
+ assertEquals(auth?.id, user.id);
72
+ });
73
+ });
74
+ });
75
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Testing helpers for apps that use `@udibo/oauth2`.
3
+ *
4
+ * Two layers ship:
5
+ *
6
+ * - **Testing surface for the OAuth2 protocol.** The recommended pattern
7
+ * for testing apps that use the resource server is to expose your
8
+ * `IntrospectionTokenReader` instance from your app's OAuth2 wiring module
9
+ * and stub `tokenReader.getToken` directly with `@std/testing/mock`'s
10
+ * `stub` —
11
+ * one method on one object, no `fetch` indirection, no wire format to
12
+ * fake. For tests that need the OAuth2 protocol end-to-end (BFF flows,
13
+ * SPA integration), build a real in-process authorization server with
14
+ * {@link createMemoryAuthorizationServer} and pass its `fetch` to your
15
+ * `DirectClient` via the constructor's `fetch` option. Both patterns
16
+ * are constructor- or method-scoped — they never touch
17
+ * `globalThis.fetch`, which silently captures every other outbound
18
+ * request the app makes.
19
+ *
20
+ * - **In-memory service implementations.** `MemoryUserService`,
21
+ * `MemoryClientService`, `MemoryTokenService`,
22
+ * `MemoryAuthorizationCodeService`, and `MemoryDeviceAuthorizationService`
23
+ * satisfy every server-side service contract, generic over the consumer's
24
+ * user / client / scope types. Suitable for tests, examples, and
25
+ * prototypes — never for production.
26
+ *
27
+ * Nothing in this module is an OAuth2 primitive — only testing support.
28
+ * Production code should never import from here.
29
+ *
30
+ * @module
31
+ */
32
+ import "../_dnt.polyfills.js";
33
+ export { MemoryAuthorizationCodeService, type MemoryAuthorizationCodeServiceOptions, MemoryClientService, MemoryDeviceAuthorizationService, type MemoryDeviceAuthorizationServiceOptions, MemoryTokenService, type MemoryTokenServiceOptions, MemoryUserService, type MemoryUserServiceOptions, type MemoryUserShape, } from "./services.js";
34
+ export { createMemoryAuthorizationServer, type CreateMemoryAuthorizationServerOptions, type MemoryAuthorizationServerClientSeed, type MemoryAuthorizationServerGrants, type MemoryAuthorizationServerHarness, type MemoryAuthorizationServerUserSeed, } from "./server.js";
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Testing helpers for apps that use `@udibo/oauth2`.
3
+ *
4
+ * Two layers ship:
5
+ *
6
+ * - **Testing surface for the OAuth2 protocol.** The recommended pattern
7
+ * for testing apps that use the resource server is to expose your
8
+ * `IntrospectionTokenReader` instance from your app's OAuth2 wiring module
9
+ * and stub `tokenReader.getToken` directly with `@std/testing/mock`'s
10
+ * `stub` —
11
+ * one method on one object, no `fetch` indirection, no wire format to
12
+ * fake. For tests that need the OAuth2 protocol end-to-end (BFF flows,
13
+ * SPA integration), build a real in-process authorization server with
14
+ * {@link createMemoryAuthorizationServer} and pass its `fetch` to your
15
+ * `DirectClient` via the constructor's `fetch` option. Both patterns
16
+ * are constructor- or method-scoped — they never touch
17
+ * `globalThis.fetch`, which silently captures every other outbound
18
+ * request the app makes.
19
+ *
20
+ * - **In-memory service implementations.** `MemoryUserService`,
21
+ * `MemoryClientService`, `MemoryTokenService`,
22
+ * `MemoryAuthorizationCodeService`, and `MemoryDeviceAuthorizationService`
23
+ * satisfy every server-side service contract, generic over the consumer's
24
+ * user / client / scope types. Suitable for tests, examples, and
25
+ * prototypes — never for production.
26
+ *
27
+ * Nothing in this module is an OAuth2 primitive — only testing support.
28
+ * Production code should never import from here.
29
+ *
30
+ * @module
31
+ */
32
+ import "../_dnt.polyfills.js";
33
+ export { MemoryAuthorizationCodeService, MemoryClientService, MemoryDeviceAuthorizationService, MemoryTokenService, MemoryUserService, } from "./services.js";
34
+ export { createMemoryAuthorizationServer, } from "./server.js";