@atproto/oauth-provider 0.5.1 → 0.6.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 (325) hide show
  1. package/CHANGELOG.md +39 -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 +13 -5
  7. package/dist/account/account-store.d.ts.map +1 -1
  8. package/dist/account/account-store.js +24 -8
  9. package/dist/account/account-store.js.map +1 -1
  10. package/dist/account/account.d.ts +1 -11
  11. package/dist/account/account.d.ts.map +1 -1
  12. package/dist/account/{sign-up-data.d.ts → sign-up-input.d.ts} +5 -5
  13. package/dist/account/sign-up-input.d.ts.map +1 -0
  14. package/dist/account/{sign-up-data.js → sign-up-input.js} +3 -3
  15. package/dist/account/sign-up-input.js.map +1 -0
  16. package/dist/assets/assets-middleware.d.ts +2 -0
  17. package/dist/assets/assets-middleware.d.ts.map +1 -1
  18. package/dist/assets/assets-middleware.js +12 -14
  19. package/dist/assets/assets-middleware.js.map +1 -1
  20. package/dist/errors/invalid-invite-code-error.d.ts +5 -0
  21. package/dist/errors/invalid-invite-code-error.d.ts.map +1 -0
  22. package/dist/errors/invalid-invite-code-error.js +11 -0
  23. package/dist/errors/invalid-invite-code-error.js.map +1 -0
  24. package/dist/errors/oauth-error.d.ts +2 -2
  25. package/dist/errors/oauth-error.js.map +1 -1
  26. package/dist/lib/csp/index.d.ts +5 -6
  27. package/dist/lib/csp/index.d.ts.map +1 -1
  28. package/dist/lib/csp/index.js +14 -11
  29. package/dist/lib/csp/index.js.map +1 -1
  30. package/dist/lib/hcaptcha.d.ts +5 -3
  31. package/dist/lib/hcaptcha.d.ts.map +1 -1
  32. package/dist/lib/hcaptcha.js +7 -4
  33. package/dist/lib/hcaptcha.js.map +1 -1
  34. package/dist/lib/html/build-document.d.ts +2 -2
  35. package/dist/lib/html/build-document.d.ts.map +1 -1
  36. package/dist/lib/html/build-document.js +11 -7
  37. package/dist/lib/html/build-document.js.map +1 -1
  38. package/dist/lib/html/html.d.ts.map +1 -1
  39. package/dist/lib/html/html.js +10 -13
  40. package/dist/lib/html/html.js.map +1 -1
  41. package/dist/lib/html/util.d.ts +0 -1
  42. package/dist/lib/html/util.d.ts.map +1 -1
  43. package/dist/lib/html/util.js +0 -4
  44. package/dist/lib/html/util.js.map +1 -1
  45. package/dist/lib/http/response.d.ts +3 -1
  46. package/dist/lib/http/response.d.ts.map +1 -1
  47. package/dist/lib/http/response.js +3 -0
  48. package/dist/lib/http/response.js.map +1 -1
  49. package/dist/lib/http/security-headers.d.ts +48 -0
  50. package/dist/lib/http/security-headers.d.ts.map +1 -0
  51. package/dist/lib/http/security-headers.js +62 -0
  52. package/dist/lib/http/security-headers.js.map +1 -0
  53. package/dist/lib/util/type.d.ts +8 -0
  54. package/dist/lib/util/type.d.ts.map +1 -1
  55. package/dist/lib/util/type.js.map +1 -1
  56. package/dist/oauth-errors.d.ts +1 -0
  57. package/dist/oauth-errors.d.ts.map +1 -1
  58. package/dist/oauth-errors.js +3 -1
  59. package/dist/oauth-errors.js.map +1 -1
  60. package/dist/oauth-hooks.d.ts +4 -25
  61. package/dist/oauth-hooks.d.ts.map +1 -1
  62. package/dist/oauth-provider.d.ts.map +1 -1
  63. package/dist/oauth-provider.js +26 -25
  64. package/dist/oauth-provider.js.map +1 -1
  65. package/dist/output/backend-data.d.ts +4 -0
  66. package/dist/output/backend-data.d.ts.map +1 -0
  67. package/dist/output/backend-data.js +19 -0
  68. package/dist/output/backend-data.js.map +1 -0
  69. package/dist/output/build-authorize-data.d.ts +3 -19
  70. package/dist/output/build-authorize-data.d.ts.map +1 -1
  71. package/dist/output/build-authorize-data.js.map +1 -1
  72. package/dist/output/build-customization-data.d.ts +11 -18
  73. package/dist/output/build-customization-data.d.ts.map +1 -1
  74. package/dist/output/build-customization-data.js +1 -1
  75. package/dist/output/build-customization-data.js.map +1 -1
  76. package/dist/output/build-error-data.d.ts +3 -0
  77. package/dist/output/build-error-data.d.ts.map +1 -0
  78. package/dist/output/build-error-data.js +10 -0
  79. package/dist/output/build-error-data.js.map +1 -0
  80. package/dist/output/build-error-payload.d.ts +2 -1
  81. package/dist/output/build-error-payload.d.ts.map +1 -1
  82. package/dist/output/build-error-payload.js.map +1 -1
  83. package/dist/output/output-manager.d.ts +10 -4
  84. package/dist/output/output-manager.d.ts.map +1 -1
  85. package/dist/output/output-manager.js +68 -39
  86. package/dist/output/output-manager.js.map +1 -1
  87. package/dist/output/send-web-page.d.ts +6 -10
  88. package/dist/output/send-web-page.d.ts.map +1 -1
  89. package/dist/output/send-web-page.js +27 -47
  90. package/dist/output/send-web-page.js.map +1 -1
  91. package/dist/signer/signed-token-payload.d.ts +3 -3
  92. package/dist/signer/signer.d.ts +2 -2
  93. package/package.json +7 -39
  94. package/src/account/account-manager.ts +55 -34
  95. package/src/account/account-store.ts +29 -6
  96. package/src/account/account.ts +1 -14
  97. package/src/account/{sign-up-data.ts → sign-up-input.ts} +2 -2
  98. package/src/assets/assets-middleware.ts +11 -17
  99. package/src/errors/invalid-invite-code-error.ts +10 -0
  100. package/src/errors/oauth-error.ts +1 -1
  101. package/src/lib/csp/index.ts +16 -13
  102. package/src/lib/hcaptcha.ts +10 -7
  103. package/src/lib/html/build-document.ts +15 -8
  104. package/src/lib/html/html.ts +11 -18
  105. package/src/lib/html/util.ts +0 -4
  106. package/src/lib/http/response.ts +9 -1
  107. package/src/lib/http/security-headers.ts +91 -0
  108. package/src/lib/util/type.ts +18 -0
  109. package/src/oauth-errors.ts +1 -0
  110. package/src/oauth-hooks.ts +4 -25
  111. package/src/oauth-provider.ts +40 -34
  112. package/src/output/backend-data.ts +18 -0
  113. package/src/output/build-authorize-data.ts +3 -26
  114. package/src/output/build-customization-data.ts +2 -13
  115. package/src/output/build-error-data.ts +8 -0
  116. package/src/output/build-error-payload.ts +4 -2
  117. package/src/output/output-manager.ts +86 -47
  118. package/src/output/send-web-page.ts +29 -58
  119. package/tsconfig.backend.json +1 -2
  120. package/tsconfig.backend.tsbuildinfo +1 -1
  121. package/tsconfig.json +1 -5
  122. package/.linguirc +0 -57
  123. package/dist/account/sign-up-data.d.ts.map +0 -1
  124. package/dist/account/sign-up-data.js.map +0 -1
  125. package/dist/assets/app/bundle-manifest.json +0 -614
  126. package/dist/assets/app/index-ItwwtJ8r.js +0 -36
  127. package/dist/assets/app/index-ItwwtJ8r.js.map +0 -1
  128. package/dist/assets/app/main-B_dNxQo_.js +0 -4
  129. package/dist/assets/app/main-B_dNxQo_.js.map +0 -1
  130. package/dist/assets/app/main-CSatvmRR.css +0 -3
  131. package/dist/assets/app/main-CSatvmRR.js +0 -306
  132. package/dist/assets/app/main-CSatvmRR.js.map +0 -1
  133. package/dist/assets/app/messages-BQeltXSF.js +0 -4
  134. package/dist/assets/app/messages-BQeltXSF.js.map +0 -1
  135. package/dist/assets/app/messages-BQkEhfjg.js +0 -4
  136. package/dist/assets/app/messages-BQkEhfjg.js.map +0 -1
  137. package/dist/assets/app/messages-BUjKj_UJ.js +0 -4
  138. package/dist/assets/app/messages-BUjKj_UJ.js.map +0 -1
  139. package/dist/assets/app/messages-BWIQa8fO.js +0 -4
  140. package/dist/assets/app/messages-BWIQa8fO.js.map +0 -1
  141. package/dist/assets/app/messages-BaNVb0bp.js +0 -4
  142. package/dist/assets/app/messages-BaNVb0bp.js.map +0 -1
  143. package/dist/assets/app/messages-BaizVXcF.js +0 -4
  144. package/dist/assets/app/messages-BaizVXcF.js.map +0 -1
  145. package/dist/assets/app/messages-BfoClA1Y.js +0 -4
  146. package/dist/assets/app/messages-BfoClA1Y.js.map +0 -1
  147. package/dist/assets/app/messages-BsKGDZnC.js +0 -4
  148. package/dist/assets/app/messages-BsKGDZnC.js.map +0 -1
  149. package/dist/assets/app/messages-Bu-TJhml.js +0 -4
  150. package/dist/assets/app/messages-Bu-TJhml.js.map +0 -1
  151. package/dist/assets/app/messages-BvOKnBQk.js +0 -4
  152. package/dist/assets/app/messages-BvOKnBQk.js.map +0 -1
  153. package/dist/assets/app/messages-BxDzCiWz.js +0 -4
  154. package/dist/assets/app/messages-BxDzCiWz.js.map +0 -1
  155. package/dist/assets/app/messages-CDgFOy4S.js +0 -4
  156. package/dist/assets/app/messages-CDgFOy4S.js.map +0 -1
  157. package/dist/assets/app/messages-CLbTz0o9.js +0 -4
  158. package/dist/assets/app/messages-CLbTz0o9.js.map +0 -1
  159. package/dist/assets/app/messages-CNwSh0t7.js +0 -4
  160. package/dist/assets/app/messages-CNwSh0t7.js.map +0 -1
  161. package/dist/assets/app/messages-CSMNJ6P8.js +0 -4
  162. package/dist/assets/app/messages-CSMNJ6P8.js.map +0 -1
  163. package/dist/assets/app/messages-CZQUw3mp.js +0 -4
  164. package/dist/assets/app/messages-CZQUw3mp.js.map +0 -1
  165. package/dist/assets/app/messages-CZT41oVp.js +0 -4
  166. package/dist/assets/app/messages-CZT41oVp.js.map +0 -1
  167. package/dist/assets/app/messages-C_b-d3t8.js +0 -4
  168. package/dist/assets/app/messages-C_b-d3t8.js.map +0 -1
  169. package/dist/assets/app/messages-C_u3MTc2.js +0 -4
  170. package/dist/assets/app/messages-C_u3MTc2.js.map +0 -1
  171. package/dist/assets/app/messages-Cn8nHZic.js +0 -4
  172. package/dist/assets/app/messages-Cn8nHZic.js.map +0 -1
  173. package/dist/assets/app/messages-CtDywJUm.js +0 -4
  174. package/dist/assets/app/messages-CtDywJUm.js.map +0 -1
  175. package/dist/assets/app/messages-CurtIjBF.js +0 -4
  176. package/dist/assets/app/messages-CurtIjBF.js.map +0 -1
  177. package/dist/assets/app/messages-Cv6zIbaP.js +0 -4
  178. package/dist/assets/app/messages-Cv6zIbaP.js.map +0 -1
  179. package/dist/assets/app/messages-D1eLQuPE.js +0 -4
  180. package/dist/assets/app/messages-D1eLQuPE.js.map +0 -1
  181. package/dist/assets/app/messages-D8vHEaYW.js +0 -4
  182. package/dist/assets/app/messages-D8vHEaYW.js.map +0 -1
  183. package/dist/assets/app/messages-DJ1Q4GeC.js +0 -4
  184. package/dist/assets/app/messages-DJ1Q4GeC.js.map +0 -1
  185. package/dist/assets/app/messages-DRL3exqd.js +0 -4
  186. package/dist/assets/app/messages-DRL3exqd.js.map +0 -1
  187. package/dist/assets/app/messages-DWLPQRTp.js +0 -4
  188. package/dist/assets/app/messages-DWLPQRTp.js.map +0 -1
  189. package/dist/assets/app/messages-DjVaE9YE.js +0 -4
  190. package/dist/assets/app/messages-DjVaE9YE.js.map +0 -1
  191. package/dist/assets/app/messages-DqpMfFJR.js +0 -4
  192. package/dist/assets/app/messages-DqpMfFJR.js.map +0 -1
  193. package/dist/assets/app/messages-ETjhJBEN.js +0 -4
  194. package/dist/assets/app/messages-ETjhJBEN.js.map +0 -1
  195. package/dist/assets/app/messages-EUKrgrGn.js +0 -4
  196. package/dist/assets/app/messages-EUKrgrGn.js.map +0 -1
  197. package/dist/assets/app/messages-QQrOUcPW.js +0 -4
  198. package/dist/assets/app/messages-QQrOUcPW.js.map +0 -1
  199. package/dist/assets/app/messages-e2QGqFL6.js +0 -4
  200. package/dist/assets/app/messages-e2QGqFL6.js.map +0 -1
  201. package/dist/assets/app/messages-p61py7gD.js +0 -4
  202. package/dist/assets/app/messages-p61py7gD.js.map +0 -1
  203. package/dist/assets/asset.d.ts +0 -9
  204. package/dist/assets/asset.d.ts.map +0 -1
  205. package/dist/assets/asset.js +0 -3
  206. package/dist/assets/asset.js.map +0 -1
  207. package/dist/assets/index.d.ts +0 -5
  208. package/dist/assets/index.d.ts.map +0 -1
  209. package/dist/assets/index.js +0 -78
  210. package/dist/assets/index.js.map +0 -1
  211. package/rollup.config.js +0 -98
  212. package/src/assets/app/app.tsx +0 -43
  213. package/src/assets/app/backend-data.ts +0 -27
  214. package/src/assets/app/backend-types.ts +0 -66
  215. package/src/assets/app/components/forms/button-toggle-visibility.tsx +0 -43
  216. package/src/assets/app/components/forms/button.tsx +0 -60
  217. package/src/assets/app/components/forms/fieldset.tsx +0 -55
  218. package/src/assets/app/components/forms/form-card-async.tsx +0 -103
  219. package/src/assets/app/components/forms/form-card.tsx +0 -49
  220. package/src/assets/app/components/forms/input-checkbox.tsx +0 -73
  221. package/src/assets/app/components/forms/input-container.tsx +0 -107
  222. package/src/assets/app/components/forms/input-email-address.tsx +0 -66
  223. package/src/assets/app/components/forms/input-new-password.tsx +0 -62
  224. package/src/assets/app/components/forms/input-password.tsx +0 -88
  225. package/src/assets/app/components/forms/input-text.tsx +0 -76
  226. package/src/assets/app/components/forms/input-token.tsx +0 -94
  227. package/src/assets/app/components/forms/wizard-card.tsx +0 -116
  228. package/src/assets/app/components/layouts/layout-title-page.tsx +0 -77
  229. package/src/assets/app/components/layouts/layout-welcome.tsx +0 -73
  230. package/src/assets/app/components/utils/account-identifier.tsx +0 -23
  231. package/src/assets/app/components/utils/account-image.tsx +0 -33
  232. package/src/assets/app/components/utils/admonition.tsx +0 -52
  233. package/src/assets/app/components/utils/client-name.tsx +0 -45
  234. package/src/assets/app/components/utils/error-card.tsx +0 -93
  235. package/src/assets/app/components/utils/error-message.tsx +0 -62
  236. package/src/assets/app/components/utils/help-card.tsx +0 -46
  237. package/src/assets/app/components/utils/icons.tsx +0 -88
  238. package/src/assets/app/components/utils/link-anchor.tsx +0 -28
  239. package/src/assets/app/components/utils/link-title.tsx +0 -26
  240. package/src/assets/app/components/utils/multi-lang-string.tsx +0 -56
  241. package/src/assets/app/components/utils/password-strength-label.tsx +0 -37
  242. package/src/assets/app/components/utils/password-strength-meter.tsx +0 -58
  243. package/src/assets/app/components/utils/url-viewer.tsx +0 -73
  244. package/src/assets/app/cookies.ts +0 -11
  245. package/src/assets/app/hooks/use-api.ts +0 -178
  246. package/src/assets/app/hooks/use-async-action.ts +0 -120
  247. package/src/assets/app/hooks/use-bound-dispatch.ts +0 -5
  248. package/src/assets/app/hooks/use-browser-color-scheme.ts +0 -31
  249. package/src/assets/app/hooks/use-csrf-token.ts +0 -5
  250. package/src/assets/app/hooks/use-random-string.ts +0 -37
  251. package/src/assets/app/hooks/use-stepper.ts +0 -87
  252. package/src/assets/app/index.html +0 -182
  253. package/src/assets/app/lib/api.ts +0 -267
  254. package/src/assets/app/lib/clsx.ts +0 -6
  255. package/src/assets/app/lib/json-client.ts +0 -94
  256. package/src/assets/app/lib/password.ts +0 -98
  257. package/src/assets/app/lib/ref.ts +0 -17
  258. package/src/assets/app/lib/util.ts +0 -13
  259. package/src/assets/app/locales/an/messages.po +0 -492
  260. package/src/assets/app/locales/ast/messages.po +0 -492
  261. package/src/assets/app/locales/ca/messages.po +0 -492
  262. package/src/assets/app/locales/da/messages.po +0 -492
  263. package/src/assets/app/locales/de/messages.po +0 -492
  264. package/src/assets/app/locales/el/messages.po +0 -492
  265. package/src/assets/app/locales/en/messages.po +0 -492
  266. package/src/assets/app/locales/en-GB/messages.po +0 -492
  267. package/src/assets/app/locales/es/messages.po +0 -492
  268. package/src/assets/app/locales/eu/messages.po +0 -492
  269. package/src/assets/app/locales/fi/messages.po +0 -492
  270. package/src/assets/app/locales/fr/messages.po +0 -492
  271. package/src/assets/app/locales/ga/messages.po +0 -492
  272. package/src/assets/app/locales/gl/messages.po +0 -492
  273. package/src/assets/app/locales/hi/messages.po +0 -492
  274. package/src/assets/app/locales/hu/messages.po +0 -492
  275. package/src/assets/app/locales/ia/messages.po +0 -492
  276. package/src/assets/app/locales/id/messages.po +0 -492
  277. package/src/assets/app/locales/it/messages.po +0 -492
  278. package/src/assets/app/locales/ja/messages.po +0 -492
  279. package/src/assets/app/locales/km/messages.po +0 -492
  280. package/src/assets/app/locales/ko/messages.po +0 -492
  281. package/src/assets/app/locales/load.ts +0 -8
  282. package/src/assets/app/locales/locale-context.ts +0 -19
  283. package/src/assets/app/locales/locale-provider.tsx +0 -112
  284. package/src/assets/app/locales/locale-selector.tsx +0 -58
  285. package/src/assets/app/locales/locales.ts +0 -168
  286. package/src/assets/app/locales/ne/messages.po +0 -492
  287. package/src/assets/app/locales/nl/messages.po +0 -492
  288. package/src/assets/app/locales/pl/messages.po +0 -492
  289. package/src/assets/app/locales/pt-BR/messages.po +0 -492
  290. package/src/assets/app/locales/ro/messages.po +0 -492
  291. package/src/assets/app/locales/ru/messages.po +0 -492
  292. package/src/assets/app/locales/sv/messages.po +0 -492
  293. package/src/assets/app/locales/th/messages.po +0 -492
  294. package/src/assets/app/locales/tr/messages.po +0 -492
  295. package/src/assets/app/locales/uk/messages.po +0 -492
  296. package/src/assets/app/locales/vi/messages.po +0 -492
  297. package/src/assets/app/locales/zh-CN/messages.po +0 -492
  298. package/src/assets/app/locales/zh-HK/messages.po +0 -492
  299. package/src/assets/app/locales/zh-TW/messages.po +0 -492
  300. package/src/assets/app/main.css +0 -33
  301. package/src/assets/app/main.tsx +0 -44
  302. package/src/assets/app/views/authorize/accept/accept-form.tsx +0 -150
  303. package/src/assets/app/views/authorize/accept/accept-view.tsx +0 -70
  304. package/src/assets/app/views/authorize/authorize-view.tsx +0 -180
  305. package/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
  306. package/src/assets/app/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
  307. package/src/assets/app/views/authorize/reset-password/reset-password-view.tsx +0 -127
  308. package/src/assets/app/views/authorize/sign-in/sign-in-form.tsx +0 -244
  309. package/src/assets/app/views/authorize/sign-in/sign-in-picker.tsx +0 -116
  310. package/src/assets/app/views/authorize/sign-in/sign-in-view.tsx +0 -145
  311. package/src/assets/app/views/authorize/sign-up/sign-up-account-form.tsx +0 -140
  312. package/src/assets/app/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
  313. package/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx +0 -289
  314. package/src/assets/app/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
  315. package/src/assets/app/views/authorize/sign-up/sign-up-view.tsx +0 -158
  316. package/src/assets/app/views/authorize/welcome/welcome-view.tsx +0 -56
  317. package/src/assets/app/views/error/error-view.tsx +0 -31
  318. package/src/assets/asset.ts +0 -9
  319. package/src/assets/index.ts +0 -86
  320. package/tailwind.config.js +0 -31
  321. package/tsconfig.frontend.json +0 -11
  322. package/tsconfig.frontend.tsbuildinfo +0 -1
  323. package/tsconfig.tools.json +0 -8
  324. package/tsconfig.tools.tsbuildinfo +0 -1
  325. package/vite.config.mjs +0 -16
@@ -1,182 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <link rel="stylesheet" href="./main.css" />
7
- <title>OAuth Provider</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script>
12
- /*
13
- * This file's purpose is to provide a way to develop the UI without
14
- * running a full featured OAuth server. It mocks the server responses and
15
- * provides configuration data to the UI.
16
- *
17
- * This file is not part of the production build.
18
- *
19
- * Start the development server with the following command from the
20
- * oauth-provider root:
21
- *
22
- * ```sh
23
- * pnpm run start:ui
24
- * ```
25
- *
26
- * Then open the browser at http://localhost:5173/
27
- */
28
- </script>
29
- <style>
30
- /*
31
- * PDS branding configuration (colors), in R G B format.
32
- *
33
- * The variables here are meant to override the default values defined in
34
- * main.css. These values are typically generated by the backend and
35
- * injected into the HTML. The colors suffixed with "-c" denote the
36
- * "contrast" color of the corresponding color name. These are also
37
- * automatically generated by the backend from the branding colors.
38
- *
39
- * The default colors can be seen by commenting out a color name (and
40
- * corresponding "-c" contrast color) below:
41
- */
42
- :root {
43
- --color-brand: 10 122 255;
44
- --color-brand-c: 255 255 255;
45
- --color-error: 244 11 66;
46
- --color-error-c: 255 255 255;
47
- --color-warning: 251 86 7;
48
- --color-warning-c: 255 255 255;
49
- --color-success: 2 195 154;
50
- --color-success-c: 0 0 0;
51
- }
52
- </style>
53
- <script type="module">
54
- /*
55
- * PDS branding configuration
56
- */
57
-
58
- const name = 'Bluesky'
59
- const links = [
60
- {
61
- title: { en: 'Home' },
62
- href: 'https://bsky.social/',
63
- rel: 'canonical', // prevents the login page from being indexed by search engines
64
- },
65
- {
66
- title: { en: 'Terms of Service' },
67
- href: 'https://bsky.social/about/support/tos',
68
- rel: 'terms-of-service',
69
- },
70
- {
71
- title: { en: 'Privacy Policy' },
72
- href: 'https://bsky.social/about/support/privacy-policy',
73
- rel: 'privacy-policy',
74
- },
75
- {
76
- title: { en: 'Support' },
77
- href: 'https://blueskyweb.zendesk.com/hc/en-us',
78
- rel: 'help',
79
- },
80
- ]
81
- const logo = `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 320 286"><path fill="rgb(10,122,255)" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z" /></svg>')}`
82
-
83
- // Provide a value here to test the "sing-in only" flow
84
- const loginHint = undefined // 'alice.test'
85
-
86
- // Use empty array to disable the "sing-up" flow, use a single value to
87
- // disable the domain selector.
88
- const availableUserDomains = ['.bsky.social', '.bsky.team']
89
-
90
- // Use non empty string to enable hCaptcha during "sing-up" flow
91
- const hcaptchaSiteKey = undefined
92
-
93
- /*
94
- * Client branding configuration
95
- */
96
-
97
- // Use an "http://" URL to test the "an app on your device" flow
98
- const clientId = 'https://example.com/client.json'
99
- const clientName = 'My App'
100
- const clientPolicyUri = 'https://bsky.app'
101
- const clientTosUri = 'https://bsky.app'
102
- const clientLogoUri = 'https://bsky.app'
103
-
104
- // Mock data
105
-
106
- const requestUri = 'foo-bar'
107
-
108
- document.cookie = `csrf-${requestUri}=xyz; path=/`
109
-
110
- window.__customizationData = {
111
- availableUserDomains,
112
- inviteCodeRequired: false,
113
- hcaptchaSiteKey,
114
- name,
115
- links,
116
- logo,
117
- }
118
-
119
- window.__authorizeData = {
120
- clientId: clientId,
121
- clientMetadata: {
122
- client_id: clientId,
123
- client_name: clientName,
124
- policy_uri: clientPolicyUri,
125
- tos_uri: clientTosUri,
126
- logo_uri: clientLogoUri,
127
- },
128
- clientTrusted: false,
129
- requestUri,
130
- loginHint,
131
- newSessionsRequireConsent: true,
132
- sessions: [],
133
- scopeDetails: [
134
- { scope: 'atproto' },
135
- { scope: 'transition:generic' },
136
- { scope: 'transition:chat.bsky' },
137
- ],
138
- }
139
-
140
- const origFetch = window.fetch
141
-
142
- async function mockFetch(...args) {
143
- const [input, init] = args
144
-
145
- if (typeof input === 'string' && init.method === 'POST') {
146
- const url = new URL(input, window.location)
147
- switch (url.pathname) {
148
- case '/oauth/authorize/sign-up':
149
- case '/oauth/authorize/sign-in':
150
- return new Response(
151
- JSON.stringify({
152
- consentRequired: false,
153
- account: {
154
- sub: 'did:plc:123',
155
- name: 'Alice',
156
- email: 'alice@test.com',
157
- email_verified: false,
158
- preferred_username: 'alice.test',
159
- picture: 'https://cat.com/cat.jpg',
160
- },
161
- }),
162
- { status: 200 },
163
- )
164
- case '/oauth/authorize/verify-handle-availability':
165
- case '/oauth/authorize/reset-password-request':
166
- case '/oauth/authorize/reset-password-confirm':
167
- return new Response(null, { status: 204 })
168
- }
169
- }
170
-
171
- return origFetch.call(this, ...args)
172
- }
173
-
174
- Object.defineProperty(window, 'fetch', {
175
- value: mockFetch,
176
- writable: true,
177
- configurable: true,
178
- })
179
- </script>
180
- <script src="./main.tsx" type="module"></script>
181
- </body>
182
- </html>
@@ -1,267 +0,0 @@
1
- import { Account } from '../backend-types.ts'
2
- import {
3
- JsonClient,
4
- JsonErrorPayload,
5
- JsonErrorResponse,
6
- } from './json-client.ts'
7
-
8
- export type { Options } from './json-client.ts'
9
-
10
- export type AcceptData = {
11
- sub: string
12
- }
13
-
14
- export type SignInData = {
15
- locale: string
16
- username: string
17
- password: string
18
- emailOtp?: string
19
- remember?: boolean
20
- }
21
-
22
- export type SignUpData = {
23
- locale: string
24
- handle: string
25
- email: string
26
- password: string
27
- inviteCode?: string
28
- hcaptchaToken?: string
29
- }
30
-
31
- export type InitiatePasswordResetData = {
32
- locale: string
33
- email: string
34
- }
35
-
36
- export type ConfirmResetPasswordData = {
37
- token: string
38
- password: string
39
- }
40
-
41
- export type VerifyHandleAvailabilityData = {
42
- handle: string
43
- }
44
-
45
- export type SessionResponse = {
46
- account: Account
47
- consentRequired: boolean
48
- }
49
-
50
- export class Api extends JsonClient<{
51
- '/verify-handle-availability': {
52
- input: VerifyHandleAvailabilityData
53
- output: void
54
- }
55
- '/sign-up': {
56
- input: SignUpData
57
- output: SessionResponse
58
- }
59
- '/sign-in': {
60
- input: SignInData
61
- output: SessionResponse
62
- }
63
- '/reset-password-request': {
64
- input: InitiatePasswordResetData
65
- output: void
66
- }
67
- '/reset-password-confirm': {
68
- input: ConfirmResetPasswordData
69
- output: void
70
- }
71
- }> {
72
- constructor(csrfToken: string) {
73
- const baseUrl = new URL('/oauth/authorize', window.origin).toString()
74
- super(baseUrl, csrfToken)
75
- }
76
-
77
- public buildAcceptUrl(data: AcceptData): URL {
78
- const url = new URL(`${this.baseUrl}/accept`)
79
- url.searchParams.set('account_sub', data.sub)
80
- url.searchParams.set('csrf_token', this.csrfToken)
81
- return url
82
- }
83
-
84
- public buildRejectUrl(): URL {
85
- const url = new URL(`${this.baseUrl}/reject`)
86
- url.searchParams.set('csrf_token', this.csrfToken)
87
- return url
88
- }
89
-
90
- public static override parseError(
91
- json: unknown,
92
- ): undefined | JsonErrorResponse {
93
- // @NOTE Most specific errors first !
94
- if (SecondAuthenticationFactorRequiredError.is(json)) {
95
- return new SecondAuthenticationFactorRequiredError(json)
96
- }
97
- if (InvalidCredentialsError.is(json)) {
98
- return new InvalidCredentialsError(json)
99
- }
100
- if (HandleUnavailableError.is(json)) {
101
- return new HandleUnavailableError(json)
102
- }
103
- if (EmailTakenError.is(json)) {
104
- return new EmailTakenError(json)
105
- }
106
- if (RequestExpiredError.is(json)) {
107
- return new RequestExpiredError(json)
108
- }
109
- if (UnknownRequestUriError.is(json)) {
110
- return new UnknownRequestUriError(json)
111
- }
112
- if (InvalidRequestError.is(json)) {
113
- return new InvalidRequestError(json)
114
- }
115
- if (AccessDeniedError.is(json)) {
116
- return new AccessDeniedError(json)
117
- }
118
- return super.parseError(json)
119
- }
120
- }
121
-
122
- export type AccessDeniedPayload = JsonErrorPayload<'access_denied'>
123
- export class AccessDeniedError<
124
- P extends AccessDeniedPayload = AccessDeniedPayload,
125
- > extends JsonErrorResponse<P> {
126
- constructor(
127
- payload: P,
128
- message = payload.error_description || 'Access denied',
129
- ) {
130
- super(payload, message)
131
- }
132
-
133
- static is(json: unknown): json is AccessDeniedPayload {
134
- return super.is(json) && json.error === 'access_denied'
135
- }
136
- }
137
-
138
- export type InvalidRequestPayload = JsonErrorPayload<'invalid_request'>
139
- export class InvalidRequestError<
140
- P extends InvalidRequestPayload = InvalidRequestPayload,
141
- > extends JsonErrorResponse<P> {
142
- constructor(
143
- payload: P,
144
- message = payload.error_description || 'Invalid request',
145
- ) {
146
- super(payload, message)
147
- }
148
-
149
- static is(json: unknown): json is InvalidRequestPayload {
150
- return super.is(json) && json.error === 'invalid_request'
151
- }
152
- }
153
-
154
- export type RequestExpiredPayload = AccessDeniedPayload & {
155
- error_description: 'This request has expired'
156
- }
157
- export class RequestExpiredError<
158
- P extends RequestExpiredPayload = RequestExpiredPayload,
159
- > extends AccessDeniedError<P> {
160
- static is(json: unknown): json is RequestExpiredPayload {
161
- return (
162
- super.is(json) && json.error_description === 'This request has expired'
163
- )
164
- }
165
- }
166
-
167
- export type InvalidCredentialsPayload = InvalidRequestPayload & {
168
- error_description: 'Invalid identifier or password'
169
- }
170
- export class InvalidCredentialsError<
171
- P extends InvalidCredentialsPayload = InvalidCredentialsPayload,
172
- > extends InvalidRequestError<P> {
173
- static is(json: unknown): json is InvalidCredentialsPayload {
174
- return (
175
- super.is(json) &&
176
- json.error_description === 'Invalid identifier or password'
177
- )
178
- }
179
- }
180
-
181
- export type UnknownRequestPayload = InvalidRequestPayload & {
182
- error_description: 'Unknown request_uri'
183
- }
184
- export class UnknownRequestUriError<
185
- P extends UnknownRequestPayload = UnknownRequestPayload,
186
- > extends InvalidRequestError<P> {
187
- static is(json: unknown): json is UnknownRequestPayload {
188
- return super.is(json) && json.error_description === 'Unknown request_uri'
189
- }
190
- }
191
- export type EmailTakenPayload = InvalidRequestPayload & {
192
- error_description: 'Email already taken'
193
- }
194
- export class EmailTakenError<
195
- P extends EmailTakenPayload = EmailTakenPayload,
196
- > extends InvalidRequestError<P> {
197
- static is(json: unknown): json is EmailTakenPayload {
198
- return super.is(json) && json.error_description === 'Email already taken'
199
- }
200
- }
201
-
202
- export type HandleUnavailablePayload =
203
- JsonErrorPayload<'handle_unavailable'> & {
204
- reason: 'syntax' | 'domain' | 'slur' | 'taken'
205
- }
206
- export class HandleUnavailableError<
207
- P extends HandleUnavailablePayload = HandleUnavailablePayload,
208
- > extends JsonErrorResponse<P> {
209
- constructor(
210
- payload: P,
211
- message = payload.error_description || 'That handle cannot be used',
212
- ) {
213
- super(payload, message)
214
- }
215
-
216
- get reason() {
217
- return this.payload.reason
218
- }
219
-
220
- static is(json: unknown): json is HandleUnavailablePayload {
221
- return (
222
- super.is(json) &&
223
- json.error === 'handle_unavailable' &&
224
- 'reason' in json &&
225
- (json.reason === 'syntax' ||
226
- json.reason === 'domain' ||
227
- json.reason === 'slur' ||
228
- json.reason === 'taken')
229
- )
230
- }
231
- }
232
-
233
- export type SecondAuthenticationFactorRequiredPayload =
234
- JsonErrorPayload<'second_authentication_factor_required'> & {
235
- type: 'emailOtp'
236
- hint: string
237
- }
238
- export class SecondAuthenticationFactorRequiredError<
239
- P extends
240
- SecondAuthenticationFactorRequiredPayload = SecondAuthenticationFactorRequiredPayload,
241
- > extends JsonErrorResponse<P> {
242
- constructor(
243
- payload: P,
244
- message = payload.error_description ||
245
- `${payload.type} authentication factor required (hint: ${payload.hint})`,
246
- ) {
247
- super(payload, message)
248
- }
249
-
250
- get type() {
251
- return this.payload.type
252
- }
253
- get hint() {
254
- return this.payload.hint
255
- }
256
-
257
- static is(json: unknown): json is SecondAuthenticationFactorRequiredPayload {
258
- return (
259
- super.is(json) &&
260
- json.error === 'second_authentication_factor_required' &&
261
- 'type' in json &&
262
- json.type === 'emailOtp' &&
263
- 'hint' in json &&
264
- typeof json.hint === 'string'
265
- )
266
- }
267
- }
@@ -1,6 +0,0 @@
1
- type ClsxArg = string | false | undefined
2
-
3
- export function clsx(...args: [ClsxArg, ...ClsxArg[]]): string | undefined {
4
- const filtered = args.filter(Boolean) as string[]
5
- return filtered.length > 0 ? filtered.join(' ') : undefined
6
- }
@@ -1,94 +0,0 @@
1
- // Using a type import to avoid bundling this lib
2
- import type { Json } from '@atproto-labs/fetch'
3
-
4
- export { type Json }
5
-
6
- export type Options = {
7
- signal?: AbortSignal
8
- }
9
-
10
- export type EndpointDefinition = {
11
- input: Json
12
- output: Json | void
13
- }
14
-
15
- export class JsonClient<E extends { [Path: string]: EndpointDefinition }> {
16
- constructor(
17
- protected readonly baseUrl: string,
18
- protected readonly csrfToken: string,
19
- ) {}
20
-
21
- public async fetch<P extends string & keyof E>(
22
- path: P,
23
- payload: E[P]['input'],
24
- options?: Options,
25
- ): Promise<E[P]['output']> {
26
- const response = await fetch(`${this.baseUrl}${path}`, {
27
- method: 'POST',
28
- headers: {
29
- 'Content-Type': 'application/json',
30
- 'X-CSRF-Token': this.csrfToken,
31
- },
32
- mode: 'same-origin',
33
- body: JSON.stringify(payload),
34
- signal: options?.signal,
35
- })
36
-
37
- if (response.status === 204) {
38
- return undefined
39
- }
40
-
41
- return response.json().then((json: Json) => {
42
- if (response.ok) return json as E[P]['output']
43
- else throw this.parseError(response, json)
44
- })
45
- }
46
-
47
- protected parseError(response: Response, json: Json): Error {
48
- const Class = this.constructor as typeof JsonClient
49
- const error = Class.parseError(json)
50
- if (error) return error
51
-
52
- return new Error('Invalid JSON response', { cause: response })
53
- }
54
-
55
- public static parseError(json: unknown): undefined | JsonErrorResponse {
56
- if (JsonErrorResponse.is(json)) {
57
- return new JsonErrorResponse(json)
58
- }
59
- }
60
- }
61
-
62
- export type JsonErrorPayload<E extends string = string> = {
63
- error: E
64
- error_description?: string
65
- }
66
-
67
- export class JsonErrorResponse<
68
- P extends JsonErrorPayload = JsonErrorPayload,
69
- > extends Error {
70
- constructor(
71
- public readonly payload: P,
72
- message = payload.error_description,
73
- ) {
74
- super(message || `Error "${payload.error}"`)
75
- }
76
-
77
- get error(): string {
78
- return this.payload.error
79
- }
80
-
81
- get description(): string | undefined {
82
- return this.payload.error_description
83
- }
84
-
85
- static is(json: unknown): json is JsonErrorPayload {
86
- return (
87
- json != null &&
88
- typeof json === 'object' &&
89
- typeof json['error'] === 'string' &&
90
- (json['error_description'] === undefined ||
91
- typeof json['error_description'] === 'string')
92
- )
93
- }
94
- }
@@ -1,98 +0,0 @@
1
- export const MIN_PASSWORD_LENGTH = 8
2
-
3
- const EMOJI =
4
- /(\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/
5
- const UPPER = /[A-Z]/
6
- const LOWER = /[a-z]/
7
- const DEC = /[0-9]/
8
- const SPECIAL = /[^a-zA-Z0-9]/
9
-
10
- export enum PasswordStrength {
11
- weak = 1,
12
- moderate = 2,
13
- strong = 3,
14
- extra = 4,
15
- }
16
-
17
- export function getPasswordStrength(pwd: string): PasswordStrength {
18
- if (pwd.length < MIN_PASSWORD_LENGTH) {
19
- return PasswordStrength.weak
20
- }
21
-
22
- // Very long passwords
23
- if (pwd.length >= MIN_PASSWORD_LENGTH + 12) {
24
- return PasswordStrength.extra
25
- }
26
-
27
- // Long passwords
28
- if (pwd.length >= MIN_PASSWORD_LENGTH + 8) {
29
- if (matches(pwd, [SPECIAL])) {
30
- return PasswordStrength.extra
31
- }
32
- if (matches(pwd, [UPPER, LOWER, DEC], 2)) {
33
- return PasswordStrength.extra
34
- }
35
- return PasswordStrength.strong
36
- }
37
-
38
- // Emojis make passwords strong
39
- if (pwd.length >= MIN_PASSWORD_LENGTH) {
40
- if (matches(pwd, [EMOJI])) {
41
- return PasswordStrength.strong
42
- }
43
- }
44
-
45
- // Pretty long passwords
46
- if (pwd.length >= MIN_PASSWORD_LENGTH + 6) {
47
- if (matches(pwd, [SPECIAL])) {
48
- return PasswordStrength.strong
49
- }
50
- if (matches(pwd, [UPPER, LOWER, DEC], 2)) {
51
- return PasswordStrength.strong
52
- }
53
- // Only 1 type of alpha-num characters
54
- return PasswordStrength.moderate
55
- }
56
-
57
- // Longish password
58
- if (pwd.length >= MIN_PASSWORD_LENGTH + 4) {
59
- if (matches(pwd, [SPECIAL])) {
60
- return PasswordStrength.moderate
61
- }
62
- if (matches(pwd, [UPPER, LOWER, DEC], 2)) {
63
- return PasswordStrength.moderate
64
- }
65
-
66
- // Only 1 type of alpha-num characters
67
- return PasswordStrength.weak
68
- }
69
-
70
- // Short password (8-11 characters)
71
- if (pwd.length >= MIN_PASSWORD_LENGTH) {
72
- if (matches(pwd, [SPECIAL])) {
73
- return PasswordStrength.moderate
74
- }
75
- if (matches(pwd, [UPPER, LOWER, DEC])) {
76
- return PasswordStrength.moderate
77
- }
78
- }
79
-
80
- return PasswordStrength.weak
81
- }
82
-
83
- function matches(
84
- pwd: string,
85
- regexps: RegExp[],
86
- regexpsCountToMatch: number = regexps.length,
87
- ): boolean {
88
- if (regexpsCountToMatch < 1 || regexpsCountToMatch > regexps.length) {
89
- throw new TypeError('Invalid regexpsCountToMatch')
90
- }
91
- for (const regexp of regexps) {
92
- if (regexp.test(pwd)) {
93
- regexpsCountToMatch--
94
- if (regexpsCountToMatch === 0) return true
95
- }
96
- }
97
- return false
98
- }
@@ -1,17 +0,0 @@
1
- import { ForwardedRef } from 'react'
2
-
3
- export function updateRef<T>(ref: ForwardedRef<T>, value: T | null) {
4
- if (typeof ref === 'function') {
5
- ref(value)
6
- } else if (ref) {
7
- ref.current = value
8
- }
9
- }
10
-
11
- export function mergeRefs<T>(refs: readonly (ForwardedRef<T> | undefined)[]) {
12
- return (value: T | null) => {
13
- for (const ref of refs) {
14
- if (ref) updateRef(ref, value)
15
- }
16
- }
17
- }
@@ -1,13 +0,0 @@
1
- export function upsert<T>(
2
- arr: readonly T[],
3
- item: T,
4
- predicate: (value: T, index: number, obj: readonly T[]) => boolean,
5
- ): T[] {
6
- const idx = arr.findIndex(predicate)
7
- return idx === -1
8
- ? [...arr, item]
9
- : [...arr.slice(0, idx), item, ...arr.slice(idx + 1)]
10
- }
11
-
12
- export type Simplify<T> = { [K in keyof T]: T[K] } & NonNullable<unknown>
13
- export type Override<T, U> = Simplify<Omit<T, keyof U> & U>