@atproto/oauth-provider 0.16.5 → 0.17.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 (321) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/access-token/access-token-mode.js +2 -5
  3. package/dist/access-token/access-token-mode.js.map +1 -1
  4. package/dist/account/account-manager.js +25 -33
  5. package/dist/account/account-manager.js.map +1 -1
  6. package/dist/account/account-store.js +11 -32
  7. package/dist/account/account-store.js.map +1 -1
  8. package/dist/account/sign-in-data.js +9 -12
  9. package/dist/account/sign-in-data.js.map +1 -1
  10. package/dist/account/sign-up-input.js +14 -17
  11. package/dist/account/sign-up-input.js.map +1 -1
  12. package/dist/client/client-auth.js +1 -2
  13. package/dist/client/client-data.js +1 -2
  14. package/dist/client/client-id.js +2 -5
  15. package/dist/client/client-id.js.map +1 -1
  16. package/dist/client/client-info.js +1 -2
  17. package/dist/client/client-manager.js +86 -97
  18. package/dist/client/client-manager.js.map +1 -1
  19. package/dist/client/client-store.js +7 -26
  20. package/dist/client/client-store.js.map +1 -1
  21. package/dist/client/client-utils.js +10 -14
  22. package/dist/client/client-utils.js.map +1 -1
  23. package/dist/client/client.js +43 -53
  24. package/dist/client/client.js.map +1 -1
  25. package/dist/constants.js +28 -31
  26. package/dist/constants.js.map +1 -1
  27. package/dist/customization/branding.js +8 -11
  28. package/dist/customization/branding.js.map +1 -1
  29. package/dist/customization/build-customization-css.js +8 -11
  30. package/dist/customization/build-customization-css.js.map +1 -1
  31. package/dist/customization/build-customization-data.js +1 -4
  32. package/dist/customization/build-customization-data.js.map +1 -1
  33. package/dist/customization/colors.js +11 -14
  34. package/dist/customization/colors.js.map +1 -1
  35. package/dist/customization/customization.js +8 -11
  36. package/dist/customization/customization.js.map +1 -1
  37. package/dist/customization/links.js +7 -10
  38. package/dist/customization/links.js.map +1 -1
  39. package/dist/device/device-data.js +7 -10
  40. package/dist/device/device-data.js.map +1 -1
  41. package/dist/device/device-id.js +11 -16
  42. package/dist/device/device-id.js.map +1 -1
  43. package/dist/device/device-manager.js +32 -38
  44. package/dist/device/device-manager.js.map +1 -1
  45. package/dist/device/device-store.js +7 -25
  46. package/dist/device/device-store.js.map +1 -1
  47. package/dist/device/session-id.js +9 -13
  48. package/dist/device/session-id.js.map +1 -1
  49. package/dist/dpop/dpop-manager.d.ts +3 -3
  50. package/dist/dpop/dpop-manager.js +38 -43
  51. package/dist/dpop/dpop-manager.js.map +1 -1
  52. package/dist/dpop/dpop-nonce.d.ts +2 -2
  53. package/dist/dpop/dpop-nonce.d.ts.map +1 -1
  54. package/dist/dpop/dpop-nonce.js +14 -18
  55. package/dist/dpop/dpop-nonce.js.map +1 -1
  56. package/dist/dpop/dpop-proof.js +1 -2
  57. package/dist/errors/access-denied-error.js +2 -6
  58. package/dist/errors/access-denied-error.js.map +1 -1
  59. package/dist/errors/account-selection-required-error.js +2 -6
  60. package/dist/errors/account-selection-required-error.js.map +1 -1
  61. package/dist/errors/authorization-error.js +7 -12
  62. package/dist/errors/authorization-error.js.map +1 -1
  63. package/dist/errors/consent-required-error.js +2 -6
  64. package/dist/errors/consent-required-error.js.map +1 -1
  65. package/dist/errors/error-parser.js +14 -18
  66. package/dist/errors/error-parser.js.map +1 -1
  67. package/dist/errors/handle-unavailable-error.js +2 -7
  68. package/dist/errors/handle-unavailable-error.js.map +1 -1
  69. package/dist/errors/invalid-authorization-details-error.js +2 -6
  70. package/dist/errors/invalid-authorization-details-error.js.map +1 -1
  71. package/dist/errors/invalid-client-error.js +2 -6
  72. package/dist/errors/invalid-client-error.js.map +1 -1
  73. package/dist/errors/invalid-client-id-error.js +2 -6
  74. package/dist/errors/invalid-client-id-error.js.map +1 -1
  75. package/dist/errors/invalid-client-metadata-error.js +7 -11
  76. package/dist/errors/invalid-client-metadata-error.js.map +1 -1
  77. package/dist/errors/invalid-credentials-error.js +2 -7
  78. package/dist/errors/invalid-credentials-error.js.map +1 -1
  79. package/dist/errors/invalid-dpop-key-binding-error.js +2 -6
  80. package/dist/errors/invalid-dpop-key-binding-error.js.map +1 -1
  81. package/dist/errors/invalid-dpop-proof-error.js +2 -6
  82. package/dist/errors/invalid-dpop-proof-error.js.map +1 -1
  83. package/dist/errors/invalid-grant-error.js +2 -6
  84. package/dist/errors/invalid-grant-error.js.map +1 -1
  85. package/dist/errors/invalid-invite-code-error.d.ts +1 -1
  86. package/dist/errors/invalid-invite-code-error.d.ts.map +1 -1
  87. package/dist/errors/invalid-invite-code-error.js +2 -6
  88. package/dist/errors/invalid-invite-code-error.js.map +1 -1
  89. package/dist/errors/invalid-redirect-uri-error.js +2 -6
  90. package/dist/errors/invalid-redirect-uri-error.js.map +1 -1
  91. package/dist/errors/invalid-request-error.js +3 -7
  92. package/dist/errors/invalid-request-error.js.map +1 -1
  93. package/dist/errors/invalid-scope-error.js +2 -6
  94. package/dist/errors/invalid-scope-error.js.map +1 -1
  95. package/dist/errors/invalid-token-error.js +10 -15
  96. package/dist/errors/invalid-token-error.js.map +1 -1
  97. package/dist/errors/login-required-error.js +2 -6
  98. package/dist/errors/login-required-error.js.map +1 -1
  99. package/dist/errors/oauth-error.js +1 -9
  100. package/dist/errors/oauth-error.js.map +1 -1
  101. package/dist/errors/second-authentication-factor-required-error.js +2 -8
  102. package/dist/errors/second-authentication-factor-required-error.js.map +1 -1
  103. package/dist/errors/unauthorized-client-error.js +2 -6
  104. package/dist/errors/unauthorized-client-error.js.map +1 -1
  105. package/dist/errors/use-dpop-nonce-error.js +4 -8
  106. package/dist/errors/use-dpop-nonce-error.js.map +1 -1
  107. package/dist/errors/www-authenticate-error.js +4 -9
  108. package/dist/errors/www-authenticate-error.js.map +1 -1
  109. package/dist/index.js +14 -30
  110. package/dist/index.js.map +1 -1
  111. package/dist/lexicon/lexicon-data.js +1 -2
  112. package/dist/lexicon/lexicon-getter.js +6 -10
  113. package/dist/lexicon/lexicon-getter.js.map +1 -1
  114. package/dist/lexicon/lexicon-manager.js +10 -30
  115. package/dist/lexicon/lexicon-manager.js.map +1 -1
  116. package/dist/lexicon/lexicon-store.js +5 -10
  117. package/dist/lexicon/lexicon-store.js.map +1 -1
  118. package/dist/lib/csp/index.js +3 -8
  119. package/dist/lib/csp/index.js.map +1 -1
  120. package/dist/lib/hcaptcha.js +33 -43
  121. package/dist/lib/hcaptcha.js.map +1 -1
  122. package/dist/lib/html/build-document.js +19 -24
  123. package/dist/lib/html/build-document.js.map +1 -1
  124. package/dist/lib/html/escapers.js +10 -16
  125. package/dist/lib/html/escapers.js.map +1 -1
  126. package/dist/lib/html/html.js +1 -5
  127. package/dist/lib/html/html.js.map +1 -1
  128. package/dist/lib/html/hydration-data.js +6 -10
  129. package/dist/lib/html/hydration-data.js.map +1 -1
  130. package/dist/lib/html/index.js +3 -19
  131. package/dist/lib/html/index.js.map +1 -1
  132. package/dist/lib/html/tags.js +14 -23
  133. package/dist/lib/html/tags.js.map +1 -1
  134. package/dist/lib/html/util.js +1 -4
  135. package/dist/lib/html/util.js.map +1 -1
  136. package/dist/lib/http/accept.d.ts.map +1 -1
  137. package/dist/lib/http/accept.js +8 -8
  138. package/dist/lib/http/accept.js.map +1 -1
  139. package/dist/lib/http/context.js +1 -4
  140. package/dist/lib/http/context.js.map +1 -1
  141. package/dist/lib/http/headers.js +1 -4
  142. package/dist/lib/http/headers.js.map +1 -1
  143. package/dist/lib/http/index.js +10 -26
  144. package/dist/lib/http/index.js.map +1 -1
  145. package/dist/lib/http/method.js +1 -4
  146. package/dist/lib/http/method.js.map +1 -1
  147. package/dist/lib/http/middleware.js +11 -17
  148. package/dist/lib/http/middleware.js.map +1 -1
  149. package/dist/lib/http/parser.js +13 -20
  150. package/dist/lib/http/parser.js.map +1 -1
  151. package/dist/lib/http/path.js +1 -4
  152. package/dist/lib/http/path.js.map +1 -1
  153. package/dist/lib/http/request.d.ts.map +1 -1
  154. package/dist/lib/http/request.js +32 -47
  155. package/dist/lib/http/request.js.map +1 -1
  156. package/dist/lib/http/response.js +14 -27
  157. package/dist/lib/http/response.js.map +1 -1
  158. package/dist/lib/http/route.js +9 -12
  159. package/dist/lib/http/route.js.map +1 -1
  160. package/dist/lib/http/router.js +8 -13
  161. package/dist/lib/http/router.js.map +1 -1
  162. package/dist/lib/http/security-headers.js +10 -15
  163. package/dist/lib/http/security-headers.js.map +1 -1
  164. package/dist/lib/http/stream.js +12 -20
  165. package/dist/lib/http/stream.js.map +1 -1
  166. package/dist/lib/http/types.js +1 -2
  167. package/dist/lib/http/url.js +1 -4
  168. package/dist/lib/http/url.js.map +1 -1
  169. package/dist/lib/nsid.js +4 -8
  170. package/dist/lib/nsid.js.map +1 -1
  171. package/dist/lib/redis.js +4 -7
  172. package/dist/lib/redis.js.map +1 -1
  173. package/dist/lib/util/authorization-header.js +11 -15
  174. package/dist/lib/util/authorization-header.js.map +1 -1
  175. package/dist/lib/util/cast.js +3 -8
  176. package/dist/lib/util/cast.js.map +1 -1
  177. package/dist/lib/util/color.js +23 -32
  178. package/dist/lib/util/color.js.map +1 -1
  179. package/dist/lib/util/crypto.js +5 -10
  180. package/dist/lib/util/crypto.js.map +1 -1
  181. package/dist/lib/util/date.js +2 -6
  182. package/dist/lib/util/date.js.map +1 -1
  183. package/dist/lib/util/error.js +5 -8
  184. package/dist/lib/util/error.js.map +1 -1
  185. package/dist/lib/util/function.js +3 -8
  186. package/dist/lib/util/function.js.map +1 -1
  187. package/dist/lib/util/locale.js +3 -6
  188. package/dist/lib/util/locale.js.map +1 -1
  189. package/dist/lib/util/object.js +1 -4
  190. package/dist/lib/util/object.js.map +1 -1
  191. package/dist/lib/util/redirect-uri.js +3 -6
  192. package/dist/lib/util/redirect-uri.js.map +1 -1
  193. package/dist/lib/util/time.js +5 -9
  194. package/dist/lib/util/time.js.map +1 -1
  195. package/dist/lib/util/type.d.ts.map +1 -1
  196. package/dist/lib/util/type.js +1 -5
  197. package/dist/lib/util/type.js.map +1 -1
  198. package/dist/lib/util/ui8.js +3 -8
  199. package/dist/lib/util/ui8.js.map +1 -1
  200. package/dist/lib/util/well-known.js +1 -4
  201. package/dist/lib/util/well-known.js.map +1 -1
  202. package/dist/lib/util/zod-error.js +4 -8
  203. package/dist/lib/util/zod-error.js.map +1 -1
  204. package/dist/lib/write-form-redirect.js +9 -12
  205. package/dist/lib/write-form-redirect.js.map +1 -1
  206. package/dist/lib/write-html.js +12 -15
  207. package/dist/lib/write-html.js.map +1 -1
  208. package/dist/metadata/build-metadata.js +9 -12
  209. package/dist/metadata/build-metadata.js.map +1 -1
  210. package/dist/oauth-client.js +2 -18
  211. package/dist/oauth-client.js.map +1 -1
  212. package/dist/oauth-dpop.js +2 -18
  213. package/dist/oauth-dpop.js.map +1 -1
  214. package/dist/oauth-errors.js +24 -42
  215. package/dist/oauth-errors.js.map +1 -1
  216. package/dist/oauth-hooks.js +8 -15
  217. package/dist/oauth-hooks.js.map +1 -1
  218. package/dist/oauth-middleware.js +13 -16
  219. package/dist/oauth-middleware.js.map +1 -1
  220. package/dist/oauth-provider.js +108 -125
  221. package/dist/oauth-provider.js.map +1 -1
  222. package/dist/oauth-store.js +7 -23
  223. package/dist/oauth-store.js.map +1 -1
  224. package/dist/oauth-verifier.js +41 -53
  225. package/dist/oauth-verifier.js.map +1 -1
  226. package/dist/oidc/sub.js +2 -5
  227. package/dist/oidc/sub.js.map +1 -1
  228. package/dist/replay/replay-manager.js +6 -11
  229. package/dist/replay/replay-manager.js.map +1 -1
  230. package/dist/replay/replay-store-memory.js +5 -7
  231. package/dist/replay/replay-store-memory.js.map +1 -1
  232. package/dist/replay/replay-store-redis.js +3 -8
  233. package/dist/replay/replay-store-redis.js.map +1 -1
  234. package/dist/replay/replay-store.js +3 -8
  235. package/dist/replay/replay-store.js.map +1 -1
  236. package/dist/request/code.js +10 -15
  237. package/dist/request/code.js.map +1 -1
  238. package/dist/request/request-data.js +1 -5
  239. package/dist/request/request-data.js.map +1 -1
  240. package/dist/request/request-id.js +9 -13
  241. package/dist/request/request-id.js.map +1 -1
  242. package/dist/request/request-manager.js +61 -71
  243. package/dist/request/request-manager.js.map +1 -1
  244. package/dist/request/request-store.js +9 -27
  245. package/dist/request/request-store.js.map +1 -1
  246. package/dist/request/request-uri.js +17 -23
  247. package/dist/request/request-uri.js.map +1 -1
  248. package/dist/result/authorization-redirect-parameters.js +1 -2
  249. package/dist/result/authorization-result-authorize-page.js +1 -2
  250. package/dist/result/authorization-result-redirect.js +1 -2
  251. package/dist/router/assets/assets-manifest.d.ts.map +1 -1
  252. package/dist/router/assets/assets-manifest.js +14 -15
  253. package/dist/router/assets/assets-manifest.js.map +1 -1
  254. package/dist/router/assets/assets.d.ts.map +1 -1
  255. package/dist/router/assets/assets.js +25 -27
  256. package/dist/router/assets/assets.js.map +1 -1
  257. package/dist/router/assets/csrf.js +16 -25
  258. package/dist/router/assets/csrf.js.map +1 -1
  259. package/dist/router/assets/send-account-page.js +3 -6
  260. package/dist/router/assets/send-account-page.js.map +1 -1
  261. package/dist/router/assets/send-authorization-page.js +3 -6
  262. package/dist/router/assets/send-authorization-page.js.map +1 -1
  263. package/dist/router/assets/send-cookie-error-page.js +3 -6
  264. package/dist/router/assets/send-cookie-error-page.js.map +1 -1
  265. package/dist/router/assets/send-error-page.js +6 -9
  266. package/dist/router/assets/send-error-page.js.map +1 -1
  267. package/dist/router/assets/send-redirect.js +12 -20
  268. package/dist/router/assets/send-redirect.js.map +1 -1
  269. package/dist/router/create-account-page-middleware.js +11 -14
  270. package/dist/router/create-account-page-middleware.js.map +1 -1
  271. package/dist/router/create-api-middleware.js +83 -90
  272. package/dist/router/create-api-middleware.js.map +1 -1
  273. package/dist/router/create-authorization-page-middleware.js +43 -46
  274. package/dist/router/create-authorization-page-middleware.js.map +1 -1
  275. package/dist/router/create-oauth-middleware.js +31 -34
  276. package/dist/router/create-oauth-middleware.js.map +1 -1
  277. package/dist/router/error-handler.js +1 -2
  278. package/dist/router/middleware-options.js +1 -2
  279. package/dist/signer/access-token-payload.js +12 -15
  280. package/dist/signer/access-token-payload.js.map +1 -1
  281. package/dist/signer/api-token-payload.js +8 -11
  282. package/dist/signer/api-token-payload.js.map +1 -1
  283. package/dist/signer/signer.js +11 -17
  284. package/dist/signer/signer.js.map +1 -1
  285. package/dist/token/refresh-token.js +10 -15
  286. package/dist/token/refresh-token.js.map +1 -1
  287. package/dist/token/token-claims.js +1 -2
  288. package/dist/token/token-data.js +1 -2
  289. package/dist/token/token-id.js +10 -15
  290. package/dist/token/token-id.js.map +1 -1
  291. package/dist/token/token-manager.js +40 -51
  292. package/dist/token/token-manager.js.map +1 -1
  293. package/dist/token/token-store.js +7 -25
  294. package/dist/token/token-store.js.map +1 -1
  295. package/dist/types/authorization-response-error.js +8 -12
  296. package/dist/types/authorization-response-error.js.map +1 -1
  297. package/dist/types/color-hue.js +2 -5
  298. package/dist/types/color-hue.js.map +1 -1
  299. package/dist/types/email-otp.js +2 -5
  300. package/dist/types/email-otp.js.map +1 -1
  301. package/dist/types/email.js +6 -9
  302. package/dist/types/email.js.map +1 -1
  303. package/dist/types/handle.js +6 -9
  304. package/dist/types/handle.js.map +1 -1
  305. package/dist/types/invite-code.js +2 -5
  306. package/dist/types/invite-code.js.map +1 -1
  307. package/dist/types/par-response-error.js +5 -9
  308. package/dist/types/par-response-error.js.map +1 -1
  309. package/dist/types/password.js +3 -6
  310. package/dist/types/password.js.map +1 -1
  311. package/dist/types/rgb-color.js +7 -10
  312. package/dist/types/rgb-color.js.map +1 -1
  313. package/package.json +20 -22
  314. package/src/dpop/dpop-nonce.ts +1 -1
  315. package/src/errors/invalid-invite-code-error.ts +1 -1
  316. package/src/lib/http/accept.ts +4 -1
  317. package/src/lib/http/request.ts +4 -1
  318. package/src/lib/util/type.ts +0 -1
  319. package/src/router/assets/assets-manifest.ts +3 -1
  320. package/src/router/assets/assets.ts +2 -0
  321. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"function.js","sourceRoot":"","sources":["../../../src/lib/util/function.ts"],"names":[],"mappings":";;AAeA,8BAKC;AAED,gCAYC;AAED,gCAEC;AAvBM,KAAK,UAAU,SAAS,CAC7B,EAAM,EACN,GAAG,IAAmB;IAEtB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAuC,CAAA;AACpE,CAAC;AAED,SAAgB,UAAU,CACxB,EAAK;IAEL,IAAI,UAAU,GAAa,EAAE,CAAA;IAC7B,OAAO,UAAU,GAAG,IAAI;QACtB,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,EAAE,GAAG,UAAU,CAAA;YACrB,UAAU,GAAG,IAAI,CAAA;YACjB,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAA;QAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAM,CAAA;AACR,CAAC;AAED,SAAgB,UAAU,CAAwB,KAAQ;IACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC","sourcesContent":["/**\n * This function serves two purposes:\n * - It ensures that the return value is a Promise, even if the function returns\n * a \"thenable\" (i.e. a Promise-like object).\n * - It allows to avoid assigning a `this` context to the function, which is\n * particularly useful when the function is a member of a \"private\" object.\n */\nexport async function callAsync<F extends (...args: any[]) => unknown>(\n fn: F,\n ...args: Parameters<F>\n): Promise<Awaited<ReturnType<F>>>\nexport async function callAsync<F extends (...args: any[]) => unknown>(\n fn?: F,\n ...args: Parameters<F>\n): Promise<Awaited<ReturnType<F>> | undefined>\nexport async function callAsync<F extends (...args: any[]) => unknown>(\n fn?: F,\n ...args: Parameters<F>\n): Promise<Awaited<ReturnType<F>> | undefined> {\n return (await fn?.(...args)) as Awaited<ReturnType<F>> | undefined\n}\n\nexport function invokeOnce<T extends (this: any, ...a: any[]) => any>(\n fn: T,\n): T {\n let fnNullable: T | null = fn\n return function (...args) {\n if (fnNullable) {\n const fn = fnNullable\n fnNullable = null\n return fn.call(this, ...args)\n }\n throw new Error('Function called multiple times')\n } as T\n}\n\nexport function includedIn<T>(this: readonly T[], value: T): boolean {\n return this.includes(value)\n}\n"]}
1
+ {"version":3,"file":"function.js","sourceRoot":"","sources":["../../../src/lib/util/function.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAM,EACN,GAAG,IAAmB;IAEtB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAuC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,EAAK;IAEL,IAAI,UAAU,GAAa,EAAE,CAAA;IAC7B,OAAO,UAAU,GAAG,IAAI;QACtB,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,EAAE,GAAG,UAAU,CAAA;YACrB,UAAU,GAAG,IAAI,CAAA;YACjB,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAA;QAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAM,CAAA;AACR,CAAC;AAED,MAAM,UAAU,UAAU,CAAwB,KAAQ;IACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC","sourcesContent":["/**\n * This function serves two purposes:\n * - It ensures that the return value is a Promise, even if the function returns\n * a \"thenable\" (i.e. a Promise-like object).\n * - It allows to avoid assigning a `this` context to the function, which is\n * particularly useful when the function is a member of a \"private\" object.\n */\nexport async function callAsync<F extends (...args: any[]) => unknown>(\n fn: F,\n ...args: Parameters<F>\n): Promise<Awaited<ReturnType<F>>>\nexport async function callAsync<F extends (...args: any[]) => unknown>(\n fn?: F,\n ...args: Parameters<F>\n): Promise<Awaited<ReturnType<F>> | undefined>\nexport async function callAsync<F extends (...args: any[]) => unknown>(\n fn?: F,\n ...args: Parameters<F>\n): Promise<Awaited<ReturnType<F>> | undefined> {\n return (await fn?.(...args)) as Awaited<ReturnType<F>> | undefined\n}\n\nexport function invokeOnce<T extends (this: any, ...a: any[]) => any>(\n fn: T,\n): T {\n let fnNullable: T | null = fn\n return function (...args) {\n if (fnNullable) {\n const fn = fnNullable\n fnNullable = null\n return fn.call(this, ...args)\n }\n throw new Error('Function called multiple times')\n } as T\n}\n\nexport function includedIn<T>(this: readonly T[], value: T): boolean {\n return this.includes(value)\n}\n"]}
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.multiLangStringSchema = exports.localeSchema = void 0;
4
- const zod_1 = require("zod");
5
- exports.localeSchema = zod_1.z
1
+ import { z } from 'zod';
2
+ export const localeSchema = z
6
3
  .string()
7
4
  .regex(/^[a-z]{2,3}(-[A-Z]{2})?$/, 'Invalid locale');
8
- exports.multiLangStringSchema = zod_1.z.record(exports.localeSchema, zod_1.z.string().optional());
5
+ export const multiLangStringSchema = z.record(localeSchema, z.string().optional());
9
6
  //# sourceMappingURL=locale.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../src/lib/util/locale.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEV,QAAA,YAAY,GAAG,OAAC;KAC1B,MAAM,EAAE;KACR,KAAK,CAAC,0BAA0B,EAAE,gBAAgB,CAAC,CAAA;AAGzC,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAC3C,oBAAY,EACZ,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CACtB,CAAA","sourcesContent":["import { z } from 'zod'\n\nexport const localeSchema = z\n .string()\n .regex(/^[a-z]{2,3}(-[A-Z]{2})?$/, 'Invalid locale')\nexport type Locale = z.infer<typeof localeSchema>\n\nexport const multiLangStringSchema = z.record(\n localeSchema,\n z.string().optional(),\n)\nexport type MultiLangString = z.infer<typeof multiLangStringSchema>\n"]}
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../src/lib/util/locale.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,EAAE;KACR,KAAK,CAAC,0BAA0B,EAAE,gBAAgB,CAAC,CAAA;AAGtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAC3C,YAAY,EACZ,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CACtB,CAAA","sourcesContent":["import { z } from 'zod'\n\nexport const localeSchema = z\n .string()\n .regex(/^[a-z]{2,3}(-[A-Z]{2})?$/, 'Invalid locale')\nexport type Locale = z.infer<typeof localeSchema>\n\nexport const multiLangStringSchema = z.record(\n localeSchema,\n z.string().optional(),\n)\nexport type MultiLangString = z.infer<typeof multiLangStringSchema>\n"]}
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mergeDefaults = mergeDefaults;
4
- function mergeDefaults(defaults, ...overrides) {
1
+ export function mergeDefaults(defaults, ...overrides) {
5
2
  // @NOTE Not using the spread operator here because TS allows "undefined"
6
3
  // values to be spread, which can lead to defaults being overwritten with
7
4
  // "undefined". This function ensures that only defined values in "options"
@@ -1 +1 @@
1
- {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/lib/util/object.ts"],"names":[],"mappings":";;AAAA,sCAsBC;AAtBD,SAAgB,aAAa,CAC3B,QAAW,EACX,GAAG,SAA4B;IAE/B,yEAAyE;IACzE,yEAAyE;IACzE,2EAA2E;IAC3E,yDAAyD;IACzD,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAA;IACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC7C,MAAM,MAAM,GAAM,EAAE,GAAG,QAAQ,EAAO,CAAA;IACtC,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;gBAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["export function mergeDefaults<T extends object>(\n defaults: T,\n ...overrides: (T | undefined)[]\n): T {\n // @NOTE Not using the spread operator here because TS allows \"undefined\"\n // values to be spread, which can lead to defaults being overwritten with\n // \"undefined\". This function ensures that only defined values in \"options\"\n // will overwrite the corresponding values in \"defaults\".\n if (!overrides.length) return defaults\n if (!overrides.some(Boolean)) return defaults\n const result: T = { ...defaults } as T\n for (const options of overrides) {\n if (options) {\n for (const key in options) {\n const value = options[key]\n if (value !== undefined) {\n result[key] = value\n }\n }\n }\n }\n return result\n}\n"]}
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/lib/util/object.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAC3B,QAAW,EACX,GAAG,SAA4B;IAE/B,yEAAyE;IACzE,yEAAyE;IACzE,2EAA2E;IAC3E,yDAAyD;IACzD,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAA;IACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC7C,MAAM,MAAM,GAAM,EAAE,GAAG,QAAQ,EAAO,CAAA;IACtC,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;gBAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["export function mergeDefaults<T extends object>(\n defaults: T,\n ...overrides: (T | undefined)[]\n): T {\n // @NOTE Not using the spread operator here because TS allows \"undefined\"\n // values to be spread, which can lead to defaults being overwritten with\n // \"undefined\". This function ensures that only defined values in \"options\"\n // will overwrite the corresponding values in \"defaults\".\n if (!overrides.length) return defaults\n if (!overrides.some(Boolean)) return defaults\n const result: T = { ...defaults } as T\n for (const options of overrides) {\n if (options) {\n for (const key in options) {\n const value = options[key]\n if (value !== undefined) {\n result[key] = value\n }\n }\n }\n }\n return result\n}\n"]}
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.compareRedirectUri = compareRedirectUri;
4
- const oauth_types_1 = require("@atproto/oauth-types");
1
+ import { isLoopbackHost } from '@atproto/oauth-types';
5
2
  /**
6
3
  *
7
4
  * @see {@link https://datatracker.ietf.org/doc/html/rfc8252#section-8.4}
8
5
  * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-8.4.2}
9
6
  */
10
- function compareRedirectUri(allowed_uri, request_uri) {
7
+ export function compareRedirectUri(allowed_uri, request_uri) {
11
8
  // https://datatracker.ietf.org/doc/html/rfc8252#section-8.4
12
9
  //
13
10
  // > Authorization servers MUST require clients to register their complete
@@ -19,7 +16,7 @@ function compareRedirectUri(allowed_uri, request_uri) {
19
16
  return true;
20
17
  // https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
21
18
  const allowedUri = new URL(allowed_uri);
22
- if ((0, oauth_types_1.isLoopbackHost)(allowedUri.hostname)) {
19
+ if (isLoopbackHost(allowedUri.hostname)) {
23
20
  const requestUri = new URL(request_uri);
24
21
  return (
25
22
  // > The authorization server MUST allow any port to be specified at the
@@ -1 +1 @@
1
- {"version":3,"file":"redirect-uri.js","sourceRoot":"","sources":["../../../src/lib/util/redirect-uri.ts"],"names":[],"mappings":";;AAOA,gDAsCC;AA7CD,sDAAqD;AAErD;;;;GAIG;AACH,SAAgB,kBAAkB,CAChC,WAAmB,EACnB,WAAmB;IAEnB,4DAA4D;IAC5D,EAAE;IACF,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,wEAAwE;IACxE,kEAAkE;IAClE,IAAI,WAAW,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IAE5C,4DAA4D;IAC5D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;IACvC,IAAI,IAAA,4BAAc,EAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;QAEvC,OAAO;QACL,wEAAwE;QACxE,sEAAsE;QACtE,uEAAuE;QACvE,sCAAsC;QACtC,EAAE;QACF,wEAAwE;QACxE,aAAa;QACb,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC;YACzD,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM;YACvC,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI;YACnC,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,CAC5C,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { isLoopbackHost } from '@atproto/oauth-types'\n\n/**\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8252#section-8.4}\n * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-8.4.2}\n */\nexport function compareRedirectUri(\n allowed_uri: string,\n request_uri: string,\n): boolean {\n // https://datatracker.ietf.org/doc/html/rfc8252#section-8.4\n //\n // > Authorization servers MUST require clients to register their complete\n // > redirect URI (including the path component) and reject authorization\n // > requests that specify a redirect URI that doesn't exactly match the\n // > one that was registered; the exception is loopback redirects, where\n // > an exact match is required except for the port URI component.\n if (allowed_uri === request_uri) return true\n\n // https://datatracker.ietf.org/doc/html/rfc8252#section-7.3\n const allowedUri = new URL(allowed_uri)\n if (isLoopbackHost(allowedUri.hostname)) {\n const requestUri = new URL(request_uri)\n\n return (\n // > The authorization server MUST allow any port to be specified at the\n // > time of the request for loopback IP redirect URIs, to accommodate\n // > clients that obtain an available ephemeral port from the operating\n // > system at the time of the request\n //\n // Note: We only apply this rule if the allowed URI does not have a port\n // specified.\n (!allowedUri.port || allowedUri.port === requestUri.port) &&\n allowedUri.hostname === requestUri.hostname &&\n allowedUri.pathname === requestUri.pathname &&\n allowedUri.protocol === requestUri.protocol &&\n allowedUri.search === requestUri.search &&\n allowedUri.hash === requestUri.hash &&\n allowedUri.username === requestUri.username &&\n allowedUri.password === requestUri.password\n )\n }\n\n return false\n}\n"]}
1
+ {"version":3,"file":"redirect-uri.js","sourceRoot":"","sources":["../../../src/lib/util/redirect-uri.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,WAAmB;IAEnB,4DAA4D;IAC5D,EAAE;IACF,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,wEAAwE;IACxE,kEAAkE;IAClE,IAAI,WAAW,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IAE5C,4DAA4D;IAC5D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;IACvC,IAAI,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;QAEvC,OAAO;QACL,wEAAwE;QACxE,sEAAsE;QACtE,uEAAuE;QACvE,sCAAsC;QACtC,EAAE;QACF,wEAAwE;QACxE,aAAa;QACb,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC;YACzD,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM;YACvC,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI;YACnC,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ;YAC3C,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,CAC5C,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { isLoopbackHost } from '@atproto/oauth-types'\n\n/**\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8252#section-8.4}\n * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-8.4.2}\n */\nexport function compareRedirectUri(\n allowed_uri: string,\n request_uri: string,\n): boolean {\n // https://datatracker.ietf.org/doc/html/rfc8252#section-8.4\n //\n // > Authorization servers MUST require clients to register their complete\n // > redirect URI (including the path component) and reject authorization\n // > requests that specify a redirect URI that doesn't exactly match the\n // > one that was registered; the exception is loopback redirects, where\n // > an exact match is required except for the port URI component.\n if (allowed_uri === request_uri) return true\n\n // https://datatracker.ietf.org/doc/html/rfc8252#section-7.3\n const allowedUri = new URL(allowed_uri)\n if (isLoopbackHost(allowedUri.hostname)) {\n const requestUri = new URL(request_uri)\n\n return (\n // > The authorization server MUST allow any port to be specified at the\n // > time of the request for loopback IP redirect URIs, to accommodate\n // > clients that obtain an available ephemeral port from the operating\n // > system at the time of the request\n //\n // Note: We only apply this rule if the allowed URI does not have a port\n // specified.\n (!allowedUri.port || allowedUri.port === requestUri.port) &&\n allowedUri.hostname === requestUri.hostname &&\n allowedUri.pathname === requestUri.pathname &&\n allowedUri.protocol === requestUri.protocol &&\n allowedUri.search === requestUri.search &&\n allowedUri.hash === requestUri.hash &&\n allowedUri.username === requestUri.username &&\n allowedUri.password === requestUri.password\n )\n }\n\n return false\n}\n"]}
@@ -1,15 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.onOvertimeDefault = onOvertimeDefault;
4
- exports.constantTime = constantTime;
5
- const promises_1 = require("node:timers/promises");
6
- function onOvertimeDefault(options) {
1
+ import { setTimeout as sleep } from 'node:timers/promises';
2
+ export function onOvertimeDefault(options) {
7
3
  console.warn(`constantTime: execution time was ${options.elapsed}ms (which is greater than ${options.time}ms). You should increase the "time" to properly defend against timing attacks.`);
8
4
  }
9
5
  /**
10
6
  * Utility function to protect against timing attacks.
11
7
  */
12
- async function constantTime(time, fn, onOvertime = onOvertimeDefault) {
8
+ export async function constantTime(time, fn, onOvertime = onOvertimeDefault) {
13
9
  if (!Number.isFinite(time) || time <= 0) {
14
10
  throw new TypeError(`"time" must be a positive number`);
15
11
  }
@@ -23,7 +19,7 @@ async function constantTime(time, fn, onOvertime = onOvertimeDefault) {
23
19
  const remaining = time - elapsed;
24
20
  if (remaining >= 0) {
25
21
  // Happy path, execution time was smaller than "time"
26
- await (0, promises_1.setTimeout)(remaining);
22
+ await sleep(remaining);
27
23
  }
28
24
  else {
29
25
  // The function execution took longer than "time"
@@ -31,7 +27,7 @@ async function constantTime(time, fn, onOvertime = onOvertimeDefault) {
31
27
  // Sleep until the next multiple of "time" to mitigate any attack
32
28
  const multiplier = Math.ceil(elapsed / time);
33
29
  const remaining = multiplier * time - elapsed;
34
- await (0, promises_1.setTimeout)(remaining);
30
+ await sleep(remaining);
35
31
  }
36
32
  }
37
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/lib/util/time.ts"],"names":[],"mappings":";;AAGA,8CASC;AAKD,oCA+BC;AAhDD,mDAA0D;AAG1D,SAAgB,iBAAiB,CAAC,OAKjC;IACC,OAAO,CAAC,IAAI,CACV,oCAAoC,OAAO,CAAC,OAAO,6BAA6B,OAAO,CAAC,IAAI,gFAAgF,CAC7K,CAAA;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,EAAsB,EACtB,UAAU,GAAG,iBAAiB;IAE9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAA;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,OAAO,GAAG,GAAG,GAAG,KAAK,CAAA;QAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,CAAA;QAChC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,qDAAqD;YACrD,MAAM,IAAA,qBAAK,EAAC,SAAS,CAAC,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YAEzC,iEAAiE;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;YAC5C,MAAM,SAAS,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,CAAA;YAE7C,MAAM,IAAA,qBAAK,EAAC,SAAS,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { Awaitable } from './type.js'\n\nexport function onOvertimeDefault(options: {\n start: number\n end: number\n elapsed: number\n time: number\n}): void {\n console.warn(\n `constantTime: execution time was ${options.elapsed}ms (which is greater than ${options.time}ms). You should increase the \"time\" to properly defend against timing attacks.`,\n )\n}\n\n/**\n * Utility function to protect against timing attacks.\n */\nexport async function constantTime<R>(\n time: number,\n fn: () => Awaitable<R>,\n onOvertime = onOvertimeDefault,\n): Promise<R> {\n if (!Number.isFinite(time) || time <= 0) {\n throw new TypeError(`\"time\" must be a positive number`)\n }\n\n const start = Date.now()\n try {\n return await fn()\n } finally {\n const end = Date.now()\n const elapsed = end - start\n\n const remaining = time - elapsed\n if (remaining >= 0) {\n // Happy path, execution time was smaller than \"time\"\n await sleep(remaining)\n } else {\n // The function execution took longer than \"time\"\n onOvertime({ start, end, elapsed, time })\n\n // Sleep until the next multiple of \"time\" to mitigate any attack\n const multiplier = Math.ceil(elapsed / time)\n const remaining = multiplier * time - elapsed\n\n await sleep(remaining)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/lib/util/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAG1D,MAAM,UAAU,iBAAiB,CAAC,OAKjC;IACC,OAAO,CAAC,IAAI,CACV,oCAAoC,OAAO,CAAC,OAAO,6BAA6B,OAAO,CAAC,IAAI,gFAAgF,CAC7K,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,EAAsB,EACtB,UAAU,GAAG,iBAAiB;IAE9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAA;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,OAAO,GAAG,GAAG,GAAG,KAAK,CAAA;QAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,CAAA;QAChC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,qDAAqD;YACrD,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YAEzC,iEAAiE;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;YAC5C,MAAM,SAAS,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,CAAA;YAE7C,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { Awaitable } from './type.js'\n\nexport function onOvertimeDefault(options: {\n start: number\n end: number\n elapsed: number\n time: number\n}): void {\n console.warn(\n `constantTime: execution time was ${options.elapsed}ms (which is greater than ${options.time}ms). You should increase the \"time\" to properly defend against timing attacks.`,\n )\n}\n\n/**\n * Utility function to protect against timing attacks.\n */\nexport async function constantTime<R>(\n time: number,\n fn: () => Awaitable<R>,\n onOvertime = onOvertimeDefault,\n): Promise<R> {\n if (!Number.isFinite(time) || time <= 0) {\n throw new TypeError(`\"time\" must be a positive number`)\n }\n\n const start = Date.now()\n try {\n return await fn()\n } finally {\n const end = Date.now()\n const elapsed = end - start\n\n const remaining = time - elapsed\n if (remaining >= 0) {\n // Happy path, execution time was smaller than \"time\"\n await sleep(remaining)\n } else {\n // The function execution took longer than \"time\"\n onOvertime({ start, end, elapsed, time })\n\n // Sleep until the next multiple of \"time\" to mitigate any attack\n const multiplier = Math.ceil(elapsed / time)\n const remaining = multiplier * time - elapsed\n\n await sleep(remaining)\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/lib/util/type.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/lib/util/type.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildInterfaceChecker = void 0;
4
1
  /**
5
2
  * This utility allows to create an assertion function that checks if a
6
3
  * particular interface is fully implemented by some value.
@@ -38,7 +35,6 @@ exports.buildInterfaceChecker = void 0;
38
35
  * buildInterfaceChecker<{ foo: string; bar: string }>(['foo', 'baz'])
39
36
  * ```
40
37
  */
41
- const buildInterfaceChecker = (keys) => (value) => keys.every((name) => value[name] !== undefined);
42
- exports.buildInterfaceChecker = buildInterfaceChecker;
38
+ export const buildInterfaceChecker = (keys) => (value) => keys.every((name) => value[name] !== undefined);
43
39
  // </hardcore-mode>
44
40
  //# sourceMappingURL=type.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"type.js","sourceRoot":"","sources":["../../../src/lib/util/type.ts"],"names":[],"mappings":";;;AA4IA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACI,MAAM,qBAAqB,GAChC,CAAmB,IAA+C,EAAE,EAAE,CACtE,CAAuB,KAAQ,EAAmC,EAAE,CAClE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAA;AAHtC,QAAA,qBAAqB,yBAGiB;AAEnD,mBAAmB","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-types\nexport type Simplify<T> = { [K in keyof T]: T[K] } & {}\nexport type Override<T, V> = Simplify<{\n [K in keyof (V & T)]: K extends keyof V\n ? V[K]\n : K extends keyof T\n ? T[K]\n : never\n}>\nexport type Awaitable<T> = T | Promise<T>\nexport type NonNullableKeys<T, K extends keyof T> = Simplify<\n OmitKey<T, K> & {\n [P in K]-?: NonNullable<T[P]>\n }\n>\n/**\n * When a type has an `[x: string]: unknown` index signature, in addition to\n * some known properties, using {@link Omit} will result in a type that only has\n * the index signature, and no known properties.\n *\n * ```ts\n * Omit<{ a: 3; b: 4; [x: string]: unknown }, 'a'> // { [x: string]: unknown }\n * ```\n *\n * In order to properly omit specific known properties from a type with an index\n * signature, we need to use another utility type that will behave correctly.\n *\n * ```ts\n * OmitKey<{ a: 3; b: 4; [x: string]: unknown }, 'a'> // { b: 4; [x: string]: unknown }\n * ```\n */\nexport type OmitKey<T, K extends keyof T> = {\n [K2 in keyof T as K2 extends K ? never : K2]: T[K2]\n}\n\nexport type RequiredKey<T, K extends keyof T = never> = Simplify<\n T & {\n [L in K]-?: unknown extends T[L]\n ? NonNullable<unknown> | null\n : Exclude<T[L], undefined>\n }\n>\n\n/**\n * Converts a tuple to the equivalent type of combining every item into a single\n * one. If any of the item in the tuple is non nullish, the result will be non\n * nullish.\n */\nexport type CombinedTuple<T extends readonly unknown[]> = T extends []\n ? undefined\n : Exclude<\n T[number],\n // If any item in the tuple is never `null` (resp. `undefined`), exclude\n // `null` (resp. `undefined`) from `T[number]`\n {\n [K in keyof T]-?:\n | (null extends T[K] ? never : null)\n | (undefined extends T[K] ? never : undefined)\n }[keyof T]\n >\n\n/**\n * Similar to {@link Required} but also ensures that all values are defined.\n */\nexport type RequiredDefined<T> = { [K in keyof T]-?: Exclude<T[K], undefined> }\n\n// <hardcore-mode> (don't touch this)\n\n/**\n * @example\n * ```ts\n * type F = UnionToFnUnion<'a' | 'b'> // (() => 'a') | (() => 'b')\n * ```\n */\ntype UnionToFnUnion<T> = T extends any ? () => T : never\n\n/**\n * @example\n * ```ts\n * type A = UnionToIntersection<(() => 'a') | (() => 'b')> // (() => 'a') & (() => 'b')\n *\n * UnionToIntersection<{ foo: string | number } | { foo: number; bar: 4 }> // { foo: number; bar: 4 }\n * ```\n */\ntype UnionToIntersection<T> = (T extends any ? (x: T) => void : never) extends (\n x: infer U,\n) => void\n ? U\n : never\n\n/**\n * @example\n * ```ts\n * type B = ExtractUnionItem<'a' | 'b'> // 'b'\n * ```\n */\ntype ExtractUnionItem<T> =\n // There exists a quirk in the way TypeScript works when inferring return\n // types of an (disjoined) intersection of functions:\n //\n // type AnB = (() => 'a') & (() => 'b')\n // type B = AnB extends () => infer R ? R : never // 'b'\n //\n // By turning the input union T (e.g. 'a' | 'b') into a union of function\n // (() => 'a') | (() => 'b') and then into an intersection of those functions\n // (() => 'a') & (() => 'b'), we can exploit the special TypeScript behavior\n // to infer only the last return type from the functions, which is effectively\n // equal to the last item of the input union T.\n UnionToIntersection<UnionToFnUnion<T>> extends () => infer R ? R : never\n\n/**\n * Utility that turn a union of types (`'a' | 'b'`) into a tuple with matching\n * types (`['a', 'b']`).\n *\n * @note this only work with unions of \"const\" types. Using this with globals\n * types (`string`, etc.) will yield unexpected results.\n *\n * @example\n * ```ts\n * type T = UnionToTuple<'a' | 'b'> // ['a', 'b']\n * type T = UnionToTuple<'a' | 'b' | 'c'> // ['a', 'b', 'c']\n * ```\n */\ntype UnionToTuple<T> = UnionToTupleInternal<T>\n\ntype UnionToTupleInternal<\n T,\n // Accumulator for terminal recursivity (initialized to empty tuple)\n Acc extends readonly any[] = [],\n // Get the next item from the union (if any)\n Next = ExtractUnionItem<T>,\n> =\n // If there were no more items to extract from the union T, then we are done\n [Next] extends [never]\n ? // Return result of previous recursive calls\n Acc\n : // Recursively call UnionToTupleInternal by Exclude'ing the Next item from\n // the union (T) and adding it to the accumulator.\n UnionToTupleInternal<Exclude<T, Next>, readonly [Next, ...Acc]>\n\n/**\n * This utility allows to create an assertion function that checks if a\n * particular interface is fully implemented by some value.\n *\n * The use of the (rather complex) {@link UnionToTuple} allows to ensure that,\n * at runtime, all the required interface keys are indeed checked, and that\n * future additions to the interface do not result in a false sense of type\n * safety.\n *\n * @note This function should not be made public, as it relies on a quirk of\n * TypeScript to work properly.\n *\n * @example Valid use\n *\n * ```ts\n * const isFoo = buildInterfaceChecker<{ foo: string }>(['foo'])\n * const isFooBar = buildInterfaceChecker<{ foo: string; bar: boolean }>([\n * 'foo',\n * 'bar',\n * ])\n *\n * declare const val: { foo?: string }\n *\n * if (isFoo(val)) {\n * val // { foo: string }\n * }\n * ```\n *\n * @example Use cases where the runtime keys do not match the interface keys\n *\n * ```ts\n * buildInterfaceChecker<{ foo: string }>([])\n * buildInterfaceChecker<{ foo: string }>(['fee'])\n * buildInterfaceChecker<{ foo: string; bar: string }>(['foo'])\n * buildInterfaceChecker<{ foo: string; bar: string }>(['foo', 'baz'])\n * ```\n */\nexport const buildInterfaceChecker =\n <I extends object>(keys: readonly string[] & UnionToTuple<keyof I>) =>\n <V extends Partial<I>>(value: V): value is V & RequiredDefined<I> =>\n keys.every((name) => value[name] !== undefined)\n\n// </hardcore-mode>\n"]}
1
+ {"version":3,"file":"type.js","sourceRoot":"","sources":["../../../src/lib/util/type.ts"],"names":[],"mappings":"AA2IA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAChC,CAAmB,IAA+C,EAAE,EAAE,CACtE,CAAuB,KAAQ,EAAmC,EAAE,CAClE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAA;AAEnD,mBAAmB","sourcesContent":["export type Simplify<T> = { [K in keyof T]: T[K] } & {}\nexport type Override<T, V> = Simplify<{\n [K in keyof (V & T)]: K extends keyof V\n ? V[K]\n : K extends keyof T\n ? T[K]\n : never\n}>\nexport type Awaitable<T> = T | Promise<T>\nexport type NonNullableKeys<T, K extends keyof T> = Simplify<\n OmitKey<T, K> & {\n [P in K]-?: NonNullable<T[P]>\n }\n>\n/**\n * When a type has an `[x: string]: unknown` index signature, in addition to\n * some known properties, using {@link Omit} will result in a type that only has\n * the index signature, and no known properties.\n *\n * ```ts\n * Omit<{ a: 3; b: 4; [x: string]: unknown }, 'a'> // { [x: string]: unknown }\n * ```\n *\n * In order to properly omit specific known properties from a type with an index\n * signature, we need to use another utility type that will behave correctly.\n *\n * ```ts\n * OmitKey<{ a: 3; b: 4; [x: string]: unknown }, 'a'> // { b: 4; [x: string]: unknown }\n * ```\n */\nexport type OmitKey<T, K extends keyof T> = {\n [K2 in keyof T as K2 extends K ? never : K2]: T[K2]\n}\n\nexport type RequiredKey<T, K extends keyof T = never> = Simplify<\n T & {\n [L in K]-?: unknown extends T[L]\n ? NonNullable<unknown> | null\n : Exclude<T[L], undefined>\n }\n>\n\n/**\n * Converts a tuple to the equivalent type of combining every item into a single\n * one. If any of the item in the tuple is non nullish, the result will be non\n * nullish.\n */\nexport type CombinedTuple<T extends readonly unknown[]> = T extends []\n ? undefined\n : Exclude<\n T[number],\n // If any item in the tuple is never `null` (resp. `undefined`), exclude\n // `null` (resp. `undefined`) from `T[number]`\n {\n [K in keyof T]-?:\n | (null extends T[K] ? never : null)\n | (undefined extends T[K] ? never : undefined)\n }[keyof T]\n >\n\n/**\n * Similar to {@link Required} but also ensures that all values are defined.\n */\nexport type RequiredDefined<T> = { [K in keyof T]-?: Exclude<T[K], undefined> }\n\n// <hardcore-mode> (don't touch this)\n\n/**\n * @example\n * ```ts\n * type F = UnionToFnUnion<'a' | 'b'> // (() => 'a') | (() => 'b')\n * ```\n */\ntype UnionToFnUnion<T> = T extends any ? () => T : never\n\n/**\n * @example\n * ```ts\n * type A = UnionToIntersection<(() => 'a') | (() => 'b')> // (() => 'a') & (() => 'b')\n *\n * UnionToIntersection<{ foo: string | number } | { foo: number; bar: 4 }> // { foo: number; bar: 4 }\n * ```\n */\ntype UnionToIntersection<T> = (T extends any ? (x: T) => void : never) extends (\n x: infer U,\n) => void\n ? U\n : never\n\n/**\n * @example\n * ```ts\n * type B = ExtractUnionItem<'a' | 'b'> // 'b'\n * ```\n */\ntype ExtractUnionItem<T> =\n // There exists a quirk in the way TypeScript works when inferring return\n // types of an (disjoined) intersection of functions:\n //\n // type AnB = (() => 'a') & (() => 'b')\n // type B = AnB extends () => infer R ? R : never // 'b'\n //\n // By turning the input union T (e.g. 'a' | 'b') into a union of function\n // (() => 'a') | (() => 'b') and then into an intersection of those functions\n // (() => 'a') & (() => 'b'), we can exploit the special TypeScript behavior\n // to infer only the last return type from the functions, which is effectively\n // equal to the last item of the input union T.\n UnionToIntersection<UnionToFnUnion<T>> extends () => infer R ? R : never\n\n/**\n * Utility that turn a union of types (`'a' | 'b'`) into a tuple with matching\n * types (`['a', 'b']`).\n *\n * @note this only work with unions of \"const\" types. Using this with globals\n * types (`string`, etc.) will yield unexpected results.\n *\n * @example\n * ```ts\n * type T = UnionToTuple<'a' | 'b'> // ['a', 'b']\n * type T = UnionToTuple<'a' | 'b' | 'c'> // ['a', 'b', 'c']\n * ```\n */\ntype UnionToTuple<T> = UnionToTupleInternal<T>\n\ntype UnionToTupleInternal<\n T,\n // Accumulator for terminal recursivity (initialized to empty tuple)\n Acc extends readonly any[] = [],\n // Get the next item from the union (if any)\n Next = ExtractUnionItem<T>,\n> =\n // If there were no more items to extract from the union T, then we are done\n [Next] extends [never]\n ? // Return result of previous recursive calls\n Acc\n : // Recursively call UnionToTupleInternal by Exclude'ing the Next item from\n // the union (T) and adding it to the accumulator.\n UnionToTupleInternal<Exclude<T, Next>, readonly [Next, ...Acc]>\n\n/**\n * This utility allows to create an assertion function that checks if a\n * particular interface is fully implemented by some value.\n *\n * The use of the (rather complex) {@link UnionToTuple} allows to ensure that,\n * at runtime, all the required interface keys are indeed checked, and that\n * future additions to the interface do not result in a false sense of type\n * safety.\n *\n * @note This function should not be made public, as it relies on a quirk of\n * TypeScript to work properly.\n *\n * @example Valid use\n *\n * ```ts\n * const isFoo = buildInterfaceChecker<{ foo: string }>(['foo'])\n * const isFooBar = buildInterfaceChecker<{ foo: string; bar: boolean }>([\n * 'foo',\n * 'bar',\n * ])\n *\n * declare const val: { foo?: string }\n *\n * if (isFoo(val)) {\n * val // { foo: string }\n * }\n * ```\n *\n * @example Use cases where the runtime keys do not match the interface keys\n *\n * ```ts\n * buildInterfaceChecker<{ foo: string }>([])\n * buildInterfaceChecker<{ foo: string }>(['fee'])\n * buildInterfaceChecker<{ foo: string; bar: string }>(['foo'])\n * buildInterfaceChecker<{ foo: string; bar: string }>(['foo', 'baz'])\n * ```\n */\nexport const buildInterfaceChecker =\n <I extends object>(keys: readonly string[] & UnionToTuple<keyof I>) =>\n <V extends Partial<I>>(value: V): value is V & RequiredDefined<I> =>\n keys.every((name) => value[name] !== undefined)\n\n// </hardcore-mode>\n"]}
@@ -1,15 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseUi8Hex = parseUi8Hex;
4
- exports.parseUi8Dec = parseUi8Dec;
5
- exports.asUi8 = asUi8;
6
- function parseUi8Hex(v) {
1
+ export function parseUi8Hex(v) {
7
2
  return asUi8(parseInt(v, 16));
8
3
  }
9
- function parseUi8Dec(v) {
4
+ export function parseUi8Dec(v) {
10
5
  return asUi8(parseInt(v, 10));
11
6
  }
12
- function asUi8(v) {
7
+ export function asUi8(v) {
13
8
  if (v >= 0 && v <= 255 && Number.isInteger(v))
14
9
  return v;
15
10
  throw new TypeError(`Invalid value "${v}" (expected an integer between 0 and 255)`);
@@ -1 +1 @@
1
- {"version":3,"file":"ui8.js","sourceRoot":"","sources":["../../../src/lib/util/ui8.ts"],"names":[],"mappings":";;AAAA,kCAEC;AAED,kCAEC;AAED,sBAKC;AAbD,SAAgB,WAAW,CAAC,CAAS;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,SAAgB,WAAW,CAAC,CAAS;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,SAAgB,KAAK,CAAC,CAAS;IAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAA;IACvD,MAAM,IAAI,SAAS,CACjB,kBAAkB,CAAC,2CAA2C,CAC/D,CAAA;AACH,CAAC","sourcesContent":["export function parseUi8Hex(v: string) {\n return asUi8(parseInt(v, 16))\n}\n\nexport function parseUi8Dec(v: string) {\n return asUi8(parseInt(v, 10))\n}\n\nexport function asUi8(v: number) {\n if (v >= 0 && v <= 255 && Number.isInteger(v)) return v\n throw new TypeError(\n `Invalid value \"${v}\" (expected an integer between 0 and 255)`,\n )\n}\n"]}
1
+ {"version":3,"file":"ui8.js","sourceRoot":"","sources":["../../../src/lib/util/ui8.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAA;IACvD,MAAM,IAAI,SAAS,CACjB,kBAAkB,CAAC,2CAA2C,CAC/D,CAAA;AACH,CAAC","sourcesContent":["export function parseUi8Hex(v: string) {\n return asUi8(parseInt(v, 16))\n}\n\nexport function parseUi8Dec(v: string) {\n return asUi8(parseInt(v, 10))\n}\n\nexport function asUi8(v: number) {\n if (v >= 0 && v <= 255 && Number.isInteger(v)) return v\n throw new TypeError(\n `Invalid value \"${v}\" (expected an integer between 0 and 255)`,\n )\n}\n"]}
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildWellknownUrl = buildWellknownUrl;
4
- function buildWellknownUrl(url, name) {
1
+ export function buildWellknownUrl(url, name) {
5
2
  const path = url.pathname === '/'
6
3
  ? `/.well-known/${name}`
7
4
  : `${url.pathname.replace(/\/+$/, '')}/${name}`;
@@ -1 +1 @@
1
- {"version":3,"file":"well-known.js","sourceRoot":"","sources":["../../../src/lib/util/well-known.ts"],"names":[],"mappings":";;AAAA,8CAOC;AAPD,SAAgB,iBAAiB,CAAC,GAAQ,EAAE,IAAY;IACtD,MAAM,IAAI,GACR,GAAG,CAAC,QAAQ,KAAK,GAAG;QAClB,CAAC,CAAC,gBAAgB,IAAI,EAAE;QACxB,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAA;IAEnD,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;AAC3B,CAAC","sourcesContent":["export function buildWellknownUrl(url: URL, name: string): URL {\n const path =\n url.pathname === '/'\n ? `/.well-known/${name}`\n : `${url.pathname.replace(/\\/+$/, '')}/${name}`\n\n return new URL(path, url)\n}\n"]}
1
+ {"version":3,"file":"well-known.js","sourceRoot":"","sources":["../../../src/lib/util/well-known.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,GAAQ,EAAE,IAAY;IACtD,MAAM,IAAI,GACR,GAAG,CAAC,QAAQ,KAAK,GAAG;QAClB,CAAC,CAAC,gBAAgB,IAAI,EAAE;QACxB,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAA;IAEnD,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;AAC3B,CAAC","sourcesContent":["export function buildWellknownUrl(url: URL, name: string): URL {\n const path =\n url.pathname === '/'\n ? `/.well-known/${name}`\n : `${url.pathname.replace(/\\/+$/, '')}/${name}`\n\n return new URL(path, url)\n}\n"]}
@@ -1,16 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatZodError = formatZodError;
4
- exports.formatZodIssue = formatZodIssue;
5
- const zod_1 = require("zod");
6
- function formatZodError(err, prefix) {
1
+ import { ZodIssueCode } from 'zod';
2
+ export function formatZodError(err, prefix) {
7
3
  const message = err.issues.length
8
4
  ? err.issues.map(formatZodIssue).join('; ')
9
5
  : err.message; // Should never happen (issues should never be empty)
10
6
  return prefix ? `${prefix}: ${message}` : message;
11
7
  }
12
- function formatZodIssue(issue) {
13
- if (issue.code === zod_1.ZodIssueCode.invalid_union) {
8
+ export function formatZodIssue(issue) {
9
+ if (issue.code === ZodIssueCode.invalid_union) {
14
10
  return issue.unionErrors
15
11
  .map((err) => err.issues.map(formatZodIssue).join('; '))
16
12
  .join(', or ');
@@ -1 +1 @@
1
- {"version":3,"file":"zod-error.js","sourceRoot":"","sources":["../../../src/lib/util/zod-error.ts"],"names":[],"mappings":";;AAEA,wCAKC;AAED,wCAgBC;AAzBD,6BAAsD;AAEtD,SAAgB,cAAc,CAAC,GAAa,EAAE,MAAe;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM;QAC/B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAA,CAAC,qDAAqD;IACrE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;AACnD,CAAC;AAED,SAAgB,cAAc,CAAC,KAAe;IAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAY,CAAC,aAAa,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,WAAW;aACrB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACvD,IAAI,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,GAAG,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,GAAG,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,OAAO,CAAA;AACtB,CAAC","sourcesContent":["import { ZodError, ZodIssue, ZodIssueCode } from 'zod'\n\nexport function formatZodError(err: ZodError, prefix?: string): string {\n const message = err.issues.length\n ? err.issues.map(formatZodIssue).join('; ')\n : err.message // Should never happen (issues should never be empty)\n return prefix ? `${prefix}: ${message}` : message\n}\n\nexport function formatZodIssue(issue: ZodIssue): string {\n if (issue.code === ZodIssueCode.invalid_union) {\n return issue.unionErrors\n .map((err) => err.issues.map(formatZodIssue).join('; '))\n .join(', or ')\n }\n\n if (issue.path.length === 1 && typeof issue.path[0] === 'number') {\n return `${issue.message} at index ${issue.path[0]}`\n }\n\n if (issue.path.length) {\n return `${issue.message} at ${issue.path.join('.')}`\n }\n\n return issue.message\n}\n"]}
1
+ {"version":3,"file":"zod-error.js","sourceRoot":"","sources":["../../../src/lib/util/zod-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,KAAK,CAAA;AAEtD,MAAM,UAAU,cAAc,CAAC,GAAa,EAAE,MAAe;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM;QAC/B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAA,CAAC,qDAAqD;IACrE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAe;IAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,aAAa,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,WAAW;aACrB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACvD,IAAI,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,GAAG,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,GAAG,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,OAAO,CAAA;AACtB,CAAC","sourcesContent":["import { ZodError, ZodIssue, ZodIssueCode } from 'zod'\n\nexport function formatZodError(err: ZodError, prefix?: string): string {\n const message = err.issues.length\n ? err.issues.map(formatZodIssue).join('; ')\n : err.message // Should never happen (issues should never be empty)\n return prefix ? `${prefix}: ${message}` : message\n}\n\nexport function formatZodIssue(issue: ZodIssue): string {\n if (issue.code === ZodIssueCode.invalid_union) {\n return issue.unionErrors\n .map((err) => err.issues.map(formatZodIssue).join('; '))\n .join(', or ')\n }\n\n if (issue.path.length === 1 && typeof issue.path[0] === 'number') {\n return `${issue.message} at index ${issue.path[0]}`\n }\n\n if (issue.path.length) {\n return `${issue.message} at ${issue.path.join('.')}`\n }\n\n return issue.message\n}\n"]}
@@ -1,12 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeFormRedirect = writeFormRedirect;
4
- const index_js_1 = require("./html/index.js");
5
- const request_js_1 = require("./http/request.js");
6
- const write_html_js_1 = require("./write-html.js");
1
+ import { html, js } from './html/index.js';
2
+ import { setCookie } from './http/request.js';
3
+ import { writeHtml } from './write-html.js';
7
4
  // We prevent the user from coming "back" to this page and resubmitting the form
8
5
  // repeatedly by disabling the submit button after the first submission.
9
- const SCRIPT = (0, index_js_1.js) `
6
+ const SCRIPT = js `
10
7
  const form = document.forms[0];
11
8
 
12
9
  let canSubmit = true;
@@ -25,19 +22,19 @@ setTimeout(() => {
25
22
  `;
26
23
  // @NOTE If translations and design are needed, consider replacing this with a
27
24
  // web app page.
28
- function writeFormRedirect(res, method, uri, params, options) {
25
+ export function writeFormRedirect(res, method, uri, params, options) {
29
26
  res.setHeader('Cache-Control', 'no-store');
30
27
  // Prevent the Chrome from caching this page
31
28
  // see: https://latesthackingnews.com/2023/12/12/google-updates-chrome-bfcache-for-faster-page-viewing/
32
- (0, request_js_1.setCookie)(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' });
33
- return (0, write_html_js_1.writeHtml)(res, {
29
+ setCookie(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' });
30
+ return writeHtml(res, {
34
31
  ...options,
35
32
  htmlAttrs: { lang: 'en' },
36
33
  scripts: [SCRIPT],
37
- body: (0, index_js_1.html) `
34
+ body: html `
38
35
  <form method="${method}" action="${uri}">
39
36
  ${Array.from(params, ([key, value]) => [
40
- (0, index_js_1.html) `<input type="hidden" name="${key}" value="${value}" />`,
37
+ html `<input type="hidden" name="${key}" value="${value}" />`,
41
38
  ])}
42
39
  <input type="submit" value="Continue" />
43
40
  </form>
@@ -1 +1 @@
1
- {"version":3,"file":"write-form-redirect.js","sourceRoot":"","sources":["../../src/lib/write-form-redirect.ts"],"names":[],"mappings":";;AA+BA,8CA0BC;AAxDD,8CAA0C;AAC1C,kDAA6C;AAE7C,mDAA2C;AAI3C,gFAAgF;AAChF,wEAAwE;AACxE,MAAM,MAAM,GAAG,IAAA,aAAE,EAAA;;;;;;;;;;;;;;;;CAgBhB,CAAA;AAED,8EAA8E;AAC9E,gBAAgB;AAEhB,SAAgB,iBAAiB,CAC/B,GAAmB,EACnB,MAAsB,EACtB,GAAW,EACX,MAAkC,EAClC,OAAkC;IAElC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAE1C,4CAA4C;IAC5C,uGAAuG;IACvG,IAAA,sBAAS,EAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;IAEtE,OAAO,IAAA,yBAAS,EAAC,GAAG,EAAE;QACpB,GAAG,OAAO;QACV,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,IAAA,eAAI,EAAA;sBACQ,MAAM,aAAa,GAAG;UAClC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACrC,IAAA,eAAI,EAAA,8BAA8B,GAAG,YAAY,KAAK,MAAM;SAC7D,CAAC;;;KAGL;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { ServerResponse } from 'node:http'\nimport { html, js } from './html/index.js'\nimport { setCookie } from './http/request.js'\nimport { SecurityHeadersOptions } from './http/security-headers.js'\nimport { writeHtml } from './write-html.js'\n\nexport type WriteFormRedirectOptions = SecurityHeadersOptions\n\n// We prevent the user from coming \"back\" to this page and resubmitting the form\n// repeatedly by disabling the submit button after the first submission.\nconst SCRIPT = js`\nconst form = document.forms[0];\n\nlet canSubmit = true;\n\nform.addEventListener('submit', (event) => {\n if (!canSubmit) {\n event.preventDefault();\n } else {\n canSubmit = false;\n }\n});\n\nsetTimeout(() => {\n form.submit();\n}, 1);\n`\n\n// @NOTE If translations and design are needed, consider replacing this with a\n// web app page.\n\nexport function writeFormRedirect(\n res: ServerResponse,\n method: 'post' | 'get',\n uri: string,\n params: Iterable<[string, string]>,\n options?: WriteFormRedirectOptions,\n): void {\n res.setHeader('Cache-Control', 'no-store')\n\n // Prevent the Chrome from caching this page\n // see: https://latesthackingnews.com/2023/12/12/google-updates-chrome-bfcache-for-faster-page-viewing/\n setCookie(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' })\n\n return writeHtml(res, {\n ...options,\n htmlAttrs: { lang: 'en' },\n scripts: [SCRIPT],\n body: html`\n <form method=\"${method}\" action=\"${uri}\">\n ${Array.from(params, ([key, value]) => [\n html`<input type=\"hidden\" name=\"${key}\" value=\"${value}\" />`,\n ])}\n <input type=\"submit\" value=\"Continue\" />\n </form>\n `,\n })\n}\n"]}
1
+ {"version":3,"file":"write-form-redirect.js","sourceRoot":"","sources":["../../src/lib/write-form-redirect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAI3C,gFAAgF;AAChF,wEAAwE;AACxE,MAAM,MAAM,GAAG,EAAE,CAAA;;;;;;;;;;;;;;;;CAgBhB,CAAA;AAED,8EAA8E;AAC9E,gBAAgB;AAEhB,MAAM,UAAU,iBAAiB,CAC/B,GAAmB,EACnB,MAAsB,EACtB,GAAW,EACX,MAAkC,EAClC,OAAkC;IAElC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAE1C,4CAA4C;IAC5C,uGAAuG;IACvG,SAAS,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;IAEtE,OAAO,SAAS,CAAC,GAAG,EAAE;QACpB,GAAG,OAAO;QACV,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,IAAI,CAAA;sBACQ,MAAM,aAAa,GAAG;UAClC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAA,8BAA8B,GAAG,YAAY,KAAK,MAAM;SAC7D,CAAC;;;KAGL;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { ServerResponse } from 'node:http'\nimport { html, js } from './html/index.js'\nimport { setCookie } from './http/request.js'\nimport { SecurityHeadersOptions } from './http/security-headers.js'\nimport { writeHtml } from './write-html.js'\n\nexport type WriteFormRedirectOptions = SecurityHeadersOptions\n\n// We prevent the user from coming \"back\" to this page and resubmitting the form\n// repeatedly by disabling the submit button after the first submission.\nconst SCRIPT = js`\nconst form = document.forms[0];\n\nlet canSubmit = true;\n\nform.addEventListener('submit', (event) => {\n if (!canSubmit) {\n event.preventDefault();\n } else {\n canSubmit = false;\n }\n});\n\nsetTimeout(() => {\n form.submit();\n}, 1);\n`\n\n// @NOTE If translations and design are needed, consider replacing this with a\n// web app page.\n\nexport function writeFormRedirect(\n res: ServerResponse,\n method: 'post' | 'get',\n uri: string,\n params: Iterable<[string, string]>,\n options?: WriteFormRedirectOptions,\n): void {\n res.setHeader('Cache-Control', 'no-store')\n\n // Prevent the Chrome from caching this page\n // see: https://latesthackingnews.com/2023/12/12/google-updates-chrome-bfcache-for-faster-page-viewing/\n setCookie(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' })\n\n return writeHtml(res, {\n ...options,\n htmlAttrs: { lang: 'en' },\n scripts: [SCRIPT],\n body: html`\n <form method=\"${method}\" action=\"${uri}\">\n ${Array.from(params, ([key, value]) => [\n html`<input type=\"hidden\" name=\"${key}\" value=\"${value}\" />`,\n ])}\n <input type=\"submit\" value=\"Continue\" />\n </form>\n `,\n })\n}\n"]}
@@ -1,18 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeHtml = writeHtml;
4
- const node_crypto_1 = require("node:crypto");
5
- const index_js_1 = require("./csp/index.js");
6
- const index_js_2 = require("./html/index.js");
7
- const response_js_1 = require("./http/response.js");
8
- const security_headers_js_1 = require("./http/security-headers.js");
9
- function writeHtml(res, options) {
1
+ import { createHash } from 'node:crypto';
2
+ import { mergeCsp } from './csp/index.js';
3
+ import { Html, buildDocument, } from './html/index.js';
4
+ import { writeBuffer } from './http/response.js';
5
+ import { setSecurityHeaders, } from './http/security-headers.js';
6
+ export function writeHtml(res, options) {
10
7
  // @NOTE the csp string might be quite long. In that case it might be tempting
11
8
  // to set it through the http-equiv <meta> in the HTML. However, some
12
9
  // directives cannot be enforced by browsers when set through the meta tag
13
10
  // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the
14
11
  // HTTP header.
15
- const csp = (0, index_js_1.mergeCsp)({
12
+ const csp = mergeCsp({
16
13
  // Keep "upgrade-insecure-requests" in sync with HSTS setting. HSTS is
17
14
  // typically set to false for localhost endpoints. Chrome and FF will
18
15
  // ignore "upgrade-insecure-requests" from localhost, but Safari will
@@ -23,10 +20,10 @@ function writeHtml(res, options) {
23
20
  'script-src': options.scripts?.map(assetToCsp).filter((v) => v != null),
24
21
  'style-src': options.styles?.map(assetToCsp).filter((v) => v != null),
25
22
  }, options.csp);
26
- const html = (0, index_js_2.buildDocument)(options).toString();
23
+ const html = buildDocument(options).toString();
27
24
  // HTML pages should always be served with safety protection headers
28
- (0, security_headers_js_1.setSecurityHeaders)(res, { ...options, csp });
29
- (0, response_js_1.writeBuffer)(res, html, {
25
+ setSecurityHeaders(res, { ...options, csp });
26
+ writeBuffer(res, html, {
30
27
  ...options,
31
28
  contentType: options?.contentType ?? 'text/html; charset=utf-8',
32
29
  });
@@ -34,9 +31,9 @@ function writeHtml(res, options) {
34
31
  function assetToCsp(asset) {
35
32
  if (asset == null)
36
33
  return undefined;
37
- if (asset instanceof index_js_2.Html) {
34
+ if (asset instanceof Html) {
38
35
  // Inline assets are "allowed" by their hash
39
- const hash = (0, node_crypto_1.createHash)('sha256');
36
+ const hash = createHash('sha256');
40
37
  for (const fragment of asset)
41
38
  hash.update(fragment);
42
39
  return `'sha256-${hash.digest('base64')}'`;
@@ -1 +1 @@
1
- {"version":3,"file":"write-html.js","sourceRoot":"","sources":["../../src/lib/write-html.ts"],"names":[],"mappings":";;AAmBA,8BAgCC;AAnDD,6CAAwC;AAExC,6CAAmD;AACnD,8CAKwB;AACxB,oDAAsE;AACtE,oEAGmC;AAMnC,SAAgB,SAAS,CACvB,GAAmB,EACnB,OAAyB;IAEzB,8EAA8E;IAC9E,qEAAqE;IACrE,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAe;IACf,MAAM,GAAG,GAAG,IAAA,mBAAQ,EAClB;QACE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,mEAAmE;QACnE,2BAA2B,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK;QACnD,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACvE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;KACtE,EACD,OAAO,CAAC,GAAG,CACZ,CAAA;IAED,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAE9C,oEAAoE;IACpE,IAAA,wCAAkB,EAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5C,IAAA,yBAAW,EAAC,GAAG,EAAE,IAAI,EAAE;QACrB,GAAG,OAAO;QACV,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,0BAA0B;KAChE,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB;IACzC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,KAAK,YAAY,eAAI,EAAE,CAAC;QAC1B,4CAA4C;QAC5C,MAAM,IAAI,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAA;QACjC,KAAK,MAAM,QAAQ,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACnD,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAA;IAC5C,CAAC;SAAM,CAAC;QACN,iDAAiD;QACjD,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAA8C,CAAA;QAC1E,CAAC;QAED,kDAAkD;QAClD,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC","sourcesContent":["import { createHash } from 'node:crypto'\nimport type { ServerResponse } from 'node:http'\nimport { CspValue, mergeCsp } from './csp/index.js'\nimport {\n AssetRef,\n BuildDocumentOptions,\n Html,\n buildDocument,\n} from './html/index.js'\nimport { WriteResponseOptions, writeBuffer } from './http/response.js'\nimport {\n SecurityHeadersOptions,\n setSecurityHeaders,\n} from './http/security-headers.js'\n\nexport type WriteHtmlOptions = BuildDocumentOptions &\n WriteResponseOptions &\n SecurityHeadersOptions\n\nexport function writeHtml(\n res: ServerResponse,\n options: WriteHtmlOptions,\n): void {\n // @NOTE the csp string might be quite long. In that case it might be tempting\n // to set it through the http-equiv <meta> in the HTML. However, some\n // directives cannot be enforced by browsers when set through the meta tag\n // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the\n // HTTP header.\n const csp = mergeCsp(\n {\n // Keep \"upgrade-insecure-requests\" in sync with HSTS setting. HSTS is\n // typically set to false for localhost endpoints. Chrome and FF will\n // ignore \"upgrade-insecure-requests\" from localhost, but Safari will\n // enforce it, requiring to be explicitly disable it for localhost.\n 'upgrade-insecure-requests': options.hsts !== false,\n 'default-src': [\"'none'\"],\n 'base-uri': options.base?.origin as undefined | `https://${string}`,\n 'script-src': options.scripts?.map(assetToCsp).filter((v) => v != null),\n 'style-src': options.styles?.map(assetToCsp).filter((v) => v != null),\n },\n options.csp,\n )\n\n const html = buildDocument(options).toString()\n\n // HTML pages should always be served with safety protection headers\n setSecurityHeaders(res, { ...options, csp })\n writeBuffer(res, html, {\n ...options,\n contentType: options?.contentType ?? 'text/html; charset=utf-8',\n })\n}\n\nfunction assetToCsp(asset?: Html | AssetRef): undefined | CspValue {\n if (asset == null) return undefined\n if (asset instanceof Html) {\n // Inline assets are \"allowed\" by their hash\n const hash = createHash('sha256')\n for (const fragment of asset) hash.update(fragment)\n return `'sha256-${hash.digest('base64')}'`\n } else {\n // External assets are referenced by their origin\n if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {\n return new URL(asset.url).origin as `https:${string}` | `http:${string}`\n }\n\n // Internal assets are served from the same origin\n return `'self'`\n }\n}\n"]}
1
+ {"version":3,"file":"write-html.js","sourceRoot":"","sources":["../../src/lib/write-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAY,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAGL,IAAI,EACJ,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAwB,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAEL,kBAAkB,GACnB,MAAM,4BAA4B,CAAA;AAMnC,MAAM,UAAU,SAAS,CACvB,GAAmB,EACnB,OAAyB;IAEzB,8EAA8E;IAC9E,qEAAqE;IACrE,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAe;IACf,MAAM,GAAG,GAAG,QAAQ,CAClB;QACE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,mEAAmE;QACnE,2BAA2B,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK;QACnD,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACvE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;KACtE,EACD,OAAO,CAAC,GAAG,CACZ,CAAA;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAE9C,oEAAoE;IACpE,kBAAkB,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5C,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE;QACrB,GAAG,OAAO;QACV,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,0BAA0B;KAChE,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB;IACzC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,4CAA4C;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;QACjC,KAAK,MAAM,QAAQ,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACnD,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAA;IAC5C,CAAC;SAAM,CAAC;QACN,iDAAiD;QACjD,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAA8C,CAAA;QAC1E,CAAC;QAED,kDAAkD;QAClD,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC","sourcesContent":["import { createHash } from 'node:crypto'\nimport type { ServerResponse } from 'node:http'\nimport { CspValue, mergeCsp } from './csp/index.js'\nimport {\n AssetRef,\n BuildDocumentOptions,\n Html,\n buildDocument,\n} from './html/index.js'\nimport { WriteResponseOptions, writeBuffer } from './http/response.js'\nimport {\n SecurityHeadersOptions,\n setSecurityHeaders,\n} from './http/security-headers.js'\n\nexport type WriteHtmlOptions = BuildDocumentOptions &\n WriteResponseOptions &\n SecurityHeadersOptions\n\nexport function writeHtml(\n res: ServerResponse,\n options: WriteHtmlOptions,\n): void {\n // @NOTE the csp string might be quite long. In that case it might be tempting\n // to set it through the http-equiv <meta> in the HTML. However, some\n // directives cannot be enforced by browsers when set through the meta tag\n // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the\n // HTTP header.\n const csp = mergeCsp(\n {\n // Keep \"upgrade-insecure-requests\" in sync with HSTS setting. HSTS is\n // typically set to false for localhost endpoints. Chrome and FF will\n // ignore \"upgrade-insecure-requests\" from localhost, but Safari will\n // enforce it, requiring to be explicitly disable it for localhost.\n 'upgrade-insecure-requests': options.hsts !== false,\n 'default-src': [\"'none'\"],\n 'base-uri': options.base?.origin as undefined | `https://${string}`,\n 'script-src': options.scripts?.map(assetToCsp).filter((v) => v != null),\n 'style-src': options.styles?.map(assetToCsp).filter((v) => v != null),\n },\n options.csp,\n )\n\n const html = buildDocument(options).toString()\n\n // HTML pages should always be served with safety protection headers\n setSecurityHeaders(res, { ...options, csp })\n writeBuffer(res, html, {\n ...options,\n contentType: options?.contentType ?? 'text/html; charset=utf-8',\n })\n}\n\nfunction assetToCsp(asset?: Html | AssetRef): undefined | CspValue {\n if (asset == null) return undefined\n if (asset instanceof Html) {\n // Inline assets are \"allowed\" by their hash\n const hash = createHash('sha256')\n for (const fragment of asset) hash.update(fragment)\n return `'sha256-${hash.digest('base64')}'`\n } else {\n // External assets are referenced by their origin\n if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {\n return new URL(asset.url).origin as `https:${string}` | `http:${string}`\n }\n\n // Internal assets are served from the same origin\n return `'self'`\n }\n}\n"]}
@@ -1,16 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildMetadata = buildMetadata;
4
- const oauth_types_1 = require("@atproto/oauth-types");
5
- const client_js_1 = require("../client/client.js");
6
- const crypto_js_1 = require("../lib/util/crypto.js");
1
+ import { oauthAuthorizationServerMetadataValidator, } from '@atproto/oauth-types';
2
+ import { Client } from '../client/client.js';
3
+ import { VERIFY_ALGOS } from '../lib/util/crypto.js';
7
4
  /**
8
5
  * @see {@link https://datatracker.ietf.org/doc/html/rfc8414#section-2}
9
6
  * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata}
10
7
  * @see {@link https://openid.net/specs/openid-connect-prompt-create-1_0.html}
11
8
  */
12
- function buildMetadata(issuer, keyset, customMetadata) {
13
- return oauth_types_1.oauthAuthorizationServerMetadataValidator.parse({
9
+ export function buildMetadata(issuer, keyset, customMetadata) {
10
+ return oauthAuthorizationServerMetadataValidator.parse({
14
11
  issuer,
15
12
  scopes_supported: [
16
13
  'atproto',
@@ -78,7 +75,7 @@ function buildMetadata(issuer, keyset, customMetadata) {
78
75
  // https://datatracker.ietf.org/doc/html/rfc9207
79
76
  authorization_response_iss_parameter_supported: true,
80
77
  // https://datatracker.ietf.org/doc/html/rfc9101#section-4
81
- request_object_signing_alg_values_supported: [...crypto_js_1.VERIFY_ALGOS, 'none'],
78
+ request_object_signing_alg_values_supported: [...VERIFY_ALGOS, 'none'],
82
79
  request_object_encryption_alg_values_supported: [], // None
83
80
  request_object_encryption_enc_values_supported: [], // None
84
81
  request_parameter_supported: true,
@@ -87,8 +84,8 @@ function buildMetadata(issuer, keyset, customMetadata) {
87
84
  jwks_uri: new URL('/oauth/jwks', issuer).href,
88
85
  authorization_endpoint: new URL('/oauth/authorize', issuer).href,
89
86
  token_endpoint: new URL('/oauth/token', issuer).href,
90
- token_endpoint_auth_methods_supported: [...client_js_1.Client.AUTH_METHODS_SUPPORTED],
91
- token_endpoint_auth_signing_alg_values_supported: [...crypto_js_1.VERIFY_ALGOS],
87
+ token_endpoint_auth_methods_supported: [...Client.AUTH_METHODS_SUPPORTED],
88
+ token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],
92
89
  revocation_endpoint: new URL('/oauth/revoke', issuer).href,
93
90
  // @TODO Should we implement these endpoints?
94
91
  // introspection_endpoint: new URL('/oauth/introspect', issuer).href,
@@ -97,7 +94,7 @@ function buildMetadata(issuer, keyset, customMetadata) {
97
94
  pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,
98
95
  require_pushed_authorization_requests: true,
99
96
  // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1
100
- dpop_signing_alg_values_supported: [...crypto_js_1.VERIFY_ALGOS],
97
+ dpop_signing_alg_values_supported: [...VERIFY_ALGOS],
101
98
  // https://datatracker.ietf.org/doc/html/rfc9396#section-14.4
102
99
  authorization_details_types_supported: customMetadata?.authorization_details_types_supported,
103
100
  // https://www.rfc-editor.org/rfc/rfc9728.html#section-4
@@ -1 +1 @@
1
- {"version":3,"file":"build-metadata.js","sourceRoot":"","sources":["../../src/metadata/build-metadata.ts"],"names":[],"mappings":";;AAmBA,sCAyHC;AA3ID,sDAI6B;AAC7B,mDAA4C;AAC5C,qDAAoD;AAOpD;;;;GAIG;AACH,SAAgB,aAAa,CAC3B,MAA6B,EAC7B,MAAc,EACd,cAA+B;IAE/B,OAAO,uDAAyC,CAAC,KAAK,CAAC;QACrD,MAAM;QAEN,gBAAgB,EAAE;YAChB,SAAS;YAET,yEAAyE;YACzE,kCAAkC;YAClC,kBAAkB;YAClB,oBAAoB;YACpB,sBAAsB;YAEtB,gEAAgE;SACjE;QACD,uBAAuB,EAAE;YACvB,EAAE;YACF,QAAQ,EAAE,6CAA6C;YACvD,+DAA+D;SAChE;QACD,wBAAwB,EAAE;YACxB,QAAQ;YACR,MAAM;YACN,WAAW;YAEX,SAAS;YACT,UAAU;YACV,yBAAyB;YACzB,mBAAmB;YACnB,gBAAgB;YAChB,oBAAoB;YACpB,cAAc;SACf;QACD,wBAAwB,EAAE;YACxB,mFAAmF;YACnF,OAAO;YACP,UAAU;YACV,0FAA0F;YAC1F,WAAW;SACZ;QACD,qBAAqB,EAAE;YACrB,EAAE;YACF,oBAAoB;YACpB,eAAe;SAChB;QACD,gCAAgC,EAAE;YAChC,sGAAsG;YACtG,MAAM;YAEN,iCAAiC;YACjC,WAAW;SACZ;QACD,oBAAoB,EAAE;YACpB,EAAE;YACF,OAAO;SACR;QACD,wBAAwB,EAAE;YACxB,EAAE;YACF,MAAM;YACN,OAAO;YACP,OAAO;YACP,aAAa;SACd;QAED,iEAAiE;QACjE,uBAAuB,EAAE;YACvB,MAAM;YACN,OAAO;YACP,SAAS;YACT,gBAAgB;YAChB,QAAQ;SACT;QAED,gDAAgD;QAChD,8CAA8C,EAAE,IAAI;QAEpD,0DAA0D;QAC1D,2CAA2C,EAAE,CAAC,GAAG,wBAAY,EAAE,MAAM,CAAC;QACtE,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAC3D,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAE3D,2BAA2B,EAAE,IAAI;QACjC,+BAA+B,EAAE,IAAI;QACrC,gCAAgC,EAAE,IAAI;QAEtC,QAAQ,EAAE,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,IAAI;QAE7C,sBAAsB,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,IAAI;QAEhE,cAAc,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI;QACpD,qCAAqC,EAAE,CAAC,GAAG,kBAAM,CAAC,sBAAsB,CAAC;QACzE,gDAAgD,EAAE,CAAC,GAAG,wBAAY,CAAC;QAEnE,mBAAmB,EAAE,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,IAAI;QAE1D,6CAA6C;QAC7C,qEAAqE;QACrE,+DAA+D;QAE/D,0DAA0D;QAC1D,qCAAqC,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI;QAEzE,qCAAqC,EAAE,IAAI;QAE3C,4DAA4D;QAC5D,iCAAiC,EAAE,CAAC,GAAG,wBAAY,CAAC;QAEpD,6DAA6D;QAC7D,qCAAqC,EACnC,cAAc,EAAE,qCAAqC;QAEvD,wDAAwD;QACxD,mBAAmB,EAAE,cAAc,EAAE,mBAAmB;QAExD,uFAAuF;QACvF,qCAAqC,EAAE,IAAI;KAC5C,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { Keyset } from '@atproto/jwk'\nimport {\n OAuthAuthorizationServerMetadata,\n OAuthIssuerIdentifier,\n oauthAuthorizationServerMetadataValidator,\n} from '@atproto/oauth-types'\nimport { Client } from '../client/client.js'\nimport { VERIFY_ALGOS } from '../lib/util/crypto.js'\n\nexport type CustomMetadata = {\n authorization_details_types_supported?: string[]\n protected_resources?: string[]\n}\n\n/**\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8414#section-2}\n * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata}\n * @see {@link https://openid.net/specs/openid-connect-prompt-create-1_0.html}\n */\nexport function buildMetadata(\n issuer: OAuthIssuerIdentifier,\n keyset: Keyset,\n customMetadata?: CustomMetadata,\n): OAuthAuthorizationServerMetadata {\n return oauthAuthorizationServerMetadataValidator.parse({\n issuer,\n\n scopes_supported: [\n 'atproto',\n\n // These serve as hint that this server supports the transitional scopes.\n // This is not a specced behavior.\n 'transition:email',\n 'transition:generic',\n 'transition:chat.bsky',\n\n // Other atproto scopes can't be enumerated as they are dynamic.\n ],\n subject_types_supported: [\n //\n 'public', // The same \"sub\" is returned for all clients\n // 'pairwise', // A different \"sub\" is returned for each client\n ],\n response_types_supported: [\n // OAuth\n 'code',\n // 'token',\n\n // OpenID\n // 'none',\n // 'code id_token token',\n // 'code id_token',\n // 'code token',\n // 'id_token token',\n // 'id_token',\n ],\n response_modes_supported: [\n // https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes\n 'query',\n 'fragment',\n // https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode\n 'form_post',\n ],\n grant_types_supported: [\n //\n 'authorization_code',\n 'refresh_token',\n ],\n code_challenge_methods_supported: [\n // https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#pkce-code-challenge-method\n 'S256',\n\n // atproto does not allow \"plain\"\n // 'plain',\n ],\n ui_locales_supported: [\n //\n 'en-US',\n ],\n display_values_supported: [\n //\n 'page',\n 'popup',\n 'touch',\n // 'wap', LoL\n ],\n\n // https://openid.net/specs/openid-connect-prompt-create-1_0.html\n prompt_values_supported: [\n 'none',\n 'login',\n 'consent',\n 'select_account',\n 'create',\n ],\n\n // https://datatracker.ietf.org/doc/html/rfc9207\n authorization_response_iss_parameter_supported: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9101#section-4\n request_object_signing_alg_values_supported: [...VERIFY_ALGOS, 'none'],\n request_object_encryption_alg_values_supported: [], // None\n request_object_encryption_enc_values_supported: [], // None\n\n request_parameter_supported: true,\n request_uri_parameter_supported: true,\n require_request_uri_registration: true,\n\n jwks_uri: new URL('/oauth/jwks', issuer).href,\n\n authorization_endpoint: new URL('/oauth/authorize', issuer).href,\n\n token_endpoint: new URL('/oauth/token', issuer).href,\n token_endpoint_auth_methods_supported: [...Client.AUTH_METHODS_SUPPORTED],\n token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n revocation_endpoint: new URL('/oauth/revoke', issuer).href,\n\n // @TODO Should we implement these endpoints?\n // introspection_endpoint: new URL('/oauth/introspect', issuer).href,\n // end_session_endpoint: new URL('/oauth/logout', issuer).href,\n\n // https://datatracker.ietf.org/doc/html/rfc9126#section-5\n pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,\n\n require_pushed_authorization_requests: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1\n dpop_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n // https://datatracker.ietf.org/doc/html/rfc9396#section-14.4\n authorization_details_types_supported:\n customMetadata?.authorization_details_types_supported,\n\n // https://www.rfc-editor.org/rfc/rfc9728.html#section-4\n protected_resources: customMetadata?.protected_resources,\n\n // https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html\n client_id_metadata_document_supported: true,\n })\n}\n"]}
1
+ {"version":3,"file":"build-metadata.js","sourceRoot":"","sources":["../../src/metadata/build-metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,yCAAyC,GAC1C,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAOpD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAA6B,EAC7B,MAAc,EACd,cAA+B;IAE/B,OAAO,yCAAyC,CAAC,KAAK,CAAC;QACrD,MAAM;QAEN,gBAAgB,EAAE;YAChB,SAAS;YAET,yEAAyE;YACzE,kCAAkC;YAClC,kBAAkB;YAClB,oBAAoB;YACpB,sBAAsB;YAEtB,gEAAgE;SACjE;QACD,uBAAuB,EAAE;YACvB,EAAE;YACF,QAAQ,EAAE,6CAA6C;YACvD,+DAA+D;SAChE;QACD,wBAAwB,EAAE;YACxB,QAAQ;YACR,MAAM;YACN,WAAW;YAEX,SAAS;YACT,UAAU;YACV,yBAAyB;YACzB,mBAAmB;YACnB,gBAAgB;YAChB,oBAAoB;YACpB,cAAc;SACf;QACD,wBAAwB,EAAE;YACxB,mFAAmF;YACnF,OAAO;YACP,UAAU;YACV,0FAA0F;YAC1F,WAAW;SACZ;QACD,qBAAqB,EAAE;YACrB,EAAE;YACF,oBAAoB;YACpB,eAAe;SAChB;QACD,gCAAgC,EAAE;YAChC,sGAAsG;YACtG,MAAM;YAEN,iCAAiC;YACjC,WAAW;SACZ;QACD,oBAAoB,EAAE;YACpB,EAAE;YACF,OAAO;SACR;QACD,wBAAwB,EAAE;YACxB,EAAE;YACF,MAAM;YACN,OAAO;YACP,OAAO;YACP,aAAa;SACd;QAED,iEAAiE;QACjE,uBAAuB,EAAE;YACvB,MAAM;YACN,OAAO;YACP,SAAS;YACT,gBAAgB;YAChB,QAAQ;SACT;QAED,gDAAgD;QAChD,8CAA8C,EAAE,IAAI;QAEpD,0DAA0D;QAC1D,2CAA2C,EAAE,CAAC,GAAG,YAAY,EAAE,MAAM,CAAC;QACtE,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAC3D,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAE3D,2BAA2B,EAAE,IAAI;QACjC,+BAA+B,EAAE,IAAI;QACrC,gCAAgC,EAAE,IAAI;QAEtC,QAAQ,EAAE,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,IAAI;QAE7C,sBAAsB,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,IAAI;QAEhE,cAAc,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI;QACpD,qCAAqC,EAAE,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC;QACzE,gDAAgD,EAAE,CAAC,GAAG,YAAY,CAAC;QAEnE,mBAAmB,EAAE,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,IAAI;QAE1D,6CAA6C;QAC7C,qEAAqE;QACrE,+DAA+D;QAE/D,0DAA0D;QAC1D,qCAAqC,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI;QAEzE,qCAAqC,EAAE,IAAI;QAE3C,4DAA4D;QAC5D,iCAAiC,EAAE,CAAC,GAAG,YAAY,CAAC;QAEpD,6DAA6D;QAC7D,qCAAqC,EACnC,cAAc,EAAE,qCAAqC;QAEvD,wDAAwD;QACxD,mBAAmB,EAAE,cAAc,EAAE,mBAAmB;QAExD,uFAAuF;QACvF,qCAAqC,EAAE,IAAI;KAC5C,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { Keyset } from '@atproto/jwk'\nimport {\n OAuthAuthorizationServerMetadata,\n OAuthIssuerIdentifier,\n oauthAuthorizationServerMetadataValidator,\n} from '@atproto/oauth-types'\nimport { Client } from '../client/client.js'\nimport { VERIFY_ALGOS } from '../lib/util/crypto.js'\n\nexport type CustomMetadata = {\n authorization_details_types_supported?: string[]\n protected_resources?: string[]\n}\n\n/**\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8414#section-2}\n * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata}\n * @see {@link https://openid.net/specs/openid-connect-prompt-create-1_0.html}\n */\nexport function buildMetadata(\n issuer: OAuthIssuerIdentifier,\n keyset: Keyset,\n customMetadata?: CustomMetadata,\n): OAuthAuthorizationServerMetadata {\n return oauthAuthorizationServerMetadataValidator.parse({\n issuer,\n\n scopes_supported: [\n 'atproto',\n\n // These serve as hint that this server supports the transitional scopes.\n // This is not a specced behavior.\n 'transition:email',\n 'transition:generic',\n 'transition:chat.bsky',\n\n // Other atproto scopes can't be enumerated as they are dynamic.\n ],\n subject_types_supported: [\n //\n 'public', // The same \"sub\" is returned for all clients\n // 'pairwise', // A different \"sub\" is returned for each client\n ],\n response_types_supported: [\n // OAuth\n 'code',\n // 'token',\n\n // OpenID\n // 'none',\n // 'code id_token token',\n // 'code id_token',\n // 'code token',\n // 'id_token token',\n // 'id_token',\n ],\n response_modes_supported: [\n // https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes\n 'query',\n 'fragment',\n // https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode\n 'form_post',\n ],\n grant_types_supported: [\n //\n 'authorization_code',\n 'refresh_token',\n ],\n code_challenge_methods_supported: [\n // https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#pkce-code-challenge-method\n 'S256',\n\n // atproto does not allow \"plain\"\n // 'plain',\n ],\n ui_locales_supported: [\n //\n 'en-US',\n ],\n display_values_supported: [\n //\n 'page',\n 'popup',\n 'touch',\n // 'wap', LoL\n ],\n\n // https://openid.net/specs/openid-connect-prompt-create-1_0.html\n prompt_values_supported: [\n 'none',\n 'login',\n 'consent',\n 'select_account',\n 'create',\n ],\n\n // https://datatracker.ietf.org/doc/html/rfc9207\n authorization_response_iss_parameter_supported: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9101#section-4\n request_object_signing_alg_values_supported: [...VERIFY_ALGOS, 'none'],\n request_object_encryption_alg_values_supported: [], // None\n request_object_encryption_enc_values_supported: [], // None\n\n request_parameter_supported: true,\n request_uri_parameter_supported: true,\n require_request_uri_registration: true,\n\n jwks_uri: new URL('/oauth/jwks', issuer).href,\n\n authorization_endpoint: new URL('/oauth/authorize', issuer).href,\n\n token_endpoint: new URL('/oauth/token', issuer).href,\n token_endpoint_auth_methods_supported: [...Client.AUTH_METHODS_SUPPORTED],\n token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n revocation_endpoint: new URL('/oauth/revoke', issuer).href,\n\n // @TODO Should we implement these endpoints?\n // introspection_endpoint: new URL('/oauth/introspect', issuer).href,\n // end_session_endpoint: new URL('/oauth/logout', issuer).href,\n\n // https://datatracker.ietf.org/doc/html/rfc9126#section-5\n pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,\n\n require_pushed_authorization_requests: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1\n dpop_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n // https://datatracker.ietf.org/doc/html/rfc9396#section-14.4\n authorization_details_types_supported:\n customMetadata?.authorization_details_types_supported,\n\n // https://www.rfc-editor.org/rfc/rfc9728.html#section-4\n protected_resources: customMetadata?.protected_resources,\n\n // https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html\n client_id_metadata_document_supported: true,\n })\n}\n"]}
@@ -1,19 +1,3 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("@atproto/oauth-types"), exports);
18
- __exportStar(require("./client/client-utils.js"), exports);
1
+ export * from '@atproto/oauth-types';
2
+ export * from './client/client-utils.js';
19
3
  //# sourceMappingURL=oauth-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-client.js","sourceRoot":"","sources":["../src/oauth-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAoC;AAEpC,2DAAwC","sourcesContent":["export * from '@atproto/oauth-types'\nexport type * from './client/client.js'\nexport * from './client/client-utils.js'\n"]}
1
+ {"version":3,"file":"oauth-client.js","sourceRoot":"","sources":["../src/oauth-client.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AAEpC,cAAc,0BAA0B,CAAA","sourcesContent":["export * from '@atproto/oauth-types'\nexport type * from './client/client.js'\nexport * from './client/client-utils.js'\n"]}
@@ -1,19 +1,3 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./dpop/dpop-nonce.js"), exports);
18
- __exportStar(require("./dpop/dpop-manager.js"), exports);
1
+ export * from './dpop/dpop-nonce.js';
2
+ export * from './dpop/dpop-manager.js';
19
3
  //# sourceMappingURL=oauth-dpop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-dpop.js","sourceRoot":"","sources":["../src/oauth-dpop.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAoC;AACpC,yDAAsC","sourcesContent":["export * from './dpop/dpop-nonce.js'\nexport * from './dpop/dpop-manager.js'\n"]}
1
+ {"version":3,"file":"oauth-dpop.js","sourceRoot":"","sources":["../src/oauth-dpop.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA","sourcesContent":["export * from './dpop/dpop-nonce.js'\nexport * from './dpop/dpop-manager.js'\n"]}