@tinyrack/tinyauth-server 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 (362) hide show
  1. package/dist/entities/oauth-client.entity.d.ts +27 -0
  2. package/dist/entities/oauth-client.entity.d.ts.map +1 -1
  3. package/dist/entities/oauth-code.entity.d.ts +27 -0
  4. package/dist/entities/oauth-code.entity.d.ts.map +1 -1
  5. package/dist/entities/oauth-device-code.entity.d.ts +27 -0
  6. package/dist/entities/oauth-device-code.entity.d.ts.map +1 -1
  7. package/dist/entities/oauth-device-code.entity.js +12 -0
  8. package/dist/entities/oauth-device-code.entity.js.map +1 -1
  9. package/dist/entities/revoked-token.entity.d.ts +27 -0
  10. package/dist/entities/revoked-token.entity.d.ts.map +1 -1
  11. package/dist/entities/user-consent.entity.d.ts +27 -0
  12. package/dist/entities/user-consent.entity.d.ts.map +1 -1
  13. package/dist/entrypoints/app.d.ts +325 -16
  14. package/dist/entrypoints/app.d.ts.map +1 -1
  15. package/dist/entrypoints/app.js +33 -7
  16. package/dist/entrypoints/app.js.map +1 -1
  17. package/dist/entrypoints/database/postgres/compiled-functions.d.ts +16 -7
  18. package/dist/entrypoints/database/postgres/compiled-functions.d.ts.map +1 -1
  19. package/dist/entrypoints/database/postgres/compiled-functions.js +183 -39
  20. package/dist/entrypoints/database/postgres/compiled-functions.js.map +1 -1
  21. package/dist/entrypoints/database/sqlite/compiled-functions.d.ts +16 -7
  22. package/dist/entrypoints/database/sqlite/compiled-functions.d.ts.map +1 -1
  23. package/dist/entrypoints/database/sqlite/compiled-functions.js +183 -39
  24. package/dist/entrypoints/database/sqlite/compiled-functions.js.map +1 -1
  25. package/dist/lib/config/admin.d.ts +9 -0
  26. package/dist/lib/config/admin.d.ts.map +1 -0
  27. package/dist/lib/config/admin.js +13 -0
  28. package/dist/lib/config/admin.js.map +1 -0
  29. package/dist/lib/config/auth.d.ts +85 -0
  30. package/dist/lib/config/auth.d.ts.map +1 -1
  31. package/dist/lib/config/auth.js +61 -0
  32. package/dist/lib/config/auth.js.map +1 -1
  33. package/dist/lib/config/client.d.ts +20 -0
  34. package/dist/lib/config/client.d.ts.map +1 -1
  35. package/dist/lib/config/client.js +14 -0
  36. package/dist/lib/config/client.js.map +1 -1
  37. package/dist/lib/config/index.d.ts +2 -0
  38. package/dist/lib/config/index.d.ts.map +1 -1
  39. package/dist/lib/config/index.js +1 -0
  40. package/dist/lib/config/index.js.map +1 -1
  41. package/dist/lib/config/resolved.d.ts +40 -0
  42. package/dist/lib/config/resolved.d.ts.map +1 -1
  43. package/dist/lib/config/resolved.js +2 -0
  44. package/dist/lib/config/resolved.js.map +1 -1
  45. package/dist/lib/config/server.d.ts.map +1 -1
  46. package/dist/lib/config/server.js +12 -0
  47. package/dist/lib/config/server.js.map +1 -1
  48. package/dist/lib/swagger-tags.d.ts +1 -0
  49. package/dist/lib/swagger-tags.d.ts.map +1 -1
  50. package/dist/lib/swagger-tags.js +1 -0
  51. package/dist/lib/swagger-tags.js.map +1 -1
  52. package/dist/middleware/auth.d.ts +3 -0
  53. package/dist/middleware/auth.d.ts.map +1 -1
  54. package/dist/middleware/auth.js +26 -0
  55. package/dist/middleware/auth.js.map +1 -1
  56. package/dist/middleware/session.d.ts +33 -1
  57. package/dist/middleware/session.d.ts.map +1 -1
  58. package/dist/middleware/session.js +84 -3
  59. package/dist/middleware/session.js.map +1 -1
  60. package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.d.ts +6 -0
  61. package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.d.ts.map +1 -0
  62. package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.js +11 -0
  63. package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.js.map +1 -0
  64. package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.d.ts +6 -0
  65. package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.d.ts.map +1 -0
  66. package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.js +14 -0
  67. package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.js.map +1 -0
  68. package/dist/migrations/postgres/index.d.ts.map +1 -1
  69. package/dist/migrations/postgres/index.js +4 -0
  70. package/dist/migrations/postgres/index.js.map +1 -1
  71. package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.d.ts +6 -0
  72. package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.d.ts.map +1 -0
  73. package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.js +10 -0
  74. package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.js.map +1 -0
  75. package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.d.ts +6 -0
  76. package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.d.ts.map +1 -0
  77. package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.js +12 -0
  78. package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.js.map +1 -0
  79. package/dist/migrations/sqlite/index.d.ts.map +1 -1
  80. package/dist/migrations/sqlite/index.js +4 -0
  81. package/dist/migrations/sqlite/index.js.map +1 -1
  82. package/dist/repositories/oauth-device-code.repository.d.ts +4 -0
  83. package/dist/repositories/oauth-device-code.repository.d.ts.map +1 -1
  84. package/dist/repositories/oauth-device-code.repository.js +19 -0
  85. package/dist/repositories/oauth-device-code.repository.js.map +1 -1
  86. package/dist/repositories/user.repository.d.ts +4 -2
  87. package/dist/repositories/user.repository.d.ts.map +1 -1
  88. package/dist/repositories/user.repository.js +11 -7
  89. package/dist/repositories/user.repository.js.map +1 -1
  90. package/dist/routes/.well-known/openid-configuration/get.d.ts.map +1 -1
  91. package/dist/routes/.well-known/openid-configuration/get.js +4 -0
  92. package/dist/routes/.well-known/openid-configuration/get.js.map +1 -1
  93. package/dist/routes/api/admin/index.d.ts +185 -0
  94. package/dist/routes/api/admin/index.d.ts.map +1 -0
  95. package/dist/routes/api/admin/index.js +13 -0
  96. package/dist/routes/api/admin/index.js.map +1 -0
  97. package/dist/routes/api/admin/me/get.d.ts +26 -0
  98. package/dist/routes/api/admin/me/get.d.ts.map +1 -0
  99. package/dist/routes/api/admin/me/get.js +29 -0
  100. package/dist/routes/api/admin/me/get.js.map +1 -0
  101. package/dist/routes/api/admin/users/index.d.ts +162 -0
  102. package/dist/routes/api/admin/users/index.d.ts.map +1 -0
  103. package/dist/routes/api/admin/users/index.js +166 -0
  104. package/dist/routes/api/admin/users/index.js.map +1 -0
  105. package/dist/routes/api/auth/accounts/get.d.ts +28 -0
  106. package/dist/routes/api/auth/accounts/get.d.ts.map +1 -0
  107. package/dist/routes/api/auth/accounts/get.js +47 -0
  108. package/dist/routes/api/auth/accounts/get.js.map +1 -0
  109. package/dist/routes/api/auth/accounts/remove.post.d.ts +30 -0
  110. package/dist/routes/api/auth/accounts/remove.post.d.ts.map +1 -0
  111. package/dist/routes/api/auth/accounts/remove.post.js +30 -0
  112. package/dist/routes/api/auth/accounts/remove.post.js.map +1 -0
  113. package/dist/routes/api/auth/accounts/select.post.d.ts +31 -0
  114. package/dist/routes/api/auth/accounts/select.post.d.ts.map +1 -0
  115. package/dist/routes/api/auth/accounts/select.post.js +26 -0
  116. package/dist/routes/api/auth/accounts/select.post.js.map +1 -0
  117. package/dist/routes/api/auth/email/verify/post.d.ts +1 -0
  118. package/dist/routes/api/auth/email/verify/post.d.ts.map +1 -1
  119. package/dist/routes/api/auth/index.d.ts +86 -0
  120. package/dist/routes/api/auth/index.d.ts.map +1 -1
  121. package/dist/routes/api/auth/index.js +6 -0
  122. package/dist/routes/api/auth/index.js.map +1 -1
  123. package/dist/routes/api/auth/login/post.d.ts +1 -0
  124. package/dist/routes/api/auth/login/post.d.ts.map +1 -1
  125. package/dist/routes/api/auth/login/post.js +15 -16
  126. package/dist/routes/api/auth/login/post.js.map +1 -1
  127. package/dist/routes/api/auth/passkey/verify/post.d.ts +1 -0
  128. package/dist/routes/api/auth/passkey/verify/post.d.ts.map +1 -1
  129. package/dist/routes/api/auth/register/post.d.ts +1 -0
  130. package/dist/routes/api/auth/register/post.d.ts.map +1 -1
  131. package/dist/routes/api/auth/totp/recovery/verify/post.d.ts +1 -0
  132. package/dist/routes/api/auth/totp/recovery/verify/post.d.ts.map +1 -1
  133. package/dist/routes/api/auth/totp/verify/post.d.ts +1 -0
  134. package/dist/routes/api/auth/totp/verify/post.d.ts.map +1 -1
  135. package/dist/routes/api/config/get.d.ts +3 -0
  136. package/dist/routes/api/config/get.d.ts.map +1 -1
  137. package/dist/routes/api/config/get.js +7 -1
  138. package/dist/routes/api/config/get.js.map +1 -1
  139. package/dist/routes/api/config/index.d.ts +3 -0
  140. package/dist/routes/api/config/index.d.ts.map +1 -1
  141. package/dist/routes/api/consent/index.d.ts +10 -0
  142. package/dist/routes/api/consent/index.d.ts.map +1 -1
  143. package/dist/routes/api/consent/post.d.ts +10 -0
  144. package/dist/routes/api/consent/post.d.ts.map +1 -1
  145. package/dist/routes/api/consent/post.js +52 -1
  146. package/dist/routes/api/consent/post.js.map +1 -1
  147. package/dist/routes/api/index.d.ts +310 -26
  148. package/dist/routes/api/index.d.ts.map +1 -1
  149. package/dist/routes/api/index.js +2 -0
  150. package/dist/routes/api/index.js.map +1 -1
  151. package/dist/routes/api/user/index.d.ts +3 -0
  152. package/dist/routes/api/user/index.d.ts.map +1 -1
  153. package/dist/routes/api/user/passkeys/register/verify/post.d.ts +1 -0
  154. package/dist/routes/api/user/passkeys/register/verify/post.d.ts.map +1 -1
  155. package/dist/routes/api/user/session/get.d.ts +1 -0
  156. package/dist/routes/api/user/session/get.d.ts.map +1 -1
  157. package/dist/routes/api/user/totp/confirm/post.d.ts +1 -0
  158. package/dist/routes/api/user/totp/confirm/post.d.ts.map +1 -1
  159. package/dist/routes/index.d.ts +303 -16
  160. package/dist/routes/index.d.ts.map +1 -1
  161. package/dist/routes/oauth/.well-known/openid-configuration/get.d.ts.map +1 -1
  162. package/dist/routes/oauth/.well-known/openid-configuration/get.js +1 -0
  163. package/dist/routes/oauth/.well-known/openid-configuration/get.js.map +1 -1
  164. package/dist/routes/oauth/authorize/get.d.ts +2 -0
  165. package/dist/routes/oauth/authorize/get.d.ts.map +1 -1
  166. package/dist/routes/oauth/authorize/get.js +12 -1
  167. package/dist/routes/oauth/authorize/get.js.map +1 -1
  168. package/dist/routes/oauth/client-auth.js +1 -1
  169. package/dist/routes/oauth/client-auth.js.map +1 -1
  170. package/dist/routes/oauth/cors.d.ts.map +1 -1
  171. package/dist/routes/oauth/cors.js +8 -3
  172. package/dist/routes/oauth/cors.js.map +1 -1
  173. package/dist/routes/oauth/device/get-post.d.ts +2 -1
  174. package/dist/routes/oauth/device/get-post.d.ts.map +1 -1
  175. package/dist/routes/oauth/device/get-post.js +15 -9
  176. package/dist/routes/oauth/device/get-post.js.map +1 -1
  177. package/dist/routes/oauth/device-authorization/post.d.ts.map +1 -1
  178. package/dist/routes/oauth/device-authorization/post.js +2 -0
  179. package/dist/routes/oauth/device-authorization/post.js.map +1 -1
  180. package/dist/routes/oauth/end-session/get.d.ts.map +1 -1
  181. package/dist/routes/oauth/end-session/get.js +17 -8
  182. package/dist/routes/oauth/end-session/get.js.map +1 -1
  183. package/dist/routes/oauth/index.d.ts +5 -2
  184. package/dist/routes/oauth/index.d.ts.map +1 -1
  185. package/dist/routes/oauth/revoke/post.d.ts.map +1 -1
  186. package/dist/routes/oauth/revoke/post.js +2 -0
  187. package/dist/routes/oauth/revoke/post.js.map +1 -1
  188. package/dist/routes/oauth/token/post.d.ts +1 -1
  189. package/dist/routes/oauth/token/post.d.ts.map +1 -1
  190. package/dist/routes/oauth/token/post.js +10 -6
  191. package/dist/routes/oauth/token/post.js.map +1 -1
  192. package/dist/routes/oauth/userinfo/get.d.ts.map +1 -1
  193. package/dist/routes/oauth/userinfo/get.js +12 -6
  194. package/dist/routes/oauth/userinfo/get.js.map +1 -1
  195. package/dist/schemas/error.d.ts +56 -6
  196. package/dist/schemas/error.d.ts.map +1 -1
  197. package/dist/schemas/error.js +4 -2
  198. package/dist/schemas/error.js.map +1 -1
  199. package/dist/schemas/field.d.ts +1 -4
  200. package/dist/schemas/field.d.ts.map +1 -1
  201. package/dist/schemas/field.js +3 -1
  202. package/dist/schemas/field.js.map +1 -1
  203. package/dist/schemas/response.d.ts +96 -0
  204. package/dist/schemas/response.d.ts.map +1 -1
  205. package/dist/schemas/response.js +29 -0
  206. package/dist/schemas/response.js.map +1 -1
  207. package/dist/services/account-selection.service.d.ts +39 -0
  208. package/dist/services/account-selection.service.d.ts.map +1 -0
  209. package/dist/services/account-selection.service.js +77 -0
  210. package/dist/services/account-selection.service.js.map +1 -0
  211. package/dist/services/container.d.ts +22 -0
  212. package/dist/services/container.d.ts.map +1 -1
  213. package/dist/services/jwt.service.js +3 -3
  214. package/dist/services/jwt.service.js.map +1 -1
  215. package/dist/services/oauth-authorize.service.d.ts +24 -1
  216. package/dist/services/oauth-authorize.service.d.ts.map +1 -1
  217. package/dist/services/oauth-authorize.service.js +232 -8
  218. package/dist/services/oauth-authorize.service.js.map +1 -1
  219. package/dist/services/oauth-token.service.d.ts +2 -3
  220. package/dist/services/oauth-token.service.d.ts.map +1 -1
  221. package/dist/services/oauth-token.service.js +18 -10
  222. package/dist/services/oauth-token.service.js.map +1 -1
  223. package/dist/services/user.service.d.ts +28 -1
  224. package/dist/services/user.service.d.ts.map +1 -1
  225. package/dist/services/user.service.js +104 -0
  226. package/dist/services/user.service.js.map +1 -1
  227. package/package.json +1 -1
  228. package/public/assets/2fa-BoyBKrjD.js +2 -0
  229. package/public/assets/2fa-BoyBKrjD.js.map +1 -0
  230. package/public/assets/2fa-DfWvDjDW.js +2 -0
  231. package/public/assets/2fa-DfWvDjDW.js.map +1 -0
  232. package/public/assets/2fa-IkQlgUP0.js +2 -0
  233. package/public/assets/2fa-IkQlgUP0.js.map +1 -0
  234. package/public/assets/2fa-SSKfXB7c.js +2 -0
  235. package/public/assets/2fa-SSKfXB7c.js.map +1 -0
  236. package/public/assets/CheckCircle.es-MnJIACCe.js +2 -0
  237. package/public/assets/CheckCircle.es-MnJIACCe.js.map +1 -0
  238. package/public/assets/EnvelopeSimple.es-BZ7u3LYh.js +2 -0
  239. package/public/assets/EnvelopeSimple.es-BZ7u3LYh.js.map +1 -0
  240. package/public/assets/Fingerprint.es-CW755VWD.js +2 -0
  241. package/public/assets/Fingerprint.es-CW755VWD.js.map +1 -0
  242. package/public/assets/IconBase.es-d5KP98Ac.js +2 -0
  243. package/public/assets/IconBase.es-d5KP98Ac.js.map +1 -0
  244. package/public/assets/Key.es-l5aSxw0I.js +2 -0
  245. package/public/assets/Key.es-l5aSxw0I.js.map +1 -0
  246. package/public/assets/Link.es-B-IJS4Q5.js +2 -0
  247. package/public/assets/Link.es-B-IJS4Q5.js.map +1 -0
  248. package/public/assets/Lock.es-Cb_uwQly.js +2 -0
  249. package/public/assets/Lock.es-Cb_uwQly.js.map +1 -0
  250. package/public/assets/ShieldCheck.es-CscPsYbC.js +2 -0
  251. package/public/assets/ShieldCheck.es-CscPsYbC.js.map +1 -0
  252. package/public/assets/Trash.es-BepW9BwV.js +2 -0
  253. package/public/assets/Trash.es-BepW9BwV.js.map +1 -0
  254. package/public/assets/Warning.es-BPpZIJYZ.js +2 -0
  255. package/public/assets/Warning.es-BPpZIJYZ.js.map +1 -0
  256. package/public/assets/X.es-IwdB4hWT.js +2 -0
  257. package/public/assets/X.es-IwdB4hWT.js.map +1 -0
  258. package/public/assets/admin-D2CMlWzS.js +2 -0
  259. package/public/assets/admin-D2CMlWzS.js.map +1 -0
  260. package/public/assets/admin-users-CTAQJl7w.js +2 -0
  261. package/public/assets/admin-users-CTAQJl7w.js.map +1 -0
  262. package/public/assets/alert-CSXqgDVi.js +2 -0
  263. package/public/assets/alert-CSXqgDVi.js.map +1 -0
  264. package/public/assets/consent-C5Qo0iLd.js +2 -0
  265. package/public/assets/consent-C5Qo0iLd.js.map +1 -0
  266. package/public/assets/consent-DwuWkp63.js +2 -0
  267. package/public/assets/consent-DwuWkp63.js.map +1 -0
  268. package/public/assets/email-CIttZRBe.js +2 -0
  269. package/public/assets/email-CIttZRBe.js.map +1 -0
  270. package/public/assets/email-SSKfXB7c.js +2 -0
  271. package/public/assets/email-SSKfXB7c.js.map +1 -0
  272. package/public/assets/error-D60wkdWN.js +2 -0
  273. package/public/assets/error-D60wkdWN.js.map +1 -0
  274. package/public/assets/footer-link-Ib1Hd-fr.js +2 -0
  275. package/public/assets/footer-link-Ib1Hd-fr.js.map +1 -0
  276. package/public/assets/forgot-SSKfXB7c.js +2 -0
  277. package/public/assets/forgot-SSKfXB7c.js.map +1 -0
  278. package/public/assets/forgot-x-UDyHXT.js +2 -0
  279. package/public/assets/forgot-x-UDyHXT.js.map +1 -0
  280. package/public/assets/icon-input-8iU7PNzd.js +2 -0
  281. package/public/assets/icon-input-8iU7PNzd.js.map +1 -0
  282. package/public/assets/index-CsT6OVnP.js +11 -0
  283. package/public/assets/index-CsT6OVnP.js.map +1 -0
  284. package/public/assets/index-D6-1JDnX.css +2 -0
  285. package/public/assets/login-DhbnCudI.js +2 -0
  286. package/public/assets/login-DhbnCudI.js.map +1 -0
  287. package/public/assets/login-SSKfXB7c.js +2 -0
  288. package/public/assets/login-SSKfXB7c.js.map +1 -0
  289. package/public/assets/modal-BjnpKlXn.js +2 -0
  290. package/public/assets/modal-BjnpKlXn.js.map +1 -0
  291. package/public/assets/mutationOptions-Dfvzj6n2.js +2 -0
  292. package/public/assets/mutationOptions-Dfvzj6n2.js.map +1 -0
  293. package/public/assets/page-header-BYMFSGfT.js +2 -0
  294. package/public/assets/page-header-BYMFSGfT.js.map +1 -0
  295. package/public/assets/page-layout-C475gs09.js +2 -0
  296. package/public/assets/page-layout-C475gs09.js.map +1 -0
  297. package/public/assets/passkey-BdISbWr7.js +2 -0
  298. package/public/assets/passkey-BdISbWr7.js.map +1 -0
  299. package/public/assets/passkey-Bv7zPLAZ.js +2 -0
  300. package/public/assets/passkey-Bv7zPLAZ.js.map +1 -0
  301. package/public/assets/passkey-e6uvApHa.js +2 -0
  302. package/public/assets/passkey-e6uvApHa.js.map +1 -0
  303. package/public/assets/password-CkeV4qxb.js +2 -0
  304. package/public/assets/password-CkeV4qxb.js.map +1 -0
  305. package/public/assets/password-SSKfXB7c.js +2 -0
  306. package/public/assets/password-SSKfXB7c.js.map +1 -0
  307. package/public/assets/password-reset-XZJTgJi3.js +2 -0
  308. package/public/assets/password-reset-XZJTgJi3.js.map +1 -0
  309. package/public/assets/pin-input-BM1UizHr.js +2 -0
  310. package/public/assets/pin-input-BM1UizHr.js.map +1 -0
  311. package/public/assets/profile-D2cuVYgE.js +2 -0
  312. package/public/assets/profile-D2cuVYgE.js.map +1 -0
  313. package/public/assets/profile-TKdT20x5.js +2 -0
  314. package/public/assets/profile-TKdT20x5.js.map +1 -0
  315. package/public/assets/promise-OpBtq8tG.js +2 -0
  316. package/public/assets/promise-OpBtq8tG.js.map +1 -0
  317. package/public/assets/recovery-DM8h2gbb.js +2 -0
  318. package/public/assets/recovery-DM8h2gbb.js.map +1 -0
  319. package/public/assets/register-SSKfXB7c.js +2 -0
  320. package/public/assets/register-SSKfXB7c.js.map +1 -0
  321. package/public/assets/register-vWW_43cD.js +2 -0
  322. package/public/assets/register-vWW_43cD.js.map +1 -0
  323. package/public/assets/reset-CgACYrdp.js +2 -0
  324. package/public/assets/reset-CgACYrdp.js.map +1 -0
  325. package/public/assets/reset-SSKfXB7c.js +2 -0
  326. package/public/assets/reset-SSKfXB7c.js.map +1 -0
  327. package/public/assets/routes-CAIeH5mq.js +2 -0
  328. package/public/assets/routes-CAIeH5mq.js.map +1 -0
  329. package/public/assets/select-BCP5fwfB.js +2 -0
  330. package/public/assets/select-BCP5fwfB.js.map +1 -0
  331. package/public/assets/select-SSKfXB7c.js +2 -0
  332. package/public/assets/select-SSKfXB7c.js.map +1 -0
  333. package/public/assets/standard-schema-o4V-s4uY.js +2 -0
  334. package/public/assets/standard-schema-o4V-s4uY.js.map +1 -0
  335. package/public/assets/submit-button-Xx6DwLyh.js +2 -0
  336. package/public/assets/submit-button-Xx6DwLyh.js.map +1 -0
  337. package/public/assets/terms-DPWrbYY2.js +2 -0
  338. package/public/assets/terms-DPWrbYY2.js.map +1 -0
  339. package/public/assets/terms-TKdT20x5.js +2 -0
  340. package/public/assets/terms-TKdT20x5.js.map +1 -0
  341. package/public/assets/terms-checkbox-list-CdrbHxiF.js +2 -0
  342. package/public/assets/terms-checkbox-list-CdrbHxiF.js.map +1 -0
  343. package/public/assets/totp-CKZ6N1NS.js +2 -0
  344. package/public/assets/totp-CKZ6N1NS.js.map +1 -0
  345. package/public/assets/totp-D-PVOsGQ.js +2 -0
  346. package/public/assets/totp-D-PVOsGQ.js.map +1 -0
  347. package/public/assets/totp-NlqqRp4a.js +2 -0
  348. package/public/assets/totp-NlqqRp4a.js.map +1 -0
  349. package/public/assets/use-theme-cVUDAjtt.js +2 -0
  350. package/public/assets/use-theme-cVUDAjtt.js.map +1 -0
  351. package/public/assets/use-totp-setup-BH75uEbE.js +3 -0
  352. package/public/assets/use-totp-setup-BH75uEbE.js.map +1 -0
  353. package/public/assets/useMutation-DVMopbtG.js +2 -0
  354. package/public/assets/useMutation-DVMopbtG.js.map +1 -0
  355. package/public/assets/users-B7ofdp72.js +2 -0
  356. package/public/assets/users-B7ofdp72.js.map +1 -0
  357. package/public/assets/zod-BItJDQBQ.js +66 -0
  358. package/public/assets/zod-BItJDQBQ.js.map +1 -0
  359. package/public/index.html +6 -2
  360. package/public/assets/index-5_9rzim1.css +0 -2
  361. package/public/assets/index-BTGeW26-.js +0 -75
  362. package/public/assets/index-BTGeW26-.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{o as e,r as t}from"./IconBase.es-d5KP98Ac.js";import{Q as n}from"./use-theme-cVUDAjtt.js";import{t as r}from"./useMutation-DVMopbtG.js";import{t as i}from"./page-layout-C475gs09.js";import{t as a}from"./ShieldCheck.es-CscPsYbC.js";import{t as o}from"./X.es-IwdB4hWT.js";import{_ as s,v as c,y as l}from"./index-CsT6OVnP.js";import{t as u}from"./page-header-BYMFSGfT.js";var d=e();function f(){let{t:e}=t(),f=s.useSearch(),p=n(l({client_id:f.client_id,scope:f.scope})),m=r({...c,onSuccess:e=>{window.location.href=e.redirect_url}}),h=()=>{m.mutate({client_id:f.client_id,redirect_uri:f.redirect_uri,response_type:f.response_type,scope:f.scope,state:f.state,nonce:f.nonce,code_challenge:f.code_challenge,code_challenge_method:f.code_challenge_method,prompt:f.prompt,max_age:f.max_age,display:f.display,response_mode:f.response_mode,login_hint:f.login_hint,ui_locales:f.ui_locales,id_token_hint:f.id_token_hint,acr_values:f.acr_values,account_selected:f.account_selected,account_selection_state:f.account_selection_state,decision:`allow`})},g=()=>{m.mutate({client_id:f.client_id,redirect_uri:f.redirect_uri,response_type:f.response_type,scope:f.scope,state:f.state,nonce:f.nonce,code_challenge:f.code_challenge,code_challenge_method:f.code_challenge_method,prompt:f.prompt,max_age:f.max_age,display:f.display,response_mode:f.response_mode,login_hint:f.login_hint,ui_locales:f.ui_locales,id_token_hint:f.id_token_hint,acr_values:f.acr_values,account_selected:f.account_selected,account_selection_state:f.account_selection_state,decision:`deny`})},{client:_,scopes:v,user:y}=p.data;return(0,d.jsxs)(i,{cardPadding:!0,maxWidth:`100`,children:[(0,d.jsx)(u,{subtitle:e(`consent.subtitle`,{app:_.name}),title:e(`consent.title`)}),(0,d.jsxs)(`div`,{className:`mb-4 rounded-lg bg-base-200 p-3 text-center`,children:[(0,d.jsx)(`p`,{className:`text-base-content/60 text-xs`,children:e(`consent.loggedInAs`)}),(0,d.jsx)(`p`,{className:`font-medium text-sm`,"data-testid":`consent-user-email`,children:y.email})]}),(0,d.jsxs)(`div`,{className:`mb-4`,children:[(0,d.jsx)(`h2`,{className:`mb-3 font-semibold text-sm`,children:e(`consent.permissions.title`)}),(0,d.jsx)(`ul`,{className:`flex flex-col gap-2`,"data-testid":`consent-scope-list`,children:v.map(t=>(0,d.jsxs)(`li`,{className:`flex items-start gap-3 rounded-lg bg-base-200 p-3`,children:[(0,d.jsx)(`div`,{className:`mt-0.5 rounded-full bg-primary/20 p-1`,children:(0,d.jsx)(a,{className:`size-4 text-primary`,weight:`fill`})}),(0,d.jsx)(`p`,{className:`font-medium text-sm`,children:e(`consent.scope.${t.name}`,{defaultValue:t.description})})]},t.name))})]}),(0,d.jsxs)(`div`,{className:`flex gap-3`,children:[(0,d.jsx)(`button`,{className:`btn btn-outline h-10 flex-1 font-semibold text-[14px]`,"data-testid":`consent-deny`,disabled:m.isPending,onClick:g,type:`button`,children:m.isPending?(0,d.jsx)(`span`,{className:`loading loading-spinner loading-sm`}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(o,{className:`size-4`,weight:`bold`}),e(`consent.deny`)]})}),(0,d.jsx)(`button`,{className:`btn btn-primary h-10 flex-1 font-semibold text-[14px]`,"data-testid":`consent-allow`,disabled:m.isPending,onClick:h,type:`button`,children:m.isPending?(0,d.jsx)(`span`,{className:`loading loading-spinner loading-sm`}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(a,{className:`size-4`,weight:`fill`}),e(`consent.allow`)]})})]})]})}export{f as component};
2
+ //# sourceMappingURL=consent-C5Qo0iLd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-C5Qo0iLd.js","names":["ShieldCheckIcon","XIcon","useMutation","useSuspenseQuery","useTranslation","PageHeader","PageLayout","consentDecisionMutationOptions","getConsentInfoQueryOptions","Route","Consent","t","search","useSearch","consentInfoQuery","client_id","scope","consentMutation","onSuccess","data","window","location","href","redirect_url","handleAllow","mutate","redirect_uri","response_type","state","nonce","code_challenge","code_challenge_method","prompt","max_age","display","response_mode","login_hint","ui_locales","id_token_hint","acr_values","account_selected","account_selection_state","decision","handleDeny","client","scopes","user","app","name","email","map","description","defaultValue","isPending","component"],"sources":["../../../frontend/src/routes/consent/index.tsx?tsr-split=component"],"sourcesContent":["import { ShieldCheckIcon, XIcon } from '@phosphor-icons/react';\nimport { useMutation, useSuspenseQuery } from '@tanstack/react-query';\nimport {\n createFileRoute,\n type ErrorComponentProps,\n} from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthorizeUrl,\n OAuthSearchSchema,\n} from '#frontend/libs/oauth-search.ts';\nimport {\n consentDecisionMutationOptions,\n getConsentInfoQueryOptions,\n} from '#frontend/queries/consent.ts';\n\nconst ConsentSearchSchema = OAuthSearchSchema.extend({\n client_id: z.string(),\n redirect_uri: z.string(),\n response_type: z.string(),\n});\n\nexport const Route = createFileRoute('/consent/')({\n component: Consent,\n errorComponent: ConsentError,\n validateSearch: ConsentSearchSchema,\n loaderDeps: ({ search }) => ({\n client_id: search.client_id,\n scope: search.scope,\n }),\n loader: async ({ context, deps }) => {\n await context.queryClient.ensureQueryData(\n getConsentInfoQueryOptions({\n client_id: deps.client_id,\n scope: deps.scope,\n }),\n );\n },\n});\n\nfunction ConsentError(props: ErrorComponentProps) {\n return (\n <RouteErrorFallback\n {...props}\n onUnauthorized={() => {\n // Re-enter the OAuth flow from the beginning so the\n // user can log in and be redirected back through\n // /oauth/authorize -> /consent/.\n const params = new URLSearchParams(window.location.search);\n const search = Object.fromEntries(params.entries());\n window.location.href = buildAuthorizeUrl(search);\n }}\n />\n );\n}\n\nfunction Consent() {\n const { t } = useTranslation();\n const search = Route.useSearch();\n\n const consentInfoQuery = useSuspenseQuery(\n getConsentInfoQueryOptions({\n client_id: search.client_id,\n scope: search.scope,\n }),\n );\n\n const consentMutation = useMutation({\n ...consentDecisionMutationOptions,\n onSuccess: (data) => {\n window.location.href = data.redirect_url;\n },\n });\n\n const handleAllow = () => {\n consentMutation.mutate({\n client_id: search.client_id,\n redirect_uri: search.redirect_uri,\n response_type: search.response_type,\n scope: search.scope,\n state: search.state,\n nonce: search.nonce,\n code_challenge: search.code_challenge,\n code_challenge_method: search.code_challenge_method,\n prompt: search.prompt,\n max_age: search.max_age,\n display: search.display,\n response_mode: search.response_mode,\n login_hint: search.login_hint,\n ui_locales: search.ui_locales,\n id_token_hint: search.id_token_hint,\n acr_values: search.acr_values,\n account_selected: search.account_selected,\n account_selection_state: search.account_selection_state,\n decision: 'allow',\n });\n };\n\n const handleDeny = () => {\n consentMutation.mutate({\n client_id: search.client_id,\n redirect_uri: search.redirect_uri,\n response_type: search.response_type,\n scope: search.scope,\n state: search.state,\n nonce: search.nonce,\n code_challenge: search.code_challenge,\n code_challenge_method: search.code_challenge_method,\n prompt: search.prompt,\n max_age: search.max_age,\n display: search.display,\n response_mode: search.response_mode,\n login_hint: search.login_hint,\n ui_locales: search.ui_locales,\n id_token_hint: search.id_token_hint,\n acr_values: search.acr_values,\n account_selected: search.account_selected,\n account_selection_state: search.account_selection_state,\n decision: 'deny',\n });\n };\n\n const { client, scopes, user } = consentInfoQuery.data;\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('consent.subtitle', { app: client.name })}\n title={t('consent.title')}\n />\n\n {/* User info */}\n <div className=\"mb-4 rounded-lg bg-base-200 p-3 text-center\">\n <p className=\"text-base-content/60 text-xs\">\n {t('consent.loggedInAs')}\n </p>\n <p className=\"font-medium text-sm\" data-testid=\"consent-user-email\">\n {user.email}\n </p>\n </div>\n\n {/* Requested permissions */}\n <div className=\"mb-4\">\n <h2 className=\"mb-3 font-semibold text-sm\">\n {t('consent.permissions.title')}\n </h2>\n <ul className=\"flex flex-col gap-2\" data-testid=\"consent-scope-list\">\n {scopes.map((scope: { name: string; description: string }) => (\n <li\n className=\"flex items-start gap-3 rounded-lg bg-base-200 p-3\"\n key={scope.name}\n >\n <div className=\"mt-0.5 rounded-full bg-primary/20 p-1\">\n <ShieldCheckIcon\n className=\"size-4 text-primary\"\n weight=\"fill\"\n />\n </div>\n <p className=\"font-medium text-sm\">\n {t(`consent.scope.${scope.name}`, {\n defaultValue: scope.description,\n })}\n </p>\n </li>\n ))}\n </ul>\n </div>\n\n {/* Action buttons */}\n <div className=\"flex gap-3\">\n <button\n className=\"btn btn-outline h-10 flex-1 font-semibold text-[14px]\"\n data-testid=\"consent-deny\"\n disabled={consentMutation.isPending}\n onClick={handleDeny}\n type=\"button\"\n >\n {consentMutation.isPending ? (\n <span className=\"loading loading-spinner loading-sm\" />\n ) : (\n <>\n <XIcon className=\"size-4\" weight=\"bold\" />\n {t('consent.deny')}\n </>\n )}\n </button>\n <button\n className=\"btn btn-primary h-10 flex-1 font-semibold text-[14px]\"\n data-testid=\"consent-allow\"\n disabled={consentMutation.isPending}\n onClick={handleAllow}\n type=\"button\"\n >\n {consentMutation.isPending ? (\n <span className=\"loading loading-spinner loading-sm\" />\n ) : (\n <>\n <ShieldCheckIcon className=\"size-4\" weight=\"fill\" />\n {t('consent.allow')}\n </>\n )}\n </button>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{o as e}from"./IconBase.es-d5KP98Ac.js";import{A as t,N as n}from"./index-CsT6OVnP.js";var r=e();function i(e){return(0,r.jsx)(n,{...e,onUnauthorized:()=>{let e=new URLSearchParams(window.location.search),n=Object.fromEntries(e.entries());window.location.href=t(n)}})}export{i as errorComponent};
2
+ //# sourceMappingURL=consent-DwuWkp63.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-DwuWkp63.js","names":["RouteErrorFallback","buildAuthorizeUrl","ConsentError","props","ErrorComponentProps","params","URLSearchParams","window","location","search","Object","fromEntries","entries","href","errorComponent"],"sources":["../../../frontend/src/routes/consent/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { ShieldCheckIcon, XIcon } from '@phosphor-icons/react';\nimport { useMutation, useSuspenseQuery } from '@tanstack/react-query';\nimport {\n createFileRoute,\n type ErrorComponentProps,\n} from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthorizeUrl,\n OAuthSearchSchema,\n} from '#frontend/libs/oauth-search.ts';\nimport {\n consentDecisionMutationOptions,\n getConsentInfoQueryOptions,\n} from '#frontend/queries/consent.ts';\n\nconst ConsentSearchSchema = OAuthSearchSchema.extend({\n client_id: z.string(),\n redirect_uri: z.string(),\n response_type: z.string(),\n});\n\nexport const Route = createFileRoute('/consent/')({\n component: Consent,\n errorComponent: ConsentError,\n validateSearch: ConsentSearchSchema,\n loaderDeps: ({ search }) => ({\n client_id: search.client_id,\n scope: search.scope,\n }),\n loader: async ({ context, deps }) => {\n await context.queryClient.ensureQueryData(\n getConsentInfoQueryOptions({\n client_id: deps.client_id,\n scope: deps.scope,\n }),\n );\n },\n});\n\nfunction ConsentError(props: ErrorComponentProps) {\n return (\n <RouteErrorFallback\n {...props}\n onUnauthorized={() => {\n // Re-enter the OAuth flow from the beginning so the\n // user can log in and be redirected back through\n // /oauth/authorize -> /consent/.\n const params = new URLSearchParams(window.location.search);\n const search = Object.fromEntries(params.entries());\n window.location.href = buildAuthorizeUrl(search);\n }}\n />\n );\n}\n\nfunction Consent() {\n const { t } = useTranslation();\n const search = Route.useSearch();\n\n const consentInfoQuery = useSuspenseQuery(\n getConsentInfoQueryOptions({\n client_id: search.client_id,\n scope: search.scope,\n }),\n );\n\n const consentMutation = useMutation({\n ...consentDecisionMutationOptions,\n onSuccess: (data) => {\n window.location.href = data.redirect_url;\n },\n });\n\n const handleAllow = () => {\n consentMutation.mutate({\n client_id: search.client_id,\n redirect_uri: search.redirect_uri,\n response_type: search.response_type,\n scope: search.scope,\n state: search.state,\n nonce: search.nonce,\n code_challenge: search.code_challenge,\n code_challenge_method: search.code_challenge_method,\n prompt: search.prompt,\n max_age: search.max_age,\n display: search.display,\n response_mode: search.response_mode,\n login_hint: search.login_hint,\n ui_locales: search.ui_locales,\n id_token_hint: search.id_token_hint,\n acr_values: search.acr_values,\n account_selected: search.account_selected,\n account_selection_state: search.account_selection_state,\n decision: 'allow',\n });\n };\n\n const handleDeny = () => {\n consentMutation.mutate({\n client_id: search.client_id,\n redirect_uri: search.redirect_uri,\n response_type: search.response_type,\n scope: search.scope,\n state: search.state,\n nonce: search.nonce,\n code_challenge: search.code_challenge,\n code_challenge_method: search.code_challenge_method,\n prompt: search.prompt,\n max_age: search.max_age,\n display: search.display,\n response_mode: search.response_mode,\n login_hint: search.login_hint,\n ui_locales: search.ui_locales,\n id_token_hint: search.id_token_hint,\n acr_values: search.acr_values,\n account_selected: search.account_selected,\n account_selection_state: search.account_selection_state,\n decision: 'deny',\n });\n };\n\n const { client, scopes, user } = consentInfoQuery.data;\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('consent.subtitle', { app: client.name })}\n title={t('consent.title')}\n />\n\n {/* User info */}\n <div className=\"mb-4 rounded-lg bg-base-200 p-3 text-center\">\n <p className=\"text-base-content/60 text-xs\">\n {t('consent.loggedInAs')}\n </p>\n <p className=\"font-medium text-sm\" data-testid=\"consent-user-email\">\n {user.email}\n </p>\n </div>\n\n {/* Requested permissions */}\n <div className=\"mb-4\">\n <h2 className=\"mb-3 font-semibold text-sm\">\n {t('consent.permissions.title')}\n </h2>\n <ul className=\"flex flex-col gap-2\" data-testid=\"consent-scope-list\">\n {scopes.map((scope: { name: string; description: string }) => (\n <li\n className=\"flex items-start gap-3 rounded-lg bg-base-200 p-3\"\n key={scope.name}\n >\n <div className=\"mt-0.5 rounded-full bg-primary/20 p-1\">\n <ShieldCheckIcon\n className=\"size-4 text-primary\"\n weight=\"fill\"\n />\n </div>\n <p className=\"font-medium text-sm\">\n {t(`consent.scope.${scope.name}`, {\n defaultValue: scope.description,\n })}\n </p>\n </li>\n ))}\n </ul>\n </div>\n\n {/* Action buttons */}\n <div className=\"flex gap-3\">\n <button\n className=\"btn btn-outline h-10 flex-1 font-semibold text-[14px]\"\n data-testid=\"consent-deny\"\n disabled={consentMutation.isPending}\n onClick={handleDeny}\n type=\"button\"\n >\n {consentMutation.isPending ? (\n <span className=\"loading loading-spinner loading-sm\" />\n ) : (\n <>\n <XIcon className=\"size-4\" weight=\"bold\" />\n {t('consent.deny')}\n </>\n )}\n </button>\n <button\n className=\"btn btn-primary h-10 flex-1 font-semibold text-[14px]\"\n data-testid=\"consent-allow\"\n disabled={consentMutation.isPending}\n onClick={handleAllow}\n type=\"button\"\n >\n {consentMutation.isPending ? (\n <span className=\"loading loading-spinner loading-sm\" />\n ) : (\n <>\n <ShieldCheckIcon className=\"size-4\" weight=\"fill\" />\n {t('consent.allow')}\n </>\n )}\n </button>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"uGA4CA,SAASE,EAAaC,EAA4B,CAChD,OACE,EAAA,EAAA,KAAC,EAAD,CACE,GAAIA,EACJ,mBAAsB,CAIpB,IAAME,EAAS,IAAIC,gBAAgBC,OAAOC,SAASC,MAAM,EACnDA,EAASC,OAAOC,YAAYN,EAAOO,QAAQ,CAAC,EAClDL,OAAOC,SAASK,KAAOZ,EAAkBQ,CAAM,CACjD,CAAE,CAAA,CAGR"}
@@ -0,0 +1,2 @@
1
+ import{o as e,r as t,s as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{Q as i,a,i as o,n as s,ut as c}from"./use-theme-cVUDAjtt.js";import{t as l}from"./useMutation-DVMopbtG.js";import{t as u}from"./mutationOptions-Dfvzj6n2.js";import{t as d}from"./CheckCircle.es-MnJIACCe.js";import{t as f}from"./page-layout-C475gs09.js";import{t as p}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{t as m}from"./Key.es-l5aSxw0I.js";import{c as h,o as g}from"./zod-BItJDQBQ.js";import{A as _,F as v,M as y,S as b,j as x,p as S}from"./index-CsT6OVnP.js";import{t as C}from"./page-header-BYMFSGfT.js";import{t as w}from"./alert-CSXqgDVi.js";import{t as T}from"./promise-OpBtq8tG.js";import{r as E,t as D}from"./standard-schema-o4V-s4uY.js";import{t as O}from"./icon-input-8iU7PNzd.js";import{t as k}from"./submit-button-Xx6DwLyh.js";var A=r(n()),j=e();function M({text:e,className:t=``}){return(0,j.jsxs)(`div`,{className:`my-4 flex items-center ${t}`,children:[(0,j.jsx)(`div`,{className:`h-px flex-1 bg-base-200`}),e&&(0,j.jsx)(`span`,{className:`px-3 text-base-content/60 text-sm`,children:e}),(0,j.jsx)(`div`,{className:`h-px flex-1 bg-base-200`})]})}var N=u({mutationFn:async e=>a(await o.api.auth.email.verify.$post({json:e}))}),P=u({mutationFn:async e=>a(await o.api.auth.email.resend.$post({json:e,header:{}}))});function F(){let{t:e}=t(),n=v(),r=c(),a=S.useSearch(),{token:o,email:u}=a,[F,I]=(0,A.useState)(!1),[L,R]=(0,A.useState)(!1),{data:z}=i(s),B=(0,A.useMemo)(()=>g({token:h().min(1,e(`validation.token.required`))}),[e]),V=l({...N,onSuccess:async e=>{let t=e.user;if(r.setQueryData(b.queryKey,{user:t}),await T(),t.second_factor_required){let e=[];return z.auth.password.totp.enabled&&e.push(`totp`),z.auth.passkey.enabled&&e.push(`passkey`),e.length===1?e[0]===`totp`?n({to:`/setup/totp`,search:x(a)}):n({to:`/setup/passkey`,search:x(a)}):n({to:`/setup/2fa`,search:x(a)})}y(a)?window.location.href=_(a):I(!0)},onSettled:()=>{r.invalidateQueries({queryKey:b.queryKey})}}),H=l({...P,onSuccess:()=>{R(!0),setTimeout(()=>R(!1),5e3)}}),{register:U,setError:W,handleSubmit:G,formState:{errors:K}}=E({defaultValues:{token:o||``},resolver:D(B)}),q=async t=>{try{await V.mutateAsync(t)}catch{W(`token`,{type:`manual`,message:e(`verifyEmail.error.invalidToken`)})}},J=async()=>{if(u)try{await H.mutateAsync({email:u})}catch{}};return F?(0,j.jsxs)(f,{cardPadding:!0,maxWidth:`100`,children:[(0,j.jsx)(w,{className:`mb-4`,icon:d,type:`success`,children:e(`verifyEmail.success.title`)}),(0,j.jsx)(C,{subtitle:e(`verifyEmail.success.description`),title:e(`verifyEmail.success.subtitle`)}),(0,j.jsx)(`button`,{className:`btn btn-block h-10 font-semibold text-[14px]`,"data-testid":`email-verify-go-profile`,onClick:()=>n({to:`/profile`}),type:`button`,children:e(`verifyEmail.success.goToProfile`)})]}):(0,j.jsxs)(f,{cardPadding:!0,maxWidth:`100`,children:[(0,j.jsx)(C,{subtitle:e(`verifyEmail.subtitle`),title:e(`verifyEmail.title`)}),u&&(0,j.jsx)(w,{className:`mb-4`,icon:p,type:`info`,children:(0,j.jsxs)(`div`,{className:`text-left`,children:[(0,j.jsx)(`p`,{className:`font-semibold`,children:e(`register.success.subtitle`)}),(0,j.jsx)(`p`,{className:`text-xs`,children:e(`register.success.description`,{email:u})})]})}),(0,j.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:G(q),children:[(0,j.jsx)(O,{error:K.token,icon:m,placeholder:e(`verifyEmail.token.placeholder`),...U(`token`),type:`text`}),(0,j.jsx)(k,{className:`mt-2`,isPending:V.isPending,pendingText:e(`verifyEmail.submitting`),children:e(`verifyEmail.submit`)})]}),u&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(M,{}),L&&(0,j.jsx)(w,{className:`mb-2`,icon:d,type:`success`,children:e(`verifyEmail.resendSuccess`)}),(0,j.jsx)(`button`,{className:`btn btn-ghost btn-sm w-full`,"data-testid":`email-verify-resend`,disabled:H.isPending||L,onClick:J,type:`button`,children:H.isPending?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`span`,{className:`loading loading-spinner loading-xs`}),e(`verifyEmail.resending`)]}):e(`verifyEmail.resend`)})]})]})}export{F as component};
2
+ //# sourceMappingURL=email-CIttZRBe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-CIttZRBe.js","names":["standardSchemaResolver","CheckCircleIcon","EnvelopeSimpleIcon","KeyIcon","useMutation","useQueryClient","useSuspenseQuery","useNavigate","useMemo","useState","useForm","useTranslation","z","IconInput","PageHeader","SubmitButton","Alert","Divider","PageLayout","buildAuthorizeUrl","extractOAuthParams","isOAuthFlow","tick","appConfigQueryOptions","getSessionQueryOptions","resendVerificationMutationOptions","verifyEmailMutationOptions","Route","VerifyEmailFormValues","token","VerifyEmail","t","navigate","queryClient","search","useSearch","queryToken","email","verified","setVerified","resendSuccess","setResendSuccess","data","appConfig","verifyEmailSchema","object","string","min","verifyEmailMutation","onSuccess","user","setQueryData","queryKey","second_factor_required","available_2fa_methods","SecondFactorMethod","auth","password","totp","enabled","push","passkey","length","method","to","window","location","href","onSettled","invalidateQueries","resendVerificationMutation","setTimeout","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","_error","type","message","handleResend","isPending","component"],"sources":["../../../frontend/src/components/ui/divider.tsx","../../../frontend/src/queries/verify-email.ts","../../../frontend/src/routes/verify/email/index.tsx?tsr-split=component"],"sourcesContent":["type DividerProps = {\n text?: string;\n className?: string;\n};\n\nexport function Divider({ text, className = '' }: DividerProps) {\n return (\n <div className={`my-4 flex items-center ${className}`}>\n <div className=\"h-px flex-1 bg-base-200\" />\n {text && (\n <span className=\"px-3 text-base-content/60 text-sm\">{text}</span>\n )}\n <div className=\"h-px flex-1 bg-base-200\" />\n </div>\n );\n}\n","import { mutationOptions } from '@tanstack/react-query';\nimport type { InferRequestType, InferResponseType } from 'hono/client';\nimport { client, jsonOk } from '#frontend/libs/api.ts';\n\nexport type VerifyEmailParams = InferRequestType<\n (typeof client.api.auth.email.verify)['$post']\n>['json'];\n\nexport type VerifyEmailResponse = InferResponseType<\n (typeof client.api.auth.email.verify)['$post'],\n 200\n>;\n\nexport const verifyEmailMutationOptions = mutationOptions({\n mutationFn: async (values: VerifyEmailParams) => {\n const res = await client.api.auth.email.verify.$post({\n json: values,\n });\n return jsonOk(res);\n },\n});\n\nexport type ResendVerificationParams = InferRequestType<\n (typeof client.api.auth.email.resend)['$post']\n>['json'];\n\nexport type ResendVerificationResponse = InferResponseType<\n (typeof client.api.auth.email.resend)['$post'],\n 200\n>;\n\nexport const resendVerificationMutationOptions = mutationOptions({\n mutationFn: async (values: ResendVerificationParams) => {\n const res = await client.api.auth.email.resend.$post({\n json: values,\n header: {},\n });\n return jsonOk(res);\n },\n});\n","import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n EnvelopeSimpleIcon,\n KeyIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { Divider } from '#frontend/components/ui/divider.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n type SecondFactorMethod,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport {\n resendVerificationMutationOptions,\n verifyEmailMutationOptions,\n} from '#frontend/queries/verify-email.ts';\n\nconst SearchSchema = z.object({\n ...OAuthSearchSchema.shape,\n token: z.string().default(''),\n email: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/verify/email/')({\n component: VerifyEmail,\n errorComponent: RouteErrorFallback,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype VerifyEmailFormValues = {\n token: string;\n};\n\nfunction VerifyEmail() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const { token: queryToken, email } = search;\n const [verified, setVerified] = useState(false);\n const [resendSuccess, setResendSuccess] = useState(false);\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const verifyEmailSchema = useMemo(\n () =>\n z.object({\n token: z.string().min(1, t('validation.token.required')),\n }),\n [t],\n );\n\n const verifyEmailMutation = useMutation({\n ...verifyEmailMutationOptions,\n onSuccess: async (data) => {\n const user = data.user;\n\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: user,\n });\n await tick();\n\n if (user.second_factor_required) {\n const available_2fa_methods: SecondFactorMethod[] = [];\n if (appConfig.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (appConfig.auth.passkey.enabled) {\n available_2fa_methods.push('passkey');\n }\n\n if (available_2fa_methods.length === 1) {\n const method = available_2fa_methods[0];\n if (method === 'totp') {\n return navigate({\n to: '/setup/totp',\n search: extractOAuthParams(search),\n });\n } else {\n return navigate({\n to: '/setup/passkey',\n search: extractOAuthParams(search),\n });\n }\n } else {\n return navigate({\n to: '/setup/2fa',\n search: extractOAuthParams(search),\n });\n }\n }\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthorizeUrl(search);\n } else {\n setVerified(true);\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const resendVerificationMutation = useMutation({\n ...resendVerificationMutationOptions,\n onSuccess: () => {\n setResendSuccess(true);\n setTimeout(() => setResendSuccess(false), 5000);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<VerifyEmailFormValues>({\n defaultValues: {\n token: queryToken || '',\n },\n resolver: standardSchemaResolver(verifyEmailSchema),\n });\n\n const onSubmit = async (values: VerifyEmailFormValues) => {\n try {\n await verifyEmailMutation.mutateAsync(values);\n } catch (_error) {\n setError('token', {\n type: 'manual',\n message: t('verifyEmail.error.invalidToken'),\n });\n }\n };\n\n const handleResend = async () => {\n if (!email) {\n return;\n }\n try {\n await resendVerificationMutation.mutateAsync({ email });\n } catch (_error) {}\n };\n\n if (verified) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('verifyEmail.success.description')}\n title={t('verifyEmail.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"email-verify-go-profile\"\n onClick={() => navigate({ to: '/profile' })}\n type=\"button\"\n >\n {t('verifyEmail.success.goToProfile')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyEmail.subtitle')}\n title={t('verifyEmail.title')}\n />\n\n {email && (\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n <div className=\"text-left\">\n <p className=\"font-semibold\">{t('register.success.subtitle')}</p>\n <p className=\"text-xs\">\n {t('register.success.description', { email })}\n </p>\n </div>\n </Alert>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('verifyEmail.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyEmailMutation.isPending}\n pendingText={t('verifyEmail.submitting')}\n >\n {t('verifyEmail.submit')}\n </SubmitButton>\n </form>\n\n {email && (\n <>\n <Divider />\n\n {resendSuccess && (\n <Alert className=\"mb-2\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.resendSuccess')}\n </Alert>\n )}\n\n <button\n className=\"btn btn-ghost btn-sm w-full\"\n data-testid=\"email-verify-resend\"\n disabled={resendVerificationMutation.isPending || resendSuccess}\n onClick={handleResend}\n type=\"button\"\n >\n {resendVerificationMutation.isPending ? (\n <>\n <span className=\"loading loading-spinner loading-xs\" />\n {t('verifyEmail.resending')}\n </>\n ) : (\n t('verifyEmail.resend')\n )}\n </button>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{N as e}from"./index-CsT6OVnP.js";var t=e;export{t as errorComponent};
2
+ //# sourceMappingURL=email-SSKfXB7c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-SSKfXB7c.js","names":["RouteErrorFallback","VerifyEmailFormValues","token","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/verify/email/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n EnvelopeSimpleIcon,\n KeyIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { Divider } from '#frontend/components/ui/divider.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n type SecondFactorMethod,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport {\n resendVerificationMutationOptions,\n verifyEmailMutationOptions,\n} from '#frontend/queries/verify-email.ts';\n\nconst SearchSchema = z.object({\n ...OAuthSearchSchema.shape,\n token: z.string().default(''),\n email: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/verify/email/')({\n component: VerifyEmail,\n errorComponent: RouteErrorFallback,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype VerifyEmailFormValues = {\n token: string;\n};\n\nfunction VerifyEmail() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const { token: queryToken, email } = search;\n const [verified, setVerified] = useState(false);\n const [resendSuccess, setResendSuccess] = useState(false);\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const verifyEmailSchema = useMemo(\n () =>\n z.object({\n token: z.string().min(1, t('validation.token.required')),\n }),\n [t],\n );\n\n const verifyEmailMutation = useMutation({\n ...verifyEmailMutationOptions,\n onSuccess: async (data) => {\n const user = data.user;\n\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: user,\n });\n await tick();\n\n if (user.second_factor_required) {\n const available_2fa_methods: SecondFactorMethod[] = [];\n if (appConfig.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (appConfig.auth.passkey.enabled) {\n available_2fa_methods.push('passkey');\n }\n\n if (available_2fa_methods.length === 1) {\n const method = available_2fa_methods[0];\n if (method === 'totp') {\n return navigate({\n to: '/setup/totp',\n search: extractOAuthParams(search),\n });\n } else {\n return navigate({\n to: '/setup/passkey',\n search: extractOAuthParams(search),\n });\n }\n } else {\n return navigate({\n to: '/setup/2fa',\n search: extractOAuthParams(search),\n });\n }\n }\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthorizeUrl(search);\n } else {\n setVerified(true);\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const resendVerificationMutation = useMutation({\n ...resendVerificationMutationOptions,\n onSuccess: () => {\n setResendSuccess(true);\n setTimeout(() => setResendSuccess(false), 5000);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<VerifyEmailFormValues>({\n defaultValues: {\n token: queryToken || '',\n },\n resolver: standardSchemaResolver(verifyEmailSchema),\n });\n\n const onSubmit = async (values: VerifyEmailFormValues) => {\n try {\n await verifyEmailMutation.mutateAsync(values);\n } catch (_error) {\n setError('token', {\n type: 'manual',\n message: t('verifyEmail.error.invalidToken'),\n });\n }\n };\n\n const handleResend = async () => {\n if (!email) {\n return;\n }\n try {\n await resendVerificationMutation.mutateAsync({ email });\n } catch (_error) {}\n };\n\n if (verified) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('verifyEmail.success.description')}\n title={t('verifyEmail.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"email-verify-go-profile\"\n onClick={() => navigate({ to: '/profile' })}\n type=\"button\"\n >\n {t('verifyEmail.success.goToProfile')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyEmail.subtitle')}\n title={t('verifyEmail.title')}\n />\n\n {email && (\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n <div className=\"text-left\">\n <p className=\"font-semibold\">{t('register.success.subtitle')}</p>\n <p className=\"text-xs\">\n {t('register.success.description', { email })}\n </p>\n </div>\n </Alert>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('verifyEmail.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyEmailMutation.isPending}\n pendingText={t('verifyEmail.submitting')}\n >\n {t('verifyEmail.submit')}\n </SubmitButton>\n </form>\n\n {email && (\n <>\n <Divider />\n\n {resendSuccess && (\n <Alert className=\"mb-2\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.resendSuccess')}\n </Alert>\n )}\n\n <button\n className=\"btn btn-ghost btn-sm w-full\"\n data-testid=\"email-verify-resend\"\n disabled={resendVerificationMutation.isPending || resendSuccess}\n onClick={handleResend}\n type=\"button\"\n >\n {resendVerificationMutation.isPending ? (\n <>\n <span className=\"loading loading-spinner loading-xs\" />\n {t('verifyEmail.resending')}\n </>\n ) : (\n t('verifyEmail.resend')\n )}\n </button>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"wCAgEE,IAAAG,EA3COH"}
@@ -0,0 +1,2 @@
1
+ import{o as e,r as t,s as n,t as r,u as i}from"./IconBase.es-d5KP98Ac.js";import{f as a}from"./use-theme-cVUDAjtt.js";import{t as o}from"./page-layout-C475gs09.js";import{I as s,P as c}from"./index-CsT6OVnP.js";import{t as l}from"./page-header-BYMFSGfT.js";import{t as u}from"./alert-CSXqgDVi.js";var d=i(n(),1),f=new Map([[`bold`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z`}))],[`duotone`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z`,opacity:`0.2`}),d.createElement(`path`,{d:`M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z`}))],[`fill`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z`}))],[`light`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z`}))],[`regular`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z`}))],[`thin`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z`}))]]),p=d.forwardRef((e,t)=>d.createElement(r,{ref:t,...e,weights:f}));p.displayName=`HouseIcon`;var m=e();function h(){let{t:e}=t(),n=s({from:`/error/`}),r=n.code||`UNKNOWN_ERROR`,i=n.message||e(`error.defaultMessage`);return(0,m.jsxs)(o,{cardPadding:!0,maxWidth:`100`,children:[(0,m.jsx)(u,{className:`mb-4`,icon:c,type:`error`,children:e(`error.title`)}),(0,m.jsx)(l,{subtitle:i,title:e(`error.subtitle`)}),(0,m.jsxs)(`div`,{className:`mb-6 rounded-lg bg-base-200 p-4 text-center`,children:[(0,m.jsx)(`p`,{className:`mb-1 text-base-content/50 text-xs`,children:e(`error.codeLabel`)}),(0,m.jsx)(`code`,{className:`font-mono text-error text-sm`,"data-testid":`error-code`,children:r})]}),(0,m.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,m.jsx)(a,{className:`btn btn-block h-10 font-semibold text-[14px]`,to:`/login`,children:e(`error.goToLogin`)}),(0,m.jsxs)(`button`,{className:`btn btn-ghost btn-block h-10 font-semibold text-[14px]`,onClick:()=>window.history.back(),type:`button`,children:[(0,m.jsx)(p,{className:`size-4`,weight:`fill`}),e(`error.goBack`)]})]}),(0,m.jsxs)(`div`,{className:`mt-6 text-center text-base-content/70 text-xs`,children:[e(`error.footer.needHelp`),` `,(0,m.jsx)(`a`,{className:`link link-info font-medium`,href:`mailto:support@example.com`,children:e(`error.footer.contactSupport`)})]})]})}export{h as component};
2
+ //# sourceMappingURL=error-D60wkdWN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-D60wkdWN.js","names":["e","t","a","HouseIcon","WarningCircleIcon","Link","useSearch","useTranslation","PageHeader","Alert","PageLayout","ErrorPage","t","search","from","errorCode","code","errorMessage","message","window","history","back","component"],"sources":["../../../../node_modules/.pnpm/@phosphor-icons+react@2.1.10_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@phosphor-icons/react/dist/defs/House.es.js","../../../../node_modules/.pnpm/@phosphor-icons+react@2.1.10_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@phosphor-icons/react/dist/csr/House.es.js","../../../frontend/src/routes/error/index.tsx?tsr-split=component"],"sourcesContent":["import * as a from \"react\";\nconst e = /* @__PURE__ */ new Map([\n [\n \"bold\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\n \"path\",\n {\n d: \"M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z\",\n opacity: \"0.2\"\n }\n ), /* @__PURE__ */ a.createElement(\"path\", { d: \"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z\" }))\n ]\n]);\nexport {\n e as default\n};\n","import * as o from \"react\";\nimport t from \"../lib/IconBase.es.js\";\nimport a from \"../defs/House.es.js\";\nconst e = o.forwardRef((r, s) => /* @__PURE__ */ o.createElement(t, { ref: s, ...r, weights: a }));\ne.displayName = \"HouseIcon\";\nconst n = e;\nexport {\n n as House,\n e as HouseIcon\n};\n","import { HouseIcon, WarningCircleIcon } from '@phosphor-icons/react';\nimport { createFileRoute, Link, useSearch } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\n\nconst errorSearchSchema = z.object({\n code: z.string().optional(),\n message: z.string().optional(),\n});\n\nexport const Route = createFileRoute('/error/')({\n component: ErrorPage,\n validateSearch: errorSearchSchema,\n});\n\nfunction ErrorPage() {\n const { t } = useTranslation();\n const search = useSearch({ from: '/error/' });\n\n const errorCode = search.code || 'UNKNOWN_ERROR';\n const errorMessage = search.message || t('error.defaultMessage');\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={WarningCircleIcon} type=\"error\">\n {t('error.title')}\n </Alert>\n\n <PageHeader subtitle={errorMessage} title={t('error.subtitle')} />\n\n {/* Error Code */}\n <div className=\"mb-6 rounded-lg bg-base-200 p-4 text-center\">\n <p className=\"mb-1 text-base-content/50 text-xs\">\n {t('error.codeLabel')}\n </p>\n <code className=\"font-mono text-error text-sm\" data-testid=\"error-code\">\n {errorCode}\n </code>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3\">\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('error.goToLogin')}\n </Link>\n <button\n className=\"btn btn-ghost btn-block h-10 font-semibold text-[14px]\"\n onClick={() => window.history.back()}\n type=\"button\"\n >\n <HouseIcon className=\"size-4\" weight=\"fill\" />\n {t('error.goBack')}\n </button>\n </div>\n\n {/* Footer */}\n <div className=\"mt-6 text-center text-base-content/70 text-xs\">\n {t('error.footer.needHelp')}{' '}\n <a\n className=\"link link-info font-medium\"\n href=\"mailto:support@example.com\"\n >\n {t('error.footer.contactSupport')}\n </a>\n </div>\n </PageLayout>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"wTACMA,EAAoB,IAAI,IAAI,CAChC,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,6RAA8R,CAAC,CAAC,CACjY,EACA,CACE,UACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAClE,OACA,CACE,EAAG,yGACH,QAAS,KACX,CACF,EAAmB,EAAE,cAAc,OAAQ,CAAE,EAAG,kQAAmQ,CAAC,CAAC,CACvT,EACA,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,mMAAoM,CAAC,CAAC,CACvS,EACA,CACE,QACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,mTAAoT,CAAC,CAAC,CACvZ,EACA,CACE,UACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,kQAAmQ,CAAC,CAAC,CACtW,EACA,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,0SAA2S,CAAC,CAAC,CAC9Y,CACF,CAAC,EC7BK,EAAA,EAAM,YAAY,EAAG,IAAsB,EAAE,cAAcC,EAAG,CAAE,IAAK,EAAG,GAAG,EAAG,QAASC,CAAE,CAAC,CAAC,EACjG,EAAE,YAAc,sBCchB,SAASS,GAAY,CACnB,GAAM,CAAEC,KAAML,EAAe,EACvBM,EAASP,EAAU,CAAEQ,KAAM,SAAU,CAAC,EAEtCC,EAAYF,EAAOG,MAAQ,gBAC3BC,EAAeJ,EAAOK,SAAWN,EAAE,sBAAsB,EAE/D,OACE,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMR,EAAmB,KAAK,iBACnDQ,EAAE,aAAa,CACX,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CAAY,SAAUK,EAAc,MAAOL,EAAE,gBAAgB,CAAE,CAAA,GAG/D,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uDAAf,EACE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,6CACVA,EAAE,iBAAiB,CACnB,CAAA,GACH,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+BAA+B,cAAY,sBACxDG,CACG,CAAA,CACH,KAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+BAAf,EACE,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,+CACV,GAAG,kBAEFH,EAAE,iBAAiB,CAChB,CAAA,GACN,EAAA,EAAA,MAAC,SAAD,CACE,UAAU,yDACV,YAAeO,OAAOC,QAAQC,KAAK,EACnC,KAAK,kBAHP,EAKE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,SAAS,OAAO,MAAM,CAAA,EAC1CT,EAAE,cAAc,CACX,GACL,KAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yDAAf,CACGA,EAAE,uBAAuB,EAAG,KAC7B,EAAA,EAAA,KAAC,IAAD,CACE,UAAU,6BACV,KAAK,sCAEJA,EAAE,6BAA6B,CAC/B,CAAA,CACA,GACK,GAEhB"}
@@ -0,0 +1,2 @@
1
+ import{o as e,s as t,u as n}from"./IconBase.es-d5KP98Ac.js";var r=n(t(),1),i=e();function a({as:e,text:t,linkText:n,className:a=``,...o}){return(0,i.jsxs)(`div`,{className:`mt-6 text-center text-base-content/70 text-xs ${a}`,children:[t,` `,(0,r.createElement)(e,{className:`link link-info font-medium`,...o},n)]})}export{a as t};
2
+ //# sourceMappingURL=footer-link-Ib1Hd-fr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footer-link-Ib1Hd-fr.js","names":[],"sources":["../../../frontend/src/components/auth/footer-link.tsx"],"sourcesContent":["import { createElement, type ElementType } from 'react';\n\ntype FooterLinkProps<C extends ElementType> = {\n as: C;\n text: string;\n linkText: string;\n className?: string;\n} & Record<string, unknown>;\n\nexport function FooterLink<C extends ElementType>({\n as: Component,\n text,\n linkText,\n className = '',\n ...linkProps\n}: FooterLinkProps<C>) {\n return (\n <div\n className={`mt-6 text-center text-base-content/70 text-xs ${className}`}\n >\n {text}{' '}\n {createElement(\n Component,\n { className: 'link link-info font-medium', ...linkProps },\n linkText,\n )}\n </div>\n );\n}\n"],"mappings":"iFASA,SAAgB,EAAkC,CAChD,GAAI,EACJ,OACA,WACA,YAAY,GACZ,GAAG,GACkB,CACrB,OACE,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,iDAAiD,aAD9D,CAGG,EAAM,wBAEL,EACA,CAAE,UAAW,6BAA8B,GAAG,CAAU,EACxD,CACF,CACG,GAET"}
@@ -0,0 +1,2 @@
1
+ import{N as e}from"./index-CsT6OVnP.js";var t=e;export{t as errorComponent};
2
+ //# sourceMappingURL=forgot-SSKfXB7c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forgot-SSKfXB7c.js","names":["RouteErrorFallback","ForgotPasswordFormValues","email","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/password/forgot/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { CheckCircleIcon, EnvelopeSimpleIcon } from '@phosphor-icons/react';\nimport { useMutation } from '@tanstack/react-query';\nimport { createFileRoute, Link, redirect } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FooterLink } from '#frontend/components/auth/footer-link.tsx';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { forgotPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nexport const Route = createFileRoute('/password/forgot/')({\n component: ForgotPassword,\n errorComponent: RouteErrorFallback,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config?.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype ForgotPasswordFormValues = {\n email: string;\n};\n\nfunction ForgotPassword() {\n const { t } = useTranslation();\n const [emailSent, setEmailSent] = useState(false);\n const [submittedEmail, setSubmittedEmail] = useState('');\n\n const forgotPasswordSchema = useMemo(\n () =>\n z.object({\n email: z.email({ error: t('validation.email.invalid') }),\n }),\n [t],\n );\n\n const forgotPasswordMutation = useMutation({\n ...forgotPasswordMutationOptions,\n onSuccess: () => {\n setEmailSent(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ForgotPasswordFormValues>({\n defaultValues: {\n email: '',\n },\n resolver: standardSchemaResolver(forgotPasswordSchema),\n });\n\n const onSubmit = async (values: ForgotPasswordFormValues) => {\n try {\n setSubmittedEmail(values.email);\n await forgotPasswordMutation.mutateAsync(values);\n } catch (error) {\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'USER_NOT_EDITABLE'\n ) {\n setError('email', {\n type: 'manual',\n message: t('forgotPassword.error.notEditable'),\n });\n } else {\n setEmailSent(true);\n }\n }\n };\n\n if (emailSent) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('forgotPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('forgotPassword.success.description', {\n email: submittedEmail,\n })}\n title={t('forgotPassword.success.subtitle')}\n />\n\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n {t('forgotPassword.success.checkSpam')}\n </Alert>\n\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('forgotPassword.backToLogin')}\n </Link>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('forgotPassword.subtitle')}\n title={t('forgotPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n autoComplete=\"email\"\n error={errors.email}\n icon={EnvelopeSimpleIcon}\n placeholder={t('forgotPassword.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={forgotPasswordMutation.isPending}\n pendingText={t('forgotPassword.submitting')}\n >\n {t('forgotPassword.submit')}\n </SubmitButton>\n </form>\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n text={t('forgotPassword.footer.rememberedPassword')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"wCAqCE,IAAAG,EAxBOH"}
@@ -0,0 +1,2 @@
1
+ import{o as e,r as t,s as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{f as i}from"./use-theme-cVUDAjtt.js";import{t as a}from"./useMutation-DVMopbtG.js";import{t as o}from"./CheckCircle.es-MnJIACCe.js";import{t as s}from"./page-layout-C475gs09.js";import{t as c}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{i as l,o as u}from"./zod-BItJDQBQ.js";import{t as d}from"./page-header-BYMFSGfT.js";import{t as f}from"./alert-CSXqgDVi.js";import{r as p,t as m}from"./standard-schema-o4V-s4uY.js";import{t as h}from"./footer-link-Ib1Hd-fr.js";import{t as g}from"./icon-input-8iU7PNzd.js";import{t as _}from"./submit-button-Xx6DwLyh.js";import{t as v}from"./password-reset-XZJTgJi3.js";var y=r(n()),b=e();function x(){let{t:e}=t(),[n,r]=(0,y.useState)(!1),[x,S]=(0,y.useState)(``),C=(0,y.useMemo)(()=>u({email:l({error:e(`validation.email.invalid`)})}),[e]),w=a({...v,onSuccess:()=>{r(!0)}}),{register:T,setError:E,handleSubmit:D,formState:{errors:O}}=p({defaultValues:{email:``},resolver:m(C)});return n?(0,b.jsxs)(s,{cardPadding:!0,maxWidth:`100`,children:[(0,b.jsx)(f,{className:`mb-4`,icon:o,type:`success`,children:e(`forgotPassword.success.title`)}),(0,b.jsx)(d,{subtitle:e(`forgotPassword.success.description`,{email:x}),title:e(`forgotPassword.success.subtitle`)}),(0,b.jsx)(f,{className:`mb-4`,icon:c,type:`info`,children:e(`forgotPassword.success.checkSpam`)}),(0,b.jsx)(i,{className:`btn btn-block h-10 font-semibold text-[14px]`,to:`/login`,children:e(`forgotPassword.backToLogin`)})]}):(0,b.jsxs)(s,{cardPadding:!0,maxWidth:`100`,children:[(0,b.jsx)(d,{subtitle:e(`forgotPassword.subtitle`),title:e(`forgotPassword.title`)}),(0,b.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:D(async t=>{try{S(t.email),await w.mutateAsync(t)}catch(t){t&&typeof t==`object`&&`code`in t&&t.code===`USER_NOT_EDITABLE`?E(`email`,{type:`manual`,message:e(`forgotPassword.error.notEditable`)}):r(!0)}}),children:[(0,b.jsx)(g,{autoComplete:`email`,error:O.email,icon:c,placeholder:e(`forgotPassword.email.placeholder`),...T(`email`),type:`email`}),(0,b.jsx)(_,{className:`mt-2`,isPending:w.isPending,pendingText:e(`forgotPassword.submitting`),children:e(`forgotPassword.submit`)})]}),(0,b.jsx)(h,{as:i,linkText:e(`register.link.login`),text:e(`forgotPassword.footer.rememberedPassword`),to:`/login`})]})}export{x as component};
2
+ //# sourceMappingURL=forgot-x-UDyHXT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forgot-x-UDyHXT.js","names":["standardSchemaResolver","CheckCircleIcon","EnvelopeSimpleIcon","useMutation","Link","useMemo","useState","useForm","useTranslation","z","FooterLink","IconInput","PageHeader","SubmitButton","Alert","PageLayout","forgotPasswordMutationOptions","ForgotPasswordFormValues","email","ForgotPassword","t","emailSent","setEmailSent","submittedEmail","setSubmittedEmail","forgotPasswordSchema","object","error","forgotPasswordMutation","onSuccess","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","code","type","message","isPending","component"],"sources":["../../../frontend/src/routes/password/forgot/index.tsx?tsr-split=component"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { CheckCircleIcon, EnvelopeSimpleIcon } from '@phosphor-icons/react';\nimport { useMutation } from '@tanstack/react-query';\nimport { createFileRoute, Link, redirect } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FooterLink } from '#frontend/components/auth/footer-link.tsx';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { forgotPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nexport const Route = createFileRoute('/password/forgot/')({\n component: ForgotPassword,\n errorComponent: RouteErrorFallback,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config?.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype ForgotPasswordFormValues = {\n email: string;\n};\n\nfunction ForgotPassword() {\n const { t } = useTranslation();\n const [emailSent, setEmailSent] = useState(false);\n const [submittedEmail, setSubmittedEmail] = useState('');\n\n const forgotPasswordSchema = useMemo(\n () =>\n z.object({\n email: z.email({ error: t('validation.email.invalid') }),\n }),\n [t],\n );\n\n const forgotPasswordMutation = useMutation({\n ...forgotPasswordMutationOptions,\n onSuccess: () => {\n setEmailSent(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ForgotPasswordFormValues>({\n defaultValues: {\n email: '',\n },\n resolver: standardSchemaResolver(forgotPasswordSchema),\n });\n\n const onSubmit = async (values: ForgotPasswordFormValues) => {\n try {\n setSubmittedEmail(values.email);\n await forgotPasswordMutation.mutateAsync(values);\n } catch (error) {\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'USER_NOT_EDITABLE'\n ) {\n setError('email', {\n type: 'manual',\n message: t('forgotPassword.error.notEditable'),\n });\n } else {\n setEmailSent(true);\n }\n }\n };\n\n if (emailSent) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('forgotPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('forgotPassword.success.description', {\n email: submittedEmail,\n })}\n title={t('forgotPassword.success.subtitle')}\n />\n\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n {t('forgotPassword.success.checkSpam')}\n </Alert>\n\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('forgotPassword.backToLogin')}\n </Link>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('forgotPassword.subtitle')}\n title={t('forgotPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n autoComplete=\"email\"\n error={errors.email}\n icon={EnvelopeSimpleIcon}\n placeholder={t('forgotPassword.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={forgotPasswordMutation.isPending}\n pendingText={t('forgotPassword.submitting')}\n >\n {t('forgotPassword.submit')}\n </SubmitButton>\n </form>\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n text={t('forgotPassword.footer.rememberedPassword')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"2rBAuCA,SAASmB,GAAiB,CACxB,GAAM,CAAEC,KAAMZ,EAAe,EACvB,CAACa,EAAWC,IAAAA,EAAAA,EAAAA,UAAyB,EAAK,EAC1C,CAACC,EAAgBC,IAAAA,EAAAA,EAAAA,UAA8B,EAAE,EAEjDC,GAAAA,EAAAA,EAAAA,aAEFhB,EAAS,CACPS,MAAOT,EAAQ,CAAEkB,MAAOP,EAAE,0BAA0B,CAAE,CAAC,CACzD,CAAC,EACH,CAACA,CAAC,CACJ,EAEMQ,EAAyBzB,EAAY,CACzC,GAAGa,EACHa,cAAiB,CACfP,EAAa,EAAI,CACnB,CACF,CAAC,EAEK,CACJQ,WACAC,WACAC,eACAC,UAAW,CAAEC,WACX3B,EAAkC,CACpC4B,cAAe,CACbjB,MAAO,EACT,EACAkB,SAAUpC,EAAuByB,CAAoB,CACvD,CAAC,EAmDD,OA5BIJ,GAEA,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMpB,EAAiB,KAAK,mBACjDmB,EAAE,8BAA8B,CAC5B,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,qCAAsC,CAChDF,MAAOK,CACT,CAAC,EACD,MAAOH,EAAE,iCAAiC,CAAE,CAAA,GAG9C,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMlB,EAAoB,KAAK,gBACpDkB,EAAE,kCAAkC,CAChC,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,+CACV,GAAG,kBAEFA,EAAE,4BAA4B,CAC3B,CAAA,CACI,KAKd,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,yBAAyB,EACrC,MAAOA,EAAE,sBAAsB,CAAE,CAAA,GAGnC,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,sBAAsB,SAAUY,EAAaK,KAxDzCC,IAAqC,CAC3D,GAAI,CACFd,EAAkBc,EAAOpB,KAAK,EAC9B,MAAMU,EAAuBW,YAAYD,CAAM,CACjD,OAASX,EAAO,CAEZA,GACA,OAAOA,GAAU,UACjB,SAAUA,GACVA,EAAMa,OAAS,oBAEfT,EAAS,QAAS,CAChBU,KAAM,SACNC,QAAStB,EAAE,kCAAkC,CAC/C,CAAC,EAEDE,EAAa,EAAI,CAErB,CACF,CAqCyE,WAArE,EACE,EAAA,EAAA,KAAC,EAAD,CACE,aAAa,QACb,MAAOY,EAAOhB,MACd,KAAMhB,EACN,YAAakB,EAAE,kCAAkC,EACjD,GAAIU,EAAS,OAAO,EACpB,KAAK,OAAO,CAAA,GAGd,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,OACV,UAAWF,EAAuBe,UAClC,YAAavB,EAAE,2BAA2B,WAEzCA,EAAE,uBAAuB,CACd,CAAA,CACV,KAEN,EAAA,EAAA,KAAC,EAAD,CACE,GAAIhB,EACJ,SAAUgB,EAAE,qBAAqB,EACjC,KAAMA,EAAE,0CAA0C,EAClD,GAAG,QAAQ,CAAA,CAEH,GAEhB"}
@@ -0,0 +1,2 @@
1
+ import{o as e}from"./IconBase.es-d5KP98Ac.js";var t=e(),n=({icon:e,type:n=`text`,placeholder:r,autoComplete:i,error:a,className:o=``,ref:s,...c})=>(0,t.jsxs)(`div`,{className:o,children:[(0,t.jsxs)(`label`,{className:`input input-bordered flex items-center gap-2 ${a?`input-error`:``}`,"data-testid":a?`input-error-wrapper`:void 0,children:[(0,t.jsx)(e,{className:`size-5 opacity-70`}),(0,t.jsx)(`input`,{autoComplete:i,className:`grow`,placeholder:r,ref:s,type:n,...c})]}),a&&(0,t.jsx)(`p`,{className:`mt-1 text-error text-sm`,"data-testid":`field-error`,children:a.message})]});export{n as t};
2
+ //# sourceMappingURL=icon-input-8iU7PNzd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-input-8iU7PNzd.js","names":[],"sources":["../../../frontend/src/components/auth/icon-input.tsx"],"sourcesContent":["import type { Icon } from '@phosphor-icons/react';\nimport type { FieldError } from 'react-hook-form';\n\ntype IconInputProps = {\n icon: Icon;\n type?: 'email' | 'password' | 'text';\n placeholder: string;\n autoComplete?: string;\n error?: FieldError;\n className?: string;\n ref?: React.Ref<HTMLInputElement>;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'className'>;\n\nexport const IconInput = ({\n icon: IconComponent,\n type = 'text',\n placeholder,\n autoComplete,\n error,\n className = '',\n ref,\n ...props\n}: IconInputProps) => {\n return (\n <div className={className}>\n <label\n className={`input input-bordered flex items-center gap-2 ${\n error ? 'input-error' : ''\n }`}\n data-testid={error ? 'input-error-wrapper' : undefined}\n >\n <IconComponent className=\"size-5 opacity-70\" />\n <input\n autoComplete={autoComplete}\n className=\"grow\"\n placeholder={placeholder}\n ref={ref}\n type={type}\n {...props}\n />\n </label>\n {error && (\n <p className=\"mt-1 text-error text-sm\" data-testid=\"field-error\">\n {error.message}\n </p>\n )}\n </div>\n );\n};\n"],"mappings":"wDAaa,GAAa,CACxB,KAAM,EACN,OAAO,OACP,cACA,eACA,QACA,YAAY,GACZ,MACA,GAAG,MAGD,EAAA,EAAA,MAAC,MAAD,CAAgB,qBAAhB,EACE,EAAA,EAAA,MAAC,QAAD,CACE,UAAW,gDACT,EAAQ,cAAgB,KAE1B,cAAa,EAAQ,sBAAwB,IAAA,YAJ/C,EAME,EAAA,EAAA,KAAC,EAAD,CAAe,UAAU,mBAAqB,CAAA,GAC9C,EAAA,EAAA,KAAC,QAAD,CACgB,eACd,UAAU,OACG,cACR,MACC,OACN,GAAI,CACL,CAAA,CACI,IACN,IACC,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,0BAA0B,cAAY,uBAChD,EAAM,OACN,CAAA,CAEF"}