@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,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,289 +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: { available: true }
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: { success: true }
66
- }
67
- '/reset-password-confirm': {
68
- input: ConfirmResetPasswordData
69
- output: { success: true }
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 (InvalidInviteCodeError.is(json)) {
101
- return new InvalidInviteCodeError(json)
102
- }
103
- if (HandleUnavailableError.is(json)) {
104
- return new HandleUnavailableError(json)
105
- }
106
- if (EmailTakenError.is(json)) {
107
- return new EmailTakenError(json)
108
- }
109
- if (RequestExpiredError.is(json)) {
110
- return new RequestExpiredError(json)
111
- }
112
- if (UnknownRequestUriError.is(json)) {
113
- return new UnknownRequestUriError(json)
114
- }
115
- if (InvalidRequestError.is(json)) {
116
- return new InvalidRequestError(json)
117
- }
118
- if (AccessDeniedError.is(json)) {
119
- return new AccessDeniedError(json)
120
- }
121
- return super.parseError(json)
122
- }
123
- }
124
-
125
- export type AccessDeniedPayload = JsonErrorPayload<'access_denied'>
126
- export class AccessDeniedError<
127
- P extends AccessDeniedPayload = AccessDeniedPayload,
128
- > extends JsonErrorResponse<P> {
129
- constructor(
130
- payload: P,
131
- message = payload.error_description || 'Access denied',
132
- ) {
133
- super(payload, message)
134
- }
135
-
136
- static is(json: unknown): json is AccessDeniedPayload {
137
- return super.is(json) && json.error === 'access_denied'
138
- }
139
- }
140
-
141
- export type InvalidRequestPayload = JsonErrorPayload<'invalid_request'>
142
- export class InvalidRequestError<
143
- P extends InvalidRequestPayload = InvalidRequestPayload,
144
- > extends JsonErrorResponse<P> {
145
- constructor(
146
- payload: P,
147
- message = payload.error_description || 'Invalid request',
148
- ) {
149
- super(payload, message)
150
- }
151
-
152
- static is(json: unknown): json is InvalidRequestPayload {
153
- return super.is(json) && json.error === 'invalid_request'
154
- }
155
- }
156
-
157
- export type InvalidInviteCodePayload = InvalidRequestPayload & {
158
- error_description: `This invite code is invalid.${string}`
159
- }
160
- export class InvalidInviteCodeError<
161
- P extends InvalidInviteCodePayload = InvalidInviteCodePayload,
162
- > extends InvalidRequestError<P> {
163
- constructor(payload: P) {
164
- super(payload)
165
- }
166
-
167
- static is(json: unknown): json is InvalidInviteCodePayload {
168
- return (
169
- super.is(json) &&
170
- json.error_description != null &&
171
- json.error_description.startsWith('This invite code is invalid.')
172
- )
173
- }
174
- }
175
-
176
- export type RequestExpiredPayload = AccessDeniedPayload & {
177
- error_description: 'This request has expired'
178
- }
179
- export class RequestExpiredError<
180
- P extends RequestExpiredPayload = RequestExpiredPayload,
181
- > extends AccessDeniedError<P> {
182
- static is(json: unknown): json is RequestExpiredPayload {
183
- return (
184
- super.is(json) && json.error_description === 'This request has expired'
185
- )
186
- }
187
- }
188
-
189
- export type InvalidCredentialsPayload = InvalidRequestPayload & {
190
- error_description: 'Invalid identifier or password'
191
- }
192
- export class InvalidCredentialsError<
193
- P extends InvalidCredentialsPayload = InvalidCredentialsPayload,
194
- > extends InvalidRequestError<P> {
195
- static is(json: unknown): json is InvalidCredentialsPayload {
196
- return (
197
- super.is(json) &&
198
- json.error_description === 'Invalid identifier or password'
199
- )
200
- }
201
- }
202
-
203
- export type UnknownRequestPayload = InvalidRequestPayload & {
204
- error_description: 'Unknown request_uri'
205
- }
206
- export class UnknownRequestUriError<
207
- P extends UnknownRequestPayload = UnknownRequestPayload,
208
- > extends InvalidRequestError<P> {
209
- static is(json: unknown): json is UnknownRequestPayload {
210
- return super.is(json) && json.error_description === 'Unknown request_uri'
211
- }
212
- }
213
- export type EmailTakenPayload = InvalidRequestPayload & {
214
- error_description: 'Email already taken'
215
- }
216
- export class EmailTakenError<
217
- P extends EmailTakenPayload = EmailTakenPayload,
218
- > extends InvalidRequestError<P> {
219
- static is(json: unknown): json is EmailTakenPayload {
220
- return super.is(json) && json.error_description === 'Email already taken'
221
- }
222
- }
223
-
224
- export type HandleUnavailablePayload =
225
- JsonErrorPayload<'handle_unavailable'> & {
226
- reason: 'syntax' | 'domain' | 'slur' | 'taken'
227
- }
228
- export class HandleUnavailableError<
229
- P extends HandleUnavailablePayload = HandleUnavailablePayload,
230
- > extends JsonErrorResponse<P> {
231
- constructor(
232
- payload: P,
233
- message = payload.error_description || 'That handle cannot be used',
234
- ) {
235
- super(payload, message)
236
- }
237
-
238
- get reason() {
239
- return this.payload.reason
240
- }
241
-
242
- static is(json: unknown): json is HandleUnavailablePayload {
243
- return (
244
- super.is(json) &&
245
- json.error === 'handle_unavailable' &&
246
- 'reason' in json &&
247
- (json.reason === 'syntax' ||
248
- json.reason === 'domain' ||
249
- json.reason === 'slur' ||
250
- json.reason === 'taken')
251
- )
252
- }
253
- }
254
-
255
- export type SecondAuthenticationFactorRequiredPayload =
256
- JsonErrorPayload<'second_authentication_factor_required'> & {
257
- type: 'emailOtp'
258
- hint: string
259
- }
260
- export class SecondAuthenticationFactorRequiredError<
261
- P extends
262
- SecondAuthenticationFactorRequiredPayload = SecondAuthenticationFactorRequiredPayload,
263
- > extends JsonErrorResponse<P> {
264
- constructor(
265
- payload: P,
266
- message = payload.error_description ||
267
- `${payload.type} authentication factor required (hint: ${payload.hint})`,
268
- ) {
269
- super(payload, message)
270
- }
271
-
272
- get type() {
273
- return this.payload.type
274
- }
275
- get hint() {
276
- return this.payload.hint
277
- }
278
-
279
- static is(json: unknown): json is SecondAuthenticationFactorRequiredPayload {
280
- return (
281
- super.is(json) &&
282
- json.error === 'second_authentication_factor_required' &&
283
- 'type' in json &&
284
- json.type === 'emailOtp' &&
285
- 'hint' in json &&
286
- typeof json.hint === 'string'
287
- )
288
- }
289
- }
@@ -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>