@atproto/oauth-provider 0.5.2 → 0.6.1

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 (310) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/account/account-manager.d.ts +7 -5
  3. package/dist/account/account-manager.d.ts.map +1 -1
  4. package/dist/account/account-manager.js +34 -25
  5. package/dist/account/account-manager.js.map +1 -1
  6. package/dist/account/account-store.d.ts +7 -0
  7. package/dist/account/account-store.d.ts.map +1 -1
  8. package/dist/account/account-store.js.map +1 -1
  9. package/dist/account/account.d.ts +1 -11
  10. package/dist/account/account.d.ts.map +1 -1
  11. package/dist/account/{sign-up-data.d.ts → sign-up-input.d.ts} +3 -3
  12. package/dist/account/sign-up-input.d.ts.map +1 -0
  13. package/dist/account/{sign-up-data.js → sign-up-input.js} +3 -3
  14. package/dist/account/sign-up-input.js.map +1 -0
  15. package/dist/assets/assets-middleware.d.ts +2 -0
  16. package/dist/assets/assets-middleware.d.ts.map +1 -1
  17. package/dist/assets/assets-middleware.js +12 -14
  18. package/dist/assets/assets-middleware.js.map +1 -1
  19. package/dist/lib/csp/index.d.ts +5 -6
  20. package/dist/lib/csp/index.d.ts.map +1 -1
  21. package/dist/lib/csp/index.js +14 -11
  22. package/dist/lib/csp/index.js.map +1 -1
  23. package/dist/lib/hcaptcha.d.ts +15 -12
  24. package/dist/lib/hcaptcha.d.ts.map +1 -1
  25. package/dist/lib/hcaptcha.js +11 -7
  26. package/dist/lib/hcaptcha.js.map +1 -1
  27. package/dist/lib/html/build-document.d.ts +2 -2
  28. package/dist/lib/html/build-document.d.ts.map +1 -1
  29. package/dist/lib/html/build-document.js +11 -7
  30. package/dist/lib/html/build-document.js.map +1 -1
  31. package/dist/lib/html/html.d.ts.map +1 -1
  32. package/dist/lib/html/html.js +10 -13
  33. package/dist/lib/html/html.js.map +1 -1
  34. package/dist/lib/html/util.d.ts +0 -1
  35. package/dist/lib/html/util.d.ts.map +1 -1
  36. package/dist/lib/html/util.js +0 -4
  37. package/dist/lib/html/util.js.map +1 -1
  38. package/dist/lib/http/response.d.ts +3 -1
  39. package/dist/lib/http/response.d.ts.map +1 -1
  40. package/dist/lib/http/response.js +3 -0
  41. package/dist/lib/http/response.js.map +1 -1
  42. package/dist/lib/http/security-headers.d.ts +48 -0
  43. package/dist/lib/http/security-headers.d.ts.map +1 -0
  44. package/dist/lib/http/security-headers.js +62 -0
  45. package/dist/lib/http/security-headers.js.map +1 -0
  46. package/dist/lib/util/type.d.ts +8 -0
  47. package/dist/lib/util/type.d.ts.map +1 -1
  48. package/dist/lib/util/type.js.map +1 -1
  49. package/dist/oauth-hooks.d.ts +4 -25
  50. package/dist/oauth-hooks.d.ts.map +1 -1
  51. package/dist/oauth-provider.js +2 -2
  52. package/dist/oauth-provider.js.map +1 -1
  53. package/dist/output/backend-data.d.ts +4 -0
  54. package/dist/output/backend-data.d.ts.map +1 -0
  55. package/dist/output/backend-data.js +19 -0
  56. package/dist/output/backend-data.js.map +1 -0
  57. package/dist/output/build-authorize-data.d.ts +3 -19
  58. package/dist/output/build-authorize-data.d.ts.map +1 -1
  59. package/dist/output/build-authorize-data.js.map +1 -1
  60. package/dist/output/build-customization-data.d.ts +11 -18
  61. package/dist/output/build-customization-data.d.ts.map +1 -1
  62. package/dist/output/build-customization-data.js +1 -1
  63. package/dist/output/build-customization-data.js.map +1 -1
  64. package/dist/output/build-error-data.d.ts +3 -0
  65. package/dist/output/build-error-data.d.ts.map +1 -0
  66. package/dist/output/build-error-data.js +10 -0
  67. package/dist/output/build-error-data.js.map +1 -0
  68. package/dist/output/build-error-payload.d.ts +2 -1
  69. package/dist/output/build-error-payload.d.ts.map +1 -1
  70. package/dist/output/build-error-payload.js.map +1 -1
  71. package/dist/output/output-manager.d.ts +10 -4
  72. package/dist/output/output-manager.d.ts.map +1 -1
  73. package/dist/output/output-manager.js +68 -39
  74. package/dist/output/output-manager.js.map +1 -1
  75. package/dist/output/send-web-page.d.ts +6 -10
  76. package/dist/output/send-web-page.d.ts.map +1 -1
  77. package/dist/output/send-web-page.js +27 -47
  78. package/dist/output/send-web-page.js.map +1 -1
  79. package/dist/signer/signed-token-payload.d.ts +3 -3
  80. package/dist/signer/signer.d.ts +2 -2
  81. package/package.json +8 -41
  82. package/src/account/account-manager.ts +55 -34
  83. package/src/account/account-store.ts +8 -0
  84. package/src/account/account.ts +1 -14
  85. package/src/account/{sign-up-data.ts → sign-up-input.ts} +2 -2
  86. package/src/assets/assets-middleware.ts +11 -17
  87. package/src/lib/csp/index.ts +16 -13
  88. package/src/lib/hcaptcha.ts +14 -10
  89. package/src/lib/html/build-document.ts +15 -8
  90. package/src/lib/html/html.ts +11 -18
  91. package/src/lib/html/util.ts +0 -4
  92. package/src/lib/http/response.ts +9 -1
  93. package/src/lib/http/security-headers.ts +91 -0
  94. package/src/lib/util/type.ts +18 -0
  95. package/src/oauth-hooks.ts +4 -25
  96. package/src/oauth-provider.ts +2 -2
  97. package/src/output/backend-data.ts +18 -0
  98. package/src/output/build-authorize-data.ts +3 -26
  99. package/src/output/build-customization-data.ts +2 -13
  100. package/src/output/build-error-data.ts +8 -0
  101. package/src/output/build-error-payload.ts +4 -2
  102. package/src/output/output-manager.ts +86 -47
  103. package/src/output/send-web-page.ts +29 -58
  104. package/tsconfig.backend.json +1 -2
  105. package/tsconfig.backend.tsbuildinfo +1 -1
  106. package/tsconfig.json +1 -5
  107. package/.linguirc +0 -57
  108. package/dist/account/sign-up-data.d.ts.map +0 -1
  109. package/dist/account/sign-up-data.js.map +0 -1
  110. package/dist/assets/app/bundle-manifest.json +0 -614
  111. package/dist/assets/app/index-DZHZ9kCP.js +0 -36
  112. package/dist/assets/app/index-DZHZ9kCP.js.map +0 -1
  113. package/dist/assets/app/main-B_dNxQo_.js +0 -4
  114. package/dist/assets/app/main-B_dNxQo_.js.map +0 -1
  115. package/dist/assets/app/main-Dr6y26KY.css +0 -3
  116. package/dist/assets/app/main-Dr6y26KY.js +0 -306
  117. package/dist/assets/app/main-Dr6y26KY.js.map +0 -1
  118. package/dist/assets/app/messages-6_mYuGzB.js +0 -4
  119. package/dist/assets/app/messages-6_mYuGzB.js.map +0 -1
  120. package/dist/assets/app/messages-7wdeBTpD.js +0 -4
  121. package/dist/assets/app/messages-7wdeBTpD.js.map +0 -1
  122. package/dist/assets/app/messages-B-YFoWKc.js +0 -4
  123. package/dist/assets/app/messages-B-YFoWKc.js.map +0 -1
  124. package/dist/assets/app/messages-B10DUOE-.js +0 -4
  125. package/dist/assets/app/messages-B10DUOE-.js.map +0 -1
  126. package/dist/assets/app/messages-B4AwFEeZ.js +0 -4
  127. package/dist/assets/app/messages-B4AwFEeZ.js.map +0 -1
  128. package/dist/assets/app/messages-BDP8MyEC.js +0 -4
  129. package/dist/assets/app/messages-BDP8MyEC.js.map +0 -1
  130. package/dist/assets/app/messages-BIS87lxQ.js +0 -4
  131. package/dist/assets/app/messages-BIS87lxQ.js.map +0 -1
  132. package/dist/assets/app/messages-BI_Wbjdt.js +0 -4
  133. package/dist/assets/app/messages-BI_Wbjdt.js.map +0 -1
  134. package/dist/assets/app/messages-BMAouhRx.js +0 -4
  135. package/dist/assets/app/messages-BMAouhRx.js.map +0 -1
  136. package/dist/assets/app/messages-BdckMnJj.js +0 -4
  137. package/dist/assets/app/messages-BdckMnJj.js.map +0 -1
  138. package/dist/assets/app/messages-BgBLzc46.js +0 -4
  139. package/dist/assets/app/messages-BgBLzc46.js.map +0 -1
  140. package/dist/assets/app/messages-BobD78yK.js +0 -4
  141. package/dist/assets/app/messages-BobD78yK.js.map +0 -1
  142. package/dist/assets/app/messages-BtThT9UZ.js +0 -4
  143. package/dist/assets/app/messages-BtThT9UZ.js.map +0 -1
  144. package/dist/assets/app/messages-BwKHkbeh.js +0 -4
  145. package/dist/assets/app/messages-BwKHkbeh.js.map +0 -1
  146. package/dist/assets/app/messages-C417YUvA.js +0 -4
  147. package/dist/assets/app/messages-C417YUvA.js.map +0 -1
  148. package/dist/assets/app/messages-C4CxO4bO.js +0 -4
  149. package/dist/assets/app/messages-C4CxO4bO.js.map +0 -1
  150. package/dist/assets/app/messages-C5vd04e6.js +0 -4
  151. package/dist/assets/app/messages-C5vd04e6.js.map +0 -1
  152. package/dist/assets/app/messages-CAri2Wnz.js +0 -4
  153. package/dist/assets/app/messages-CAri2Wnz.js.map +0 -1
  154. package/dist/assets/app/messages-CPtWTZeG.js +0 -4
  155. package/dist/assets/app/messages-CPtWTZeG.js.map +0 -1
  156. package/dist/assets/app/messages-CiaM5zm8.js +0 -4
  157. package/dist/assets/app/messages-CiaM5zm8.js.map +0 -1
  158. package/dist/assets/app/messages-CkL-L2R6.js +0 -4
  159. package/dist/assets/app/messages-CkL-L2R6.js.map +0 -1
  160. package/dist/assets/app/messages-Cy_4XLNe.js +0 -4
  161. package/dist/assets/app/messages-Cy_4XLNe.js.map +0 -1
  162. package/dist/assets/app/messages-D5_ad-Eo.js +0 -4
  163. package/dist/assets/app/messages-D5_ad-Eo.js.map +0 -1
  164. package/dist/assets/app/messages-DChMl9mT.js +0 -4
  165. package/dist/assets/app/messages-DChMl9mT.js.map +0 -1
  166. package/dist/assets/app/messages-DWX-DIfv.js +0 -4
  167. package/dist/assets/app/messages-DWX-DIfv.js.map +0 -1
  168. package/dist/assets/app/messages-DgfsOphe.js +0 -4
  169. package/dist/assets/app/messages-DgfsOphe.js.map +0 -1
  170. package/dist/assets/app/messages-Dj5B_DR6.js +0 -4
  171. package/dist/assets/app/messages-Dj5B_DR6.js.map +0 -1
  172. package/dist/assets/app/messages-Dwzqo4eA.js +0 -4
  173. package/dist/assets/app/messages-Dwzqo4eA.js.map +0 -1
  174. package/dist/assets/app/messages-ESCIXJR7.js +0 -4
  175. package/dist/assets/app/messages-ESCIXJR7.js.map +0 -1
  176. package/dist/assets/app/messages-dglB2edb.js +0 -4
  177. package/dist/assets/app/messages-dglB2edb.js.map +0 -1
  178. package/dist/assets/app/messages-e_ClRrWc.js +0 -4
  179. package/dist/assets/app/messages-e_ClRrWc.js.map +0 -1
  180. package/dist/assets/app/messages-evvDxmrP.js +0 -4
  181. package/dist/assets/app/messages-evvDxmrP.js.map +0 -1
  182. package/dist/assets/app/messages-pPbdLb5B.js +0 -4
  183. package/dist/assets/app/messages-pPbdLb5B.js.map +0 -1
  184. package/dist/assets/app/messages-tJv8gHL2.js +0 -4
  185. package/dist/assets/app/messages-tJv8gHL2.js.map +0 -1
  186. package/dist/assets/app/messages-vLRVEw96.js +0 -4
  187. package/dist/assets/app/messages-vLRVEw96.js.map +0 -1
  188. package/dist/assets/asset.d.ts +0 -9
  189. package/dist/assets/asset.d.ts.map +0 -1
  190. package/dist/assets/asset.js +0 -3
  191. package/dist/assets/asset.js.map +0 -1
  192. package/dist/assets/index.d.ts +0 -5
  193. package/dist/assets/index.d.ts.map +0 -1
  194. package/dist/assets/index.js +0 -78
  195. package/dist/assets/index.js.map +0 -1
  196. package/rollup.config.js +0 -98
  197. package/src/assets/app/app.tsx +0 -43
  198. package/src/assets/app/backend-data.ts +0 -27
  199. package/src/assets/app/backend-types.ts +0 -66
  200. package/src/assets/app/components/forms/button-toggle-visibility.tsx +0 -43
  201. package/src/assets/app/components/forms/button.tsx +0 -60
  202. package/src/assets/app/components/forms/fieldset.tsx +0 -55
  203. package/src/assets/app/components/forms/form-card-async.tsx +0 -103
  204. package/src/assets/app/components/forms/form-card.tsx +0 -49
  205. package/src/assets/app/components/forms/input-checkbox.tsx +0 -78
  206. package/src/assets/app/components/forms/input-container.tsx +0 -107
  207. package/src/assets/app/components/forms/input-email-address.tsx +0 -65
  208. package/src/assets/app/components/forms/input-new-password.tsx +0 -62
  209. package/src/assets/app/components/forms/input-password.tsx +0 -87
  210. package/src/assets/app/components/forms/input-text.tsx +0 -82
  211. package/src/assets/app/components/forms/input-token.tsx +0 -94
  212. package/src/assets/app/components/forms/wizard-card.tsx +0 -116
  213. package/src/assets/app/components/layouts/layout-title-page.tsx +0 -77
  214. package/src/assets/app/components/layouts/layout-welcome.tsx +0 -73
  215. package/src/assets/app/components/utils/account-identifier.tsx +0 -23
  216. package/src/assets/app/components/utils/account-image.tsx +0 -33
  217. package/src/assets/app/components/utils/admonition.tsx +0 -52
  218. package/src/assets/app/components/utils/client-name.tsx +0 -45
  219. package/src/assets/app/components/utils/error-card.tsx +0 -93
  220. package/src/assets/app/components/utils/error-message.tsx +0 -88
  221. package/src/assets/app/components/utils/help-card.tsx +0 -46
  222. package/src/assets/app/components/utils/icons.tsx +0 -88
  223. package/src/assets/app/components/utils/link-anchor.tsx +0 -28
  224. package/src/assets/app/components/utils/link-title.tsx +0 -26
  225. package/src/assets/app/components/utils/multi-lang-string.tsx +0 -56
  226. package/src/assets/app/components/utils/password-strength-label.tsx +0 -37
  227. package/src/assets/app/components/utils/password-strength-meter.tsx +0 -58
  228. package/src/assets/app/components/utils/url-viewer.tsx +0 -73
  229. package/src/assets/app/cookies.ts +0 -11
  230. package/src/assets/app/hooks/use-api.ts +0 -178
  231. package/src/assets/app/hooks/use-async-action.ts +0 -120
  232. package/src/assets/app/hooks/use-bound-dispatch.ts +0 -5
  233. package/src/assets/app/hooks/use-browser-color-scheme.ts +0 -31
  234. package/src/assets/app/hooks/use-csrf-token.ts +0 -5
  235. package/src/assets/app/hooks/use-random-string.ts +0 -37
  236. package/src/assets/app/hooks/use-stepper.ts +0 -87
  237. package/src/assets/app/index.html +0 -182
  238. package/src/assets/app/lib/api.ts +0 -289
  239. package/src/assets/app/lib/clsx.ts +0 -6
  240. package/src/assets/app/lib/json-client.ts +0 -94
  241. package/src/assets/app/lib/password.ts +0 -98
  242. package/src/assets/app/lib/ref.ts +0 -17
  243. package/src/assets/app/lib/util.ts +0 -13
  244. package/src/assets/app/locales/an/messages.po +0 -490
  245. package/src/assets/app/locales/ast/messages.po +0 -490
  246. package/src/assets/app/locales/ca/messages.po +0 -490
  247. package/src/assets/app/locales/da/messages.po +0 -490
  248. package/src/assets/app/locales/de/messages.po +0 -490
  249. package/src/assets/app/locales/el/messages.po +0 -490
  250. package/src/assets/app/locales/en/messages.po +0 -490
  251. package/src/assets/app/locales/en-GB/messages.po +0 -490
  252. package/src/assets/app/locales/es/messages.po +0 -490
  253. package/src/assets/app/locales/eu/messages.po +0 -490
  254. package/src/assets/app/locales/fi/messages.po +0 -490
  255. package/src/assets/app/locales/fr/messages.po +0 -490
  256. package/src/assets/app/locales/ga/messages.po +0 -490
  257. package/src/assets/app/locales/gl/messages.po +0 -490
  258. package/src/assets/app/locales/hi/messages.po +0 -490
  259. package/src/assets/app/locales/hu/messages.po +0 -490
  260. package/src/assets/app/locales/ia/messages.po +0 -490
  261. package/src/assets/app/locales/id/messages.po +0 -490
  262. package/src/assets/app/locales/it/messages.po +0 -490
  263. package/src/assets/app/locales/ja/messages.po +0 -490
  264. package/src/assets/app/locales/km/messages.po +0 -490
  265. package/src/assets/app/locales/ko/messages.po +0 -490
  266. package/src/assets/app/locales/load.ts +0 -8
  267. package/src/assets/app/locales/locale-context.ts +0 -19
  268. package/src/assets/app/locales/locale-provider.tsx +0 -112
  269. package/src/assets/app/locales/locale-selector.tsx +0 -58
  270. package/src/assets/app/locales/locales.ts +0 -168
  271. package/src/assets/app/locales/ne/messages.po +0 -490
  272. package/src/assets/app/locales/nl/messages.po +0 -490
  273. package/src/assets/app/locales/pl/messages.po +0 -490
  274. package/src/assets/app/locales/pt-BR/messages.po +0 -490
  275. package/src/assets/app/locales/ro/messages.po +0 -490
  276. package/src/assets/app/locales/ru/messages.po +0 -490
  277. package/src/assets/app/locales/sv/messages.po +0 -490
  278. package/src/assets/app/locales/th/messages.po +0 -490
  279. package/src/assets/app/locales/tr/messages.po +0 -490
  280. package/src/assets/app/locales/uk/messages.po +0 -490
  281. package/src/assets/app/locales/vi/messages.po +0 -490
  282. package/src/assets/app/locales/zh-CN/messages.po +0 -490
  283. package/src/assets/app/locales/zh-HK/messages.po +0 -490
  284. package/src/assets/app/locales/zh-TW/messages.po +0 -490
  285. package/src/assets/app/main.css +0 -33
  286. package/src/assets/app/main.tsx +0 -44
  287. package/src/assets/app/views/authorize/accept/accept-form.tsx +0 -150
  288. package/src/assets/app/views/authorize/accept/accept-view.tsx +0 -70
  289. package/src/assets/app/views/authorize/authorize-view.tsx +0 -180
  290. package/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
  291. package/src/assets/app/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
  292. package/src/assets/app/views/authorize/reset-password/reset-password-view.tsx +0 -127
  293. package/src/assets/app/views/authorize/sign-in/sign-in-form.tsx +0 -242
  294. package/src/assets/app/views/authorize/sign-in/sign-in-picker.tsx +0 -116
  295. package/src/assets/app/views/authorize/sign-in/sign-in-view.tsx +0 -145
  296. package/src/assets/app/views/authorize/sign-up/sign-up-account-form.tsx +0 -142
  297. package/src/assets/app/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
  298. package/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx +0 -287
  299. package/src/assets/app/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
  300. package/src/assets/app/views/authorize/sign-up/sign-up-view.tsx +0 -158
  301. package/src/assets/app/views/authorize/welcome/welcome-view.tsx +0 -56
  302. package/src/assets/app/views/error/error-view.tsx +0 -31
  303. package/src/assets/asset.ts +0 -9
  304. package/src/assets/index.ts +0 -86
  305. package/tailwind.config.js +0 -31
  306. package/tsconfig.frontend.json +0 -11
  307. package/tsconfig.frontend.tsbuildinfo +0 -1
  308. package/tsconfig.tools.json +0 -8
  309. package/tsconfig.tools.tsbuildinfo +0 -1
  310. package/vite.config.mjs +0 -16
@@ -1,14 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OutputManager = void 0;
4
- const index_js_1 = require("../assets/index.js");
5
- const index_js_2 = require("../lib/csp/index.js");
6
- const index_js_3 = require("../lib/html/index.js");
4
+ const oauth_provider_ui_1 = require("@atproto/oauth-provider-ui");
5
+ const assets_middleware_js_1 = require("../assets/assets-middleware.js");
6
+ const index_js_1 = require("../lib/csp/index.js");
7
+ const index_js_2 = require("../lib/html/index.js");
8
+ const security_headers_js_1 = require("../lib/http/security-headers.js");
7
9
  const locale_js_1 = require("../lib/locale.js");
10
+ const backend_data_js_1 = require("./backend-data.js");
8
11
  const build_authorize_data_js_1 = require("./build-authorize-data.js");
9
12
  const build_customization_data_js_1 = require("./build-customization-data.js");
13
+ const build_error_data_js_1 = require("./build-error-data.js");
10
14
  const build_error_payload_js_1 = require("./build-error-payload.js");
11
15
  const send_web_page_js_1 = require("./send-web-page.js");
16
+ const BASE_CSP = {
17
+ // API calls are made to the same origin
18
+ 'connect-src': ["'self'"],
19
+ // Allow loading of PDS logo & User avatars
20
+ 'img-src': ['data:', 'https:'],
21
+ // Prevent embedding in iframes
22
+ 'frame-ancestors': ["'none'"],
23
+ };
24
+ /**
25
+ * @see {@link https://docs.hcaptcha.com/#content-security-policy-settings}
26
+ */
12
27
  const HCAPTCHA_CSP = {
13
28
  'script-src': ['https://hcaptcha.com', 'https://*.hcaptcha.com'],
14
29
  'frame-src': ['https://hcaptcha.com', 'https://*.hcaptcha.com'],
@@ -21,68 +36,82 @@ class OutputManager {
21
36
  { name: 'robots', content: 'noindex' },
22
37
  { name: 'description', content: 'ATProto OAuth authorization page' },
23
38
  ];
24
- scripts;
25
- styles;
26
39
  csp;
40
+ coep;
41
+ customizationData;
42
+ customizationCss;
27
43
  constructor(customization) {
28
44
  this.links = customization.branding?.links;
29
- const scripts = Array.from((0, index_js_1.enumerateAssets)('application/javascript'));
30
- const styles = Array.from((0, index_js_1.enumerateAssets)('text/css'));
31
- // Note: building scripts/styles/csp here for two reasons:
32
- // 1. To avoid re-building it on every request
33
- // 2. To throw during init if the customization/config is invalid
34
- this.scripts = [
35
- (0, send_web_page_js_1.declareBackendData)('__availableLocales', locale_js_1.AVAILABLE_LOCALES),
36
- (0, send_web_page_js_1.declareBackendData)('__customizationData', (0, build_customization_data_js_1.buildCustomizationData)(customization)),
37
- // Last (to be able to read the "backend data" variables)
38
- ...scripts.filter((asset) => asset.isEntry),
39
- ];
40
- this.styles = [
41
- // First (to be overridden by customization)
42
- ...styles,
43
- (0, index_js_3.cssCode)((0, build_customization_data_js_1.buildCustomizationCss)(customization)),
44
- ];
45
- const customizationCsp = customization?.hcaptcha ? HCAPTCHA_CSP : undefined;
46
- const assetsCsp = {
47
- 'script-src': scripts.map(send_web_page_js_1.assetToCsp),
48
- 'style-src': styles.map(send_web_page_js_1.assetToCsp),
45
+ // "cache" these:
46
+ this.customizationData = (0, build_customization_data_js_1.buildCustomizationData)(customization);
47
+ this.customizationCss = (0, index_js_2.cssCode)((0, build_customization_data_js_1.buildCustomizationCss)(customization));
48
+ this.csp = (0, index_js_1.mergeCsp)(BASE_CSP, customization?.hcaptcha ? HCAPTCHA_CSP : undefined);
49
+ // Because we are loading avatar images from external sources, that might
50
+ // not have CORP headers set, we need to use at least "credentialless".
51
+ this.coep = customization?.hcaptcha
52
+ ? // https://github.com/hCaptcha/react-hcaptcha/issues/259
53
+ // @TODO Remove the use of `unsafeNone` once the issue above is resolved
54
+ security_headers_js_1.CrossOriginEmbedderPolicy.unsafeNone
55
+ : security_headers_js_1.CrossOriginEmbedderPolicy.credentialless;
56
+ }
57
+ buildAssets(name, backendData) {
58
+ return {
59
+ scripts: [
60
+ (0, backend_data_js_1.declareBackendData)(backendData),
61
+ // After backend injected data
62
+ ...Array.from(oauth_provider_ui_1.assets)
63
+ .filter(([, item]) => item.type === 'chunk' && item.isEntry && item.name === name)
64
+ .map(([filename]) => ({ url: (0, assets_middleware_js_1.buildAssetUrl)(filename) })),
65
+ ],
66
+ styles: [
67
+ ...Array.from(oauth_provider_ui_1.assets)
68
+ .filter(([, item]) => item.mime === 'text/css')
69
+ .map(([filename]) => ({ url: (0, assets_middleware_js_1.buildAssetUrl)(filename) })),
70
+ // Last (to be able to override the default styles)
71
+ this.customizationCss,
72
+ ],
49
73
  };
50
- this.csp = (0, index_js_2.mergeCsp)(customizationCsp, assetsCsp);
51
74
  }
52
75
  async sendAuthorizePage(res, data, options) {
53
76
  const locale = negotiateLocale(data.parameters.ui_locales?.split(' ') ?? options?.preferredLocales);
77
+ const { scripts, styles } = this.buildAssets('authorization-page', {
78
+ __availableLocales: locale_js_1.AVAILABLE_LOCALES,
79
+ __customizationData: this.customizationData,
80
+ __authorizeData: (0, build_authorize_data_js_1.buildAuthorizeData)(data),
81
+ });
54
82
  return (0, send_web_page_js_1.sendWebPage)(res, {
55
- scripts: [
56
- (0, send_web_page_js_1.declareBackendData)('__authorizeData', (0, build_authorize_data_js_1.buildAuthorizeData)(data)),
57
- ...this.scripts,
58
- ],
59
- styles: this.styles,
83
+ scripts,
84
+ styles,
60
85
  meta: this.meta,
61
86
  links: this.buildLinks(locale),
62
87
  htmlAttrs: { lang: locale },
63
- body: (0, index_js_3.html) `<div id="root"></div>`,
88
+ body: (0, index_js_2.html) `<div id="root"></div>`,
64
89
  csp: this.csp,
90
+ coep: this.coep,
65
91
  });
66
92
  }
67
93
  async sendErrorPage(res, err, options) {
68
94
  const locale = negotiateLocale(options?.preferredLocales);
95
+ const { scripts, styles } = this.buildAssets('error-page', {
96
+ __availableLocales: locale_js_1.AVAILABLE_LOCALES,
97
+ __customizationData: this.customizationData,
98
+ __errorData: (0, build_error_data_js_1.buildErrorData)(err),
99
+ });
69
100
  return (0, send_web_page_js_1.sendWebPage)(res, {
70
101
  status: (0, build_error_payload_js_1.buildErrorStatus)(err),
71
- scripts: [
72
- (0, send_web_page_js_1.declareBackendData)('__errorData', (0, build_error_payload_js_1.buildErrorPayload)(err)),
73
- ...this.scripts,
74
- ],
75
- styles: this.styles,
102
+ scripts,
103
+ styles,
76
104
  meta: this.meta,
77
105
  links: this.buildLinks(locale),
78
106
  htmlAttrs: { lang: locale },
79
- body: (0, index_js_3.html) `<div id="root"></div>`,
107
+ body: (0, index_js_2.html) `<div id="root"></div>`,
80
108
  csp: this.csp,
109
+ coep: this.coep,
81
110
  });
82
111
  }
83
112
  buildLinks(locale) {
84
113
  return this.links
85
- ?.map(({ rel, href, title }) => (0, index_js_3.isLinkRel)(rel)
114
+ ?.map(({ rel, href, title }) => (0, index_js_2.isLinkRel)(rel)
86
115
  ? typeof title === 'string'
87
116
  ? { href, rel, title }
88
117
  : { href, rel, title: title[locale] || title.en }
@@ -1 +1 @@
1
- {"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../src/output/output-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../src/output/output-manager.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,8 @@
1
1
  import type { ServerResponse } from 'node:http';
2
- import { CspConfig, CspValue } from '../lib/csp/index.js';
3
- import { AssetRef, BuildDocumentOptions, Html } from '../lib/html/index.js';
4
- import { WriteResponseOptions } from '../lib/http/response.js';
5
- export declare function declareBackendData(name: string, data: unknown): Html;
6
- export type SendWebPageOptions = BuildDocumentOptions & WriteResponseOptions & {
7
- csp?: CspConfig;
8
- };
9
- export declare function sendWebPage(res: ServerResponse, options: SendWebPageOptions): Promise<void>;
10
- export declare function assetsToCsp(assets?: Iterable<Html | AssetRef>): Generator<CspValue>;
11
- export declare function assetToCsp(asset: Html | AssetRef): CspValue;
2
+ import { CspConfig } from '../lib/csp/index.js';
3
+ import { BuildDocumentOptions } from '../lib/html/index.js';
4
+ import { WriteHtmlOptions } from '../lib/http/response.js';
5
+ export declare const DEFAULT_CSP: CspConfig;
6
+ export type SendWebPageOptions = BuildDocumentOptions & WriteHtmlOptions;
7
+ export declare function sendWebPage(res: ServerResponse, { csp: inputCsp, ...options }: SendWebPageOptions): Promise<void>;
12
8
  //# sourceMappingURL=send-web-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAsB,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,IAAI,EAGL,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,oBAAoB,EAAa,MAAM,yBAAyB,CAAA;AAEzE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,QAM7D;AAED,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GACnD,oBAAoB,GAAG;IACrB,GAAG,CAAC,EAAE,SAAS,CAAA;CAChB,CAAA;AAEH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED,wBAAiB,WAAW,CAC1B,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,GACjC,SAAS,CAAC,QAAQ,CAAC,CAMrB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAO3D"}
1
+ {"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAsB,MAAM,qBAAqB,CAAA;AACnE,OAAO,EAEL,oBAAoB,EAGrB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAa,MAAM,yBAAyB,CAAA;AAErE,eAAO,MAAM,WAAW,EAAE,SAGzB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG,gBAAgB,CAAA;AAExE,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,kBAAkB,GAChD,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -1,64 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.declareBackendData = declareBackendData;
3
+ exports.DEFAULT_CSP = void 0;
4
4
  exports.sendWebPage = sendWebPage;
5
- exports.assetsToCsp = assetsToCsp;
6
- exports.assetToCsp = assetToCsp;
7
5
  const node_crypto_1 = require("node:crypto");
8
6
  const index_js_1 = require("../lib/csp/index.js");
9
7
  const index_js_2 = require("../lib/html/index.js");
10
8
  const response_js_1 = require("../lib/http/response.js");
11
- function declareBackendData(name, data) {
12
- // The script tag is removed after the data is assigned to the global variable
13
- // to prevent other scripts from deducing the value of the variable. The "app"
14
- // script will read the global variable and then unset it. See
15
- // "readBackendData" in "src/assets/app/backend-types.ts".
16
- return (0, index_js_2.js) `window[${name}]=${data};document.currentScript.remove();`;
17
- }
18
- async function sendWebPage(res, options) {
19
- const csp = (0, index_js_1.mergeCsp)(options.csp, {
20
- 'default-src': ["'none'"],
9
+ exports.DEFAULT_CSP = {
10
+ 'upgrade-insecure-requests': true,
11
+ 'default-src': ["'none'"],
12
+ };
13
+ async function sendWebPage(res, { csp: inputCsp, ...options }) {
14
+ // @NOTE the csp string might be quite long. In that case it might be tempting
15
+ // to set it through the http-equiv <meta> in the HTML. However, some
16
+ // directives cannot be enforced by browsers when set through the meta tag
17
+ // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the
18
+ // HTTP header.
19
+ const csp = (0, index_js_1.mergeCsp)(exports.DEFAULT_CSP, inputCsp, {
21
20
  'base-uri': options.base?.origin,
22
- 'script-src': ["'self'", ...assetsToCsp(options.scripts)],
23
- 'style-src': ["'self'", ...assetsToCsp(options.styles)],
24
- 'img-src': ["'self'", 'data:', 'https:'],
25
- 'connect-src': ["'self'"],
26
- 'upgrade-insecure-requests': true,
27
- // Prevents the CSP to be embedded in a page <meta>:
28
- 'frame-ancestors': ["'none'"],
21
+ 'script-src': options.scripts?.map(assetToCsp),
22
+ 'style-src': options.styles?.map(assetToCsp),
29
23
  });
30
- // @NOTE the csp string might become too long. However, since we need to
31
- // specify the "frame-ancestors" directive, we can't use a meta tag. For that
32
- // reason, we won't try to avoid too long headers and let the proxy throw
33
- // in case of a too long header.
34
- res.setHeader('Content-Security-Policy', (0, index_js_1.buildCsp)(csp));
35
- // @TODO: make these headers configurable (?)
36
- res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()');
37
- res.setHeader('Cross-Origin-Embedder-Policy', 'credentialless');
38
- res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
39
- res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
40
- res.setHeader('Referrer-Policy', 'same-origin');
41
- res.setHeader('X-Frame-Options', 'DENY');
42
- res.setHeader('X-Content-Type-Options', 'nosniff');
43
- res.setHeader('X-XSS-Protection', '0');
44
- res.setHeader('Strict-Transport-Security', 'max-age=63072000');
45
- const html = (0, index_js_2.buildDocument)(options);
46
- return (0, response_js_1.writeHtml)(res, html.toString(), options);
47
- }
48
- function* assetsToCsp(assets) {
49
- if (assets) {
50
- for (const asset of assets) {
51
- yield assetToCsp(asset);
52
- }
53
- }
24
+ const html = (0, index_js_2.buildDocument)(options).toString();
25
+ return (0, response_js_1.writeHtml)(res, html, { ...options, csp });
54
26
  }
55
27
  function assetToCsp(asset) {
56
28
  if (asset instanceof index_js_2.Html) {
57
- const hash = (0, node_crypto_1.createHash)('sha256').update(asset.toString()).digest('base64');
58
- return `'sha256-${hash}'`;
29
+ // Inline assets are "allowed" by their hash
30
+ const hash = (0, node_crypto_1.createHash)('sha256');
31
+ for (const fragment of asset)
32
+ hash.update(fragment);
33
+ return `'sha256-${hash.digest('base64')}'`;
59
34
  }
60
35
  else {
61
- return `'sha256-${asset.sha256}'`;
36
+ // External assets are referenced by their origin
37
+ if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {
38
+ return new URL(asset.url).origin;
39
+ }
40
+ // Internal assets are served from the same origin
41
+ return `'self'`;
62
42
  }
63
43
  }
64
44
  //# sourceMappingURL=send-web-page.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;AAYA,gDAMC;AAOD,kCAqCC;AAED,kCAQC;AAED,gCAOC;AAjFD,6CAAwC;AAExC,kDAA6E;AAC7E,mDAM6B;AAC7B,yDAAyE;AAEzE,SAAgB,kBAAkB,CAAC,IAAY,EAAE,IAAa;IAC5D,8EAA8E;IAC9E,8EAA8E;IAC9E,8DAA8D;IAC9D,0DAA0D;IAC1D,OAAO,IAAA,aAAE,EAAA,UAAU,IAAI,KAAK,IAAI,mCAAmC,CAAA;AACrE,CAAC;AAOM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,OAA2B;IAE3B,MAAM,GAAG,GAAG,IAAA,mBAAQ,EAAC,OAAO,CAAC,GAAG,EAAE;QAChC,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzD,WAAW,EAAE,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;QACxC,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,2BAA2B,EAAE,IAAI;QAEjC,oDAAoD;QACpD,iBAAiB,EAAE,CAAC,QAAQ,CAAC;KAC9B,CAAC,CAAA;IAEF,wEAAwE;IACxE,6EAA6E;IAC7E,yEAAyE;IACzE,gCAAgC;IAChC,GAAG,CAAC,SAAS,CAAC,yBAAyB,EAAE,IAAA,mBAAQ,EAAC,GAAG,CAAC,CAAC,CAAA;IAEvD,6CAA6C;IAC7C,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAA;IAC5E,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,CAAA;IAC/D,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAA;IAC5D,GAAG,CAAC,SAAS,CAAC,4BAA4B,EAAE,aAAa,CAAC,CAAA;IAC1D,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;IAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;IACxC,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAA;IAClD,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IACtC,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAA;IAE9D,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAA;IAEnC,OAAO,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAA;AACjD,CAAC;AAED,QAAe,CAAC,CAAC,WAAW,CAC1B,MAAkC;IAElC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,KAAsB;IAC/C,IAAI,KAAK,YAAY,eAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC3E,OAAO,WAAW,IAAI,GAAG,CAAA;IAC3B,CAAC;SAAM,CAAC;QACN,OAAO,WAAW,KAAK,CAAC,MAAM,GAAG,CAAA;IACnC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;;AAkBA,kCAiBC;AAnCD,6CAAwC;AAExC,kDAAmE;AACnE,mDAK6B;AAC7B,yDAAqE;AAExD,QAAA,WAAW,GAAc;IACpC,2BAA2B,EAAE,IAAI;IACjC,aAAa,EAAE,CAAC,QAAQ,CAAC;CAC1B,CAAA;AAIM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAsB;IAEjD,8EAA8E;IAC9E,qEAAqE;IACrE,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAe;IACf,MAAM,GAAG,GAAG,IAAA,mBAAQ,EAAC,mBAAW,EAAE,QAAQ,EAAE;QAC1C,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC;QAC9C,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC;KAC7C,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC9C,OAAO,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,KAAsB;IACxC,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"}
@@ -2,18 +2,18 @@ import { z } from 'zod';
2
2
  import { Simplify } from '../lib/util/type.js';
3
3
  export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
4
4
  iat: z.ZodNumber;
5
- aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
6
5
  iss: z.ZodString;
6
+ aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
7
7
  exp: z.ZodNumber;
8
8
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
9
9
  iat: z.ZodNumber;
10
- aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
11
10
  iss: z.ZodString;
11
+ aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
12
12
  exp: z.ZodNumber;
13
13
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
14
14
  iat: z.ZodNumber;
15
- aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
16
15
  iss: z.ZodString;
16
+ aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
17
17
  exp: z.ZodNumber;
18
18
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<z.objectUtil.extendShape<{
19
19
  nonce: z.ZodOptional<z.ZodOptional<z.ZodString>>;
@@ -200,8 +200,8 @@ export declare class Signer {
200
200
  htu?: string | undefined;
201
201
  ath?: string | undefined;
202
202
  sub?: string | undefined;
203
- aud?: string | [string, ...string[]] | undefined;
204
203
  iss?: string | undefined;
204
+ aud?: string | [string, ...string[]] | undefined;
205
205
  exp?: number | undefined;
206
206
  nbf?: number | undefined;
207
207
  azp?: string | undefined;
@@ -5817,8 +5817,8 @@ export declare class Signer {
5817
5817
  htu?: string | undefined;
5818
5818
  ath?: string | undefined;
5819
5819
  sub?: string | undefined;
5820
- aud?: string | [string, ...string[]] | undefined;
5821
5820
  iss?: string | undefined;
5821
+ aud?: string | [string, ...string[]] | undefined;
5822
5822
  exp?: number | undefined;
5823
5823
  nbf?: number | undefined;
5824
5824
  azp?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/oauth-provider",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
4
4
  "license": "MIT",
5
5
  "description": "Generic OAuth2 and OpenID Connect provider for Node.js. Currently only supports features needed for Atproto.",
6
6
  "keywords": [
@@ -43,49 +43,24 @@
43
43
  "jose": "^5.2.0",
44
44
  "psl": "^1.9.0",
45
45
  "zod": "^3.23.8",
46
+ "@atproto-labs/fetch": "0.2.2",
46
47
  "@atproto-labs/fetch-node": "0.1.8",
47
48
  "@atproto-labs/pipe": "0.1.0",
48
49
  "@atproto-labs/simple-store": "0.1.2",
49
50
  "@atproto-labs/simple-store-memory": "0.1.2",
50
- "@atproto/common": "^0.4.8",
51
51
  "@atproto/jwk": "0.1.4",
52
52
  "@atproto/jwk-jose": "0.1.5",
53
53
  "@atproto/oauth-types": "0.2.4",
54
- "@atproto/syntax": "0.3.4",
55
- "@atproto-labs/fetch": "0.2.2"
54
+ "@atproto/oauth-provider-api": "0.0.1",
55
+ "@atproto/common": "^0.4.8",
56
+ "@atproto/oauth-provider-ui": "0.0.2",
57
+ "@atproto/syntax": "0.4.0"
56
58
  },
57
59
  "devDependencies": {
58
- "@hcaptcha/react-hcaptcha": "^1.11.2",
59
- "@lingui/cli": "^5.2.0",
60
- "@lingui/core": "^5.2.0",
61
- "@lingui/react": "^5.2.0",
62
- "@lingui/swc-plugin": "^5.4.0",
63
- "@lingui/vite-plugin": "^5.2.0",
64
- "@rollup/plugin-commonjs": "^28.0.2",
65
- "@rollup/plugin-dynamic-import-vars": "^2.1.5",
66
- "@rollup/plugin-node-resolve": "^16.0.0",
67
- "@rollup/plugin-swc": "^0.4.0",
68
- "@swc/core": "^1.10.18",
69
- "@swc/helpers": "^0.5.15",
70
60
  "@types/cookie": "^0.6.0",
71
61
  "@types/forwarded": "0.1.3",
72
62
  "@types/psl": "1.1.3",
73
- "@types/react": "^19.0.10",
74
- "@types/react-dom": "^19.0.4",
75
- "@types/send": "^0.17.4",
76
- "@vitejs/plugin-react-swc": "^3.8.0",
77
- "@web/rollup-plugin-import-meta-assets": "^2.2.1",
78
- "autoprefixer": "^10.4.17",
79
- "postcss": "^8.4.38",
80
- "react": "^19.0.0",
81
- "react-dom": "^19.0.0",
82
- "react-error-boundary": "^5.0.0",
83
- "rollup": "^4.13.0",
84
- "rollup-plugin-postcss": "^4.0.2",
85
- "tailwindcss": "^3.4.3",
86
- "typescript": "^5.6.3",
87
- "vite": "^6.2.0",
88
- "@atproto-labs/rollup-plugin-bundle-manifest": "0.1.2"
63
+ "@types/send": "^0.17.4"
89
64
  },
90
65
  "postcss": {
91
66
  "plugins": {
@@ -94,14 +69,6 @@
94
69
  }
95
70
  },
96
71
  "scripts": {
97
- "po:extract": "lingui extract --clean",
98
- "po:compile": "lingui compile --typescript",
99
- "prebuild:frontend": "pnpm po:compile",
100
- "build:frontend": "rollup --config rollup.config.js",
101
- "build:backend": "tsc --build --force tsconfig.backend.json",
102
- "start:ui": "vite",
103
- "dev:frontend": "pnpm run build:frontend --watch",
104
- "dev:catalogs": "pnpm run po:extract --debounce 250 --watch > /dev/null",
105
- "dev:messages": "pnpm run po:compile --debounce 500 --watch"
72
+ "build": "tsc --build tsconfig.backend.json"
106
73
  }
107
74
  }
@@ -18,9 +18,10 @@ import {
18
18
  AccountStore,
19
19
  ResetPasswordConfirmData,
20
20
  ResetPasswordRequestData,
21
+ SignUpData,
21
22
  } from './account-store.js'
22
23
  import { SignInData } from './sign-in-data.js'
23
- import { SignUpData } from './sign-up-data.js'
24
+ import { SignUpInput } from './sign-up-input.js'
24
25
 
25
26
  const TIMING_ATTACK_MITIGATION_DELAY = 400
26
27
  const BRUTE_FORCE_MITIGATION_DELAY = 300
@@ -41,59 +42,79 @@ export class AccountManager {
41
42
  : undefined
42
43
  }
43
44
 
44
- protected async verifySignupData(
45
- data: SignUpData,
45
+ protected async processHcaptchaToken(
46
+ input: SignUpInput,
46
47
  deviceId: DeviceId,
47
48
  deviceMetadata: RequestMetadata,
48
- ): Promise<void> {
49
- let hcaptchaResult: undefined | HcaptchaVerifyResult
50
-
51
- if (this.inviteCodeRequired && !data.inviteCode) {
52
- throw new InvalidRequestError('Invite code is required')
49
+ ): Promise<HcaptchaVerifyResult | undefined> {
50
+ if (!this.hcaptchaClient) {
51
+ return undefined
53
52
  }
54
53
 
55
- if (this.hcaptchaClient) {
56
- if (!data.hcaptchaToken) {
57
- throw new InvalidRequestError('hCaptcha token is required')
58
- }
54
+ if (!input.hcaptchaToken) {
55
+ throw new InvalidRequestError('hCaptcha token is required')
56
+ }
59
57
 
60
- const { allowed, result } = await this.hcaptchaClient.verify(
58
+ const { allowed, result } = await this.hcaptchaClient
59
+ .verify(
61
60
  'signup',
62
- data.hcaptchaToken,
61
+ input.hcaptchaToken,
63
62
  deviceMetadata.ipAddress,
64
- data.handle,
63
+ input.handle,
65
64
  deviceMetadata.userAgent,
66
65
  )
67
-
68
- await callAsync(this.hooks.onSignupHcaptchaResult, {
69
- data,
70
- allowed,
71
- result,
72
- deviceId,
73
- deviceMetadata,
66
+ .catch((err) => {
67
+ throw InvalidRequestError.from(err, 'hCaptcha verification failed')
74
68
  })
75
69
 
76
- if (!allowed) {
77
- throw new InvalidRequestError('hCaptcha verification failed')
78
- }
70
+ if (!allowed) {
71
+ throw new InvalidRequestError('hCaptcha verification failed')
72
+ }
73
+
74
+ return result
75
+ }
79
76
 
80
- hcaptchaResult = result
77
+ protected async enforceInviteCode(
78
+ input: SignUpInput,
79
+ _deviceId: DeviceId,
80
+ _deviceMetadata: RequestMetadata,
81
+ ): Promise<string | undefined> {
82
+ if (!this.inviteCodeRequired) {
83
+ return undefined
81
84
  }
82
85
 
83
- await callAsync(this.hooks.onSignupAttempt, {
84
- data,
85
- deviceId,
86
- deviceMetadata,
87
- hcaptchaResult,
88
- })
86
+ if (!input.inviteCode) {
87
+ throw new InvalidRequestError('Invite code is required')
88
+ }
89
+
90
+ return input.inviteCode
91
+ }
92
+
93
+ protected async buildSignupData(
94
+ input: SignUpInput,
95
+ deviceId: DeviceId,
96
+ deviceMetadata: RequestMetadata,
97
+ ): Promise<SignUpData> {
98
+ const [hcaptchaResult, inviteCode] = await Promise.all([
99
+ this.processHcaptchaToken(input, deviceId, deviceMetadata),
100
+ this.enforceInviteCode(input, deviceId, deviceMetadata),
101
+ ])
102
+
103
+ return { ...input, hcaptchaResult, inviteCode }
89
104
  }
90
105
 
91
106
  public async signUp(
92
- data: SignUpData,
107
+ input: SignUpInput,
93
108
  deviceId: DeviceId,
94
109
  deviceMetadata: RequestMetadata,
95
110
  ): Promise<AccountInfo> {
96
- await this.verifySignupData(data, deviceId, deviceMetadata)
111
+ await callAsync(this.hooks.onSignupAttempt, {
112
+ input,
113
+ deviceId,
114
+ deviceMetadata,
115
+ })
116
+
117
+ const data = await this.buildSignupData(input, deviceId, deviceMetadata)
97
118
 
98
119
  // Mitigation against brute forcing email of users.
99
120
  // @TODO Add rate limit to all the OAuth routes.
@@ -4,6 +4,7 @@ import { z } from 'zod'
4
4
  import { ensureValidHandle, normalizeHandle } from '@atproto/syntax'
5
5
  import { ClientId } from '../client/client-id.js'
6
6
  import { DeviceId } from '../device/device-id.js'
7
+ import { HcaptchaVerifyResult } from '../lib/hcaptcha.js'
7
8
  import { localeSchema } from '../lib/locale.js'
8
9
  import { Awaitable, buildInterfaceChecker } from '../lib/util/type.js'
9
10
  import {
@@ -13,6 +14,7 @@ import {
13
14
  } from '../oauth-errors.js'
14
15
  import { Sub } from '../oidc/sub.js'
15
16
  import { Account } from './account.js'
17
+ import { SignUpInput } from './sign-up-input.js'
16
18
 
17
19
  // @NOTE Change the length here to force stronger passwords (through a reset)
18
20
  export const oldPasswordSchema = z.string().min(1)
@@ -49,6 +51,7 @@ export const emailSchema = z
49
51
  })
50
52
  .transform((value) => value.toLowerCase())
51
53
  export const inviteCodeSchema = z.string().min(1)
54
+ export type InviteCode = z.infer<typeof inviteCodeSchema>
52
55
 
53
56
  export const authenticateAccountDataSchema = z
54
57
  .object({
@@ -118,6 +121,11 @@ export type AccountInfo = {
118
121
  info: DeviceAccountInfo
119
122
  }
120
123
 
124
+ export type SignUpData = SignUpInput & {
125
+ hcaptchaResult?: HcaptchaVerifyResult
126
+ inviteCode?: InviteCode
127
+ }
128
+
121
129
  export interface AccountStore {
122
130
  /**
123
131
  * @throws {HandleUnavailableError} - To indicate that the handle is already taken
@@ -1,14 +1 @@
1
- import { Simplify } from '../lib/util/type.js'
2
- import { Sub } from '../oidc/sub.js'
3
-
4
- export type Account = Simplify<{
5
- sub: Sub // Account id
6
- aud: string | [string, ...string[]] // Resource server URL
7
-
8
- // OIDC inspired
9
- preferred_username?: string
10
- email?: string
11
- email_verified?: boolean
12
- picture?: string
13
- name?: string
14
- }>
1
+ export type { Account } from '@atproto/oauth-provider-api'
@@ -2,10 +2,10 @@ import { z } from 'zod'
2
2
  import { hcaptchaTokenSchema } from '../lib/hcaptcha.js'
3
3
  import { createAccountDataSchema } from './account-store.js'
4
4
 
5
- export const signUpDataSchema = createAccountDataSchema
5
+ export const signUpInputSchema = createAccountDataSchema
6
6
  .extend({
7
7
  hcaptchaToken: hcaptchaTokenSchema.optional(),
8
8
  })
9
9
  .strict()
10
10
 
11
- export type SignUpData = z.TypeOf<typeof signUpDataSchema>
11
+ export type SignUpInput = z.TypeOf<typeof signUpInputSchema>