@atproto/oauth-provider 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 (631) hide show
  1. package/.postcssrc.yml +3 -0
  2. package/CHANGELOG.md +19 -0
  3. package/LICENSE.txt +7 -0
  4. package/dist/access-token/access-token-type.d.ts +6 -0
  5. package/dist/access-token/access-token-type.d.ts.map +1 -0
  6. package/dist/access-token/access-token-type.js +10 -0
  7. package/dist/access-token/access-token-type.js.map +1 -0
  8. package/dist/account/account-manager.d.ts +14 -0
  9. package/dist/account/account-manager.d.ts.map +1 -0
  10. package/dist/account/account-manager.js +39 -0
  11. package/dist/account/account-manager.js.map +1 -0
  12. package/dist/account/account-store.d.ts +39 -0
  13. package/dist/account/account-store.d.ts.map +1 -0
  14. package/dist/account/account-store.js +19 -0
  15. package/dist/account/account-store.js.map +1 -0
  16. package/dist/account/account.d.ts +8 -0
  17. package/dist/account/account.d.ts.map +1 -0
  18. package/dist/account/account.js +3 -0
  19. package/dist/account/account.js.map +1 -0
  20. package/dist/assets/app/bundle-manifest.json +22 -0
  21. package/dist/assets/app/main.css +3 -0
  22. package/dist/assets/app/main.js +20 -0
  23. package/dist/assets/app/main.js.map +1 -0
  24. package/dist/assets/asset.d.ts +9 -0
  25. package/dist/assets/asset.d.ts.map +1 -0
  26. package/dist/assets/asset.js +3 -0
  27. package/dist/assets/asset.js.map +1 -0
  28. package/dist/assets/assets-middleware.d.ts +2 -0
  29. package/dist/assets/assets-middleware.d.ts.map +1 -0
  30. package/dist/assets/assets-middleware.js +30 -0
  31. package/dist/assets/assets-middleware.js.map +1 -0
  32. package/dist/assets/index.d.ts +4 -0
  33. package/dist/assets/index.d.ts.map +1 -0
  34. package/dist/assets/index.js +65 -0
  35. package/dist/assets/index.js.map +1 -0
  36. package/dist/client/client-auth.d.ts +13 -0
  37. package/dist/client/client-auth.d.ts.map +1 -0
  38. package/dist/client/client-auth.js +35 -0
  39. package/dist/client/client-auth.js.map +1 -0
  40. package/dist/client/client-data.d.ts +8 -0
  41. package/dist/client/client-data.d.ts.map +1 -0
  42. package/dist/client/client-data.js +3 -0
  43. package/dist/client/client-data.js.map +1 -0
  44. package/dist/client/client-id.d.ts +4 -0
  45. package/dist/client/client-id.d.ts.map +1 -0
  46. package/dist/client/client-id.js +6 -0
  47. package/dist/client/client-id.js.map +1 -0
  48. package/dist/client/client-info.d.ts +13 -0
  49. package/dist/client/client-info.d.ts.map +1 -0
  50. package/dist/client/client-info.js +3 -0
  51. package/dist/client/client-info.js.map +1 -0
  52. package/dist/client/client-manager.d.ts +38 -0
  53. package/dist/client/client-manager.d.ts.map +1 -0
  54. package/dist/client/client-manager.js +534 -0
  55. package/dist/client/client-manager.js.map +1 -0
  56. package/dist/client/client-store.d.ts +13 -0
  57. package/dist/client/client-store.d.ts.map +1 -0
  58. package/dist/client/client-store.js +39 -0
  59. package/dist/client/client-store.js.map +1 -0
  60. package/dist/client/client-utils.d.ts +6 -0
  61. package/dist/client/client-utils.d.ts.map +1 -0
  62. package/dist/client/client-utils.js +40 -0
  63. package/dist/client/client-utils.js.map +1 -0
  64. package/dist/client/client.d.ts +41 -0
  65. package/dist/client/client.d.ts.map +1 -0
  66. package/dist/client/client.js +163 -0
  67. package/dist/client/client.js.map +1 -0
  68. package/dist/constants.d.ts +42 -0
  69. package/dist/constants.d.ts.map +1 -0
  70. package/dist/constants.js +53 -0
  71. package/dist/constants.js.map +1 -0
  72. package/dist/device/device-data.d.ts +20 -0
  73. package/dist/device/device-data.d.ts.map +1 -0
  74. package/dist/device/device-data.js +11 -0
  75. package/dist/device/device-data.js.map +1 -0
  76. package/dist/device/device-details.d.ts +17 -0
  77. package/dist/device/device-details.d.ts.map +1 -0
  78. package/dist/device/device-details.js +34 -0
  79. package/dist/device/device-details.js.map +1 -0
  80. package/dist/device/device-id.d.ts +6 -0
  81. package/dist/device/device-id.d.ts.map +1 -0
  82. package/dist/device/device-id.js +18 -0
  83. package/dist/device/device-id.js.map +1 -0
  84. package/dist/device/device-manager.d.ts +88 -0
  85. package/dist/device/device-manager.d.ts.map +1 -0
  86. package/dist/device/device-manager.js +206 -0
  87. package/dist/device/device-manager.js.map +1 -0
  88. package/dist/device/device-store.d.ts +15 -0
  89. package/dist/device/device-store.d.ts.map +1 -0
  90. package/dist/device/device-store.js +36 -0
  91. package/dist/device/device-store.js.map +1 -0
  92. package/dist/device/session-id.d.ts +6 -0
  93. package/dist/device/session-id.d.ts.map +1 -0
  94. package/dist/device/session-id.js +18 -0
  95. package/dist/device/session-id.js.map +1 -0
  96. package/dist/dpop/dpop-manager.d.ts +33 -0
  97. package/dist/dpop/dpop-manager.d.ts.map +1 -0
  98. package/dist/dpop/dpop-manager.js +115 -0
  99. package/dist/dpop/dpop-manager.js.map +1 -0
  100. package/dist/dpop/dpop-nonce.d.ts +13 -0
  101. package/dist/dpop/dpop-nonce.d.ts.map +1 -0
  102. package/dist/dpop/dpop-nonce.js +94 -0
  103. package/dist/dpop/dpop-nonce.js.map +1 -0
  104. package/dist/errors/access-denied-error.d.ts +8 -0
  105. package/dist/errors/access-denied-error.d.ts.map +1 -0
  106. package/dist/errors/access-denied-error.js +21 -0
  107. package/dist/errors/access-denied-error.js.map +1 -0
  108. package/dist/errors/account-selection-required-error.d.ts +6 -0
  109. package/dist/errors/account-selection-required-error.d.ts.map +1 -0
  110. package/dist/errors/account-selection-required-error.js +11 -0
  111. package/dist/errors/account-selection-required-error.js.map +1 -0
  112. package/dist/errors/consent-required-error.d.ts +6 -0
  113. package/dist/errors/consent-required-error.d.ts.map +1 -0
  114. package/dist/errors/consent-required-error.js +11 -0
  115. package/dist/errors/consent-required-error.js.map +1 -0
  116. package/dist/errors/invalid-authorization-details-error.d.ts +20 -0
  117. package/dist/errors/invalid-authorization-details-error.d.ts.map +1 -0
  118. package/dist/errors/invalid-authorization-details-error.js +26 -0
  119. package/dist/errors/invalid-authorization-details-error.js.map +1 -0
  120. package/dist/errors/invalid-client-error.d.ts +18 -0
  121. package/dist/errors/invalid-client-error.d.ts.map +1 -0
  122. package/dist/errors/invalid-client-error.js +24 -0
  123. package/dist/errors/invalid-client-error.js.map +1 -0
  124. package/dist/errors/invalid-client-id-error.d.ts +13 -0
  125. package/dist/errors/invalid-client-id-error.d.ts.map +1 -0
  126. package/dist/errors/invalid-client-id-error.js +25 -0
  127. package/dist/errors/invalid-client-id-error.js.map +1 -0
  128. package/dist/errors/invalid-client-metadata-error.d.ts +13 -0
  129. package/dist/errors/invalid-client-metadata-error.d.ts.map +1 -0
  130. package/dist/errors/invalid-client-metadata-error.js +23 -0
  131. package/dist/errors/invalid-client-metadata-error.js.map +1 -0
  132. package/dist/errors/invalid-dpop-key-binding-error.d.ts +12 -0
  133. package/dist/errors/invalid-dpop-key-binding-error.d.ts.map +1 -0
  134. package/dist/errors/invalid-dpop-key-binding-error.js +20 -0
  135. package/dist/errors/invalid-dpop-key-binding-error.js.map +1 -0
  136. package/dist/errors/invalid-dpop-proof-error.d.ts +5 -0
  137. package/dist/errors/invalid-dpop-proof-error.d.ts.map +1 -0
  138. package/dist/errors/invalid-dpop-proof-error.js +12 -0
  139. package/dist/errors/invalid-dpop-proof-error.js.map +1 -0
  140. package/dist/errors/invalid-grant-error.d.ts +14 -0
  141. package/dist/errors/invalid-grant-error.d.ts.map +1 -0
  142. package/dist/errors/invalid-grant-error.js +20 -0
  143. package/dist/errors/invalid-grant-error.js.map +1 -0
  144. package/dist/errors/invalid-parameters-error.d.ts +6 -0
  145. package/dist/errors/invalid-parameters-error.d.ts.map +1 -0
  146. package/dist/errors/invalid-parameters-error.js +11 -0
  147. package/dist/errors/invalid-parameters-error.js.map +1 -0
  148. package/dist/errors/invalid-redirect-uri-error.d.ts +11 -0
  149. package/dist/errors/invalid-redirect-uri-error.d.ts.map +1 -0
  150. package/dist/errors/invalid-redirect-uri-error.js +21 -0
  151. package/dist/errors/invalid-redirect-uri-error.js.map +1 -0
  152. package/dist/errors/invalid-request-error.d.ts +28 -0
  153. package/dist/errors/invalid-request-error.d.ts.map +1 -0
  154. package/dist/errors/invalid-request-error.js +34 -0
  155. package/dist/errors/invalid-request-error.js.map +1 -0
  156. package/dist/errors/invalid-token-error.d.ts +16 -0
  157. package/dist/errors/invalid-token-error.d.ts.map +1 -0
  158. package/dist/errors/invalid-token-error.js +45 -0
  159. package/dist/errors/invalid-token-error.js.map +1 -0
  160. package/dist/errors/login-required-error.d.ts +6 -0
  161. package/dist/errors/login-required-error.d.ts.map +1 -0
  162. package/dist/errors/login-required-error.js +11 -0
  163. package/dist/errors/login-required-error.js.map +1 -0
  164. package/dist/errors/oauth-error.d.ts +13 -0
  165. package/dist/errors/oauth-error.d.ts.map +1 -0
  166. package/dist/errors/oauth-error.js +29 -0
  167. package/dist/errors/oauth-error.js.map +1 -0
  168. package/dist/errors/unauthorized-client-error.d.ts +18 -0
  169. package/dist/errors/unauthorized-client-error.d.ts.map +1 -0
  170. package/dist/errors/unauthorized-client-error.js +24 -0
  171. package/dist/errors/unauthorized-client-error.js.map +1 -0
  172. package/dist/errors/use-dpop-nonce-error.d.ts +18 -0
  173. package/dist/errors/use-dpop-nonce-error.d.ts.map +1 -0
  174. package/dist/errors/use-dpop-nonce-error.js +27 -0
  175. package/dist/errors/use-dpop-nonce-error.js.map +1 -0
  176. package/dist/errors/www-authenticate-error.d.ts +9 -0
  177. package/dist/errors/www-authenticate-error.d.ts.map +1 -0
  178. package/dist/errors/www-authenticate-error.js +46 -0
  179. package/dist/errors/www-authenticate-error.js.map +1 -0
  180. package/dist/index.d.ts +14 -0
  181. package/dist/index.d.ts.map +1 -0
  182. package/dist/index.js +31 -0
  183. package/dist/index.js.map +1 -0
  184. package/dist/lib/html/build-document.d.ts +32 -0
  185. package/dist/lib/html/build-document.d.ts.map +1 -0
  186. package/dist/lib/html/build-document.js +61 -0
  187. package/dist/lib/html/build-document.js.map +1 -0
  188. package/dist/lib/html/escapers.d.ts +9 -0
  189. package/dist/lib/html/escapers.d.ts.map +1 -0
  190. package/dist/lib/html/escapers.js +66 -0
  191. package/dist/lib/html/escapers.js.map +1 -0
  192. package/dist/lib/html/html.d.ts +13 -0
  193. package/dist/lib/html/html.d.ts.map +1 -0
  194. package/dist/lib/html/html.js +53 -0
  195. package/dist/lib/html/html.js.map +1 -0
  196. package/dist/lib/html/index.d.ts +4 -0
  197. package/dist/lib/html/index.d.ts.map +1 -0
  198. package/dist/lib/html/index.js +21 -0
  199. package/dist/lib/html/index.js.map +1 -0
  200. package/dist/lib/html/tags.d.ts +34 -0
  201. package/dist/lib/html/tags.d.ts.map +1 -0
  202. package/dist/lib/html/tags.js +47 -0
  203. package/dist/lib/html/tags.js.map +1 -0
  204. package/dist/lib/html/util.d.ts +4 -0
  205. package/dist/lib/html/util.d.ts.map +1 -0
  206. package/dist/lib/html/util.js +20 -0
  207. package/dist/lib/html/util.js.map +1 -0
  208. package/dist/lib/http/accept.d.ts +29 -0
  209. package/dist/lib/http/accept.d.ts.map +1 -0
  210. package/dist/lib/http/accept.js +67 -0
  211. package/dist/lib/http/accept.js.map +1 -0
  212. package/dist/lib/http/context.d.ts +5 -0
  213. package/dist/lib/http/context.d.ts.map +1 -0
  214. package/dist/lib/http/context.js +10 -0
  215. package/dist/lib/http/context.js.map +1 -0
  216. package/dist/lib/http/index.d.ts +10 -0
  217. package/dist/lib/http/index.d.ts.map +1 -0
  218. package/dist/lib/http/index.js +26 -0
  219. package/dist/lib/http/index.js.map +1 -0
  220. package/dist/lib/http/method.d.ts +6 -0
  221. package/dist/lib/http/method.d.ts.map +1 -0
  222. package/dist/lib/http/method.js +19 -0
  223. package/dist/lib/http/method.js.map +1 -0
  224. package/dist/lib/http/middleware.d.ts +18 -0
  225. package/dist/lib/http/middleware.d.ts.map +1 -0
  226. package/dist/lib/http/middleware.js +118 -0
  227. package/dist/lib/http/middleware.js.map +1 -0
  228. package/dist/lib/http/parser.d.ts +33 -0
  229. package/dist/lib/http/parser.d.ts.map +1 -0
  230. package/dist/lib/http/parser.js +48 -0
  231. package/dist/lib/http/parser.js.map +1 -0
  232. package/dist/lib/http/path.d.ts +9 -0
  233. package/dist/lib/http/path.d.ts.map +1 -0
  234. package/dist/lib/http/path.js +54 -0
  235. package/dist/lib/http/path.js.map +1 -0
  236. package/dist/lib/http/request.d.ts +33 -0
  237. package/dist/lib/http/request.d.ts.map +1 -0
  238. package/dist/lib/http/request.js +86 -0
  239. package/dist/lib/http/request.js.map +1 -0
  240. package/dist/lib/http/response.d.ts +13 -0
  241. package/dist/lib/http/response.d.ts.map +1 -0
  242. package/dist/lib/http/response.js +98 -0
  243. package/dist/lib/http/response.js.map +1 -0
  244. package/dist/lib/http/route.d.ts +25 -0
  245. package/dist/lib/http/route.d.ts.map +1 -0
  246. package/dist/lib/http/route.js +39 -0
  247. package/dist/lib/http/route.js.map +1 -0
  248. package/dist/lib/http/router.d.ts +32 -0
  249. package/dist/lib/http/router.d.ts.map +1 -0
  250. package/dist/lib/http/router.js +74 -0
  251. package/dist/lib/http/router.js.map +1 -0
  252. package/dist/lib/http/stream.d.ts +13 -0
  253. package/dist/lib/http/stream.d.ts.map +1 -0
  254. package/dist/lib/http/stream.js +46 -0
  255. package/dist/lib/http/stream.js.map +1 -0
  256. package/dist/lib/http/types.d.ts +7 -0
  257. package/dist/lib/http/types.d.ts.map +1 -0
  258. package/dist/lib/http/types.js +3 -0
  259. package/dist/lib/http/types.js.map +1 -0
  260. package/dist/lib/http/url.d.ts +8 -0
  261. package/dist/lib/http/url.d.ts.map +1 -0
  262. package/dist/lib/http/url.js +22 -0
  263. package/dist/lib/http/url.js.map +1 -0
  264. package/dist/lib/redis.d.ts +5 -0
  265. package/dist/lib/redis.d.ts.map +1 -0
  266. package/dist/lib/redis.js +22 -0
  267. package/dist/lib/redis.js.map +1 -0
  268. package/dist/lib/util/authorization-header.d.ts +4 -0
  269. package/dist/lib/util/authorization-header.d.ts.map +1 -0
  270. package/dist/lib/util/authorization-header.js +23 -0
  271. package/dist/lib/util/authorization-header.js.map +1 -0
  272. package/dist/lib/util/cast.d.ts +2 -0
  273. package/dist/lib/util/cast.d.ts.map +1 -0
  274. package/dist/lib/util/cast.js +10 -0
  275. package/dist/lib/util/cast.js.map +1 -0
  276. package/dist/lib/util/crypto.d.ts +3 -0
  277. package/dist/lib/util/crypto.d.ts.map +1 -0
  278. package/dist/lib/util/crypto.js +29 -0
  279. package/dist/lib/util/crypto.js.map +1 -0
  280. package/dist/lib/util/date.d.ts +3 -0
  281. package/dist/lib/util/date.d.ts.map +1 -0
  282. package/dist/lib/util/date.js +12 -0
  283. package/dist/lib/util/date.js.map +1 -0
  284. package/dist/lib/util/hostname.d.ts +6 -0
  285. package/dist/lib/util/hostname.d.ts.map +1 -0
  286. package/dist/lib/util/hostname.js +24 -0
  287. package/dist/lib/util/hostname.js.map +1 -0
  288. package/dist/lib/util/redirect-uri.d.ts +7 -0
  289. package/dist/lib/util/redirect-uri.d.ts.map +1 -0
  290. package/dist/lib/util/redirect-uri.js +44 -0
  291. package/dist/lib/util/redirect-uri.js.map +1 -0
  292. package/dist/lib/util/time.d.ts +6 -0
  293. package/dist/lib/util/time.d.ts.map +1 -0
  294. package/dist/lib/util/time.js +28 -0
  295. package/dist/lib/util/time.js.map +1 -0
  296. package/dist/lib/util/type.d.ts +6 -0
  297. package/dist/lib/util/type.d.ts.map +1 -0
  298. package/dist/lib/util/type.js +3 -0
  299. package/dist/lib/util/type.js.map +1 -0
  300. package/dist/lib/util/well-known.d.ts +3 -0
  301. package/dist/lib/util/well-known.d.ts.map +1 -0
  302. package/dist/lib/util/well-known.js +11 -0
  303. package/dist/lib/util/well-known.js.map +1 -0
  304. package/dist/metadata/build-metadata.d.ts +14 -0
  305. package/dist/metadata/build-metadata.d.ts.map +1 -0
  306. package/dist/metadata/build-metadata.js +132 -0
  307. package/dist/metadata/build-metadata.js.map +1 -0
  308. package/dist/oauth-client.d.ts +4 -0
  309. package/dist/oauth-client.d.ts.map +1 -0
  310. package/dist/oauth-client.js +19 -0
  311. package/dist/oauth-client.js.map +1 -0
  312. package/dist/oauth-dpop.d.ts +3 -0
  313. package/dist/oauth-dpop.d.ts.map +1 -0
  314. package/dist/oauth-dpop.js +19 -0
  315. package/dist/oauth-dpop.js.map +1 -0
  316. package/dist/oauth-errors.d.ts +20 -0
  317. package/dist/oauth-errors.d.ts.map +1 -0
  318. package/dist/oauth-errors.js +43 -0
  319. package/dist/oauth-errors.js.map +1 -0
  320. package/dist/oauth-hooks.d.ts +42 -0
  321. package/dist/oauth-hooks.d.ts.map +1 -0
  322. package/dist/oauth-hooks.js +3 -0
  323. package/dist/oauth-hooks.js.map +1 -0
  324. package/dist/oauth-provider.d.ts +179 -0
  325. package/dist/oauth-provider.d.ts.map +1 -0
  326. package/dist/oauth-provider.js +748 -0
  327. package/dist/oauth-provider.js.map +1 -0
  328. package/dist/oauth-store.d.ts +11 -0
  329. package/dist/oauth-store.d.ts.map +1 -0
  330. package/dist/oauth-store.js +27 -0
  331. package/dist/oauth-store.js.map +1 -0
  332. package/dist/oauth-verifier.d.ts +66 -0
  333. package/dist/oauth-verifier.d.ts.map +1 -0
  334. package/dist/oauth-verifier.js +94 -0
  335. package/dist/oauth-verifier.js.map +1 -0
  336. package/dist/oidc/claims.d.ts +16 -0
  337. package/dist/oidc/claims.d.ts.map +1 -0
  338. package/dist/oidc/claims.js +29 -0
  339. package/dist/oidc/claims.js.map +1 -0
  340. package/dist/oidc/sub.d.ts +4 -0
  341. package/dist/oidc/sub.d.ts.map +1 -0
  342. package/dist/oidc/sub.js +6 -0
  343. package/dist/oidc/sub.js.map +1 -0
  344. package/dist/oidc/userinfo.d.ts +7 -0
  345. package/dist/oidc/userinfo.d.ts.map +1 -0
  346. package/dist/oidc/userinfo.js +3 -0
  347. package/dist/oidc/userinfo.js.map +1 -0
  348. package/dist/output/build-error-payload.d.ts +6 -0
  349. package/dist/output/build-error-payload.d.ts.map +1 -0
  350. package/dist/output/build-error-payload.js +108 -0
  351. package/dist/output/build-error-payload.js.map +1 -0
  352. package/dist/output/customization.d.ts +37 -0
  353. package/dist/output/customization.d.ts.map +1 -0
  354. package/dist/output/customization.js +62 -0
  355. package/dist/output/customization.js.map +1 -0
  356. package/dist/output/send-authorize-page.d.ts +43 -0
  357. package/dist/output/send-authorize-page.d.ts.map +1 -0
  358. package/dist/output/send-authorize-page.js +49 -0
  359. package/dist/output/send-authorize-page.js.map +1 -0
  360. package/dist/output/send-authorize-redirect.d.ts +25 -0
  361. package/dist/output/send-authorize-redirect.d.ts.map +1 -0
  362. package/dist/output/send-authorize-redirect.js +72 -0
  363. package/dist/output/send-authorize-redirect.js.map +1 -0
  364. package/dist/output/send-error-page.d.ts +5 -0
  365. package/dist/output/send-error-page.d.ts.map +1 -0
  366. package/dist/output/send-error-page.js +31 -0
  367. package/dist/output/send-error-page.js.map +1 -0
  368. package/dist/output/send-web-page.d.ts +8 -0
  369. package/dist/output/send-web-page.d.ts.map +1 -0
  370. package/dist/output/send-web-page.js +48 -0
  371. package/dist/output/send-web-page.js.map +1 -0
  372. package/dist/parameters/claims-requested.d.ts +3 -0
  373. package/dist/parameters/claims-requested.d.ts.map +1 -0
  374. package/dist/parameters/claims-requested.js +77 -0
  375. package/dist/parameters/claims-requested.js.map +1 -0
  376. package/dist/parameters/oidc-payload.d.ts +31 -0
  377. package/dist/parameters/oidc-payload.d.ts.map +1 -0
  378. package/dist/parameters/oidc-payload.js +25 -0
  379. package/dist/parameters/oidc-payload.js.map +1 -0
  380. package/dist/replay/replay-manager.d.ts +10 -0
  381. package/dist/replay/replay-manager.d.ts.map +1 -0
  382. package/dist/replay/replay-manager.js +23 -0
  383. package/dist/replay/replay-manager.js.map +1 -0
  384. package/dist/replay/replay-store-memory.d.ts +11 -0
  385. package/dist/replay/replay-store-memory.d.ts.map +1 -0
  386. package/dist/replay/replay-store-memory.js +30 -0
  387. package/dist/replay/replay-store-memory.js.map +1 -0
  388. package/dist/replay/replay-store-redis.d.ts +16 -0
  389. package/dist/replay/replay-store-redis.d.ts.map +1 -0
  390. package/dist/replay/replay-store-redis.js +20 -0
  391. package/dist/replay/replay-store-redis.js.map +1 -0
  392. package/dist/replay/replay-store.d.ts +16 -0
  393. package/dist/replay/replay-store.d.ts.map +1 -0
  394. package/dist/replay/replay-store.js +22 -0
  395. package/dist/replay/replay-store.js.map +1 -0
  396. package/dist/request/code.d.ts +7 -0
  397. package/dist/request/code.d.ts.map +1 -0
  398. package/dist/request/code.js +20 -0
  399. package/dist/request/code.js.map +1 -0
  400. package/dist/request/request-data.d.ts +21 -0
  401. package/dist/request/request-data.d.ts.map +1 -0
  402. package/dist/request/request-data.js +6 -0
  403. package/dist/request/request-data.js.map +1 -0
  404. package/dist/request/request-id.d.ts +6 -0
  405. package/dist/request/request-id.d.ts.map +1 -0
  406. package/dist/request/request-id.js +18 -0
  407. package/dist/request/request-id.js.map +1 -0
  408. package/dist/request/request-info.d.ts +12 -0
  409. package/dist/request/request-info.d.ts.map +1 -0
  410. package/dist/request/request-info.js +3 -0
  411. package/dist/request/request-info.js.map +1 -0
  412. package/dist/request/request-manager.d.ts +40 -0
  413. package/dist/request/request-manager.d.ts.map +1 -0
  414. package/dist/request/request-manager.js +310 -0
  415. package/dist/request/request-manager.js.map +1 -0
  416. package/dist/request/request-store-memory.d.ts +16 -0
  417. package/dist/request/request-store-memory.d.ts.map +1 -0
  418. package/dist/request/request-store-memory.js +31 -0
  419. package/dist/request/request-store-memory.js.map +1 -0
  420. package/dist/request/request-store-redis.d.ts +24 -0
  421. package/dist/request/request-store-redis.d.ts.map +1 -0
  422. package/dist/request/request-store-redis.js +58 -0
  423. package/dist/request/request-store-redis.js.map +1 -0
  424. package/dist/request/request-store.d.ts +27 -0
  425. package/dist/request/request-store.d.ts.map +1 -0
  426. package/dist/request/request-store.js +37 -0
  427. package/dist/request/request-store.js.map +1 -0
  428. package/dist/request/request-uri.d.ts +8 -0
  429. package/dist/request/request-uri.d.ts.map +1 -0
  430. package/dist/request/request-uri.js +24 -0
  431. package/dist/request/request-uri.js.map +1 -0
  432. package/dist/request/types.d.ts +328 -0
  433. package/dist/request/types.d.ts.map +1 -0
  434. package/dist/request/types.js +27 -0
  435. package/dist/request/types.js.map +1 -0
  436. package/dist/signer/signed-token-payload.d.ts +1694 -0
  437. package/dist/signer/signed-token-payload.d.ts.map +1 -0
  438. package/dist/signer/signed-token-payload.js +32 -0
  439. package/dist/signer/signed-token-payload.js.map +1 -0
  440. package/dist/signer/signer.d.ts +193 -0
  441. package/dist/signer/signer.d.ts.map +1 -0
  442. package/dist/signer/signer.js +101 -0
  443. package/dist/signer/signer.js.map +1 -0
  444. package/dist/token/refresh-token.d.ts +7 -0
  445. package/dist/token/refresh-token.d.ts.map +1 -0
  446. package/dist/token/refresh-token.js +20 -0
  447. package/dist/token/refresh-token.js.map +1 -0
  448. package/dist/token/token-claims.d.ts +1687 -0
  449. package/dist/token/token-claims.d.ts.map +1 -0
  450. package/dist/token/token-claims.js +30 -0
  451. package/dist/token/token-claims.js.map +1 -0
  452. package/dist/token/token-data.d.ts +20 -0
  453. package/dist/token/token-data.d.ts.map +1 -0
  454. package/dist/token/token-data.js +3 -0
  455. package/dist/token/token-data.js.map +1 -0
  456. package/dist/token/token-id.d.ts +7 -0
  457. package/dist/token/token-id.d.ts.map +1 -0
  458. package/dist/token/token-id.js +20 -0
  459. package/dist/token/token-id.js.map +1 -0
  460. package/dist/token/token-manager.d.ts +48 -0
  461. package/dist/token/token-manager.d.ts.map +1 -0
  462. package/dist/token/token-manager.js +421 -0
  463. package/dist/token/token-manager.js.map +1 -0
  464. package/dist/token/token-store.d.ts +35 -0
  465. package/dist/token/token-store.d.ts.map +1 -0
  466. package/dist/token/token-store.js +38 -0
  467. package/dist/token/token-store.js.map +1 -0
  468. package/dist/token/types.d.ts +250 -0
  469. package/dist/token/types.d.ts.map +1 -0
  470. package/dist/token/types.js +36 -0
  471. package/dist/token/types.js.map +1 -0
  472. package/dist/token/verify-token-claims.d.ts +17 -0
  473. package/dist/token/verify-token-claims.d.ts.map +1 -0
  474. package/dist/token/verify-token-claims.js +39 -0
  475. package/dist/token/verify-token-claims.js.map +1 -0
  476. package/package.json +83 -0
  477. package/rollup.config.js +55 -0
  478. package/src/access-token/access-token-type.ts +5 -0
  479. package/src/account/account-manager.ts +55 -0
  480. package/src/account/account-store.ts +74 -0
  481. package/src/account/account.ts +10 -0
  482. package/src/assets/app/app.tsx +28 -0
  483. package/src/assets/app/backend-data.ts +65 -0
  484. package/src/assets/app/components/accept-form.tsx +112 -0
  485. package/src/assets/app/components/account-identifier.tsx +18 -0
  486. package/src/assets/app/components/account-picker.tsx +108 -0
  487. package/src/assets/app/components/client-identifier.tsx +32 -0
  488. package/src/assets/app/components/client-name.tsx +30 -0
  489. package/src/assets/app/components/error-card.tsx +41 -0
  490. package/src/assets/app/components/help-card.tsx +42 -0
  491. package/src/assets/app/components/layout-title-page.tsx +43 -0
  492. package/src/assets/app/components/layout-welcome.tsx +58 -0
  493. package/src/assets/app/components/sign-in-form.tsx +290 -0
  494. package/src/assets/app/components/sign-up-account-form.tsx +210 -0
  495. package/src/assets/app/components/sign-up-disclaimer.tsx +44 -0
  496. package/src/assets/app/components/url-viewer.tsx +70 -0
  497. package/src/assets/app/cookies.ts +11 -0
  498. package/src/assets/app/hooks/use-api.ts +104 -0
  499. package/src/assets/app/hooks/use-bound-dispatch.ts +5 -0
  500. package/src/assets/app/hooks/use-csrf-token.ts +5 -0
  501. package/src/assets/app/lib/api.ts +64 -0
  502. package/src/assets/app/lib/clsx.ts +4 -0
  503. package/src/assets/app/lib/util.ts +10 -0
  504. package/src/assets/app/main.css +11 -0
  505. package/src/assets/app/main.tsx +28 -0
  506. package/src/assets/app/views/accept-view.tsx +51 -0
  507. package/src/assets/app/views/authorize-view.tsx +101 -0
  508. package/src/assets/app/views/error-view.tsx +27 -0
  509. package/src/assets/app/views/sign-in-view.tsx +121 -0
  510. package/src/assets/app/views/sign-up-view.tsx +93 -0
  511. package/src/assets/app/views/welcome-view.tsx +61 -0
  512. package/src/assets/asset.ts +8 -0
  513. package/src/assets/assets-middleware.ts +32 -0
  514. package/src/assets/index.ts +74 -0
  515. package/src/client/client-auth.ts +45 -0
  516. package/src/client/client-data.ts +9 -0
  517. package/src/client/client-id.ts +4 -0
  518. package/src/client/client-info.ts +13 -0
  519. package/src/client/client-manager.ts +818 -0
  520. package/src/client/client-store.ts +38 -0
  521. package/src/client/client-utils.ts +43 -0
  522. package/src/client/client.ts +231 -0
  523. package/src/constants.ts +69 -0
  524. package/src/device/device-data.ts +11 -0
  525. package/src/device/device-details.ts +43 -0
  526. package/src/device/device-id.ts +23 -0
  527. package/src/device/device-manager.ts +287 -0
  528. package/src/device/device-store.ts +35 -0
  529. package/src/device/session-id.ts +22 -0
  530. package/src/dpop/dpop-manager.ts +147 -0
  531. package/src/dpop/dpop-nonce.ts +104 -0
  532. package/src/errors/access-denied-error.ts +26 -0
  533. package/src/errors/account-selection-required-error.ts +12 -0
  534. package/src/errors/consent-required-error.ts +12 -0
  535. package/src/errors/invalid-authorization-details-error.ts +22 -0
  536. package/src/errors/invalid-client-error.ts +20 -0
  537. package/src/errors/invalid-client-id-error.ts +20 -0
  538. package/src/errors/invalid-client-metadata-error.ts +19 -0
  539. package/src/errors/invalid-dpop-key-binding-error.ts +21 -0
  540. package/src/errors/invalid-dpop-proof-error.ts +13 -0
  541. package/src/errors/invalid-grant-error.ts +16 -0
  542. package/src/errors/invalid-parameters-error.ts +12 -0
  543. package/src/errors/invalid-redirect-uri-error.ts +17 -0
  544. package/src/errors/invalid-request-error.ts +30 -0
  545. package/src/errors/invalid-token-error.ts +59 -0
  546. package/src/errors/login-required-error.ts +12 -0
  547. package/src/errors/oauth-error.ts +28 -0
  548. package/src/errors/unauthorized-client-error.ts +20 -0
  549. package/src/errors/use-dpop-nonce-error.ts +32 -0
  550. package/src/errors/www-authenticate-error.ts +65 -0
  551. package/src/index.ts +15 -0
  552. package/src/lib/html/README.md +9 -0
  553. package/src/lib/html/build-document.ts +98 -0
  554. package/src/lib/html/escapers.ts +66 -0
  555. package/src/lib/html/html.ts +61 -0
  556. package/src/lib/html/index.ts +5 -0
  557. package/src/lib/html/tags.ts +58 -0
  558. package/src/lib/html/util.ts +21 -0
  559. package/src/lib/http/README.md +11 -0
  560. package/src/lib/http/accept.ts +91 -0
  561. package/src/lib/http/context.ts +11 -0
  562. package/src/lib/http/index.ts +9 -0
  563. package/src/lib/http/method.ts +18 -0
  564. package/src/lib/http/middleware.ts +183 -0
  565. package/src/lib/http/parser.ts +64 -0
  566. package/src/lib/http/path.ts +82 -0
  567. package/src/lib/http/request.ts +141 -0
  568. package/src/lib/http/response.ts +133 -0
  569. package/src/lib/http/route.ts +56 -0
  570. package/src/lib/http/router.ts +118 -0
  571. package/src/lib/http/stream.ts +78 -0
  572. package/src/lib/http/types.ts +22 -0
  573. package/src/lib/http/url.ts +23 -0
  574. package/src/lib/redis.ts +23 -0
  575. package/src/lib/util/authorization-header.ts +26 -0
  576. package/src/lib/util/cast.ts +4 -0
  577. package/src/lib/util/crypto.ts +27 -0
  578. package/src/lib/util/date.ts +7 -0
  579. package/src/lib/util/hostname.ts +19 -0
  580. package/src/lib/util/redirect-uri.ts +46 -0
  581. package/src/lib/util/time.ts +33 -0
  582. package/src/lib/util/type.ts +4 -0
  583. package/src/lib/util/well-known.ts +8 -0
  584. package/src/metadata/build-metadata.ts +165 -0
  585. package/src/oauth-client.ts +3 -0
  586. package/src/oauth-dpop.ts +2 -0
  587. package/src/oauth-errors.ts +21 -0
  588. package/src/oauth-hooks.ts +66 -0
  589. package/src/oauth-provider.ts +1409 -0
  590. package/src/oauth-store.ts +11 -0
  591. package/src/oauth-verifier.ts +219 -0
  592. package/src/oidc/claims.ts +35 -0
  593. package/src/oidc/sub.ts +4 -0
  594. package/src/oidc/userinfo.ts +11 -0
  595. package/src/output/build-error-payload.ts +143 -0
  596. package/src/output/customization.ts +96 -0
  597. package/src/output/send-authorize-page.ts +111 -0
  598. package/src/output/send-authorize-redirect.ts +130 -0
  599. package/src/output/send-error-page.ts +41 -0
  600. package/src/output/send-web-page.ts +66 -0
  601. package/src/parameters/claims-requested.ts +106 -0
  602. package/src/parameters/oidc-payload.ts +28 -0
  603. package/src/replay/replay-manager.ts +38 -0
  604. package/src/replay/replay-store-memory.ts +36 -0
  605. package/src/replay/replay-store-redis.ts +31 -0
  606. package/src/replay/replay-store.ts +44 -0
  607. package/src/request/code.ts +24 -0
  608. package/src/request/request-data.ts +26 -0
  609. package/src/request/request-id.ts +23 -0
  610. package/src/request/request-info.ts +12 -0
  611. package/src/request/request-manager.ts +479 -0
  612. package/src/request/request-store-memory.ts +39 -0
  613. package/src/request/request-store-redis.ts +71 -0
  614. package/src/request/request-store.ts +54 -0
  615. package/src/request/request-uri.ts +29 -0
  616. package/src/request/types.ts +48 -0
  617. package/src/signer/signed-token-payload.ts +35 -0
  618. package/src/signer/signer.ts +165 -0
  619. package/src/token/refresh-token.ts +31 -0
  620. package/src/token/token-claims.ts +31 -0
  621. package/src/token/token-data.ts +33 -0
  622. package/src/token/token-id.ts +26 -0
  623. package/src/token/token-manager.ts +591 -0
  624. package/src/token/token-store.ts +78 -0
  625. package/src/token/types.ts +86 -0
  626. package/src/token/verify-token-claims.ts +65 -0
  627. package/tailwind.config.js +13 -0
  628. package/tsconfig.backend.json +9 -0
  629. package/tsconfig.frontend.json +11 -0
  630. package/tsconfig.json +8 -0
  631. package/tsconfig.tools.json +8 -0
@@ -0,0 +1,133 @@
1
+ import { PassThrough, Readable, Transform } from 'node:stream'
2
+ import { pipeline } from 'node:stream/promises'
3
+ import { constants, createBrotliCompress, createGzip } from 'node:zlib'
4
+
5
+ import { Handler, ServerResponse } from './types.js'
6
+
7
+ export function appendHeader(
8
+ res: ServerResponse,
9
+ header: string,
10
+ value: string | readonly string[],
11
+ ): void {
12
+ const existing = res.getHeader(header)
13
+ if (existing == null) {
14
+ res.setHeader(header, value)
15
+ } else {
16
+ const arr = Array.isArray(existing) ? existing : [String(existing)]
17
+ res.setHeader(header, arr.concat(value))
18
+ }
19
+ }
20
+
21
+ export function writeRedirect(
22
+ res: ServerResponse,
23
+ url: string,
24
+ status = 302,
25
+ ): void {
26
+ res.writeHead(status, { Location: url }).end()
27
+ }
28
+
29
+ function negotiateEncoding(accept?: string | string[]) {
30
+ if (accept?.includes('br')) return 'br'
31
+ if (accept?.includes('gzip')) return 'gzip'
32
+ return 'identity'
33
+ }
34
+
35
+ function getEncoder(encoding: string): Transform {
36
+ switch (encoding) {
37
+ case 'br':
38
+ return createBrotliCompress({
39
+ // Default quality is too slow
40
+ params: { [constants.BROTLI_PARAM_QUALITY]: 5 },
41
+ })
42
+ case 'gzip':
43
+ return createGzip()
44
+ case 'identity':
45
+ return new PassThrough()
46
+ default:
47
+ throw new Error(`Unsupported encoding: ${encoding}`)
48
+ }
49
+ }
50
+
51
+ const ifString = (value: unknown): string | undefined =>
52
+ typeof value === 'string' ? value : undefined
53
+
54
+ export async function writeStream(
55
+ res: ServerResponse,
56
+ stream: Readable,
57
+ contentType = ifString((stream as any).headers?.['content-type']) ||
58
+ 'application/octet-stream',
59
+ status = 200,
60
+ ): Promise<void> {
61
+ res.statusCode = status
62
+ res.setHeader('content-type', contentType)
63
+ appendHeader(res, 'vary', 'accept-encoding')
64
+
65
+ const encoding = negotiateEncoding(res.req.headers['accept-encoding'])
66
+
67
+ res.setHeader('content-encoding', encoding)
68
+ res.setHeader('transfer-encoding', 'chunked')
69
+
70
+ if (res.req.method === 'HEAD') {
71
+ res.end()
72
+ stream.destroy()
73
+ return
74
+ }
75
+
76
+ try {
77
+ await pipeline(stream, getEncoder(encoding), res)
78
+ } catch (err) {
79
+ // Prevent the socket from being left open in a bad state
80
+ res.socket?.destroy()
81
+
82
+ if (err != null && typeof err === 'object') {
83
+ // If an abort signal is used, we can consider this function's job successful
84
+ if ('name' in err && err.name === 'AbortError') return
85
+
86
+ // If the client closes the connection, we don't care about the error
87
+ if ('code' in err && err.code === 'ERR_STREAM_PREMATURE_CLOSE') return
88
+ }
89
+
90
+ throw err
91
+ }
92
+ }
93
+
94
+ export async function writeBuffer(
95
+ res: ServerResponse,
96
+ buffer: Buffer,
97
+ contentType?: string,
98
+ status = 200,
99
+ ): Promise<void> {
100
+ const stream = Readable.from([buffer])
101
+ return writeStream(res, stream, contentType, status)
102
+ }
103
+
104
+ export async function writeJson(
105
+ res: ServerResponse,
106
+ payload: unknown,
107
+ status = 200,
108
+ contentType = 'application/json',
109
+ ): Promise<void> {
110
+ const buffer = Buffer.from(JSON.stringify(payload))
111
+ return writeBuffer(res, buffer, contentType, status)
112
+ }
113
+
114
+ export function staticJsonHandler(
115
+ value: unknown,
116
+ contentType = 'application/json',
117
+ status = 200,
118
+ ): Handler<unknown> {
119
+ const buffer = Buffer.from(JSON.stringify(value))
120
+ return function (req, res, next) {
121
+ void writeBuffer(res, buffer, contentType, status).catch(next)
122
+ }
123
+ }
124
+
125
+ export async function writeHtml(
126
+ res: ServerResponse,
127
+ html: Buffer | string,
128
+ status = 200,
129
+ contentType = 'text/html',
130
+ ): Promise<void> {
131
+ const buffer = Buffer.isBuffer(html) ? html : Buffer.from(html)
132
+ return writeBuffer(res, buffer, contentType, status)
133
+ }
@@ -0,0 +1,56 @@
1
+ import { SubCtx, subCtx } from './context.js'
2
+ import { MethodMatcherInput, createMethodMatcher } from './method.js'
3
+ import { combineMiddlewares } from './middleware.js'
4
+ import { Params, Path, createPathMatcher } from './path.js'
5
+ import { IncomingMessage, Middleware, ServerResponse } from './types.js'
6
+
7
+ export type RouteCtx<T, P extends Params> = SubCtx<T, { params: Readonly<P> }>
8
+ export type RouteMiddleware<
9
+ T,
10
+ P extends Params,
11
+ Req = IncomingMessage,
12
+ Res = ServerResponse,
13
+ > = Middleware<RouteCtx<T, P>, Req, Res>
14
+
15
+ /**
16
+ * @example
17
+ * ```ts
18
+ * createRoute<{ foo: string }>('GET', '/foo/:foo', function (req, res) {
19
+ * console.log(this.params.foo) // OK
20
+ * console.log(this.params.bar) // Error
21
+ * })
22
+ *
23
+ * createRoute<{ foo: string }>(['POST', 'PUT'], '/foo/:foo', function (req, res) {
24
+ * console.log(this.params.foo) // OK
25
+ * console.log(this.params.bar) // Error
26
+ * })
27
+ * ```
28
+ */
29
+ export function createRoute<
30
+ P extends Params,
31
+ T = void,
32
+ Req extends IncomingMessage = IncomingMessage,
33
+ Res extends ServerResponse = ServerResponse,
34
+ >(
35
+ method: MethodMatcherInput,
36
+ path: Path<P>,
37
+ ...mw: RouteMiddleware<T, P, Req, Res>[]
38
+ ): Middleware<T, Req, Res> {
39
+ const paramsMatcher = createPathMatcher<P>(path)
40
+ const methodMatcher = createMethodMatcher(method)
41
+
42
+ const middleware = combineMiddlewares(mw, { skipKeyword: 'route' })
43
+
44
+ return function (req, res, next) {
45
+ if (methodMatcher(req)) {
46
+ const pathname = req.url?.split('?')[0] ?? '/'
47
+ const params = paramsMatcher(pathname)
48
+ if (params) {
49
+ const context = subCtx(this, 'params', params)
50
+ return middleware.call(context, req, res, next)
51
+ }
52
+ }
53
+
54
+ return next()
55
+ }
56
+ }
@@ -0,0 +1,118 @@
1
+ import { SubCtx, subCtx } from './context.js'
2
+ import { MethodMatcherInput } from './method.js'
3
+ import { asHandler, combineMiddlewares } from './middleware.js'
4
+ import { Params, Path } from './path.js'
5
+ import { RouteMiddleware, createRoute } from './route.js'
6
+ import { IncomingMessage, Middleware, ServerResponse } from './types.js'
7
+
8
+ export type RouterCtx<T> = SubCtx<T, { url: Readonly<URL> }>
9
+ export type RouterMiddleware<
10
+ T = void,
11
+ Req = IncomingMessage,
12
+ Res = ServerResponse,
13
+ > = Middleware<RouterCtx<T>, Req, Res>
14
+
15
+ export class Router<
16
+ T = void,
17
+ Req extends IncomingMessage = IncomingMessage,
18
+ Res extends ServerResponse = ServerResponse,
19
+ > {
20
+ private readonly middlewares: RouterMiddleware<T, Req, Res>[] = []
21
+
22
+ constructor(
23
+ private readonly url?: {
24
+ /** Used to build the origin of the {@link RouterCtx['url']} context property */
25
+ protocol?: string
26
+ /** Used to build the origin of the {@link RouterCtx['url']} context property */
27
+ host?: string
28
+ },
29
+ ) {}
30
+
31
+ use(...middlewares: RouterMiddleware<T, Req, Res>[]) {
32
+ this.middlewares.push(...middlewares)
33
+ return this
34
+ }
35
+
36
+ all<P extends Params = Params>(
37
+ path: Path<P>,
38
+ ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]
39
+ ) {
40
+ return this.addRoute<P>('*', path, ...mw)
41
+ }
42
+
43
+ get<P extends Params = Params>(
44
+ path: Path<P>,
45
+ ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]
46
+ ) {
47
+ return this.addRoute<P>('GET', path, ...mw)
48
+ }
49
+
50
+ post<P extends Params = Params>(
51
+ path: Path<P>,
52
+ ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]
53
+ ) {
54
+ return this.addRoute<P>('POST', path, ...mw)
55
+ }
56
+
57
+ options<P extends Params = Params>(
58
+ path: Path<P>,
59
+ ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]
60
+ ) {
61
+ return this.addRoute<P>('OPTIONS', path, ...mw)
62
+ }
63
+
64
+ addRoute<P extends Params>(
65
+ method: MethodMatcherInput,
66
+ path: Path<P>,
67
+ ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]
68
+ ) {
69
+ return this.use(createRoute(method, path, ...mw))
70
+ }
71
+
72
+ /**
73
+ * @returns router middleware which dispatches a route matching the request.
74
+ */
75
+ buildHandler() {
76
+ const routerUrl = this.url
77
+
78
+ // Calling next('router') from a middleware will skip all the remaining
79
+ // middlewares in the stack.
80
+ const middleware = combineMiddlewares(this.middlewares, {
81
+ skipKeyword: 'router',
82
+ })
83
+
84
+ return asHandler<Middleware<T, Req, Res>>(function (this, req, res, next) {
85
+ // Make sure that the context contains a "url". This will allow the add()
86
+ // method to match routes based on the pathname and will allow routes to
87
+ // access the query params (through this.url.searchParams).
88
+ let url: URL
89
+
90
+ if (
91
+ !routerUrl &&
92
+ this != null &&
93
+ typeof this === 'object' &&
94
+ 'url' in this &&
95
+ this.url instanceof URL
96
+ ) {
97
+ // If the context already contains a "url" (router inside router), let's
98
+ // use it.
99
+ url = this.url
100
+ } else {
101
+ // Parse the URL using node's URL parser.
102
+ try {
103
+ const protocol = routerUrl?.protocol || 'https:'
104
+ const host = req.headers.host || routerUrl?.host || 'localhost'
105
+ const pathname = req.url || '/'
106
+ url = new URL(pathname, `${protocol}//${host}`)
107
+ } catch (err) {
108
+ return next(
109
+ Object.assign(err as Error, { status: 400, statusCode: 400 }),
110
+ )
111
+ }
112
+ }
113
+
114
+ const context = subCtx(this, 'url', url)
115
+ middleware.call(context, req, res, next)
116
+ })
117
+ }
118
+ }
@@ -0,0 +1,78 @@
1
+ import { PassThrough, Readable } from 'node:stream'
2
+ import { createGunzip, createInflate } from 'node:zlib'
3
+
4
+ import createHttpError from 'http-errors'
5
+
6
+ import {
7
+ KnownNames,
8
+ KnownParser,
9
+ KnownTypes,
10
+ ParserForType,
11
+ ParserResult,
12
+ parsers,
13
+ } from './parser.js'
14
+
15
+ export async function readStream(req: Readable): Promise<Buffer> {
16
+ const chunks: Buffer[] = []
17
+ let totalLength = 0
18
+ for await (const chunk of req) {
19
+ chunks.push(chunk)
20
+ totalLength += chunk.length
21
+ }
22
+ return Buffer.concat(chunks, totalLength)
23
+ }
24
+
25
+ export function decodeStream(
26
+ req: Readable,
27
+ encoding: string = 'identity',
28
+ ): Readable {
29
+ switch (encoding) {
30
+ case 'deflate':
31
+ return req.compose(createInflate())
32
+ case 'gzip':
33
+ return req.compose(createGunzip())
34
+ case 'identity':
35
+ return req.compose(new PassThrough())
36
+ default:
37
+ throw createHttpError(415, 'Unsupported content-encoding')
38
+ }
39
+ }
40
+
41
+ export async function parseStream<
42
+ T extends KnownTypes,
43
+ A extends readonly KnownNames[] = readonly KnownNames[],
44
+ >(
45
+ req: Readable,
46
+ contentType: T,
47
+ allow?: A,
48
+ ): Promise<
49
+ ParserResult<ParserForType<Extract<KnownParser, { name: A[number] }>, T>>
50
+ >
51
+ export async function parseStream<
52
+ A extends readonly KnownNames[] = readonly KnownNames[],
53
+ >(
54
+ req: Readable,
55
+ contentType: unknown,
56
+ allow?: A,
57
+ ): Promise<ParserResult<Extract<KnownParser, { name: A[number] }>>>
58
+ export async function parseStream(
59
+ req: Readable,
60
+ contentType: unknown = 'application/octet-stream',
61
+ allow?: string[],
62
+ ): Promise<ParserResult<KnownParser>> {
63
+ if (typeof contentType !== 'string') {
64
+ throw createHttpError(400, 'Invalid content-type')
65
+ }
66
+
67
+ const parser = parsers.find(
68
+ (parser) =>
69
+ allow?.includes(parser.name) !== false && parser.test(contentType),
70
+ )
71
+
72
+ if (!parser) {
73
+ throw createHttpError(400, 'Unsupported content-type')
74
+ }
75
+
76
+ const buffer = await readStream(req)
77
+ return parser.parse(buffer)
78
+ }
@@ -0,0 +1,22 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http'
2
+ export { IncomingMessage, ServerResponse }
3
+
4
+ export type NextFunction = (err?: unknown) => void
5
+
6
+ export type Middleware<
7
+ T = void,
8
+ Req = IncomingMessage,
9
+ Res = ServerResponse,
10
+ > = (
11
+ this: T,
12
+ req: Req,
13
+ res: Res,
14
+ next: NextFunction,
15
+ ) => void | PromiseLike<void>
16
+
17
+ export type Handler<T = void, Req = IncomingMessage, Res = ServerResponse> = (
18
+ this: T,
19
+ req: Req,
20
+ res: Res,
21
+ next?: NextFunction,
22
+ ) => void
@@ -0,0 +1,23 @@
1
+ export type UrlReference = {
2
+ origin?: string
3
+ pathname?: string
4
+ searchParams?: Iterable<readonly [string, string]> // compatible with URLSearchParams
5
+ }
6
+
7
+ export function urlMatch(url: URL, reference: UrlReference) {
8
+ if (reference.origin !== undefined) {
9
+ if (url.origin !== reference.origin) return false
10
+ }
11
+
12
+ if (reference.pathname !== undefined) {
13
+ if (url.pathname !== reference.pathname) return false
14
+ }
15
+
16
+ if (reference.searchParams !== undefined) {
17
+ for (const [key, value] of reference.searchParams) {
18
+ if (url.searchParams.get(key) !== value) return false
19
+ }
20
+ }
21
+
22
+ return true
23
+ }
@@ -0,0 +1,23 @@
1
+ import { Redis, type RedisOptions } from 'ioredis'
2
+
3
+ export type { Redis, RedisOptions }
4
+
5
+ export type CreateRedisOptions = Redis | RedisOptions | string
6
+
7
+ export function createRedis(options: CreateRedisOptions): Redis {
8
+ if (options instanceof Redis) {
9
+ return options
10
+ } else if (typeof options === 'string') {
11
+ const url = new URL(
12
+ options.startsWith('redis://') ? options : `redis://${options}`,
13
+ )
14
+
15
+ return new Redis({
16
+ host: url.hostname,
17
+ port: parseInt(url.port, 10),
18
+ password: url.password,
19
+ })
20
+ } else {
21
+ return new Redis(options)
22
+ }
23
+ }
@@ -0,0 +1,26 @@
1
+ import { accessTokenSchema, oauthTokenTypeSchema } from '@atproto/oauth-types'
2
+ import { z } from 'zod'
3
+
4
+ import { InvalidRequestError } from '../../errors/invalid-request-error.js'
5
+ import { WWWAuthenticateError } from '../../errors/www-authenticate-error.js'
6
+
7
+ export const authorizationHeaderSchema = z.tuple([
8
+ oauthTokenTypeSchema,
9
+ accessTokenSchema,
10
+ ])
11
+
12
+ export const parseAuthorizationHeader = (header?: string) => {
13
+ if (header == null) {
14
+ throw new WWWAuthenticateError(
15
+ 'invalid_request',
16
+ 'Authorization header required',
17
+ { Bearer: {}, DPoP: {} },
18
+ )
19
+ }
20
+
21
+ const parsed = authorizationHeaderSchema.safeParse(header.split(' ', 2))
22
+ if (!parsed.success) {
23
+ throw new InvalidRequestError('Invalid authorization header')
24
+ }
25
+ return parsed.data
26
+ }
@@ -0,0 +1,4 @@
1
+ export function asArray<T>(value: T | T[]): T[] {
2
+ if (value == null) return []
3
+ return Array.isArray(value) ? value : [value]
4
+ }
@@ -0,0 +1,27 @@
1
+ import { randomBytes } from 'node:crypto'
2
+
3
+ export async function randomHexId(bytesLength = 16) {
4
+ return new Promise<string>((resolve, reject) => {
5
+ randomBytes(bytesLength, (err, buf) => {
6
+ if (err) return reject(err)
7
+ resolve(buf.toString('hex'))
8
+ })
9
+ })
10
+ }
11
+
12
+ // Basically all algorithms supported by "jose"'s jwtVerify().
13
+ // @TODO: Is there a way to get this list from the runtime instead of hardcoding it?
14
+ export const VERIFY_ALGOS = [
15
+ 'RS256',
16
+ 'RS384',
17
+ 'RS512',
18
+
19
+ 'PS256',
20
+ 'PS384',
21
+ 'PS512',
22
+
23
+ 'ES256',
24
+ 'ES256K',
25
+ 'ES384',
26
+ 'ES512',
27
+ ] as const
@@ -0,0 +1,7 @@
1
+ export function dateToEpoch(date: Date = new Date()) {
2
+ return Math.floor(date.getTime() / 1000)
3
+ }
4
+
5
+ export function dateToRelativeSeconds(date: Date) {
6
+ return Math.floor((date.getTime() - Date.now()) / 1000)
7
+ }
@@ -0,0 +1,19 @@
1
+ import { parse, ParsedDomain } from 'psl'
2
+
3
+ export function isInternetHost(host: string): boolean {
4
+ return parseDomain(host) !== null
5
+ }
6
+
7
+ export function parseUrlDomain(input: string | URL): ParsedDomain | null {
8
+ const url = new URL(input)
9
+ return parseDomain(url.hostname)
10
+ }
11
+
12
+ export function parseDomain(domain: string) {
13
+ const parsed = parse(domain)
14
+ if ('listed' in parsed && parsed.listed && parsed.domain) {
15
+ return parsed
16
+ } else {
17
+ return null
18
+ }
19
+ }
@@ -0,0 +1,46 @@
1
+ import { isLoopbackHost } from '@atproto/oauth-types'
2
+
3
+ /**
4
+ *
5
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc8252#section-8.4}
6
+ * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-8.4.2}
7
+ */
8
+ export function compareRedirectUri(
9
+ allowed_uri: string,
10
+ request_uri: string,
11
+ ): boolean {
12
+ // https://datatracker.ietf.org/doc/html/rfc8252#section-8.4
13
+ //
14
+ // > Authorization servers MUST require clients to register their complete
15
+ // > redirect URI (including the path component) and reject authorization
16
+ // > requests that specify a redirect URI that doesn't exactly match the
17
+ // > one that was registered; the exception is loopback redirects, where
18
+ // > an exact match is required except for the port URI component.
19
+ if (allowed_uri === request_uri) return true
20
+
21
+ // https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
22
+ const allowedUri = new URL(allowed_uri)
23
+ if (isLoopbackHost(allowedUri.hostname)) {
24
+ const requestUri = new URL(request_uri)
25
+
26
+ return (
27
+ // > The authorization server MUST allow any port to be specified at the
28
+ // > time of the request for loopback IP redirect URIs, to accommodate
29
+ // > clients that obtain an available ephemeral port from the operating
30
+ // > system at the time of the request
31
+ //
32
+ // Note: We only apply this rule if the allowed URI does not have a port
33
+ // specified.
34
+ (!allowedUri.port || allowedUri.port === requestUri.port) &&
35
+ allowedUri.hostname === requestUri.hostname &&
36
+ allowedUri.pathname === requestUri.pathname &&
37
+ allowedUri.protocol === requestUri.protocol &&
38
+ allowedUri.search === requestUri.search &&
39
+ allowedUri.hash === requestUri.hash &&
40
+ allowedUri.username === requestUri.username &&
41
+ allowedUri.password === requestUri.password
42
+ )
43
+ }
44
+
45
+ return false
46
+ }
@@ -0,0 +1,33 @@
1
+ import { Awaitable } from './type.js'
2
+
3
+ /**
4
+ * Utility function to protect against timing attacks.
5
+ */
6
+ export async function constantTime<T>(
7
+ delay: number,
8
+ fn: () => Awaitable<T>,
9
+ ): Promise<T> {
10
+ if (!Number.isFinite(delay) || delay <= 0) {
11
+ throw new TypeError('Delay must be greater than 0')
12
+ }
13
+
14
+ const start = Date.now()
15
+ try {
16
+ return await fn()
17
+ } finally {
18
+ const delta = Date.now() - start
19
+
20
+ // Let's make sure we always wait for a multiple of `delay` milliseconds.
21
+ const n = Math.max(1, Math.ceil(delta / delay))
22
+
23
+ // Ideally, the multiple should always be 1 in order to to properly defend
24
+ // against timing attacks. Show a warning if it's not.
25
+ if (n > 1) {
26
+ console.warn(
27
+ `constantTime: execution time was ${delta}ms, waiting for the next multiple of ${delay}ms. You should increase the delay to properly defend against timing attacks.`,
28
+ )
29
+ }
30
+
31
+ await new Promise((resolve) => setTimeout(resolve, n * delay))
32
+ }
33
+ }
@@ -0,0 +1,4 @@
1
+ // eslint-disable-next-line @typescript-eslint/ban-types
2
+ export type Simplify<T> = { [K in keyof T]: T[K] } & {}
3
+ export type Override<T, V> = Simplify<V & Omit<T, keyof V>>
4
+ export type Awaitable<T> = T | Promise<T>
@@ -0,0 +1,8 @@
1
+ export function buildWellknownUrl(url: URL, name: string): URL {
2
+ const path =
3
+ url.pathname === '/'
4
+ ? `/.well-known/${name}`
5
+ : `${url.pathname.replace(/\/+$/, '')}/${name}`
6
+
7
+ return new URL(path, url)
8
+ }