@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,242 @@
1
+ import type { ClientInterface } from "../../models/client.js";
2
+ import type { AuthenticationContext } from "../../models/authentication.js";
3
+ import type { RefreshToken, Token } from "../../models/token.js";
4
+ import type { AbstractScope, BasicScope } from "../../models/scope.js";
5
+ import type { ClientServiceInterface } from "./client.js";
6
+ import type { UserServiceInterface } from "./user.js";
7
+ /**
8
+ * Minimal interface for reading/validating tokens.
9
+ *
10
+ * This is all a resource server needs to authenticate requests.
11
+ * Implement this when your resource server validates tokens against
12
+ * an external authorization server (e.g., via introspection) or
13
+ * a shared token store.
14
+ */
15
+ export interface TokenReaderInterface<Client extends ClientInterface, User, Scope extends AbstractScope = BasicScope> {
16
+ /** Retrieves an existing token by access token string. */
17
+ getToken(accessToken: string): Promise<Token<Client, User, Scope> | undefined>;
18
+ }
19
+ /**
20
+ * Full service interface for token lifecycle management.
21
+ *
22
+ * Extends {@linkcode TokenReaderInterface} with methods for generating,
23
+ * saving, and revoking tokens. Used by the authorization server and
24
+ * its grant types.
25
+ *
26
+ * **A token need not have a user.** The client credentials grant (RFC 6749
27
+ * §4.4) has no resource owner, so it calls `acceptedScope`,
28
+ * `generateAccessToken`, and `accessTokenExpiresAt` with `user: undefined` and
29
+ * saves a {@linkcode Token} whose `user` is unset. An implementation that
30
+ * dereferences `user` without checking will throw on those requests, and a
31
+ * store with a non-nullable user column cannot persist the result — decide
32
+ * scope and lifetime from the client alone when it is absent.
33
+ * `generateRefreshToken` and `refreshTokenExpiresAt` always receive a user:
34
+ * a token with no resource owner is never issued a refresh token.
35
+ */
36
+ export interface TokenServiceInterface<Client extends ClientInterface, User, Scope extends AbstractScope = BasicScope> extends TokenReaderInterface<Client, User, Scope> {
37
+ /** Lifetime of access tokens in seconds. */
38
+ accessTokenLifetime: number;
39
+ /** Lifetime of refresh tokens in seconds. */
40
+ refreshTokenLifetime: number;
41
+ /**
42
+ * Validates and returns the accepted scope for a client and user. Return a
43
+ * scope to grant it (it may narrow the requested scope, RFC 6749 §3.3),
44
+ * `null`/`undefined` to accept the requested scope as-is, or `false` to
45
+ * reject with `invalid_scope`. `user` is `undefined` for a client acting as
46
+ * its own resource owner (client credentials).
47
+ * @returns The accepted scope, null/undefined to accept as-is, or false to reject.
48
+ */
49
+ acceptedScope(client: Client, user: User | undefined, scope?: Scope | null): Promise<Scope | null | undefined | false>;
50
+ /**
51
+ * Generates an access token string. `user` is `undefined` for a client
52
+ * acting as its own resource owner (client credentials) — a signed-token
53
+ * generator names the client as the subject then, per RFC 9068 §2.2.
54
+ * Forward `authenticationContext` to a signed-token generator so it uses
55
+ * the credential's event, including the original event on refresh.
56
+ */
57
+ generateAccessToken(client: Client, user: User | undefined, scope?: Scope | null, authenticationContext?: AuthenticationContext): Promise<string>;
58
+ /** Generates a refresh token string. */
59
+ generateRefreshToken(client: Client, user: User, scope?: Scope | null): Promise<string | undefined>;
60
+ /**
61
+ * Gets the date that a new access token would expire at. `user` is
62
+ * `undefined` for a client acting as its own resource owner (client
63
+ * credentials).
64
+ */
65
+ accessTokenExpiresAt(client: Client, user: User | undefined, scope?: Scope | null): Promise<Date | undefined>;
66
+ /** Gets the date that a new refresh token would expire at. */
67
+ refreshTokenExpiresAt(client: Client, user: User, scope?: Scope | null): Promise<Date | undefined>;
68
+ /**
69
+ * Gets the absolute date a rotation family stops being refreshable, from the
70
+ * family's anchor ({@linkcode RefreshToken.familyCreatedAt}).
71
+ *
72
+ * **This method is the whole cap.** The grants clamp a rotation's access and
73
+ * refresh expiries to the date it returns and answer `invalid_grant` once
74
+ * that date has passed. Return `undefined` — or leave the method off
75
+ * entirely, which is the default — and the family is never capped, however
76
+ * the service is otherwise configured. Implement it to cap per client (see
77
+ * {@linkcode AbstractTokenService.refreshTokenMaxLifetime} for the
78
+ * service-wide version, which is what the abstract implementation reads).
79
+ *
80
+ * `user` is the refreshed token's own — `undefined` when the store returns a
81
+ * token that has none, so cap from the client alone in that case.
82
+ */
83
+ refreshTokenFamilyExpiresAt?(client: Client, user: User | undefined, familyCreatedAt: Date, scope?: Scope | null): Promise<Date | undefined>;
84
+ /** Retrieves an existing token by refresh token. */
85
+ getRefreshToken(refreshToken: string): Promise<RefreshToken<Client, User, Scope> | undefined>;
86
+ /** Persists a refresh token and returns the saved record. */
87
+ save(token: RefreshToken<Client, User, Scope>): Promise<RefreshToken<Client, User, Scope>>;
88
+ /** Persists an access token and returns the saved record. */
89
+ save(token: Token<Client, User, Scope>): Promise<Token<Client, User, Scope>>;
90
+ /**
91
+ * Persists either token kind and returns the saved record. Preserve
92
+ * `authenticationContext` on save and every read, including refresh and
93
+ * revoked records; never reconstruct it from a user's current session.
94
+ */
95
+ save(token: Token<Client, User, Scope> | RefreshToken<Client, User, Scope>): Promise<Token<Client, User, Scope> | RefreshToken<Client, User, Scope>>;
96
+ /** Revokes a token record. Resolves true if a token was revoked. */
97
+ revoke(token: Token<Client, User, Scope> | RefreshToken<Client, User, Scope>): Promise<boolean>;
98
+ /**
99
+ * Revokes a token by string, using `hint` (`access_token`/`refresh_token`,
100
+ * RFC 7009 §2.1) to disambiguate which kind to look up first.
101
+ */
102
+ revoke(token: string, hint?: string | null): Promise<boolean>;
103
+ /** Revokes a token given as a record or string. Resolves true if revoked. */
104
+ revoke(token: Token<Client, User, Scope> | RefreshToken<Client, User, Scope> | string, hint?: string | null): Promise<boolean>;
105
+ /**
106
+ * Revokes a refresh token that has just been superseded by rotation.
107
+ * Atomically claims the active token: resolves `true` once, and `false` for
108
+ * concurrent or repeated claims. The grant saves a successor only after a
109
+ * successful claim. Apply the same guarantee to `revoke` when it is the fallback.
110
+ *
111
+ * Rotation is bookkeeping inside a **continuing** grant: the person stays
112
+ * signed in and the successor token takes over. Implement this when
113
+ * {@linkcode revoke} carries end-of-grant side effects — ending the session
114
+ * the token belongs to, cascading to sibling records — so a routine refresh
115
+ * cannot terminate the very session it renews. When absent, the refresh
116
+ * grant falls back to {@linkcode revoke}.
117
+ */
118
+ revokeRotated?(token: RefreshToken<Client, User, Scope>): Promise<boolean>;
119
+ /**
120
+ * Revokes all tokens issued with the given authorization code.
121
+ * Returns true if any tokens were revoked (indicating code replay).
122
+ *
123
+ * Per RFC 6819 Section 4.4.1.1, if an authorization code is used more
124
+ * than once, the authorization server MUST revoke all tokens previously
125
+ * issued based on that authorization code.
126
+ *
127
+ * @see https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.1.1
128
+ */
129
+ revokeCode(code: string): Promise<boolean>;
130
+ /**
131
+ * Looks up a refresh token that has already been revoked/rotated out —
132
+ * the signal the refresh grant's reuse detection needs. Implement this
133
+ * (with {@linkcode revokeFamily}) by keeping revoked refresh-token records
134
+ * findable instead of deleting them; when absent, reuse detection is
135
+ * silently disabled.
136
+ */
137
+ getRevokedRefreshToken?(refreshToken: string): Promise<RefreshToken<Client, User, Scope> | undefined>;
138
+ /**
139
+ * Revokes every token belonging to a rotation family — called by the
140
+ * refresh grant when a rotated-out member is replayed, so a stolen token
141
+ * can't keep a session alive. Returns true if anything was revoked.
142
+ */
143
+ revokeFamily?(familyId: string): Promise<boolean>;
144
+ }
145
+ /** Options for configuring an abstract token service. */
146
+ export interface AbstractTokenServiceOptions<Client extends ClientInterface, User> {
147
+ /** Lifetime of access tokens in seconds. Defaults to 3600 (1 hour). */
148
+ accessTokenLifetime?: number;
149
+ /** Lifetime of refresh tokens in seconds. Defaults to 1209600 (14 days). */
150
+ refreshTokenLifetime?: number;
151
+ /**
152
+ * Absolute lifetime of a refresh-token family in seconds, read by this
153
+ * class's {@linkcode AbstractTokenService.refreshTokenFamilyExpiresAt}. Omit
154
+ * for the historical behavior, an uncapped sliding window. Must be at least
155
+ * `refreshTokenLifetime`.
156
+ */
157
+ refreshTokenMaxLifetime?: number;
158
+ /** Client service for hydrating tokens. */
159
+ clientService?: ClientServiceInterface<Client, User>;
160
+ /** User service for hydrating tokens. */
161
+ userService?: UserServiceInterface<User>;
162
+ }
163
+ /**
164
+ * Abstract token service with sensible defaults for token generation.
165
+ *
166
+ * Provides default implementations for:
167
+ * - `acceptedScope` — accepts scope as-is
168
+ * - `generateAccessToken` / `generateRefreshToken` — crypto.randomUUID()
169
+ * - `accessTokenExpiresAt` / `refreshTokenExpiresAt` — based on lifetime settings
170
+ *
171
+ * Subclasses must implement the storage methods:
172
+ * `getToken`, `getRefreshToken`, `save`, `revoke`, `revokeCode`
173
+ */
174
+ export declare abstract class AbstractTokenService<Client extends ClientInterface, User, Scope extends AbstractScope = BasicScope> implements TokenServiceInterface<Client, User, Scope> {
175
+ /** Lifetime of access tokens in seconds. */
176
+ accessTokenLifetime: number;
177
+ /** Lifetime of refresh tokens in seconds. */
178
+ refreshTokenLifetime: number;
179
+ /**
180
+ * Absolute lifetime of a refresh-token family in seconds, or `undefined` for
181
+ * an uncapped family. Enforced only through this class's
182
+ * {@linkcode refreshTokenFamilyExpiresAt}: an override that ignores it
183
+ * ignores the cap.
184
+ */
185
+ refreshTokenMaxLifetime?: number;
186
+ /** Client service used by subclasses to hydrate tokens. */
187
+ protected clientService?: ClientServiceInterface<Client, User>;
188
+ /** User service used by subclasses to hydrate tokens. */
189
+ protected userService?: UserServiceInterface<User>;
190
+ /**
191
+ * Lifetimes default to 3600 seconds (access) and 1209600 seconds / 14 days
192
+ * (refresh) when not supplied. `refreshTokenMaxLifetime` has no default —
193
+ * refresh-token families are uncapped unless one is configured.
194
+ *
195
+ * @throws {TypeError} If `refreshTokenLifetime` exceeds
196
+ * `refreshTokenMaxLifetime`, which would truncate every issued refresh token.
197
+ */
198
+ constructor(options?: AbstractTokenServiceOptions<Client, User>);
199
+ /**
200
+ * Accepts the requested scope unchanged. Override to narrow or reject scope
201
+ * (return `false` to reject with `invalid_scope`).
202
+ */
203
+ acceptedScope(_client: Client, _user: User | undefined, scope?: Scope | null): Promise<Scope | null | undefined | false>;
204
+ /** Generates an opaque access token string. Override to issue a different format. */
205
+ generateAccessToken(_client: Client, _user: User | undefined, _scope?: Scope | null, _authenticationContext?: AuthenticationContext): Promise<string>;
206
+ /** Generates an opaque refresh token string. Override to issue a different format. */
207
+ generateRefreshToken(_client: Client, _user: User, _scope?: Scope | null): Promise<string | undefined>;
208
+ /** Computes the access token expiry as now plus {@linkcode accessTokenLifetime}. */
209
+ accessTokenExpiresAt(_client: Client, _user: User | undefined, _scope?: Scope | null): Promise<Date | undefined>;
210
+ /** Computes the refresh token expiry as now plus {@linkcode refreshTokenLifetime}. */
211
+ refreshTokenExpiresAt(_client: Client, _user: User, _scope?: Scope | null): Promise<Date | undefined>;
212
+ /**
213
+ * Computes the family's absolute expiry as its anchor plus
214
+ * {@linkcode refreshTokenMaxLifetime}, or `undefined` when no cap is
215
+ * configured. Override to cap per client instead of service-wide.
216
+ */
217
+ refreshTokenFamilyExpiresAt(_client: Client, _user: User | undefined, familyCreatedAt: Date, _scope?: Scope | null): Promise<Date | undefined>;
218
+ /** Retrieves a persisted token by its access token string. */
219
+ abstract getToken(accessToken: string): Promise<Token<Client, User, Scope> | undefined>;
220
+ /** Retrieves a persisted token by its refresh token string. */
221
+ abstract getRefreshToken(refreshToken: string): Promise<RefreshToken<Client, User, Scope> | undefined>;
222
+ /** Persists a refresh token and returns the saved record. */
223
+ abstract save(token: RefreshToken<Client, User, Scope>): Promise<RefreshToken<Client, User, Scope>>;
224
+ /** Persists an access token and returns the saved record. */
225
+ abstract save(token: Token<Client, User, Scope>): Promise<Token<Client, User, Scope>>;
226
+ /** Persists either token kind and returns the saved record. */
227
+ abstract save(token: Token<Client, User, Scope> | RefreshToken<Client, User, Scope>): Promise<Token<Client, User, Scope> | RefreshToken<Client, User, Scope>>;
228
+ /** Revokes a token record. Resolves true if a token was revoked. */
229
+ abstract revoke(token: Token<Client, User, Scope> | RefreshToken<Client, User, Scope>): Promise<boolean>;
230
+ /**
231
+ * Revokes a token by string, using `hint` (`access_token`/`refresh_token`,
232
+ * RFC 7009 §2.1) to disambiguate which kind to look up first.
233
+ */
234
+ abstract revoke(token: string, hint?: string | null): Promise<boolean>;
235
+ /** Revokes a token given as a record or string. Resolves true if revoked. */
236
+ abstract revoke(token: Token<Client, User, Scope> | RefreshToken<Client, User, Scope> | string, hint?: string | null): Promise<boolean>;
237
+ /**
238
+ * Revokes every token issued from the given authorization code, returning
239
+ * true if any were revoked (signaling code replay per RFC 6819 §4.4.1.1).
240
+ */
241
+ abstract revokeCode(code: string): Promise<boolean>;
242
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Abstract token service with sensible defaults for token generation.
3
+ *
4
+ * Provides default implementations for:
5
+ * - `acceptedScope` — accepts scope as-is
6
+ * - `generateAccessToken` / `generateRefreshToken` — crypto.randomUUID()
7
+ * - `accessTokenExpiresAt` / `refreshTokenExpiresAt` — based on lifetime settings
8
+ *
9
+ * Subclasses must implement the storage methods:
10
+ * `getToken`, `getRefreshToken`, `save`, `revoke`, `revokeCode`
11
+ */
12
+ export class AbstractTokenService {
13
+ /** Lifetime of access tokens in seconds. */
14
+ accessTokenLifetime;
15
+ /** Lifetime of refresh tokens in seconds. */
16
+ refreshTokenLifetime;
17
+ /**
18
+ * Absolute lifetime of a refresh-token family in seconds, or `undefined` for
19
+ * an uncapped family. Enforced only through this class's
20
+ * {@linkcode refreshTokenFamilyExpiresAt}: an override that ignores it
21
+ * ignores the cap.
22
+ */
23
+ refreshTokenMaxLifetime;
24
+ /** Client service used by subclasses to hydrate tokens. */
25
+ clientService;
26
+ /** User service used by subclasses to hydrate tokens. */
27
+ userService;
28
+ /**
29
+ * Lifetimes default to 3600 seconds (access) and 1209600 seconds / 14 days
30
+ * (refresh) when not supplied. `refreshTokenMaxLifetime` has no default —
31
+ * refresh-token families are uncapped unless one is configured.
32
+ *
33
+ * @throws {TypeError} If `refreshTokenLifetime` exceeds
34
+ * `refreshTokenMaxLifetime`, which would truncate every issued refresh token.
35
+ */
36
+ constructor(options) {
37
+ this.accessTokenLifetime = options?.accessTokenLifetime ?? 3600;
38
+ this.refreshTokenLifetime = options?.refreshTokenLifetime ?? 1209600;
39
+ this.refreshTokenMaxLifetime = options?.refreshTokenMaxLifetime;
40
+ if (this.refreshTokenMaxLifetime !== undefined &&
41
+ this.refreshTokenLifetime > this.refreshTokenMaxLifetime) {
42
+ throw new TypeError("refreshTokenLifetime must not exceed refreshTokenMaxLifetime");
43
+ }
44
+ this.clientService = options?.clientService;
45
+ this.userService = options?.userService;
46
+ }
47
+ /**
48
+ * Accepts the requested scope unchanged. Override to narrow or reject scope
49
+ * (return `false` to reject with `invalid_scope`).
50
+ */
51
+ acceptedScope(_client, _user, scope) {
52
+ return Promise.resolve(scope);
53
+ }
54
+ /** Generates an opaque access token string. Override to issue a different format. */
55
+ generateAccessToken(_client, _user, _scope, _authenticationContext) {
56
+ return Promise.resolve(crypto.randomUUID());
57
+ }
58
+ /** Generates an opaque refresh token string. Override to issue a different format. */
59
+ generateRefreshToken(_client, _user, _scope) {
60
+ return Promise.resolve(crypto.randomUUID());
61
+ }
62
+ /** Computes the access token expiry as now plus {@linkcode accessTokenLifetime}. */
63
+ accessTokenExpiresAt(_client, _user, _scope) {
64
+ return Promise.resolve(new Date(Date.now() + this.accessTokenLifetime * 1000));
65
+ }
66
+ /** Computes the refresh token expiry as now plus {@linkcode refreshTokenLifetime}. */
67
+ refreshTokenExpiresAt(_client, _user, _scope) {
68
+ return Promise.resolve(new Date(Date.now() + this.refreshTokenLifetime * 1000));
69
+ }
70
+ /**
71
+ * Computes the family's absolute expiry as its anchor plus
72
+ * {@linkcode refreshTokenMaxLifetime}, or `undefined` when no cap is
73
+ * configured. Override to cap per client instead of service-wide.
74
+ */
75
+ refreshTokenFamilyExpiresAt(_client, _user, familyCreatedAt, _scope) {
76
+ return Promise.resolve(this.refreshTokenMaxLifetime == null ? undefined : new Date(familyCreatedAt.getTime() + this.refreshTokenMaxLifetime * 1000));
77
+ }
78
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Service interface for user management.
3
+ * Provides user lookup and authentication.
4
+ */
5
+ export interface UserServiceInterface<User> {
6
+ /** Retrieves a user by their unique identifier. */
7
+ get(id: string): Promise<User | undefined>;
8
+ /**
9
+ * Retrieves an authenticated user if the username/password combination is
10
+ * correct.
11
+ *
12
+ * Only the password grant calls this, and the grant issues tokens for
13
+ * whatever user this returns — it applies **no second-factor check of its
14
+ * own**. This method is therefore the only place an MFA policy can be
15
+ * enforced on that flow: return `undefined` or throw for a user who owes a
16
+ * second factor, or accept that their password alone mints tokens.
17
+ *
18
+ * Throwing an OAuth2 error (e.g. `InvalidGrantError`) surfaces it on the
19
+ * token response as that error; anything else becomes a `server_error`.
20
+ */
21
+ getAuthenticated(username: string, password: string): Promise<User | undefined>;
22
+ }
23
+ /**
24
+ * The password hashing primitives, re-exported from the identity layer so a
25
+ * credential minted through one entrypoint verifies through the other. See
26
+ * `@udibo/oauth2/identity` for the work-factor constants and the
27
+ * `PasswordIdentityService` that records them on the credential.
28
+ */
29
+ export { generateSalt, hashPassword, verifyPassword, } from "../../identity/password.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The password hashing primitives, re-exported from the identity layer so a
3
+ * credential minted through one entrypoint verifies through the other. See
4
+ * `@udibo/oauth2/identity` for the work-factor constants and the
5
+ * `PasswordIdentityService` that records them on the credential.
6
+ */
7
+ export { generateSalt, hashPassword, verifyPassword, } from "../../identity/password.js";
@@ -0,0 +1,201 @@
1
+ /**
2
+ * OIDC signing keys and compact JWS signing — Web Crypto only, no
3
+ * dependencies. Backs id_token issuance, the JWKS endpoint, and the optional
4
+ * signed (JWT) access-token generator.
5
+ *
6
+ * Keys are ES256 (the OIDC-recommended default with broad library support).
7
+ * Generate once with {@link generateSigningKey}, persist via
8
+ * {@link exportSigningKeyJwk}, and load on boot with {@link importSigningKeyJwk}
9
+ * so every instance of a multi-instance deploy signs with the same key (an
10
+ * ephemeral per-instance key would fail verification across instances).
11
+ *
12
+ * @module
13
+ */
14
+ import type { AuthenticationContext } from "../models/authentication.js";
15
+ /** A ready-to-use signing key: private half signs, public JWK is published. */
16
+ export interface SigningKey {
17
+ /** Key id, stamped into JWS headers and the JWKS entry. */
18
+ kid: string;
19
+ /** JWS algorithm. Always `ES256` today. */
20
+ alg: "ES256";
21
+ /** The private key used to sign. */
22
+ privateKey: CryptoKey;
23
+ /** The public JWK (no private material) served from the JWKS endpoint. */
24
+ publicJwk: JsonWebKey & {
25
+ kid: string;
26
+ alg: string;
27
+ use: string;
28
+ };
29
+ }
30
+ /**
31
+ * Provides the server's current signing key. A provider seam so key storage
32
+ * and rotation stay app-owned; {@link StaticSigningKeyProvider} covers the
33
+ * single-key case.
34
+ */
35
+ export interface SigningKeyProvider {
36
+ /** The key new tokens are signed with. */
37
+ getSigningKey(): Promise<SigningKey>;
38
+ /** Every public key a verifier may need (current + not-yet-expired old). */
39
+ getPublicJwks(): Promise<{
40
+ keys: JsonWebKey[];
41
+ }>;
42
+ }
43
+ /** A {@link SigningKeyProvider} over one fixed key. */
44
+ export declare class StaticSigningKeyProvider implements SigningKeyProvider {
45
+ #private;
46
+ /** Fixes the single key this provider signs with and publishes. */
47
+ constructor(key: SigningKey);
48
+ /** The fixed key passed at construction. */
49
+ getSigningKey(): Promise<SigningKey>;
50
+ /** A JWKS containing only the fixed key's public JWK. */
51
+ getPublicJwks(): Promise<{
52
+ keys: JsonWebKey[];
53
+ }>;
54
+ }
55
+ /** Options for {@link RotatingSigningKeyProvider}. */
56
+ export interface RotatingSigningKeyProviderOptions {
57
+ /** The key new tokens are signed with. Its `kid` is stamped into every JWS. */
58
+ current: SigningKey;
59
+ /**
60
+ * Keys retired from signing but still published in JWKS so tokens minted
61
+ * before the rotation keep verifying. Omit (or pass `[]`) for the single-key
62
+ * steady state, where this provider behaves exactly like
63
+ * {@link StaticSigningKeyProvider}.
64
+ */
65
+ previous?: SigningKey[];
66
+ }
67
+ /**
68
+ * A {@link SigningKeyProvider} for rotating the signing key through a JWKS
69
+ * grace window: sign with {@link RotatingSigningKeyProviderOptions.current}
70
+ * only, while {@link RotatingSigningKeyProviderOptions.previous} keys stay
71
+ * published so outstanding tokens keep validating until they expire and every
72
+ * consumer has refetched JWKS.
73
+ *
74
+ * Rotation is: promote the new key to `current`, move the old one into
75
+ * `previous`, and hold that grace window for at least the longest token
76
+ * lifetime before dropping the old key from `previous`. Because
77
+ * {@link signJwt} stamps the current key's `kid` into every JWS header and each
78
+ * published JWK carries its own `kid`, verifiers select the right key by `kid`
79
+ * across the window. Keys are published current-first and de-duplicated by
80
+ * `kid`.
81
+ *
82
+ * A single-key configuration (`previous` empty or omitted) publishes exactly
83
+ * the one key and is behaviourally identical to
84
+ * {@link StaticSigningKeyProvider} — adopting this provider does not change a
85
+ * deployment that has not started a rotation.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * const provider = new RotatingSigningKeyProvider({
90
+ * current: await importSigningKeyJwk(JSON.parse(currentJwk)),
91
+ * previous: [await importSigningKeyJwk(JSON.parse(oldJwk))],
92
+ * });
93
+ * ```
94
+ */
95
+ export declare class RotatingSigningKeyProvider implements SigningKeyProvider {
96
+ #private;
97
+ /** Fixes the current signing key and the published set (current + previous). */
98
+ constructor(options: RotatingSigningKeyProviderOptions);
99
+ /** The current key — the only key new tokens are ever signed with. */
100
+ getSigningKey(): Promise<SigningKey>;
101
+ /** Public JWKs for the current key and every still-published previous key. */
102
+ getPublicJwks(): Promise<{
103
+ keys: JsonWebKey[];
104
+ }>;
105
+ }
106
+ /** Maps a user to a JWT `sub` claim: the user's `id` property, else the user itself. */
107
+ export declare function defaultSubjectOf(user: unknown): string;
108
+ /** Generate a fresh ES256 signing key with a random `kid`. */
109
+ export declare function generateSigningKey(): Promise<SigningKey>;
110
+ /**
111
+ * Export a signing key (including private material) as a JWK for persistence
112
+ * — e.g. into a secret-manager entry the app loads on boot. Guard it like any
113
+ * credential.
114
+ */
115
+ export declare function exportSigningKeyJwk(key: SigningKey): Promise<JsonWebKey & {
116
+ kid: string;
117
+ }>;
118
+ /** Import a signing key previously exported with {@link exportSigningKeyJwk}. */
119
+ export declare function importSigningKeyJwk(jwk: JsonWebKey & {
120
+ kid?: string;
121
+ }): Promise<SigningKey>;
122
+ /**
123
+ * Sign a compact JWS (`header.payload.signature`) with the given key —
124
+ * the primitive behind id_tokens and JWT access tokens.
125
+ */
126
+ export declare function signJwt(key: SigningKey, payload: Record<string, unknown>, header?: Record<string, unknown>): Promise<string>;
127
+ /** Options for {@link verifyJwt}. */
128
+ export interface VerifyJwtOptions {
129
+ /**
130
+ * Accept a payload whose `exp` has passed. Only for a token used as a
131
+ * **hint** rather than as authority — OIDC RP-Initiated Logout's
132
+ * `id_token_hint` is the case this exists for, since the id_token naming the
133
+ * session to end has usually outlived its own lifetime by the time anyone
134
+ * logs out. Never set it for a token that authorizes something.
135
+ *
136
+ * @default false
137
+ */
138
+ ignoreExpiration?: boolean;
139
+ }
140
+ /**
141
+ * Verify a compact JWS against a public JWK and return its payload, or
142
+ * `undefined` when the signature (or shape) is invalid or the payload's `exp`
143
+ * is in the past. Exported for tests and lightweight in-process verification;
144
+ * production resource servers should verify against the JWKS endpoint with
145
+ * their JOSE library of choice.
146
+ */
147
+ export declare function verifyJwt(jwt: string, publicJwk: JsonWebKey, options?: VerifyJwtOptions): Promise<Record<string, unknown> | undefined>;
148
+ /**
149
+ * Build a `generateAccessToken` implementation that issues **signed JWT
150
+ * access tokens** (RFC 9068 `at+jwt`) instead of opaque strings — the
151
+ * "verifiable signed-token option": resource servers can validate offline
152
+ * against the JWKS endpoint. Wire it into your token service:
153
+ *
154
+ * ```ts
155
+ * class JwtTokenService extends MyTokenService {
156
+ * override generateAccessToken = createJwtAccessTokenGenerator({
157
+ * signingKeys, issuer: "https://auth.example.com",
158
+ * });
159
+ * }
160
+ * ```
161
+ *
162
+ * The token store still persists the (hashed) JWT string, so revocation and
163
+ * introspection keep working exactly as with opaque tokens.
164
+ */
165
+ export declare function createJwtAccessTokenGenerator(options: {
166
+ /** Keys the tokens are signed with (also served from JWKS). */
167
+ signingKeys: SigningKeyProvider;
168
+ /** The `iss` claim — must match the advertised issuer. */
169
+ issuer: string;
170
+ /**
171
+ * The `aud` claim — per RFC 9068 an identifier of the resource server(s)
172
+ * the token is intended for (e.g. `https://api.example.com`). Defaults to
173
+ * the client id, which single-resource validators must then accept.
174
+ */
175
+ audience?: string;
176
+ /** Token lifetime in seconds for the `exp` claim. Defaults to 3600. */
177
+ lifetimeSeconds?: number;
178
+ /** Maps a user to the `sub` claim. Defaults to the user's `id` property. */
179
+ subjectOf?: (user: unknown) => string;
180
+ /**
181
+ * Extra claims for the resource owner's tokens — the same seam
182
+ * `AuthorizationServer`'s `userClaims` option gives the id_token, so one
183
+ * claims computation can feed both. Called only when a user is present: a
184
+ * client-credentials token has no resource owner, so it never carries user
185
+ * claims. The protocol claims (`iss`, `sub`, `aud`, `client_id`, `iat`,
186
+ * `exp`, `jti`, `scope`) always win — a returned claim under one of those
187
+ * names is discarded, never merged.
188
+ * The fourth argument is the token's recorded authentication event. Return
189
+ * its fields to emit them, without consulting a newer session. Custom token
190
+ * service wrappers must forward the fourth `generateAccessToken` argument.
191
+ */
192
+ userClaims?: (user: unknown, scope?: {
193
+ toString(): string;
194
+ } | null, client?: {
195
+ id: string;
196
+ }, authenticationContext?: AuthenticationContext) => Record<string, unknown> | Promise<Record<string, unknown>>;
197
+ }): (client: {
198
+ id: string;
199
+ }, user: unknown, scope?: {
200
+ toString(): string;
201
+ } | null, authenticationContext?: AuthenticationContext) => Promise<string>;