@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,164 @@
1
+ /**
2
+ * Token reader that validates tokens via an OAuth2 introspection endpoint.
3
+ *
4
+ * This is the standard way for resource servers to validate tokens when
5
+ * they are separate from the authorization server. The reader calls the
6
+ * authorization server's introspection endpoint (RFC 7662) to check
7
+ * whether a token is active and retrieve its metadata.
8
+ *
9
+ * @see https://datatracker.ietf.org/doc/html/rfc7662
10
+ * @module
11
+ */
12
+ import { ServerError, TemporarilyUnavailableError } from "../errors.js";
13
+ import { BasicScope } from "../models/scope.js";
14
+ import { encodeBasicAuth } from "../utils/basic-auth.js";
15
+ /**
16
+ * Validates tokens by calling an OAuth2 introspection endpoint (RFC 7662).
17
+ *
18
+ * Use this with {@linkcode ResourceServer} when your resource server is
19
+ * separate from the authorization server. The reader authenticates with
20
+ * the introspection endpoint using client credentials (HTTP Basic Auth)
21
+ * and projects the response into the resource server's `Client` / `User`
22
+ * types via the {@linkcode IntrospectionTokenReaderOptions.getClient} and
23
+ * {@linkcode IntrospectionTokenReaderOptions.getUser} mappers.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import {
28
+ * IntrospectionTokenReader,
29
+ * ResourceServer,
30
+ * } from "@udibo/oauth2/server/resource";
31
+ *
32
+ * interface MyClient { id: string }
33
+ * interface MyUser { id: string; email?: string }
34
+ *
35
+ * const tokenReader = new IntrospectionTokenReader<MyClient, MyUser>({
36
+ * introspectionEndpoint: "https://auth.example.com/introspect",
37
+ * clientId: "my-api",
38
+ * clientSecret: "my-secret",
39
+ * getClient: (data) => ({ id: data.client_id! }),
40
+ * getUser: (data) =>
41
+ * data.sub
42
+ * ? { id: data.sub, email: data.email as string | undefined }
43
+ * : undefined,
44
+ * });
45
+ *
46
+ * const resourceServer = new ResourceServer<MyClient, MyUser>({
47
+ * resolve: () => ({ services: { tokenService: tokenReader } }),
48
+ * });
49
+ * ```
50
+ */
51
+ export class IntrospectionTokenReader {
52
+ introspectionEndpoint;
53
+ clientId;
54
+ clientSecret;
55
+ Scope;
56
+ getClient;
57
+ getUser;
58
+ fetchTimeoutMs;
59
+ customFetch;
60
+ /**
61
+ * `Scope` defaults to {@linkcode BasicScope}, `fetchTimeoutMs` to 5000, and
62
+ * `fetch` to the global `fetch` when omitted from `options`.
63
+ */
64
+ constructor(options) {
65
+ this.introspectionEndpoint = options.introspectionEndpoint;
66
+ this.clientId = options.clientId;
67
+ this.clientSecret = options.clientSecret;
68
+ this.Scope = options.Scope ??
69
+ BasicScope;
70
+ this.getClient = options.getClient;
71
+ this.getUser = options.getUser;
72
+ this.fetchTimeoutMs = options.fetchTimeoutMs ?? 5_000;
73
+ this.customFetch = options.fetch;
74
+ }
75
+ /**
76
+ * Validates an access token by calling the introspection endpoint.
77
+ *
78
+ * Sends a POST request with the token to the configured introspection
79
+ * endpoint, authenticated with client credentials via HTTP Basic Auth.
80
+ *
81
+ * @returns The token with client/user/scope info, or `undefined` when the
82
+ * endpoint reports the token inactive (RFC 7662 `{ active: false }`) or
83
+ * does not identify it as a bearer access token.
84
+ * @throws {TemporarilyUnavailableError} If the introspection endpoint is
85
+ * unreachable, takes longer than
86
+ * {@linkcode IntrospectionTokenReaderOptions.fetchTimeoutMs} to answer, or
87
+ * returns a 5xx — a down authorization server must be distinguishable from
88
+ * a genuinely invalid token (which is `undefined` → `invalid_token`), not
89
+ * collapsed into it.
90
+ * @throws {ServerError} If the endpoint returns a 4xx (e.g. the reader's own
91
+ * introspection credentials are rejected) — a misconfiguration, not a
92
+ * verdict on the caller's token.
93
+ *
94
+ * An active response is only accepted when its `token_type` names a bearer
95
+ * token. RFC 7662 answers for refresh tokens too, and a refresh token's
96
+ * response is otherwise indistinguishable from an access token's — without
97
+ * this check a refresh token presented as `Authorization: Bearer …` would
98
+ * authenticate at the resource server, bypassing rotation and reuse
99
+ * detection. An authorization server that omits `token_type` from an active
100
+ * response cannot be read by this reader.
101
+ */
102
+ async getToken(accessToken) {
103
+ const data = await this.#introspect(accessToken);
104
+ if (!data.active)
105
+ return undefined;
106
+ if (data.token_type?.toLowerCase() !== "bearer")
107
+ return undefined;
108
+ const [client, user] = await Promise.all([
109
+ this.getClient(data),
110
+ this.getUser?.(data),
111
+ ]);
112
+ return {
113
+ accessToken,
114
+ accessTokenExpiresAt: data.exp ? new Date(data.exp * 1000) : undefined,
115
+ client,
116
+ user,
117
+ scope: data.scope
118
+ ? new this.Scope(data.scope)
119
+ : undefined,
120
+ claims: data,
121
+ };
122
+ }
123
+ async #introspect(accessToken) {
124
+ const fetchImpl = this.customFetch ?? globalThis.fetch;
125
+ const controller = new AbortController();
126
+ const deadline = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
127
+ try {
128
+ let response;
129
+ try {
130
+ response = await fetchImpl(this.introspectionEndpoint, {
131
+ method: "POST",
132
+ headers: {
133
+ "Content-Type": "application/x-www-form-urlencoded",
134
+ "Authorization": encodeBasicAuth(this.clientId, this.clientSecret),
135
+ },
136
+ body: new URLSearchParams({ token: accessToken }),
137
+ signal: controller.signal,
138
+ });
139
+ }
140
+ catch (cause) {
141
+ throw new TemporarilyUnavailableError("token introspection request failed", { cause });
142
+ }
143
+ if (!response.ok) {
144
+ await response.body?.cancel();
145
+ throw response.status >= 500
146
+ ? new TemporarilyUnavailableError(`token introspection failed (HTTP ${response.status})`)
147
+ : new ServerError(`token introspection failed (HTTP ${response.status})`);
148
+ }
149
+ try {
150
+ return await response.json();
151
+ }
152
+ catch (cause) {
153
+ throw controller.signal.aborted
154
+ ? new TemporarilyUnavailableError("token introspection request failed", { cause })
155
+ : new ServerError("token introspection response was not JSON", {
156
+ cause,
157
+ });
158
+ }
159
+ }
160
+ finally {
161
+ clearTimeout(deadline);
162
+ }
163
+ }
164
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Token reader that validates JWT access tokens locally against the
3
+ * issuer's published JWKS, with no per-request network hop.
4
+ *
5
+ * This is the validating half of RFC 9068 (`at+jwt`): the authorization
6
+ * server signs access tokens and publishes its public keys at a `jwks_uri`;
7
+ * the resource server fetches those keys once, caches them, and verifies
8
+ * every subsequent token in-process. Signature verification uses Web Crypto
9
+ * only — the package takes no JOSE dependency.
10
+ *
11
+ * @see https://datatracker.ietf.org/doc/html/rfc9068
12
+ * @see https://datatracker.ietf.org/doc/html/rfc7517
13
+ * @module
14
+ */
15
+ import type { ClientInterface } from "../models/client.js";
16
+ import type { AbstractScope, ScopeConstructor } from "../models/scope.js";
17
+ import { BasicScope } from "../models/scope.js";
18
+ import type { Token } from "../models/token.js";
19
+ import type { TokenReaderInterface } from "./services/token.js";
20
+ /**
21
+ * Claims of a validated JWT access token, as defined by RFC 9068 §2.2.
22
+ *
23
+ * Passed to the {@linkcode JwksTokenReaderOptions.getClient} and
24
+ * {@linkcode JwksTokenReaderOptions.getUser} mappers. Issuers routinely add
25
+ * their own claims (roles, tenant, email); the index signature exposes them.
26
+ */
27
+ export interface JwtAccessTokenClaims {
28
+ /** Issuer that signed the token. Verified against the configured issuer. */
29
+ iss: string;
30
+ /** Subject — the end user, or the client itself for client-credentials tokens. */
31
+ sub?: string;
32
+ /** Audience(s) the token is intended for. Verified against the configured audience. */
33
+ aud: string | string[];
34
+ /** Expiration time, seconds since the epoch. */
35
+ exp: number;
36
+ /** Issued-at time, seconds since the epoch. */
37
+ iat?: number;
38
+ /** Not-before time, seconds since the epoch. */
39
+ nbf?: number;
40
+ /** Unique token identifier. */
41
+ jti?: string;
42
+ /** Client the token was issued to. */
43
+ client_id?: string;
44
+ /** Space-delimited granted scopes. */
45
+ scope?: string;
46
+ /** Granted scopes as an array or string — the variant some issuers emit instead of `scope`. */
47
+ scp?: string | string[];
48
+ /** Extension claims. Issuers may add anything. */
49
+ [claim: string]: unknown;
50
+ }
51
+ /**
52
+ * Options for configuring the JWKS token reader.
53
+ *
54
+ * {@linkcode issuer} and {@linkcode audience} are required because RFC 9068
55
+ * §4 requires a resource server to reject tokens minted for a different
56
+ * issuer or a different audience — with local validation there is no
57
+ * authorization server in the request path to do it for you.
58
+ */
59
+ export interface JwksTokenReaderOptions<Client extends ClientInterface, User, S extends AbstractScope = BasicScope> {
60
+ /**
61
+ * Expected `iss` claim. Also the discovery base when
62
+ * {@linkcode jwksUri} is omitted.
63
+ */
64
+ issuer: string;
65
+ /**
66
+ * Accepted `aud` claim value(s) — this resource server's identifier. A
67
+ * token passes when its `aud` (string or array) includes at least one of
68
+ * these. Authorization servers that default `aud` to the client id
69
+ * require listing the client ids you accept.
70
+ */
71
+ audience: string | string[];
72
+ /**
73
+ * URL of the issuer's JWKS. Omit to discover it from `issuer`, trying
74
+ * `/.well-known/oauth-authorization-server` then
75
+ * `/.well-known/openid-configuration` inserted before the issuer's path
76
+ * component (RFC 8414 §3.1), then the OIDC Core form with
77
+ * `/.well-known/openid-configuration` appended. For a path-less issuer the
78
+ * last two are the same URL and only one request is made.
79
+ */
80
+ jwksUri?: string;
81
+ /**
82
+ * JWS algorithms accepted from the token header, intersected with what the
83
+ * matched key supports. Defaults to every asymmetric algorithm Web Crypto
84
+ * covers: `ES256`/`ES384`/`ES512`, `RS256`/`RS384`/`RS512`, and
85
+ * `PS256`/`PS384`/`PS512`. Pin it to what your issuer actually signs with
86
+ * when you can. Symmetric (`HS*`) and `none` are never accepted.
87
+ */
88
+ algorithms?: string[];
89
+ /**
90
+ * Accepted `typ` header values, compared case-insensitively with an
91
+ * optional `application/` prefix. Defaults to `["at+jwt"]` per RFC 9068 §4.
92
+ *
93
+ * This is the first line of defense against another JWT the same issuer
94
+ * signs — an OIDC `id_token` above all — being replayed as an access
95
+ * token. Prefer configuring your issuer to stamp `at+jwt` over widening
96
+ * this. If you must widen it (`["at+jwt", "jwt"]`) or disable it (`[]`),
97
+ * give this API an {@linkcode audience} that is **not** one of your client
98
+ * ids, since an `id_token`'s `aud` is a client id. The
99
+ * {@linkcode clientIdClaim} requirement and the rejection of
100
+ * `id_token`-only claims still apply either way.
101
+ */
102
+ types?: string[];
103
+ /**
104
+ * Claim carrying the client id, required on every accepted token (RFC 9068
105
+ * §2.2 makes `client_id` REQUIRED, and its absence is what tells an
106
+ * `id_token` apart from an access token). Defaults to `"client_id"`; point
107
+ * it at the vendor claim for issuers that deviate — Okta's `cid`, Azure
108
+ * AD v1's `appid`. There is deliberately no way to drop the requirement.
109
+ */
110
+ clientIdClaim?: string;
111
+ /**
112
+ * Leeway in seconds applied to `exp` and `nbf` to absorb clock drift
113
+ * between the issuer and this server. Defaults to 30.
114
+ *
115
+ * This governs this reader's own claim checks. The token it returns carries
116
+ * the issuer's `exp` verbatim, and {@linkcode ResourceServer} re-checks that
117
+ * against its own {@linkcode ResourceServerOptions.clockSkewSeconds}, which
118
+ * defaults to no leeway — so set that one too for a resource server that
119
+ * must tolerate an about-to-expire token.
120
+ */
121
+ clockSkewSeconds?: number;
122
+ /**
123
+ * How long a fetched JWKS is served before the next validation refreshes
124
+ * it. Defaults to 600000 (10 minutes). A refresh that fails keeps serving
125
+ * the cached keys. Zero or negative makes every read refresh — supported,
126
+ * and the deterministic setting for tests, but it leans on
127
+ * {@link JwksTokenReaderOptions.minFetchIntervalMs} alone for rate limiting.
128
+ */
129
+ cacheMaxAgeMs?: number;
130
+ /**
131
+ * Minimum interval between JWKS fetches. Defaults to 30000 (30 seconds).
132
+ * This is the guard that stops a flood of tokens bearing unknown `kid`s
133
+ * from turning this reader into a JWKS-endpoint DoS amplifier; the cost is
134
+ * that a key rotation is picked up at most one interval late. Zero or
135
+ * negative removes the throttle entirely — a test-only setting, never
136
+ * appropriate against a real endpoint.
137
+ */
138
+ minFetchIntervalMs?: number;
139
+ /**
140
+ * Deadline in milliseconds for a JWKS or discovery request. Defaults to
141
+ * 5000. Without it a blackholed endpoint (dropped packets rather than a
142
+ * refused connection) would hang the refresh — and with it every request
143
+ * that joins the shared in-flight fetch. Ignored by an injected
144
+ * {@linkcode fetch} that doesn't honour `AbortSignal`.
145
+ */
146
+ fetchTimeoutMs?: number;
147
+ /** Optional scope constructor for parsing scope strings. Defaults to BasicScope. */
148
+ Scope?: ScopeConstructor<S>;
149
+ /**
150
+ * Projects a validated token's claims into a typed `Client`. Required
151
+ * because the client shape is app-specific; `client_id` (RFC 9068) is the
152
+ * usual key.
153
+ *
154
+ * May be async — return a promise to enrich from a DB lookup.
155
+ */
156
+ getClient: (claims: JwtAccessTokenClaims) => Client | Promise<Client>;
157
+ /**
158
+ * Projects a validated token's claims into a typed `User`. Return
159
+ * `undefined` when the token doesn't represent a user (e.g.
160
+ * client-credentials tokens). Omit entirely if your app never reads user
161
+ * info off the token.
162
+ *
163
+ * May be async — return a promise to enrich from a DB lookup or the
164
+ * issuer's UserInfo endpoint, using `claims.sub` as the lookup key.
165
+ */
166
+ getUser?: (claims: JwtAccessTokenClaims) => User | undefined | Promise<User | undefined>;
167
+ /**
168
+ * `fetch` implementation used for JWKS and discovery requests. Defaults to
169
+ * the global `fetch`. Inject it to route through a custom client (mTLS,
170
+ * timeouts, retries) or to stub the network in tests.
171
+ */
172
+ fetch?: typeof fetch;
173
+ }
174
+ /**
175
+ * Validates JWT access tokens (RFC 9068) against the issuer's remote JWKS.
176
+ *
177
+ * Use this with {@linkcode ResourceServer} when the authorization server
178
+ * issues **signed** access tokens: keys are fetched once and cached on the
179
+ * instance, so validation costs no network round-trip per request — the
180
+ * trade-off against {@linkcode IntrospectionTokenReader}, which sees
181
+ * revocation immediately but calls the authorization server every time. A
182
+ * revoked JWT stays valid here until it expires, so keep access-token
183
+ * lifetimes short, or introspect on the endpoints where revocation latency
184
+ * matters.
185
+ *
186
+ * A token is accepted only when its signature verifies against a published
187
+ * key whose algorithm the header matches, and its `typ`, `iss`, `aud`, `exp`
188
+ * and `nbf` all satisfy the configuration. Anything else is `undefined` —
189
+ * the same `invalid_token` surface as an unknown opaque token. Unreachable
190
+ * key material throws instead, so a down issuer is never reported as a bad
191
+ * token.
192
+ *
193
+ * **Token substitution.** An access token must never be confused with
194
+ * another JWT the same issuer signs. Three checks enforce that
195
+ * independently: `typ` must be `at+jwt`
196
+ * ({@linkcode JwksTokenReaderOptions.types}), the client-id claim must be
197
+ * present ({@linkcode JwksTokenReaderOptions.clientIdClaim}, REQUIRED by
198
+ * RFC 9068 §2.2 and absent from an `id_token`), and `id_token`-only claims
199
+ * (`nonce`, `at_hash`, `c_hash`, `s_hash`) are rejected outright.
200
+ * `auth_time`, `acr` and `amr` are **not** in that list — RFC 9068 §2.2.1
201
+ * permits them on an access token. A `crit` header is rejected per RFC 7515
202
+ * §4.1.11, since this reader understands no JWS extensions.
203
+ *
204
+ * The cache lives on the instance: construct one reader and reuse it.
205
+ *
206
+ * @example
207
+ * ```ts
208
+ * import { JwksTokenReader, ResourceServer } from "@udibo/oauth2/server/resource";
209
+ *
210
+ * interface MyClient { id: string }
211
+ * interface MyUser { id: string }
212
+ *
213
+ * const tokenReader = new JwksTokenReader<MyClient, MyUser>({
214
+ * issuer: "https://auth.example.com",
215
+ * audience: "https://api.example.com",
216
+ * getClient: (claims) => ({ id: String(claims.client_id) }),
217
+ * getUser: (claims) => claims.sub ? { id: claims.sub } : undefined,
218
+ * });
219
+ *
220
+ * const resourceServer = new ResourceServer<MyClient, MyUser>({
221
+ * resolve: () => ({ services: { tokenService: tokenReader } }),
222
+ * });
223
+ * ```
224
+ */
225
+ export declare class JwksTokenReader<Client extends ClientInterface, User, S extends AbstractScope = BasicScope> implements TokenReaderInterface<Client, User, S> {
226
+ #private;
227
+ /**
228
+ * Defaults: every Web Crypto asymmetric algorithm accepted, `at+jwt`
229
+ * required as `typ`, `client_id` as the required client-id claim, 30
230
+ * seconds of clock skew, a 10-minute cache with a 30-second minimum
231
+ * between fetches, a 5-second request deadline, {@linkcode BasicScope},
232
+ * and the global `fetch`.
233
+ *
234
+ * @throws {TypeError} If `issuer` is not an absolute URL, `audience` is
235
+ * empty, or `algorithms` names an algorithm this package cannot verify
236
+ * (a silently ignored entry would read as a policy that isn't enforced).
237
+ */
238
+ constructor(options: JwksTokenReaderOptions<Client, User, S>);
239
+ /**
240
+ * Validates a JWT access token against the cached JWKS.
241
+ *
242
+ * Refreshes the keys when no published key verifies the signature — at
243
+ * most one fetch per {@linkcode
244
+ * JwksTokenReaderOptions.minFetchIntervalMs}, shared by concurrent
245
+ * callers. A token whose `kid` matched a cached key and still failed
246
+ * verification is a forgery, not a rotation, and provokes no fetch. A
247
+ * stale cache refreshes in the background: requests are served from the
248
+ * cached keys rather than blocked on the issuer.
249
+ *
250
+ * @returns The token with client/user/scope info, or `undefined` when the
251
+ * token is malformed, signed by an unknown or unaccepted key, or fails
252
+ * any claim check.
253
+ * @throws {TemporarilyUnavailableError} If the JWKS (or discovery
254
+ * document) is unreachable or returns a 5xx **and** no cached keys are
255
+ * available — a down issuer must be distinguishable from a genuinely
256
+ * invalid token, not collapsed into it. Once keys are cached, a failed
257
+ * refresh is absorbed and the cached keys keep serving.
258
+ * @throws {ServerError} If the JWKS endpoint returns a 4xx or a body that
259
+ * is not a JWKS, or discovery reports no `jwks_uri` — a
260
+ * misconfiguration, not a verdict on the caller's token.
261
+ */
262
+ getToken(accessToken: string): Promise<Token<Client, User, S> | undefined>;
263
+ }