@_mustachio/openauth 0.9.2 → 0.10.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 (712) hide show
  1. package/dist/esm/adapters/d1/audit-log.js +15 -0
  2. package/dist/esm/adapters/d1/config-store.js +45 -0
  3. package/dist/esm/adapters/d1/index.js +12 -0
  4. package/dist/esm/adapters/d1/key-store.js +116 -0
  5. package/dist/esm/adapters/d1/method-store.js +52 -0
  6. package/dist/esm/adapters/d1/migrations.js +77 -0
  7. package/dist/esm/adapters/d1/session-store.js +134 -0
  8. package/dist/esm/adapters/d1/session.js +18 -0
  9. package/dist/esm/adapters/d1/token-store.js +140 -0
  10. package/dist/esm/adapters/durable-object/index.js +3 -0
  11. package/dist/esm/adapters/durable-object/session-store.js +139 -0
  12. package/dist/esm/adapters/durable-object/types.js +0 -0
  13. package/dist/esm/adapters/dynamo/audit-log.js +23 -0
  14. package/dist/esm/adapters/dynamo/client.js +0 -0
  15. package/dist/esm/adapters/dynamo/config-store.js +57 -0
  16. package/dist/esm/adapters/dynamo/index.js +10 -0
  17. package/dist/esm/adapters/dynamo/key-store.js +188 -0
  18. package/dist/esm/adapters/dynamo/method-store.js +72 -0
  19. package/dist/esm/adapters/dynamo/passkey-credential-store.js +83 -0
  20. package/dist/esm/adapters/dynamo/sdk.js +128 -0
  21. package/dist/esm/adapters/dynamo/session-store.js +173 -0
  22. package/dist/esm/adapters/dynamo/token-store.js +178 -0
  23. package/dist/esm/adapters/kms/in-memory-backing.js +28 -0
  24. package/dist/esm/adapters/kms/index.js +5 -0
  25. package/dist/esm/adapters/kms/key-store.js +129 -0
  26. package/dist/esm/adapters/kms/sdk.js +23 -0
  27. package/dist/esm/adapters/kms/types.js +0 -0
  28. package/dist/esm/adapters/kv/audit-log.js +21 -0
  29. package/dist/esm/adapters/kv/config-store.js +43 -0
  30. package/dist/esm/adapters/kv/index.js +5 -0
  31. package/dist/esm/adapters/kv/method-store.js +63 -0
  32. package/dist/esm/adapters/kv/types.js +0 -0
  33. package/dist/esm/adapters/memory/audit-log.js +16 -0
  34. package/dist/esm/adapters/memory/clock.js +5 -0
  35. package/dist/esm/adapters/memory/config-store.js +31 -0
  36. package/dist/esm/adapters/memory/index.js +10 -0
  37. package/dist/esm/adapters/memory/key-store.js +78 -0
  38. package/dist/esm/adapters/memory/method-store.js +43 -0
  39. package/dist/esm/adapters/memory/passkey-credential-store.js +53 -0
  40. package/dist/esm/adapters/memory/session-store.js +82 -0
  41. package/dist/esm/adapters/memory/token-store.js +91 -0
  42. package/dist/esm/adapters/postgres/audit-log.js +16 -0
  43. package/dist/esm/adapters/postgres/config-store.js +48 -0
  44. package/dist/esm/adapters/postgres/executor.js +21 -0
  45. package/dist/esm/adapters/postgres/index.js +13 -0
  46. package/dist/esm/adapters/postgres/key-store.js +191 -0
  47. package/dist/esm/adapters/postgres/method-store.js +61 -0
  48. package/dist/esm/adapters/postgres/migrations.js +111 -0
  49. package/dist/esm/adapters/postgres/passkey-credential-store.js +80 -0
  50. package/dist/esm/adapters/postgres/session-store.js +135 -0
  51. package/dist/esm/adapters/postgres/token-store.js +151 -0
  52. package/dist/esm/client.js +26 -10
  53. package/dist/esm/domain/audit.js +13 -0
  54. package/dist/esm/domain/authorize.js +212 -0
  55. package/dist/esm/domain/callback.js +173 -0
  56. package/dist/esm/domain/client-auth.js +61 -0
  57. package/dist/esm/domain/client-credentials.js +91 -0
  58. package/dist/esm/domain/crypto.js +97 -0
  59. package/dist/esm/domain/discovery.js +41 -0
  60. package/dist/esm/domain/introspect.js +51 -0
  61. package/dist/esm/domain/jwt.js +43 -0
  62. package/dist/esm/domain/method-cache.js +136 -0
  63. package/dist/esm/domain/method-dispatch.js +36 -0
  64. package/dist/esm/domain/method-route.js +108 -0
  65. package/dist/esm/domain/pkce.js +16 -0
  66. package/dist/esm/domain/refresh.js +91 -0
  67. package/dist/esm/domain/revoke.js +81 -0
  68. package/dist/esm/domain/state-envelope.js +80 -0
  69. package/dist/esm/domain/token-exchange.js +101 -0
  70. package/dist/esm/domain/token.js +205 -0
  71. package/dist/esm/domain/userinfo.js +27 -0
  72. package/dist/esm/http/context.js +7 -0
  73. package/dist/esm/http/cookies.js +98 -0
  74. package/dist/esm/http/errors.js +71 -0
  75. package/dist/esm/http/handlers/authorize.js +163 -0
  76. package/dist/esm/http/handlers/callback.js +53 -0
  77. package/dist/esm/http/handlers/metadata.js +34 -0
  78. package/dist/esm/http/handlers/method-route.js +87 -0
  79. package/dist/esm/http/handlers/revocation.js +98 -0
  80. package/dist/esm/http/handlers/token.js +167 -0
  81. package/dist/esm/http/handlers/userinfo.js +54 -0
  82. package/dist/esm/http/middleware/error.js +15 -0
  83. package/dist/esm/http/middleware/tenant.js +102 -0
  84. package/dist/esm/http/resolver.js +15 -0
  85. package/dist/esm/http/router.js +35 -0
  86. package/dist/esm/http/schemas/authorize.js +24 -0
  87. package/dist/esm/http/schemas/revocation.js +18 -0
  88. package/dist/esm/http/schemas/token.js +57 -0
  89. package/dist/esm/index.js +121 -9
  90. package/dist/esm/methods/code.js +221 -0
  91. package/dist/esm/methods/m2m.js +41 -0
  92. package/dist/esm/methods/oauth2-factory.js +84 -0
  93. package/dist/esm/methods/oauth2-generic.js +196 -0
  94. package/dist/esm/methods/oidc-generic.js +53 -0
  95. package/dist/esm/methods/passkey.js +275 -0
  96. package/dist/esm/methods/password-hash.js +79 -0
  97. package/dist/esm/methods/password.js +166 -0
  98. package/dist/esm/methods/providers/apple.js +29 -0
  99. package/dist/esm/methods/providers/cognito.js +37 -0
  100. package/dist/esm/methods/providers/discord.js +28 -0
  101. package/dist/esm/methods/providers/facebook.js +42 -0
  102. package/dist/esm/methods/providers/github.js +29 -0
  103. package/dist/esm/methods/providers/google.js +29 -0
  104. package/dist/esm/methods/providers/index.js +17 -0
  105. package/dist/esm/methods/providers/jumpcloud.js +27 -0
  106. package/dist/esm/methods/providers/keycloak.js +32 -0
  107. package/dist/esm/methods/providers/linkedin.js +28 -0
  108. package/dist/esm/methods/providers/microsoft.js +28 -0
  109. package/dist/esm/methods/providers/slack.js +30 -0
  110. package/dist/esm/methods/providers/spotify.js +28 -0
  111. package/dist/esm/methods/providers/twitch.js +28 -0
  112. package/dist/esm/methods/providers/x.js +28 -0
  113. package/dist/esm/methods/providers/yahoo.js +27 -0
  114. package/dist/esm/pkce.js +4 -16
  115. package/dist/esm/ports/audit-log.js +0 -0
  116. package/dist/esm/ports/config-store.js +0 -0
  117. package/dist/esm/ports/key-store.js +0 -0
  118. package/dist/esm/ports/method-store.js +0 -0
  119. package/dist/esm/ports/session-store.js +0 -0
  120. package/dist/esm/ports/token-store.js +0 -0
  121. package/dist/esm/types/authorization.js +0 -0
  122. package/dist/esm/types/error.js +65 -0
  123. package/dist/esm/types/flow.js +0 -0
  124. package/dist/esm/types/idp.js +0 -0
  125. package/dist/esm/types/method.js +0 -0
  126. package/dist/esm/types/picker.js +0 -0
  127. package/dist/esm/types/result.js +11 -0
  128. package/dist/esm/types/subject.js +0 -0
  129. package/dist/esm/types/tenant.js +5 -0
  130. package/dist/esm/types/token.js +0 -0
  131. package/dist/esm/ui/forms.js +253 -0
  132. package/dist/esm/ui/index.js +8 -0
  133. package/dist/esm/ui/picker.js +49 -0
  134. package/dist/types/adapters/d1/audit-log.d.ts +19 -0
  135. package/dist/types/adapters/d1/audit-log.d.ts.map +1 -0
  136. package/dist/types/adapters/d1/config-store.d.ts +20 -0
  137. package/dist/types/adapters/d1/config-store.d.ts.map +1 -0
  138. package/dist/types/adapters/d1/index.d.ts +35 -0
  139. package/dist/types/adapters/d1/index.d.ts.map +1 -0
  140. package/dist/types/adapters/d1/key-store.d.ts +17 -0
  141. package/dist/types/adapters/d1/key-store.d.ts.map +1 -0
  142. package/dist/types/adapters/d1/method-store.d.ts +21 -0
  143. package/dist/types/adapters/d1/method-store.d.ts.map +1 -0
  144. package/dist/types/adapters/d1/migrations.d.ts +18 -0
  145. package/dist/types/adapters/d1/migrations.d.ts.map +1 -0
  146. package/dist/types/adapters/d1/session-store.d.ts +20 -0
  147. package/dist/types/adapters/d1/session-store.d.ts.map +1 -0
  148. package/dist/types/adapters/d1/session.d.ts +18 -0
  149. package/dist/types/adapters/d1/session.d.ts.map +1 -0
  150. package/dist/types/adapters/d1/token-store.d.ts +29 -0
  151. package/dist/types/adapters/d1/token-store.d.ts.map +1 -0
  152. package/dist/types/adapters/d1/types.d.ts +43 -0
  153. package/dist/types/adapters/d1/types.d.ts.map +1 -0
  154. package/dist/types/adapters/durable-object/index.d.ts +17 -0
  155. package/dist/types/adapters/durable-object/index.d.ts.map +1 -0
  156. package/dist/types/adapters/durable-object/session-store.d.ts +21 -0
  157. package/dist/types/adapters/durable-object/session-store.d.ts.map +1 -0
  158. package/dist/types/adapters/durable-object/types.d.ts +23 -0
  159. package/dist/types/adapters/durable-object/types.d.ts.map +1 -0
  160. package/dist/types/adapters/dynamo/audit-log.d.ts +19 -0
  161. package/dist/types/adapters/dynamo/audit-log.d.ts.map +1 -0
  162. package/dist/types/adapters/dynamo/client.d.ts +111 -0
  163. package/dist/types/adapters/dynamo/client.d.ts.map +1 -0
  164. package/dist/types/adapters/dynamo/config-store.d.ts +21 -0
  165. package/dist/types/adapters/dynamo/config-store.d.ts.map +1 -0
  166. package/dist/types/adapters/dynamo/index.d.ts +60 -0
  167. package/dist/types/adapters/dynamo/index.d.ts.map +1 -0
  168. package/dist/types/adapters/dynamo/key-store.d.ts +23 -0
  169. package/dist/types/adapters/dynamo/key-store.d.ts.map +1 -0
  170. package/dist/types/adapters/dynamo/method-store.d.ts +20 -0
  171. package/dist/types/adapters/dynamo/method-store.d.ts.map +1 -0
  172. package/dist/types/adapters/dynamo/passkey-credential-store.d.ts +47 -0
  173. package/dist/types/adapters/dynamo/passkey-credential-store.d.ts.map +1 -0
  174. package/dist/types/adapters/dynamo/sdk.d.ts +23 -0
  175. package/dist/types/adapters/dynamo/sdk.d.ts.map +1 -0
  176. package/dist/types/adapters/dynamo/session-store.d.ts +20 -0
  177. package/dist/types/adapters/dynamo/session-store.d.ts.map +1 -0
  178. package/dist/types/adapters/dynamo/token-store.d.ts +29 -0
  179. package/dist/types/adapters/dynamo/token-store.d.ts.map +1 -0
  180. package/dist/types/adapters/kms/in-memory-backing.d.ts +9 -0
  181. package/dist/types/adapters/kms/in-memory-backing.d.ts.map +1 -0
  182. package/dist/types/adapters/kms/index.d.ts +35 -0
  183. package/dist/types/adapters/kms/index.d.ts.map +1 -0
  184. package/dist/types/adapters/kms/key-store.d.ts +20 -0
  185. package/dist/types/adapters/kms/key-store.d.ts.map +1 -0
  186. package/dist/types/adapters/kms/sdk.d.ts +16 -0
  187. package/dist/types/adapters/kms/sdk.d.ts.map +1 -0
  188. package/dist/types/adapters/kms/types.d.ts +58 -0
  189. package/dist/types/adapters/kms/types.d.ts.map +1 -0
  190. package/dist/types/adapters/kv/audit-log.d.ts +22 -0
  191. package/dist/types/adapters/kv/audit-log.d.ts.map +1 -0
  192. package/dist/types/adapters/kv/config-store.d.ts +25 -0
  193. package/dist/types/adapters/kv/config-store.d.ts.map +1 -0
  194. package/dist/types/adapters/kv/index.d.ts +21 -0
  195. package/dist/types/adapters/kv/index.d.ts.map +1 -0
  196. package/dist/types/adapters/kv/method-store.d.ts +23 -0
  197. package/dist/types/adapters/kv/method-store.d.ts.map +1 -0
  198. package/dist/types/adapters/kv/types.d.ts +28 -0
  199. package/dist/types/adapters/kv/types.d.ts.map +1 -0
  200. package/dist/types/adapters/memory/audit-log.d.ts +18 -0
  201. package/dist/types/adapters/memory/audit-log.d.ts.map +1 -0
  202. package/dist/types/adapters/memory/clock.d.ts +7 -0
  203. package/dist/types/adapters/memory/clock.d.ts.map +1 -0
  204. package/dist/types/adapters/memory/config-store.d.ts +19 -0
  205. package/dist/types/adapters/memory/config-store.d.ts.map +1 -0
  206. package/dist/types/adapters/memory/index.d.ts +15 -0
  207. package/dist/types/adapters/memory/index.d.ts.map +1 -0
  208. package/dist/types/adapters/memory/key-store.d.ts +17 -0
  209. package/dist/types/adapters/memory/key-store.d.ts.map +1 -0
  210. package/dist/types/adapters/memory/method-store.d.ts +26 -0
  211. package/dist/types/adapters/memory/method-store.d.ts.map +1 -0
  212. package/dist/types/adapters/memory/passkey-credential-store.d.ts +43 -0
  213. package/dist/types/adapters/memory/passkey-credential-store.d.ts.map +1 -0
  214. package/dist/types/adapters/memory/session-store.d.ts +19 -0
  215. package/dist/types/adapters/memory/session-store.d.ts.map +1 -0
  216. package/dist/types/adapters/memory/token-store.d.ts +28 -0
  217. package/dist/types/adapters/memory/token-store.d.ts.map +1 -0
  218. package/dist/types/adapters/postgres/audit-log.d.ts +18 -0
  219. package/dist/types/adapters/postgres/audit-log.d.ts.map +1 -0
  220. package/dist/types/adapters/postgres/config-store.d.ts +21 -0
  221. package/dist/types/adapters/postgres/config-store.d.ts.map +1 -0
  222. package/dist/types/adapters/postgres/executor.d.ts +48 -0
  223. package/dist/types/adapters/postgres/executor.d.ts.map +1 -0
  224. package/dist/types/adapters/postgres/index.d.ts +39 -0
  225. package/dist/types/adapters/postgres/index.d.ts.map +1 -0
  226. package/dist/types/adapters/postgres/key-store.d.ts +23 -0
  227. package/dist/types/adapters/postgres/key-store.d.ts.map +1 -0
  228. package/dist/types/adapters/postgres/method-store.d.ts +21 -0
  229. package/dist/types/adapters/postgres/method-store.d.ts.map +1 -0
  230. package/dist/types/adapters/postgres/migrations.d.ts +22 -0
  231. package/dist/types/adapters/postgres/migrations.d.ts.map +1 -0
  232. package/dist/types/adapters/postgres/passkey-credential-store.d.ts +48 -0
  233. package/dist/types/adapters/postgres/passkey-credential-store.d.ts.map +1 -0
  234. package/dist/types/adapters/postgres/session-store.d.ts +20 -0
  235. package/dist/types/adapters/postgres/session-store.d.ts.map +1 -0
  236. package/dist/types/adapters/postgres/token-store.d.ts +30 -0
  237. package/dist/types/adapters/postgres/token-store.d.ts.map +1 -0
  238. package/dist/types/client.d.ts +1 -1
  239. package/dist/types/client.d.ts.map +1 -1
  240. package/dist/types/domain/audit.d.ts +17 -0
  241. package/dist/types/domain/audit.d.ts.map +1 -0
  242. package/dist/types/domain/authorize.d.ts +125 -0
  243. package/dist/types/domain/authorize.d.ts.map +1 -0
  244. package/dist/types/domain/callback.d.ts +70 -0
  245. package/dist/types/domain/callback.d.ts.map +1 -0
  246. package/dist/types/domain/client-auth.d.ts +57 -0
  247. package/dist/types/domain/client-auth.d.ts.map +1 -0
  248. package/dist/types/domain/client-credentials.d.ts +52 -0
  249. package/dist/types/domain/client-credentials.d.ts.map +1 -0
  250. package/dist/types/domain/crypto.d.ts +53 -0
  251. package/dist/types/domain/crypto.d.ts.map +1 -0
  252. package/dist/types/domain/discovery.d.ts +44 -0
  253. package/dist/types/domain/discovery.d.ts.map +1 -0
  254. package/dist/types/domain/introspect.d.ts +71 -0
  255. package/dist/types/domain/introspect.d.ts.map +1 -0
  256. package/dist/types/domain/jwt.d.ts +48 -0
  257. package/dist/types/domain/jwt.d.ts.map +1 -0
  258. package/dist/types/domain/method-cache.d.ts +42 -0
  259. package/dist/types/domain/method-cache.d.ts.map +1 -0
  260. package/dist/types/domain/method-dispatch.d.ts +37 -0
  261. package/dist/types/domain/method-dispatch.d.ts.map +1 -0
  262. package/dist/types/domain/method-route.d.ts +77 -0
  263. package/dist/types/domain/method-route.d.ts.map +1 -0
  264. package/dist/types/domain/pkce.d.ts +15 -0
  265. package/dist/types/domain/pkce.d.ts.map +1 -0
  266. package/dist/types/domain/refresh.d.ts +43 -0
  267. package/dist/types/domain/refresh.d.ts.map +1 -0
  268. package/dist/types/domain/revoke.d.ts +61 -0
  269. package/dist/types/domain/revoke.d.ts.map +1 -0
  270. package/dist/types/domain/state-envelope.d.ts +30 -0
  271. package/dist/types/domain/state-envelope.d.ts.map +1 -0
  272. package/dist/types/domain/token-exchange.d.ts +67 -0
  273. package/dist/types/domain/token-exchange.d.ts.map +1 -0
  274. package/dist/types/domain/token.d.ts +100 -0
  275. package/dist/types/domain/token.d.ts.map +1 -0
  276. package/dist/types/domain/userinfo.d.ts +22 -0
  277. package/dist/types/domain/userinfo.d.ts.map +1 -0
  278. package/dist/types/http/context.d.ts +63 -0
  279. package/dist/types/http/context.d.ts.map +1 -0
  280. package/dist/types/http/cookies.d.ts +45 -0
  281. package/dist/types/http/cookies.d.ts.map +1 -0
  282. package/dist/types/http/errors.d.ts +36 -0
  283. package/dist/types/http/errors.d.ts.map +1 -0
  284. package/dist/types/http/handlers/authorize.d.ts +3 -0
  285. package/dist/types/http/handlers/authorize.d.ts.map +1 -0
  286. package/dist/types/http/handlers/callback.d.ts +3 -0
  287. package/dist/types/http/handlers/callback.d.ts.map +1 -0
  288. package/dist/types/http/handlers/metadata.d.ts +4 -0
  289. package/dist/types/http/handlers/metadata.d.ts.map +1 -0
  290. package/dist/types/http/handlers/method-route.d.ts +3 -0
  291. package/dist/types/http/handlers/method-route.d.ts.map +1 -0
  292. package/dist/types/http/handlers/revocation.d.ts +4 -0
  293. package/dist/types/http/handlers/revocation.d.ts.map +1 -0
  294. package/dist/types/http/handlers/token.d.ts +3 -0
  295. package/dist/types/http/handlers/token.d.ts.map +1 -0
  296. package/dist/types/http/handlers/userinfo.d.ts +3 -0
  297. package/dist/types/http/handlers/userinfo.d.ts.map +1 -0
  298. package/dist/types/http/middleware/error.d.ts +9 -0
  299. package/dist/types/http/middleware/error.d.ts.map +1 -0
  300. package/dist/types/http/middleware/tenant.d.ts +30 -0
  301. package/dist/types/http/middleware/tenant.d.ts.map +1 -0
  302. package/dist/types/http/resolver.d.ts +22 -0
  303. package/dist/types/http/resolver.d.ts.map +1 -0
  304. package/dist/types/http/router.d.ts +21 -0
  305. package/dist/types/http/router.d.ts.map +1 -0
  306. package/dist/types/http/schemas/authorize.d.ts +52 -0
  307. package/dist/types/http/schemas/authorize.d.ts.map +1 -0
  308. package/dist/types/http/schemas/revocation.d.ts +41 -0
  309. package/dist/types/http/schemas/revocation.d.ts.map +1 -0
  310. package/dist/types/http/schemas/token.d.ts +227 -0
  311. package/dist/types/http/schemas/token.d.ts.map +1 -0
  312. package/dist/types/index.d.ts +63 -13
  313. package/dist/types/index.d.ts.map +1 -1
  314. package/dist/types/methods/code.d.ts +96 -0
  315. package/dist/types/methods/code.d.ts.map +1 -0
  316. package/dist/types/methods/m2m.d.ts +41 -0
  317. package/dist/types/methods/m2m.d.ts.map +1 -0
  318. package/dist/types/methods/oauth2-factory.d.ts +133 -0
  319. package/dist/types/methods/oauth2-factory.d.ts.map +1 -0
  320. package/dist/types/methods/oauth2-generic.d.ts +75 -0
  321. package/dist/types/methods/oauth2-generic.d.ts.map +1 -0
  322. package/dist/types/methods/oidc-generic.d.ts +26 -0
  323. package/dist/types/methods/oidc-generic.d.ts.map +1 -0
  324. package/dist/types/methods/passkey.d.ts +106 -0
  325. package/dist/types/methods/passkey.d.ts.map +1 -0
  326. package/dist/types/methods/password-hash.d.ts +25 -0
  327. package/dist/types/methods/password-hash.d.ts.map +1 -0
  328. package/dist/types/methods/password.d.ts +70 -0
  329. package/dist/types/methods/password.d.ts.map +1 -0
  330. package/dist/types/methods/providers/apple.d.ts +29 -0
  331. package/dist/types/methods/providers/apple.d.ts.map +1 -0
  332. package/dist/types/methods/providers/cognito.d.ts +36 -0
  333. package/dist/types/methods/providers/cognito.d.ts.map +1 -0
  334. package/dist/types/methods/providers/discord.d.ts +22 -0
  335. package/dist/types/methods/providers/discord.d.ts.map +1 -0
  336. package/dist/types/methods/providers/facebook.d.ts +29 -0
  337. package/dist/types/methods/providers/facebook.d.ts.map +1 -0
  338. package/dist/types/methods/providers/github.d.ts +25 -0
  339. package/dist/types/methods/providers/github.d.ts.map +1 -0
  340. package/dist/types/methods/providers/google.d.ts +28 -0
  341. package/dist/types/methods/providers/google.d.ts.map +1 -0
  342. package/dist/types/methods/providers/index.d.ts +24 -0
  343. package/dist/types/methods/providers/index.d.ts.map +1 -0
  344. package/dist/types/methods/providers/jumpcloud.d.ts +22 -0
  345. package/dist/types/methods/providers/jumpcloud.d.ts.map +1 -0
  346. package/dist/types/methods/providers/keycloak.d.ts +30 -0
  347. package/dist/types/methods/providers/keycloak.d.ts.map +1 -0
  348. package/dist/types/methods/providers/linkedin.d.ts +22 -0
  349. package/dist/types/methods/providers/linkedin.d.ts.map +1 -0
  350. package/dist/types/methods/providers/microsoft.d.ts +30 -0
  351. package/dist/types/methods/providers/microsoft.d.ts.map +1 -0
  352. package/dist/types/methods/providers/slack.d.ts +25 -0
  353. package/dist/types/methods/providers/slack.d.ts.map +1 -0
  354. package/dist/types/methods/providers/spotify.d.ts +22 -0
  355. package/dist/types/methods/providers/spotify.d.ts.map +1 -0
  356. package/dist/types/methods/providers/twitch.d.ts +23 -0
  357. package/dist/types/methods/providers/twitch.d.ts.map +1 -0
  358. package/dist/types/methods/providers/x.d.ts +25 -0
  359. package/dist/types/methods/providers/x.d.ts.map +1 -0
  360. package/dist/types/methods/providers/yahoo.d.ts +22 -0
  361. package/dist/types/methods/providers/yahoo.d.ts.map +1 -0
  362. package/dist/types/pkce.d.ts +1 -2
  363. package/dist/types/pkce.d.ts.map +1 -1
  364. package/dist/types/ports/audit-log.d.ts +139 -0
  365. package/dist/types/ports/audit-log.d.ts.map +1 -0
  366. package/dist/types/ports/config-store.d.ts +32 -0
  367. package/dist/types/ports/config-store.d.ts.map +1 -0
  368. package/dist/types/ports/key-store.d.ts +98 -0
  369. package/dist/types/ports/key-store.d.ts.map +1 -0
  370. package/dist/types/ports/method-store.d.ts +29 -0
  371. package/dist/types/ports/method-store.d.ts.map +1 -0
  372. package/dist/types/ports/session-store.d.ts +82 -0
  373. package/dist/types/ports/session-store.d.ts.map +1 -0
  374. package/dist/types/ports/token-store.d.ts +93 -0
  375. package/dist/types/ports/token-store.d.ts.map +1 -0
  376. package/dist/types/types/authorization.d.ts +52 -0
  377. package/dist/types/types/authorization.d.ts.map +1 -0
  378. package/dist/types/types/error.d.ts +92 -0
  379. package/dist/types/types/error.d.ts.map +1 -0
  380. package/dist/types/types/flow.d.ts +87 -0
  381. package/dist/types/types/flow.d.ts.map +1 -0
  382. package/dist/types/types/idp.d.ts +234 -0
  383. package/dist/types/types/idp.d.ts.map +1 -0
  384. package/dist/types/types/method.d.ts +256 -0
  385. package/dist/types/types/method.d.ts.map +1 -0
  386. package/dist/types/types/picker.d.ts +31 -0
  387. package/dist/types/types/picker.d.ts.map +1 -0
  388. package/dist/types/types/result.d.ts +29 -0
  389. package/dist/types/types/result.d.ts.map +1 -0
  390. package/dist/types/types/subject.d.ts +47 -0
  391. package/dist/types/types/subject.d.ts.map +1 -0
  392. package/dist/types/types/tenant.d.ts +239 -0
  393. package/dist/types/types/tenant.d.ts.map +1 -0
  394. package/dist/types/types/token.d.ts +103 -0
  395. package/dist/types/types/token.d.ts.map +1 -0
  396. package/dist/types/ui/forms.d.ts +35 -0
  397. package/dist/types/ui/forms.d.ts.map +1 -0
  398. package/dist/types/ui/index.d.ts +14 -0
  399. package/dist/types/ui/index.d.ts.map +1 -0
  400. package/dist/types/ui/picker.d.ts +18 -0
  401. package/dist/types/ui/picker.d.ts.map +1 -0
  402. package/package.json +41 -6
  403. package/src/adapters/d1/audit-log.ts +32 -0
  404. package/src/adapters/d1/config-store.ts +67 -0
  405. package/src/adapters/d1/index.ts +41 -0
  406. package/src/adapters/d1/key-store.ts +218 -0
  407. package/src/adapters/d1/method-store.ts +103 -0
  408. package/src/adapters/d1/migrations.ts +89 -0
  409. package/src/adapters/d1/session-store.ts +230 -0
  410. package/src/adapters/d1/session.ts +38 -0
  411. package/src/adapters/d1/token-store.ts +251 -0
  412. package/src/adapters/d1/types.ts +53 -0
  413. package/src/adapters/durable-object/index.ts +23 -0
  414. package/src/adapters/durable-object/session-store.ts +227 -0
  415. package/src/adapters/durable-object/types.ts +25 -0
  416. package/src/adapters/dynamo/audit-log.ts +35 -0
  417. package/src/adapters/dynamo/client.ts +118 -0
  418. package/src/adapters/dynamo/config-store.ts +72 -0
  419. package/src/adapters/dynamo/index.ts +81 -0
  420. package/src/adapters/dynamo/key-store.ts +267 -0
  421. package/src/adapters/dynamo/method-store.ts +105 -0
  422. package/src/adapters/dynamo/passkey-credential-store.ts +132 -0
  423. package/src/adapters/dynamo/sdk.ts +189 -0
  424. package/src/adapters/dynamo/session-store.ts +229 -0
  425. package/src/adapters/dynamo/token-store.ts +248 -0
  426. package/src/adapters/kms/in-memory-backing.ts +36 -0
  427. package/src/adapters/kms/index.ts +39 -0
  428. package/src/adapters/kms/key-store.ts +176 -0
  429. package/src/adapters/kms/sdk.ts +39 -0
  430. package/src/adapters/kms/types.ts +61 -0
  431. package/src/adapters/kv/audit-log.ts +40 -0
  432. package/src/adapters/kv/config-store.ts +63 -0
  433. package/src/adapters/kv/index.ts +20 -0
  434. package/src/adapters/kv/method-store.ts +98 -0
  435. package/src/adapters/kv/types.ts +26 -0
  436. package/src/adapters/memory/audit-log.ts +28 -0
  437. package/src/adapters/memory/clock.ts +7 -0
  438. package/src/adapters/memory/config-store.ts +41 -0
  439. package/src/adapters/memory/index.ts +26 -0
  440. package/src/adapters/memory/key-store.ts +102 -0
  441. package/src/adapters/memory/method-store.ts +75 -0
  442. package/src/adapters/memory/passkey-credential-store.ts +97 -0
  443. package/src/adapters/memory/session-store.ts +128 -0
  444. package/src/adapters/memory/token-store.ts +165 -0
  445. package/src/adapters/postgres/audit-log.ts +34 -0
  446. package/src/adapters/postgres/config-store.ts +72 -0
  447. package/src/adapters/postgres/executor.ts +76 -0
  448. package/src/adapters/postgres/index.ts +60 -0
  449. package/src/adapters/postgres/key-store.ts +334 -0
  450. package/src/adapters/postgres/method-store.ts +104 -0
  451. package/src/adapters/postgres/migrations.ts +131 -0
  452. package/src/adapters/postgres/passkey-credential-store.ts +150 -0
  453. package/src/adapters/postgres/session-store.ts +216 -0
  454. package/src/adapters/postgres/token-store.ts +263 -0
  455. package/src/client.ts +50 -16
  456. package/src/domain/audit.ts +28 -0
  457. package/src/domain/authorize.ts +405 -0
  458. package/src/domain/callback.ts +263 -0
  459. package/src/domain/client-auth.ts +116 -0
  460. package/src/domain/client-credentials.ts +178 -0
  461. package/src/domain/crypto.ts +168 -0
  462. package/src/domain/discovery.ts +83 -0
  463. package/src/domain/introspect.ts +145 -0
  464. package/src/domain/jwt.ts +106 -0
  465. package/src/domain/method-cache.ts +220 -0
  466. package/src/domain/method-dispatch.ts +95 -0
  467. package/src/domain/method-route.ts +208 -0
  468. package/src/domain/pkce.ts +37 -0
  469. package/src/domain/refresh.ts +169 -0
  470. package/src/domain/revoke.ts +161 -0
  471. package/src/domain/state-envelope.ts +142 -0
  472. package/src/domain/token-exchange.ts +232 -0
  473. package/src/domain/token.ts +357 -0
  474. package/src/domain/userinfo.ts +56 -0
  475. package/src/http/context.ts +86 -0
  476. package/src/http/cookies.ts +167 -0
  477. package/src/http/errors.ts +98 -0
  478. package/src/http/handlers/authorize.ts +221 -0
  479. package/src/http/handlers/callback.ts +77 -0
  480. package/src/http/handlers/metadata.ts +44 -0
  481. package/src/http/handlers/method-route.ts +115 -0
  482. package/src/http/handlers/revocation.ts +151 -0
  483. package/src/http/handlers/token.ts +244 -0
  484. package/src/http/handlers/userinfo.ts +66 -0
  485. package/src/http/middleware/error.ts +26 -0
  486. package/src/http/middleware/tenant.ts +165 -0
  487. package/src/http/resolver.ts +34 -0
  488. package/src/http/router.ts +66 -0
  489. package/src/http/schemas/authorize.ts +58 -0
  490. package/src/http/schemas/revocation.ts +23 -0
  491. package/src/http/schemas/token.ts +85 -0
  492. package/src/index.ts +266 -20
  493. package/src/methods/code.ts +359 -0
  494. package/src/methods/m2m.ts +82 -0
  495. package/src/methods/oauth2-factory.ts +151 -0
  496. package/src/methods/oauth2-generic.ts +360 -0
  497. package/src/methods/oidc-generic.ts +109 -0
  498. package/src/methods/passkey.ts +419 -0
  499. package/src/methods/password-hash.ts +134 -0
  500. package/src/methods/password.ts +298 -0
  501. package/src/methods/providers/apple.ts +42 -0
  502. package/src/methods/providers/cognito.ts +55 -0
  503. package/src/methods/providers/discord.ts +37 -0
  504. package/src/methods/providers/facebook.ts +54 -0
  505. package/src/methods/providers/github.ts +42 -0
  506. package/src/methods/providers/google.ts +43 -0
  507. package/src/methods/providers/index.ts +23 -0
  508. package/src/methods/providers/jumpcloud.ts +36 -0
  509. package/src/methods/providers/keycloak.ts +42 -0
  510. package/src/methods/providers/linkedin.ts +37 -0
  511. package/src/methods/providers/microsoft.ts +42 -0
  512. package/src/methods/providers/slack.ts +42 -0
  513. package/src/methods/providers/spotify.ts +37 -0
  514. package/src/methods/providers/twitch.ts +38 -0
  515. package/src/methods/providers/x.ts +40 -0
  516. package/src/methods/providers/yahoo.ts +36 -0
  517. package/src/pkce.ts +20 -21
  518. package/src/ports/CONSISTENCY.md +88 -0
  519. package/src/ports/audit-log.ts +148 -0
  520. package/src/ports/config-store.ts +34 -0
  521. package/src/ports/key-store.ts +106 -0
  522. package/src/ports/method-store.ts +41 -0
  523. package/src/ports/session-store.ts +98 -0
  524. package/src/ports/token-store.ts +103 -0
  525. package/src/types/authorization.ts +53 -0
  526. package/src/types/error.ts +123 -0
  527. package/src/types/flow.ts +89 -0
  528. package/src/types/idp.ts +269 -0
  529. package/src/types/method.ts +270 -0
  530. package/src/types/picker.ts +32 -0
  531. package/src/types/result.ts +23 -0
  532. package/src/types/subject.ts +50 -0
  533. package/src/types/tenant.ts +248 -0
  534. package/src/types/token.ts +101 -0
  535. package/src/ui/forms.ts +289 -0
  536. package/src/ui/index.ts +14 -0
  537. package/src/ui/picker.ts +63 -0
  538. package/dist/esm/issuer.js +0 -691
  539. package/dist/esm/jwt.js +0 -16
  540. package/dist/esm/keys.js +0 -113
  541. package/dist/esm/provider/apple.js +0 -28
  542. package/dist/esm/provider/arctic.js +0 -43
  543. package/dist/esm/provider/code.js +0 -58
  544. package/dist/esm/provider/cognito.js +0 -16
  545. package/dist/esm/provider/discord.js +0 -15
  546. package/dist/esm/provider/facebook.js +0 -24
  547. package/dist/esm/provider/github.js +0 -15
  548. package/dist/esm/provider/google.js +0 -25
  549. package/dist/esm/provider/index.js +0 -3
  550. package/dist/esm/provider/jumpcloud.js +0 -15
  551. package/dist/esm/provider/keycloak.js +0 -15
  552. package/dist/esm/provider/linkedin.js +0 -15
  553. package/dist/esm/provider/m2m.js +0 -16
  554. package/dist/esm/provider/microsoft.js +0 -24
  555. package/dist/esm/provider/oauth2.js +0 -119
  556. package/dist/esm/provider/oidc.js +0 -69
  557. package/dist/esm/provider/passkey.js +0 -315
  558. package/dist/esm/provider/password.js +0 -306
  559. package/dist/esm/provider/provider.js +0 -10
  560. package/dist/esm/provider/slack.js +0 -15
  561. package/dist/esm/provider/spotify.js +0 -15
  562. package/dist/esm/provider/twitch.js +0 -15
  563. package/dist/esm/provider/x.js +0 -16
  564. package/dist/esm/provider/yahoo.js +0 -15
  565. package/dist/esm/random.js +0 -27
  566. package/dist/esm/storage/aws.js +0 -39
  567. package/dist/esm/storage/cloudflare.js +0 -42
  568. package/dist/esm/storage/dynamo.js +0 -116
  569. package/dist/esm/storage/memory.js +0 -88
  570. package/dist/esm/storage/storage.js +0 -36
  571. package/dist/esm/subject.js +0 -7
  572. package/dist/esm/ui/base.js +0 -407
  573. package/dist/esm/ui/code.js +0 -151
  574. package/dist/esm/ui/form.js +0 -43
  575. package/dist/esm/ui/icon.js +0 -92
  576. package/dist/esm/ui/passkey.js +0 -329
  577. package/dist/esm/ui/password.js +0 -338
  578. package/dist/esm/ui/select.js +0 -187
  579. package/dist/esm/ui/theme.js +0 -115
  580. package/dist/esm/util.js +0 -54
  581. package/dist/types/issuer.d.ts +0 -607
  582. package/dist/types/issuer.d.ts.map +0 -1
  583. package/dist/types/jwt.d.ts +0 -6
  584. package/dist/types/jwt.d.ts.map +0 -1
  585. package/dist/types/keys.d.ts +0 -18
  586. package/dist/types/keys.d.ts.map +0 -1
  587. package/dist/types/provider/apple.d.ts +0 -108
  588. package/dist/types/provider/apple.d.ts.map +0 -1
  589. package/dist/types/provider/arctic.d.ts +0 -16
  590. package/dist/types/provider/arctic.d.ts.map +0 -1
  591. package/dist/types/provider/code.d.ts +0 -74
  592. package/dist/types/provider/code.d.ts.map +0 -1
  593. package/dist/types/provider/cognito.d.ts +0 -64
  594. package/dist/types/provider/cognito.d.ts.map +0 -1
  595. package/dist/types/provider/discord.d.ts +0 -38
  596. package/dist/types/provider/discord.d.ts.map +0 -1
  597. package/dist/types/provider/facebook.d.ts +0 -74
  598. package/dist/types/provider/facebook.d.ts.map +0 -1
  599. package/dist/types/provider/github.d.ts +0 -38
  600. package/dist/types/provider/github.d.ts.map +0 -1
  601. package/dist/types/provider/google.d.ts +0 -74
  602. package/dist/types/provider/google.d.ts.map +0 -1
  603. package/dist/types/provider/index.d.ts +0 -4
  604. package/dist/types/provider/index.d.ts.map +0 -1
  605. package/dist/types/provider/jumpcloud.d.ts +0 -38
  606. package/dist/types/provider/jumpcloud.d.ts.map +0 -1
  607. package/dist/types/provider/keycloak.d.ts +0 -67
  608. package/dist/types/provider/keycloak.d.ts.map +0 -1
  609. package/dist/types/provider/linkedin.d.ts +0 -6
  610. package/dist/types/provider/linkedin.d.ts.map +0 -1
  611. package/dist/types/provider/m2m.d.ts +0 -34
  612. package/dist/types/provider/m2m.d.ts.map +0 -1
  613. package/dist/types/provider/microsoft.d.ts +0 -89
  614. package/dist/types/provider/microsoft.d.ts.map +0 -1
  615. package/dist/types/provider/oauth2.d.ts +0 -133
  616. package/dist/types/provider/oauth2.d.ts.map +0 -1
  617. package/dist/types/provider/oidc.d.ts +0 -91
  618. package/dist/types/provider/oidc.d.ts.map +0 -1
  619. package/dist/types/provider/passkey.d.ts +0 -143
  620. package/dist/types/provider/passkey.d.ts.map +0 -1
  621. package/dist/types/provider/password.d.ts +0 -210
  622. package/dist/types/provider/password.d.ts.map +0 -1
  623. package/dist/types/provider/provider.d.ts +0 -29
  624. package/dist/types/provider/provider.d.ts.map +0 -1
  625. package/dist/types/provider/slack.d.ts +0 -59
  626. package/dist/types/provider/slack.d.ts.map +0 -1
  627. package/dist/types/provider/spotify.d.ts +0 -38
  628. package/dist/types/provider/spotify.d.ts.map +0 -1
  629. package/dist/types/provider/twitch.d.ts +0 -38
  630. package/dist/types/provider/twitch.d.ts.map +0 -1
  631. package/dist/types/provider/x.d.ts +0 -38
  632. package/dist/types/provider/x.d.ts.map +0 -1
  633. package/dist/types/provider/yahoo.d.ts +0 -38
  634. package/dist/types/provider/yahoo.d.ts.map +0 -1
  635. package/dist/types/random.d.ts +0 -3
  636. package/dist/types/random.d.ts.map +0 -1
  637. package/dist/types/storage/aws.d.ts +0 -4
  638. package/dist/types/storage/aws.d.ts.map +0 -1
  639. package/dist/types/storage/cloudflare.d.ts +0 -34
  640. package/dist/types/storage/cloudflare.d.ts.map +0 -1
  641. package/dist/types/storage/dynamo.d.ts +0 -65
  642. package/dist/types/storage/dynamo.d.ts.map +0 -1
  643. package/dist/types/storage/memory.d.ts +0 -49
  644. package/dist/types/storage/memory.d.ts.map +0 -1
  645. package/dist/types/storage/storage.d.ts +0 -15
  646. package/dist/types/storage/storage.d.ts.map +0 -1
  647. package/dist/types/subject.d.ts +0 -122
  648. package/dist/types/subject.d.ts.map +0 -1
  649. package/dist/types/ui/base.d.ts +0 -5
  650. package/dist/types/ui/base.d.ts.map +0 -1
  651. package/dist/types/ui/code.d.ts +0 -104
  652. package/dist/types/ui/code.d.ts.map +0 -1
  653. package/dist/types/ui/form.d.ts +0 -6
  654. package/dist/types/ui/form.d.ts.map +0 -1
  655. package/dist/types/ui/icon.d.ts +0 -6
  656. package/dist/types/ui/icon.d.ts.map +0 -1
  657. package/dist/types/ui/passkey.d.ts +0 -5
  658. package/dist/types/ui/passkey.d.ts.map +0 -1
  659. package/dist/types/ui/password.d.ts +0 -139
  660. package/dist/types/ui/password.d.ts.map +0 -1
  661. package/dist/types/ui/select.d.ts +0 -55
  662. package/dist/types/ui/select.d.ts.map +0 -1
  663. package/dist/types/ui/theme.d.ts +0 -207
  664. package/dist/types/ui/theme.d.ts.map +0 -1
  665. package/dist/types/util.d.ts +0 -8
  666. package/dist/types/util.d.ts.map +0 -1
  667. package/src/css.d.ts +0 -4
  668. package/src/issuer.ts +0 -1628
  669. package/src/jwt.ts +0 -17
  670. package/src/keys.ts +0 -139
  671. package/src/provider/apple.ts +0 -127
  672. package/src/provider/arctic.ts +0 -66
  673. package/src/provider/code.ts +0 -227
  674. package/src/provider/cognito.ts +0 -74
  675. package/src/provider/discord.ts +0 -45
  676. package/src/provider/facebook.ts +0 -84
  677. package/src/provider/github.ts +0 -45
  678. package/src/provider/google.ts +0 -85
  679. package/src/provider/index.ts +0 -3
  680. package/src/provider/jumpcloud.ts +0 -45
  681. package/src/provider/keycloak.ts +0 -75
  682. package/src/provider/linkedin.ts +0 -12
  683. package/src/provider/m2m.ts +0 -56
  684. package/src/provider/microsoft.ts +0 -100
  685. package/src/provider/oauth2.ts +0 -297
  686. package/src/provider/oidc.ts +0 -179
  687. package/src/provider/passkey.ts +0 -655
  688. package/src/provider/password.ts +0 -672
  689. package/src/provider/provider.ts +0 -33
  690. package/src/provider/slack.ts +0 -67
  691. package/src/provider/spotify.ts +0 -45
  692. package/src/provider/twitch.ts +0 -45
  693. package/src/provider/x.ts +0 -46
  694. package/src/provider/yahoo.ts +0 -45
  695. package/src/random.ts +0 -24
  696. package/src/storage/aws.ts +0 -59
  697. package/src/storage/cloudflare.ts +0 -77
  698. package/src/storage/dynamo.ts +0 -193
  699. package/src/storage/memory.ts +0 -135
  700. package/src/storage/storage.ts +0 -46
  701. package/src/subject.ts +0 -130
  702. package/src/ui/base.tsx +0 -118
  703. package/src/ui/code.tsx +0 -215
  704. package/src/ui/form.tsx +0 -40
  705. package/src/ui/icon.tsx +0 -95
  706. package/src/ui/passkey.tsx +0 -321
  707. package/src/ui/password.tsx +0 -405
  708. package/src/ui/select.tsx +0 -221
  709. package/src/ui/theme.ts +0 -319
  710. package/src/ui/ui.css +0 -252
  711. package/src/util.ts +0 -58
  712. /package/dist/esm/{css.d.js → adapters/d1/types.js} +0 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * RFC 7009 `/revoke` and RFC 7662 `/introspect` HTTP shims.
3
+ *
4
+ * Both accept `application/x-www-form-urlencoded`. Client credentials
5
+ * may ride in the form body (`client_id`, `client_secret`) or in an
6
+ * `Authorization: Basic` header (RFC 6749 §2.3.1); the header wins when
7
+ * both are present.
8
+ *
9
+ * Revoke: anonymous calls are permitted for tokens issued to public
10
+ * clients (RFC 7009 §2.1). Confidential-client tokens require auth.
11
+ *
12
+ * Introspect: client auth is REQUIRED (RFC 7662 §2.1). Anonymous calls
13
+ * are rejected at this layer with `invalid_client`.
14
+ */
15
+ import { resolveClientCredentials } from "../../domain/client-auth"
16
+ import { introspect } from "../../domain/introspect"
17
+ import { revokeToken } from "../../domain/revoke"
18
+ import { authError } from "../../types/error"
19
+ import { isErr } from "../../types/result"
20
+
21
+ import type { HttpContext, HttpDeps } from "../context"
22
+ import { tokenEndpointErrorResponse } from "../errors"
23
+ import { injectResolverHints } from "../resolver"
24
+ import { introspectBodySchema, revokeBodySchema } from "../schemas/revocation"
25
+
26
+ export function makeRevokeHandler(deps: HttpDeps) {
27
+ return async (c: HttpContext): Promise<Response> => {
28
+ const body = await readForm(c.req.raw)
29
+ if (!body) {
30
+ return tokenEndpointErrorResponse(
31
+ authError.invalidRequest(
32
+ "body must be application/x-www-form-urlencoded",
33
+ ),
34
+ )
35
+ }
36
+ const parsed = revokeBodySchema.safeParse(
37
+ Object.fromEntries(body.entries()),
38
+ )
39
+ if (!parsed.success) {
40
+ return tokenEndpointErrorResponse(
41
+ authError.invalidRequest(parsed.error.issues[0]?.message ?? "invalid"),
42
+ )
43
+ }
44
+ const creds = resolveClientCredentials({
45
+ authorizationHeader: c.req.header("authorization") ?? null,
46
+ bodyClientId: parsed.data.client_id,
47
+ bodyClientSecret: parsed.data.client_secret,
48
+ })
49
+ const res = await revokeToken(
50
+ {
51
+ token: parsed.data.token,
52
+ ...(parsed.data.token_type_hint
53
+ ? { tokenTypeHint: parsed.data.token_type_hint }
54
+ : {}),
55
+ ...(creds ? { clientId: creds.clientId } : {}),
56
+ ...(creds?.clientSecret !== undefined
57
+ ? { clientSecret: creds.clientSecret }
58
+ : {}),
59
+ },
60
+ {
61
+ tokenStore: deps.tokenStore,
62
+ configStore: deps.configStore,
63
+ ...(deps.auditLog ? { auditLog: deps.auditLog } : {}),
64
+ clock: deps.clock,
65
+ },
66
+ )
67
+ if (isErr(res)) return tokenEndpointErrorResponse(res.error)
68
+ // RFC 7009 §2.2: success returns 200 with empty body.
69
+ return new Response(null, {
70
+ status: 200,
71
+ headers: { "cache-control": "no-store" },
72
+ })
73
+ }
74
+ }
75
+
76
+ export function makeIntrospectHandler(deps: HttpDeps) {
77
+ return async (c: HttpContext): Promise<Response> => {
78
+ const body = await readForm(c.req.raw)
79
+ if (!body) {
80
+ return tokenEndpointErrorResponse(
81
+ authError.invalidRequest(
82
+ "body must be application/x-www-form-urlencoded",
83
+ ),
84
+ )
85
+ }
86
+ const parsed = introspectBodySchema.safeParse(
87
+ Object.fromEntries(body.entries()),
88
+ )
89
+ if (!parsed.success) {
90
+ return tokenEndpointErrorResponse(
91
+ authError.invalidRequest(parsed.error.issues[0]?.message ?? "invalid"),
92
+ )
93
+ }
94
+ const creds = resolveClientCredentials({
95
+ authorizationHeader: c.req.header("authorization") ?? null,
96
+ bodyClientId: parsed.data.client_id,
97
+ bodyClientSecret: parsed.data.client_secret,
98
+ })
99
+ if (!creds) {
100
+ // RFC 7662 §2.1 — endpoint MUST require some form of auth.
101
+ return tokenEndpointErrorResponse(
102
+ authError.invalidClient("introspection requires client authentication"),
103
+ )
104
+ }
105
+ // Resolve the presenter's tenant from the request the same way the
106
+ // m2m grant does — by injecting client_id into the URL so a
107
+ // canonical search-param resolver works for introspect too.
108
+ const tenantRes = await deps.resolveTenant(
109
+ injectResolverHints(c.req.raw, { client_id: creds.clientId }),
110
+ )
111
+ if (isErr(tenantRes)) {
112
+ return tokenEndpointErrorResponse(
113
+ authError.invalidClient(`unknown client "${creds.clientId}"`),
114
+ )
115
+ }
116
+ const res = await introspect(
117
+ {
118
+ token: parsed.data.token,
119
+ ...(parsed.data.token_type_hint
120
+ ? { tokenTypeHint: parsed.data.token_type_hint }
121
+ : {}),
122
+ clientId: creds.clientId,
123
+ ...(creds.clientSecret !== undefined
124
+ ? { clientSecret: creds.clientSecret }
125
+ : {}),
126
+ presenterTenantId: tenantRes.value,
127
+ },
128
+ {
129
+ keyStore: deps.keyStore,
130
+ configStore: deps.configStore,
131
+ issuerUrl: c.get("issuerUrl"),
132
+ },
133
+ )
134
+ if (isErr(res)) return tokenEndpointErrorResponse(res.error)
135
+ return new Response(JSON.stringify(res.value), {
136
+ status: 200,
137
+ headers: {
138
+ "content-type": "application/json",
139
+ "cache-control": "no-store",
140
+ },
141
+ })
142
+ }
143
+ }
144
+
145
+ async function readForm(req: Request): Promise<URLSearchParams | null> {
146
+ const ct = req.headers.get("content-type") ?? ""
147
+ if (!ct.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
148
+ return null
149
+ }
150
+ return new URLSearchParams(await req.text())
151
+ }
@@ -0,0 +1,244 @@
1
+ /**
2
+ * `POST /token` handler.
3
+ *
4
+ * Accepts `application/x-www-form-urlencoded` (RFC 6749 §3.2). Discriminates
5
+ * on `grant_type`:
6
+ * - `authorization_code` → `exchangeCode`
7
+ * - `refresh_token` → `refreshTokens`
8
+ *
9
+ * `client_credentials` arrives in Phase 5 alongside the m2m method.
10
+ *
11
+ * Client authentication: secrets can ride either in the form body
12
+ * (`client_secret`) or in the `Authorization: Basic` header. Both are
13
+ * accepted; the header takes precedence.
14
+ *
15
+ * The token endpoint does NOT consult the tenant middleware — every code /
16
+ * refresh token carries its tenant on its payload, so the auth-code or
17
+ * refresh-token snapshot is authoritative.
18
+ */
19
+ import { clientCredentialsGrant } from "../../domain/client-credentials"
20
+ import { exchangeCode } from "../../domain/token"
21
+ import { exchangeToken } from "../../domain/token-exchange"
22
+ import { refreshTokens } from "../../domain/refresh"
23
+ import { isErr } from "../../types/result"
24
+ import { authError } from "../../types/error"
25
+
26
+ import type { HttpContext, HttpDeps } from "../context"
27
+ import { tokenEndpointErrorResponse } from "../errors"
28
+ import { injectResolverHints } from "../resolver"
29
+ import { tokenRequestSchema } from "../schemas/token"
30
+
31
+ export function makeTokenHandler(deps: HttpDeps) {
32
+ return async (c: HttpContext): Promise<Response> => {
33
+ const body = await readFormBody(c.req.raw)
34
+ if (!body) {
35
+ return tokenEndpointErrorResponse(
36
+ authError.invalidRequest(
37
+ "body must be application/x-www-form-urlencoded",
38
+ ),
39
+ )
40
+ }
41
+
42
+ const basic = parseBasicAuth(c.req.header("authorization") ?? null)
43
+ if (basic) {
44
+ body.set("client_id", basic.id)
45
+ body.set("client_secret", basic.secret)
46
+ }
47
+
48
+ const parsed = tokenRequestSchema.safeParse(
49
+ Object.fromEntries(body.entries()),
50
+ )
51
+ if (!parsed.success) {
52
+ const first = parsed.error.issues[0]
53
+ // RFC 6749 §5.2 maps grant_type problems to `unsupported_grant_type`.
54
+ if (first?.path[0] === "grant_type") {
55
+ return tokenEndpointErrorResponse(
56
+ authError.unsupportedGrantType(
57
+ first.message ?? "unsupported grant_type",
58
+ ),
59
+ )
60
+ }
61
+ return tokenEndpointErrorResponse(
62
+ authError.invalidRequest(first?.message ?? "invalid request"),
63
+ )
64
+ }
65
+ const req = parsed.data
66
+
67
+ if (req.grant_type === "authorization_code") {
68
+ const result = await exchangeCode(
69
+ {
70
+ grantType: "authorization_code",
71
+ code: req.code,
72
+ redirectUri: req.redirect_uri,
73
+ clientId: req.client_id,
74
+ ...(req.client_secret !== undefined
75
+ ? { clientSecret: req.client_secret }
76
+ : {}),
77
+ ...(req.code_verifier !== undefined
78
+ ? { codeVerifier: req.code_verifier }
79
+ : {}),
80
+ },
81
+ {
82
+ configStore: deps.configStore,
83
+ tokenStore: deps.tokenStore,
84
+ keyStore: deps.keyStore,
85
+ ...(deps.auditLog ? { auditLog: deps.auditLog } : {}),
86
+ success: deps.success,
87
+ ...(deps.persistUpstreamTokens
88
+ ? { persistUpstreamTokens: deps.persistUpstreamTokens }
89
+ : {}),
90
+ issuerUrl: c.get("issuerUrl"),
91
+ clock: deps.clock,
92
+ },
93
+ )
94
+ if (isErr(result)) return tokenEndpointErrorResponse(result.error)
95
+ return jsonResponse(result.value)
96
+ }
97
+
98
+ if (req.grant_type === "client_credentials") {
99
+ // Resolve tenant — client_credentials carries no auth code, so we
100
+ // call the user-supplied resolver against the /token request. The
101
+ // canonical resolver pattern (INTEGRATION.md §5.1) reads `client_id`
102
+ // from URL search params, but the m2m grant carries client_id in the
103
+ // form body / Basic auth — never the URL. Inject the parsed
104
+ // `client_id` into a synthesized request so resolvers using the
105
+ // canonical pattern work for m2m without an extra hook.
106
+ const tenantRes = await deps.resolveTenant(
107
+ injectResolverHints(c.req.raw, { client_id: req.client_id }),
108
+ )
109
+ if (isErr(tenantRes)) {
110
+ return tokenEndpointErrorResponse(tenantRes.error)
111
+ }
112
+ const params: Record<string, string> = {}
113
+ for (const [k, v] of body.entries()) {
114
+ if (typeof v === "string") params[k] = v
115
+ }
116
+ const result = await clientCredentialsGrant(
117
+ {
118
+ grantType: "client_credentials",
119
+ clientId: req.client_id,
120
+ clientSecret: req.client_secret,
121
+ ...(req.scope !== undefined ? { scope: req.scope } : {}),
122
+ params,
123
+ },
124
+ {
125
+ configStore: deps.configStore,
126
+ tokenStore: deps.tokenStore,
127
+ keyStore: deps.keyStore,
128
+ ...(deps.auditLog ? { auditLog: deps.auditLog } : {}),
129
+ methodCache: deps.methodCache,
130
+ success: deps.success,
131
+ ...(deps.persistUpstreamTokens
132
+ ? { persistUpstreamTokens: deps.persistUpstreamTokens }
133
+ : {}),
134
+ issuerUrl: c.get("issuerUrl"),
135
+ clock: deps.clock,
136
+ },
137
+ tenantRes.value,
138
+ )
139
+ if (isErr(result)) return tokenEndpointErrorResponse(result.error)
140
+ return jsonResponse(result.value)
141
+ }
142
+
143
+ if (req.grant_type === "refresh_token") {
144
+ const refreshResult = await refreshTokens(
145
+ {
146
+ grantType: "refresh_token",
147
+ refreshToken: req.refresh_token,
148
+ ...(req.scope !== undefined ? { scope: req.scope } : {}),
149
+ ...(req.client_id !== undefined ? { clientId: req.client_id } : {}),
150
+ ...(req.client_secret !== undefined
151
+ ? { clientSecret: req.client_secret }
152
+ : {}),
153
+ },
154
+ {
155
+ configStore: deps.configStore,
156
+ tokenStore: deps.tokenStore,
157
+ keyStore: deps.keyStore,
158
+ ...(deps.auditLog ? { auditLog: deps.auditLog } : {}),
159
+ issuerUrl: c.get("issuerUrl"),
160
+ clock: deps.clock,
161
+ },
162
+ )
163
+ if (isErr(refreshResult))
164
+ return tokenEndpointErrorResponse(refreshResult.error)
165
+ return jsonResponse(refreshResult.value)
166
+ }
167
+
168
+ // RFC 8693 token-exchange. Delegation (actor_token) is out of scope;
169
+ // reject up front so we don't silently accept an actor and ignore it.
170
+ if (req.actor_token !== undefined) {
171
+ return tokenEndpointErrorResponse(
172
+ authError.invalidRequest(
173
+ "actor_token (delegation) is not supported; only impersonation / audience-switch is in scope",
174
+ ),
175
+ )
176
+ }
177
+ const exchangeResult = await exchangeToken(
178
+ {
179
+ grantType: req.grant_type,
180
+ subjectToken: req.subject_token,
181
+ audience: req.audience,
182
+ ...(req.scope !== undefined ? { scope: req.scope } : {}),
183
+ ...(req.client_id !== undefined ? { clientId: req.client_id } : {}),
184
+ ...(req.client_secret !== undefined
185
+ ? { clientSecret: req.client_secret }
186
+ : {}),
187
+ },
188
+ {
189
+ configStore: deps.configStore,
190
+ tokenStore: deps.tokenStore,
191
+ keyStore: deps.keyStore,
192
+ ...(deps.auditLog ? { auditLog: deps.auditLog } : {}),
193
+ ...(deps.exchangeAudience
194
+ ? { exchangeAudience: deps.exchangeAudience }
195
+ : {}),
196
+ issuerUrl: c.get("issuerUrl"),
197
+ clock: deps.clock,
198
+ },
199
+ )
200
+ if (isErr(exchangeResult)) {
201
+ return tokenEndpointErrorResponse(exchangeResult.error)
202
+ }
203
+ return jsonResponse(exchangeResult.value)
204
+ }
205
+ }
206
+
207
+ function jsonResponse(body: unknown): Response {
208
+ return new Response(JSON.stringify(body), {
209
+ status: 200,
210
+ headers: {
211
+ "content-type": "application/json",
212
+ "cache-control": "no-store",
213
+ pragma: "no-cache",
214
+ },
215
+ })
216
+ }
217
+
218
+ async function readFormBody(req: Request): Promise<URLSearchParams | null> {
219
+ const ct = req.headers.get("content-type") ?? ""
220
+ if (!ct.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
221
+ return null
222
+ }
223
+ const text = await req.text()
224
+ return new URLSearchParams(text)
225
+ }
226
+
227
+ function parseBasicAuth(
228
+ header: string | null,
229
+ ): { id: string; secret: string } | null {
230
+ if (!header) return null
231
+ const m = /^Basic\s+(.+)$/i.exec(header)
232
+ if (!m || !m[1]) return null
233
+ try {
234
+ const decoded = atob(m[1])
235
+ const colon = decoded.indexOf(":")
236
+ if (colon === -1) return null
237
+ return {
238
+ id: decodeURIComponent(decoded.slice(0, colon)),
239
+ secret: decodeURIComponent(decoded.slice(colon + 1)),
240
+ }
241
+ } catch {
242
+ return null
243
+ }
244
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * OIDC `/userinfo` handler (OIDC Core §5.3). Accepts `GET` or `POST` per
3
+ * the spec.
4
+ */
5
+ import { userinfo } from "../../domain/userinfo"
6
+ import { isErr } from "../../types/result"
7
+
8
+ import type { HttpContext, HttpDeps } from "../context"
9
+
10
+ export function makeUserinfoHandler(deps: HttpDeps) {
11
+ return async (c: HttpContext): Promise<Response> => {
12
+ const bearer = extractBearer(c.req.header("authorization") ?? null)
13
+ if (!bearer) {
14
+ const r = new Response(
15
+ JSON.stringify({
16
+ error: "invalid_token",
17
+ error_description: "missing bearer token",
18
+ }),
19
+ {
20
+ status: 401,
21
+ headers: {
22
+ "content-type": "application/json",
23
+ "www-authenticate": 'Bearer realm="userinfo"',
24
+ },
25
+ },
26
+ )
27
+ return r
28
+ }
29
+
30
+ const res = await userinfo(bearer, {
31
+ keyStore: deps.keyStore,
32
+ issuerUrl: c.get("issuerUrl"),
33
+ })
34
+ if (isErr(res)) {
35
+ // OIDC userinfo returns 401 on invalid token (vs. 400 elsewhere).
36
+ const err = res.error
37
+ return new Response(
38
+ JSON.stringify({
39
+ error: "invalid_token",
40
+ error_description: err.description,
41
+ }),
42
+ {
43
+ status: 401,
44
+ headers: {
45
+ "content-type": "application/json",
46
+ "www-authenticate": `Bearer error="invalid_token"`,
47
+ },
48
+ },
49
+ )
50
+ }
51
+
52
+ return new Response(JSON.stringify(res.value), {
53
+ status: 200,
54
+ headers: {
55
+ "content-type": "application/json",
56
+ "cache-control": "no-store",
57
+ },
58
+ })
59
+ }
60
+ }
61
+
62
+ function extractBearer(header: string | null): string | null {
63
+ if (!header) return null
64
+ const m = /^Bearer\s+(.+)$/i.exec(header)
65
+ return m?.[1] ?? null
66
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Global error middleware. Catches thrown values and serializes them as
3
+ * OAuth-compliant responses. Inside handlers we route through `Result<T,
4
+ * AuthError>` instead — this is the last-resort net for unexpected throws.
5
+ */
6
+ import type { MiddlewareHandler } from "hono"
7
+
8
+ import { authError } from "../../types/error"
9
+
10
+ import type { HttpDeps, HttpEnv } from "../context"
11
+ import { tokenEndpointErrorResponse } from "../errors"
12
+
13
+ export function errorMiddleware(_deps: HttpDeps): MiddlewareHandler<HttpEnv> {
14
+ return async (_c, next) => {
15
+ try {
16
+ await next()
17
+ } catch (e) {
18
+ return tokenEndpointErrorResponse(
19
+ authError.serverError(
20
+ e instanceof Error ? e.message : "unexpected error",
21
+ e,
22
+ ),
23
+ )
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Tenant resolution + callback-recovery middleware.
3
+ *
4
+ * Phase 3 ships the mac-state recovery path. Mechanisms #2 (partitioned
5
+ * host) and #3 (`flowId`-in-URI) are scaffolded but not yet plumbed end-to-
6
+ * end (per plan §"Phase 2 — Deferred"); the framework currently falls back
7
+ * to `resolveTenant` when the state envelope is absent or invalid, so users
8
+ * who want partitioned-host deployments can implement the lookup inside
9
+ * their own `resolveTenant`.
10
+ *
11
+ * Order on `/cb/*`:
12
+ * 1. If `state` MAC-verifies → `mac-state`. `resolveTenant` is NOT called.
13
+ * 2. Else fall through to `resolveTenant` (host-plus-* deployments do the
14
+ * host inspection there).
15
+ *
16
+ * Order on all other paths: `resolveTenant` directly.
17
+ */
18
+ import type { MiddlewareHandler } from "hono"
19
+
20
+ import { verifyStateEnvelope } from "../../domain/state-envelope"
21
+ import { isErr } from "../../types/result"
22
+ import type {
23
+ TenantConfig,
24
+ TenantContext,
25
+ TenantId,
26
+ TenantRecovery,
27
+ } from "../../types/tenant"
28
+
29
+ import { parseCookieHeader } from "../cookies"
30
+ import type { HttpDeps, HttpEnv } from "../context"
31
+ import {
32
+ authorizeDirectErrorResponse,
33
+ tokenEndpointErrorResponse,
34
+ } from "../errors"
35
+ import { authError } from "../../types/error"
36
+
37
+ function isCallbackPath(pathname: string): boolean {
38
+ return pathname.startsWith("/cb/")
39
+ }
40
+
41
+ /**
42
+ * Initial pass — parse cookies + resolve issuer URL. Runs unconditionally.
43
+ */
44
+ export function bootstrapMiddleware(
45
+ deps: HttpDeps,
46
+ ): MiddlewareHandler<HttpEnv> {
47
+ return async (c, next) => {
48
+ const cookies = parseCookieHeader(c.req.header("cookie") ?? null)
49
+ c.set("cookies", cookies)
50
+ c.set("issuerUrl", deps.resolveIssuer(c.req.raw))
51
+ c.set("tenant", null)
52
+ c.set("recovery", null)
53
+ await next()
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Tenant + recovery resolution middleware. Mount on routes that need a
59
+ * tenant in scope (`/authorize`, method dispatch, `/cb/*`). Token endpoints
60
+ * derive tenant from the auth code's snapshot — they skip this middleware.
61
+ */
62
+ export function tenantMiddleware(deps: HttpDeps): MiddlewareHandler<HttpEnv> {
63
+ return async (c, next) => {
64
+ const url = new URL(c.req.url)
65
+
66
+ if (isCallbackPath(url.pathname)) {
67
+ const recovery = await runCallbackRecovery(c.req.raw, deps)
68
+ c.set("recovery", recovery)
69
+ if (recovery.kind !== "fresh-request") {
70
+ const cfg = await deps.configStore.getTenantConfig(recovery.tenantId)
71
+ if (isErr(cfg)) {
72
+ return tokenEndpointErrorResponse(cfg.error)
73
+ }
74
+ const customCb = deps.buildCustomContext
75
+ ? await deps.buildCustomContext(c.req.raw)
76
+ : {}
77
+ c.set(
78
+ "tenant",
79
+ buildTenantContext(c.req.raw, recovery.tenantId, cfg.value, customCb),
80
+ )
81
+ return next()
82
+ }
83
+ }
84
+
85
+ const resolved = await deps.resolveTenant(c.req.raw)
86
+ if (isErr(resolved)) {
87
+ // For /authorize, surface as plain text (open-redirector defense — we
88
+ // don't have a verified RP yet). For other paths, JSON suffices.
89
+ if (url.pathname === "/authorize") {
90
+ return authorizeDirectErrorResponse(resolved.error)
91
+ }
92
+ return tokenEndpointErrorResponse(resolved.error)
93
+ }
94
+ const tenantId = resolved.value
95
+ const cfg = await deps.configStore.getTenantConfig(tenantId)
96
+ if (isErr(cfg)) {
97
+ const err =
98
+ cfg.error.code === "tenant_not_found"
99
+ ? authError.invalidRequest(cfg.error.description, "tenant")
100
+ : cfg.error
101
+ if (url.pathname === "/authorize") {
102
+ return authorizeDirectErrorResponse(err)
103
+ }
104
+ return tokenEndpointErrorResponse(err)
105
+ }
106
+ const custom = deps.buildCustomContext
107
+ ? await deps.buildCustomContext(c.req.raw)
108
+ : {}
109
+ c.set("tenant", buildTenantContext(c.req.raw, tenantId, cfg.value, custom))
110
+ await next()
111
+ }
112
+ }
113
+
114
+ function buildTenantContext(
115
+ req: Request,
116
+ id: TenantId,
117
+ config: TenantConfig,
118
+ custom: Record<string, unknown>,
119
+ ): TenantContext {
120
+ return {
121
+ id,
122
+ config,
123
+ request: { raw: req, custom },
124
+ }
125
+ }
126
+
127
+ async function runCallbackRecovery(
128
+ req: Request,
129
+ deps: HttpDeps,
130
+ ): Promise<TenantRecovery> {
131
+ const state = await extractStateParam(req)
132
+ if (state) {
133
+ const env = await verifyStateEnvelope(state, deps.stateKeys)
134
+ if (env.ok) {
135
+ return {
136
+ kind: "mac-state",
137
+ tenantId: env.value.tenantId,
138
+ flowId: env.value.flowId,
139
+ }
140
+ }
141
+ }
142
+ return { kind: "fresh-request" }
143
+ }
144
+
145
+ /**
146
+ * Pull `state` from the query for GET callbacks, or from a form body for
147
+ * POST callbacks (Apple's `response_mode=form_post`). The body is cloned
148
+ * so the handler can still read it.
149
+ */
150
+ async function extractStateParam(req: Request): Promise<string | null> {
151
+ const url = new URL(req.url)
152
+ const fromQuery = url.searchParams.get("state")
153
+ if (fromQuery) return fromQuery
154
+ if (req.method !== "POST") return null
155
+ const ct = req.headers.get("content-type") ?? ""
156
+ if (!ct.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
157
+ return null
158
+ }
159
+ try {
160
+ const text = await req.clone().text()
161
+ return new URLSearchParams(text).get("state")
162
+ } catch {
163
+ return null
164
+ }
165
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Helpers that prepare a `Request` for the host-supplied
3
+ * `IdPOptions.resolveTenant` hook.
4
+ *
5
+ * The canonical resolver reads `client_id` from URL search params
6
+ * (INTEGRATION.md §5.1). On endpoints where `client_id` is carried in
7
+ * the form body / Basic-auth header rather than the URL (m2m at
8
+ * `/token`, introspect at `/introspect`, revoke at `/revoke`) the
9
+ * framework parses the body first and then injects the parsed
10
+ * `client_id` into a synthesized request so the resolver still sees
11
+ * what it expects.
12
+ */
13
+
14
+ /**
15
+ * Build a new `Request` whose URL search params carry the supplied
16
+ * resolver hints. Existing query params win — hosts can still override
17
+ * via the URL. Headers are copied so Basic-auth-based resolvers still
18
+ * see the original `Authorization`. The body is intentionally dropped:
19
+ * the original is already consumed by the handler and resolvers must
20
+ * not depend on body state.
21
+ */
22
+ export function injectResolverHints(
23
+ original: Request,
24
+ hints: Record<string, string>,
25
+ ): Request {
26
+ const url = new URL(original.url)
27
+ for (const [k, v] of Object.entries(hints)) {
28
+ if (!url.searchParams.has(k)) url.searchParams.set(k, v)
29
+ }
30
+ return new Request(url.toString(), {
31
+ method: original.method,
32
+ headers: original.headers,
33
+ })
34
+ }