@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.
- package/dist/entities/oauth-client.entity.d.ts +27 -0
- package/dist/entities/oauth-client.entity.d.ts.map +1 -1
- package/dist/entities/oauth-code.entity.d.ts +27 -0
- package/dist/entities/oauth-code.entity.d.ts.map +1 -1
- package/dist/entities/oauth-device-code.entity.d.ts +27 -0
- package/dist/entities/oauth-device-code.entity.d.ts.map +1 -1
- package/dist/entities/oauth-device-code.entity.js +12 -0
- package/dist/entities/oauth-device-code.entity.js.map +1 -1
- package/dist/entities/revoked-token.entity.d.ts +27 -0
- package/dist/entities/revoked-token.entity.d.ts.map +1 -1
- package/dist/entities/user-consent.entity.d.ts +27 -0
- package/dist/entities/user-consent.entity.d.ts.map +1 -1
- package/dist/entrypoints/app.d.ts +325 -16
- package/dist/entrypoints/app.d.ts.map +1 -1
- package/dist/entrypoints/app.js +33 -7
- package/dist/entrypoints/app.js.map +1 -1
- package/dist/entrypoints/database/postgres/compiled-functions.d.ts +16 -7
- package/dist/entrypoints/database/postgres/compiled-functions.d.ts.map +1 -1
- package/dist/entrypoints/database/postgres/compiled-functions.js +183 -39
- package/dist/entrypoints/database/postgres/compiled-functions.js.map +1 -1
- package/dist/entrypoints/database/sqlite/compiled-functions.d.ts +16 -7
- package/dist/entrypoints/database/sqlite/compiled-functions.d.ts.map +1 -1
- package/dist/entrypoints/database/sqlite/compiled-functions.js +183 -39
- package/dist/entrypoints/database/sqlite/compiled-functions.js.map +1 -1
- package/dist/lib/config/admin.d.ts +9 -0
- package/dist/lib/config/admin.d.ts.map +1 -0
- package/dist/lib/config/admin.js +13 -0
- package/dist/lib/config/admin.js.map +1 -0
- package/dist/lib/config/auth.d.ts +85 -0
- package/dist/lib/config/auth.d.ts.map +1 -1
- package/dist/lib/config/auth.js +61 -0
- package/dist/lib/config/auth.js.map +1 -1
- package/dist/lib/config/client.d.ts +20 -0
- package/dist/lib/config/client.d.ts.map +1 -1
- package/dist/lib/config/client.js +14 -0
- package/dist/lib/config/client.js.map +1 -1
- package/dist/lib/config/index.d.ts +2 -0
- package/dist/lib/config/index.d.ts.map +1 -1
- package/dist/lib/config/index.js +1 -0
- package/dist/lib/config/index.js.map +1 -1
- package/dist/lib/config/resolved.d.ts +40 -0
- package/dist/lib/config/resolved.d.ts.map +1 -1
- package/dist/lib/config/resolved.js +2 -0
- package/dist/lib/config/resolved.js.map +1 -1
- package/dist/lib/config/server.d.ts.map +1 -1
- package/dist/lib/config/server.js +12 -0
- package/dist/lib/config/server.js.map +1 -1
- package/dist/lib/swagger-tags.d.ts +1 -0
- package/dist/lib/swagger-tags.d.ts.map +1 -1
- package/dist/lib/swagger-tags.js +1 -0
- package/dist/lib/swagger-tags.js.map +1 -1
- package/dist/middleware/auth.d.ts +3 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +26 -0
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/session.d.ts +33 -1
- package/dist/middleware/session.d.ts.map +1 -1
- package/dist/middleware/session.js +84 -3
- package/dist/middleware/session.js.map +1 -1
- package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.d.ts +6 -0
- package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.d.ts.map +1 -0
- package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.js +11 -0
- package/dist/migrations/postgres/Migration20260624190500_add_oauth_device_denied_at.js.map +1 -0
- package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.d.ts +6 -0
- package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.d.ts.map +1 -0
- package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.js +14 -0
- package/dist/migrations/postgres/Migration20260624223000_add_oauth_device_poll_state.js.map +1 -0
- package/dist/migrations/postgres/index.d.ts.map +1 -1
- package/dist/migrations/postgres/index.js +4 -0
- package/dist/migrations/postgres/index.js.map +1 -1
- package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.d.ts +6 -0
- package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.d.ts.map +1 -0
- package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.js +10 -0
- package/dist/migrations/sqlite/Migration20260624190500_add_oauth_device_denied_at.js.map +1 -0
- package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.d.ts +6 -0
- package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.d.ts.map +1 -0
- package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.js +12 -0
- package/dist/migrations/sqlite/Migration20260624223000_add_oauth_device_poll_state.js.map +1 -0
- package/dist/migrations/sqlite/index.d.ts.map +1 -1
- package/dist/migrations/sqlite/index.js +4 -0
- package/dist/migrations/sqlite/index.js.map +1 -1
- package/dist/repositories/oauth-device-code.repository.d.ts +4 -0
- package/dist/repositories/oauth-device-code.repository.d.ts.map +1 -1
- package/dist/repositories/oauth-device-code.repository.js +19 -0
- package/dist/repositories/oauth-device-code.repository.js.map +1 -1
- package/dist/repositories/user.repository.d.ts +4 -2
- package/dist/repositories/user.repository.d.ts.map +1 -1
- package/dist/repositories/user.repository.js +11 -7
- package/dist/repositories/user.repository.js.map +1 -1
- package/dist/routes/.well-known/openid-configuration/get.d.ts.map +1 -1
- package/dist/routes/.well-known/openid-configuration/get.js +4 -0
- package/dist/routes/.well-known/openid-configuration/get.js.map +1 -1
- package/dist/routes/api/admin/index.d.ts +185 -0
- package/dist/routes/api/admin/index.d.ts.map +1 -0
- package/dist/routes/api/admin/index.js +13 -0
- package/dist/routes/api/admin/index.js.map +1 -0
- package/dist/routes/api/admin/me/get.d.ts +26 -0
- package/dist/routes/api/admin/me/get.d.ts.map +1 -0
- package/dist/routes/api/admin/me/get.js +29 -0
- package/dist/routes/api/admin/me/get.js.map +1 -0
- package/dist/routes/api/admin/users/index.d.ts +162 -0
- package/dist/routes/api/admin/users/index.d.ts.map +1 -0
- package/dist/routes/api/admin/users/index.js +166 -0
- package/dist/routes/api/admin/users/index.js.map +1 -0
- package/dist/routes/api/auth/accounts/get.d.ts +28 -0
- package/dist/routes/api/auth/accounts/get.d.ts.map +1 -0
- package/dist/routes/api/auth/accounts/get.js +47 -0
- package/dist/routes/api/auth/accounts/get.js.map +1 -0
- package/dist/routes/api/auth/accounts/remove.post.d.ts +30 -0
- package/dist/routes/api/auth/accounts/remove.post.d.ts.map +1 -0
- package/dist/routes/api/auth/accounts/remove.post.js +30 -0
- package/dist/routes/api/auth/accounts/remove.post.js.map +1 -0
- package/dist/routes/api/auth/accounts/select.post.d.ts +31 -0
- package/dist/routes/api/auth/accounts/select.post.d.ts.map +1 -0
- package/dist/routes/api/auth/accounts/select.post.js +26 -0
- package/dist/routes/api/auth/accounts/select.post.js.map +1 -0
- package/dist/routes/api/auth/email/verify/post.d.ts +1 -0
- package/dist/routes/api/auth/email/verify/post.d.ts.map +1 -1
- package/dist/routes/api/auth/index.d.ts +86 -0
- package/dist/routes/api/auth/index.d.ts.map +1 -1
- package/dist/routes/api/auth/index.js +6 -0
- package/dist/routes/api/auth/index.js.map +1 -1
- package/dist/routes/api/auth/login/post.d.ts +1 -0
- package/dist/routes/api/auth/login/post.d.ts.map +1 -1
- package/dist/routes/api/auth/login/post.js +15 -16
- package/dist/routes/api/auth/login/post.js.map +1 -1
- package/dist/routes/api/auth/passkey/verify/post.d.ts +1 -0
- package/dist/routes/api/auth/passkey/verify/post.d.ts.map +1 -1
- package/dist/routes/api/auth/register/post.d.ts +1 -0
- package/dist/routes/api/auth/register/post.d.ts.map +1 -1
- package/dist/routes/api/auth/totp/recovery/verify/post.d.ts +1 -0
- package/dist/routes/api/auth/totp/recovery/verify/post.d.ts.map +1 -1
- package/dist/routes/api/auth/totp/verify/post.d.ts +1 -0
- package/dist/routes/api/auth/totp/verify/post.d.ts.map +1 -1
- package/dist/routes/api/config/get.d.ts +3 -0
- package/dist/routes/api/config/get.d.ts.map +1 -1
- package/dist/routes/api/config/get.js +7 -1
- package/dist/routes/api/config/get.js.map +1 -1
- package/dist/routes/api/config/index.d.ts +3 -0
- package/dist/routes/api/config/index.d.ts.map +1 -1
- package/dist/routes/api/consent/index.d.ts +10 -0
- package/dist/routes/api/consent/index.d.ts.map +1 -1
- package/dist/routes/api/consent/post.d.ts +10 -0
- package/dist/routes/api/consent/post.d.ts.map +1 -1
- package/dist/routes/api/consent/post.js +52 -1
- package/dist/routes/api/consent/post.js.map +1 -1
- package/dist/routes/api/index.d.ts +310 -26
- package/dist/routes/api/index.d.ts.map +1 -1
- package/dist/routes/api/index.js +2 -0
- package/dist/routes/api/index.js.map +1 -1
- package/dist/routes/api/user/index.d.ts +3 -0
- package/dist/routes/api/user/index.d.ts.map +1 -1
- package/dist/routes/api/user/passkeys/register/verify/post.d.ts +1 -0
- package/dist/routes/api/user/passkeys/register/verify/post.d.ts.map +1 -1
- package/dist/routes/api/user/session/get.d.ts +1 -0
- package/dist/routes/api/user/session/get.d.ts.map +1 -1
- package/dist/routes/api/user/totp/confirm/post.d.ts +1 -0
- package/dist/routes/api/user/totp/confirm/post.d.ts.map +1 -1
- package/dist/routes/index.d.ts +303 -16
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/oauth/.well-known/openid-configuration/get.d.ts.map +1 -1
- package/dist/routes/oauth/.well-known/openid-configuration/get.js +1 -0
- package/dist/routes/oauth/.well-known/openid-configuration/get.js.map +1 -1
- package/dist/routes/oauth/authorize/get.d.ts +2 -0
- package/dist/routes/oauth/authorize/get.d.ts.map +1 -1
- package/dist/routes/oauth/authorize/get.js +12 -1
- package/dist/routes/oauth/authorize/get.js.map +1 -1
- package/dist/routes/oauth/client-auth.js +1 -1
- package/dist/routes/oauth/client-auth.js.map +1 -1
- package/dist/routes/oauth/cors.d.ts.map +1 -1
- package/dist/routes/oauth/cors.js +8 -3
- package/dist/routes/oauth/cors.js.map +1 -1
- package/dist/routes/oauth/device/get-post.d.ts +2 -1
- package/dist/routes/oauth/device/get-post.d.ts.map +1 -1
- package/dist/routes/oauth/device/get-post.js +15 -9
- package/dist/routes/oauth/device/get-post.js.map +1 -1
- package/dist/routes/oauth/device-authorization/post.d.ts.map +1 -1
- package/dist/routes/oauth/device-authorization/post.js +2 -0
- package/dist/routes/oauth/device-authorization/post.js.map +1 -1
- package/dist/routes/oauth/end-session/get.d.ts.map +1 -1
- package/dist/routes/oauth/end-session/get.js +17 -8
- package/dist/routes/oauth/end-session/get.js.map +1 -1
- package/dist/routes/oauth/index.d.ts +5 -2
- package/dist/routes/oauth/index.d.ts.map +1 -1
- package/dist/routes/oauth/revoke/post.d.ts.map +1 -1
- package/dist/routes/oauth/revoke/post.js +2 -0
- package/dist/routes/oauth/revoke/post.js.map +1 -1
- package/dist/routes/oauth/token/post.d.ts +1 -1
- package/dist/routes/oauth/token/post.d.ts.map +1 -1
- package/dist/routes/oauth/token/post.js +10 -6
- package/dist/routes/oauth/token/post.js.map +1 -1
- package/dist/routes/oauth/userinfo/get.d.ts.map +1 -1
- package/dist/routes/oauth/userinfo/get.js +12 -6
- package/dist/routes/oauth/userinfo/get.js.map +1 -1
- package/dist/schemas/error.d.ts +56 -6
- package/dist/schemas/error.d.ts.map +1 -1
- package/dist/schemas/error.js +4 -2
- package/dist/schemas/error.js.map +1 -1
- package/dist/schemas/field.d.ts +1 -4
- package/dist/schemas/field.d.ts.map +1 -1
- package/dist/schemas/field.js +3 -1
- package/dist/schemas/field.js.map +1 -1
- package/dist/schemas/response.d.ts +96 -0
- package/dist/schemas/response.d.ts.map +1 -1
- package/dist/schemas/response.js +29 -0
- package/dist/schemas/response.js.map +1 -1
- package/dist/services/account-selection.service.d.ts +39 -0
- package/dist/services/account-selection.service.d.ts.map +1 -0
- package/dist/services/account-selection.service.js +77 -0
- package/dist/services/account-selection.service.js.map +1 -0
- package/dist/services/container.d.ts +22 -0
- package/dist/services/container.d.ts.map +1 -1
- package/dist/services/jwt.service.js +3 -3
- package/dist/services/jwt.service.js.map +1 -1
- package/dist/services/oauth-authorize.service.d.ts +24 -1
- package/dist/services/oauth-authorize.service.d.ts.map +1 -1
- package/dist/services/oauth-authorize.service.js +232 -8
- package/dist/services/oauth-authorize.service.js.map +1 -1
- package/dist/services/oauth-token.service.d.ts +2 -3
- package/dist/services/oauth-token.service.d.ts.map +1 -1
- package/dist/services/oauth-token.service.js +18 -10
- package/dist/services/oauth-token.service.js.map +1 -1
- package/dist/services/user.service.d.ts +28 -1
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +104 -0
- package/dist/services/user.service.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/2fa-BoyBKrjD.js +2 -0
- package/public/assets/2fa-BoyBKrjD.js.map +1 -0
- package/public/assets/2fa-DfWvDjDW.js +2 -0
- package/public/assets/2fa-DfWvDjDW.js.map +1 -0
- package/public/assets/2fa-IkQlgUP0.js +2 -0
- package/public/assets/2fa-IkQlgUP0.js.map +1 -0
- package/public/assets/2fa-SSKfXB7c.js +2 -0
- package/public/assets/2fa-SSKfXB7c.js.map +1 -0
- package/public/assets/CheckCircle.es-MnJIACCe.js +2 -0
- package/public/assets/CheckCircle.es-MnJIACCe.js.map +1 -0
- package/public/assets/EnvelopeSimple.es-BZ7u3LYh.js +2 -0
- package/public/assets/EnvelopeSimple.es-BZ7u3LYh.js.map +1 -0
- package/public/assets/Fingerprint.es-CW755VWD.js +2 -0
- package/public/assets/Fingerprint.es-CW755VWD.js.map +1 -0
- package/public/assets/IconBase.es-d5KP98Ac.js +2 -0
- package/public/assets/IconBase.es-d5KP98Ac.js.map +1 -0
- package/public/assets/Key.es-l5aSxw0I.js +2 -0
- package/public/assets/Key.es-l5aSxw0I.js.map +1 -0
- package/public/assets/Link.es-B-IJS4Q5.js +2 -0
- package/public/assets/Link.es-B-IJS4Q5.js.map +1 -0
- package/public/assets/Lock.es-Cb_uwQly.js +2 -0
- package/public/assets/Lock.es-Cb_uwQly.js.map +1 -0
- package/public/assets/ShieldCheck.es-CscPsYbC.js +2 -0
- package/public/assets/ShieldCheck.es-CscPsYbC.js.map +1 -0
- package/public/assets/Trash.es-BepW9BwV.js +2 -0
- package/public/assets/Trash.es-BepW9BwV.js.map +1 -0
- package/public/assets/Warning.es-BPpZIJYZ.js +2 -0
- package/public/assets/Warning.es-BPpZIJYZ.js.map +1 -0
- package/public/assets/X.es-IwdB4hWT.js +2 -0
- package/public/assets/X.es-IwdB4hWT.js.map +1 -0
- package/public/assets/admin-D2CMlWzS.js +2 -0
- package/public/assets/admin-D2CMlWzS.js.map +1 -0
- package/public/assets/admin-users-CTAQJl7w.js +2 -0
- package/public/assets/admin-users-CTAQJl7w.js.map +1 -0
- package/public/assets/alert-CSXqgDVi.js +2 -0
- package/public/assets/alert-CSXqgDVi.js.map +1 -0
- package/public/assets/consent-C5Qo0iLd.js +2 -0
- package/public/assets/consent-C5Qo0iLd.js.map +1 -0
- package/public/assets/consent-DwuWkp63.js +2 -0
- package/public/assets/consent-DwuWkp63.js.map +1 -0
- package/public/assets/email-CIttZRBe.js +2 -0
- package/public/assets/email-CIttZRBe.js.map +1 -0
- package/public/assets/email-SSKfXB7c.js +2 -0
- package/public/assets/email-SSKfXB7c.js.map +1 -0
- package/public/assets/error-D60wkdWN.js +2 -0
- package/public/assets/error-D60wkdWN.js.map +1 -0
- package/public/assets/footer-link-Ib1Hd-fr.js +2 -0
- package/public/assets/footer-link-Ib1Hd-fr.js.map +1 -0
- package/public/assets/forgot-SSKfXB7c.js +2 -0
- package/public/assets/forgot-SSKfXB7c.js.map +1 -0
- package/public/assets/forgot-x-UDyHXT.js +2 -0
- package/public/assets/forgot-x-UDyHXT.js.map +1 -0
- package/public/assets/icon-input-8iU7PNzd.js +2 -0
- package/public/assets/icon-input-8iU7PNzd.js.map +1 -0
- package/public/assets/index-CsT6OVnP.js +11 -0
- package/public/assets/index-CsT6OVnP.js.map +1 -0
- package/public/assets/index-D6-1JDnX.css +2 -0
- package/public/assets/login-DhbnCudI.js +2 -0
- package/public/assets/login-DhbnCudI.js.map +1 -0
- package/public/assets/login-SSKfXB7c.js +2 -0
- package/public/assets/login-SSKfXB7c.js.map +1 -0
- package/public/assets/modal-BjnpKlXn.js +2 -0
- package/public/assets/modal-BjnpKlXn.js.map +1 -0
- package/public/assets/mutationOptions-Dfvzj6n2.js +2 -0
- package/public/assets/mutationOptions-Dfvzj6n2.js.map +1 -0
- package/public/assets/page-header-BYMFSGfT.js +2 -0
- package/public/assets/page-header-BYMFSGfT.js.map +1 -0
- package/public/assets/page-layout-C475gs09.js +2 -0
- package/public/assets/page-layout-C475gs09.js.map +1 -0
- package/public/assets/passkey-BdISbWr7.js +2 -0
- package/public/assets/passkey-BdISbWr7.js.map +1 -0
- package/public/assets/passkey-Bv7zPLAZ.js +2 -0
- package/public/assets/passkey-Bv7zPLAZ.js.map +1 -0
- package/public/assets/passkey-e6uvApHa.js +2 -0
- package/public/assets/passkey-e6uvApHa.js.map +1 -0
- package/public/assets/password-CkeV4qxb.js +2 -0
- package/public/assets/password-CkeV4qxb.js.map +1 -0
- package/public/assets/password-SSKfXB7c.js +2 -0
- package/public/assets/password-SSKfXB7c.js.map +1 -0
- package/public/assets/password-reset-XZJTgJi3.js +2 -0
- package/public/assets/password-reset-XZJTgJi3.js.map +1 -0
- package/public/assets/pin-input-BM1UizHr.js +2 -0
- package/public/assets/pin-input-BM1UizHr.js.map +1 -0
- package/public/assets/profile-D2cuVYgE.js +2 -0
- package/public/assets/profile-D2cuVYgE.js.map +1 -0
- package/public/assets/profile-TKdT20x5.js +2 -0
- package/public/assets/profile-TKdT20x5.js.map +1 -0
- package/public/assets/promise-OpBtq8tG.js +2 -0
- package/public/assets/promise-OpBtq8tG.js.map +1 -0
- package/public/assets/recovery-DM8h2gbb.js +2 -0
- package/public/assets/recovery-DM8h2gbb.js.map +1 -0
- package/public/assets/register-SSKfXB7c.js +2 -0
- package/public/assets/register-SSKfXB7c.js.map +1 -0
- package/public/assets/register-vWW_43cD.js +2 -0
- package/public/assets/register-vWW_43cD.js.map +1 -0
- package/public/assets/reset-CgACYrdp.js +2 -0
- package/public/assets/reset-CgACYrdp.js.map +1 -0
- package/public/assets/reset-SSKfXB7c.js +2 -0
- package/public/assets/reset-SSKfXB7c.js.map +1 -0
- package/public/assets/routes-CAIeH5mq.js +2 -0
- package/public/assets/routes-CAIeH5mq.js.map +1 -0
- package/public/assets/select-BCP5fwfB.js +2 -0
- package/public/assets/select-BCP5fwfB.js.map +1 -0
- package/public/assets/select-SSKfXB7c.js +2 -0
- package/public/assets/select-SSKfXB7c.js.map +1 -0
- package/public/assets/standard-schema-o4V-s4uY.js +2 -0
- package/public/assets/standard-schema-o4V-s4uY.js.map +1 -0
- package/public/assets/submit-button-Xx6DwLyh.js +2 -0
- package/public/assets/submit-button-Xx6DwLyh.js.map +1 -0
- package/public/assets/terms-DPWrbYY2.js +2 -0
- package/public/assets/terms-DPWrbYY2.js.map +1 -0
- package/public/assets/terms-TKdT20x5.js +2 -0
- package/public/assets/terms-TKdT20x5.js.map +1 -0
- package/public/assets/terms-checkbox-list-CdrbHxiF.js +2 -0
- package/public/assets/terms-checkbox-list-CdrbHxiF.js.map +1 -0
- package/public/assets/totp-CKZ6N1NS.js +2 -0
- package/public/assets/totp-CKZ6N1NS.js.map +1 -0
- package/public/assets/totp-D-PVOsGQ.js +2 -0
- package/public/assets/totp-D-PVOsGQ.js.map +1 -0
- package/public/assets/totp-NlqqRp4a.js +2 -0
- package/public/assets/totp-NlqqRp4a.js.map +1 -0
- package/public/assets/use-theme-cVUDAjtt.js +2 -0
- package/public/assets/use-theme-cVUDAjtt.js.map +1 -0
- package/public/assets/use-totp-setup-BH75uEbE.js +3 -0
- package/public/assets/use-totp-setup-BH75uEbE.js.map +1 -0
- package/public/assets/useMutation-DVMopbtG.js +2 -0
- package/public/assets/useMutation-DVMopbtG.js.map +1 -0
- package/public/assets/users-B7ofdp72.js +2 -0
- package/public/assets/users-B7ofdp72.js.map +1 -0
- package/public/assets/zod-BItJDQBQ.js +66 -0
- package/public/assets/zod-BItJDQBQ.js.map +1 -0
- package/public/index.html +6 -2
- package/public/assets/index-5_9rzim1.css +0 -2
- package/public/assets/index-BTGeW26-.js +0 -75
- package/public/assets/index-BTGeW26-.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-TKdT20x5.js","names":["RouteErrorFallback","PasswordModalType","TotpModalType","PasskeyModalType","ProfileError","props","ErrorComponentProps","window","location","href","errorComponent"],"sources":["../../../frontend/src/routes/profile/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { SignOutIcon, WarningCircleIcon } from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport {\n createFileRoute,\n type ErrorComponentProps,\n redirect,\n useRouter,\n} from '@tanstack/react-router';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { DangerZoneSection } from '#frontend/components/profile/danger-zone-section.tsx';\nimport { LinkedAccountsSection } from '#frontend/components/profile/linked-accounts-section.tsx';\nimport { PasskeySection } from '#frontend/components/profile/passkey-section.tsx';\nimport { PasswordSection } from '#frontend/components/profile/password-section.tsx';\nimport { TotpSection } from '#frontend/components/profile/totp-section.tsx';\nimport { UnlinkOAuthModal } from '#frontend/components/profile/unlink-oauth-modal.tsx';\nimport { UserInfoSection } from '#frontend/components/profile/user-info-section.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { InitialAvatar } from '#frontend/components/ui/initial-avatar.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { ChangePasswordModal } from '#frontend/features/profile/change-password-modal.tsx';\nimport { DeleteAccountModal } from '#frontend/features/profile/delete-account-modal.tsx';\nimport { DisableTotpModal } from '#frontend/features/profile/disable-totp-modal.tsx';\nimport { ManagePasskeysModal } from '#frontend/features/profile/manage-passkeys-modal.tsx';\nimport { RegenerateTotpRecoveryCodesModal } from '#frontend/features/profile/regenerate-totp-recovery-codes-modal.tsx';\nimport { RemovePasswordModal } from '#frontend/features/profile/remove-password-modal.tsx';\nimport { SetPasswordModal } from '#frontend/features/profile/set-password-modal.tsx';\nimport { SetupPasskeyModal } from '#frontend/features/profile/setup-passkey-modal.tsx';\nimport { SetupTotpModal } from '#frontend/features/profile/setup-totp-modal.tsx';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { logoutMutationOptions } from '#frontend/queries/logout.ts';\nimport {\n getOAuthAuthorizeUrl,\n oauthAccountsQueryOptions,\n unlinkOAuthMutationOptions,\n} from '#frontend/queries/oauth.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\n\ntype PasswordModalType = 'set' | 'change' | 'remove' | null;\ntype TotpModalType = 'setup' | 'disable' | 'regenerate' | null;\ntype PasskeyModalType = 'setup' | 'manage' | null;\n\nconst SearchSchema = z.object({\n oauth_error: z.string().optional(),\n oauth_error_description: z.string().optional(),\n});\n\nconst OAUTH_ERROR_I18N_MAP: Record<string, string> = {\n access_denied: 'oauth.error.accessDenied',\n temporarily_unavailable: 'oauth.error.temporarilyUnavailable',\n server_error: 'oauth.error.serverError',\n};\n\nfunction ProfileError(props: ErrorComponentProps) {\n return (\n <RouteErrorFallback\n {...props}\n onUnauthorized={() => {\n window.location.href = '/login';\n }}\n />\n );\n}\n\nexport const Route = createFileRoute('/profile/')({\n component: Profile,\n errorComponent: ProfileError,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n if (!context.user) {\n throw redirect({\n to: '/login',\n });\n }\n },\n loader: async ({ context }) => {\n await Promise.all([\n context.queryClient.ensureQueryData(getSessionQueryOptions),\n context.queryClient.ensureQueryData(oauthAccountsQueryOptions),\n context.queryClient.ensureQueryData(appConfigQueryOptions),\n ]);\n },\n});\n\nfunction Profile() {\n const { t } = useTranslation();\n const router = useRouter();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n\n const oauthError = search.oauth_error;\n const oauthErrorMessage = oauthError\n ? t(OAUTH_ERROR_I18N_MAP[oauthError] ?? 'oauth.error.failed')\n : undefined;\n const [unlinkingProvider, setUnlinkingProvider] = useState<string | null>(\n null,\n );\n const [unlinkModal, setUnlinkModal] = useState<{\n id: string;\n name: string;\n } | null>(null);\n const [passwordModal, setPasswordModal] = useState<PasswordModalType>(null);\n const [totpModal, setTotpModal] = useState<TotpModalType>(null);\n const [passkeyModal, setPasskeyModal] = useState<PasskeyModalType>(null);\n const [showDeleteModal, setShowDeleteModal] = useState(false);\n\n const { data: session } = useSuspenseQuery(getSessionQueryOptions);\n const { data: oauthAccountsData } = useSuspenseQuery(\n oauthAccountsQueryOptions,\n );\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const logoutMutation = useMutation({\n ...logoutMutationOptions,\n onSuccess: async () => {\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: null,\n });\n await tick();\n router.navigate({\n to: '/login',\n });\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const unlinkMutation = useMutation({\n ...unlinkOAuthMutationOptions,\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: oauthAccountsQueryOptions.queryKey,\n });\n },\n onSettled: () => {\n setUnlinkingProvider(null);\n },\n });\n\n const handleUnlinkConfirm = async () => {\n if (!unlinkModal) return;\n setUnlinkingProvider(unlinkModal.id);\n await unlinkMutation.mutateAsync(unlinkModal.id);\n };\n\n // Handle non-authenticated states (should be redirected, but fallback)\n if (!session.user) {\n return null;\n }\n\n const user = session.user;\n const availableProviders = oauthAccountsData.available_providers;\n const hasLinkedOAuth = availableProviders.some((p) => p.linked);\n const isConfigManaged = user.managed_by === 'config';\n\n // Check if TOTP and Passkey are enabled in config\n const passwordAuthMethod = appConfig.auth.password;\n const passkeyAuthMethod = appConfig.auth.passkey;\n const totpEnabled = passwordAuthMethod.totp.enabled;\n const passkeyEnabled = passkeyAuthMethod.enabled;\n\n // Account deletion settings\n const accountDeletionEnabled = appConfig.account_deletion.enabled;\n const retentionPeriod = appConfig.account_deletion.retention;\n\n // Parse retention period to get days for display\n const retentionDays = (() => {\n const match = retentionPeriod.match(/^(\\d+)([dmy])$/);\n if (!match) return 30;\n const value = parseInt(match[1], 10);\n const unit = match[2];\n switch (unit) {\n case 'd':\n return value;\n case 'm':\n return value * 30;\n case 'y':\n return value * 365;\n default:\n return 30;\n }\n })();\n\n // Determine which security sections to show\n const showPasswordSection = true;\n const showTotpSection = !isConfigManaged && totpEnabled;\n const showPasskeySection = !isConfigManaged && passkeyEnabled;\n const showLinkedAccounts = availableProviders.length > 0;\n const hasSecurityOptions =\n showPasswordSection || showTotpSection || showPasskeySection;\n\n return (\n <PageLayout maxWidth=\"xl\" responsivePadding>\n {/* Header */}\n <div className=\"border-base-200 border-b p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-center gap-4\">\n <InitialAvatar email={user.email} size=\"lg\" />\n <div className=\"min-w-0\">\n <h1 className=\"font-bold text-xl\">{t('profile.title')}</h1>\n <p\n className=\"truncate text-base-content/70 text-sm\"\n data-testid=\"profile-user-email\"\n >\n {user.email}\n </p>\n </div>\n </div>\n <button\n className=\"btn btn-ghost btn-sm gap-2\"\n data-testid=\"profile-logout\"\n disabled={logoutMutation.isPending}\n onClick={() => logoutMutation.mutate()}\n type=\"button\"\n >\n {logoutMutation.isPending ? (\n <span className=\"loading loading-spinner loading-sm\" />\n ) : (\n <SignOutIcon className=\"size-4\" weight=\"bold\" />\n )}\n <span className=\"hidden sm:inline\">{t('profile.logout')}</span>\n </button>\n </div>\n </div>\n\n {/* OAuth Error Alert */}\n {oauthErrorMessage && (\n <div className=\"px-6 pt-4\">\n <Alert icon={WarningCircleIcon} type=\"error\">\n {oauthErrorMessage}\n </Alert>\n </div>\n )}\n\n {/* Content - Single Column */}\n <div className=\"space-y-5 p-6\">\n {/* Account Information */}\n {user && <UserInfoSection user={user} />}\n\n {/* Security Options */}\n {hasSecurityOptions && (\n <div className=\"rounded-xl border border-base-200\">\n <div className=\"border-base-200 border-b px-4 py-3\">\n <h2 className=\"font-semibold text-sm\">\n {t('profile.security.title')}\n </h2>\n <p className=\"text-base-content/60 text-xs\">\n {t('profile.security.description')}\n </p>\n </div>\n {showTotpSection && user.totp_recovery_codes_missing && (\n <div\n className=\"border-base-200 border-b px-4 py-3\"\n data-testid=\"profile-totp-recovery-warning\"\n >\n <Alert icon={WarningCircleIcon} type=\"warning\">\n {t('profile.totp.recoveryCodesMissing')}\n </Alert>\n </div>\n )}\n <div className=\"divide-y divide-base-200\">\n {showPasswordSection && (\n <PasswordSection\n hasLinkedOAuth={hasLinkedOAuth}\n hasPassword={user.has_password}\n hasSecondFactorOnly={\n user.has_password &&\n !hasLinkedOAuth &&\n (user.totp_registered || user.passkey_count > 0)\n }\n isConfigManaged={isConfigManaged}\n onOpenModal={setPasswordModal}\n />\n )}\n {showTotpSection && (\n <TotpSection\n onOpenModal={setTotpModal}\n recoveryCodesMissing={user.totp_recovery_codes_missing}\n totpEnabled={user.totp_registered}\n />\n )}\n {showPasskeySection && (\n <PasskeySection\n onOpenModal={setPasskeyModal}\n passkeyCount={user.passkey_count}\n />\n )}\n </div>\n </div>\n )}\n\n {/* Linked OAuth Accounts */}\n {showLinkedAccounts && (\n <LinkedAccountsSection\n getAuthorizeUrl={getOAuthAuthorizeUrl}\n onUnlinkRequest={(provider) =>\n setUnlinkModal({\n id: provider.id,\n name: provider.display_name,\n })\n }\n providers={availableProviders}\n unlinkingProvider={unlinkingProvider}\n />\n )}\n\n {/* Danger Zone */}\n <DangerZoneSection\n isConfigManaged={isConfigManaged}\n isDeletionEnabled={accountDeletionEnabled}\n onDeleteClick={() => setShowDeleteModal(true)}\n />\n </div>\n\n {/* Password Modals */}\n <SetPasswordModal\n isOpen={passwordModal === 'set'}\n onClose={() => setPasswordModal(null)}\n />\n <ChangePasswordModal\n isOpen={passwordModal === 'change'}\n onClose={() => setPasswordModal(null)}\n />\n <RemovePasswordModal\n isOpen={passwordModal === 'remove'}\n onClose={() => setPasswordModal(null)}\n />\n\n {/* TOTP Modals */}\n <SetupTotpModal\n isOpen={totpModal === 'setup'}\n onClose={() => setTotpModal(null)}\n />\n <DisableTotpModal\n isOpen={totpModal === 'disable'}\n onClose={() => setTotpModal(null)}\n />\n <RegenerateTotpRecoveryCodesModal\n isOpen={totpModal === 'regenerate'}\n onClose={() => setTotpModal(null)}\n />\n\n {/* Passkey Modals */}\n <SetupPasskeyModal\n isOpen={passkeyModal === 'setup'}\n onClose={() => setPasskeyModal(null)}\n />\n <ManagePasskeysModal\n isOpen={passkeyModal === 'manage'}\n onAddNew={() => setPasskeyModal('setup')}\n onClose={() => setPasskeyModal(null)}\n />\n\n {/* Unlink OAuth Modal */}\n <UnlinkOAuthModal\n isOpen={unlinkModal !== null}\n isPending={unlinkMutation.isPending}\n onClose={() => setUnlinkModal(null)}\n onConfirm={handleUnlinkConfirm}\n providerName={unlinkModal?.name ?? ''}\n />\n\n {/* Delete Account Modal */}\n <DeleteAccountModal\n isOpen={showDeleteModal}\n onClose={() => setShowDeleteModal(false)}\n retentionDays={retentionDays}\n />\n </PageLayout>\n );\n}\n"],"mappings":"gGA4DA,SAASI,EAAaC,EAA4B,CAChD,OACE,EAAA,EAAA,KAAC,EAAD,CACE,GAAIA,EACJ,mBAAsB,CACpBE,OAAOC,SAASC,KAAO,QACzB,CAAE,CAAA,CAGR"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promise-OpBtq8tG.js","names":[],"sources":["../../../frontend/src/libs/promise.ts"],"sourcesContent":["export const tick = () => new Promise((resolve) => setTimeout(resolve, 0));\n"],"mappings":"AAAA,IAAa,MAAa,IAAI,QAAS,GAAY,WAAW,EAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n as e,o as t,r as n,s as r,u as i}from"./IconBase.es-d5KP98Ac.js";import{f as a,h as o,ut as s}from"./use-theme-cVUDAjtt.js";import{t as c}from"./useMutation-DVMopbtG.js";import{t as l}from"./page-layout-C475gs09.js";import{c as u,o as d}from"./zod-BItJDQBQ.js";import{A as f,M as p,P as m,S as h,j as g,t as _}from"./index-CsT6OVnP.js";import{t as v}from"./page-header-BYMFSGfT.js";import{t as y}from"./promise-OpBtq8tG.js";import{r as b,t as x}from"./standard-schema-o4V-s4uY.js";import{t as S}from"./footer-link-Ib1Hd-fr.js";import{t as C}from"./submit-button-Xx6DwLyh.js";import{a as w}from"./totp-NlqqRp4a.js";var T=i(r()),E=t(),D={SECOND_FACTOR_SESSION_EXPIRED:`SECOND_FACTOR_SESSION_EXPIRED`,INVALID_RECOVERY_CODE:`INVALID_RECOVERY_CODE`,NO_RECOVERY_CODES_AVAILABLE:`NO_RECOVERY_CODES_AVAILABLE`,TOTP_NOT_ENABLED:`TOTP_NOT_ENABLED`},O=5;function k(){let{t}=n(),r=o(),i=s(),k=_.useSearch(),A=(0,T.useRef)(null),[j,M]=(0,T.useState)(!1),[N,P]=(0,T.useState)(O),F=(0,T.useMemo)(()=>d({code:u().transform(e=>e.toUpperCase()).pipe(u().regex(/^[A-HJ-NP-TV-Z2-9]{4}(?:-[A-HJ-NP-TV-Z2-9]{4}){3}$/,t(`verifyRecovery.error.invalid`)))}),[t]),I=c({...w,onSuccess:async e=>{i.setQueryData(h.queryKey,{user:e.user}),await y(),p(k)?window.location.href=f(k):r.navigate({to:`/profile`})},onSettled:()=>{i.invalidateQueries({queryKey:h.queryKey})}}),{register:L,setError:R,handleSubmit:z,setValue:B,formState:{errors:V}}=b({defaultValues:{code:``},resolver:x(F)}),H=(0,T.useCallback)(()=>{r.navigate({to:`/login`,search:g(k)})},[r,k]);(0,T.useEffect)(()=>{if(!j)return;let e=setInterval(()=>{P(t=>t<=1?(clearInterval(e),H(),0):t-1)},1e3);return()=>clearInterval(e)},[j,H]);let U=async n=>{try{await I.mutateAsync(n)}catch(n){if(n instanceof e)switch(n.code){case D.SECOND_FACTOR_SESSION_EXPIRED:M(!0),P(O);return;case D.TOTP_NOT_ENABLED:H();return;case D.NO_RECOVERY_CODES_AVAILABLE:R(`code`,{type:`manual`,message:t(`verifyRecovery.error.noCodesAvailable`)}),B(`code`,``),A.current?.focus();return;case D.INVALID_RECOVERY_CODE:R(`code`,{type:`manual`,message:t(`verifyRecovery.error.invalid`)}),B(`code`,``),A.current?.focus();return}R(`code`,{type:`manual`,message:t(`verifyRecovery.error.invalid`)}),B(`code`,``),A.current?.focus()}},{ref:W,...G}=L(`code`);return(0,E.jsxs)(l,{cardPadding:!0,maxWidth:`100`,children:[(0,E.jsx)(v,{subtitle:t(`verifyRecovery.subtitle`),title:t(`verifyRecovery.title`)}),j&&(0,E.jsxs)(`div`,{className:`alert alert-warning mb-4`,"data-testid":`recovery-session-expired`,children:[(0,E.jsx)(m,{className:`size-5`,weight:`fill`}),(0,E.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,E.jsx)(`span`,{children:t(`verifyRecovery.error.expired`)}),(0,E.jsx)(`span`,{className:`text-sm opacity-80`,children:t(`verifyRecovery.redirecting`,{seconds:N})}),(0,E.jsx)(`button`,{className:`btn btn-sm btn-ghost mt-2 w-fit`,onClick:H,type:`button`,children:t(`verifyRecovery.redirectNow`)})]})]}),(0,E.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:z(U),children:[(0,E.jsxs)(`fieldset`,{className:`fieldset`,children:[(0,E.jsx)(`input`,{...G,autoComplete:`off`,className:`input input-bordered w-full text-center font-mono ${V.code?`input-error`:``}`,"data-testid":`recovery-code-input`,disabled:j,placeholder:t(`verifyRecovery.placeholder`),ref:e=>{W(e),A.current=e},type:`text`}),V.code&&(0,E.jsx)(`p`,{className:`fieldset-label text-error`,"data-testid":`recovery-error`,children:V.code.message})]}),j?(0,E.jsx)(`button`,{className:`btn btn-block btn-disabled mt-2`,disabled:!0,type:`button`,children:t(`verifyRecovery.submit`)}):(0,E.jsx)(C,{className:`mt-2`,isPending:I.isPending,pendingText:t(`verifyRecovery.submitting`),children:t(`verifyRecovery.submit`)})]}),(0,E.jsx)(`div`,{className:`mt-4 text-center`,children:(0,E.jsx)(`button`,{className:`link link-info font-medium text-xs`,"data-testid":`recovery-back-to-totp`,onClick:()=>r.navigate({to:`/verify/totp`,search:g(k)}),type:`button`,children:t(`verifyRecovery.backToTotp`)})}),(0,E.jsx)(S,{as:a,linkText:t(`verifyRecovery.backToLogin`),search:g(k),text:``,to:`/login`})]})}export{k as component};
|
|
2
|
+
//# sourceMappingURL=recovery-DM8h2gbb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-DM8h2gbb.js","names":["standardSchemaResolver","WarningCircleIcon","useMutation","useQueryClient","Link","useRouter","useCallback","useEffect","useMemo","useRef","useState","useForm","useTranslation","z","FooterLink","PageHeader","SubmitButton","PageLayout","TinyAuthError","buildAuthorizeUrl","extractOAuthParams","isOAuthFlow","tick","getSessionQueryOptions","verifyRecoveryCodeMutationOptions","ERROR_CODES","SECOND_FACTOR_SESSION_EXPIRED","INVALID_RECOVERY_CODE","NO_RECOVERY_CODES_AVAILABLE","TOTP_NOT_ENABLED","const","Route","RecoveryFormValues","code","REDIRECT_COUNTDOWN_SECONDS","VerifyRecovery","t","router","queryClient","search","useSearch","inputRef","HTMLInputElement","sessionExpired","setSessionExpired","redirectCountdown","setRedirectCountdown","recoverySchema","object","string","transform","value","toUpperCase","pipe","regex","verifyMutation","onSuccess","data","setQueryData","queryKey","user","window","location","href","navigate","to","onSettled","invalidateQueries","register","setError","handleSubmit","setValue","formState","errors","defaultValues","resolver","redirectToLogin","timer","setInterval","prev","clearInterval","onSubmit","values","mutateAsync","error","type","message","current","focus","ref","formRef","registerRest","seconds","el","isPending","component"],"sources":["../../../frontend/src/routes/verify/totp/recovery/index.tsx?tsr-split=component"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { WarningCircleIcon } from '@phosphor-icons/react';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { createFileRoute, Link, useRouter } from '@tanstack/react-router';\nimport { useCallback, useEffect, useMemo, useRef, 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 { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { TinyAuthError } from '#frontend/libs/error.ts';\nimport {\n buildAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport { verifyRecoveryCodeMutationOptions } from '#frontend/queries/totp.ts';\n\n/** Error codes from backend */\nconst ERROR_CODES = {\n SECOND_FACTOR_SESSION_EXPIRED: 'SECOND_FACTOR_SESSION_EXPIRED',\n INVALID_RECOVERY_CODE: 'INVALID_RECOVERY_CODE',\n NO_RECOVERY_CODES_AVAILABLE: 'NO_RECOVERY_CODES_AVAILABLE',\n TOTP_NOT_ENABLED: 'TOTP_NOT_ENABLED',\n} as const;\n\nconst SearchSchema = OAuthSearchSchema;\n\nexport const Route = createFileRoute('/verify/totp/recovery/')({\n component: VerifyRecovery,\n validateSearch: SearchSchema,\n});\n\ntype RecoveryFormValues = {\n code: string;\n};\n\n/** Auto redirect countdown seconds */\nconst REDIRECT_COUNTDOWN_SECONDS = 5;\n\nfunction VerifyRecovery() {\n const { t } = useTranslation();\n const router = useRouter();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const [sessionExpired, setSessionExpired] = useState(false);\n const [redirectCountdown, setRedirectCountdown] = useState(\n REDIRECT_COUNTDOWN_SECONDS,\n );\n\n const recoverySchema = useMemo(\n () =>\n z.object({\n code: z\n .string()\n .transform((value) => value.toUpperCase())\n .pipe(\n z\n .string()\n .regex(\n /^[A-HJ-NP-TV-Z2-9]{4}(?:-[A-HJ-NP-TV-Z2-9]{4}){3}$/,\n t('verifyRecovery.error.invalid'),\n ),\n ),\n }),\n [t],\n );\n\n const verifyMutation = useMutation({\n ...verifyRecoveryCodeMutationOptions,\n onSuccess: async (data) => {\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: data.user,\n });\n await tick();\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthorizeUrl(search);\n } else {\n router.navigate({ to: '/profile' });\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n setValue,\n formState: { errors },\n } = useForm<RecoveryFormValues>({\n defaultValues: {\n code: '',\n },\n resolver: standardSchemaResolver(recoverySchema),\n });\n\n // Auto redirect when session expires\n const redirectToLogin = useCallback(() => {\n router.navigate({\n to: '/login',\n search: extractOAuthParams(search),\n });\n }, [router, search]);\n\n useEffect(() => {\n if (!sessionExpired) return;\n\n const timer = setInterval(() => {\n setRedirectCountdown((prev) => {\n if (prev <= 1) {\n clearInterval(timer);\n redirectToLogin();\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(timer);\n }, [sessionExpired, redirectToLogin]);\n\n const onSubmit = async (values: RecoveryFormValues) => {\n try {\n await verifyMutation.mutateAsync(values);\n } catch (error) {\n if (error instanceof TinyAuthError) {\n switch (error.code) {\n case ERROR_CODES.SECOND_FACTOR_SESSION_EXPIRED:\n setSessionExpired(true);\n setRedirectCountdown(REDIRECT_COUNTDOWN_SECONDS);\n return;\n\n case ERROR_CODES.TOTP_NOT_ENABLED:\n redirectToLogin();\n return;\n\n case ERROR_CODES.NO_RECOVERY_CODES_AVAILABLE:\n setError('code', {\n type: 'manual',\n message: t('verifyRecovery.error.noCodesAvailable'),\n });\n setValue('code', '');\n inputRef.current?.focus();\n return;\n\n case ERROR_CODES.INVALID_RECOVERY_CODE:\n setError('code', {\n type: 'manual',\n message: t('verifyRecovery.error.invalid'),\n });\n setValue('code', '');\n inputRef.current?.focus();\n return;\n }\n }\n\n // Generic error fallback\n setError('code', {\n type: 'manual',\n message: t('verifyRecovery.error.invalid'),\n });\n setValue('code', '');\n inputRef.current?.focus();\n }\n };\n\n const { ref: formRef, ...registerRest } = register('code');\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyRecovery.subtitle')}\n title={t('verifyRecovery.title')}\n />\n\n {sessionExpired && (\n <div\n className=\"alert alert-warning mb-4\"\n data-testid=\"recovery-session-expired\"\n >\n <WarningCircleIcon className=\"size-5\" weight=\"fill\" />\n <div className=\"flex flex-col gap-1\">\n <span>{t('verifyRecovery.error.expired')}</span>\n <span className=\"text-sm opacity-80\">\n {t('verifyRecovery.redirecting', {\n seconds: redirectCountdown,\n })}\n </span>\n <button\n className=\"btn btn-sm btn-ghost mt-2 w-fit\"\n onClick={redirectToLogin}\n type=\"button\"\n >\n {t('verifyRecovery.redirectNow')}\n </button>\n </div>\n </div>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <fieldset className=\"fieldset\">\n <input\n {...registerRest}\n autoComplete=\"off\"\n className={`input input-bordered w-full text-center font-mono ${\n errors.code ? 'input-error' : ''\n }`}\n data-testid=\"recovery-code-input\"\n disabled={sessionExpired}\n placeholder={t('verifyRecovery.placeholder')}\n ref={(el) => {\n formRef(el);\n inputRef.current = el;\n }}\n type=\"text\"\n />\n {errors.code && (\n <p\n className=\"fieldset-label text-error\"\n data-testid=\"recovery-error\"\n >\n {errors.code.message}\n </p>\n )}\n </fieldset>\n\n {sessionExpired ? (\n <button\n className=\"btn btn-block btn-disabled mt-2\"\n disabled\n type=\"button\"\n >\n {t('verifyRecovery.submit')}\n </button>\n ) : (\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyMutation.isPending}\n pendingText={t('verifyRecovery.submitting')}\n >\n {t('verifyRecovery.submit')}\n </SubmitButton>\n )}\n </form>\n\n <div className=\"mt-4 text-center\">\n <button\n className=\"link link-info font-medium text-xs\"\n data-testid=\"recovery-back-to-totp\"\n onClick={() =>\n router.navigate({\n to: '/verify/totp',\n search: extractOAuthParams(search),\n })\n }\n type=\"button\"\n >\n {t('verifyRecovery.backToTotp')}\n </button>\n </div>\n\n <FooterLink\n as={Link}\n linkText={t('verifyRecovery.backToLogin')}\n search={extractOAuthParams(search)}\n text=\"\"\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-SSKfXB7c.js","names":["RouteErrorFallback","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/register/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { EnvelopeSimpleIcon, LockIcon } from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport {\n createFileRoute,\n Link,\n redirect,\n useNavigate,\n} from '@tanstack/react-router';\nimport { useDeferredValue, useMemo } 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 { TermsCheckboxList } from '#frontend/components/terms/terms-checkbox-list.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { TinyAuthError } from '#frontend/libs/error.ts';\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 { registerMutationOptions } from '#frontend/queries/register.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport { getTermsQueryOptions } from '#frontend/queries/terms.ts';\n\nexport const Route = createFileRoute('/register/')({\n component: Register,\n errorComponent: RouteErrorFallback,\n validateSearch: OAuthSearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n if (!config.registration.public_registration) {\n throw redirect({\n to: '/',\n replace: true,\n });\n }\n },\n loaderDeps: ({ search }) => ({\n lang: search.lang,\n }),\n loader: async ({ context, deps }) => {\n const lang = deps.lang ?? context.i18n.language;\n await Promise.all([\n context.queryClient.ensureQueryData(appConfigQueryOptions),\n context.queryClient.ensureQueryData(getTermsQueryOptions(lang)),\n ]);\n },\n});\n\nfunction Register() {\n const { t, i18n } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n\n const lang = search.lang ?? i18n.language;\n const deferredLang = useDeferredValue(lang);\n\n const { data: configData } = useSuspenseQuery(appConfigQueryOptions);\n const { data: termsData } = useSuspenseQuery(\n getTermsQueryOptions(deferredLang),\n );\n\n const isPasswordAuthEnabled = configData.auth.password.enabled;\n const passwordPolicy = configData.auth.password.policy;\n\n // Check if there are any terms to display\n const hasTerms = termsData.terms.length > 0;\n const explicitTerms = useMemo(\n () => termsData.terms.filter((term) => term.consentMode === 'explicit'),\n [termsData.terms],\n );\n const hasExplicitTerms = explicitTerms.length > 0;\n\n // Get implicit notice from config\n const implicitNotice =\n configData.registration.signup_notice?.[lang] ??\n configData.registration.signup_notice?.[configData.i18n.fallback_language];\n\n const registerSchema = useMemo(\n () =>\n z.object({\n email: z.email(t('validation.email.invalid')),\n password: z\n .string()\n .min(\n passwordPolicy.min_length,\n t('validation.password.min', {\n count: passwordPolicy.min_length,\n }),\n )\n .max(\n passwordPolicy.max_length,\n t('validation.password.max', {\n count: passwordPolicy.max_length,\n }),\n ),\n termsConsents: z.object(\n Object.fromEntries(\n explicitTerms.map((term) => [\n term.id,\n term.required\n ? z.literal(true, {\n message: t('validation.terms.required'),\n })\n : z.boolean(),\n ]),\n ),\n ),\n }),\n [explicitTerms, passwordPolicy.max_length, passwordPolicy.min_length, t],\n );\n\n type RegisterFormValues = z.infer<typeof registerSchema>;\n\n const registerMutation = useMutation({\n ...registerMutationOptions,\n onSuccess: async (data, params) => {\n const user = data.user;\n\n if (user.email_verification_required && !user.email_verified) {\n return navigate({\n to: '/verify/email',\n search: {\n email: params.email,\n ...extractOAuthParams(search),\n },\n });\n }\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 (configData.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (configData.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: {\n ...extractOAuthParams(search),\n passkey_name: 'default',\n },\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 navigate({ to: '/profile' });\n }\n },\n onError: (error) => {\n if (error instanceof TinyAuthError) {\n if (error.code === 'REGISTRATION_EMAIL_NOT_ALLOWED') {\n setError('email', {\n type: 'manual',\n message: t('register.error.emailNotAllowed'),\n });\n } else if (error.code === 'REGISTRATION_DISABLED') {\n setError('email', {\n type: 'manual',\n message: t('register.error.registrationDisabled'),\n });\n } else {\n setError('email', {\n type: 'manual',\n message: t('register.error.emailExists'),\n });\n }\n } else {\n setError('email', {\n type: 'manual',\n message: t('register.error.emailExists'),\n });\n }\n },\n onSettled: async () => {\n await queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n control,\n setValue,\n formState: { errors },\n } = useForm<RegisterFormValues>({\n defaultValues: {\n email: '',\n password: '',\n termsConsents: Object.fromEntries(\n explicitTerms.map((term) => [term.id, false]),\n ),\n },\n resolver: standardSchemaResolver(registerSchema),\n mode: 'onChange',\n });\n\n const onSubmit = (values: RegisterFormValues) => {\n // Build consents array for registration\n // Only send explicit consents - implicit ones are handled by backend\n const consents = hasTerms\n ? explicitTerms.map((term) => ({\n termsId: term.id,\n agreed: values.termsConsents[term.id] ?? false,\n }))\n : undefined;\n\n registerMutation.mutate({\n email: values.email,\n password: values.password,\n consents,\n });\n };\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('register.subtitle')}\n title={t('register.title')}\n />\n\n {isPasswordAuthEnabled && (\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('register.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <IconInput\n autoComplete=\"new-password\"\n error={errors.password}\n icon={LockIcon}\n placeholder={t('register.password.placeholder')}\n {...register('password')}\n type=\"password\"\n />\n\n <div className=\"flex flex-col\">\n {implicitNotice && (\n <div className={'text-center text-base-content/60 text-xs'}>\n <div\n className=\"prose prose-sm text-xs! **:text-xs!\"\n dangerouslySetInnerHTML={{\n __html: implicitNotice,\n }}\n data-testid=\"terms-implicit-notice\"\n />\n </div>\n )}\n\n {implicitNotice && hasExplicitTerms && (\n <div className=\"divider text-xs\">AND</div>\n )}\n\n {hasTerms && hasExplicitTerms && (\n <TermsCheckboxList\n control={control}\n disabled={registerMutation.isPending}\n errors={errors}\n setValue={setValue}\n terms={explicitTerms}\n />\n )}\n </div>\n\n <SubmitButton\n className=\"mt-6\"\n isPending={registerMutation.isPending}\n pendingText={t('register.submitting')}\n >\n {t('register.submit')}\n </SubmitButton>\n </form>\n )}\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n search={extractOAuthParams(search)}\n text={t('register.footer.haveAccount')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"wCAsBsF,IAAAC,EAA7ED"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n as e,o as t,r as n,s as r,u as i}from"./IconBase.es-d5KP98Ac.js";import{Q as a,a as o,f as s,i as c,n as l,ut as u}from"./use-theme-cVUDAjtt.js";import{t as d}from"./useMutation-DVMopbtG.js";import{t as f}from"./mutationOptions-Dfvzj6n2.js";import{t as p}from"./page-layout-C475gs09.js";import{t as m}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{t as h}from"./Lock.es-Cb_uwQly.js";import{a as g,c as _,i as ee,o as v,r as y}from"./zod-BItJDQBQ.js";import{A as b,E as x,F as S,M as C,O as w,S as T,j as E}from"./index-CsT6OVnP.js";import{t as D}from"./page-header-BYMFSGfT.js";import{t as O}from"./promise-OpBtq8tG.js";import{r as k,t as A}from"./standard-schema-o4V-s4uY.js";import{t as j}from"./footer-link-Ib1Hd-fr.js";import{t as M}from"./icon-input-8iU7PNzd.js";import{t as N}from"./submit-button-Xx6DwLyh.js";import{t as P}from"./terms-checkbox-list-CdrbHxiF.js";var F=i(r()),I=f({mutationFn:async e=>o(await c.api.auth.register.$post({json:e,header:{}}))}),L=t();function R(){let{t,i18n:r}=n(),i=S(),o=u(),c=x.useSearch(),f=c.lang??r.language,R=(0,F.useDeferredValue)(f),{data:z}=a(l),{data:B}=a(w(R)),V=z.auth.password.enabled,H=z.auth.password.policy,U=B.terms.length>0,W=(0,F.useMemo)(()=>B.terms.filter(e=>e.consentMode===`explicit`),[B.terms]),G=W.length>0,K=z.registration.signup_notice?.[f]??z.registration.signup_notice?.[z.i18n.fallback_language],q=(0,F.useMemo)(()=>v({email:ee(t(`validation.email.invalid`)),password:_().min(H.min_length,t(`validation.password.min`,{count:H.min_length})).max(H.max_length,t(`validation.password.max`,{count:H.max_length})),termsConsents:v(Object.fromEntries(W.map(e=>[e.id,e.required?g(!0,{message:t(`validation.terms.required`)}):y()])))}),[W,H.max_length,H.min_length,t]),J=d({...I,onSuccess:async(e,t)=>{let n=e.user;if(n.email_verification_required&&!n.email_verified)return i({to:`/verify/email`,search:{email:t.email,...E(c)}});if(o.setQueryData(T.queryKey,{user:n}),await O(),n.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`?i({to:`/setup/totp`,search:E(c)}):i({to:`/setup/passkey`,search:{...E(c),passkey_name:`default`}}):i({to:`/setup/2fa`,search:E(c)})}C(c)?window.location.href=b(c):i({to:`/profile`})},onError:n=>{n instanceof e?n.code===`REGISTRATION_EMAIL_NOT_ALLOWED`?X(`email`,{type:`manual`,message:t(`register.error.emailNotAllowed`)}):n.code===`REGISTRATION_DISABLED`?X(`email`,{type:`manual`,message:t(`register.error.registrationDisabled`)}):X(`email`,{type:`manual`,message:t(`register.error.emailExists`)}):X(`email`,{type:`manual`,message:t(`register.error.emailExists`)})},onSettled:async()=>{await o.invalidateQueries({queryKey:T.queryKey})}}),{register:Y,setError:X,handleSubmit:Z,control:Q,setValue:te,formState:{errors:$}}=k({defaultValues:{email:``,password:``,termsConsents:Object.fromEntries(W.map(e=>[e.id,!1]))},resolver:A(q),mode:`onChange`});return(0,L.jsxs)(p,{cardPadding:!0,maxWidth:`100`,children:[(0,L.jsx)(D,{subtitle:t(`register.subtitle`),title:t(`register.title`)}),V&&(0,L.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:Z(e=>{let t=U?W.map(t=>({termsId:t.id,agreed:e.termsConsents[t.id]??!1})):void 0;J.mutate({email:e.email,password:e.password,consents:t})}),children:[(0,L.jsx)(M,{autoComplete:`email`,error:$.email,icon:m,placeholder:t(`register.email.placeholder`),...Y(`email`),type:`email`}),(0,L.jsx)(M,{autoComplete:`new-password`,error:$.password,icon:h,placeholder:t(`register.password.placeholder`),...Y(`password`),type:`password`}),(0,L.jsxs)(`div`,{className:`flex flex-col`,children:[K&&(0,L.jsx)(`div`,{className:`text-center text-base-content/60 text-xs`,children:(0,L.jsx)(`div`,{className:`prose prose-sm text-xs! **:text-xs!`,dangerouslySetInnerHTML:{__html:K},"data-testid":`terms-implicit-notice`})}),K&&G&&(0,L.jsx)(`div`,{className:`divider text-xs`,children:`AND`}),U&&G&&(0,L.jsx)(P,{control:Q,disabled:J.isPending,errors:$,setValue:te,terms:W})]}),(0,L.jsx)(N,{className:`mt-6`,isPending:J.isPending,pendingText:t(`register.submitting`),children:t(`register.submit`)})]}),(0,L.jsx)(j,{as:s,linkText:t(`register.link.login`),search:E(c),text:t(`register.footer.haveAccount`),to:`/login`})]})}export{R as component};
|
|
2
|
+
//# sourceMappingURL=register-vWW_43cD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-vWW_43cD.js","names":["standardSchemaResolver","EnvelopeSimpleIcon","LockIcon","useMutation","useQueryClient","useSuspenseQuery","Link","useNavigate","useDeferredValue","useMemo","useForm","useTranslation","z","FooterLink","IconInput","PageHeader","SubmitButton","TermsCheckboxList","PageLayout","TinyAuthError","buildAuthorizeUrl","extractOAuthParams","isOAuthFlow","tick","appConfigQueryOptions","registerMutationOptions","getSessionQueryOptions","getTermsQueryOptions","Route","Register","t","i18n","navigate","queryClient","search","useSearch","lang","language","deferredLang","data","configData","termsData","isPasswordAuthEnabled","auth","password","enabled","passwordPolicy","policy","hasTerms","terms","length","explicitTerms","filter","term","consentMode","hasExplicitTerms","implicitNotice","registration","signup_notice","fallback_language","registerSchema","object","email","string","min","min_length","count","max","max_length","termsConsents","Object","fromEntries","map","id","required","literal","message","boolean","RegisterFormValues","infer","registerMutation","onSuccess","params","user","email_verification_required","email_verified","to","setQueryData","queryKey","second_factor_required","available_2fa_methods","SecondFactorMethod","totp","push","passkey","method","passkey_name","window","location","href","onError","error","code","setError","type","onSettled","invalidateQueries","register","handleSubmit","control","setValue","formState","errors","defaultValues","resolver","mode","onSubmit","values","consents","termsId","agreed","undefined","mutate","__html","isPending","component"],"sources":["../../../frontend/src/queries/register.ts","../../../frontend/src/routes/register/index.tsx?tsr-split=component"],"sourcesContent":["import { mutationOptions } from '@tanstack/react-query';\nimport type { InferResponseType } from 'hono/client';\nimport { client, jsonOk } from '#frontend/libs/api.ts';\nimport type { TermsConsentItem } from './terms';\n\nexport type RegisterParams = {\n email: string;\n password: string;\n consents?: TermsConsentItem[];\n};\n\nexport type RegisterResponse = InferResponseType<\n (typeof client.api.auth.register)['$post'],\n 200\n>;\n\nexport const registerMutationOptions = mutationOptions({\n mutationFn: async (values: RegisterParams) => {\n const res = await client.api.auth.register.$post({\n json: values,\n header: {},\n });\n return jsonOk(res);\n },\n});\n","import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { EnvelopeSimpleIcon, LockIcon } from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport {\n createFileRoute,\n Link,\n redirect,\n useNavigate,\n} from '@tanstack/react-router';\nimport { useDeferredValue, useMemo } 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 { TermsCheckboxList } from '#frontend/components/terms/terms-checkbox-list.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { TinyAuthError } from '#frontend/libs/error.ts';\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 { registerMutationOptions } from '#frontend/queries/register.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport { getTermsQueryOptions } from '#frontend/queries/terms.ts';\n\nexport const Route = createFileRoute('/register/')({\n component: Register,\n errorComponent: RouteErrorFallback,\n validateSearch: OAuthSearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n if (!config.registration.public_registration) {\n throw redirect({\n to: '/',\n replace: true,\n });\n }\n },\n loaderDeps: ({ search }) => ({\n lang: search.lang,\n }),\n loader: async ({ context, deps }) => {\n const lang = deps.lang ?? context.i18n.language;\n await Promise.all([\n context.queryClient.ensureQueryData(appConfigQueryOptions),\n context.queryClient.ensureQueryData(getTermsQueryOptions(lang)),\n ]);\n },\n});\n\nfunction Register() {\n const { t, i18n } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n\n const lang = search.lang ?? i18n.language;\n const deferredLang = useDeferredValue(lang);\n\n const { data: configData } = useSuspenseQuery(appConfigQueryOptions);\n const { data: termsData } = useSuspenseQuery(\n getTermsQueryOptions(deferredLang),\n );\n\n const isPasswordAuthEnabled = configData.auth.password.enabled;\n const passwordPolicy = configData.auth.password.policy;\n\n // Check if there are any terms to display\n const hasTerms = termsData.terms.length > 0;\n const explicitTerms = useMemo(\n () => termsData.terms.filter((term) => term.consentMode === 'explicit'),\n [termsData.terms],\n );\n const hasExplicitTerms = explicitTerms.length > 0;\n\n // Get implicit notice from config\n const implicitNotice =\n configData.registration.signup_notice?.[lang] ??\n configData.registration.signup_notice?.[configData.i18n.fallback_language];\n\n const registerSchema = useMemo(\n () =>\n z.object({\n email: z.email(t('validation.email.invalid')),\n password: z\n .string()\n .min(\n passwordPolicy.min_length,\n t('validation.password.min', {\n count: passwordPolicy.min_length,\n }),\n )\n .max(\n passwordPolicy.max_length,\n t('validation.password.max', {\n count: passwordPolicy.max_length,\n }),\n ),\n termsConsents: z.object(\n Object.fromEntries(\n explicitTerms.map((term) => [\n term.id,\n term.required\n ? z.literal(true, {\n message: t('validation.terms.required'),\n })\n : z.boolean(),\n ]),\n ),\n ),\n }),\n [explicitTerms, passwordPolicy.max_length, passwordPolicy.min_length, t],\n );\n\n type RegisterFormValues = z.infer<typeof registerSchema>;\n\n const registerMutation = useMutation({\n ...registerMutationOptions,\n onSuccess: async (data, params) => {\n const user = data.user;\n\n if (user.email_verification_required && !user.email_verified) {\n return navigate({\n to: '/verify/email',\n search: {\n email: params.email,\n ...extractOAuthParams(search),\n },\n });\n }\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 (configData.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (configData.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: {\n ...extractOAuthParams(search),\n passkey_name: 'default',\n },\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 navigate({ to: '/profile' });\n }\n },\n onError: (error) => {\n if (error instanceof TinyAuthError) {\n if (error.code === 'REGISTRATION_EMAIL_NOT_ALLOWED') {\n setError('email', {\n type: 'manual',\n message: t('register.error.emailNotAllowed'),\n });\n } else if (error.code === 'REGISTRATION_DISABLED') {\n setError('email', {\n type: 'manual',\n message: t('register.error.registrationDisabled'),\n });\n } else {\n setError('email', {\n type: 'manual',\n message: t('register.error.emailExists'),\n });\n }\n } else {\n setError('email', {\n type: 'manual',\n message: t('register.error.emailExists'),\n });\n }\n },\n onSettled: async () => {\n await queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n control,\n setValue,\n formState: { errors },\n } = useForm<RegisterFormValues>({\n defaultValues: {\n email: '',\n password: '',\n termsConsents: Object.fromEntries(\n explicitTerms.map((term) => [term.id, false]),\n ),\n },\n resolver: standardSchemaResolver(registerSchema),\n mode: 'onChange',\n });\n\n const onSubmit = (values: RegisterFormValues) => {\n // Build consents array for registration\n // Only send explicit consents - implicit ones are handled by backend\n const consents = hasTerms\n ? explicitTerms.map((term) => ({\n termsId: term.id,\n agreed: values.termsConsents[term.id] ?? false,\n }))\n : undefined;\n\n registerMutation.mutate({\n email: values.email,\n password: values.password,\n consents,\n });\n };\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('register.subtitle')}\n title={t('register.title')}\n />\n\n {isPasswordAuthEnabled && (\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('register.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <IconInput\n autoComplete=\"new-password\"\n error={errors.password}\n icon={LockIcon}\n placeholder={t('register.password.placeholder')}\n {...register('password')}\n type=\"password\"\n />\n\n <div className=\"flex flex-col\">\n {implicitNotice && (\n <div className={'text-center text-base-content/60 text-xs'}>\n <div\n className=\"prose prose-sm text-xs! **:text-xs!\"\n dangerouslySetInnerHTML={{\n __html: implicitNotice,\n }}\n data-testid=\"terms-implicit-notice\"\n />\n </div>\n )}\n\n {implicitNotice && hasExplicitTerms && (\n <div className=\"divider text-xs\">AND</div>\n )}\n\n {hasTerms && hasExplicitTerms && (\n <TermsCheckboxList\n control={control}\n disabled={registerMutation.isPending}\n errors={errors}\n setValue={setValue}\n terms={explicitTerms}\n />\n )}\n </div>\n\n <SubmitButton\n className=\"mt-6\"\n isPending={registerMutation.isPending}\n pendingText={t('register.submitting')}\n >\n {t('register.submit')}\n </SubmitButton>\n </form>\n )}\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n search={extractOAuthParams(search)}\n text={t('register.footer.haveAccount')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -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{Q as a,f as o,n as s}from"./use-theme-cVUDAjtt.js";import{t as c}from"./useMutation-DVMopbtG.js";import{t as l}from"./CheckCircle.es-MnJIACCe.js";import{t as u}from"./page-layout-C475gs09.js";import{t as d}from"./Key.es-l5aSxw0I.js";import{t as f}from"./Lock.es-Cb_uwQly.js";import{c as p,o as m}from"./zod-BItJDQBQ.js";import{F as h,c as g}from"./index-CsT6OVnP.js";import{t as _}from"./page-header-BYMFSGfT.js";import{t as v}from"./alert-CSXqgDVi.js";import{r as y,t as b}from"./standard-schema-o4V-s4uY.js";import{t as x}from"./icon-input-8iU7PNzd.js";import{t as S}from"./submit-button-Xx6DwLyh.js";import{n as C}from"./password-reset-XZJTgJi3.js";var w=i(n(),1),T=new Map([[`bold`,w.createElement(w.Fragment,null,w.createElement(`path`,{d:`M208,76H180V56A52,52,0,0,0,76,56V76H48A20,20,0,0,0,28,96V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V96A20,20,0,0,0,208,76ZM100,56a28,28,0,0,1,56,0V76H100ZM204,204H52V100H204Zm-76-92a32,32,0,0,0-12,61.66V180a12,12,0,0,0,24,0v-6.34A32,32,0,0,0,128,112Zm0,24a8,8,0,1,1-8,8A8,8,0,0,1,128,136Z`}))],[`duotone`,w.createElement(w.Fragment,null,w.createElement(`path`,{d:`M208,88H48a8,8,0,0,0-8,8V208a8,8,0,0,0,8,8H208a8,8,0,0,0,8-8V96A8,8,0,0,0,208,88Zm-80,72a20,20,0,1,1,20-20A20,20,0,0,1,128,160Z`,opacity:`0.2`}),w.createElement(`path`,{d:`M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Zm-80-96a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Z`}))],[`fill`,w.createElement(w.Fragment,null,w.createElement(`path`,{d:`M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80Zm-72,78.63V184a8,8,0,0,1-16,0V158.63a24,24,0,1,1,16,0ZM160,80H96V56a32,32,0,0,1,64,0Z`}))],[`light`,w.createElement(w.Fragment,null,w.createElement(`path`,{d:`M208,82H174V56a46,46,0,0,0-92,0V82H48A14,14,0,0,0,34,96V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V96A14,14,0,0,0,208,82ZM94,56a34,34,0,0,1,68,0V82H94ZM210,208a2,2,0,0,1-2,2H48a2,2,0,0,1-2-2V96a2,2,0,0,1,2-2H208a2,2,0,0,1,2,2Zm-82-94a26,26,0,0,0-6,51.29V184a6,6,0,0,0,12,0V165.29A26,26,0,0,0,128,114Zm0,40a14,14,0,1,1,14-14A14,14,0,0,1,128,154Z`}))],[`regular`,w.createElement(w.Fragment,null,w.createElement(`path`,{d:`M128,112a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Zm80-72H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Z`}))],[`thin`,w.createElement(w.Fragment,null,w.createElement(`path`,{d:`M208,84H172V56a44,44,0,0,0-88,0V84H48A12,12,0,0,0,36,96V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V96A12,12,0,0,0,208,84ZM92,56a36,36,0,0,1,72,0V84H92ZM212,208a4,4,0,0,1-4,4H48a4,4,0,0,1-4-4V96a4,4,0,0,1,4-4H208a4,4,0,0,1,4,4Zm-84-92a24,24,0,0,0-4,47.66V184a4,4,0,0,0,8,0V163.66A24,24,0,0,0,128,116Zm0,40a16,16,0,1,1,16-16A16,16,0,0,1,128,156Z`}))]]),E=w.forwardRef((e,t)=>w.createElement(r,{ref:t,...e,weights:T}));E.displayName=`LockKeyIcon`;var D=e();function O(){let{t:e}=t(),n=h(),{token:r}=g.useSearch(),[i,T]=(0,w.useState)(!1),{data:O}=a(s),k=O.auth.password.policy,A=(0,w.useMemo)(()=>m({token:p().min(1,e(`validation.token.required`)),password:p().min(k.min_length,e(`validation.password.min`,{count:k.min_length})).max(k.max_length,e(`validation.password.max`,{count:k.max_length})),confirmPassword:p().min(1,e(`validation.confirmPassword.required`))}).refine(e=>e.password===e.confirmPassword,{message:e(`validation.confirmPassword.mismatch`),path:[`confirmPassword`]}),[k.max_length,k.min_length,e]),j=c({...C,onSuccess:()=>{T(!0)}}),{register:M,setError:N,handleSubmit:P,formState:{errors:F}}=y({defaultValues:{token:r||``,password:``,confirmPassword:``},resolver:b(A)});return i?(0,D.jsxs)(u,{cardPadding:!0,maxWidth:`100`,children:[(0,D.jsx)(v,{className:`mb-4`,icon:l,type:`success`,children:e(`resetPassword.success.title`)}),(0,D.jsx)(_,{subtitle:e(`resetPassword.success.description`),title:e(`resetPassword.success.subtitle`)}),(0,D.jsx)(`button`,{className:`btn btn-block h-10 font-semibold text-[14px]`,"data-testid":`reset-password-go-login`,onClick:()=>n({to:`/login`}),type:`button`,children:e(`resetPassword.success.goToLogin`)})]}):(0,D.jsxs)(u,{cardPadding:!0,maxWidth:`100`,children:[(0,D.jsx)(_,{subtitle:e(`resetPassword.subtitle`),title:e(`resetPassword.title`)}),(0,D.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:P(async t=>{try{await j.mutateAsync({token:t.token,password:t.password})}catch(t){t&&typeof t==`object`&&`code`in t?t.code===`INVALID_PASSWORD_RESET_TOKEN`?N(`token`,{type:`manual`,message:e(`resetPassword.error.invalidToken`)}):t.code===`USER_NOT_EDITABLE`&&N(`token`,{type:`manual`,message:e(`resetPassword.error.notEditable`)}):N(`token`,{type:`manual`,message:e(`resetPassword.error.invalidToken`)})}}),children:[!r&&(0,D.jsx)(x,{error:F.token,icon:d,placeholder:e(`resetPassword.token.placeholder`),...M(`token`),type:`text`}),r&&F.token&&(0,D.jsx)(`div`,{className:`alert alert-error`,"data-testid":`reset-password-token-error`,children:(0,D.jsx)(`span`,{className:`text-sm`,children:F.token.message})}),(0,D.jsx)(x,{autoComplete:`new-password`,error:F.password,icon:f,placeholder:e(`resetPassword.password.placeholder`),...M(`password`),type:`password`}),(0,D.jsx)(x,{autoComplete:`new-password`,error:F.confirmPassword,icon:E,placeholder:e(`resetPassword.confirmPassword.placeholder`),...M(`confirmPassword`),type:`password`}),(0,D.jsx)(S,{className:`mt-2`,isPending:j.isPending,pendingText:e(`resetPassword.submitting`),children:e(`resetPassword.submit`)})]}),(0,D.jsx)(`div`,{className:`mt-6 text-center text-base-content/70 text-xs`,children:(0,D.jsx)(o,{className:`link link-info font-medium`,"data-testid":`reset-password-back-to-login`,to:`/login`,children:e(`resetPassword.backToLogin`)})})]})}export{O as component};
|
|
2
|
+
//# sourceMappingURL=reset-CgACYrdp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset-CgACYrdp.js","names":["e","t","a","standardSchemaResolver","CheckCircleIcon","KeyIcon","LockIcon","LockKeyIcon","useMutation","useSuspenseQuery","Link","useNavigate","useMemo","useState","useForm","useTranslation","z","IconInput","PageHeader","SubmitButton","Alert","PageLayout","appConfigQueryOptions","resetPasswordMutationOptions","Route","ResetPasswordFormValues","token","password","confirmPassword","ResetPassword","t","navigate","search","useSearch","queryToken","resetSuccess","setResetSuccess","data","configData","passwordPolicy","auth","policy","resetPasswordSchema","object","string","min","min_length","count","max","max_length","refine","message","path","resetPasswordMutation","onSuccess","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","error","code","type","to","isPending","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/LockKey.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/LockKey.es.js","../../../frontend/src/routes/password/reset/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: \"M208,76H180V56A52,52,0,0,0,76,56V76H48A20,20,0,0,0,28,96V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V96A20,20,0,0,0,208,76ZM100,56a28,28,0,0,1,56,0V76H100ZM204,204H52V100H204Zm-76-92a32,32,0,0,0-12,61.66V180a12,12,0,0,0,24,0v-6.34A32,32,0,0,0,128,112Zm0,24a8,8,0,1,1-8,8A8,8,0,0,1,128,136Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\n \"path\",\n {\n d: \"M208,88H48a8,8,0,0,0-8,8V208a8,8,0,0,0,8,8H208a8,8,0,0,0,8-8V96A8,8,0,0,0,208,88Zm-80,72a20,20,0,1,1,20-20A20,20,0,0,1,128,160Z\",\n opacity: \"0.2\"\n }\n ), /* @__PURE__ */ a.createElement(\"path\", { d: \"M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Zm-80-96a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80Zm-72,78.63V184a8,8,0,0,1-16,0V158.63a24,24,0,1,1,16,0ZM160,80H96V56a32,32,0,0,1,64,0Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M208,82H174V56a46,46,0,0,0-92,0V82H48A14,14,0,0,0,34,96V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V96A14,14,0,0,0,208,82ZM94,56a34,34,0,0,1,68,0V82H94ZM210,208a2,2,0,0,1-2,2H48a2,2,0,0,1-2-2V96a2,2,0,0,1,2-2H208a2,2,0,0,1,2,2Zm-82-94a26,26,0,0,0-6,51.29V184a6,6,0,0,0,12,0V165.29A26,26,0,0,0,128,114Zm0,40a14,14,0,1,1,14-14A14,14,0,0,1,128,154Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M128,112a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Zm80-72H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M208,84H172V56a44,44,0,0,0-88,0V84H48A12,12,0,0,0,36,96V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V96A12,12,0,0,0,208,84ZM92,56a36,36,0,0,1,72,0V84H92ZM212,208a4,4,0,0,1-4,4H48a4,4,0,0,1-4-4V96a4,4,0,0,1,4-4H208a4,4,0,0,1,4,4Zm-84-92a24,24,0,0,0-4,47.66V184a4,4,0,0,0,8,0V163.66A24,24,0,0,0,128,116Zm0,40a16,16,0,1,1,16-16A16,16,0,0,1,128,156Z\" }))\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/LockKey.es.js\";\nconst e = o.forwardRef((c, r) => /* @__PURE__ */ o.createElement(t, { ref: r, ...c, weights: a }));\ne.displayName = \"LockKeyIcon\";\nconst n = e;\nexport {\n n as LockKey,\n e as LockKeyIcon\n};\n","import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n KeyIcon,\n LockIcon,\n LockKeyIcon,\n} from '@phosphor-icons/react';\nimport { useMutation, useSuspenseQuery } from '@tanstack/react-query';\nimport {\n createFileRoute,\n Link,\n redirect,\n useNavigate,\n} 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 { 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 { resetPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nconst SearchSchema = z.object({\n token: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/password/reset/')({\n component: ResetPassword,\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 ResetPasswordFormValues = {\n token: string;\n password: string;\n confirmPassword: string;\n};\n\nfunction ResetPassword() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const search = Route.useSearch();\n const { token: queryToken } = search;\n const [resetSuccess, setResetSuccess] = useState(false);\n const { data: configData } = useSuspenseQuery(appConfigQueryOptions);\n const passwordPolicy = configData.auth.password.policy;\n\n const resetPasswordSchema = useMemo(\n () =>\n z\n .object({\n token: z.string().min(1, t('validation.token.required')),\n password: z\n .string()\n .min(\n passwordPolicy.min_length,\n t('validation.password.min', {\n count: passwordPolicy.min_length,\n }),\n )\n .max(\n passwordPolicy.max_length,\n t('validation.password.max', {\n count: passwordPolicy.max_length,\n }),\n ),\n confirmPassword: z\n .string()\n .min(1, t('validation.confirmPassword.required')),\n })\n .refine((data) => data.password === data.confirmPassword, {\n message: t('validation.confirmPassword.mismatch'),\n path: ['confirmPassword'],\n }),\n [passwordPolicy.max_length, passwordPolicy.min_length, t],\n );\n\n const resetPasswordMutation = useMutation({\n ...resetPasswordMutationOptions,\n onSuccess: () => {\n setResetSuccess(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ResetPasswordFormValues>({\n defaultValues: {\n token: queryToken || '',\n password: '',\n confirmPassword: '',\n },\n resolver: standardSchemaResolver(resetPasswordSchema),\n });\n\n const onSubmit = async (values: ResetPasswordFormValues) => {\n try {\n await resetPasswordMutation.mutateAsync({\n token: values.token,\n password: values.password,\n });\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error) {\n if (error.code === 'INVALID_PASSWORD_RESET_TOKEN') {\n setError('token', {\n type: 'manual',\n message: t('resetPassword.error.invalidToken'),\n });\n } else if (error.code === 'USER_NOT_EDITABLE') {\n setError('token', {\n type: 'manual',\n message: t('resetPassword.error.notEditable'),\n });\n }\n } else {\n setError('token', {\n type: 'manual',\n message: t('resetPassword.error.invalidToken'),\n });\n }\n }\n };\n\n if (resetSuccess) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('resetPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('resetPassword.success.description')}\n title={t('resetPassword.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"reset-password-go-login\"\n onClick={() => navigate({ to: '/login' })}\n type=\"button\"\n >\n {t('resetPassword.success.goToLogin')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('resetPassword.subtitle')}\n title={t('resetPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n {!queryToken && (\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('resetPassword.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n )}\n\n {queryToken && errors.token && (\n <div\n className=\"alert alert-error\"\n data-testid=\"reset-password-token-error\"\n >\n <span className=\"text-sm\">{errors.token.message}</span>\n </div>\n )}\n\n <IconInput\n autoComplete=\"new-password\"\n error={errors.password}\n icon={LockIcon}\n placeholder={t('resetPassword.password.placeholder')}\n {...register('password')}\n type=\"password\"\n />\n\n <IconInput\n autoComplete=\"new-password\"\n error={errors.confirmPassword}\n icon={LockKeyIcon}\n placeholder={t('resetPassword.confirmPassword.placeholder')}\n {...register('confirmPassword')}\n type=\"password\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={resetPasswordMutation.isPending}\n pendingText={t('resetPassword.submitting')}\n >\n {t('resetPassword.submit')}\n </SubmitButton>\n </form>\n\n <div className=\"mt-6 text-center text-base-content/70 text-xs\">\n <Link\n className=\"link link-info font-medium\"\n data-testid=\"reset-password-back-to-login\"\n to=\"/login\"\n >\n {t('resetPassword.backToLogin')}\n </Link>\n </div>\n </PageLayout>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset-SSKfXB7c.js","names":["RouteErrorFallback","ResetPasswordFormValues","token","password","confirmPassword","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/password/reset/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n KeyIcon,\n LockIcon,\n LockKeyIcon,\n} from '@phosphor-icons/react';\nimport { useMutation, useSuspenseQuery } from '@tanstack/react-query';\nimport {\n createFileRoute,\n Link,\n redirect,\n useNavigate,\n} 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 { 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 { resetPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nconst SearchSchema = z.object({\n token: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/password/reset/')({\n component: ResetPassword,\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 ResetPasswordFormValues = {\n token: string;\n password: string;\n confirmPassword: string;\n};\n\nfunction ResetPassword() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const search = Route.useSearch();\n const { token: queryToken } = search;\n const [resetSuccess, setResetSuccess] = useState(false);\n const { data: configData } = useSuspenseQuery(appConfigQueryOptions);\n const passwordPolicy = configData.auth.password.policy;\n\n const resetPasswordSchema = useMemo(\n () =>\n z\n .object({\n token: z.string().min(1, t('validation.token.required')),\n password: z\n .string()\n .min(\n passwordPolicy.min_length,\n t('validation.password.min', {\n count: passwordPolicy.min_length,\n }),\n )\n .max(\n passwordPolicy.max_length,\n t('validation.password.max', {\n count: passwordPolicy.max_length,\n }),\n ),\n confirmPassword: z\n .string()\n .min(1, t('validation.confirmPassword.required')),\n })\n .refine((data) => data.password === data.confirmPassword, {\n message: t('validation.confirmPassword.mismatch'),\n path: ['confirmPassword'],\n }),\n [passwordPolicy.max_length, passwordPolicy.min_length, t],\n );\n\n const resetPasswordMutation = useMutation({\n ...resetPasswordMutationOptions,\n onSuccess: () => {\n setResetSuccess(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ResetPasswordFormValues>({\n defaultValues: {\n token: queryToken || '',\n password: '',\n confirmPassword: '',\n },\n resolver: standardSchemaResolver(resetPasswordSchema),\n });\n\n const onSubmit = async (values: ResetPasswordFormValues) => {\n try {\n await resetPasswordMutation.mutateAsync({\n token: values.token,\n password: values.password,\n });\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error) {\n if (error.code === 'INVALID_PASSWORD_RESET_TOKEN') {\n setError('token', {\n type: 'manual',\n message: t('resetPassword.error.invalidToken'),\n });\n } else if (error.code === 'USER_NOT_EDITABLE') {\n setError('token', {\n type: 'manual',\n message: t('resetPassword.error.notEditable'),\n });\n }\n } else {\n setError('token', {\n type: 'manual',\n message: t('resetPassword.error.invalidToken'),\n });\n }\n }\n };\n\n if (resetSuccess) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('resetPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('resetPassword.success.description')}\n title={t('resetPassword.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"reset-password-go-login\"\n onClick={() => navigate({ to: '/login' })}\n type=\"button\"\n >\n {t('resetPassword.success.goToLogin')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('resetPassword.subtitle')}\n title={t('resetPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n {!queryToken && (\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('resetPassword.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n )}\n\n {queryToken && errors.token && (\n <div\n className=\"alert alert-error\"\n data-testid=\"reset-password-token-error\"\n >\n <span className=\"text-sm\">{errors.token.message}</span>\n </div>\n )}\n\n <IconInput\n autoComplete=\"new-password\"\n error={errors.password}\n icon={LockIcon}\n placeholder={t('resetPassword.password.placeholder')}\n {...register('password')}\n type=\"password\"\n />\n\n <IconInput\n autoComplete=\"new-password\"\n error={errors.confirmPassword}\n icon={LockKeyIcon}\n placeholder={t('resetPassword.confirmPassword.placeholder')}\n {...register('confirmPassword')}\n type=\"password\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={resetPasswordMutation.isPending}\n pendingText={t('resetPassword.submitting')}\n >\n {t('resetPassword.submit')}\n </SubmitButton>\n </form>\n\n <div className=\"mt-6 text-center text-base-content/70 text-xs\">\n <Link\n className=\"link link-info font-medium\"\n data-testid=\"reset-password-back-to-login\"\n to=\"/login\"\n >\n {t('resetPassword.backToLogin')}\n </Link>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"wCAqDE,IAAAK,EA/BOL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes-CAIeH5mq.js","names":["Index","component"],"sources":["../../../frontend/src/routes/index.tsx?tsr-split=component"],"sourcesContent":["import { createFileRoute, redirect } from '@tanstack/react-router';\n\nexport const Route = createFileRoute('/')({\n component: Index,\n beforeLoad: async ({ context }) => {\n if (context.user) {\n throw redirect({\n to: '/profile',\n });\n } else {\n throw redirect({\n to: '/login',\n });\n }\n },\n});\n\nfunction Index() {\n return null;\n}\n"],"mappings":"AAiBA,SAASA,GAAQ,CACf,OAAO,IACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{o as e,s as t,t as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{Q as i,r as a,ut as o}from"./use-theme-cVUDAjtt.js";import{t as s}from"./useMutation-DVMopbtG.js";import{t as c}from"./page-layout-C475gs09.js";import{t as l}from"./Trash.es-BepW9BwV.js";import{A as u,a as d,i as f,j as p,n as m,r as h}from"./index-CsT6OVnP.js";import{t as g}from"./page-header-BYMFSGfT.js";import{t as _}from"./alert-CSXqgDVi.js";var v=r(t(),1),y=new Map([[`bold`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M224.49,136.49l-72,72a12,12,0,0,1-17-17L187,140H40a12,12,0,0,1,0-24H187L135.51,64.48a12,12,0,0,1,17-17l72,72A12,12,0,0,1,224.49,136.49Z`}))],[`duotone`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M216,128l-72,72V56Z`,opacity:`0.2`}),v.createElement(`path`,{d:`M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z`}))],[`fill`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M221.66,133.66l-72,72A8,8,0,0,1,136,200V136H40a8,8,0,0,1,0-16h96V56a8,8,0,0,1,13.66-5.66l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`light`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M220.24,132.24l-72,72a6,6,0,0,1-8.48-8.48L201.51,134H40a6,6,0,0,1,0-12H201.51L139.76,60.24a6,6,0,0,1,8.48-8.48l72,72A6,6,0,0,1,220.24,132.24Z`}))],[`regular`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`thin`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M218.83,130.83l-72,72a4,4,0,0,1-5.66-5.66L206.34,132H40a4,4,0,0,1,0-8H206.34L141.17,58.83a4,4,0,0,1,5.66-5.66l72,72A4,4,0,0,1,218.83,130.83Z`}))]]),b=new Map([[`bold`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z`}))],[`duotone`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`,opacity:`0.2`}),v.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z`}))],[`fill`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM184,136H136v48a8,8,0,0,1-16,0V136H72a8,8,0,0,1,0-16h48V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z`}))],[`light`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H134v82a6,6,0,0,1-12,0V134H40a6,6,0,0,1,0-12h82V40a6,6,0,0,1,12,0v82h82A6,6,0,0,1,222,128Z`}))],[`regular`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z`}))],[`thin`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H132v84a4,4,0,0,1-8,0V132H40a4,4,0,0,1,0-8h84V40a4,4,0,0,1,8,0v84h84A4,4,0,0,1,220,128Z`}))]]),x=new Map([[`bold`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20ZM79.57,196.57a60,60,0,0,1,96.86,0,83.72,83.72,0,0,1-96.86,0ZM100,120a28,28,0,1,1,28,28A28,28,0,0,1,100,120ZM194,179.94a83.48,83.48,0,0,0-29-23.42,52,52,0,1,0-74,0,83.48,83.48,0,0,0-29,23.42,84,84,0,1,1,131.9,0Z`}))],[`duotone`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M224,128a95.76,95.76,0,0,1-31.8,71.37A72,72,0,0,0,128,160a40,40,0,1,0-40-40,40,40,0,0,0,40,40,72,72,0,0,0-64.2,39.37h0A96,96,0,1,1,224,128Z`,opacity:`0.2`}),v.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24ZM74.08,197.5a64,64,0,0,1,107.84,0,87.83,87.83,0,0,1-107.84,0ZM96,120a32,32,0,1,1,32,32A32,32,0,0,1,96,120Zm97.76,66.41a79.66,79.66,0,0,0-36.06-28.75,48,48,0,1,0-59.4,0,79.66,79.66,0,0,0-36.06,28.75,88,88,0,1,1,131.52,0Z`}))],[`fill`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M172,120a44,44,0,1,1-44-44A44.05,44.05,0,0,1,172,120Zm60,8A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88.09,88.09,0,0,0-91.47-87.93C77.43,41.89,39.87,81.12,40,128.25a87.65,87.65,0,0,0,22.24,58.16A79.71,79.71,0,0,1,84,165.1a4,4,0,0,1,4.83.32,59.83,59.83,0,0,0,78.28,0,4,4,0,0,1,4.83-.32,79.71,79.71,0,0,1,21.79,21.31A87.62,87.62,0,0,0,216,128Z`}))],[`light`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26ZM71.44,198a66,66,0,0,1,113.12,0,89.8,89.8,0,0,1-113.12,0ZM94,120a34,34,0,1,1,34,34A34,34,0,0,1,94,120Zm99.51,69.64a77.53,77.53,0,0,0-40-31.38,46,46,0,1,0-51,0,77.53,77.53,0,0,0-40,31.38,90,90,0,1,1,131,0Z`}))],[`regular`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24ZM74.08,197.5a64,64,0,0,1,107.84,0,87.83,87.83,0,0,1-107.84,0ZM96,120a32,32,0,1,1,32,32A32,32,0,0,1,96,120Zm97.76,66.41a79.66,79.66,0,0,0-36.06-28.75,48,48,0,1,0-59.4,0,79.66,79.66,0,0,0-36.06,28.75,88,88,0,1,1,131.52,0Z`}))],[`thin`,v.createElement(v.Fragment,null,v.createElement(`path`,{d:`M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28ZM68.87,198.42a68,68,0,0,1,118.26,0,91.8,91.8,0,0,1-118.26,0Zm124.3-5.55a75.61,75.61,0,0,0-44.51-34,44,44,0,1,0-41.32,0,75.61,75.61,0,0,0-44.51,34,92,92,0,1,1,130.34,0ZM128,156a36,36,0,1,1,36-36A36,36,0,0,1,128,156Z`}))]]),S=v.forwardRef((e,t)=>v.createElement(n,{ref:t,...e,weights:y}));S.displayName=`ArrowRightIcon`;var C=v.forwardRef((e,t)=>v.createElement(n,{ref:t,...e,weights:b}));C.displayName=`PlusIcon`;var w=v.forwardRef((e,t)=>v.createElement(n,{ref:t,...e,weights:x}));w.displayName=`UserCircleIcon`;var T=e();function E(e){let t=new URLSearchParams;for(let[n,r]of Object.entries({...p(e),account_selected:`1`}))r!==void 0&&t.set(n,String(r));return`/login?${t.toString()}`}function D(){let e=m.useSearch(),t=o(),{data:n}=i(h(e.client_id)),r=()=>{window.location.href=u({...e,account_selected:`1`})},p=s({...d,onSuccess:r}),v=s({...f,onSuccess:()=>{t.invalidateQueries({queryKey:a.accounts(e.client_id)})}});return(0,T.jsxs)(c,{cardPadding:!0,maxWidth:`100`,children:[(0,T.jsx)(g,{subtitle:`Choose an account to continue to this application`,title:`Choose an account`}),n.accounts.length===0?(0,T.jsx)(_,{className:`mb-4`,icon:w,type:`info`,children:`No remembered accounts are available in this browser session.`}):(0,T.jsx)(`div`,{className:`flex flex-col gap-2`,"data-testid":`account-list`,children:n.accounts.map(e=>(0,T.jsxs)(`div`,{className:`flex items-center gap-3 rounded-box border border-base-300 bg-base-100 p-3 shadow-sm`,"data-testid":`remembered-account`,children:[(0,T.jsx)(`div`,{className:`avatar placeholder`,children:(0,T.jsx)(`div`,{className:`w-10 rounded-full bg-primary/10 text-primary`,children:(0,T.jsx)(w,{className:`size-7`,weight:`duotone`})})}),(0,T.jsxs)(`button`,{className:`min-w-0 flex-1 text-left`,"data-testid":`select-account-${e.sub}`,disabled:p.isPending,onClick:()=>p.mutate({sub:e.sub}),type:`button`,children:[(0,T.jsx)(`div`,{className:`truncate font-medium text-sm`,children:e.email}),(0,T.jsx)(`div`,{className:`text-base-content/60 text-xs`,children:e.current?`Current account`:`Remembered account`})]}),e.current?(0,T.jsx)(`span`,{className:`badge badge-primary badge-sm`,children:`Current`}):null,n.allow_remove_account&&!e.current?(0,T.jsx)(`button`,{"aria-label":`Remove ${e.email}`,className:`btn btn-ghost btn-square btn-sm text-base-content/60`,"data-testid":`remove-account-${e.sub}`,disabled:v.isPending,onClick:()=>v.mutate({sub:e.sub}),type:`button`,children:(0,T.jsx)(l,{className:`size-4`})}):null]},e.sub))}),n.allow_add_account?(0,T.jsxs)(`a`,{className:`btn btn-outline mt-4 w-full justify-between`,href:E(e),children:[(0,T.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,T.jsx)(C,{className:`size-4`}),`Use another account`]}),(0,T.jsx)(S,{className:`size-4`})]}):null]})}export{D as component};
|
|
2
|
+
//# sourceMappingURL=select-BCP5fwfB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-BCP5fwfB.js","names":["a","a","r","a","i","t","a","s","t","ArrowRightIcon","PlusIcon","TrashIcon","UserCircleIcon","useMutation","useQueryClient","useSuspenseQuery","PageHeader","Alert","PageLayout","buildAuthorizeUrl","extractOAuthParams","accountsQueryOptions","removeAccountMutationOptions","selectAccountMutationOptions","queryKeys","Route","buildLoginHref","search","ReturnType","useSearch","params","URLSearchParams","key","value","Object","entries","account_selected","undefined","set","String","toString","AccountSelect","queryClient","data","client_id","continueWithSelectedAccount","window","location","href","selectMutation","onSuccess","removeMutation","invalidateQueries","queryKey","accounts","length","map","account","sub","isPending","mutate","email","current","allow_remove_account","allow_add_account","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/ArrowRight.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/defs/Plus.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/defs/UserCircle.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/ArrowRight.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/Plus.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/UserCircle.es.js","../../../frontend/src/routes/account/select/index.tsx?tsr-split=component"],"sourcesContent":["import * as e from \"react\";\nconst a = /* @__PURE__ */ new Map([\n [\n \"bold\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M224.49,136.49l-72,72a12,12,0,0,1-17-17L187,140H40a12,12,0,0,1,0-24H187L135.51,64.48a12,12,0,0,1,17-17l72,72A12,12,0,0,1,224.49,136.49Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M216,128l-72,72V56Z\", opacity: \"0.2\" }), /* @__PURE__ */ e.createElement(\"path\", { d: \"M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M221.66,133.66l-72,72A8,8,0,0,1,136,200V136H40a8,8,0,0,1,0-16h96V56a8,8,0,0,1,13.66-5.66l72,72A8,8,0,0,1,221.66,133.66Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M220.24,132.24l-72,72a6,6,0,0,1-8.48-8.48L201.51,134H40a6,6,0,0,1,0-12H201.51L139.76,60.24a6,6,0,0,1,8.48-8.48l72,72A6,6,0,0,1,220.24,132.24Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M218.83,130.83l-72,72a4,4,0,0,1-5.66-5.66L206.34,132H40a4,4,0,0,1,0-8H206.34L141.17,58.83a4,4,0,0,1,5.66-5.66l72,72A4,4,0,0,1,218.83,130.83Z\" }))\n ]\n]);\nexport {\n a as default\n};\n","import * as e from \"react\";\nconst a = /* @__PURE__ */ new Map([\n [\n \"bold\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\n \"path\",\n {\n d: \"M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z\",\n opacity: \"0.2\"\n }\n ), /* @__PURE__ */ e.createElement(\"path\", { d: \"M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM184,136H136v48a8,8,0,0,1-16,0V136H72a8,8,0,0,1,0-16h48V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M222,128a6,6,0,0,1-6,6H134v82a6,6,0,0,1-12,0V134H40a6,6,0,0,1,0-12h82V40a6,6,0,0,1,12,0v82h82A6,6,0,0,1,222,128Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M220,128a4,4,0,0,1-4,4H132v84a4,4,0,0,1-8,0V132H40a4,4,0,0,1,0-8h84V40a4,4,0,0,1,8,0v84h84A4,4,0,0,1,220,128Z\" }))\n ]\n]);\nexport {\n a as default\n};\n","import * as e from \"react\";\nconst a = /* @__PURE__ */ new Map([\n [\n \"bold\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20ZM79.57,196.57a60,60,0,0,1,96.86,0,83.72,83.72,0,0,1-96.86,0ZM100,120a28,28,0,1,1,28,28A28,28,0,0,1,100,120ZM194,179.94a83.48,83.48,0,0,0-29-23.42,52,52,0,1,0-74,0,83.48,83.48,0,0,0-29,23.42,84,84,0,1,1,131.9,0Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\n \"path\",\n {\n d: \"M224,128a95.76,95.76,0,0,1-31.8,71.37A72,72,0,0,0,128,160a40,40,0,1,0-40-40,40,40,0,0,0,40,40,72,72,0,0,0-64.2,39.37h0A96,96,0,1,1,224,128Z\",\n opacity: \"0.2\"\n }\n ), /* @__PURE__ */ e.createElement(\"path\", { d: \"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24ZM74.08,197.5a64,64,0,0,1,107.84,0,87.83,87.83,0,0,1-107.84,0ZM96,120a32,32,0,1,1,32,32A32,32,0,0,1,96,120Zm97.76,66.41a79.66,79.66,0,0,0-36.06-28.75,48,48,0,1,0-59.4,0,79.66,79.66,0,0,0-36.06,28.75,88,88,0,1,1,131.52,0Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M172,120a44,44,0,1,1-44-44A44.05,44.05,0,0,1,172,120Zm60,8A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88.09,88.09,0,0,0-91.47-87.93C77.43,41.89,39.87,81.12,40,128.25a87.65,87.65,0,0,0,22.24,58.16A79.71,79.71,0,0,1,84,165.1a4,4,0,0,1,4.83.32,59.83,59.83,0,0,0,78.28,0,4,4,0,0,1,4.83-.32,79.71,79.71,0,0,1,21.79,21.31A87.62,87.62,0,0,0,216,128Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26ZM71.44,198a66,66,0,0,1,113.12,0,89.8,89.8,0,0,1-113.12,0ZM94,120a34,34,0,1,1,34,34A34,34,0,0,1,94,120Zm99.51,69.64a77.53,77.53,0,0,0-40-31.38,46,46,0,1,0-51,0,77.53,77.53,0,0,0-40,31.38,90,90,0,1,1,131,0Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24ZM74.08,197.5a64,64,0,0,1,107.84,0,87.83,87.83,0,0,1-107.84,0ZM96,120a32,32,0,1,1,32,32A32,32,0,0,1,96,120Zm97.76,66.41a79.66,79.66,0,0,0-36.06-28.75,48,48,0,1,0-59.4,0,79.66,79.66,0,0,0-36.06,28.75,88,88,0,1,1,131.52,0Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(\"path\", { d: \"M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28ZM68.87,198.42a68,68,0,0,1,118.26,0,91.8,91.8,0,0,1-118.26,0Zm124.3-5.55a75.61,75.61,0,0,0-44.51-34,44,44,0,1,0-41.32,0,75.61,75.61,0,0,0-44.51,34,92,92,0,1,1,130.34,0ZM128,156a36,36,0,1,1,36-36A36,36,0,0,1,128,156Z\" }))\n ]\n]);\nexport {\n a as default\n};\n","import * as o from \"react\";\nimport a from \"../lib/IconBase.es.js\";\nimport i from \"../defs/ArrowRight.es.js\";\nconst r = o.forwardRef((t, e) => /* @__PURE__ */ o.createElement(a, { ref: e, ...t, weights: i }));\nr.displayName = \"ArrowRightIcon\";\nconst s = r;\nexport {\n s as ArrowRight,\n r as ArrowRightIcon\n};\n","import * as o from \"react\";\nimport t from \"../lib/IconBase.es.js\";\nimport a from \"../defs/Plus.es.js\";\nconst e = o.forwardRef((r, s) => /* @__PURE__ */ o.createElement(t, { ref: s, ...r, weights: a }));\ne.displayName = \"PlusIcon\";\nconst n = e;\nexport {\n n as Plus,\n e as PlusIcon\n};\n","import * as e from \"react\";\nimport s from \"../lib/IconBase.es.js\";\nimport t from \"../defs/UserCircle.es.js\";\nconst r = e.forwardRef((o, c) => /* @__PURE__ */ e.createElement(s, { ref: c, ...o, weights: t }));\nr.displayName = \"UserCircleIcon\";\nconst m = r;\nexport {\n m as UserCircle,\n r as UserCircleIcon\n};\n","import {\n ArrowRightIcon,\n PlusIcon,\n TrashIcon,\n UserCircleIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute } from '@tanstack/react-router';\nimport { PageHeader } from '#frontend/components/auth/page-header.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 {\n buildAuthorizeUrl,\n extractOAuthParams,\n OAuthSearchSchema,\n} from '#frontend/libs/oauth-search.ts';\nimport {\n accountsQueryOptions,\n removeAccountMutationOptions,\n selectAccountMutationOptions,\n} from '#frontend/queries/accounts.ts';\nimport { queryKeys } from '#frontend/queries/keys.ts';\n\nexport const Route = createFileRoute('/account/select/')({\n component: AccountSelect,\n errorComponent: RouteErrorFallback,\n validateSearch: OAuthSearchSchema,\n loader: async ({ context, location }) => {\n const search = location.search as { client_id?: string };\n await context.queryClient.ensureQueryData(\n accountsQueryOptions(search.client_id),\n );\n },\n});\n\nfunction buildLoginHref(search: ReturnType<typeof Route.useSearch>) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries({\n ...extractOAuthParams(search),\n account_selected: '1',\n })) {\n if (value !== undefined) {\n params.set(key, String(value));\n }\n }\n return `/login?${params.toString()}`;\n}\n\nfunction AccountSelect() {\n const search = Route.useSearch();\n const queryClient = useQueryClient();\n const { data } = useSuspenseQuery(accountsQueryOptions(search.client_id));\n\n const continueWithSelectedAccount = () => {\n window.location.href = buildAuthorizeUrl({\n ...search,\n account_selected: '1',\n });\n };\n\n const selectMutation = useMutation({\n ...selectAccountMutationOptions,\n onSuccess: continueWithSelectedAccount,\n });\n const removeMutation = useMutation({\n ...removeAccountMutationOptions,\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: queryKeys.accounts(search.client_id),\n });\n },\n });\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle=\"Choose an account to continue to this application\"\n title=\"Choose an account\"\n />\n\n {data.accounts.length === 0 ? (\n <Alert className=\"mb-4\" icon={UserCircleIcon} type=\"info\">\n No remembered accounts are available in this browser session.\n </Alert>\n ) : (\n <div className=\"flex flex-col gap-2\" data-testid=\"account-list\">\n {data.accounts.map((account) => (\n <div\n className=\"flex items-center gap-3 rounded-box border border-base-300 bg-base-100 p-3 shadow-sm\"\n data-testid=\"remembered-account\"\n key={account.sub}\n >\n <div className=\"avatar placeholder\">\n <div className=\"w-10 rounded-full bg-primary/10 text-primary\">\n <UserCircleIcon className=\"size-7\" weight=\"duotone\" />\n </div>\n </div>\n <button\n className=\"min-w-0 flex-1 text-left\"\n data-testid={`select-account-${account.sub}`}\n disabled={selectMutation.isPending}\n onClick={() => selectMutation.mutate({ sub: account.sub })}\n type=\"button\"\n >\n <div className=\"truncate font-medium text-sm\">\n {account.email}\n </div>\n <div className=\"text-base-content/60 text-xs\">\n {account.current ? 'Current account' : 'Remembered account'}\n </div>\n </button>\n {account.current ? (\n <span className=\"badge badge-primary badge-sm\">Current</span>\n ) : null}\n {data.allow_remove_account && !account.current ? (\n <button\n aria-label={`Remove ${account.email}`}\n className=\"btn btn-ghost btn-square btn-sm text-base-content/60\"\n data-testid={`remove-account-${account.sub}`}\n disabled={removeMutation.isPending}\n onClick={() => removeMutation.mutate({ sub: account.sub })}\n type=\"button\"\n >\n <TrashIcon className=\"size-4\" />\n </button>\n ) : null}\n </div>\n ))}\n </div>\n )}\n\n {data.allow_add_account ? (\n <a\n className=\"btn btn-outline mt-4 w-full justify-between\"\n href={buildLoginHref(search)}\n >\n <span className=\"inline-flex items-center gap-2\">\n <PlusIcon className=\"size-4\" />\n Use another account\n </span>\n <ArrowRightIcon className=\"size-4\" />\n </a>\n ) : null}\n </PageLayout>\n );\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-SSKfXB7c.js","names":["RouteErrorFallback","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/account/select/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import {\n ArrowRightIcon,\n PlusIcon,\n TrashIcon,\n UserCircleIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute } from '@tanstack/react-router';\nimport { PageHeader } from '#frontend/components/auth/page-header.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 {\n buildAuthorizeUrl,\n extractOAuthParams,\n OAuthSearchSchema,\n} from '#frontend/libs/oauth-search.ts';\nimport {\n accountsQueryOptions,\n removeAccountMutationOptions,\n selectAccountMutationOptions,\n} from '#frontend/queries/accounts.ts';\nimport { queryKeys } from '#frontend/queries/keys.ts';\n\nexport const Route = createFileRoute('/account/select/')({\n component: AccountSelect,\n errorComponent: RouteErrorFallback,\n validateSearch: OAuthSearchSchema,\n loader: async ({ context, location }) => {\n const search = location.search as { client_id?: string };\n await context.queryClient.ensureQueryData(\n accountsQueryOptions(search.client_id),\n );\n },\n});\n\nfunction buildLoginHref(search: ReturnType<typeof Route.useSearch>) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries({\n ...extractOAuthParams(search),\n account_selected: '1',\n })) {\n if (value !== undefined) {\n params.set(key, String(value));\n }\n }\n return `/login?${params.toString()}`;\n}\n\nfunction AccountSelect() {\n const search = Route.useSearch();\n const queryClient = useQueryClient();\n const { data } = useSuspenseQuery(accountsQueryOptions(search.client_id));\n\n const continueWithSelectedAccount = () => {\n window.location.href = buildAuthorizeUrl({\n ...search,\n account_selected: '1',\n });\n };\n\n const selectMutation = useMutation({\n ...selectAccountMutationOptions,\n onSuccess: continueWithSelectedAccount,\n });\n const removeMutation = useMutation({\n ...removeAccountMutationOptions,\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: queryKeys.accounts(search.client_id),\n });\n },\n });\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle=\"Choose an account to continue to this application\"\n title=\"Choose an account\"\n />\n\n {data.accounts.length === 0 ? (\n <Alert className=\"mb-4\" icon={UserCircleIcon} type=\"info\">\n No remembered accounts are available in this browser session.\n </Alert>\n ) : (\n <div className=\"flex flex-col gap-2\" data-testid=\"account-list\">\n {data.accounts.map((account) => (\n <div\n className=\"flex items-center gap-3 rounded-box border border-base-300 bg-base-100 p-3 shadow-sm\"\n data-testid=\"remembered-account\"\n key={account.sub}\n >\n <div className=\"avatar placeholder\">\n <div className=\"w-10 rounded-full bg-primary/10 text-primary\">\n <UserCircleIcon className=\"size-7\" weight=\"duotone\" />\n </div>\n </div>\n <button\n className=\"min-w-0 flex-1 text-left\"\n data-testid={`select-account-${account.sub}`}\n disabled={selectMutation.isPending}\n onClick={() => selectMutation.mutate({ sub: account.sub })}\n type=\"button\"\n >\n <div className=\"truncate font-medium text-sm\">\n {account.email}\n </div>\n <div className=\"text-base-content/60 text-xs\">\n {account.current ? 'Current account' : 'Remembered account'}\n </div>\n </button>\n {account.current ? (\n <span className=\"badge badge-primary badge-sm\">Current</span>\n ) : null}\n {data.allow_remove_account && !account.current ? (\n <button\n aria-label={`Remove ${account.email}`}\n className=\"btn btn-ghost btn-square btn-sm text-base-content/60\"\n data-testid={`remove-account-${account.sub}`}\n disabled={removeMutation.isPending}\n onClick={() => removeMutation.mutate({ sub: account.sub })}\n type=\"button\"\n >\n <TrashIcon className=\"size-4\" />\n </button>\n ) : null}\n </div>\n ))}\n </div>\n )}\n\n {data.allow_add_account ? (\n <a\n className=\"btn btn-outline mt-4 w-full justify-between\"\n href={buildLoginHref(search)}\n >\n <span className=\"inline-flex items-center gap-2\">\n <PlusIcon className=\"size-4\" />\n Use another account\n </span>\n <ArrowRightIcon className=\"size-4\" />\n </a>\n ) : null}\n </PageLayout>\n );\n}\n"],"mappings":"wCAcsF,IAAAC,EAA7ED"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{s as e,u as t}from"./IconBase.es-d5KP98Ac.js";var n=t(e(),1),r=e=>e.type===`checkbox`,i=e=>e instanceof Date,a=e=>e==null,o=e=>typeof e==`object`,s=e=>!a(e)&&!Array.isArray(e)&&o(e)&&!i(e),c=e=>s(e)&&e.target?r(e.target)?e.target.checked:e.target.value:e,l=(e,t)=>t.split(`.`).some((t,n,r)=>!isNaN(Number(t))&&e.has(r.slice(0,n).join(`.`))),u=e=>{let t=e.constructor&&e.constructor.prototype;return s(t)&&t.hasOwnProperty(`isPrototypeOf`)},d=typeof window<`u`&&window.HTMLElement!==void 0&&typeof document<`u`;function f(e){if(e instanceof Date)return new Date(e);let t=typeof FileList<`u`&&e instanceof FileList;if(d&&(e instanceof Blob||t))return e;let n=Array.isArray(e);if(!n&&!(s(e)&&u(e)))return e;let r=n?[]:Object.create(Object.getPrototypeOf(e));for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[t]=f(e[t]));return r}var p={BLUR:`blur`,FOCUS_OUT:`focusout`,CHANGE:`change`,SUBMIT:`submit`,TRIGGER:`trigger`,VALID:`valid`},m={onBlur:`onBlur`,onChange:`onChange`,onSubmit:`onSubmit`,onTouched:`onTouched`,all:`all`},h={max:`max`,min:`min`,maxLength:`maxLength`,minLength:`minLength`,pattern:`pattern`,required:`required`,validate:`validate`},g=`form`,_=`root`,v=[`__proto__`,`constructor`,`prototype`],y=e=>/^\w*$/.test(e),b=e=>e===void 0,x=e=>e.split(/[.[\]'"]/g).filter(Boolean),S=(e,t,n)=>{if(!t||!s(e))return n;let r=y(t)?[t]:x(t);if(r.some(e=>v.includes(e)))return n;let i=r.reduce((e,t)=>a(e)?void 0:e[t],e);return b(i)||i===e?b(e[t])?n:e[t]:i},C=e=>typeof e==`boolean`,w=e=>typeof e==`function`,T=(e,t,n)=>{let r=-1,i=y(t)?[t]:x(t),a=i.length,o=a-1;for(;++r<a;){let t=i[r],a=n;if(r!==o){let n=e[t];a=s(n)||Array.isArray(n)?n:isNaN(+i[r+1])?{}:[]}if(v.includes(t))return;e[t]=a,e=e[t]}},E=n.createContext(null);E.displayName=`HookFormControlContext`;var D=()=>n.useContext(E),O=(e,t,n,r=!0)=>{let i={};for(let a in e)Object.defineProperty(i,a,{get:()=>{let i=a;return t._proxyFormState[i]!==m.all&&(t._proxyFormState[i]=!r||m.all),n&&(n[i]=!0),e[i]}});return i},k=d?n.useLayoutEffect:n.useEffect;function A(e){let t=D(),{control:r=t,disabled:i,name:a,exact:o}=e||{},[s,c]=n.useState(()=>({...r._formState,defaultValues:r._defaultValues})),l=n.useRef({isDirty:!1,isLoading:!1,dirtyFields:!1,touchedFields:!1,validatingFields:!1,isValidating:!1,isValid:!1,errors:!1});return k(()=>r._subscribe({name:a,formState:l.current,exact:o,callback:e=>{!i&&c({...r._formState,...e,defaultValues:r._defaultValues})}}),[a,i,o]),n.useEffect(()=>{l.current.isValid&&r._setValid(!0)},[r]),n.useMemo(()=>O(s,r,l.current,!1),[s,r])}var j=e=>typeof e==`string`,M=(e,t,n,r,i)=>j(e)?(r&&t.watch.add(e),S(n,e,i)):Array.isArray(e)?e.map(e=>(r&&t.watch.add(e),S(n,e))):(r&&(t.watchAll=!0),n),N=e=>a(e)||!o(e),P=(e,t)=>t.length===0&&!Array.isArray(e)&&!u(e);function F(e,t,n=new WeakMap){if(e===t)return!0;if(N(e)||N(t))return Object.is(e,t);if(i(e)&&i(t))return Object.is(e.getTime(),t.getTime());let r=Object.keys(e),a=Object.keys(t);if(r.length!==a.length)return!1;if(P(e,r)||P(t,a))return Object.is(e,t);let o=n.get(e);if(o&&o.has(t))return!0;o?o.add(t):n.set(e,new WeakSet([t]));for(let a of r){let r=e[a];if(!(a in t))return!1;if(a!==`ref`){let e=t[a];if(i(r)&&i(e)||(s(r)||Array.isArray(r))&&(s(e)||Array.isArray(e))?!F(r,e,n):!Object.is(r,e))return!1}}return!0}function I(e){let t=D(),{control:r=t,name:i,defaultValue:a,disabled:o,exact:s,compute:c}=e||{},l=n.useRef(a),u=n.useRef(c),d=n.useRef(void 0),f=n.useRef(r),p=n.useRef(i);u.current=c;let[m,h]=n.useState(()=>{let e=r._getWatch(i,l.current);return u.current?u.current(e):e}),g=n.useCallback(e=>{let t=M(i,r._names,e||r._formValues,!1,l.current);return u.current?u.current(t):t},[r._formValues,r._names,i]),_=n.useCallback(e=>{if(!o){let t=M(i,r._names,e||r._formValues,!1,l.current);if(u.current){let e=u.current(t);F(e,d.current)||(h(e),d.current=e)}else h(t)}},[r._formValues,r._names,o,i]);k(()=>((f.current!==r||!F(p.current,i))&&(f.current=r,p.current=i,_()),r._subscribe({name:i,formState:{values:!0},exact:s,callback:e=>{_(e.values)}})),[r,s,i,_]),n.useEffect(()=>r._removeUnmounted());let v=f.current!==r,y=p.current,b=n.useMemo(()=>{if(o)return null;let e=!v&&!F(y,i);return v||e?g():null},[o,v,i,y,g]);return b===null?m:b}function ee(e){let t=D(),{name:r,disabled:i,control:a=t,shouldUnregister:o,defaultValue:s,exact:u=!0}=e,d=l(a._names.array,r),m=I({control:a,name:r,defaultValue:n.useMemo(()=>S(a._formValues,r,S(a._defaultValues,r,s)),[a,r,s]),exact:u}),h=A({control:a,name:r,exact:u}),g=n.useRef(e),_=n.useRef(null),v=n.useRef(a.register(r,{...e.rules,value:m,...C(e.disabled)?{disabled:e.disabled}:{}}));g.current=e;let y=n.useMemo(()=>Object.defineProperties({},{invalid:{enumerable:!0,get:()=>!!S(h.errors,r)},isDirty:{enumerable:!0,get:()=>!!S(h.dirtyFields,r)},isTouched:{enumerable:!0,get:()=>!!S(h.touchedFields,r)},isValidating:{enumerable:!0,get:()=>!!S(h.validatingFields,r)},error:{enumerable:!0,get:()=>S(h.errors,r)}}),[h,r]),x=n.useCallback(e=>{let t=c(e);return S(a._fields,r)||(v.current=a.register(r,{...g.current.rules,value:t})),v.current.onChange({target:{value:c(e),name:r},type:p.CHANGE})},[r,a]),E=n.useCallback(()=>v.current.onBlur({target:{value:S(a._formValues,r),name:r},type:p.BLUR}),[r,a._formValues]),O=n.useCallback(e=>{e&&(_.current={focus:()=>w(e.focus)&&e.focus(),select:()=>w(e.select)&&e.select(),setCustomValidity:t=>w(e.setCustomValidity)&&e.setCustomValidity(t),reportValidity:()=>w(e.reportValidity)&&e.reportValidity()});let t=S(a._fields,r);t&&t._f&&e&&(t._f.ref=_.current)},[a._fields,r]),k=n.useMemo(()=>({name:r,value:m,...C(i)||h.disabled?{disabled:h.disabled||i}:{},onChange:x,onBlur:E,ref:O}),[r,i,h.disabled,x,E,O,m]);return n.useEffect(()=>{let e=a._options.shouldUnregister||o;a.register(r,{...g.current.rules,...C(g.current.disabled)?{disabled:g.current.disabled}:{}});let t=(e,t)=>{let n=S(a._fields,e);n&&n._f&&(n._f.mount=t)};if(t(r,!0),e){let e=f(S(o?a._defaultValues:a._options.values||a._defaultValues,r,S(a._options.defaultValues,r,g.current.defaultValue)));T(a._defaultValues,r,e),b(S(a._formValues,r))&&T(a._formValues,r,e)}if(!d&&a.register(r),_.current){let e=S(a._fields,r);e&&e._f&&(e._f.ref=_.current)}return()=>{(d?e&&!a._state.action:e)?a.unregister(r):t(r,!1)}},[r,a,d,o]),n.useEffect(()=>{a._setDisabledField({disabled:i,name:r})},[i,r,a]),n.useMemo(()=>({field:k,formState:h,fieldState:y}),[k,h,y])}var te=e=>e.render(ee(e)),L=n.createContext(null);L.displayName=`HookFormContext`;var R=(e,t,n,r,i)=>t?{...n[e],types:{...n[e]&&n[e].types?n[e].types:{},[r]:i||!0}}:{},ne=e=>Array.isArray(e)?e.filter(Boolean):[],re=e=>Array.isArray(e)?e:[e],ie=()=>{let e=[];return{get observers(){return e},next:t=>{for(let n of e)n.next&&n.next(t)},subscribe:t=>(e.push(t),{unsubscribe:()=>{e=e.filter(e=>e!==t)}}),unsubscribe:()=>{e=[]}}};function ae(e,t){let n={};for(let r in e)if(e.hasOwnProperty(r)){let i=e[r],a=t[r];if(i&&s(i)&&a){let e=ae(i,a);s(e)&&(n[r]=e)}else e[r]&&(n[r]=a)}return n}var z=e=>s(e)&&!Object.keys(e).length,oe=e=>e.type===`file`,se=e=>{if(!d)return!1;let t=e?e.ownerDocument:0;return e instanceof(t&&t.defaultView?t.defaultView.HTMLElement:HTMLElement)},ce=e=>e.type===`select-multiple`,B=e=>e.type===`radio`,le=e=>B(e)||r(e),ue=e=>se(e)&&e.isConnected;function de(e,t){let n=t.slice(0,-1).length,r=0;for(;r<n;){if(a(e)){e=void 0;break}e=e[t[r]],r++}return e}function fe(e){for(let t in e)if(e.hasOwnProperty(t)&&!b(e[t]))return!1;return!0}function V(e,t){if(j(t)&&Object.prototype.hasOwnProperty.call(e,t))return delete e[t],e;let n=Array.isArray(t)?t:y(t)?[t]:x(t),r=n.length===1?e:de(e,n),i=n.length-1,a=n[i];return r&&delete r[a],i!==0&&(s(r)&&z(r)||Array.isArray(r)&&fe(r))&&V(e,n.slice(0,-1)),e}var pe=e=>{for(let t in e)if(w(e[t]))return!0;return!1};function me(e){return Array.isArray(e)||s(e)&&!pe(e)}function H(e,t={}){for(let n in e){let r=e[n];me(r)?(t[n]=Array.isArray(r)?[]:{},H(r,t[n])):b(r)||(t[n]=!0)}return t}function U(e){if(e!==!1){if(e===!0)return!0;if(Array.isArray(e)){let t=e.map(e=>U(e));return t.some(e=>e!==void 0)?t:void 0}if(s(e)){let t={};for(let n in e){let r=U(e[n]);b(r)||(t[n]=r)}return Object.keys(t).length?t:void 0}}}function W(e,t,n){n||=H(t);for(let r in e){let i=e[r];if(me(i))b(t)||N(n[r])?n[r]=H(i,Array.isArray(i)?[]:{}):W(i,a(t)?{}:t[r],n[r]);else{let e=t[r];n[r]=!F(i,e)}}return U(n)||{}}var he={value:!1,isValid:!1},G={value:!0,isValid:!0},ge=e=>{if(Array.isArray(e)){if(e.length>1){let t=e.filter(e=>e&&e.checked&&!e.disabled).map(e=>e.value);return{value:t,isValid:!!t.length}}return e[0].checked&&!e[0].disabled?e[0].attributes&&!b(e[0].attributes.value)?b(e[0].value)||e[0].value===``?G:{value:e[0].value,isValid:!0}:G:he}return he},_e=(e,{valueAsNumber:t,valueAsDate:n,setValueAs:r})=>b(e)?e:t?e===``?NaN:e&&+e:n&&j(e)?new Date(e):r?r(e):e,ve={isValid:!1,value:null},K=e=>Array.isArray(e)?e.reduce((e,t)=>t&&t.checked&&!t.disabled?{isValid:!0,value:t.value}:e,ve):ve;function ye(e){let t=e.ref;return oe(t)?t.files:B(t)?K(e.refs).value:ce(t)?[...t.selectedOptions].map(({value:e})=>e):r(t)?ge(e.refs).value:_e(b(t.value)?e.ref.value:t.value,e)}var be=(e,t,n,r)=>{let i={};for(let n of e){let e=S(t,n);e&&T(i,n,e._f)}return{criteriaMode:n,names:[...e],fields:i,shouldUseNativeValidation:r}},q=e=>e instanceof RegExp,J=e=>b(e)?e:q(e)?e.source:s(e)?q(e.value)?e.value.source:e.value:e,xe=e=>({isOnSubmit:!e||e===m.onSubmit,isOnBlur:e===m.onBlur,isOnChange:e===m.onChange,isOnAll:e===m.all,isOnTouch:e===m.onTouched}),Y=`AsyncFunction`,Se=e=>!!e&&!!e.validate&&!!(w(e.validate)&&e.validate.constructor.name===Y||s(e.validate)&&Object.values(e.validate).find(e=>e.constructor.name===Y)),Ce=e=>e.mount&&(e.required||e.min||e.max||e.maxLength||e.minLength||e.pattern||e.validate),we=(e,t,n)=>!n&&(t.watchAll||t.watch.has(e)||[...t.watch].some(t=>e.startsWith(`${t}.`))),X=(e,t,n,r)=>{for(let i of n||Object.keys(e)){let n=S(e,i);if(n){let{_f:e,...a}=n;if(e){if(e.refs&&e.refs[0]&&t(e.refs[0],i)&&!r||e.ref&&t(e.ref,e.name)&&!r)return!0;if(X(a,t))break}else if(s(a)&&X(a,t))break}}};function Te(e,t,n){let r=S(e,n);if(r||y(n))return{error:r,name:n};let i=n.split(`.`);for(;i.length;){let r=i.join(`.`),a=S(t,r),o=S(e,r);if(a&&!Array.isArray(a)&&n!==r)return{name:n};if(o&&o.type)return{name:r,error:o};if(o&&o.root&&o.root.type)return{name:`${r}.root`,error:o.root};i.pop()}return{name:n}}var Ee=(e,t,n,r)=>{n(e);let{name:i,...a}=e;return z(a)||r&&Object.keys(a).length>=Object.keys(t).length||Object.keys(a).find(e=>t[e]===(!r||m.all))},De=(e,t,n)=>!e||!t||e===t||re(e).some(e=>e&&(n?e===t:e.startsWith(t)||t.startsWith(e))),Oe=(e,t,n,r,i)=>i.isOnAll?!1:!n&&i.isOnTouch?!(t||e):(n?r.isOnBlur:i.isOnBlur)?!e:(n?r.isOnChange:i.isOnChange)?e:!0,ke=(e,t)=>!ne(S(e,t)).length&&V(e,t),Ae=(e,t,n)=>{let r=S(e,n),i=Array.isArray(r)?r:[];return T(i,_,t[n]),T(e,n,i),e};function Z(e,t,n=`validate`){if(j(e)||Array.isArray(e)&&e.every(j)||C(e)&&!e)return{type:n,message:j(e)?e:``,ref:t}}var Q=e=>s(e)&&!q(e)?e:{value:e,message:``},je=async(e,t,n,i,o,c)=>{let{ref:l,refs:u,required:d,maxLength:f,minLength:p,min:m,max:g,pattern:_,validate:v,name:y,valueAsNumber:x,mount:T}=e._f,E=S(n,y);if(!T||t.has(y))return{};let D=u?u[0]:l,O=e=>{if(o&&D.reportValidity){let t=C(e)?``:e||``;u?u.forEach(e=>e.setCustomValidity(t)):D.setCustomValidity(t),D.reportValidity()}},k={},A=B(l),M=r(l),N=A||M,P=(x||oe(l))&&b(l.value)&&b(E)||se(l)&&l.value===``||E===``||Array.isArray(E)&&!E.length,F=R.bind(null,y,i,k),I=(e,t,n,r=h.maxLength,i=h.minLength)=>{let a=e?t:n;k[y]={type:e?r:i,message:a,ref:l,...F(e?r:i,a)}};if(c?!Array.isArray(E)||!E.length:d&&(!N&&(P||a(E))||C(E)&&!E||M&&!ge(u).isValid||A&&!K(u).isValid)){let{value:e,message:t}=j(d)?{value:!!d,message:d}:Q(d);if(e&&(k[y]={type:h.required,message:t,ref:D,...F(h.required,t)},!i))return O(t),k}if(!P&&(!a(m)||!a(g))){let e,t,n=Q(g),r=Q(m);if(!a(E)&&!isNaN(E)){let i=l.valueAsNumber||E&&+E;a(n.value)||(e=i>n.value),a(r.value)||(t=i<r.value)}else{let i=l.valueAsDate||new Date(E),a=e=>new Date(new Date().toDateString()+` `+e),o=l.type==`time`,s=l.type==`week`;j(n.value)&&E&&(e=o?a(E)>a(n.value):s?E>n.value:i>new Date(n.value)),j(r.value)&&E&&(t=o?a(E)<a(r.value):s?E<r.value:i<new Date(r.value))}if((e||t)&&(I(!!e,n.message,r.message,h.max,h.min),!i))return O(k[y].message),k}if((f||p)&&!P&&(j(E)||c&&Array.isArray(E))){let e=Q(f),t=Q(p),n=!a(e.value)&&E.length>+e.value,r=!a(t.value)&&E.length<+t.value;if((n||r)&&(I(n,e.message,t.message),!i))return O(k[y].message),k}if(_&&!P&&j(E)){let{value:e,message:t}=Q(_);if(q(e)&&!E.match(e)&&(k[y]={type:h.pattern,message:t,ref:l,...F(h.pattern,t)},!i))return O(t),k}if(v){if(w(v)){let e=Z(await v(E,n),D);if(e&&(k[y]={...e,...F(h.validate,e.message)},!i))return O(e.message),k}else if(s(v)){let e={};for(let t in v){if(!z(e)&&!i)break;let r=Z(await v[t](E,n),D,t);r&&(e={...r,...F(t,r.message)},O(r.message),i&&(k[y]=e))}if(!z(e)&&(k[y]={ref:D,...e},!i))return k}}return O(!0),k},Me={mode:m.onSubmit,reValidateMode:m.onChange,shouldFocusError:!0},Ne={submitCount:0,isDirty:!1,isReady:!1,isValidating:!1,isSubmitted:!1,isSubmitting:!1,isSubmitSuccessful:!1,isValid:!1,touchedFields:{},dirtyFields:{},validatingFields:{}};function Pe(e={}){let t={...Me,...e},n={...f(Ne),isLoading:w(t.defaultValues),errors:t.errors||{},disabled:t.disabled||!1},o={},u=(s(t.defaultValues)||s(t.values))&&f(t.defaultValues||t.values)||{},v=t.shouldUnregister?{}:f(u),E={action:!1,mount:!1,watch:!1,keepIsValid:!1},D={mount:new Set,disabled:new Set,unMount:new Set,array:new Set,watch:new Set,registerName:new Set},O,k=0,A={isDirty:!1,dirtyFields:!1,validatingFields:!1,touchedFields:!1,isValidating:!1,isValid:!1,errors:!1},N={...A},P={...N},I={array:ie(),state:ie()},ee=t.criteriaMode===m.all,te=e=>t=>{clearTimeout(k),k=setTimeout(e,t)},L=async e=>{if(!E.keepIsValid&&!t.disabled&&(N.isValid||P.isValid||e)){let e;t.resolver?(e=z((await G()).errors),R()):e=await K({fields:o,onlyCheckValid:!0,eventType:p.VALID}),e!==n.isValid&&I.state.next({isValid:e})}},R=(e,r)=>{!t.disabled&&(N.isValidating||N.validatingFields||P.isValidating||P.validatingFields)&&((e||Array.from(D.mount)).forEach(e=>{e&&(r?T(n.validatingFields,e,r):V(n.validatingFields,e))}),I.state.next({validatingFields:n.validatingFields,isValidating:!z(n.validatingFields)}))},B=()=>{n.dirtyFields=W(u,v)},de=(e,r=[],i,a,s=!0,c=!0)=>{if(a&&i&&!t.disabled){if(E.action=!0,c&&Array.isArray(S(o,e))){let t=i(S(o,e),a.argA,a.argB);s&&T(o,e,t)}if(c&&Array.isArray(S(n.errors,e))){let t=i(S(n.errors,e),a.argA,a.argB);s&&T(n.errors,e,t),ke(n.errors,e)}if((N.touchedFields||P.touchedFields)&&c&&Array.isArray(S(n.touchedFields,e))){let t=i(S(n.touchedFields,e),a.argA,a.argB);s&&T(n.touchedFields,e,t)}(N.dirtyFields||P.dirtyFields)&&B(),I.state.next({name:e,isDirty:Y(e,r),dirtyFields:n.dirtyFields,errors:n.errors,isValid:n.isValid})}else T(v,e,r)},fe=(e,t)=>{T(n.errors,e,t),n.errors={...n.errors},I.state.next({errors:n.errors})},pe=e=>{n.errors=e,I.state.next({errors:n.errors,isValid:!1})},me=e=>{let t=y(e)?[e]:x(e),n=v,r=u;for(let e=0;e<t.length-1;e++){let i=t[e];if(n=a(n)?n:n[i],r=a(r)?r:r[i],n===null&&r!==null)return!0}return!1},H=(t,r,i,a)=>{let s=S(o,t);if(s){if(me(t))return;let o=b(S(v,t)),c=S(v,t,b(i)?S(u,t):i);b(c)||a&&a.defaultChecked||r?T(v,t,r?c:ye(s._f)):Pe(t,c),E.mount&&!E.action&&(L(),o&&n.isDirty&&(N.isDirty||P.isDirty)&&(Y()||(n.isDirty=!1,I.state.next({...n}))),e.shouldUnregister&&o&&!b(S(v,t))&&we(t,D)&&(E.watch=!0))}},U=(e,r,i,a,o)=>{let s=!1,c=!1,l={name:e};if(!t.disabled){if(!i||a){(N.isDirty||P.isDirty)&&(c=n.isDirty,n.isDirty=l.isDirty=Y(),s=c!==l.isDirty);let t=F(S(u,e),r);c=!!S(n.dirtyFields,e),t===n.isDirty?t?V(n.dirtyFields,e):T(n.dirtyFields,e,!0):n.dirtyFields=W(u,v),l.dirtyFields=n.dirtyFields,s||=(N.dirtyFields||P.dirtyFields)&&c!==!t}if(i){let t=S(n.touchedFields,e);t||(T(n.touchedFields,e,i),l.touchedFields=n.touchedFields,s||=(N.touchedFields||P.touchedFields)&&t!==i)}s&&o&&I.state.next(l)}return s?l:{}},he=(e,r,i,a)=>{let o=S(n.errors,e),s=(N.isValid||P.isValid)&&C(r)&&n.isValid!==r;if(t.delayError&&i?(O=te(()=>fe(e,i)),O(t.delayError)):(clearTimeout(k),O=null,i?T(n.errors,e,i):V(n.errors,e),n.errors={...n.errors}),(i?!F(o,i):o)||!z(a)||s){let t={...a,...s&&C(r)?{isValid:r}:{},errors:n.errors,name:e};n={...n,...t},I.state.next(t)}},G=async e=>(R(e,!0),await t.resolver(v,t.context,be(e||D.mount,o,t.criteriaMode,t.shouldUseNativeValidation))),ge=async e=>{let{errors:t}=await G(e);if(R(e),e){for(let r of e){let e=S(t,r);e?D.array.has(r)&&s(e)&&!Object.keys(e).some(e=>!Number.isNaN(Number(e)))?Ae(n.errors,{[r]:e},r):T(n.errors,r,e):V(n.errors,r)}n.errors={...n.errors}}else n.errors=t;return t},ve=async({name:t,eventType:r})=>{if(e.validate){let i=await e.validate({formValues:v,formState:n,name:t,eventType:r});if(s(i))for(let e in i){let t=i[e];t&&We(`${g}.${e}`,{message:j(t.message)?t.message:``,type:t.type||h.validate})}else j(i)||!i?We(g,{message:i||``,type:h.validate}):Ue(g);return i}return!0},K=async({fields:r,onlyCheckValid:i,name:a,eventType:o,context:s={valid:!0,runRootValidation:!1}})=>{if(e.validate&&(s.runRootValidation=!0,!await ve({name:a,eventType:o})&&(s.valid=!1,i)))return s.valid;for(let a in r){let c=r[a];if(c){let{_f:r,...l}=c;if(r){let a=D.array.has(r.name),o=c._f&&Se(c._f),l=N.validatingFields||N.isValidating||P.validatingFields||P.isValidating;o&&l&&R([r.name],!0);let u=await je(c,D.disabled,v,ee,t.shouldUseNativeValidation&&!i,a);if(o&&l&&R([r.name]),u[r.name]&&(s.valid=!1,i)||(!i&&(S(u,r.name)?a?Ae(n.errors,u,r.name):T(n.errors,r.name,u[r.name]):V(n.errors,r.name)),e.shouldUseNativeValidation&&u[r.name]))break}!z(l)&&await K({context:s,onlyCheckValid:i,fields:l,name:a,eventType:o})}}return s.valid},q=()=>{for(let e of D.unMount){let t=S(o,e);t&&(t._f.refs?t._f.refs.every(e=>!ue(e)):!ue(t._f.ref))&&Je(e)}D.unMount=new Set},Y=(e,n)=>!t.disabled&&(e&&n&&T(v,e,n),!F(Ve(),u)),Z=(e,t,n)=>M(e,D,{...E.mount?v:b(t)?u:j(e)?{[e]:t}:t},n,t),Q=e=>ne(S(E.mount?v:u,e,t.shouldUnregister?S(u,e,[]):[])),Pe=(e,t,n={},i=!1)=>{let s=S(o,e),c=t;if(s){let n=s._f;n&&(!n.disabled&&T(v,e,_e(t,n)),c=se(n.ref)&&a(t)?``:t,ce(n.ref)?[...n.ref.options].forEach(e=>e.selected=c.includes(e.value)):n.refs?r(n.ref)?n.refs.forEach(e=>{(!e.defaultChecked||!e.disabled)&&(Array.isArray(c)?e.checked=!!c.find(t=>t===e.value):e.checked=c===e.value||!!c)}):n.refs.forEach(e=>e.checked=e.value===c):oe(n.ref)?n.ref.value=``:(n.ref.value=c,n.ref.type||I.state.next({name:e,values:i?v:f(v)})))}(n.shouldDirty||n.shouldTouch)&&U(e,c,n.shouldTouch,n.shouldDirty,!0),n.shouldValidate&&Be(e)},Fe=(e,t,n,r=!1)=>{for(let a in t){if(!t.hasOwnProperty(a))return;let c=t[a],l=e+`.`+a,u=S(o,l);(D.array.has(e)||s(c)||u&&!u._f)&&!i(c)?Fe(l,c,n,r):Pe(l,c,n,r)}},Ie=(e,t,r,i)=>{let s=S(o,e),c=D.array.has(e),l=i?t:f(t),u=F(S(v,e),l);if(u||T(v,e,l),c)I.array.next({name:e,values:i?v:f(v)}),(N.isDirty||N.dirtyFields||P.isDirty||P.dirtyFields)&&r.shouldDirty&&(B(),I.state.next({name:e,dirtyFields:n.dirtyFields,isDirty:Y(e,l)}));else{let t=Array.isArray(l)&&!l.length||z(l);!s||s._f||a(l)||t?Pe(e,l,r,i):Fe(e,l,r,i)}if(!u){let t=we(e,D),r=i?v:f(v);I.state.next({...t&&n,name:E.mount||t?e:void 0,values:r})}},$=(e,t,n={})=>Ie(e,t,n,!1),Le=(e,t={})=>{let r=w(e)?e(v):e;if(!F(v,r)){v={...v,...r};for(let e of D.mount)Ie(e,S(r,e),t,!0);I.state.next({...n,name:void 0,type:void 0,values:v}),t.shouldValidate&&L()}},Re=async r=>{E.mount=!0;let a=r.target,s=a.name,l=!0,u=S(o,s),d=e=>{l=Number.isNaN(e)||i(e)&&isNaN(e.getTime())||F(e,S(v,s,e))},m=xe(t.mode),h=xe(t.reValidateMode);if(u){let i,g,_=a.type?ye(u._f):c(r),y=r.type===p.BLUR||r.type===p.FOCUS_OUT,b=!Ce(u._f)&&!e.validate&&!t.resolver&&!S(n.errors,s)&&!u._f.deps||Oe(y,S(n.touchedFields,s),n.isSubmitted,h,m),x=we(s,D,y);T(v,s,_),y?(!a||!a.readOnly)&&(u._f.onBlur&&u._f.onBlur(r),O&&O(0)):u._f.onChange&&u._f.onChange(r);let C=U(s,_,y),w=!z(C)||x;if(!y&&I.state.next({name:s,type:r.type,values:f(v)}),b)return(N.isValid||P.isValid)&&(t.mode===`onBlur`?y&&L():y||L()),w&&I.state.next({name:s,...x?{}:C});if(!t.resolver&&e.validate&&await ve({name:s,eventType:r.type}),!y&&x&&I.state.next({...n}),t.resolver){let{errors:e}=await G([s]);if(R([s]),d(_),!l){!z(C)&&I.state.next(C);return}let t=Te(n.errors,o,s),r=Te(e,o,t.name||s);i=r.error,s=r.name,g=z(e)}else R([s],!0),i=(await je(u,D.disabled,v,ee,t.shouldUseNativeValidation))[s],R([s]),d(_),l&&(i?g=!1:(N.isValid||P.isValid)&&(g=await K({fields:o,onlyCheckValid:!0,name:s,eventType:r.type})));l&&(u._f.deps&&(!Array.isArray(u._f.deps)||u._f.deps.length>0)&&Be(u._f.deps),he(s,g,i,C))}},ze=(e,t)=>{if(S(n.errors,t)&&e.focus)return e.focus(),1},Be=async(e,r={})=>{let i,a,s=re(e);if(t.resolver){let t=await ge(b(e)?e:s);i=z(t),a=e?!s.some(e=>S(t,e)):i}else e?(a=(await Promise.all(s.map(async e=>{let t=S(o,e);return await K({fields:t&&t._f?{[e]:t}:t,eventType:p.TRIGGER})}))).every(Boolean),!(!a&&!n.isValid)&&L()):a=i=await K({fields:o,name:e,eventType:p.TRIGGER});return I.state.next({...!j(e)||(N.isValid||P.isValid)&&i!==n.isValid?{}:{name:e},...t.resolver||!e?{isValid:i}:{},errors:n.errors}),r.shouldFocus&&!a&&X(o,ze,e?s:D.mount),a},Ve=(e,t)=>{let r={...E.mount?v:u};return t&&(r=ae(t.dirtyFields?n.dirtyFields:n.touchedFields,r)),b(e)?r:j(e)?S(r,e):e.map(e=>S(r,e))},He=(e,t)=>({invalid:!!S((t||n).errors,e),isDirty:!!S((t||n).dirtyFields,e),error:S((t||n).errors,e),isValidating:!!S(n.validatingFields,e),isTouched:!!S((t||n).touchedFields,e)}),Ue=e=>{let t=e?re(e):void 0;t?.forEach(e=>V(n.errors,e)),t?t.forEach(e=>{I.state.next({name:e,errors:n.errors})}):I.state.next({errors:{}})},We=(e,t,r)=>{let i=(S(o,e,{_f:{}})._f||{}).ref,{ref:a,message:s,type:c,...l}=S(n.errors,e)||{};T(n.errors,e,{...l,...t,ref:i}),I.state.next({name:e,errors:n.errors,isValid:!1}),r&&r.shouldFocus&&i&&i.focus&&i.focus()},Ge=(e,t)=>w(e)?I.state.subscribe({next:n=>`values`in n&&e(n.values||Z(void 0,t),n)}):Z(e,t,!0),Ke=e=>I.state.subscribe({next:t=>{if(De(e.name,t.name,e.exact)&&Ee(t,e.formState||N,it,e.reRenderRoot)){let r={...v};e.callback({values:r,...n,...t,defaultValues:u})}}}).unsubscribe,qe=e=>(E.mount=!0,P={...P,...e.formState},Ke({...e,formState:{...A,...e.formState}})),Je=(e,r={})=>{for(let i of e?re(e):D.mount)D.mount.delete(i),D.array.delete(i),r.keepValue||(V(o,i),V(v,i)),!r.keepError&&V(n.errors,i),!r.keepDirty&&V(n.dirtyFields,i),!r.keepTouched&&V(n.touchedFields,i),!r.keepIsValidating&&V(n.validatingFields,i),!t.shouldUnregister&&!r.keepDefaultValue&&V(u,i);I.state.next({values:f(v)}),I.state.next({...n,...r.keepDirty?{isDirty:Y()}:{}}),!r.keepIsValid&&L()},Ye=({disabled:e,name:t})=>{if(C(e)&&E.mount||e||D.disabled.has(t)){let n=D.disabled.has(t)!==!!e;e?D.disabled.add(t):D.disabled.delete(t),n&&E.mount&&!E.action&&L()}},Xe=(e,n={})=>{let r=S(o,e),i=C(n.disabled)||C(t.disabled),a=!D.registerName.has(e)&&r&&r._f&&!r._f.mount;return T(o,e,{...r||{},_f:{...r&&r._f?r._f:{ref:{name:e}},name:e,mount:!0,...n}}),D.mount.add(e),r&&!a?Ye({disabled:C(n.disabled)?n.disabled:t.disabled,name:e}):H(e,!0,n.value),{...i?{disabled:n.disabled||t.disabled}:{},...t.progressive?{required:!!n.required,min:J(n.min),max:J(n.max),minLength:J(n.minLength),maxLength:J(n.maxLength),pattern:J(n.pattern)}:{},name:e,onChange:Re,onBlur:Re,ref:i=>{if(i){D.registerName.add(e),Xe(e,n),D.registerName.delete(e),r=S(o,e);let t=b(i.value)&&i.querySelectorAll&&i.querySelectorAll(`input,select,textarea`)[0]||i,a=le(t),s=r._f.refs||[];if(a?s.find(e=>e===t):t===r._f.ref)return;T(o,e,{_f:{...r._f,...a?{refs:[...s.filter(ue),t,...Array.isArray(S(u,e))?[{}]:[]],ref:{type:t.type,name:e}}:{ref:t}}}),H(e,!1,void 0,t)}else r=S(o,e,{}),r._f&&(r._f.mount=!1),(t.shouldUnregister||n.shouldUnregister)&&!(l(D.array,e)&&E.action)&&D.unMount.add(e)}}},Ze=()=>t.shouldFocusError&&!t.shouldUseNativeValidation&&X(o,ze,D.mount),Qe=e=>{C(e)&&(I.state.next({disabled:e}),X(o,(t,n)=>{let r=S(o,n);r&&(t.disabled=r._f.disabled||e,Array.isArray(r._f.refs)&&r._f.refs.forEach(t=>{t.disabled=r._f.disabled||e}))},0,!1))},$e=(e,r)=>async i=>{let a;i&&(i.preventDefault&&i.preventDefault(),i.persist&&i.persist());let s=f(v);if(I.state.next({isSubmitting:!0}),t.resolver){let{errors:e,values:t}=await G();R(),n.errors=e,s=f(t)}else await K({fields:o,eventType:p.SUBMIT});if(D.disabled.size)for(let e of D.disabled)V(s,e);if(V(n.errors,_),z(n.errors)){I.state.next({errors:{}});try{await e(s,i)}catch(e){a=e}}else r&&await r({...n.errors},i),Ze(),setTimeout(Ze);if(I.state.next({isSubmitted:!0,isSubmitting:!1,isSubmitSuccessful:z(n.errors)&&!a,submitCount:n.submitCount+1,errors:n.errors}),a)throw a},et=(e,t={})=>{S(o,e)&&(b(t.defaultValue)?$(e,f(S(u,e))):($(e,t.defaultValue),T(u,e,f(t.defaultValue))),t.keepTouched||V(n.touchedFields,e),t.keepDirty||(V(n.dirtyFields,e),n.isDirty=t.defaultValue?Y(e,f(S(u,e))):Y()),t.keepError||(V(n.errors,e),N.isValid&&L()),I.state.next({...n}))},tt=(e,r={})=>{let i=e?f(e):u,a=f(i),s=z(e),c=a;if(r.keepDefaultValues||(u=i),!r.keepValues){if(r.keepDirtyValues){let e=new Set([...D.mount,...Object.keys(W(u,v))]);for(let t of Array.from(e)){let e=S(n.dirtyFields,t),r=S(v,t),i=S(c,t);e&&!b(r)?T(c,t,r):!e&&!b(i)&&$(t,i)}}else{if(d&&b(e))for(let e of D.mount){let t=S(o,e);if(t&&t._f){let e=Array.isArray(t._f.refs)?t._f.refs[0]:t._f.ref;if(se(e)){let t=e.closest(`form`);if(t){t.reset();break}}}}if(r.keepFieldsRef)for(let e of D.mount)$(e,S(c,e));else o={}}if(t.shouldUnregister){if(v=r.keepDefaultValues?f(u):{},r.keepFieldsRef)for(let e of D.mount)T(v,e,S(c,e))}else v=f(c);I.array.next({values:{...c}}),I.state.next({values:{...c}})}D={mount:r.keepDirtyValues?D.mount:new Set,unMount:new Set,array:new Set,registerName:new Set,disabled:new Set,watch:new Set,watchAll:!1,focus:``},E.mount=!N.isValid||!!r.keepIsValid||!!r.keepDirtyValues||!t.shouldUnregister&&!z(c),E.watch=!!t.shouldUnregister,E.keepIsValid=!!r.keepIsValid,E.action=!1,r.keepErrors||(n.errors={}),I.state.next({submitCount:r.keepSubmitCount?n.submitCount:0,isDirty:s?!1:r.keepDirty?n.isDirty:r.keepValues?Y():!!(r.keepDefaultValues&&!F(e,u)),isSubmitted:r.keepIsSubmitted?n.isSubmitted:!1,dirtyFields:s?{}:r.keepDirtyValues?r.keepDefaultValues&&v?W(u,v):n.dirtyFields:r.keepDefaultValues&&e?W(u,e):r.keepDirty?n.dirtyFields:{},touchedFields:r.keepTouched?n.touchedFields:{},errors:r.keepErrors?n.errors:{},isSubmitSuccessful:r.keepIsSubmitSuccessful?n.isSubmitSuccessful:!1,isSubmitting:!1,defaultValues:u})},nt=(e,n)=>tt(w(e)?e(v):e,{...t.resetOptions,...n}),rt=(e,t={})=>{let n=S(o,e),r=n&&n._f;if(r){let e=r.refs?r.refs[0]:r.ref;e.focus&&setTimeout(()=>{e.focus(),t.shouldSelect&&w(e.select)&&e.select()})}},it=e=>{n={...n,...e}},at={control:{register:Xe,unregister:Je,getFieldState:He,handleSubmit:$e,setError:We,_subscribe:Ke,_runSchema:G,_updateIsValidating:R,_focusError:Ze,_getWatch:Z,_getDirty:Y,_setValid:L,_setFieldArray:de,_setDisabledField:Ye,_setErrors:pe,_getFieldArray:Q,_reset:tt,_resetDefaultValues:()=>w(t.defaultValues)&&t.defaultValues().then(e=>{nt(e,t.resetOptions),I.state.next({isLoading:!1})}),_removeUnmounted:q,_disableForm:Qe,_subjects:I,_proxyFormState:N,get _fields(){return o},get _formValues(){return v},get _state(){return E},set _state(e){E=e},get _defaultValues(){return u},get _names(){return D},set _names(e){D=e},get _formState(){return n},get _options(){return t},set _options(e){t={...t,...e}}},subscribe:qe,trigger:Be,register:Xe,handleSubmit:$e,watch:Ge,setValue:$,setValues:Le,getValues:Ve,reset:nt,resetField:et,resetDefaultValues:(e,t={})=>{if(u=f(e),!t.keepDirty){let e=W(u,v);n.dirtyFields=e,n.isDirty=!z(e)}t.keepIsValid||L(),I.state.next({...n,defaultValues:u})},clearErrors:Ue,unregister:Je,setError:We,setFocus:rt,getFieldState:He};return{...at,formControl:at}}function Fe(e={}){let t=n.useRef(void 0),r=n.useRef(void 0),i=n.useRef(e.formControl),[a,o]=n.useState(()=>({...f(Ne),isLoading:w(e.defaultValues),errors:e.errors||{},disabled:e.disabled||!1,defaultValues:w(e.defaultValues)?void 0:e.defaultValues}));if(!t.current||e.formControl&&i.current!==e.formControl)if(i.current=e.formControl,e.formControl)t.current={...e.formControl,formState:a},e.defaultValues&&!w(e.defaultValues)&&e.formControl.reset(e.defaultValues,e.resetOptions);else{let{formControl:n,...r}=Pe(e);t.current={...r,formState:a}}let s=t.current.control;return s._options=e,k(()=>{let e=s._subscribe({formState:s._proxyFormState,callback:()=>o({...s._formState,defaultValues:s._defaultValues}),reRenderRoot:!0});return o(e=>({...e,isReady:!0})),s._formState.isReady=!0,e},[s]),n.useEffect(()=>s._disableForm(e.disabled),[s,e.disabled]),n.useEffect(()=>{e.mode&&(s._options.mode=e.mode),e.reValidateMode&&(s._options.reValidateMode=e.reValidateMode)},[s,e.mode,e.reValidateMode]),n.useEffect(()=>{e.errors&&(s._setErrors(e.errors),s._focusError())},[s,e.errors]),n.useEffect(()=>{e.shouldUnregister&&s._subjects.state.next({values:s._getWatch()})},[s,e.shouldUnregister]),n.useEffect(()=>{if(s._proxyFormState.isDirty){let e=s._getDirty();e!==a.isDirty&&s._subjects.state.next({isDirty:e})}},[s,a.isDirty]),n.useEffect(()=>{e.values&&!F(e.values,r.current)?(s._reset(e.values,{keepFieldsRef:!0,...s._options.resetOptions}),s._options.resetOptions?.keepIsValid||s._setValid(),r.current=e.values,o(e=>({...e}))):s._resetDefaultValues()},[s,e.values]),n.useEffect(()=>{s._state.mount||(s._setValid(),s._state.mount=!0),s._state.watch&&(s._state.watch=!1,s._subjects.state.next({...s._formState})),s._removeUnmounted()}),t.current.formState=n.useMemo(()=>O(a,s),[s,a]),t.current}var Ie=(e,t,n)=>{if(e&&`reportValidity`in e){let r=S(n,t);e.setCustomValidity(r&&r.message||``),e.reportValidity()}},$=(e,t)=>{for(let n in t.fields){let r=t.fields[n];r&&r.ref&&`reportValidity`in r.ref?Ie(r.ref,n,e):r&&r.refs&&r.refs.forEach(t=>Ie(t,n,e))}},Le=(e,t)=>{t.shouldUseNativeValidation&&$(e,t);let n={};for(let r in e){let i=S(t.fields,r),a=Object.assign(e[r]||{},{ref:i&&i.ref});if(Re(t.names||Object.keys(e),r)){let e=Object.assign({},S(n,r));T(e,`root`,a),T(n,r,e)}else T(n,r,a)}return n},Re=(e,t)=>{let n=ze(t).replace(/[.*+?^${}()|\\]/g,`\\$&`);return e.some(e=>ze(e).match(`^${n}\\.\\d+`))};function ze(e){return e.replace(/[\[\]]/g,``)}function Be(e){if(e.path?.length){let t=``;for(let n of e.path){let e=typeof n==`object`?n.key:n;if(typeof e==`string`||typeof e==`number`)t?t+=`.${e}`:t+=e;else return null}return t}return null}function Ve(){return Ve=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Ve.apply(null,arguments)}function He(e,t,n){return n===void 0&&(n={}),function(t,r,i){try{var a=function(){return o.issues?{values:{},errors:Le(function(e,t){for(var n={},r=0;r<e.length;r++){var i=e[r],a=Be(i);if(a&&(n[a]||(n[a]={message:i.message,type:``}),t)){var o,s=n[a].types||{};n[a].types=Ve({},s,((o={})[Object.keys(s).length]=i.message,o))}}return n}(o.issues,!i.shouldUseNativeValidation&&i.criteriaMode===`all`),i)}:(i.shouldUseNativeValidation&&$({},i),{values:n.raw?Object.assign({},t):o.value,errors:{}})},o=e[`~standard`].validate(t),s=function(){if(o instanceof Promise)return Promise.resolve(o).then(function(e){o=e})}();return Promise.resolve(s&&s.then?s.then(a):a())}catch(e){return Promise.reject(e)}}}export{I as i,te as n,Fe as r,He as t};
|
|
2
|
+
//# sourceMappingURL=standard-schema-o4V-s4uY.js.map
|