@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,244 +0,0 @@
1
- import { Trans, useLingui } from '@lingui/react/macro'
2
- import { useCallback, useRef, useState } from 'react'
3
- import { Button } from '../../../components/forms/button.tsx'
4
- import { Fieldset } from '../../../components/forms/fieldset.tsx'
5
- import {
6
- FormCardAsync,
7
- FormCardAsyncProps,
8
- } from '../../../components/forms/form-card-async.tsx'
9
- import { InputCheckbox } from '../../../components/forms/input-checkbox.tsx'
10
- import { InputPassword } from '../../../components/forms/input-password.tsx'
11
- import { InputText } from '../../../components/forms/input-text.tsx'
12
- import { InputToken } from '../../../components/forms/input-token.tsx'
13
- import { Admonition } from '../../../components/utils/admonition.tsx'
14
- import { AtSymbolIcon } from '../../../components/utils/icons.tsx'
15
- import { AsyncActionController } from '../../../hooks/use-async-action.ts'
16
- import {
17
- InvalidCredentialsError,
18
- SecondAuthenticationFactorRequiredError,
19
- } from '../../../lib/api.ts'
20
- import { mergeRefs } from '../../../lib/ref.ts'
21
- import { Override } from '../../../lib/util.ts'
22
-
23
- export type SignInFormOutput = {
24
- username: string
25
- password: string
26
- remember?: boolean
27
- }
28
-
29
- export type SignInFormProps = Override<
30
- Omit<FormCardAsyncProps, 'append' | 'onCancel'>,
31
- {
32
- usernameDefault?: string
33
- usernameReadonly?: boolean
34
- rememberDefault?: boolean
35
-
36
- onBack?: () => void
37
- onForgotPassword?: (emailHint?: string) => void
38
- onSubmit: (
39
- credentials: SignInFormOutput,
40
- signal: AbortSignal,
41
- ) => void | PromiseLike<void>
42
- }
43
- >
44
-
45
- export function SignInForm({
46
- usernameDefault = '',
47
- usernameReadonly = false,
48
- rememberDefault = false,
49
-
50
- onSubmit,
51
- onBack,
52
- onForgotPassword,
53
-
54
- // FormCardAsync
55
- ref,
56
- invalid,
57
- children,
58
- ...props
59
- }: SignInFormProps) {
60
- const { t } = useLingui()
61
-
62
- const [username, setUsername] = useState<string>(usernameDefault)
63
- const [password, setPassword] = useState<string>('')
64
- const [remember, setRemember] = useState<boolean>(rememberDefault)
65
- const [otp, setOtp] = useState<string | null>(null)
66
-
67
- const [secondFactor, setSecondFactor] =
68
- useState<null | SecondAuthenticationFactorRequiredError>(null)
69
-
70
- const [loading, setLoading] = useState(false)
71
-
72
- const formRef = useRef<AsyncActionController>(null)
73
-
74
- const clearSecondFactor = useCallback(() => {
75
- setOtp(null)
76
- setSecondFactor(null)
77
- }, [setOtp, setSecondFactor])
78
-
79
- const resetState = useCallback(() => {
80
- clearSecondFactor()
81
- formRef.current?.reset()
82
- }, [clearSecondFactor, formRef])
83
-
84
- const doSubmit = useCallback(
85
- async (signal: AbortSignal) => {
86
- try {
87
- await onSubmit(
88
- {
89
- username,
90
- password,
91
- remember,
92
- ...(secondFactor ? { [secondFactor.type]: otp } : {}),
93
- },
94
- signal,
95
- )
96
- } catch (err) {
97
- if (signal.aborted) {
98
- // If the action was aborted, ignore the error
99
- return
100
- }
101
-
102
- if (err instanceof SecondAuthenticationFactorRequiredError) {
103
- setSecondFactor(err)
104
-
105
- // Do not re-throw 2FA required error to prevent the form from from
106
- // displaying it. Instead, we handle the error by showing the second
107
- // factor form.
108
- return
109
- }
110
-
111
- if (err instanceof InvalidCredentialsError) {
112
- // If the username/password are not valid, clear the second factor
113
- // as valid credentials are a pre-requisite for 2FA.
114
- clearSecondFactor()
115
- }
116
-
117
- // Any thrown err will be displayed through the form's errorRender
118
- throw err
119
- }
120
- },
121
- [username, password, remember, secondFactor, otp, onSubmit],
122
- )
123
-
124
- return (
125
- <FormCardAsync
126
- {...props}
127
- ref={mergeRefs([ref, formRef])}
128
- onLoading={setLoading}
129
- onCancel={onBack}
130
- cancelLabel={t`Back`}
131
- append={children}
132
- invalid={
133
- invalid || !username || !password || (secondFactor != null && !otp)
134
- }
135
- submitLabel={secondFactor ? t`Confirm` : t`Sign in`}
136
- onSubmit={doSubmit}
137
- >
138
- <Fieldset disabled={loading} label={<Trans>Account</Trans>}>
139
- <InputText
140
- icon={<AtSymbolIcon className="w-5" />}
141
- name="username"
142
- type="text"
143
- placeholder={t`Username or email address`}
144
- aria-label={t`Username or email address`}
145
- autoCapitalize="none"
146
- autoCorrect="off"
147
- autoComplete="username"
148
- spellCheck="false"
149
- dir="auto"
150
- enterKeyHint="next"
151
- required
152
- readOnly={usernameReadonly}
153
- disabled={usernameReadonly}
154
- title={t`Valid email address or username`}
155
- autoFocus
156
- value={username}
157
- onChange={(event) => {
158
- resetState()
159
- setUsername(event.target.value)
160
- }}
161
- />
162
- </Fieldset>
163
-
164
- <InputPassword
165
- name="password"
166
- onChange={(event) => {
167
- resetState()
168
- setPassword(event.target.value)
169
- }}
170
- append={
171
- onForgotPassword && (
172
- <Button
173
- className="text-sm"
174
- type="button"
175
- onClick={() => {
176
- onForgotPassword(username?.includes('@') ? username : undefined)
177
- }}
178
- aria-label={t`Reset your password`}
179
- >
180
- <Trans>Forgot?</Trans>
181
- </Button>
182
- )
183
- }
184
- enterKeyHint={secondFactor ? 'next' : 'done'}
185
- disabled={loading}
186
- required
187
- />
188
-
189
- <Admonition role="status">
190
- <p className="font-bold text-md text-brand pb-1">
191
- <Trans>Warning</Trans>
192
- </p>
193
- <p className="text-sm">
194
- <Trans>
195
- Please verify the domain name of the website before entering your
196
- password. Never enter your password on a domain you do not trust.
197
- </Trans>
198
- </p>
199
- </Admonition>
200
-
201
- <Fieldset
202
- key="remember"
203
- disabled={loading}
204
- label={<Trans>Session</Trans>}
205
- >
206
- <InputCheckbox
207
- name="remember"
208
- aria-label={t`Remember this account on this device`}
209
- enterKeyHint={secondFactor ? 'next' : 'done'}
210
- checked={remember}
211
- onChange={(event) => setRemember(event.target.checked)}
212
- >
213
- <Trans>Remember this account on this device</Trans>
214
- </InputCheckbox>
215
- </Fieldset>
216
-
217
- {secondFactor && (
218
- <Fieldset
219
- key="2fa"
220
- disabled={loading}
221
- label={<Trans>2FA Confirmation</Trans>}
222
- >
223
- <div>
224
- <InputToken
225
- aria-label={t`Confirmation code`}
226
- enterKeyHint="done"
227
- required
228
- autoFocus={true}
229
- value={otp ?? ''}
230
- onToken={setOtp}
231
- />
232
-
233
- <p className="text-slate-600 dark:text-slate-400 text-sm">
234
- <Trans>
235
- Check your {secondFactor.hint} email for a login code and enter
236
- it here.
237
- </Trans>
238
- </p>
239
- </div>
240
- </Fieldset>
241
- )}
242
- </FormCardAsync>
243
- )
244
- }
@@ -1,116 +0,0 @@
1
- import { Trans, useLingui } from '@lingui/react/macro'
2
- import { Account } from '../../../backend-types.ts'
3
- import { Button } from '../../../components/forms/button.tsx'
4
- import {
5
- FormCard,
6
- FormCardProps,
7
- } from '../../../components/forms/form-card.tsx'
8
- import { InputContainer } from '../../../components/forms/input-container.tsx'
9
- import { AccountImage } from '../../../components/utils/account-image.tsx'
10
- import {
11
- AtSymbolIcon,
12
- CaretRightIcon,
13
- } from '../../../components/utils/icons.tsx'
14
- import { Override } from '../../../lib/util.ts'
15
-
16
- export type SignInPickerProps = Override<
17
- Omit<FormCardProps, 'cancel' | 'actions' | 'append'>,
18
- {
19
- accounts: readonly Account[]
20
-
21
- onAccount: (account: Account) => void
22
- onOther?: () => void
23
- onBack?: () => void
24
- }
25
- >
26
-
27
- export function SignInPicker({
28
- accounts,
29
-
30
- onAccount,
31
- onOther = undefined,
32
- onBack,
33
-
34
- // FormCard
35
- children,
36
- ...props
37
- }: SignInPickerProps) {
38
- const { t } = useLingui()
39
- return (
40
- <FormCard
41
- {...props}
42
- append={children}
43
- actions={null}
44
- cancel={
45
- onBack && (
46
- <Button onClick={onBack}>
47
- <Trans>Back</Trans>
48
- </Button>
49
- )
50
- }
51
- >
52
- <p className="text-slate-600 dark:text-slate-400 text-sm font-medium">
53
- <Trans>Sign in as...</Trans>
54
- </p>
55
-
56
- {accounts.map((account) => {
57
- const [name, identifier] = [
58
- account.name,
59
- account.preferred_username,
60
- account.email,
61
- account.sub,
62
- ].filter(Boolean) as [string, string?]
63
-
64
- return (
65
- <InputContainer
66
- tabIndex={0}
67
- key={account.sub}
68
- onKeyDown={(event) => {
69
- if (event.key === 'Enter' || event.key === ' ') {
70
- onAccount(account)
71
- }
72
- }}
73
- onClick={() => onAccount(account)}
74
- role="button"
75
- aria-label={t`Sign in as ${account.name}`}
76
- icon={<AccountImage src={account.picture} alt={name} />}
77
- append={<CaretRightIcon aria-hidden className="h-4" />}
78
- >
79
- <span className="flex flex-wrap items-center">
80
- <span className="font-medium truncate mr-2" arial-label={t`Name`}>
81
- {name}
82
- </span>
83
- {identifier && (
84
- <span
85
- className="text-sm text-neutral-500 dark:text-neutral-400 truncate"
86
- arial-label={t`Identifier`}
87
- >
88
- {identifier}
89
- </span>
90
- )}
91
- </span>
92
- </InputContainer>
93
- )
94
- })}
95
-
96
- {onOther && (
97
- <InputContainer
98
- key="other"
99
- tabIndex={0}
100
- onKeyDown={(event) => {
101
- if (event.key === 'Enter' || event.key === ' ') onOther()
102
- }}
103
- onClick={onOther}
104
- aria-label={t`Login to account that is not listed`}
105
- role="button"
106
- append={<CaretRightIcon aria-hidden className="h-4" />}
107
- icon={<AtSymbolIcon aria-hidden className="h-4" />}
108
- >
109
- <span className="truncate text-slate-700 dark:text-slate-400">
110
- <Trans>Another account</Trans>
111
- </span>
112
- </InputContainer>
113
- )}
114
- </FormCard>
115
- )
116
- }
@@ -1,145 +0,0 @@
1
- import { Trans, useLingui } from '@lingui/react/macro'
2
- import { useCallback, useEffect, useMemo, useState } from 'react'
3
- import { Session } from '../../../backend-types.ts'
4
- import {
5
- LayoutTitlePage,
6
- LayoutTitlePageProps,
7
- } from '../../../components/layouts/layout-title-page.tsx'
8
- import { Override } from '../../../lib/util.ts'
9
- import { SignInForm, SignInFormOutput } from './sign-in-form.tsx'
10
- import { SignInPicker } from './sign-in-picker.tsx'
11
-
12
- export type SignInViewProps = Override<
13
- LayoutTitlePageProps,
14
- {
15
- sessions: readonly Session[]
16
- selectSub: (sub: string | null) => void
17
- loginHint?: string
18
-
19
- onSignIn: (
20
- credentials: SignInFormOutput,
21
- signal: AbortSignal,
22
- ) => void | PromiseLike<void>
23
- onForgotPassword?: (emailHint?: string) => void
24
- onBack?: () => void
25
- }
26
- >
27
-
28
- export function SignInView({
29
- loginHint,
30
- sessions,
31
- selectSub,
32
-
33
- onSignIn,
34
- onForgotPassword,
35
- onBack,
36
-
37
- // LayoutTitlePage
38
- title,
39
- subtitle,
40
- ...props
41
- }: SignInViewProps) {
42
- const { t } = useLingui()
43
- const session = useMemo(() => sessions.find((s) => s.selected), [sessions])
44
- const clearSession = useCallback(() => selectSub(null), [selectSub])
45
- const accounts = useMemo(() => sessions.map((s) => s.account), [sessions])
46
- const [showSignInForm, setShowSignInForm] = useState(sessions.length === 0)
47
-
48
- title ??= t`Sign in`
49
-
50
- useEffect(() => {
51
- // Make sure the "back" action shows the account picker instead of the
52
- // sign-in form (since the account was added to the list of current
53
- // sessions).
54
- if (session) setShowSignInForm(false)
55
- }, [session])
56
-
57
- if (session) {
58
- // All set (parent view will handle the redirect)
59
- if (!session.loginRequired) return null
60
-
61
- return (
62
- <LayoutTitlePage
63
- {...props}
64
- title={title}
65
- subtitle={subtitle ?? <Trans>Confirm your password to continue</Trans>}
66
- >
67
- <SignInForm
68
- onSubmit={onSignIn}
69
- onForgotPassword={onForgotPassword}
70
- onBack={clearSession}
71
- usernameDefault={
72
- session.account.preferred_username || session.account.sub
73
- }
74
- usernameReadonly={true}
75
- rememberDefault={true}
76
- />
77
- </LayoutTitlePage>
78
- )
79
- }
80
-
81
- if (loginHint) {
82
- return (
83
- <LayoutTitlePage
84
- {...props}
85
- title={title}
86
- subtitle={subtitle ?? <Trans>Enter your password</Trans>}
87
- >
88
- <SignInForm
89
- onSubmit={onSignIn}
90
- onForgotPassword={onForgotPassword}
91
- onBack={onBack}
92
- usernameDefault={loginHint}
93
- usernameReadonly={true}
94
- />
95
- </LayoutTitlePage>
96
- )
97
- }
98
-
99
- if (sessions.length === 0) {
100
- return (
101
- <LayoutTitlePage
102
- {...props}
103
- title={title}
104
- subtitle={subtitle ?? <Trans>Enter your username and password</Trans>}
105
- >
106
- <SignInForm
107
- onSubmit={onSignIn}
108
- onForgotPassword={onForgotPassword}
109
- onBack={onBack}
110
- />
111
- </LayoutTitlePage>
112
- )
113
- }
114
-
115
- if (showSignInForm) {
116
- return (
117
- <LayoutTitlePage
118
- {...props}
119
- title={title}
120
- subtitle={subtitle ?? <Trans>Enter your username and password</Trans>}
121
- >
122
- <SignInForm
123
- onSubmit={onSignIn}
124
- onForgotPassword={onForgotPassword}
125
- onBack={() => setShowSignInForm(false)}
126
- />
127
- </LayoutTitlePage>
128
- )
129
- }
130
-
131
- return (
132
- <LayoutTitlePage
133
- {...props}
134
- title={title}
135
- subtitle={subtitle ?? <Trans>Select from an existing account</Trans>}
136
- >
137
- <SignInPicker
138
- accounts={accounts}
139
- onAccount={(a) => selectSub(a.sub)}
140
- onOther={() => setShowSignInForm(true)}
141
- onBack={onBack}
142
- />
143
- </LayoutTitlePage>
144
- )
145
- }
@@ -1,140 +0,0 @@
1
- import { Trans, useLingui } from '@lingui/react/macro'
2
- import { ReactNode, useEffect, useMemo, useRef, useState } from 'react'
3
- import { Fieldset } from '../../../components/forms/fieldset.tsx'
4
- import {
5
- AsyncActionController,
6
- FormCardAsync,
7
- FormCardAsyncProps,
8
- } from '../../../components/forms/form-card-async.tsx'
9
- import { InputEmailAddress } from '../../../components/forms/input-email-address.tsx'
10
- import { InputNewPassword } from '../../../components/forms/input-new-password.tsx'
11
- import { InputToken } from '../../../components/forms/input-token.tsx'
12
- import { mergeRefs } from '../../../lib/ref.ts'
13
- import { Override } from '../../../lib/util.ts'
14
-
15
- export type SignUpAccountFormOutput = {
16
- email: string
17
- password: string
18
- inviteCode?: string
19
- }
20
-
21
- export type SignUpAccountFormProps = Override<
22
- Omit<
23
- FormCardAsyncProps,
24
- 'append' | 'onCancel' | 'onSubmit' | 'submitLabel' | 'cancelLabel'
25
- >,
26
- {
27
- inviteCodeRequired?: boolean
28
-
29
- credentials?: SignUpAccountFormOutput
30
- onCredentials?: (credentials?: SignUpAccountFormOutput) => void
31
-
32
- onNext: (signal: AbortSignal) => void | PromiseLike<void>
33
- nextLabel?: ReactNode
34
-
35
- onPrev?: () => void
36
- prevLabel?: ReactNode
37
- }
38
- >
39
-
40
- export function SignUpAccountForm({
41
- inviteCodeRequired = true,
42
-
43
- credentials: creds,
44
- onCredentials,
45
-
46
- onNext,
47
- nextLabel,
48
-
49
- onPrev,
50
- prevLabel,
51
-
52
- // FormCardAsyncProps
53
- children,
54
- ref,
55
- invalid,
56
- ...props
57
- }: SignUpAccountFormProps) {
58
- const { t } = useLingui()
59
-
60
- const [email, setEmail] = useState(creds?.email)
61
- const [password, setPassword] = useState(creds?.password)
62
- const [inviteCode, setInviteCode] = useState(creds?.inviteCode)
63
-
64
- const formRef = useRef<AsyncActionController>(null)
65
- const resetForm = () => formRef.current?.reset()
66
-
67
- const credentials = useMemo(
68
- () =>
69
- email && password && (!inviteCodeRequired || inviteCode)
70
- ? {
71
- email,
72
- password,
73
- inviteCode: inviteCodeRequired ? inviteCode : undefined,
74
- }
75
- : undefined,
76
- [email, password, inviteCode, inviteCodeRequired],
77
- )
78
-
79
- useEffect(() => {
80
- onCredentials?.(credentials)
81
- }, [credentials, onCredentials])
82
-
83
- return (
84
- <FormCardAsync
85
- {...props}
86
- ref={mergeRefs([ref, formRef])}
87
- invalid={invalid || !credentials}
88
- onCancel={onPrev}
89
- cancelLabel={prevLabel}
90
- onSubmit={onNext}
91
- submitLabel={nextLabel}
92
- append={children}
93
- >
94
- {inviteCodeRequired && (
95
- <Fieldset label={<Trans>Invite code</Trans>}>
96
- <InputToken
97
- autoFocus
98
- name="inviteCode"
99
- aria-label={t`Invite code`}
100
- title={t`Invite code`}
101
- required
102
- value={inviteCode}
103
- onChange={(event) => {
104
- setInviteCode(event.target.value)
105
- resetForm()
106
- }}
107
- enterKeyHint="next"
108
- />
109
- </Fieldset>
110
- )}
111
-
112
- <Fieldset label={<Trans>Email</Trans>}>
113
- <InputEmailAddress
114
- autoFocus={!inviteCodeRequired}
115
- name="email"
116
- enterKeyHint="next"
117
- required
118
- defaultValue={email}
119
- onEmail={(email) => {
120
- setEmail(email)
121
- resetForm()
122
- }}
123
- />
124
- </Fieldset>
125
-
126
- <Fieldset label={<Trans>Password</Trans>}>
127
- <InputNewPassword
128
- name="password"
129
- enterKeyHint="next"
130
- required
131
- password={password}
132
- onPassword={(value) => {
133
- setPassword(value)
134
- resetForm()
135
- }}
136
- />
137
- </Fieldset>
138
- </FormCardAsync>
139
- )
140
- }
@@ -1,51 +0,0 @@
1
- import { Trans } from '@lingui/react/macro'
2
- import { JSX } from 'react'
3
- import { LinkDefinition } from '../../../backend-types.ts'
4
- import { LinkAnchor } from '../../../components/utils/link-anchor.tsx'
5
- import { clsx } from '../../../lib/clsx.ts'
6
- import { Override } from '../../../lib/util.ts'
7
-
8
- export type SignUpDisclaimerProps = Override<
9
- Omit<JSX.IntrinsicElements['p'], 'children'>,
10
- {
11
- links?: readonly LinkDefinition[]
12
- }
13
- >
14
-
15
- export function SignUpDisclaimer({
16
- links,
17
-
18
- // p
19
- className,
20
- ...attrs
21
- }: SignUpDisclaimerProps) {
22
- const tosLink = links?.find((l) => l.rel === 'terms-of-service')
23
- const ppLink = links?.find((l) => l.rel === 'privacy-policy')
24
-
25
- return (
26
- <p
27
- className={clsx('text-sm text-slate-500 dark:text-slate-400', className)}
28
- {...attrs}
29
- >
30
- <Trans>
31
- By creating an account you agree to the{' '}
32
- {tosLink ? (
33
- <LinkAnchor className="text-brand underline" link={tosLink}>
34
- <Trans>Terms of Service</Trans>
35
- </LinkAnchor>
36
- ) : (
37
- <Trans>Terms of Service</Trans>
38
- )}
39
- {' and the '}
40
- {ppLink ? (
41
- <LinkAnchor className="text-brand underline" link={ppLink}>
42
- <Trans>Privacy Policy</Trans>
43
- </LinkAnchor>
44
- ) : (
45
- <Trans>Privacy Policy</Trans>
46
- )}{' '}
47
- of this service.
48
- </Trans>
49
- </p>
50
- )
51
- }