@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,203 @@
1
+ /**
2
+ * OAuth2 error classes following RFC 6749.
3
+ *
4
+ * These error classes map to the OAuth2 error codes defined in:
5
+ * - RFC 6749 Section 4.1.2.1 (Authorization errors)
6
+ * - RFC 6749 Section 5.2 (Token errors)
7
+ * - RFC 6750 Section 3.1 (Bearer token errors)
8
+ * - RFC 8628 Section 3.5 (Device flow errors)
9
+ *
10
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
11
+ * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
12
+ * @module
13
+ */
14
+ import { HttpError, type HttpErrorOptions } from "./deps/jsr.io/@udibo/http-error/0.11.1/mod.js";
15
+ /**
16
+ * Problem Details extension members carried by every {@linkcode OAuth2Error}.
17
+ *
18
+ * These map the standard OAuth2 error response fields (RFC 6749 Section 5.2)
19
+ * onto the error's `extensions` bag so they can be serialized in either the
20
+ * OAuth2 error format or the RFC 9457 Problem Details format.
21
+ */
22
+ export interface OAuth2ProblemDetailsExtensions {
23
+ /** An ASCII error code. */
24
+ error?: string;
25
+ /** Human-readable error description. */
26
+ error_description?: string;
27
+ /** A URI identifying a human readable web page with information about the error. */
28
+ error_uri?: string;
29
+ }
30
+ /**
31
+ * Constructor type for OAuth2 error classes produced by
32
+ * `createHttpErrorClass`. Declared explicitly so the exported error classes
33
+ * have a JSR-fast public type (the inferred type spans multiple constructor
34
+ * overloads and trips the `no-slow-types` rule).
35
+ */
36
+ export type OAuth2ErrorClass<Extensions extends OAuth2ProblemDetailsExtensions = OAuth2ProblemDetailsExtensions> = {
37
+ new <E extends Extensions = Extensions>(status?: number, message?: string, options?: HttpErrorOptions<E>): HttpError<E>;
38
+ new <E extends Extensions = Extensions>(status?: number, options?: HttpErrorOptions<E>): HttpError<E>;
39
+ new <E extends Extensions = Extensions>(message?: string, options?: HttpErrorOptions<E>): HttpError<E>;
40
+ new <E extends Extensions = Extensions>(options?: HttpErrorOptions<E>): HttpError<E>;
41
+ prototype: HttpError<Extensions>;
42
+ };
43
+ /**
44
+ * An OAuth2 error: an {@linkcode HttpError} whose `extensions` carry the
45
+ * OAuth2 error fields described by {@linkcode OAuth2ProblemDetailsExtensions}.
46
+ * This is the common type for every error class in this module.
47
+ */
48
+ export type OAuth2Error = HttpError<OAuth2ProblemDetailsExtensions>;
49
+ /**
50
+ * The base OAuth2 error class, an {@linkcode HttpError} subclass that defaults
51
+ * to the `server_error` code. Used as a catch-all and as the value-side
52
+ * companion of the {@linkcode OAuth2Error} type; prefer a specific subclass
53
+ * (e.g. {@linkcode InvalidRequestError}) when the condition is known.
54
+ */
55
+ export declare const OAuth2Error: OAuth2ErrorClass;
56
+ /** Type guard for OAuth2 errors. */
57
+ export declare function isOAuth2Error(value: unknown): value is OAuth2Error;
58
+ /**
59
+ * Converts an arbitrary error into an {@link OAuth2Error}.
60
+ *
61
+ * If the input is already an OAuth2Error it is returned as-is; otherwise it is
62
+ * wrapped in a {@link ServerError} with the original error attached as `cause`.
63
+ *
64
+ * The returned error also has its `type` and `extensions.error_uri` synced so
65
+ * that if one is set the other is too. This lets both the standard OAuth2
66
+ * error format (which emits `error_uri`) and the RFC 9457 Problem Details
67
+ * format (which emits `type`) carry the same URI without the handler having to
68
+ * set both fields.
69
+ */
70
+ export declare function toOAuth2Error(error: unknown): OAuth2Error;
71
+ /**
72
+ * The request is missing a required parameter, includes an unsupported parameter value,
73
+ * repeats a parameter, includes multiple credentials, utilizes more than one mechanism
74
+ * for authenticating the client, or is otherwise malformed.
75
+ *
76
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
77
+ */
78
+ export declare const InvalidRequestError: OAuth2ErrorClass;
79
+ /**
80
+ * Client authentication failed.
81
+ *
82
+ * The authorization server MAY return an HTTP 401 (Unauthorized) status code
83
+ * to indicate which HTTP authentication schemes are supported.
84
+ *
85
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
86
+ */
87
+ export declare const InvalidClientError: OAuth2ErrorClass;
88
+ /**
89
+ * The provided authorization grant or refresh token is invalid, expired, revoked,
90
+ * does not match the redirection URI used in the authorization request, or was issued to another client.
91
+ *
92
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
93
+ */
94
+ export declare const InvalidGrantError: OAuth2ErrorClass;
95
+ /**
96
+ * The authenticated client is not authorized to use this authorization grant type.
97
+ *
98
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
99
+ */
100
+ export declare const UnauthorizedClientError: OAuth2ErrorClass;
101
+ /**
102
+ * The token type is not supported by the authorization server.
103
+ *
104
+ * Used by the revocation endpoint (RFC 7009) when the server doesn't
105
+ * support revoking the presented token type.
106
+ *
107
+ * @see https://datatracker.ietf.org/doc/html/rfc7009#section-2.2.1
108
+ */
109
+ export declare const UnsupportedTokenTypeError: OAuth2ErrorClass;
110
+ /**
111
+ * The authorization grant type is not supported by the authorization server.
112
+ *
113
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
114
+ */
115
+ export declare const UnsupportedGrantTypeError: OAuth2ErrorClass;
116
+ /**
117
+ * The resource owner or authorization server denied the request.
118
+ *
119
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
120
+ */
121
+ export declare const AccessDeniedError: OAuth2ErrorClass;
122
+ /**
123
+ * The access token provided is expired, revoked, malformed, or invalid.
124
+ *
125
+ * Per RFC 6750, this error uses HTTP 401 status and should trigger
126
+ * a WWW-Authenticate header with the "invalid_token" error code.
127
+ *
128
+ * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
129
+ */
130
+ export declare const InvalidTokenError: OAuth2ErrorClass;
131
+ /**
132
+ * The request requires higher privileges than provided by the access token.
133
+ *
134
+ * Per RFC 6750, this error uses HTTP 403 status and should trigger
135
+ * a WWW-Authenticate header with the "insufficient_scope" error code
136
+ * and optionally a "requiredScope" extension indicating required scope.
137
+ *
138
+ * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
139
+ */
140
+ export declare const InsufficientScopeError: OAuth2ErrorClass<OAuth2ProblemDetailsExtensions & {
141
+ requiredScope?: string;
142
+ }>;
143
+ /**
144
+ * The request requires an authorization the subject does not hold — a
145
+ * permission, role, or organization context check failed on an otherwise
146
+ * valid token. HTTP 403 with a bare `realm` challenge: RFC 6750 registers no
147
+ * challenge code for this, so unlike {@link InsufficientScopeError} the
148
+ * `WWW-Authenticate` header names no error — the body carries
149
+ * `insufficient_permissions`.
150
+ */
151
+ export declare const InsufficientPermissionsError: OAuth2ErrorClass;
152
+ /**
153
+ * The authorization server does not support obtaining an authorization code using this method.
154
+ *
155
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
156
+ */
157
+ export declare const UnsupportedResponseTypeError: OAuth2ErrorClass;
158
+ /**
159
+ * The requested scope is invalid, unknown, or malformed.
160
+ *
161
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
162
+ */
163
+ export declare const InvalidScopeError: OAuth2ErrorClass;
164
+ /**
165
+ * The authorization server encountered an unexpected condition that prevented it from fulfilling the request.
166
+ *
167
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
168
+ */
169
+ export declare const ServerError: OAuth2ErrorClass;
170
+ /**
171
+ * The authorization server is currently unable to handle the request due to a temporary overloading or maintenance.
172
+ *
173
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
174
+ */
175
+ export declare const TemporarilyUnavailableError: OAuth2ErrorClass;
176
+ /**
177
+ * The authorization request is still pending user approval.
178
+ *
179
+ * Used in the device authorization flow (RFC 8628) when the user
180
+ * has not yet authorized the request.
181
+ *
182
+ * @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
183
+ */
184
+ export declare const AuthorizationPendingError: OAuth2ErrorClass;
185
+ /**
186
+ * The client is polling too frequently.
187
+ *
188
+ * Used in the device authorization flow (RFC 8628) when the client
189
+ * polls faster than the allowed interval. The client should increase
190
+ * its polling interval by 5 seconds.
191
+ *
192
+ * @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
193
+ */
194
+ export declare const SlowDownError: OAuth2ErrorClass;
195
+ /**
196
+ * The device_code has expired.
197
+ *
198
+ * Used in the device authorization flow (RFC 8628) when the
199
+ * device code expires before the user authorizes the request.
200
+ *
201
+ * @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
202
+ */
203
+ export declare const ExpiredTokenError: OAuth2ErrorClass;
package/esm/errors.js ADDED
@@ -0,0 +1,287 @@
1
+ /**
2
+ * OAuth2 error classes following RFC 6749.
3
+ *
4
+ * These error classes map to the OAuth2 error codes defined in:
5
+ * - RFC 6749 Section 4.1.2.1 (Authorization errors)
6
+ * - RFC 6749 Section 5.2 (Token errors)
7
+ * - RFC 6750 Section 3.1 (Bearer token errors)
8
+ * - RFC 8628 Section 3.5 (Device flow errors)
9
+ *
10
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
11
+ * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
12
+ * @module
13
+ */
14
+ import { createHttpErrorClass, HttpError, } from "./deps/jsr.io/@udibo/http-error/0.11.1/mod.js";
15
+ /**
16
+ * The base OAuth2 error class, an {@linkcode HttpError} subclass that defaults
17
+ * to the `server_error` code. Used as a catch-all and as the value-side
18
+ * companion of the {@linkcode OAuth2Error} type; prefer a specific subclass
19
+ * (e.g. {@linkcode InvalidRequestError}) when the condition is known.
20
+ */
21
+ export const OAuth2Error = createHttpErrorClass({
22
+ name: "OAuth2 Error",
23
+ extensions: {
24
+ error: "server_error",
25
+ },
26
+ });
27
+ /** Type guard for OAuth2 errors. */
28
+ export function isOAuth2Error(value) {
29
+ return value instanceof HttpError && value.extensions.error !== undefined;
30
+ }
31
+ /**
32
+ * Converts an arbitrary error into an {@link OAuth2Error}.
33
+ *
34
+ * If the input is already an OAuth2Error it is returned as-is; otherwise it is
35
+ * wrapped in a {@link ServerError} with the original error attached as `cause`.
36
+ *
37
+ * The returned error also has its `type` and `extensions.error_uri` synced so
38
+ * that if one is set the other is too. This lets both the standard OAuth2
39
+ * error format (which emits `error_uri`) and the RFC 9457 Problem Details
40
+ * format (which emits `type`) carry the same URI without the handler having to
41
+ * set both fields.
42
+ */
43
+ export function toOAuth2Error(error) {
44
+ const oauth2Error = isOAuth2Error(error)
45
+ ? error
46
+ : new ServerError("unexpected error", { cause: error });
47
+ if (oauth2Error.type && !oauth2Error.extensions.error_uri) {
48
+ oauth2Error.extensions.error_uri = oauth2Error.type;
49
+ }
50
+ else if (oauth2Error.extensions.error_uri && !oauth2Error.type) {
51
+ oauth2Error.type = oauth2Error.extensions.error_uri;
52
+ }
53
+ return oauth2Error;
54
+ }
55
+ /**
56
+ * The request is missing a required parameter, includes an unsupported parameter value,
57
+ * repeats a parameter, includes multiple credentials, utilizes more than one mechanism
58
+ * for authenticating the client, or is otherwise malformed.
59
+ *
60
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
61
+ */
62
+ export const InvalidRequestError = createHttpErrorClass({
63
+ name: "Invalid Request",
64
+ status: 400,
65
+ extensions: {
66
+ error: "invalid_request",
67
+ },
68
+ });
69
+ /**
70
+ * Client authentication failed.
71
+ *
72
+ * The authorization server MAY return an HTTP 401 (Unauthorized) status code
73
+ * to indicate which HTTP authentication schemes are supported.
74
+ *
75
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
76
+ */
77
+ export const InvalidClientError = createHttpErrorClass({
78
+ name: "Invalid Client",
79
+ status: 401,
80
+ extensions: {
81
+ error: "invalid_client",
82
+ },
83
+ });
84
+ /**
85
+ * The provided authorization grant or refresh token is invalid, expired, revoked,
86
+ * does not match the redirection URI used in the authorization request, or was issued to another client.
87
+ *
88
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
89
+ */
90
+ export const InvalidGrantError = createHttpErrorClass({
91
+ name: "Invalid Grant",
92
+ status: 400,
93
+ extensions: {
94
+ error: "invalid_grant",
95
+ },
96
+ });
97
+ /**
98
+ * The authenticated client is not authorized to use this authorization grant type.
99
+ *
100
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
101
+ */
102
+ export const UnauthorizedClientError = createHttpErrorClass({
103
+ name: "Unauthorized Client",
104
+ status: 401,
105
+ extensions: {
106
+ error: "unauthorized_client",
107
+ },
108
+ });
109
+ /**
110
+ * The token type is not supported by the authorization server.
111
+ *
112
+ * Used by the revocation endpoint (RFC 7009) when the server doesn't
113
+ * support revoking the presented token type.
114
+ *
115
+ * @see https://datatracker.ietf.org/doc/html/rfc7009#section-2.2.1
116
+ */
117
+ export const UnsupportedTokenTypeError = createHttpErrorClass({
118
+ name: "Unsupported Token Type",
119
+ status: 400,
120
+ extensions: {
121
+ error: "unsupported_token_type",
122
+ },
123
+ });
124
+ /**
125
+ * The authorization grant type is not supported by the authorization server.
126
+ *
127
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
128
+ */
129
+ export const UnsupportedGrantTypeError = createHttpErrorClass({
130
+ name: "Unsupported Grant Type",
131
+ status: 400,
132
+ extensions: {
133
+ error: "unsupported_grant_type",
134
+ },
135
+ });
136
+ /**
137
+ * The resource owner or authorization server denied the request.
138
+ *
139
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
140
+ */
141
+ export const AccessDeniedError = createHttpErrorClass({
142
+ name: "Access Denied",
143
+ status: 401,
144
+ extensions: {
145
+ error: "access_denied",
146
+ },
147
+ });
148
+ /**
149
+ * The access token provided is expired, revoked, malformed, or invalid.
150
+ *
151
+ * Per RFC 6750, this error uses HTTP 401 status and should trigger
152
+ * a WWW-Authenticate header with the "invalid_token" error code.
153
+ *
154
+ * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
155
+ */
156
+ export const InvalidTokenError = createHttpErrorClass({
157
+ name: "Invalid Token",
158
+ status: 401,
159
+ extensions: {
160
+ error: "invalid_token",
161
+ },
162
+ });
163
+ /**
164
+ * The request requires higher privileges than provided by the access token.
165
+ *
166
+ * Per RFC 6750, this error uses HTTP 403 status and should trigger
167
+ * a WWW-Authenticate header with the "insufficient_scope" error code
168
+ * and optionally a "requiredScope" extension indicating required scope.
169
+ *
170
+ * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
171
+ */
172
+ export const InsufficientScopeError = createHttpErrorClass({
173
+ name: "Insufficient Scope",
174
+ status: 403,
175
+ extensions: {
176
+ error: "insufficient_scope",
177
+ },
178
+ });
179
+ /**
180
+ * The request requires an authorization the subject does not hold — a
181
+ * permission, role, or organization context check failed on an otherwise
182
+ * valid token. HTTP 403 with a bare `realm` challenge: RFC 6750 registers no
183
+ * challenge code for this, so unlike {@link InsufficientScopeError} the
184
+ * `WWW-Authenticate` header names no error — the body carries
185
+ * `insufficient_permissions`.
186
+ */
187
+ export const InsufficientPermissionsError = createHttpErrorClass({
188
+ name: "Insufficient Permissions",
189
+ status: 403,
190
+ extensions: {
191
+ error: "insufficient_permissions",
192
+ },
193
+ });
194
+ /**
195
+ * The authorization server does not support obtaining an authorization code using this method.
196
+ *
197
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
198
+ */
199
+ export const UnsupportedResponseTypeError = createHttpErrorClass({
200
+ name: "Unsupported Response Type",
201
+ status: 400,
202
+ extensions: {
203
+ error: "unsupported_response_type",
204
+ },
205
+ });
206
+ /**
207
+ * The requested scope is invalid, unknown, or malformed.
208
+ *
209
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
210
+ */
211
+ export const InvalidScopeError = createHttpErrorClass({
212
+ name: "Invalid Scope",
213
+ status: 400,
214
+ extensions: {
215
+ error: "invalid_scope",
216
+ },
217
+ });
218
+ /**
219
+ * The authorization server encountered an unexpected condition that prevented it from fulfilling the request.
220
+ *
221
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
222
+ */
223
+ export const ServerError = createHttpErrorClass({
224
+ name: "Server Error",
225
+ status: 500,
226
+ extensions: {
227
+ error: "server_error",
228
+ },
229
+ });
230
+ /**
231
+ * The authorization server is currently unable to handle the request due to a temporary overloading or maintenance.
232
+ *
233
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
234
+ */
235
+ export const TemporarilyUnavailableError = createHttpErrorClass({
236
+ name: "Temporarily Unavailable",
237
+ status: 503,
238
+ extensions: {
239
+ error: "temporarily_unavailable",
240
+ },
241
+ });
242
+ /**
243
+ * The authorization request is still pending user approval.
244
+ *
245
+ * Used in the device authorization flow (RFC 8628) when the user
246
+ * has not yet authorized the request.
247
+ *
248
+ * @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
249
+ */
250
+ export const AuthorizationPendingError = createHttpErrorClass({
251
+ name: "Authorization Pending",
252
+ status: 400,
253
+ extensions: {
254
+ error: "authorization_pending",
255
+ },
256
+ });
257
+ /**
258
+ * The client is polling too frequently.
259
+ *
260
+ * Used in the device authorization flow (RFC 8628) when the client
261
+ * polls faster than the allowed interval. The client should increase
262
+ * its polling interval by 5 seconds.
263
+ *
264
+ * @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
265
+ */
266
+ export const SlowDownError = createHttpErrorClass({
267
+ name: "Slow Down",
268
+ status: 400,
269
+ extensions: {
270
+ error: "slow_down",
271
+ },
272
+ });
273
+ /**
274
+ * The device_code has expired.
275
+ *
276
+ * Used in the device authorization flow (RFC 8628) when the
277
+ * device code expires before the user authorizes the request.
278
+ *
279
+ * @see https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
280
+ */
281
+ export const ExpiredTokenError = createHttpErrorClass({
282
+ name: "Expired Token",
283
+ status: 400,
284
+ extensions: {
285
+ error: "expired_token",
286
+ },
287
+ });
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Bring-your-own bot-challenge verification for auth endpoints — the CAPTCHA
3
+ * analogue of the {@link RateLimiterLike} seam. {@link CaptchaProvider} is the
4
+ * contract a client-issued challenge token is verified against server-side;
5
+ * Cloudflare Turnstile, hCaptcha, and reCAPTCHA all satisfy it, so nothing here
6
+ * depends on a vendor SDK. {@link verifyCaptcha} composes a provider with the
7
+ * fail-open/closed discipline a login flow needs: a missing or rejected token
8
+ * is a refusal, but a provider *outage* degrades to your existing rate-limit and
9
+ * lockout floor rather than locking everyone out.
10
+ *
11
+ * Tenant-agnostic: scope by passing whatever `action` and `ip` your provider
12
+ * scores on. **No provider means no challenge** — {@link verifyCaptcha} passes
13
+ * every request, so wiring the seam without configuring a provider changes
14
+ * nothing about existing behavior.
15
+ *
16
+ * @module
17
+ */
18
+ /** What a {@link CaptchaProvider} is told about the request it is scoring. */
19
+ export interface CaptchaVerifyContext {
20
+ /**
21
+ * The caller's IP, for providers that fold network reputation into the score
22
+ * (Turnstile's `remoteip`, reCAPTCHA's `remoteip`). Omit when unknown.
23
+ */
24
+ ip?: string;
25
+ /**
26
+ * The flow the token was issued for (`"signup"`, `"signin"`, …). Providers
27
+ * that bind a token to an action (reCAPTCHA v3, Turnstile `action`) verify it
28
+ * against this; providers that don't may ignore it.
29
+ */
30
+ action?: string;
31
+ }
32
+ /** The outcome of a {@link CaptchaProvider.verify}. */
33
+ export interface CaptchaVerifyResult {
34
+ /**
35
+ * Whether the token is a valid, unspent solution to a real challenge. `false`
36
+ * is a genuine rejection (forged, replayed, or expired token) — the caller
37
+ * refuses the request. Reserve *throwing* for the provider being unreachable
38
+ * so {@link verifyCaptcha} can tell a rejection apart from an outage.
39
+ */
40
+ success: boolean;
41
+ /**
42
+ * The provider's confidence in `[0, 1]` when it scores (reCAPTCHA v3,
43
+ * Turnstile enterprise), higher meaning more likely human. Omit for
44
+ * pass/fail providers. Surfaced for score-threshold tuning; {@link
45
+ * verifyCaptcha} decides purely on `success`.
46
+ */
47
+ score?: number;
48
+ }
49
+ /**
50
+ * The seam a bot-challenge vendor plugs into: verify one client-issued token
51
+ * server-side and report pass/fail. The package ships **no** provider — bring
52
+ * your own: implement this against your provider's siteverify endpoint (a
53
+ * single HTTPS POST, as in the example below — Turnstile, hCaptcha, and
54
+ * reCAPTCHA all take that shape) or against an enterprise bot-detection service
55
+ * you already run. Wire the result through {@link verifyCaptcha} for the
56
+ * fail-open/closed handling, and reject a `"fail"` decision with
57
+ * `IdentityError` `captcha_failed`.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const provider: CaptchaProvider = {
62
+ * async verify(token, context) {
63
+ * const body = new URLSearchParams({ secret, response: token });
64
+ * if (context?.ip) body.set("remoteip", context.ip);
65
+ * const res = await fetch(SITEVERIFY, { method: "POST", body });
66
+ * if (!res.ok) throw new Error(`siteverify ${res.status}`); // outage
67
+ * const data = await res.json() as { success: boolean };
68
+ * return { success: data.success };
69
+ * },
70
+ * };
71
+ * ```
72
+ */
73
+ export interface CaptchaProvider {
74
+ /**
75
+ * Verify `token` server-side. Resolve `{ success: false }` for a genuine
76
+ * rejection; **throw** when the provider cannot be reached (network error,
77
+ * non-2xx) so an outage is distinguishable from a rejection.
78
+ */
79
+ verify(token: string, context?: CaptchaVerifyContext): Promise<CaptchaVerifyResult>;
80
+ }
81
+ /** The decision {@link verifyCaptcha} returns. */
82
+ export interface CaptchaOutcome {
83
+ /** `"pass"` lets the flow proceed; `"fail"` is a refusal. */
84
+ decision: "pass" | "fail";
85
+ /**
86
+ * Whether a provider actually evaluated a token. `false` means no provider
87
+ * was configured (the request passes unchallenged) — distinct from a `"pass"`
88
+ * a provider granted.
89
+ */
90
+ challenged: boolean;
91
+ /** The provider's {@link CaptchaVerifyResult.score}, when it returned one. */
92
+ score?: number;
93
+ /**
94
+ * Whether the provider could not be reached, so this outcome came from the
95
+ * `failOpen` policy rather than a real evaluation — `true` on both the
96
+ * fail-open `"pass"` and the fail-closed `"fail"`. Audit it: a degraded pass
97
+ * is the window where only your rate-limit/lockout floor is protecting the
98
+ * endpoint, and a run of degraded fails is an outage locking users out.
99
+ */
100
+ degraded: boolean;
101
+ }
102
+ /** Options for {@link verifyCaptcha}. */
103
+ export interface VerifyCaptchaOptions {
104
+ /**
105
+ * The provider to verify against. `undefined` disables the challenge
106
+ * entirely — {@link verifyCaptcha} returns an unchallenged `"pass"`.
107
+ */
108
+ provider: CaptchaProvider | undefined;
109
+ /**
110
+ * The client-issued token from the request. A missing/empty token with a
111
+ * provider configured is a `"fail"` (the challenge was required and not
112
+ * answered).
113
+ */
114
+ token: string | null | undefined;
115
+ /** Passed through to {@link CaptchaProvider.verify}. */
116
+ context?: CaptchaVerifyContext;
117
+ /**
118
+ * What to do when the provider throws (an outage). `true` (the default)
119
+ * fails open — the request passes with `degraded: true` — so a provider
120
+ * outage falls back to your rate-limit/lockout floor instead of blocking
121
+ * every user. `false` fails closed for a tenant that would rather refuse than
122
+ * degrade.
123
+ */
124
+ failOpen?: boolean;
125
+ }
126
+ /**
127
+ * Verify a client-issued CAPTCHA token with the fail-open/closed discipline an
128
+ * auth endpoint needs, and return a {@link CaptchaOutcome}.
129
+ *
130
+ * - **No provider** → unchallenged `"pass"` (`challenged: false`).
131
+ * - **Missing/empty token** → `"fail"` (the challenge went unanswered).
132
+ * - **Provider `{ success }`** → `"pass"`/`"fail"` accordingly.
133
+ * - **Provider throws (outage)** → `failOpen` decides `"pass"` or `"fail"`;
134
+ * either way the outcome is `degraded: true`, because no token was really
135
+ * evaluated.
136
+ *
137
+ * Never throws — a broken provider becomes a decision, not an exception the
138
+ * route must catch. Compose the result with your rate limiter and lockout; this
139
+ * does not replace them.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const outcome = await verifyCaptcha({ provider, token, context: { ip, action: "signin" } });
144
+ * if (outcome.decision === "fail") return uniformRejection();
145
+ * ```
146
+ */
147
+ export declare function verifyCaptcha(options: VerifyCaptchaOptions): Promise<CaptchaOutcome>;