@tinyrack/issuary-server 0.22.0 → 0.23.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 +0 -18
- package/dist/entities/oauth-client.entity.d.ts.map +1 -1
- package/dist/entities/oauth-code.entity.d.ts +0 -18
- package/dist/entities/oauth-code.entity.d.ts.map +1 -1
- package/dist/entities/oauth-device-code.entity.d.ts +0 -18
- package/dist/entities/oauth-device-code.entity.d.ts.map +1 -1
- package/dist/entities/revoked-token.entity.d.ts +0 -18
- package/dist/entities/revoked-token.entity.d.ts.map +1 -1
- package/dist/entities/terms-content.entity.d.ts +0 -9
- package/dist/entities/terms-content.entity.d.ts.map +1 -1
- package/dist/entities/terms.entity.d.ts +0 -9
- package/dist/entities/terms.entity.d.ts.map +1 -1
- package/dist/entities/user-consent.entity.d.ts +0 -18
- package/dist/entities/user-consent.entity.d.ts.map +1 -1
- package/dist/entities/user-terms-consent.entity.d.ts +0 -9
- package/dist/entities/user-terms-consent.entity.d.ts.map +1 -1
- package/dist/entities/user-totp-recovery-code.entity.d.ts +0 -9
- package/dist/entities/user-totp-recovery-code.entity.d.ts.map +1 -1
- package/dist/entities/user-totp.entity.d.ts +0 -9
- package/dist/entities/user-totp.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.d.ts +0 -9
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +0 -4
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/entrypoints/app.d.ts +0 -53
- package/dist/entrypoints/app.d.ts.map +1 -1
- package/dist/entrypoints/database/postgres/compiled-functions.d.ts +20 -23
- package/dist/entrypoints/database/postgres/compiled-functions.d.ts.map +1 -1
- package/dist/entrypoints/database/postgres/compiled-functions.js +104 -134
- package/dist/entrypoints/database/postgres/compiled-functions.js.map +1 -1
- package/dist/entrypoints/database/sqlite/compiled-functions.d.ts +20 -23
- package/dist/entrypoints/database/sqlite/compiled-functions.d.ts.map +1 -1
- package/dist/entrypoints/database/sqlite/compiled-functions.js +104 -134
- package/dist/entrypoints/database/sqlite/compiled-functions.js.map +1 -1
- package/dist/lib/config/resolved.d.ts +0 -1
- package/dist/lib/config/resolved.d.ts.map +1 -1
- package/dist/lib/config/security.d.ts +0 -2
- package/dist/lib/config/security.d.ts.map +1 -1
- package/dist/lib/config/security.js +0 -5
- package/dist/lib/config/security.js.map +1 -1
- package/dist/middleware/auth.d.ts +0 -8
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +0 -64
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/session.d.ts +0 -9
- package/dist/middleware/session.d.ts.map +1 -1
- package/dist/middleware/session.js +0 -18
- package/dist/middleware/session.js.map +1 -1
- package/dist/migrations/postgres/Migration20260825140000_drop_password_reset_required.d.ts +6 -0
- package/dist/migrations/postgres/Migration20260825140000_drop_password_reset_required.d.ts.map +1 -0
- package/dist/migrations/postgres/Migration20260825140000_drop_password_reset_required.js +19 -0
- package/dist/migrations/postgres/Migration20260825140000_drop_password_reset_required.js.map +1 -0
- package/dist/migrations/postgres/index.d.ts.map +1 -1
- package/dist/migrations/postgres/index.js +2 -0
- package/dist/migrations/postgres/index.js.map +1 -1
- package/dist/migrations/sqlite/Migration20260825140000_drop_password_reset_required.d.ts +6 -0
- package/dist/migrations/sqlite/Migration20260825140000_drop_password_reset_required.d.ts.map +1 -0
- package/dist/migrations/sqlite/Migration20260825140000_drop_password_reset_required.js +19 -0
- package/dist/migrations/sqlite/Migration20260825140000_drop_password_reset_required.js.map +1 -0
- package/dist/migrations/sqlite/index.d.ts.map +1 -1
- package/dist/migrations/sqlite/index.js +2 -0
- package/dist/migrations/sqlite/index.js.map +1 -1
- package/dist/repositories/oauth-code.repository.d.ts +2 -2
- package/dist/repositories/oauth-code.repository.d.ts.map +1 -1
- package/dist/repositories/oauth-code.repository.js +3 -7
- package/dist/repositories/oauth-code.repository.js.map +1 -1
- package/dist/repositories/oauth-device-code.repository.d.ts +4 -4
- package/dist/repositories/oauth-device-code.repository.d.ts.map +1 -1
- package/dist/repositories/oauth-device-code.repository.js +6 -18
- package/dist/repositories/oauth-device-code.repository.js.map +1 -1
- package/dist/repositories/user-totp-recovery-code.repository.d.ts +1 -7
- package/dist/repositories/user-totp-recovery-code.repository.d.ts.map +1 -1
- package/dist/repositories/user-totp-recovery-code.repository.js +1 -2
- package/dist/repositories/user-totp-recovery-code.repository.js.map +1 -1
- package/dist/repositories/user-totp.repository.d.ts +0 -9
- package/dist/repositories/user-totp.repository.d.ts.map +1 -1
- package/dist/routes/api/auth/index.d.ts +0 -52
- package/dist/routes/api/auth/index.d.ts.map +1 -1
- package/dist/routes/api/auth/index.js +0 -2
- package/dist/routes/api/auth/index.js.map +1 -1
- package/dist/routes/api/auth/passkey/verify/post.d.ts +0 -37
- package/dist/routes/api/auth/passkey/verify/post.d.ts.map +1 -1
- package/dist/routes/api/auth/passkey/verify/post.js +2 -8
- package/dist/routes/api/auth/passkey/verify/post.js.map +1 -1
- package/dist/routes/api/index.d.ts +0 -52
- package/dist/routes/api/index.d.ts.map +1 -1
- package/dist/routes/index.d.ts +0 -52
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/oauth/device/get-post.js +5 -5
- package/dist/routes/oauth/device/get-post.js.map +1 -1
- package/dist/schemas/error.d.ts +0 -25
- package/dist/schemas/error.d.ts.map +1 -1
- package/dist/schemas/error.js +0 -1
- package/dist/schemas/error.js.map +1 -1
- package/dist/schemas/response.d.ts +0 -22
- package/dist/schemas/response.d.ts.map +1 -1
- package/dist/schemas/response.js +0 -8
- package/dist/schemas/response.js.map +1 -1
- package/dist/seeders/config.seeder.js +0 -1
- package/dist/seeders/config.seeder.js.map +1 -1
- package/dist/services/container.d.ts +0 -1
- package/dist/services/container.d.ts.map +1 -1
- package/dist/services/container.js +0 -15
- package/dist/services/container.js.map +1 -1
- package/dist/services/oauth-client.service.d.ts +0 -1
- package/dist/services/oauth-client.service.d.ts.map +1 -1
- package/dist/services/oauth-client.service.js +2 -17
- package/dist/services/oauth-client.service.js.map +1 -1
- package/dist/services/oauth-connect.service.d.ts.map +1 -1
- package/dist/services/oauth-connect.service.js +0 -4
- package/dist/services/oauth-connect.service.js.map +1 -1
- package/dist/services/oauth-token.service.d.ts.map +1 -1
- package/dist/services/oauth-token.service.js +4 -4
- package/dist/services/oauth-token.service.js.map +1 -1
- package/dist/services/password-auth.service.d.ts.map +1 -1
- package/dist/services/password-auth.service.js +3 -12
- package/dist/services/password-auth.service.js.map +1 -1
- package/dist/services/security.service.d.ts +0 -8
- package/dist/services/security.service.d.ts.map +1 -1
- package/dist/services/security.service.js +21 -82
- package/dist/services/security.service.js.map +1 -1
- package/dist/services/totp.service.js +2 -2
- package/dist/services/totp.service.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/2fa-B5vLgDXQ.js +2 -0
- package/public/assets/{2fa-BgveHSB_.js.map → 2fa-B5vLgDXQ.js.map} +1 -1
- package/public/assets/2fa-BqsM_D-X.js +2 -0
- package/public/assets/{2fa-kiqzGSz2.js.map → 2fa-BqsM_D-X.js.map} +1 -1
- package/public/assets/2fa-C5vUVgr_.js +2 -0
- package/public/assets/{2fa-UL_cNRnQ.js.map → 2fa-C5vUVgr_.js.map} +1 -1
- package/public/assets/2fa-CCOTIHDZ.js +2 -0
- package/public/assets/{2fa-C37MUkye.js.map → 2fa-CCOTIHDZ.js.map} +1 -1
- package/public/assets/{DialogHandle-Zvz8SgS0.js → DialogHandle-BmtK2pRn.js} +2 -2
- package/public/assets/{DialogHandle-Zvz8SgS0.js.map → DialogHandle-BmtK2pRn.js.map} +1 -1
- package/public/assets/admin-BPijkLw-.js +2 -0
- package/public/assets/{admin-DbDuu6AI.js.map → admin-BPijkLw-.js.map} +1 -1
- package/public/assets/admin-users-DvPbw1Vq.js +2 -0
- package/public/assets/{admin-users-CwTJdiih.js.map → admin-users-DvPbw1Vq.js.map} +1 -1
- package/public/assets/{auth-choice-row-BlSsUI7d.js → auth-choice-row-BCGjuedo.js} +2 -2
- package/public/assets/{auth-choice-row-BlSsUI7d.js.map → auth-choice-row-BCGjuedo.js.map} +1 -1
- package/public/assets/{auth-field-HwxENJnB.js → auth-field-DD8kvl--.js} +2 -2
- package/public/assets/{auth-field-HwxENJnB.js.map → auth-field-DD8kvl--.js.map} +1 -1
- package/public/assets/{auth-layout-CoeqNhTT.js → auth-layout-VtpryDof.js} +2 -2
- package/public/assets/{auth-layout-CoeqNhTT.js.map → auth-layout-VtpryDof.js.map} +1 -1
- package/public/assets/{auth-page-header-CIs08f5Y.js → auth-page-header-CIn2E4zI.js} +2 -2
- package/public/assets/{auth-page-header-CIs08f5Y.js.map → auth-page-header-CIn2E4zI.js.map} +1 -1
- package/public/assets/{authorization-context-banner-BbtQmMYH.js → authorization-context-banner-SOuBHWIb.js} +2 -2
- package/public/assets/{authorization-context-banner-BbtQmMYH.js.map → authorization-context-banner-SOuBHWIb.js.map} +1 -1
- package/public/assets/{avatar-CttWiIv3.js → avatar-BEQjf2x6.js} +2 -2
- package/public/assets/{avatar-CttWiIv3.js.map → avatar-BEQjf2x6.js.map} +1 -1
- package/public/assets/{checkbox-CJrRV8S1.js → checkbox-gdHnSFQ-.js} +2 -2
- package/public/assets/{checkbox-CJrRV8S1.js.map → checkbox-gdHnSFQ-.js.map} +1 -1
- package/public/assets/config-DTQCUlfZ.js +2 -0
- package/public/assets/config-DTQCUlfZ.js.map +1 -0
- package/public/assets/{consent-BIhxtXHx.js → consent-BqqFDdsr.js} +2 -2
- package/public/assets/{consent-BIhxtXHx.js.map → consent-BqqFDdsr.js.map} +1 -1
- package/public/assets/{consent-DRmENn26.js → consent-CfRbz2R7.js} +2 -2
- package/public/assets/{consent-DRmENn26.js.map → consent-CfRbz2R7.js.map} +1 -1
- package/public/assets/email-C5vUVgr_.js +2 -0
- package/public/assets/{email-UL_cNRnQ.js.map → email-C5vUVgr_.js.map} +1 -1
- package/public/assets/{email-CVRDeJ78.js → email-CKKakxPJ.js} +2 -2
- package/public/assets/{email-CVRDeJ78.js.map → email-CKKakxPJ.js.map} +1 -1
- package/public/assets/error-BMXxpgfR.js +2 -0
- package/public/assets/{error-2VPY5w8V.js.map → error-BMXxpgfR.js.map} +1 -1
- package/public/assets/{field-DDt6F9TZ.js → field-Cn4H1CUj.js} +2 -2
- package/public/assets/{field-DDt6F9TZ.js.map → field-Cn4H1CUj.js.map} +1 -1
- package/public/assets/forgot-C5vUVgr_.js +2 -0
- package/public/assets/{forgot-UL_cNRnQ.js.map → forgot-C5vUVgr_.js.map} +1 -1
- package/public/assets/forgot-rO9sByfV.js +2 -0
- package/public/assets/{forgot-DzDcduho.js.map → forgot-rO9sByfV.js.map} +1 -1
- package/public/assets/index-CS23Ozt6.js +11 -0
- package/public/assets/index-CS23Ozt6.js.map +1 -0
- package/public/assets/{initial-avatar-CZzHAPm3.js → initial-avatar-CtuDUz_W.js} +2 -2
- package/public/assets/{initial-avatar-CZzHAPm3.js.map → initial-avatar-CtuDUz_W.js.map} +1 -1
- package/public/assets/{input-CNRpSR08.js → input-CzQki7k6.js} +2 -2
- package/public/assets/{input-CNRpSR08.js.map → input-CzQki7k6.js.map} +1 -1
- package/public/assets/{labeled-separator-fnKySKv2.js → labeled-separator-CV7nb0XW.js} +2 -2
- package/public/assets/{labeled-separator-fnKySKv2.js.map → labeled-separator-CV7nb0XW.js.map} +1 -1
- package/public/assets/login-C5vUVgr_.js +2 -0
- package/public/assets/login-C5vUVgr_.js.map +1 -0
- package/public/assets/login-nukebli4.js +2 -0
- package/public/assets/login-nukebli4.js.map +1 -0
- package/public/assets/{logout-CHdmF_16.js → logout-B5T52P8u.js} +2 -2
- package/public/assets/{logout-CHdmF_16.js.map → logout-B5T52P8u.js.map} +1 -1
- package/public/assets/{modal-sCM_zT82.js → modal-BDQFucjz.js} +2 -2
- package/public/assets/{modal-sCM_zT82.js.map → modal-BDQFucjz.js.map} +1 -1
- package/public/assets/{mutationOptions-CrswitPs.js → mutationOptions-DyYFUbyn.js} +2 -2
- package/public/assets/{mutationOptions-CrswitPs.js.map → mutationOptions-DyYFUbyn.js.map} +1 -1
- package/public/assets/passkey-BE9JvJOP.js +2 -0
- package/public/assets/{passkey-CU8x9J2w.js.map → passkey-BE9JvJOP.js.map} +1 -1
- package/public/assets/passkey-C5vUVgr_.js +2 -0
- package/public/assets/{passkey-UL_cNRnQ.js.map → passkey-C5vUVgr_.js.map} +1 -1
- package/public/assets/passkey-CynCz1Dt.js +2 -0
- package/public/assets/{passkey-CEx1VZ5R.js.map → passkey-CynCz1Dt.js.map} +1 -1
- package/public/assets/passkey-J1qnYp9A.js +2 -0
- package/public/assets/{passkey-B2Blw47e.js.map → passkey-J1qnYp9A.js.map} +1 -1
- package/public/assets/password-C5vUVgr_.js +2 -0
- package/public/assets/password-C5vUVgr_.js.map +1 -0
- package/public/assets/password-RkUttbhD.js +2 -0
- package/public/assets/password-RkUttbhD.js.map +1 -0
- package/public/assets/password-reset-sU5KkBKi.js +2 -0
- package/public/assets/{password-reset-CIacHnvA.js.map → password-reset-sU5KkBKi.js.map} +1 -1
- package/public/assets/{password-strength-C0Zkrrct.js → password-strength-BeSOu_Ga.js} +2 -2
- package/public/assets/{password-strength-C0Zkrrct.js.map → password-strength-BeSOu_Ga.js.map} +1 -1
- package/public/assets/{pin-input-BlD4tPZJ.js → pin-input-Cc-VkrQ3.js} +2 -2
- package/public/assets/{pin-input-BlD4tPZJ.js.map → pin-input-Cc-VkrQ3.js.map} +1 -1
- package/public/assets/{profile-D43Yq-6S.js → profile-B5NaJfeS.js} +2 -2
- package/public/assets/{profile-D43Yq-6S.js.map → profile-B5NaJfeS.js.map} +1 -1
- package/public/assets/{profile-D1cEjfs8.js → profile-BcjsVYOx.js} +2 -2
- package/public/assets/{profile-D1cEjfs8.js.map → profile-BcjsVYOx.js.map} +1 -1
- package/public/assets/recovery-PnUATiUi.js +2 -0
- package/public/assets/{recovery-CLExnfYX.js.map → recovery-PnUATiUi.js.map} +1 -1
- package/public/assets/register-C5vUVgr_.js +2 -0
- package/public/assets/{register-UL_cNRnQ.js.map → register-C5vUVgr_.js.map} +1 -1
- package/public/assets/register-DQXhru0_.js +2 -0
- package/public/assets/{register-CZUyWXRO.js.map → register-DQXhru0_.js.map} +1 -1
- package/public/assets/reset-C5vUVgr_.js +2 -0
- package/public/assets/{reset-UL_cNRnQ.js.map → reset-C5vUVgr_.js.map} +1 -1
- package/public/assets/reset-CQgIa3yf.js +2 -0
- package/public/assets/reset-CQgIa3yf.js.map +1 -0
- package/public/assets/select-C5vUVgr_.js +2 -0
- package/public/assets/{select-UL_cNRnQ.js.map → select-C5vUVgr_.js.map} +1 -1
- package/public/assets/{select-CWdSzsVo.js → select-DqZynXSt.js} +2 -2
- package/public/assets/{select-CWdSzsVo.js.map → select-DqZynXSt.js.map} +1 -1
- package/public/assets/{separator-BWGym8uM.js → separator-B0Bvh1he.js} +2 -2
- package/public/assets/{separator-BWGym8uM.js.map → separator-B0Bvh1he.js.map} +1 -1
- package/public/assets/shell-header-bar-CjG5qvPg.js +2 -0
- package/public/assets/{shell-header-bar-C9AB5lT-.js.map → shell-header-bar-CjG5qvPg.js.map} +1 -1
- package/public/assets/{terms-D43Yq-6S.js → terms-B5NaJfeS.js} +2 -2
- package/public/assets/{terms-D43Yq-6S.js.map → terms-B5NaJfeS.js.map} +1 -1
- package/public/assets/{terms-COVFmzyl.js → terms-BHDAgn-H.js} +2 -2
- package/public/assets/{terms-COVFmzyl.js.map → terms-BHDAgn-H.js.map} +1 -1
- package/public/assets/{terms-checkbox-list-Cw0zB-lO.js → terms-checkbox-list-6jteUTIZ.js} +2 -2
- package/public/assets/{terms-checkbox-list-Cw0zB-lO.js.map → terms-checkbox-list-6jteUTIZ.js.map} +1 -1
- package/public/assets/{totp-BfCm6IWl.js → totp-BNZ904Zm.js} +2 -2
- package/public/assets/{totp-BfCm6IWl.js.map → totp-BNZ904Zm.js.map} +1 -1
- package/public/assets/totp-CJtfVNEq.js +2 -0
- package/public/assets/{totp-BFJEXxk0.js.map → totp-CJtfVNEq.js.map} +1 -1
- package/public/assets/totp-ECvOUcFx.js +2 -0
- package/public/assets/{totp-MINhsVxT.js.map → totp-ECvOUcFx.js.map} +1 -1
- package/public/assets/use-totp-setup-BbS3XcZA.js +3 -0
- package/public/assets/{use-totp-setup-C7Zk_2IY.js.map → use-totp-setup-BbS3XcZA.js.map} +1 -1
- package/public/assets/{useAriaLabelledBy-CiOCg6X5.js → useAriaLabelledBy-ByuMi3Ry.js} +2 -2
- package/public/assets/{useAriaLabelledBy-CiOCg6X5.js.map → useAriaLabelledBy-ByuMi3Ry.js.map} +1 -1
- package/public/assets/{useMutation-ZLFeJg75.js → useMutation-BWZ0G4Td.js} +2 -2
- package/public/assets/{useMutation-ZLFeJg75.js.map → useMutation-BWZ0G4Td.js.map} +1 -1
- package/public/assets/useQuery-Ckxjmvtl.js +2 -0
- package/public/assets/{useQuery-BvMz34BW.js.map → useQuery-Ckxjmvtl.js.map} +1 -1
- package/public/assets/{users-COM7u3A-.js → users-CmFxrCQT.js} +2 -2
- package/public/assets/{users-COM7u3A-.js.map → users-CmFxrCQT.js.map} +1 -1
- package/public/index.html +3 -4
- package/dist/routes/api/auth/password/reset-required/post.d.ts +0 -18
- package/dist/routes/api/auth/password/reset-required/post.d.ts.map +0 -1
- package/dist/routes/api/auth/password/reset-required/post.js +0 -39
- package/dist/routes/api/auth/password/reset-required/post.js.map +0 -1
- package/dist/services/legacy-credential-retirement.service.d.ts +0 -20
- package/dist/services/legacy-credential-retirement.service.d.ts.map +0 -1
- package/dist/services/legacy-credential-retirement.service.js +0 -90
- package/dist/services/legacy-credential-retirement.service.js.map +0 -1
- package/public/assets/2fa-BgveHSB_.js +0 -2
- package/public/assets/2fa-C37MUkye.js +0 -2
- package/public/assets/2fa-UL_cNRnQ.js +0 -2
- package/public/assets/2fa-kiqzGSz2.js +0 -2
- package/public/assets/admin-DbDuu6AI.js +0 -2
- package/public/assets/admin-users-CwTJdiih.js +0 -2
- package/public/assets/config-v3-oy_ef.js +0 -2
- package/public/assets/config-v3-oy_ef.js.map +0 -1
- package/public/assets/email-UL_cNRnQ.js +0 -2
- package/public/assets/error-2VPY5w8V.js +0 -2
- package/public/assets/forgot-DzDcduho.js +0 -2
- package/public/assets/forgot-UL_cNRnQ.js +0 -2
- package/public/assets/index-gliHKncz.js +0 -11
- package/public/assets/index-gliHKncz.js.map +0 -1
- package/public/assets/link-BN90emXr.js +0 -2
- package/public/assets/link-BN90emXr.js.map +0 -1
- package/public/assets/lock-keyhole-Cz72xkCn.js +0 -2
- package/public/assets/lock-keyhole-Cz72xkCn.js.map +0 -1
- package/public/assets/login-C6m2qSUt.js +0 -2
- package/public/assets/login-C6m2qSUt.js.map +0 -1
- package/public/assets/login-UL_cNRnQ.js +0 -2
- package/public/assets/login-UL_cNRnQ.js.map +0 -1
- package/public/assets/passkey-B2Blw47e.js +0 -2
- package/public/assets/passkey-CEx1VZ5R.js +0 -2
- package/public/assets/passkey-CU8x9J2w.js +0 -2
- package/public/assets/passkey-UL_cNRnQ.js +0 -2
- package/public/assets/password-BhU_a0cR.js +0 -2
- package/public/assets/password-BhU_a0cR.js.map +0 -1
- package/public/assets/password-UL_cNRnQ.js +0 -2
- package/public/assets/password-UL_cNRnQ.js.map +0 -1
- package/public/assets/password-reset-CIacHnvA.js +0 -2
- package/public/assets/recovery-CLExnfYX.js +0 -2
- package/public/assets/register-CZUyWXRO.js +0 -2
- package/public/assets/register-UL_cNRnQ.js +0 -2
- package/public/assets/reset-N3RQTYEB.js +0 -2
- package/public/assets/reset-N3RQTYEB.js.map +0 -1
- package/public/assets/reset-UL_cNRnQ.js +0 -2
- package/public/assets/reset-required-Cv5edDS6.js +0 -2
- package/public/assets/reset-required-Cv5edDS6.js.map +0 -1
- package/public/assets/reset-required-UL_cNRnQ.js +0 -2
- package/public/assets/reset-required-UL_cNRnQ.js.map +0 -1
- package/public/assets/select-UL_cNRnQ.js +0 -2
- package/public/assets/shell-header-bar-C9AB5lT-.js +0 -2
- package/public/assets/totp-BFJEXxk0.js +0 -2
- package/public/assets/totp-MINhsVxT.js +0 -2
- package/public/assets/use-totp-setup-C7Zk_2IY.js +0 -3
- package/public/assets/useQuery-BvMz34BW.js +0 -2
package/public/assets/{password-strength-C0Zkrrct.js.map → password-strength-BeSOu_Ga.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-strength-C0Zkrrct.js","names":["_formatErrorMessage","Meter.Indicator","Meter.Label","Meter.Root","Meter.Track","Meter.Value"],"sources":["../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/root/MeterRootContext.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/root/MeterRoot.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/track/MeterTrack.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/indicator/MeterIndicator.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/value/MeterValue.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/label/MeterLabel.mjs","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-indicator.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-label.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-root.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-track.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-value.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/index.js","../../../frontend/src/components/auth/password-strength.tsx"],"sourcesContent":["'use client';\n\nimport _formatErrorMessage from \"@base-ui/utils/formatErrorMessage\";\nimport * as React from 'react';\nexport const MeterRootContext = /*#__PURE__*/React.createContext(undefined);\nif (process.env.NODE_ENV !== \"production\") MeterRootContext.displayName = \"MeterRootContext\";\nexport function useMeterRootContext() {\n const context = React.useContext(MeterRootContext);\n if (context === undefined) {\n throw new Error(process.env.NODE_ENV !== \"production\" ? 'Base UI: MeterRootContext is missing. Meter parts must be placed within <Meter.Root>.' : _formatErrorMessage(38));\n }\n return context;\n}","'use client';\n\nimport * as React from 'react';\nimport { visuallyHidden } from '@base-ui/utils/visuallyHidden';\nimport { MeterRootContext } from \"./MeterRootContext.mjs\";\nimport { formatNumber } from \"../../utils/formatNumber.mjs\";\nimport { valueToPercent } from \"../../utils/valueToPercent.mjs\";\nimport { clamp } from \"../../internals/clamp.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * Groups all parts of the meter and provides the value for screen readers.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nexport const MeterRoot = /*#__PURE__*/React.forwardRef(function MeterRoot(componentProps, forwardedRef) {\n const {\n format,\n getAriaValueText,\n locale,\n max = 100,\n min = 0,\n value: valueProp,\n render,\n className,\n children,\n style,\n ...elementProps\n } = componentProps;\n const [labelId, setLabelId] = React.useState();\n\n // `clamp` handles infinity, but NaN needs an explicit fallback before normalizing range outputs.\n const rawPercentage = valueToPercent(valueProp, min, max);\n const percentageValue = clamp(Number.isNaN(rawPercentage) ? 0 : rawPercentage, 0, 100);\n const clampedValue = clamp(Number.isNaN(valueProp) ? min : valueProp, min, max);\n\n // Format the clamped value so visible and accessible text stay in sync with `aria-valuenow` and\n // the indicator fill. The raw value remains available as the second `getAriaValueText` argument.\n const formattedValue = format ? formatNumber(clampedValue, locale, format) : formatNumber(percentageValue / 100, locale, {\n style: 'percent'\n });\n let ariaValuetext = formattedValue;\n if (getAriaValueText) {\n ariaValuetext = getAriaValueText(formattedValue, valueProp);\n }\n const defaultProps = {\n 'aria-labelledby': labelId,\n 'aria-valuemax': max,\n 'aria-valuemin': min,\n 'aria-valuenow': clampedValue,\n 'aria-valuetext': ariaValuetext,\n role: 'meter',\n children: /*#__PURE__*/_jsxs(React.Fragment, {\n children: [children, /*#__PURE__*/_jsx(\"span\", {\n role: \"presentation\",\n style: visuallyHidden,\n children: \"x\"\n })]\n })\n };\n const contextValue = React.useMemo(() => ({\n formattedValue,\n percentageValue,\n setLabelId,\n value: valueProp\n }), [formattedValue, percentageValue, setLabelId, valueProp]);\n const element = useRenderElement('div', componentProps, {\n ref: forwardedRef,\n props: [defaultProps, elementProps]\n });\n return /*#__PURE__*/_jsx(MeterRootContext.Provider, {\n value: contextValue,\n children: element\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterRoot.displayName = \"MeterRoot\";","'use client';\n\nimport * as React from 'react';\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * Contains the meter indicator and represents the entire range of the meter.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterTrack = /*#__PURE__*/React.forwardRef(function MeterTrack(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n return useRenderElement('div', componentProps, {\n ref: forwardedRef,\n props: elementProps\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterTrack.displayName = \"MeterTrack\";","'use client';\n\nimport * as React from 'react';\nimport { useMeterRootContext } from \"../root/MeterRootContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * Visualizes the position of the value along the range.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterIndicator = /*#__PURE__*/React.forwardRef(function MeterIndicator(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n const {\n percentageValue\n } = useMeterRootContext();\n return useRenderElement('div', componentProps, {\n ref: forwardedRef,\n props: [{\n style: {\n insetInlineStart: 0,\n height: 'inherit',\n width: `${percentageValue}%`\n }\n }, elementProps]\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterIndicator.displayName = \"MeterIndicator\";","'use client';\n\nimport * as React from 'react';\nimport { useMeterRootContext } from \"../root/MeterRootContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * A text element displaying the current value.\n * Renders a `<span>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterValue = /*#__PURE__*/React.forwardRef(function MeterValue(componentProps, forwardedRef) {\n const {\n className,\n render,\n children,\n style,\n ...elementProps\n } = componentProps;\n const {\n value,\n formattedValue\n } = useMeterRootContext();\n return useRenderElement('span', componentProps, {\n ref: forwardedRef,\n props: [{\n 'aria-hidden': true,\n children: typeof children === 'function' ? children(formattedValue, value) : formattedValue\n }, elementProps]\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterValue.displayName = \"MeterValue\";","'use client';\n\nimport * as React from 'react';\nimport { useMeterRootContext } from \"../root/MeterRootContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\nimport { useRegisteredLabelId } from \"../../utils/useRegisteredLabelId.mjs\";\n\n/**\n * An accessible label for the meter.\n * Renders a `<span>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterLabel = /*#__PURE__*/React.forwardRef(function MeterLabel(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n id: idProp,\n ...elementProps\n } = componentProps;\n const {\n setLabelId\n } = useMeterRootContext();\n const id = useRegisteredLabelId(idProp, setLabelId);\n return useRenderElement('span', componentProps, {\n ref: forwardedRef,\n props: [{\n id,\n role: 'presentation'\n }, elementProps]\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterLabel.displayName = \"MeterLabel\";","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-indicator.tsx\nconst TRMeterIndicator = createComponentPart(Meter.Indicator, \"tr-meter-indicator\");\n//#endregion\nexport { TRMeterIndicator };\n\n//# sourceMappingURL=meter-indicator.js.map","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-label.tsx\nconst TRMeterLabel = createComponentPart(Meter.Label, \"tr-meter-label\");\n//#endregion\nexport { TRMeterLabel };\n\n//# sourceMappingURL=meter-label.js.map","\"use client\";\nimport { mergeComponentClassName } from \"../../internal/component-class-name.js\";\nimport { jsx } from \"react/jsx-runtime\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-root.tsx\nfunction TRMeterRoot({ className, max = 100, min = 0, value, variant = \"neutral\", ...props }) {\n\tconst clampedValue = Math.min(max, Math.max(min, Number.isNaN(value) ? min : value));\n\treturn /* @__PURE__ */ jsx(Meter.Root, {\n\t\t...props,\n\t\tclassName: mergeComponentClassName(\"tr-meter\", className),\n\t\t\"data-variant\": variant,\n\t\tmax,\n\t\tmin,\n\t\tvalue: clampedValue\n\t});\n}\n//#endregion\nexport { TRMeterRoot };\n\n//# sourceMappingURL=meter-root.js.map","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-track.tsx\nconst TRMeterTrack = createComponentPart(Meter.Track, \"tr-meter-track\");\n//#endregion\nexport { TRMeterTrack };\n\n//# sourceMappingURL=meter-track.js.map","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-value.tsx\nconst TRMeterValue = createComponentPart(Meter.Value, \"tr-meter-value\");\n//#endregion\nexport { TRMeterValue };\n\n//# sourceMappingURL=meter-value.js.map","import { TRMeterIndicator } from \"./meter-indicator.js\";\nimport { TRMeterLabel } from \"./meter-label.js\";\nimport { TRMeterRoot } from \"./meter-root.js\";\nimport { TRMeterTrack } from \"./meter-track.js\";\nimport { TRMeterValue } from \"./meter-value.js\";\n//#region src/components/meter/index.tsx\nconst TRMeter = {\n\tRoot: TRMeterRoot,\n\tTrack: TRMeterTrack,\n\tIndicator: TRMeterIndicator,\n\tValue: TRMeterValue,\n\tLabel: TRMeterLabel\n};\n//#endregion\nexport { TRMeter, TRMeterIndicator, TRMeterLabel, TRMeterRoot, TRMeterTrack, TRMeterValue };\n\n//# sourceMappingURL=index.js.map","import { TRMeter } from '@tinyrack/ui/components/meter';\nimport { TRText } from '@tinyrack/ui/components/text';\nimport { useTranslation } from 'react-i18next';\n\ntype PasswordPolicy = {\n min_length: number;\n max_length: number;\n};\n\ntype PasswordStrengthProps = {\n password: string;\n policy: PasswordPolicy;\n};\n\nconst LEVELS = ['weak', 'fair', 'good', 'strong'] as const;\n\nconst VARIANTS = {\n weak: 'danger',\n fair: 'warning',\n good: 'info',\n strong: 'success',\n} as const;\n\n/**\n * Scores a password 1-4 for feedback only.\n *\n * Deliberately simple: length against the deployment's own policy plus\n * character-class variety. The server is the authority on what is acceptable,\n * so this only needs to steer the user, and a full entropy estimator would be\n * a large dependency for a hint bar.\n *\n * Returns 0 for \"nothing to say yet\" so the caller can stay silent.\n */\nfunction scorePassword(password: string, policy: PasswordPolicy): number {\n if (password.length === 0) {\n return 0;\n }\n if (password.length < policy.min_length) {\n return 1;\n }\n\n const classes = [/[a-z]/, /[A-Z]/, /\\d/, /[^a-zA-Z0-9]/].filter((pattern) =>\n pattern.test(password),\n ).length;\n\n const isLong = password.length >= policy.min_length + 4;\n\n if (classes >= 3 && isLong) {\n return 4;\n }\n if (classes >= 2 && isLong) {\n return 3;\n }\n return 2;\n}\n\n/**\n * Strength hint under a new-password field.\n *\n * Renders nothing for an empty field so the form does not shift as soon as it\n * is focused. Announced politely rather than assertively — it updates on every\n * keystroke and should not interrupt typing.\n */\nexport function PasswordStrength({ password, policy }: PasswordStrengthProps) {\n const { t } = useTranslation();\n const score = scorePassword(password, policy);\n\n if (score === 0) {\n return null;\n }\n\n const level = LEVELS[score - 1];\n\n return (\n <TRMeter.Root\n aria-live=\"polite\"\n className=\"flex flex-col gap-tinyrack-xs\"\n max={4}\n min={0}\n value={score}\n variant={VARIANTS[level]}\n >\n <div className=\"flex items-baseline justify-between gap-tinyrack-sm\">\n <TRMeter.Label\n render={\n <TRText color=\"muted\" variant=\"caption\">\n {t('validation.password.strength.label')}\n </TRText>\n }\n />\n <TRMeter.Value\n render={\n <TRText color=\"muted\" variant=\"caption\">\n {t(`validation.password.strength.${level}`)}\n </TRText>\n }\n />\n </div>\n <TRMeter.Track>\n <TRMeter.Indicator />\n </TRMeter.Track>\n </TRMeter.Root>\n );\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"password-strength-BeSOu_Ga.js","names":["_formatErrorMessage","Meter.Indicator","Meter.Label","Meter.Root","Meter.Track","Meter.Value"],"sources":["../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/root/MeterRootContext.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/root/MeterRoot.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/track/MeterTrack.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/indicator/MeterIndicator.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/value/MeterValue.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/meter/label/MeterLabel.mjs","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-indicator.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-label.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-root.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-track.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/meter-value.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/meter/index.js","../../../frontend/src/components/auth/password-strength.tsx"],"sourcesContent":["'use client';\n\nimport _formatErrorMessage from \"@base-ui/utils/formatErrorMessage\";\nimport * as React from 'react';\nexport const MeterRootContext = /*#__PURE__*/React.createContext(undefined);\nif (process.env.NODE_ENV !== \"production\") MeterRootContext.displayName = \"MeterRootContext\";\nexport function useMeterRootContext() {\n const context = React.useContext(MeterRootContext);\n if (context === undefined) {\n throw new Error(process.env.NODE_ENV !== \"production\" ? 'Base UI: MeterRootContext is missing. Meter parts must be placed within <Meter.Root>.' : _formatErrorMessage(38));\n }\n return context;\n}","'use client';\n\nimport * as React from 'react';\nimport { visuallyHidden } from '@base-ui/utils/visuallyHidden';\nimport { MeterRootContext } from \"./MeterRootContext.mjs\";\nimport { formatNumber } from \"../../utils/formatNumber.mjs\";\nimport { valueToPercent } from \"../../utils/valueToPercent.mjs\";\nimport { clamp } from \"../../internals/clamp.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * Groups all parts of the meter and provides the value for screen readers.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nexport const MeterRoot = /*#__PURE__*/React.forwardRef(function MeterRoot(componentProps, forwardedRef) {\n const {\n format,\n getAriaValueText,\n locale,\n max = 100,\n min = 0,\n value: valueProp,\n render,\n className,\n children,\n style,\n ...elementProps\n } = componentProps;\n const [labelId, setLabelId] = React.useState();\n\n // `clamp` handles infinity, but NaN needs an explicit fallback before normalizing range outputs.\n const rawPercentage = valueToPercent(valueProp, min, max);\n const percentageValue = clamp(Number.isNaN(rawPercentage) ? 0 : rawPercentage, 0, 100);\n const clampedValue = clamp(Number.isNaN(valueProp) ? min : valueProp, min, max);\n\n // Format the clamped value so visible and accessible text stay in sync with `aria-valuenow` and\n // the indicator fill. The raw value remains available as the second `getAriaValueText` argument.\n const formattedValue = format ? formatNumber(clampedValue, locale, format) : formatNumber(percentageValue / 100, locale, {\n style: 'percent'\n });\n let ariaValuetext = formattedValue;\n if (getAriaValueText) {\n ariaValuetext = getAriaValueText(formattedValue, valueProp);\n }\n const defaultProps = {\n 'aria-labelledby': labelId,\n 'aria-valuemax': max,\n 'aria-valuemin': min,\n 'aria-valuenow': clampedValue,\n 'aria-valuetext': ariaValuetext,\n role: 'meter',\n children: /*#__PURE__*/_jsxs(React.Fragment, {\n children: [children, /*#__PURE__*/_jsx(\"span\", {\n role: \"presentation\",\n style: visuallyHidden,\n children: \"x\"\n })]\n })\n };\n const contextValue = React.useMemo(() => ({\n formattedValue,\n percentageValue,\n setLabelId,\n value: valueProp\n }), [formattedValue, percentageValue, setLabelId, valueProp]);\n const element = useRenderElement('div', componentProps, {\n ref: forwardedRef,\n props: [defaultProps, elementProps]\n });\n return /*#__PURE__*/_jsx(MeterRootContext.Provider, {\n value: contextValue,\n children: element\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterRoot.displayName = \"MeterRoot\";","'use client';\n\nimport * as React from 'react';\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * Contains the meter indicator and represents the entire range of the meter.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterTrack = /*#__PURE__*/React.forwardRef(function MeterTrack(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n return useRenderElement('div', componentProps, {\n ref: forwardedRef,\n props: elementProps\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterTrack.displayName = \"MeterTrack\";","'use client';\n\nimport * as React from 'react';\nimport { useMeterRootContext } from \"../root/MeterRootContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * Visualizes the position of the value along the range.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterIndicator = /*#__PURE__*/React.forwardRef(function MeterIndicator(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n const {\n percentageValue\n } = useMeterRootContext();\n return useRenderElement('div', componentProps, {\n ref: forwardedRef,\n props: [{\n style: {\n insetInlineStart: 0,\n height: 'inherit',\n width: `${percentageValue}%`\n }\n }, elementProps]\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterIndicator.displayName = \"MeterIndicator\";","'use client';\n\nimport * as React from 'react';\nimport { useMeterRootContext } from \"../root/MeterRootContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\n\n/**\n * A text element displaying the current value.\n * Renders a `<span>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterValue = /*#__PURE__*/React.forwardRef(function MeterValue(componentProps, forwardedRef) {\n const {\n className,\n render,\n children,\n style,\n ...elementProps\n } = componentProps;\n const {\n value,\n formattedValue\n } = useMeterRootContext();\n return useRenderElement('span', componentProps, {\n ref: forwardedRef,\n props: [{\n 'aria-hidden': true,\n children: typeof children === 'function' ? children(formattedValue, value) : formattedValue\n }, elementProps]\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterValue.displayName = \"MeterValue\";","'use client';\n\nimport * as React from 'react';\nimport { useMeterRootContext } from \"../root/MeterRootContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\nimport { useRegisteredLabelId } from \"../../utils/useRegisteredLabelId.mjs\";\n\n/**\n * An accessible label for the meter.\n * Renders a `<span>` element.\n *\n * Documentation: [Base UI Meter](https://base-ui.com/react/components/meter)\n */\nexport const MeterLabel = /*#__PURE__*/React.forwardRef(function MeterLabel(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n id: idProp,\n ...elementProps\n } = componentProps;\n const {\n setLabelId\n } = useMeterRootContext();\n const id = useRegisteredLabelId(idProp, setLabelId);\n return useRenderElement('span', componentProps, {\n ref: forwardedRef,\n props: [{\n id,\n role: 'presentation'\n }, elementProps]\n });\n});\nif (process.env.NODE_ENV !== \"production\") MeterLabel.displayName = \"MeterLabel\";","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-indicator.tsx\nconst TRMeterIndicator = createComponentPart(Meter.Indicator, \"tr-meter-indicator\");\n//#endregion\nexport { TRMeterIndicator };\n\n//# sourceMappingURL=meter-indicator.js.map","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-label.tsx\nconst TRMeterLabel = createComponentPart(Meter.Label, \"tr-meter-label\");\n//#endregion\nexport { TRMeterLabel };\n\n//# sourceMappingURL=meter-label.js.map","\"use client\";\nimport { mergeComponentClassName } from \"../../internal/component-class-name.js\";\nimport { jsx } from \"react/jsx-runtime\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-root.tsx\nfunction TRMeterRoot({ className, max = 100, min = 0, value, variant = \"neutral\", ...props }) {\n\tconst clampedValue = Math.min(max, Math.max(min, Number.isNaN(value) ? min : value));\n\treturn /* @__PURE__ */ jsx(Meter.Root, {\n\t\t...props,\n\t\tclassName: mergeComponentClassName(\"tr-meter\", className),\n\t\t\"data-variant\": variant,\n\t\tmax,\n\t\tmin,\n\t\tvalue: clampedValue\n\t});\n}\n//#endregion\nexport { TRMeterRoot };\n\n//# sourceMappingURL=meter-root.js.map","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-track.tsx\nconst TRMeterTrack = createComponentPart(Meter.Track, \"tr-meter-track\");\n//#endregion\nexport { TRMeterTrack };\n\n//# sourceMappingURL=meter-track.js.map","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { Meter } from \"@base-ui/react/meter\";\n//#region src/components/meter/meter-value.tsx\nconst TRMeterValue = createComponentPart(Meter.Value, \"tr-meter-value\");\n//#endregion\nexport { TRMeterValue };\n\n//# sourceMappingURL=meter-value.js.map","import { TRMeterIndicator } from \"./meter-indicator.js\";\nimport { TRMeterLabel } from \"./meter-label.js\";\nimport { TRMeterRoot } from \"./meter-root.js\";\nimport { TRMeterTrack } from \"./meter-track.js\";\nimport { TRMeterValue } from \"./meter-value.js\";\n//#region src/components/meter/index.tsx\nconst TRMeter = {\n\tRoot: TRMeterRoot,\n\tTrack: TRMeterTrack,\n\tIndicator: TRMeterIndicator,\n\tValue: TRMeterValue,\n\tLabel: TRMeterLabel\n};\n//#endregion\nexport { TRMeter, TRMeterIndicator, TRMeterLabel, TRMeterRoot, TRMeterTrack, TRMeterValue };\n\n//# sourceMappingURL=index.js.map","import { TRMeter } from '@tinyrack/ui/components/meter';\nimport { TRText } from '@tinyrack/ui/components/text';\nimport { useTranslation } from 'react-i18next';\n\ntype PasswordPolicy = {\n min_length: number;\n max_length: number;\n};\n\ntype PasswordStrengthProps = {\n password: string;\n policy: PasswordPolicy;\n};\n\nconst LEVELS = ['weak', 'fair', 'good', 'strong'] as const;\n\nconst VARIANTS = {\n weak: 'danger',\n fair: 'warning',\n good: 'info',\n strong: 'success',\n} as const;\n\n/**\n * Scores a password 1-4 for feedback only.\n *\n * Deliberately simple: length against the deployment's own policy plus\n * character-class variety. The server is the authority on what is acceptable,\n * so this only needs to steer the user, and a full entropy estimator would be\n * a large dependency for a hint bar.\n *\n * Returns 0 for \"nothing to say yet\" so the caller can stay silent.\n */\nfunction scorePassword(password: string, policy: PasswordPolicy): number {\n if (password.length === 0) {\n return 0;\n }\n if (password.length < policy.min_length) {\n return 1;\n }\n\n const classes = [/[a-z]/, /[A-Z]/, /\\d/, /[^a-zA-Z0-9]/].filter((pattern) =>\n pattern.test(password),\n ).length;\n\n const isLong = password.length >= policy.min_length + 4;\n\n if (classes >= 3 && isLong) {\n return 4;\n }\n if (classes >= 2 && isLong) {\n return 3;\n }\n return 2;\n}\n\n/**\n * Strength hint under a new-password field.\n *\n * Renders nothing for an empty field so the form does not shift as soon as it\n * is focused. Announced politely rather than assertively — it updates on every\n * keystroke and should not interrupt typing.\n */\nexport function PasswordStrength({ password, policy }: PasswordStrengthProps) {\n const { t } = useTranslation();\n const score = scorePassword(password, policy);\n\n if (score === 0) {\n return null;\n }\n\n const level = LEVELS[score - 1];\n\n return (\n <TRMeter.Root\n aria-live=\"polite\"\n className=\"flex flex-col gap-tinyrack-xs\"\n max={4}\n min={0}\n value={score}\n variant={VARIANTS[level]}\n >\n <div className=\"flex items-baseline justify-between gap-tinyrack-sm\">\n <TRMeter.Label\n render={\n <TRText color=\"muted\" variant=\"caption\">\n {t('validation.password.strength.label')}\n </TRText>\n }\n />\n <TRMeter.Value\n render={\n <TRText color=\"muted\" variant=\"caption\">\n {t(`validation.password.strength.${level}`)}\n </TRText>\n }\n />\n </div>\n <TRMeter.Track>\n <TRMeter.Indicator />\n </TRMeter.Track>\n </TRMeter.Root>\n );\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{G as e,J as t,Z as n,_ as r,b as i,c as a,i as o,q as s,v as c,x as l}from"./createLucideIcon-BPpAIXR_.js";import{F as u,G as d,P as f,S as ee,U as p,Vt as m,W as h,Zt as te,bn as g,bt as ne,k as _,q as re,xt as v}from"./config-
|
|
2
|
-
//# sourceMappingURL=pin-input-
|
|
1
|
+
import{G as e,J as t,Z as n,_ as r,b as i,c as a,i as o,q as s,v as c,x as l}from"./createLucideIcon-BPpAIXR_.js";import{F as u,G as d,P as f,S as ee,U as p,Vt as m,W as h,Zt as te,bn as g,bt as ne,k as _,q as re,xt as v}from"./config-DTQCUlfZ.js";import{S as ie,T as ae,_ as oe,b as se,g as ce,h as le,i as y,u as b,w as x,y as ue}from"./shell-header-bar-CjG5qvPg.js";import{t as S}from"./useAriaLabelledBy-ByuMi3Ry.js";import{t as C}from"./field-Cn4H1CUj.js";import{t as w}from"./separator-B0Bvh1he.js";var T=n(t(),1),E=T.createContext(void 0);function de(){let e=T.useContext(E);if(e===void 0)throw Error(c(98));return e}function D(e,t,n){return{...e,value:t,index:n,filled:t!==``}}var O={value:()=>null,length:()=>null,...x},k={value:()=>null,index:()=>null,...x},A={numeric:{slotPattern:`\\d{1}`,getRootPattern:e=>`\\d{${e}}`,regexp:/[^\d]/g,inputMode:`numeric`},alpha:{slotPattern:`[a-zA-Z]{1}`,getRootPattern:e=>`[a-zA-Z]{${e}}`,regexp:/[^a-zA-Z]/g,inputMode:`text`},alphanumeric:{slotPattern:`[a-zA-Z0-9]{1}`,getRootPattern:e=>`[a-zA-Z0-9]{${e}}`,regexp:/[^a-zA-Z0-9]/g,inputMode:`text`}};function j(e){return e===`none`?null:A[e]}function M(e){return(e??``).replace(/\s/g,``)}function fe(e,t){return t?e.replace(t.regexp,``):e}function N(e,t,n,r){let i=M(e),a=j(n),o=fe(i,a),s=i.length>o.length;if(r){let e=r(o);s||=o.length>e.length,o=fe(e,a),s||=e.length>o.length}let c=t<0?0:t,l=Array.from(o);return[l.slice(0,c).join(``),s||l.length>c]}function P(e,t,n,r){return N(e,t,n,r)[0]}function pe(e,t,n,r,i,a){let o=P(n,r,i,a);return P(`${e.slice(0,t)}${o}${e.slice(t+o.length)}`,r,i,a)}function F(e,t){return t<0||t>=e.length?e:`${e.slice(0,t)}${e.slice(t+1)}`}var I=s(),L=T.forwardRef(function(e,t){let{"aria-describedby":n,"aria-labelledby":o,id:s,autoComplete:c=`one-time-code`,defaultValue:d,value:ee,onValueChange:p,onValueComplete:m,form:h,length:g,autoSubmit:re=!1,mask:y=!1,inputMode:x,validationType:C=`numeric`,normalizeValue:w,disabled:de=!1,readOnly:D=!1,required:k=!1,name:A,onValueInvalid:M,render:fe,className:pe,style:F,...L}=e,{setDirty:z,validityData:B,disabled:V,setFilled:H,invalid:U,name:me,state:he,validation:W,validationMode:ge,setFocused:_e,setTouched:ve}=ie(),{clearErrors:ye}=ce(),{getDescriptionProps:be,labelId:xe}=ue(),G=V||de,K=me??A,[Se,Ce]=ae({controlled:ee,default:d,name:`OTPField`,state:`value`}),we=T.useRef(null),q=T.useRef([]),Te=T.useRef(null),J=T.useRef(null),Ee=T.useMemo(()=>({get current(){return q.current[0]??null}}),[]),Y=oe({id:s}),De=S(o,xe,Ee,!0,Y),Oe=o==null?De:void 0,ke=R(n,be({})[`aria-describedby`]),Ae=j(C),je=Ae?.slotPattern,Me=Ae?.getRootPattern(g),Ne=x??Ae?.inputMode,Pe=Number.isInteger(g)&&g>0,X=P(Se,g,C,w),Z=_(X),Q=X!==``,[Fe,Ie]=T.useState(0),[Le,Re]=T.useState(()=>Math.min(X.length,g-1)),[ze,Be]=T.useState(!1),Ve=ze?Math.min(Le,Math.max(g-1,0)):Math.min(X.length,g-1);i(()=>{H(Q)},[Q,H]),se(Ee,Y,X,void 0,!G,A);let $=l(e=>{let t=Math.min(Math.max(e,0),Math.max(q.current.length-1,0)),n=q.current[t];n?.focus(),n?.select()}),He=l((e,t)=>{Te.current={index:e,value:t}});function Ue(){let e=W.inputRef.current?.form??q.current[0]?.form??null;if(h){let t=r(we.current).getElementById(h);t?.tagName===`FORM`&&(e=t)}e&&typeof e.requestSubmit==`function`&&e.requestSubmit()}function We(e,t){m?.(e,t),re&&Ue()}le(X,()=>{ye(K),z(X!==B.initialValue),W.change(X);let e=Te.current;e!=null&&(Te.current=null,e.value===X&&$(e.index));let t=J.current;t!=null&&(J.current=null,t.value===X&&We(X,t.eventDetails))});let Ge=l((e,t)=>{let n=P(e,g,C,w),r=(t.reason===`input-change`||t.reason===`input-paste`)&&n.length===g&&(Z.current.length!==g||t.reason===`input-paste`)?u(t.reason,t.event):null;return n===Z.current?(r!=null&&We(n,r),null):(p?.(n,t),t.isCanceled?null:(Ce(n),r==null?n.length!==g&&(J.current=null):J.current={value:n,eventDetails:r},n))}),Ke=l((e,t)=>{M?.(e,t)}),qe=l((e,t)=>{if(e>Z.current.length){$(Math.min(Z.current.length,g-1));return}Re(e),Be(!0),_e(!0),t.currentTarget.select()}),Je=l(e=>{te(we.current,e.relatedTarget)||(ve(!0),Be(!1),_e(!1),ge===`onBlur`&&W.commit(Z.current))}),Ye=T.useCallback(e=>{if(Y!=null)return e===0?Y:`${Y}-${e+1}`},[Y]),Xe=T.useMemo(()=>({...he,complete:X.length===g,disabled:G,filled:Q,focused:ze,length:g,readOnly:D,required:k,value:X}),[G,he,Q,ze,g,D,k,X]),Ze=T.useMemo(()=>({autoComplete:c,activeIndex:Ve,disabled:G,form:h,focusInput:$,queueFocusInput:He,getInputId:Ye,handleInputBlur:Je,handleInputFocus:qe,inputMode:Ne,inputAriaLabelledBy:Oe,invalid:U,length:g,mask:y,pattern:je,reportValueInvalid:Ke,readOnly:D,required:k,normalizeValue:w,setValue:Ge,state:Xe,validationType:C,value:X}),[Ve,c,G,$,h,Ye,Je,qe,Ne,Oe,U,g,y,je,He,D,Ke,k,w,Ge,Xe,C,X]),Qe=a(`div`,e,{ref:[t,we],state:Xe,props:[{role:`group`,"aria-describedby":ke,"aria-labelledby":De},L],stateAttributesMapping:O});return(0,I.jsx)(b,{elementsRef:q,onMapChange:e=>{Ie(e.size)},children:(0,I.jsxs)(E.Provider,{value:Ze,children:[Qe,Pe&&(0,I.jsx)(`input`,{...W.getValidationProps(G,{onFocus(){$(0)},onChange(e){if(e.nativeEvent.defaultPrevented||G||D)return;let t=e.currentTarget.value,[n,r]=N(t,g,C,w);r&&Ke(t,u(`input-change`,e.nativeEvent));let i=Ge(n,f(`input-change`,e.nativeEvent));i!=null&&i!==``&&He(i.length-1,i)}}),ref:W.inputRef,type:`text`,id:Y&&K==null?`${Y}-hidden-input`:void 0,form:h,name:K,value:X,autoComplete:c,inputMode:Ne,minLength:g,maxLength:g,pattern:Me,disabled:G,readOnly:D,required:k,"aria-hidden":!0,tabIndex:-1,style:K?v:ne})]})})});function R(...e){let t=e.flatMap(e=>e?.split(/\s+/).filter(Boolean)??[]);return t.length>0?Array.from(new Set(t)).join(` `):void 0}var z=g(T.forwardRef(function(e,t){let{"aria-label":n,"aria-labelledby":r,render:i,className:o,style:s,...c}=e,{activeIndex:l,autoComplete:te,disabled:g,form:ne,focusInput:_,queueFocusInput:v,getInputId:ie,handleInputBlur:ae,handleInputFocus:oe,inputMode:se,inputAriaLabelledBy:ce,invalid:le,length:b,mask:x,pattern:ue,reportValueInvalid:S,readOnly:C,required:w,normalizeValue:E,setValue:O,state:A,validationType:j,value:M}=de(),{ref:fe,index:P}=y({guess:!0}),I=T.useRef(null),L=ee(),R=M[P]??``,z=D(A,R,P),B=n,V=r??ce,H=P===0?void 0:B,U={id:ie(P),value:R,type:x?`password`:`text`,inputMode:se,autoComplete:P===0?te:`off`,autoCorrect:`off`,spellCheck:`false`,enterKeyHint:P===b-1?`done`:`next`,maxLength:P===0?b:void 0,tabIndex:l===P?0:-1,disabled:g,form:ne,pattern:ue,readOnly:C,required:w,"aria-labelledby":H==null?V:void 0,"aria-invalid":!g&&le?!0:void 0,"aria-label":H,onMouseDown(e){e.defaultPrevented||g||(e.preventDefault(),_(P))},onFocus(e){e.defaultPrevented||g||oe(P,e)},onBlur(e){e.defaultPrevented||ae(e)},onChange(e){if(e.defaultPrevented||g||C)return;let t=e.currentTarget.value,[n,r]=N(t,b,j,E);if(r&&S(t,u(p,e.nativeEvent)),n===``){t===``?O(F(M,P),f(h,e.nativeEvent)):R!==``&&(e.currentTarget.value=R,e.currentTarget.select());return}let i=pe(M,P,n,b,j,E),a=O(i,f(p,e.nativeEvent));if(a!=null){let e=Math.min(P+n.length,b-1);v(e,a)}},onKeyDown(e){if(e.defaultPrevented||g)return;let t=Math.max(b-1,0),n=Math.min(M.length,t),r=(e.ctrlKey||e.metaKey)&&!e.altKey,i=L===`rtl`,a=i?`ArrowRight`:`ArrowLeft`,o=i?`ArrowLeft`:`ArrowRight`;if(e.key===a){m(e),_(r?0:Math.max(0,P-1));return}if(e.key===o){m(e),_(r?n:Math.min(t,P+1));return}if(e.key===`Home`||e.key===`ArrowUp`){m(e),_(0);return}if(e.key===`End`||e.key===`ArrowDown`){m(e),_(n);return}if(C)return;function s(t,n){let r=O(t,f(re,e.nativeEvent));r!=null&&v(n,r)}if(e.key===`Backspace`&&r){m(e),s(``,0);return}if(e.key===`Delete`){m(e),s(F(M,P),P);return}let c=e.currentTarget.value,l=e.currentTarget.selectionStart===0&&e.currentTarget.selectionEnd===c.length;if(e.key.length===1&&l&&R===e.key){m(e),P<b-1&&_(P+1);return}if(e.key===`Backspace`){m(e);let t=Math.max(0,P-1);s(F(M,R===``?t:P),t)}},onPaste(e){if(e.defaultPrevented||g||C)return;let t=``;try{t=e.clipboardData?.getData(`text/plain`)??``}catch{return}e.preventDefault();let[n,r]=N(t,b,j,E);if(r&&S(t,u(d,e.nativeEvent)),n===``)return;let i=O(pe(M,P,n,b,j,E),f(d,e.nativeEvent));if(i!=null){let e=Math.min(P+n.length,b-1);v(e,i)}}};return a(`input`,e,{ref:[t,fe,I],state:z,props:[U,c],stateAttributesMapping:k})}),`tr-otp-field-digit`,{tracksFocusModality:!0});function B({appearance:t=`solid`,className:n,uiSize:r=`md`,...i}){return(0,I.jsx)(L,{...i,className:e(`tr-otp-field`,n),"data-appearance":t,"data-ui-size":r})}function V({className:t,orientation:n=`vertical`,...r}){return(0,I.jsx)(w,{...r,className:e(`tr-otp-field-separator`,t),orientation:n})}var H={Root:B,Input:z,Separator:V},U=(0,T.forwardRef)(function({length:e=6,error:t,disabled:n=!1,onComplete:r,onChange:i,value:a,autoFocus:s=!1,className:c=``},l){let{t:u}=o(),d=(0,T.useId)(),f=(0,T.useRef)(null),[ee,p]=(0,T.useState)(a??``);(0,T.useEffect)(()=>{a!==void 0&&p(a)},[a]),(0,T.useImperativeHandle)(l,()=>({focus:()=>{(f.current?.querySelector(`input`))?.focus()},clear:()=>{p(``),(f.current?.querySelector(`input`))?.focus()}}),[]);let m=(0,T.useCallback)(e=>{p(e),i?.(e)},[i]),h=(0,T.useCallback)(e=>{r?.(e)},[r]);return(0,I.jsxs)(C.Root,{className:c,ref:f,children:[(0,I.jsx)(C.Label,{className:`sr-only`,htmlFor:d,children:u(`common.otp.label`)}),(0,I.jsx)(H.Root,{disabled:n,id:d,length:e,onValueChange:m,onValueComplete:h,uiSize:`md`,validationType:`numeric`,value:ee,children:Array.from({length:e},(t,n)=>(0,I.jsx)(H.Input,{"aria-label":n===0?void 0:u(`common.otp.digit`,{label:u(`common.otp.label`),position:n+1,total:e}),autoFocus:s&&n===0},n))}),t&&(0,I.jsx)(`p`,{className:`mt-tinyrack-sm text-center text-tinyrack-danger text-tinyrack-sm`,"data-testid":`pin-input-error`,children:t.message})]})});export{U as t};
|
|
2
|
+
//# sourceMappingURL=pin-input-Cc-VkrQ3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pin-input-BlD4tPZJ.js","names":["_formatErrorMessage","REASONS.inputChange","REASONS.inputClear","REASONS.keyboard","REASONS.inputPaste","OTPField.Input","OTPField.Root"],"sources":["../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/root/OTPFieldRootContext.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/utils/stateAttributesMapping.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/utils/otp.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/root/OTPFieldRoot.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/input/OTPFieldInput.mjs","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/otp-field-input.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/otp-field-root.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/otp-field-separator.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/index.js","../../../frontend/src/components/ui/pin-input.tsx"],"sourcesContent":["'use client';\n\nimport _formatErrorMessage from \"@base-ui/utils/formatErrorMessage\";\nimport * as React from 'react';\nexport const OTPFieldRootContext = /*#__PURE__*/React.createContext(undefined);\nif (process.env.NODE_ENV !== \"production\") OTPFieldRootContext.displayName = \"OTPFieldRootContext\";\nexport function useOTPFieldRootContext() {\n const context = React.useContext(OTPFieldRootContext);\n if (context === undefined) {\n throw new Error(process.env.NODE_ENV !== \"production\" ? 'Base UI: OTPFieldRootContext is missing. OTPField parts must be placed within <OTPField.Root>.' : _formatErrorMessage(98));\n }\n return context;\n}\nexport function getOTPFieldInputState(state, value, index) {\n return {\n ...state,\n value,\n index,\n filled: value !== ''\n };\n}","import { fieldValidityMapping } from \"../../internals/field-constants/constants.mjs\";\nexport const rootStateAttributesMapping = {\n value: () => null,\n length: () => null,\n ...fieldValidityMapping\n};\nexport const inputStateAttributesMapping = {\n value: () => null,\n index: () => null,\n ...fieldValidityMapping\n};","const OTP_VALIDATION_CONFIG = {\n numeric: {\n slotPattern: '\\\\d{1}',\n getRootPattern: length => `\\\\d{${length}}`,\n regexp: /[^\\d]/g,\n inputMode: 'numeric'\n },\n alpha: {\n slotPattern: '[a-zA-Z]{1}',\n getRootPattern: length => `[a-zA-Z]{${length}}`,\n regexp: /[^a-zA-Z]/g,\n inputMode: 'text'\n },\n alphanumeric: {\n slotPattern: '[a-zA-Z0-9]{1}',\n getRootPattern: length => `[a-zA-Z0-9]{${length}}`,\n regexp: /[^a-zA-Z0-9]/g,\n inputMode: 'text'\n }\n};\nexport function getOTPValidationConfig(validationType) {\n if (validationType === 'none') {\n return null;\n }\n return OTP_VALIDATION_CONFIG[validationType];\n}\nexport function stripOTPWhitespace(value) {\n return (value ?? '').replace(/\\s/g, '');\n}\nfunction applyOTPValidation(value, validation) {\n return validation ? value.replace(validation.regexp, '') : value;\n}\n\n/**\n * Normalizes user-entered OTP text by stripping whitespace, applying validation and custom\n * normalization, and clamping the final value to the configured slot count.\n */\nexport function normalizeOTPValueWithDetails(value, length, validationType, normalizeValue) {\n const strippedValue = stripOTPWhitespace(value);\n const validation = getOTPValidationConfig(validationType);\n let normalizedValue = applyOTPValidation(strippedValue, validation);\n let didRejectCharacters = strippedValue.length > normalizedValue.length;\n if (normalizeValue) {\n const customNormalizedValue = normalizeValue(normalizedValue);\n didRejectCharacters ||= normalizedValue.length > customNormalizedValue.length;\n normalizedValue = applyOTPValidation(customNormalizedValue, validation);\n didRejectCharacters ||= customNormalizedValue.length > normalizedValue.length;\n }\n\n // Slice by Unicode code points so multi-byte characters do not split across OTP slots.\n const maxLength = length < 0 ? 0 : length;\n const normalizedCharacters = Array.from(normalizedValue);\n return [normalizedCharacters.slice(0, maxLength).join(''), didRejectCharacters || normalizedCharacters.length > maxLength];\n}\nexport function normalizeOTPValue(value, length, validationType, normalizeValue) {\n return normalizeOTPValueWithDetails(value, length, validationType, normalizeValue)[0];\n}\n\n/**\n * Replaces characters starting at the provided slot index, then re-normalizes the final OTP value\n * so paste and multi-character edits stay contiguous and length-bounded.\n */\nexport function replaceOTPValue(currentValue, index, nextValue, length, validationType, normalizeValue) {\n const normalizedValue = normalizeOTPValue(nextValue, length, validationType, normalizeValue);\n const prefix = currentValue.slice(0, index);\n const suffix = currentValue.slice(index + normalizedValue.length);\n return normalizeOTPValue(`${prefix}${normalizedValue}${suffix}`, length, validationType, normalizeValue);\n}\nexport function removeOTPCharacter(currentValue, index) {\n if (index < 0 || index >= currentValue.length) {\n return currentValue;\n }\n return `${currentValue.slice(0, index)}${currentValue.slice(index + 1)}`;\n}","'use client';\n\nimport * as React from 'react';\nimport { SafeReact } from '@base-ui/utils/safeReact';\nimport { useControlled } from '@base-ui/utils/useControlled';\nimport { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';\nimport { useStableCallback } from '@base-ui/utils/useStableCallback';\nimport { useValueAsRef } from '@base-ui/utils/useValueAsRef';\nimport { visuallyHidden, visuallyHiddenInput } from '@base-ui/utils/visuallyHidden';\nimport { warn } from '@base-ui/utils/warn';\nimport { ownerDocument } from '@base-ui/utils/owner';\nimport { contains } from \"../../floating-ui-react/utils.mjs\";\nimport { CompositeList } from \"../../internals/composite/list/CompositeList.mjs\";\nimport { useFieldRootContext } from \"../../internals/field-root-context/FieldRootContext.mjs\";\nimport { useRegisterFieldControl } from \"../../internals/field-register-control/useRegisterFieldControl.mjs\";\nimport { useFormContext } from \"../../internals/form-context/FormContext.mjs\";\nimport { useLabelableContext } from \"../../internals/labelable-provider/LabelableContext.mjs\";\nimport { useAriaLabelledBy } from \"../../internals/labelable-provider/useAriaLabelledBy.mjs\";\nimport { useLabelableId } from \"../../internals/labelable-provider/useLabelableId.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\nimport { useValueChanged } from \"../../internals/useValueChanged.mjs\";\nimport { createChangeEventDetails, createGenericEventDetails } from \"../../internals/createBaseUIEventDetails.mjs\";\nimport { REASONS } from \"../../internals/reasons.mjs\";\nimport { OTPFieldRootContext } from \"./OTPFieldRootContext.mjs\";\nimport { rootStateAttributesMapping } from \"../utils/stateAttributesMapping.mjs\";\nimport { getOTPValidationConfig, normalizeOTPValue, normalizeOTPValueWithDetails } from \"../utils/otp.mjs\";\n\n/**\n * Groups all OTP field parts and manages their state.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI OTP Field](https://base-ui.com/react/components/otp-field)\n */\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nexport const OTPFieldRoot = /*#__PURE__*/React.forwardRef(function OTPFieldRoot(componentProps, forwardedRef) {\n const {\n 'aria-describedby': ariaDescribedByProp,\n 'aria-labelledby': ariaLabelledByProp,\n id: idProp,\n autoComplete = 'one-time-code',\n defaultValue,\n value: valueProp,\n onValueChange,\n onValueComplete: onValueCompleteProp,\n form,\n length,\n autoSubmit = false,\n mask = false,\n inputMode: inputModeProp,\n validationType = 'numeric',\n normalizeValue,\n disabled: disabledProp = false,\n readOnly = false,\n required = false,\n name: nameProp,\n onValueInvalid,\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n const {\n setDirty,\n validityData,\n disabled: fieldDisabled,\n setFilled,\n invalid,\n name: fieldName,\n state: fieldState,\n validation,\n validationMode,\n setFocused,\n setTouched\n } = useFieldRootContext();\n const {\n clearErrors\n } = useFormContext();\n const {\n getDescriptionProps,\n labelId\n } = useLabelableContext();\n const disabled = fieldDisabled || disabledProp;\n const name = fieldName ?? nameProp;\n const [valueUnwrapped, setValueUnwrapped] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: 'OTPField',\n state: 'value'\n });\n const rootRef = React.useRef(null);\n const inputRefs = React.useRef([]);\n const pendingFocusRef = React.useRef(null);\n const pendingCompleteValueRef = React.useRef(null);\n const firstInputRef = React.useMemo(() => ({\n get current() {\n return inputRefs.current[0] ?? null;\n }\n }), []);\n const id = useLabelableId({\n id: idProp\n });\n const ariaLabelledBy = useAriaLabelledBy(ariaLabelledByProp, labelId, firstInputRef, true, id);\n const inputAriaLabelledBy = ariaLabelledByProp == null ? ariaLabelledBy : undefined;\n const fieldDescriptionProps = getDescriptionProps({});\n const ariaDescribedBy = mergeAriaIds(ariaDescribedByProp, fieldDescriptionProps['aria-describedby']);\n const validationConfig = getOTPValidationConfig(validationType);\n const pattern = validationConfig?.slotPattern;\n const hiddenInputPattern = validationConfig?.getRootPattern(length);\n const inputMode = inputModeProp ?? validationConfig?.inputMode;\n const hasValidLength = Number.isInteger(length) && length > 0;\n const value = normalizeOTPValue(valueUnwrapped, length, validationType, normalizeValue);\n const valueRef = useValueAsRef(value);\n const filled = value !== '';\n const [inputCount, setInputCount] = React.useState(0);\n const [focusedIndex, setFocusedIndex] = React.useState(() => Math.min(value.length, length - 1));\n const [focused, setFocusedState] = React.useState(false);\n const activeIndex = focused ? Math.min(focusedIndex, Math.max(length - 1, 0)) : Math.min(value.length, length - 1);\n useIsoLayoutEffect(() => {\n setFilled(filled);\n }, [filled, setFilled]);\n\n /* istanbul ignore else -- `process.env.NODE_ENV` is a build-time constant under test */\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useOTPFieldRootDevWarnings({\n inputCount,\n length\n });\n }\n useRegisterFieldControl(firstInputRef, id, value, undefined, !disabled, nameProp);\n const focusInput = useStableCallback(index => {\n const targetIndex = Math.min(Math.max(index, 0), Math.max(inputRefs.current.length - 1, 0));\n const target = inputRefs.current[targetIndex];\n target?.focus();\n target?.select();\n });\n const queueFocusInput = useStableCallback((index, nextValue) => {\n pendingFocusRef.current = {\n index,\n value: nextValue\n };\n });\n function requestSubmit() {\n // The hidden validation input only renders for a valid `length`, but the slots always do,\n // so fall back to the owning form of the first slot.\n let formElement = validation.inputRef.current?.form ?? inputRefs.current[0]?.form ?? null;\n if (form) {\n const associatedElement = ownerDocument(rootRef.current).getElementById(form);\n if (associatedElement?.tagName === 'FORM') {\n formElement = associatedElement;\n }\n }\n if (formElement && typeof formElement.requestSubmit === 'function') {\n formElement.requestSubmit();\n }\n }\n function completeValue(completedValue, eventDetails) {\n onValueCompleteProp?.(completedValue, eventDetails);\n if (autoSubmit) {\n requestSubmit();\n }\n }\n useValueChanged(value, () => {\n clearErrors(name);\n setDirty(value !== validityData.initialValue);\n validation.change(value);\n const pendingFocus = pendingFocusRef.current;\n if (pendingFocus != null) {\n pendingFocusRef.current = null;\n if (pendingFocus.value === value) {\n focusInput(pendingFocus.index);\n }\n }\n const pendingCompleteValue = pendingCompleteValueRef.current;\n if (pendingCompleteValue != null) {\n pendingCompleteValueRef.current = null;\n if (pendingCompleteValue.value === value) {\n completeValue(value, pendingCompleteValue.eventDetails);\n }\n }\n });\n const setValue = useStableCallback((nextValue, details) => {\n const normalizedValue = normalizeOTPValue(nextValue, length, validationType, normalizeValue);\n const canComplete = details.reason === REASONS.inputChange || details.reason === REASONS.inputPaste;\n const completeEventDetails = canComplete && normalizedValue.length === length && (valueRef.current.length !== length || details.reason === REASONS.inputPaste) ? createGenericEventDetails(details.reason, details.event) : null;\n if (normalizedValue === valueRef.current) {\n if (completeEventDetails != null) {\n completeValue(normalizedValue, completeEventDetails);\n }\n return null;\n }\n onValueChange?.(normalizedValue, details);\n if (details.isCanceled) {\n return null;\n }\n setValueUnwrapped(normalizedValue);\n if (completeEventDetails != null) {\n pendingCompleteValueRef.current = {\n value: normalizedValue,\n eventDetails: completeEventDetails\n };\n } else if (normalizedValue.length !== length) {\n pendingCompleteValueRef.current = null;\n }\n return normalizedValue;\n });\n const reportValueInvalid = useStableCallback((invalidValue, details) => {\n onValueInvalid?.(invalidValue, details);\n });\n const handleInputFocus = useStableCallback((index, event) => {\n if (index > valueRef.current.length) {\n focusInput(Math.min(valueRef.current.length, length - 1));\n return;\n }\n setFocusedIndex(index);\n setFocusedState(true);\n setFocused(true);\n event.currentTarget.select();\n });\n const handleInputBlur = useStableCallback(event => {\n if (contains(rootRef.current, event.relatedTarget)) {\n return;\n }\n setTouched(true);\n setFocusedState(false);\n setFocused(false);\n if (validationMode === 'onBlur') {\n validation.commit(valueRef.current);\n }\n });\n const getInputId = React.useCallback(index => {\n if (id == null) {\n return undefined;\n }\n return index === 0 ? id : `${id}-${index + 1}`;\n }, [id]);\n const state = React.useMemo(() => ({\n ...fieldState,\n complete: value.length === length,\n disabled,\n filled,\n focused,\n length,\n readOnly,\n required,\n value\n }), [disabled, fieldState, filled, focused, length, readOnly, required, value]);\n const contextValue = React.useMemo(() => ({\n autoComplete,\n activeIndex,\n disabled,\n form,\n focusInput,\n queueFocusInput,\n getInputId,\n handleInputBlur,\n handleInputFocus,\n inputMode,\n inputAriaLabelledBy,\n invalid,\n length,\n mask,\n pattern,\n reportValueInvalid,\n readOnly,\n required,\n normalizeValue,\n setValue,\n state,\n validationType,\n value\n }), [activeIndex, autoComplete, disabled, focusInput, form, getInputId, handleInputBlur, handleInputFocus, inputMode, inputAriaLabelledBy, invalid, length, mask, pattern, queueFocusInput, readOnly, reportValueInvalid, required, normalizeValue, setValue, state, validationType, value]);\n const element = useRenderElement('div', componentProps, {\n ref: [forwardedRef, rootRef],\n state,\n props: [{\n role: 'group',\n 'aria-describedby': ariaDescribedBy,\n 'aria-labelledby': ariaLabelledBy\n }, elementProps],\n stateAttributesMapping: rootStateAttributesMapping\n });\n return /*#__PURE__*/_jsx(CompositeList, {\n elementsRef: inputRefs,\n onMapChange: newMap => {\n setInputCount(newMap.size);\n },\n children: /*#__PURE__*/_jsxs(OTPFieldRootContext.Provider, {\n value: contextValue,\n children: [element, hasValidLength && /*#__PURE__*/_jsx(\"input\", {\n ...validation.getValidationProps(disabled, {\n onFocus() {\n focusInput(0);\n },\n onChange(event) {\n if (event.nativeEvent.defaultPrevented || disabled || readOnly) {\n return;\n }\n const rawValue = event.currentTarget.value;\n const [normalizedValue, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length, validationType, normalizeValue);\n if (didRejectCharacters) {\n reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputChange, event.nativeEvent));\n }\n const committedValue = setValue(normalizedValue, createChangeEventDetails(REASONS.inputChange, event.nativeEvent));\n if (committedValue != null && committedValue !== '') {\n queueFocusInput(committedValue.length - 1, committedValue);\n }\n }\n }),\n ref: validation.inputRef,\n type: \"text\",\n id: id && name == null ? `${id}-hidden-input` : undefined,\n form: form,\n name: name,\n value: value,\n autoComplete: autoComplete,\n inputMode: inputMode,\n minLength: length,\n maxLength: length,\n pattern: hiddenInputPattern,\n disabled: disabled,\n readOnly: readOnly,\n required: required,\n \"aria-hidden\": true,\n tabIndex: -1,\n style: name ? visuallyHiddenInput : visuallyHidden\n })]\n })\n });\n});\nif (process.env.NODE_ENV !== \"production\") OTPFieldRoot.displayName = \"OTPFieldRoot\";\nfunction mergeAriaIds(...values) {\n const ids = values.flatMap(value => value?.split(/\\s+/).filter(Boolean) ?? []);\n return ids.length > 0 ? Array.from(new Set(ids)).join(' ') : undefined;\n}\nfunction useOTPFieldRootDevWarnings(parameters) {\n const {\n inputCount,\n length\n } = parameters;\n React.useEffect(() => {\n if (!Number.isInteger(length) || length <= 0 || inputCount === 0 || inputCount === length) {\n return;\n }\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n const message = '<OTPField.Root> `length` must match the number of rendered ' + `<OTPField.Input /> parts. Received \\`length={${length}}\\` but rendered ` + `${inputCount} input${inputCount === 1 ? '' : 's'}.`;\n warn(message, ownerStackMessage);\n }, [inputCount, length]);\n React.useEffect(() => {\n if (Number.isInteger(length) && length > 0) {\n return;\n }\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n warn(`<OTPField.Root> \\`length\\` must be a positive integer. Received \\`length={${String(length)}}\\`.`, ownerStackMessage);\n }, [length]);\n}","'use client';\n\nimport * as React from 'react';\nimport { SafeReact } from '@base-ui/utils/safeReact';\nimport { warn } from '@base-ui/utils/warn';\nimport { stopEvent } from \"../../floating-ui-react/utils.mjs\";\nimport { useCompositeListItem } from \"../../internals/composite/list/useCompositeListItem.mjs\";\nimport { useDirection } from \"../../internals/direction-context/DirectionContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\nimport { createChangeEventDetails, createGenericEventDetails } from \"../../internals/createBaseUIEventDetails.mjs\";\nimport { REASONS } from \"../../internals/reasons.mjs\";\nimport { useOTPFieldRootContext, getOTPFieldInputState } from \"../root/OTPFieldRootContext.mjs\";\nimport { inputStateAttributesMapping } from \"../utils/stateAttributesMapping.mjs\";\nimport { normalizeOTPValueWithDetails, removeOTPCharacter, replaceOTPValue } from \"../utils/otp.mjs\";\n\n/**\n * An individual OTP character input.\n * Renders an `<input>` element.\n *\n * Documentation: [Base UI OTP Field](https://base-ui.com/react/components/otp-field)\n */\nexport const OTPFieldInput = /*#__PURE__*/React.forwardRef(function OTPFieldInput(componentProps, forwardedRef) {\n const {\n 'aria-label': externalAriaLabel,\n 'aria-labelledby': externalAriaLabelledBy,\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n const {\n activeIndex,\n autoComplete,\n disabled,\n form,\n focusInput,\n queueFocusInput,\n getInputId,\n handleInputBlur,\n handleInputFocus,\n inputMode,\n inputAriaLabelledBy,\n invalid,\n length,\n mask,\n pattern,\n reportValueInvalid,\n readOnly,\n required,\n normalizeValue,\n setValue,\n state,\n validationType,\n value\n } = useOTPFieldRootContext();\n const {\n ref: listItemRef,\n index\n } = useCompositeListItem({\n guess: true\n });\n const inputRef = React.useRef(null);\n const direction = useDirection();\n const slotValue = value[index] ?? '';\n const inputState = getOTPFieldInputState(state, slotValue, index);\n const slotAriaLabel = externalAriaLabel;\n const inheritedLabel = externalAriaLabelledBy ?? inputAriaLabelledBy;\n const ariaLabel = index === 0 ? undefined : slotAriaLabel;\n\n /* istanbul ignore else -- `process.env.NODE_ENV` is a build-time constant under test */\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (index !== 0 || slotAriaLabel == null || inputRef.current?.labels?.length) {\n return;\n }\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n warn('<OTPField.Input> ignores `aria-label` on the first input. Use a `<label>` or `<Field.Label>` to label the OTP field.', ownerStackMessage);\n }, [index, slotAriaLabel]);\n }\n const inputProps = {\n id: getInputId(index),\n value: slotValue,\n type: mask ? 'password' : 'text',\n inputMode,\n autoComplete: index === 0 ? autoComplete : 'off',\n autoCorrect: 'off',\n spellCheck: 'false',\n enterKeyHint: index === length - 1 ? 'done' : 'next',\n // Only the first slot has a max length to avoid password manager bubbles appearing after later inputs.\n maxLength: index === 0 ? length : undefined,\n tabIndex: activeIndex === index ? 0 : -1,\n disabled,\n form,\n pattern,\n readOnly,\n required,\n 'aria-labelledby': ariaLabel == null ? inheritedLabel : undefined,\n 'aria-invalid': !disabled && invalid ? true : undefined,\n 'aria-label': ariaLabel,\n onMouseDown(event) {\n if (event.defaultPrevented || disabled) {\n return;\n }\n event.preventDefault();\n focusInput(index);\n },\n onFocus(event) {\n if (event.defaultPrevented || disabled) {\n return;\n }\n handleInputFocus(index, event);\n },\n onBlur(event) {\n if (event.defaultPrevented) {\n return;\n }\n handleInputBlur(event);\n },\n onChange(event) {\n if (event.defaultPrevented || disabled || readOnly) {\n return;\n }\n const rawValue = event.currentTarget.value;\n const [nextDigits, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length, validationType, normalizeValue);\n if (didRejectCharacters) {\n reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputChange, event.nativeEvent));\n }\n if (nextDigits === '') {\n if (rawValue === '') {\n setValue(removeOTPCharacter(value, index), createChangeEventDetails(REASONS.inputClear, event.nativeEvent));\n } else if (slotValue !== '') {\n event.currentTarget.value = slotValue;\n event.currentTarget.select();\n }\n return;\n }\n const nextValue = replaceOTPValue(value, index, nextDigits, length, validationType, normalizeValue);\n const committedValue = setValue(nextValue, createChangeEventDetails(REASONS.inputChange, event.nativeEvent));\n if (committedValue != null) {\n const nextInput = Math.min(index + nextDigits.length, length - 1);\n queueFocusInput(nextInput, committedValue);\n }\n },\n onKeyDown(event) {\n if (event.defaultPrevented || disabled) {\n return;\n }\n const firstIndex = 0;\n const lastIndex = Math.max(length - 1, firstIndex);\n const endTargetIndex = Math.min(value.length, lastIndex);\n const hasBoundaryModifier = (event.ctrlKey || event.metaKey) && !event.altKey;\n const isRtl = direction === 'rtl';\n const previousKey = isRtl ? 'ArrowRight' : 'ArrowLeft';\n const nextKey = isRtl ? 'ArrowLeft' : 'ArrowRight';\n if (event.key === previousKey) {\n stopEvent(event);\n focusInput(hasBoundaryModifier ? firstIndex : Math.max(firstIndex, index - 1));\n return;\n }\n if (event.key === nextKey) {\n stopEvent(event);\n focusInput(hasBoundaryModifier ? endTargetIndex : Math.min(lastIndex, index + 1));\n return;\n }\n if (event.key === 'Home' || event.key === 'ArrowUp') {\n stopEvent(event);\n focusInput(firstIndex);\n return;\n }\n if (event.key === 'End' || event.key === 'ArrowDown') {\n stopEvent(event);\n focusInput(endTargetIndex);\n return;\n }\n if (readOnly) {\n return;\n }\n function setKeyboardValue(nextValue, targetIndex) {\n const committedValue = setValue(nextValue, createChangeEventDetails(REASONS.keyboard, event.nativeEvent));\n if (committedValue != null) {\n queueFocusInput(targetIndex, committedValue);\n }\n }\n if (event.key === 'Backspace' && hasBoundaryModifier) {\n stopEvent(event);\n setKeyboardValue('', firstIndex);\n return;\n }\n if (event.key === 'Delete') {\n stopEvent(event);\n setKeyboardValue(removeOTPCharacter(value, index), index);\n return;\n }\n const inputValue = event.currentTarget.value;\n const fullSelection = event.currentTarget.selectionStart === 0 && event.currentTarget.selectionEnd === inputValue.length;\n if (event.key.length === 1 && fullSelection && slotValue === event.key) {\n stopEvent(event);\n if (index < length - 1) {\n focusInput(index + 1);\n }\n return;\n }\n if (event.key === 'Backspace') {\n stopEvent(event);\n const targetIndex = Math.max(firstIndex, index - 1);\n const deleteIndex = slotValue === '' ? targetIndex : index;\n setKeyboardValue(removeOTPCharacter(value, deleteIndex), targetIndex);\n }\n },\n onPaste(event) {\n if (event.defaultPrevented || disabled || readOnly) {\n return;\n }\n let rawValue = '';\n try {\n rawValue = event.clipboardData?.getData('text/plain') ?? '';\n } catch {\n /* istanbul ignore else -- `process.env.NODE_ENV` is a build-time constant under test */\n if (process.env.NODE_ENV !== 'production') {\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n warn('<OTPField.Input> could not read clipboard text during paste handling.', ownerStackMessage);\n }\n return;\n }\n event.preventDefault();\n const [nextDigits, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length, validationType, normalizeValue);\n if (didRejectCharacters) {\n reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputPaste, event.nativeEvent));\n }\n if (nextDigits === '') {\n return;\n }\n const committedValue = setValue(replaceOTPValue(value, index, nextDigits, length, validationType, normalizeValue), createChangeEventDetails(REASONS.inputPaste, event.nativeEvent));\n if (committedValue != null) {\n const nextInput = Math.min(index + nextDigits.length, length - 1);\n queueFocusInput(nextInput, committedValue);\n }\n }\n };\n const element = useRenderElement('input', componentProps, {\n ref: [forwardedRef, listItemRef, inputRef],\n state: inputState,\n props: [inputProps, elementProps],\n stateAttributesMapping: inputStateAttributesMapping\n });\n return element;\n});\nif (process.env.NODE_ENV !== \"production\") OTPFieldInput.displayName = \"OTPFieldInput\";","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { OTPField } from \"@base-ui/react/otp-field\";\n//#region src/components/otp-field/otp-field-input.tsx\nconst TROTPFieldInput = createComponentPart(OTPField.Input, \"tr-otp-field-digit\", { tracksFocusModality: true });\n//#endregion\nexport { TROTPFieldInput };\n\n//# sourceMappingURL=otp-field-input.js.map","\"use client\";\nimport { mergeComponentClassName } from \"../../internal/component-class-name.js\";\nimport { jsx } from \"react/jsx-runtime\";\nimport { OTPField } from \"@base-ui/react/otp-field\";\n//#region src/components/otp-field/otp-field-root.tsx\nfunction TROTPFieldRoot({ appearance = \"solid\", className, uiSize = \"md\", ...props }) {\n\treturn /* @__PURE__ */ jsx(OTPField.Root, {\n\t\t...props,\n\t\tclassName: mergeComponentClassName(\"tr-otp-field\", className),\n\t\t\"data-appearance\": appearance,\n\t\t\"data-ui-size\": uiSize\n\t});\n}\n//#endregion\nexport { TROTPFieldRoot };\n\n//# sourceMappingURL=otp-field-root.js.map","import { mergeComponentClassName } from \"../../internal/component-class-name.js\";\nimport { TRSeparator } from \"../separator/separator.js\";\nimport { jsx } from \"react/jsx-runtime\";\n//#region src/components/otp-field/otp-field-separator.tsx\nfunction TROTPFieldSeparator({ className, orientation = \"vertical\", ...props }) {\n\treturn /* @__PURE__ */ jsx(TRSeparator, {\n\t\t...props,\n\t\tclassName: mergeComponentClassName(\"tr-otp-field-separator\", className),\n\t\torientation\n\t});\n}\n//#endregion\nexport { TROTPFieldSeparator };\n\n//# sourceMappingURL=otp-field-separator.js.map","import { TROTPFieldInput } from \"./otp-field-input.js\";\nimport { TROTPFieldRoot } from \"./otp-field-root.js\";\nimport { TROTPFieldSeparator } from \"./otp-field-separator.js\";\n//#region src/components/otp-field/index.tsx\nconst TROTPField = {\n\tRoot: TROTPFieldRoot,\n\tInput: TROTPFieldInput,\n\tSeparator: TROTPFieldSeparator\n};\n//#endregion\nexport { TROTPField, TROTPFieldInput, TROTPFieldRoot, TROTPFieldSeparator };\n\n//# sourceMappingURL=index.js.map","import { TRField } from '@tinyrack/ui/components/field';\nimport { TROTPField } from '@tinyrack/ui/components/otp-field';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport type { FieldError } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\n\nexport type PinInputRef = {\n focus: () => void;\n clear: () => void;\n};\n\ntype PinInputProps = {\n length?: number;\n error?: FieldError;\n disabled?: boolean;\n onComplete?: (value: string) => void;\n onChange?: (value: string) => void;\n value?: string;\n autoFocus?: boolean;\n className?: string;\n};\n\nexport const PinInput = forwardRef<PinInputRef, PinInputProps>(\n function PinInput(\n {\n length = 6,\n error,\n disabled = false,\n onComplete,\n onChange,\n value: controlledValue,\n autoFocus = false,\n className = '',\n },\n ref,\n ) {\n const { t } = useTranslation();\n const otpId = useId();\n const containerRef = useRef<HTMLDivElement>(null);\n const [internalValue, setInternalValue] = useState(controlledValue ?? '');\n\n useEffect(() => {\n if (controlledValue !== undefined) {\n setInternalValue(controlledValue);\n }\n }, [controlledValue]);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => {\n const firstInput = containerRef.current?.querySelector('input');\n firstInput?.focus();\n },\n clear: () => {\n setInternalValue('');\n const firstInput = containerRef.current?.querySelector('input');\n firstInput?.focus();\n },\n }),\n [],\n );\n\n const handleValueChange = useCallback(\n (newValue: string) => {\n setInternalValue(newValue);\n onChange?.(newValue);\n },\n [onChange],\n );\n\n const handleValueComplete = useCallback(\n (completedValue: string) => {\n onComplete?.(completedValue);\n },\n [onComplete],\n );\n\n return (\n <TRField.Root className={className} ref={containerRef}>\n {/*\n A real label, not `aria-label`: Base UI deliberately ignores\n `aria-label` on the first OTP input and warns to use a label instead,\n because that input is also the one password managers autofill.\n Visually hidden — the screen's own heading already says what the code\n is, so showing it twice would be noise.\n */}\n <TRField.Label className=\"sr-only\" htmlFor={otpId}>\n {t('common.otp.label')}\n </TRField.Label>\n <TROTPField.Root\n disabled={disabled}\n /*\n * Base UI gives the first slot the root's own id and derives the\n * rest from it, so naming the root is what lets the label point at\n * a real input rather than at the wrapping group.\n */\n id={otpId}\n length={length}\n onValueChange={handleValueChange}\n onValueComplete={handleValueComplete}\n uiSize=\"md\"\n validationType=\"numeric\"\n value={internalValue}\n >\n {/*\n Each box is a separate input, so each needs to say which position\n it is. Two Base UI behaviours shape this: the first box ignores\n `aria-label` outright (it is the one password managers autofill, so\n it takes the field's own label), and on the rest an `aria-label`\n *replaces* the inherited field name rather than adding to it. So\n the field name is folded into the per-box string, and box one is\n left to the label above.\n */}\n {Array.from({ length }, (_, index) => (\n <TROTPField.Input\n aria-label={\n index === 0\n ? undefined\n : t('common.otp.digit', {\n label: t('common.otp.label'),\n position: index + 1,\n total: length,\n })\n }\n autoFocus={autoFocus && index === 0}\n key={index}\n />\n ))}\n </TROTPField.Root>\n {error && (\n <p\n className=\"mt-tinyrack-sm text-center text-tinyrack-danger text-tinyrack-sm\"\n data-testid=\"pin-input-error\"\n >\n {error.message}\n </p>\n )}\n </TRField.Root>\n );\n },\n);\n\nexport default PinInput;\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pin-input-Cc-VkrQ3.js","names":["_formatErrorMessage","REASONS.inputChange","REASONS.inputClear","REASONS.keyboard","REASONS.inputPaste","OTPField.Input","OTPField.Root"],"sources":["../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/root/OTPFieldRootContext.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/utils/stateAttributesMapping.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/utils/otp.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/root/OTPFieldRoot.mjs","../../../../node_modules/.pnpm/@base-ui+react@1.7.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@base-ui/react/otp-field/input/OTPFieldInput.mjs","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/otp-field-input.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/otp-field-root.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/otp-field-separator.js","../../../../node_modules/.pnpm/@tinyrack+ui@0.25.0_@types+react@19.2.17_react-dom@19.2.7_react@19.2.7__react@19.2.7_shiki@4.3.1_tailwindcss@4.3.2/node_modules/@tinyrack/ui/dist/components/otp-field/index.js","../../../frontend/src/components/ui/pin-input.tsx"],"sourcesContent":["'use client';\n\nimport _formatErrorMessage from \"@base-ui/utils/formatErrorMessage\";\nimport * as React from 'react';\nexport const OTPFieldRootContext = /*#__PURE__*/React.createContext(undefined);\nif (process.env.NODE_ENV !== \"production\") OTPFieldRootContext.displayName = \"OTPFieldRootContext\";\nexport function useOTPFieldRootContext() {\n const context = React.useContext(OTPFieldRootContext);\n if (context === undefined) {\n throw new Error(process.env.NODE_ENV !== \"production\" ? 'Base UI: OTPFieldRootContext is missing. OTPField parts must be placed within <OTPField.Root>.' : _formatErrorMessage(98));\n }\n return context;\n}\nexport function getOTPFieldInputState(state, value, index) {\n return {\n ...state,\n value,\n index,\n filled: value !== ''\n };\n}","import { fieldValidityMapping } from \"../../internals/field-constants/constants.mjs\";\nexport const rootStateAttributesMapping = {\n value: () => null,\n length: () => null,\n ...fieldValidityMapping\n};\nexport const inputStateAttributesMapping = {\n value: () => null,\n index: () => null,\n ...fieldValidityMapping\n};","const OTP_VALIDATION_CONFIG = {\n numeric: {\n slotPattern: '\\\\d{1}',\n getRootPattern: length => `\\\\d{${length}}`,\n regexp: /[^\\d]/g,\n inputMode: 'numeric'\n },\n alpha: {\n slotPattern: '[a-zA-Z]{1}',\n getRootPattern: length => `[a-zA-Z]{${length}}`,\n regexp: /[^a-zA-Z]/g,\n inputMode: 'text'\n },\n alphanumeric: {\n slotPattern: '[a-zA-Z0-9]{1}',\n getRootPattern: length => `[a-zA-Z0-9]{${length}}`,\n regexp: /[^a-zA-Z0-9]/g,\n inputMode: 'text'\n }\n};\nexport function getOTPValidationConfig(validationType) {\n if (validationType === 'none') {\n return null;\n }\n return OTP_VALIDATION_CONFIG[validationType];\n}\nexport function stripOTPWhitespace(value) {\n return (value ?? '').replace(/\\s/g, '');\n}\nfunction applyOTPValidation(value, validation) {\n return validation ? value.replace(validation.regexp, '') : value;\n}\n\n/**\n * Normalizes user-entered OTP text by stripping whitespace, applying validation and custom\n * normalization, and clamping the final value to the configured slot count.\n */\nexport function normalizeOTPValueWithDetails(value, length, validationType, normalizeValue) {\n const strippedValue = stripOTPWhitespace(value);\n const validation = getOTPValidationConfig(validationType);\n let normalizedValue = applyOTPValidation(strippedValue, validation);\n let didRejectCharacters = strippedValue.length > normalizedValue.length;\n if (normalizeValue) {\n const customNormalizedValue = normalizeValue(normalizedValue);\n didRejectCharacters ||= normalizedValue.length > customNormalizedValue.length;\n normalizedValue = applyOTPValidation(customNormalizedValue, validation);\n didRejectCharacters ||= customNormalizedValue.length > normalizedValue.length;\n }\n\n // Slice by Unicode code points so multi-byte characters do not split across OTP slots.\n const maxLength = length < 0 ? 0 : length;\n const normalizedCharacters = Array.from(normalizedValue);\n return [normalizedCharacters.slice(0, maxLength).join(''), didRejectCharacters || normalizedCharacters.length > maxLength];\n}\nexport function normalizeOTPValue(value, length, validationType, normalizeValue) {\n return normalizeOTPValueWithDetails(value, length, validationType, normalizeValue)[0];\n}\n\n/**\n * Replaces characters starting at the provided slot index, then re-normalizes the final OTP value\n * so paste and multi-character edits stay contiguous and length-bounded.\n */\nexport function replaceOTPValue(currentValue, index, nextValue, length, validationType, normalizeValue) {\n const normalizedValue = normalizeOTPValue(nextValue, length, validationType, normalizeValue);\n const prefix = currentValue.slice(0, index);\n const suffix = currentValue.slice(index + normalizedValue.length);\n return normalizeOTPValue(`${prefix}${normalizedValue}${suffix}`, length, validationType, normalizeValue);\n}\nexport function removeOTPCharacter(currentValue, index) {\n if (index < 0 || index >= currentValue.length) {\n return currentValue;\n }\n return `${currentValue.slice(0, index)}${currentValue.slice(index + 1)}`;\n}","'use client';\n\nimport * as React from 'react';\nimport { SafeReact } from '@base-ui/utils/safeReact';\nimport { useControlled } from '@base-ui/utils/useControlled';\nimport { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';\nimport { useStableCallback } from '@base-ui/utils/useStableCallback';\nimport { useValueAsRef } from '@base-ui/utils/useValueAsRef';\nimport { visuallyHidden, visuallyHiddenInput } from '@base-ui/utils/visuallyHidden';\nimport { warn } from '@base-ui/utils/warn';\nimport { ownerDocument } from '@base-ui/utils/owner';\nimport { contains } from \"../../floating-ui-react/utils.mjs\";\nimport { CompositeList } from \"../../internals/composite/list/CompositeList.mjs\";\nimport { useFieldRootContext } from \"../../internals/field-root-context/FieldRootContext.mjs\";\nimport { useRegisterFieldControl } from \"../../internals/field-register-control/useRegisterFieldControl.mjs\";\nimport { useFormContext } from \"../../internals/form-context/FormContext.mjs\";\nimport { useLabelableContext } from \"../../internals/labelable-provider/LabelableContext.mjs\";\nimport { useAriaLabelledBy } from \"../../internals/labelable-provider/useAriaLabelledBy.mjs\";\nimport { useLabelableId } from \"../../internals/labelable-provider/useLabelableId.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\nimport { useValueChanged } from \"../../internals/useValueChanged.mjs\";\nimport { createChangeEventDetails, createGenericEventDetails } from \"../../internals/createBaseUIEventDetails.mjs\";\nimport { REASONS } from \"../../internals/reasons.mjs\";\nimport { OTPFieldRootContext } from \"./OTPFieldRootContext.mjs\";\nimport { rootStateAttributesMapping } from \"../utils/stateAttributesMapping.mjs\";\nimport { getOTPValidationConfig, normalizeOTPValue, normalizeOTPValueWithDetails } from \"../utils/otp.mjs\";\n\n/**\n * Groups all OTP field parts and manages their state.\n * Renders a `<div>` element.\n *\n * Documentation: [Base UI OTP Field](https://base-ui.com/react/components/otp-field)\n */\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nexport const OTPFieldRoot = /*#__PURE__*/React.forwardRef(function OTPFieldRoot(componentProps, forwardedRef) {\n const {\n 'aria-describedby': ariaDescribedByProp,\n 'aria-labelledby': ariaLabelledByProp,\n id: idProp,\n autoComplete = 'one-time-code',\n defaultValue,\n value: valueProp,\n onValueChange,\n onValueComplete: onValueCompleteProp,\n form,\n length,\n autoSubmit = false,\n mask = false,\n inputMode: inputModeProp,\n validationType = 'numeric',\n normalizeValue,\n disabled: disabledProp = false,\n readOnly = false,\n required = false,\n name: nameProp,\n onValueInvalid,\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n const {\n setDirty,\n validityData,\n disabled: fieldDisabled,\n setFilled,\n invalid,\n name: fieldName,\n state: fieldState,\n validation,\n validationMode,\n setFocused,\n setTouched\n } = useFieldRootContext();\n const {\n clearErrors\n } = useFormContext();\n const {\n getDescriptionProps,\n labelId\n } = useLabelableContext();\n const disabled = fieldDisabled || disabledProp;\n const name = fieldName ?? nameProp;\n const [valueUnwrapped, setValueUnwrapped] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: 'OTPField',\n state: 'value'\n });\n const rootRef = React.useRef(null);\n const inputRefs = React.useRef([]);\n const pendingFocusRef = React.useRef(null);\n const pendingCompleteValueRef = React.useRef(null);\n const firstInputRef = React.useMemo(() => ({\n get current() {\n return inputRefs.current[0] ?? null;\n }\n }), []);\n const id = useLabelableId({\n id: idProp\n });\n const ariaLabelledBy = useAriaLabelledBy(ariaLabelledByProp, labelId, firstInputRef, true, id);\n const inputAriaLabelledBy = ariaLabelledByProp == null ? ariaLabelledBy : undefined;\n const fieldDescriptionProps = getDescriptionProps({});\n const ariaDescribedBy = mergeAriaIds(ariaDescribedByProp, fieldDescriptionProps['aria-describedby']);\n const validationConfig = getOTPValidationConfig(validationType);\n const pattern = validationConfig?.slotPattern;\n const hiddenInputPattern = validationConfig?.getRootPattern(length);\n const inputMode = inputModeProp ?? validationConfig?.inputMode;\n const hasValidLength = Number.isInteger(length) && length > 0;\n const value = normalizeOTPValue(valueUnwrapped, length, validationType, normalizeValue);\n const valueRef = useValueAsRef(value);\n const filled = value !== '';\n const [inputCount, setInputCount] = React.useState(0);\n const [focusedIndex, setFocusedIndex] = React.useState(() => Math.min(value.length, length - 1));\n const [focused, setFocusedState] = React.useState(false);\n const activeIndex = focused ? Math.min(focusedIndex, Math.max(length - 1, 0)) : Math.min(value.length, length - 1);\n useIsoLayoutEffect(() => {\n setFilled(filled);\n }, [filled, setFilled]);\n\n /* istanbul ignore else -- `process.env.NODE_ENV` is a build-time constant under test */\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useOTPFieldRootDevWarnings({\n inputCount,\n length\n });\n }\n useRegisterFieldControl(firstInputRef, id, value, undefined, !disabled, nameProp);\n const focusInput = useStableCallback(index => {\n const targetIndex = Math.min(Math.max(index, 0), Math.max(inputRefs.current.length - 1, 0));\n const target = inputRefs.current[targetIndex];\n target?.focus();\n target?.select();\n });\n const queueFocusInput = useStableCallback((index, nextValue) => {\n pendingFocusRef.current = {\n index,\n value: nextValue\n };\n });\n function requestSubmit() {\n // The hidden validation input only renders for a valid `length`, but the slots always do,\n // so fall back to the owning form of the first slot.\n let formElement = validation.inputRef.current?.form ?? inputRefs.current[0]?.form ?? null;\n if (form) {\n const associatedElement = ownerDocument(rootRef.current).getElementById(form);\n if (associatedElement?.tagName === 'FORM') {\n formElement = associatedElement;\n }\n }\n if (formElement && typeof formElement.requestSubmit === 'function') {\n formElement.requestSubmit();\n }\n }\n function completeValue(completedValue, eventDetails) {\n onValueCompleteProp?.(completedValue, eventDetails);\n if (autoSubmit) {\n requestSubmit();\n }\n }\n useValueChanged(value, () => {\n clearErrors(name);\n setDirty(value !== validityData.initialValue);\n validation.change(value);\n const pendingFocus = pendingFocusRef.current;\n if (pendingFocus != null) {\n pendingFocusRef.current = null;\n if (pendingFocus.value === value) {\n focusInput(pendingFocus.index);\n }\n }\n const pendingCompleteValue = pendingCompleteValueRef.current;\n if (pendingCompleteValue != null) {\n pendingCompleteValueRef.current = null;\n if (pendingCompleteValue.value === value) {\n completeValue(value, pendingCompleteValue.eventDetails);\n }\n }\n });\n const setValue = useStableCallback((nextValue, details) => {\n const normalizedValue = normalizeOTPValue(nextValue, length, validationType, normalizeValue);\n const canComplete = details.reason === REASONS.inputChange || details.reason === REASONS.inputPaste;\n const completeEventDetails = canComplete && normalizedValue.length === length && (valueRef.current.length !== length || details.reason === REASONS.inputPaste) ? createGenericEventDetails(details.reason, details.event) : null;\n if (normalizedValue === valueRef.current) {\n if (completeEventDetails != null) {\n completeValue(normalizedValue, completeEventDetails);\n }\n return null;\n }\n onValueChange?.(normalizedValue, details);\n if (details.isCanceled) {\n return null;\n }\n setValueUnwrapped(normalizedValue);\n if (completeEventDetails != null) {\n pendingCompleteValueRef.current = {\n value: normalizedValue,\n eventDetails: completeEventDetails\n };\n } else if (normalizedValue.length !== length) {\n pendingCompleteValueRef.current = null;\n }\n return normalizedValue;\n });\n const reportValueInvalid = useStableCallback((invalidValue, details) => {\n onValueInvalid?.(invalidValue, details);\n });\n const handleInputFocus = useStableCallback((index, event) => {\n if (index > valueRef.current.length) {\n focusInput(Math.min(valueRef.current.length, length - 1));\n return;\n }\n setFocusedIndex(index);\n setFocusedState(true);\n setFocused(true);\n event.currentTarget.select();\n });\n const handleInputBlur = useStableCallback(event => {\n if (contains(rootRef.current, event.relatedTarget)) {\n return;\n }\n setTouched(true);\n setFocusedState(false);\n setFocused(false);\n if (validationMode === 'onBlur') {\n validation.commit(valueRef.current);\n }\n });\n const getInputId = React.useCallback(index => {\n if (id == null) {\n return undefined;\n }\n return index === 0 ? id : `${id}-${index + 1}`;\n }, [id]);\n const state = React.useMemo(() => ({\n ...fieldState,\n complete: value.length === length,\n disabled,\n filled,\n focused,\n length,\n readOnly,\n required,\n value\n }), [disabled, fieldState, filled, focused, length, readOnly, required, value]);\n const contextValue = React.useMemo(() => ({\n autoComplete,\n activeIndex,\n disabled,\n form,\n focusInput,\n queueFocusInput,\n getInputId,\n handleInputBlur,\n handleInputFocus,\n inputMode,\n inputAriaLabelledBy,\n invalid,\n length,\n mask,\n pattern,\n reportValueInvalid,\n readOnly,\n required,\n normalizeValue,\n setValue,\n state,\n validationType,\n value\n }), [activeIndex, autoComplete, disabled, focusInput, form, getInputId, handleInputBlur, handleInputFocus, inputMode, inputAriaLabelledBy, invalid, length, mask, pattern, queueFocusInput, readOnly, reportValueInvalid, required, normalizeValue, setValue, state, validationType, value]);\n const element = useRenderElement('div', componentProps, {\n ref: [forwardedRef, rootRef],\n state,\n props: [{\n role: 'group',\n 'aria-describedby': ariaDescribedBy,\n 'aria-labelledby': ariaLabelledBy\n }, elementProps],\n stateAttributesMapping: rootStateAttributesMapping\n });\n return /*#__PURE__*/_jsx(CompositeList, {\n elementsRef: inputRefs,\n onMapChange: newMap => {\n setInputCount(newMap.size);\n },\n children: /*#__PURE__*/_jsxs(OTPFieldRootContext.Provider, {\n value: contextValue,\n children: [element, hasValidLength && /*#__PURE__*/_jsx(\"input\", {\n ...validation.getValidationProps(disabled, {\n onFocus() {\n focusInput(0);\n },\n onChange(event) {\n if (event.nativeEvent.defaultPrevented || disabled || readOnly) {\n return;\n }\n const rawValue = event.currentTarget.value;\n const [normalizedValue, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length, validationType, normalizeValue);\n if (didRejectCharacters) {\n reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputChange, event.nativeEvent));\n }\n const committedValue = setValue(normalizedValue, createChangeEventDetails(REASONS.inputChange, event.nativeEvent));\n if (committedValue != null && committedValue !== '') {\n queueFocusInput(committedValue.length - 1, committedValue);\n }\n }\n }),\n ref: validation.inputRef,\n type: \"text\",\n id: id && name == null ? `${id}-hidden-input` : undefined,\n form: form,\n name: name,\n value: value,\n autoComplete: autoComplete,\n inputMode: inputMode,\n minLength: length,\n maxLength: length,\n pattern: hiddenInputPattern,\n disabled: disabled,\n readOnly: readOnly,\n required: required,\n \"aria-hidden\": true,\n tabIndex: -1,\n style: name ? visuallyHiddenInput : visuallyHidden\n })]\n })\n });\n});\nif (process.env.NODE_ENV !== \"production\") OTPFieldRoot.displayName = \"OTPFieldRoot\";\nfunction mergeAriaIds(...values) {\n const ids = values.flatMap(value => value?.split(/\\s+/).filter(Boolean) ?? []);\n return ids.length > 0 ? Array.from(new Set(ids)).join(' ') : undefined;\n}\nfunction useOTPFieldRootDevWarnings(parameters) {\n const {\n inputCount,\n length\n } = parameters;\n React.useEffect(() => {\n if (!Number.isInteger(length) || length <= 0 || inputCount === 0 || inputCount === length) {\n return;\n }\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n const message = '<OTPField.Root> `length` must match the number of rendered ' + `<OTPField.Input /> parts. Received \\`length={${length}}\\` but rendered ` + `${inputCount} input${inputCount === 1 ? '' : 's'}.`;\n warn(message, ownerStackMessage);\n }, [inputCount, length]);\n React.useEffect(() => {\n if (Number.isInteger(length) && length > 0) {\n return;\n }\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n warn(`<OTPField.Root> \\`length\\` must be a positive integer. Received \\`length={${String(length)}}\\`.`, ownerStackMessage);\n }, [length]);\n}","'use client';\n\nimport * as React from 'react';\nimport { SafeReact } from '@base-ui/utils/safeReact';\nimport { warn } from '@base-ui/utils/warn';\nimport { stopEvent } from \"../../floating-ui-react/utils.mjs\";\nimport { useCompositeListItem } from \"../../internals/composite/list/useCompositeListItem.mjs\";\nimport { useDirection } from \"../../internals/direction-context/DirectionContext.mjs\";\nimport { useRenderElement } from \"../../internals/useRenderElement.mjs\";\nimport { createChangeEventDetails, createGenericEventDetails } from \"../../internals/createBaseUIEventDetails.mjs\";\nimport { REASONS } from \"../../internals/reasons.mjs\";\nimport { useOTPFieldRootContext, getOTPFieldInputState } from \"../root/OTPFieldRootContext.mjs\";\nimport { inputStateAttributesMapping } from \"../utils/stateAttributesMapping.mjs\";\nimport { normalizeOTPValueWithDetails, removeOTPCharacter, replaceOTPValue } from \"../utils/otp.mjs\";\n\n/**\n * An individual OTP character input.\n * Renders an `<input>` element.\n *\n * Documentation: [Base UI OTP Field](https://base-ui.com/react/components/otp-field)\n */\nexport const OTPFieldInput = /*#__PURE__*/React.forwardRef(function OTPFieldInput(componentProps, forwardedRef) {\n const {\n 'aria-label': externalAriaLabel,\n 'aria-labelledby': externalAriaLabelledBy,\n render,\n className,\n style,\n ...elementProps\n } = componentProps;\n const {\n activeIndex,\n autoComplete,\n disabled,\n form,\n focusInput,\n queueFocusInput,\n getInputId,\n handleInputBlur,\n handleInputFocus,\n inputMode,\n inputAriaLabelledBy,\n invalid,\n length,\n mask,\n pattern,\n reportValueInvalid,\n readOnly,\n required,\n normalizeValue,\n setValue,\n state,\n validationType,\n value\n } = useOTPFieldRootContext();\n const {\n ref: listItemRef,\n index\n } = useCompositeListItem({\n guess: true\n });\n const inputRef = React.useRef(null);\n const direction = useDirection();\n const slotValue = value[index] ?? '';\n const inputState = getOTPFieldInputState(state, slotValue, index);\n const slotAriaLabel = externalAriaLabel;\n const inheritedLabel = externalAriaLabelledBy ?? inputAriaLabelledBy;\n const ariaLabel = index === 0 ? undefined : slotAriaLabel;\n\n /* istanbul ignore else -- `process.env.NODE_ENV` is a build-time constant under test */\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (index !== 0 || slotAriaLabel == null || inputRef.current?.labels?.length) {\n return;\n }\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n warn('<OTPField.Input> ignores `aria-label` on the first input. Use a `<label>` or `<Field.Label>` to label the OTP field.', ownerStackMessage);\n }, [index, slotAriaLabel]);\n }\n const inputProps = {\n id: getInputId(index),\n value: slotValue,\n type: mask ? 'password' : 'text',\n inputMode,\n autoComplete: index === 0 ? autoComplete : 'off',\n autoCorrect: 'off',\n spellCheck: 'false',\n enterKeyHint: index === length - 1 ? 'done' : 'next',\n // Only the first slot has a max length to avoid password manager bubbles appearing after later inputs.\n maxLength: index === 0 ? length : undefined,\n tabIndex: activeIndex === index ? 0 : -1,\n disabled,\n form,\n pattern,\n readOnly,\n required,\n 'aria-labelledby': ariaLabel == null ? inheritedLabel : undefined,\n 'aria-invalid': !disabled && invalid ? true : undefined,\n 'aria-label': ariaLabel,\n onMouseDown(event) {\n if (event.defaultPrevented || disabled) {\n return;\n }\n event.preventDefault();\n focusInput(index);\n },\n onFocus(event) {\n if (event.defaultPrevented || disabled) {\n return;\n }\n handleInputFocus(index, event);\n },\n onBlur(event) {\n if (event.defaultPrevented) {\n return;\n }\n handleInputBlur(event);\n },\n onChange(event) {\n if (event.defaultPrevented || disabled || readOnly) {\n return;\n }\n const rawValue = event.currentTarget.value;\n const [nextDigits, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length, validationType, normalizeValue);\n if (didRejectCharacters) {\n reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputChange, event.nativeEvent));\n }\n if (nextDigits === '') {\n if (rawValue === '') {\n setValue(removeOTPCharacter(value, index), createChangeEventDetails(REASONS.inputClear, event.nativeEvent));\n } else if (slotValue !== '') {\n event.currentTarget.value = slotValue;\n event.currentTarget.select();\n }\n return;\n }\n const nextValue = replaceOTPValue(value, index, nextDigits, length, validationType, normalizeValue);\n const committedValue = setValue(nextValue, createChangeEventDetails(REASONS.inputChange, event.nativeEvent));\n if (committedValue != null) {\n const nextInput = Math.min(index + nextDigits.length, length - 1);\n queueFocusInput(nextInput, committedValue);\n }\n },\n onKeyDown(event) {\n if (event.defaultPrevented || disabled) {\n return;\n }\n const firstIndex = 0;\n const lastIndex = Math.max(length - 1, firstIndex);\n const endTargetIndex = Math.min(value.length, lastIndex);\n const hasBoundaryModifier = (event.ctrlKey || event.metaKey) && !event.altKey;\n const isRtl = direction === 'rtl';\n const previousKey = isRtl ? 'ArrowRight' : 'ArrowLeft';\n const nextKey = isRtl ? 'ArrowLeft' : 'ArrowRight';\n if (event.key === previousKey) {\n stopEvent(event);\n focusInput(hasBoundaryModifier ? firstIndex : Math.max(firstIndex, index - 1));\n return;\n }\n if (event.key === nextKey) {\n stopEvent(event);\n focusInput(hasBoundaryModifier ? endTargetIndex : Math.min(lastIndex, index + 1));\n return;\n }\n if (event.key === 'Home' || event.key === 'ArrowUp') {\n stopEvent(event);\n focusInput(firstIndex);\n return;\n }\n if (event.key === 'End' || event.key === 'ArrowDown') {\n stopEvent(event);\n focusInput(endTargetIndex);\n return;\n }\n if (readOnly) {\n return;\n }\n function setKeyboardValue(nextValue, targetIndex) {\n const committedValue = setValue(nextValue, createChangeEventDetails(REASONS.keyboard, event.nativeEvent));\n if (committedValue != null) {\n queueFocusInput(targetIndex, committedValue);\n }\n }\n if (event.key === 'Backspace' && hasBoundaryModifier) {\n stopEvent(event);\n setKeyboardValue('', firstIndex);\n return;\n }\n if (event.key === 'Delete') {\n stopEvent(event);\n setKeyboardValue(removeOTPCharacter(value, index), index);\n return;\n }\n const inputValue = event.currentTarget.value;\n const fullSelection = event.currentTarget.selectionStart === 0 && event.currentTarget.selectionEnd === inputValue.length;\n if (event.key.length === 1 && fullSelection && slotValue === event.key) {\n stopEvent(event);\n if (index < length - 1) {\n focusInput(index + 1);\n }\n return;\n }\n if (event.key === 'Backspace') {\n stopEvent(event);\n const targetIndex = Math.max(firstIndex, index - 1);\n const deleteIndex = slotValue === '' ? targetIndex : index;\n setKeyboardValue(removeOTPCharacter(value, deleteIndex), targetIndex);\n }\n },\n onPaste(event) {\n if (event.defaultPrevented || disabled || readOnly) {\n return;\n }\n let rawValue = '';\n try {\n rawValue = event.clipboardData?.getData('text/plain') ?? '';\n } catch {\n /* istanbul ignore else -- `process.env.NODE_ENV` is a build-time constant under test */\n if (process.env.NODE_ENV !== 'production') {\n const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';\n warn('<OTPField.Input> could not read clipboard text during paste handling.', ownerStackMessage);\n }\n return;\n }\n event.preventDefault();\n const [nextDigits, didRejectCharacters] = normalizeOTPValueWithDetails(rawValue, length, validationType, normalizeValue);\n if (didRejectCharacters) {\n reportValueInvalid(rawValue, createGenericEventDetails(REASONS.inputPaste, event.nativeEvent));\n }\n if (nextDigits === '') {\n return;\n }\n const committedValue = setValue(replaceOTPValue(value, index, nextDigits, length, validationType, normalizeValue), createChangeEventDetails(REASONS.inputPaste, event.nativeEvent));\n if (committedValue != null) {\n const nextInput = Math.min(index + nextDigits.length, length - 1);\n queueFocusInput(nextInput, committedValue);\n }\n }\n };\n const element = useRenderElement('input', componentProps, {\n ref: [forwardedRef, listItemRef, inputRef],\n state: inputState,\n props: [inputProps, elementProps],\n stateAttributesMapping: inputStateAttributesMapping\n });\n return element;\n});\nif (process.env.NODE_ENV !== \"production\") OTPFieldInput.displayName = \"OTPFieldInput\";","\"use client\";\nimport { createComponentPart } from \"../../internal/component-part.js\";\nimport { OTPField } from \"@base-ui/react/otp-field\";\n//#region src/components/otp-field/otp-field-input.tsx\nconst TROTPFieldInput = createComponentPart(OTPField.Input, \"tr-otp-field-digit\", { tracksFocusModality: true });\n//#endregion\nexport { TROTPFieldInput };\n\n//# sourceMappingURL=otp-field-input.js.map","\"use client\";\nimport { mergeComponentClassName } from \"../../internal/component-class-name.js\";\nimport { jsx } from \"react/jsx-runtime\";\nimport { OTPField } from \"@base-ui/react/otp-field\";\n//#region src/components/otp-field/otp-field-root.tsx\nfunction TROTPFieldRoot({ appearance = \"solid\", className, uiSize = \"md\", ...props }) {\n\treturn /* @__PURE__ */ jsx(OTPField.Root, {\n\t\t...props,\n\t\tclassName: mergeComponentClassName(\"tr-otp-field\", className),\n\t\t\"data-appearance\": appearance,\n\t\t\"data-ui-size\": uiSize\n\t});\n}\n//#endregion\nexport { TROTPFieldRoot };\n\n//# sourceMappingURL=otp-field-root.js.map","import { mergeComponentClassName } from \"../../internal/component-class-name.js\";\nimport { TRSeparator } from \"../separator/separator.js\";\nimport { jsx } from \"react/jsx-runtime\";\n//#region src/components/otp-field/otp-field-separator.tsx\nfunction TROTPFieldSeparator({ className, orientation = \"vertical\", ...props }) {\n\treturn /* @__PURE__ */ jsx(TRSeparator, {\n\t\t...props,\n\t\tclassName: mergeComponentClassName(\"tr-otp-field-separator\", className),\n\t\torientation\n\t});\n}\n//#endregion\nexport { TROTPFieldSeparator };\n\n//# sourceMappingURL=otp-field-separator.js.map","import { TROTPFieldInput } from \"./otp-field-input.js\";\nimport { TROTPFieldRoot } from \"./otp-field-root.js\";\nimport { TROTPFieldSeparator } from \"./otp-field-separator.js\";\n//#region src/components/otp-field/index.tsx\nconst TROTPField = {\n\tRoot: TROTPFieldRoot,\n\tInput: TROTPFieldInput,\n\tSeparator: TROTPFieldSeparator\n};\n//#endregion\nexport { TROTPField, TROTPFieldInput, TROTPFieldRoot, TROTPFieldSeparator };\n\n//# sourceMappingURL=index.js.map","import { TRField } from '@tinyrack/ui/components/field';\nimport { TROTPField } from '@tinyrack/ui/components/otp-field';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport type { FieldError } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\n\nexport type PinInputRef = {\n focus: () => void;\n clear: () => void;\n};\n\ntype PinInputProps = {\n length?: number;\n error?: FieldError;\n disabled?: boolean;\n onComplete?: (value: string) => void;\n onChange?: (value: string) => void;\n value?: string;\n autoFocus?: boolean;\n className?: string;\n};\n\nexport const PinInput = forwardRef<PinInputRef, PinInputProps>(\n function PinInput(\n {\n length = 6,\n error,\n disabled = false,\n onComplete,\n onChange,\n value: controlledValue,\n autoFocus = false,\n className = '',\n },\n ref,\n ) {\n const { t } = useTranslation();\n const otpId = useId();\n const containerRef = useRef<HTMLDivElement>(null);\n const [internalValue, setInternalValue] = useState(controlledValue ?? '');\n\n useEffect(() => {\n if (controlledValue !== undefined) {\n setInternalValue(controlledValue);\n }\n }, [controlledValue]);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => {\n const firstInput = containerRef.current?.querySelector('input');\n firstInput?.focus();\n },\n clear: () => {\n setInternalValue('');\n const firstInput = containerRef.current?.querySelector('input');\n firstInput?.focus();\n },\n }),\n [],\n );\n\n const handleValueChange = useCallback(\n (newValue: string) => {\n setInternalValue(newValue);\n onChange?.(newValue);\n },\n [onChange],\n );\n\n const handleValueComplete = useCallback(\n (completedValue: string) => {\n onComplete?.(completedValue);\n },\n [onComplete],\n );\n\n return (\n <TRField.Root className={className} ref={containerRef}>\n {/*\n A real label, not `aria-label`: Base UI deliberately ignores\n `aria-label` on the first OTP input and warns to use a label instead,\n because that input is also the one password managers autofill.\n Visually hidden — the screen's own heading already says what the code\n is, so showing it twice would be noise.\n */}\n <TRField.Label className=\"sr-only\" htmlFor={otpId}>\n {t('common.otp.label')}\n </TRField.Label>\n <TROTPField.Root\n disabled={disabled}\n /*\n * Base UI gives the first slot the root's own id and derives the\n * rest from it, so naming the root is what lets the label point at\n * a real input rather than at the wrapping group.\n */\n id={otpId}\n length={length}\n onValueChange={handleValueChange}\n onValueComplete={handleValueComplete}\n uiSize=\"md\"\n validationType=\"numeric\"\n value={internalValue}\n >\n {/*\n Each box is a separate input, so each needs to say which position\n it is. Two Base UI behaviours shape this: the first box ignores\n `aria-label` outright (it is the one password managers autofill, so\n it takes the field's own label), and on the rest an `aria-label`\n *replaces* the inherited field name rather than adding to it. So\n the field name is folded into the per-box string, and box one is\n left to the label above.\n */}\n {Array.from({ length }, (_, index) => (\n <TROTPField.Input\n aria-label={\n index === 0\n ? undefined\n : t('common.otp.digit', {\n label: t('common.otp.label'),\n position: index + 1,\n total: length,\n })\n }\n autoFocus={autoFocus && index === 0}\n key={index}\n />\n ))}\n </TROTPField.Root>\n {error && (\n <p\n className=\"mt-tinyrack-sm text-center text-tinyrack-danger text-tinyrack-sm\"\n data-testid=\"pin-input-error\"\n >\n {error.message}\n </p>\n )}\n </TRField.Root>\n );\n },\n);\n\nexport default PinInput;\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{q as e}from"./createLucideIcon-BPpAIXR_.js";import{I as t}from"./index-
|
|
2
|
-
//# sourceMappingURL=profile-
|
|
1
|
+
import{q as e}from"./createLucideIcon-BPpAIXR_.js";import{I as t}from"./index-CS23Ozt6.js";var n=e();function r(e){return(0,n.jsx)(t,{...e,onUnauthorized:()=>{window.location.href=`/login`}})}export{r as errorComponent};
|
|
2
|
+
//# sourceMappingURL=profile-B5NaJfeS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile-D43Yq-6S.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 {\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 { TRButton } from '@tinyrack/ui/components/button';\nimport { TRCard } from '@tinyrack/ui/components/card';\nimport { TRText } from '@tinyrack/ui/components/text';\nimport { CircleAlertIcon, LogOutIcon } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { AuthPageHeader } from '#frontend/components/auth/auth-page-header.tsx';\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 { AppLayout } from '#frontend/features/layout/app-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 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 const passwordAuthMethod = appConfig.auth.password;\n const passkeyAuthMethod = appConfig.auth.passkey;\n const totpEnabled = passwordAuthMethod.totp.enabled;\n const passkeyEnabled = passkeyAuthMethod.enabled;\n\n const accountDeletionEnabled = appConfig.account_deletion.enabled;\n const retentionPeriod = appConfig.account_deletion.retention;\n\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 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 <AppLayout\n headerActions={\n <TRButton\n appearance=\"ghost\"\n /*\n The visible label collapses below `sm:`, which would leave the\n control unnamed on a phone. `profile.logout` is the same string\n the label renders, so this does not shadow it.\n */\n aria-label={t('profile.logout')}\n data-testid=\"profile-logout\"\n disabled={logoutMutation.isPending}\n loading={logoutMutation.isPending}\n onClick={() => logoutMutation.mutate()}\n type=\"button\"\n uiSize=\"sm\"\n >\n {logoutMutation.isPending ? undefined : (\n <>\n <LogOutIcon aria-hidden className=\"size-tinyrack-lg\" />\n <span className=\"hidden sm:inline\">{t('profile.logout')}</span>\n </>\n )}\n </TRButton>\n }\n >\n <div className=\"flex items-center gap-tinyrack-lg\">\n <InitialAvatar email={user.email} size=\"lg\" />\n <div className=\"flex min-w-0 flex-col gap-tinyrack-3xs\">\n <AuthPageHeader title={t('profile.title')} />\n {/*\n Rendered here rather than as the header's `subtitle`: this node\n carries a testid and needs to truncate, neither of which the\n shared header does, and growing its API for one non-auth caller\n would be the wrong trade.\n */}\n <TRText\n as=\"p\"\n color=\"muted\"\n data-testid=\"profile-user-email\"\n truncate\n variant=\"bodySm\"\n >\n {user.email}\n </TRText>\n </div>\n </div>\n\n {oauthErrorMessage && (\n <Alert icon={CircleAlertIcon} type=\"error\">\n {oauthErrorMessage}\n </Alert>\n )}\n\n {user && <UserInfoSection user={user} />}\n\n {hasSecurityOptions && (\n <TRCard.Root variant=\"outlined\">\n <TRCard.Header className=\"border-tinyrack-border border-b-tinyrack-default px-tinyrack-lg py-tinyrack-md\">\n <TRCard.Title>{t('profile.security.title')}</TRCard.Title>\n <TRCard.Description>\n {t('profile.security.description')}\n </TRCard.Description>\n </TRCard.Header>\n {showTotpSection && user.totp_recovery_codes_missing && (\n <div\n className=\"border-tinyrack-border border-b-tinyrack-default px-tinyrack-lg py-tinyrack-md\"\n data-testid=\"profile-totp-recovery-warning\"\n >\n <Alert icon={CircleAlertIcon} type=\"warning\">\n {t('profile.totp.recoveryCodesMissing')}\n </Alert>\n </div>\n )}\n <TRCard.Content className=\"divide-y divide-tinyrack-border p-0\">\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 </TRCard.Content>\n </TRCard.Root>\n )}\n\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 <DangerZoneSection\n isConfigManaged={isConfigManaged}\n isDeletionEnabled={accountDeletionEnabled}\n onDeleteClick={() => setShowDeleteModal(true)}\n />\n\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 <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 <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 <UnlinkOAuthModal\n isOpen={unlinkModal !== null}\n isPending={unlinkMutation.isPending}\n onClose={() => setUnlinkModal(null)}\n onConfirm={handleUnlinkConfirm}\n providerName={unlinkModal?.name ?? ''}\n />\n\n <DeleteAccountModal\n isOpen={showDeleteModal}\n onClose={() => setShowDeleteModal(false)}\n retentionDays={retentionDays}\n />\n </AppLayout>\n );\n}\n"],"mappings":"qGAgEA,SAASI,EAAaC,EAA4B,CAChD,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,GAAIA,EACJ,mBAAsB,CACpBE,OAAOC,SAASC,KAAO,QACzB,CAAE,CAAA,CAGR"}
|
|
1
|
+
{"version":3,"file":"profile-B5NaJfeS.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 {\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 { TRButton } from '@tinyrack/ui/components/button';\nimport { TRCard } from '@tinyrack/ui/components/card';\nimport { TRText } from '@tinyrack/ui/components/text';\nimport { CircleAlertIcon, LogOutIcon } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { AuthPageHeader } from '#frontend/components/auth/auth-page-header.tsx';\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 { AppLayout } from '#frontend/features/layout/app-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 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 const passwordAuthMethod = appConfig.auth.password;\n const passkeyAuthMethod = appConfig.auth.passkey;\n const totpEnabled = passwordAuthMethod.totp.enabled;\n const passkeyEnabled = passkeyAuthMethod.enabled;\n\n const accountDeletionEnabled = appConfig.account_deletion.enabled;\n const retentionPeriod = appConfig.account_deletion.retention;\n\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 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 <AppLayout\n headerActions={\n <TRButton\n appearance=\"ghost\"\n /*\n The visible label collapses below `sm:`, which would leave the\n control unnamed on a phone. `profile.logout` is the same string\n the label renders, so this does not shadow it.\n */\n aria-label={t('profile.logout')}\n data-testid=\"profile-logout\"\n disabled={logoutMutation.isPending}\n loading={logoutMutation.isPending}\n onClick={() => logoutMutation.mutate()}\n type=\"button\"\n uiSize=\"sm\"\n >\n {logoutMutation.isPending ? undefined : (\n <>\n <LogOutIcon aria-hidden className=\"size-tinyrack-lg\" />\n <span className=\"hidden sm:inline\">{t('profile.logout')}</span>\n </>\n )}\n </TRButton>\n }\n >\n <div className=\"flex items-center gap-tinyrack-lg\">\n <InitialAvatar email={user.email} size=\"lg\" />\n <div className=\"flex min-w-0 flex-col gap-tinyrack-3xs\">\n <AuthPageHeader title={t('profile.title')} />\n {/*\n Rendered here rather than as the header's `subtitle`: this node\n carries a testid and needs to truncate, neither of which the\n shared header does, and growing its API for one non-auth caller\n would be the wrong trade.\n */}\n <TRText\n as=\"p\"\n color=\"muted\"\n data-testid=\"profile-user-email\"\n truncate\n variant=\"bodySm\"\n >\n {user.email}\n </TRText>\n </div>\n </div>\n\n {oauthErrorMessage && (\n <Alert icon={CircleAlertIcon} type=\"error\">\n {oauthErrorMessage}\n </Alert>\n )}\n\n {user && <UserInfoSection user={user} />}\n\n {hasSecurityOptions && (\n <TRCard.Root variant=\"outlined\">\n <TRCard.Header className=\"border-tinyrack-border border-b-tinyrack-default px-tinyrack-lg py-tinyrack-md\">\n <TRCard.Title>{t('profile.security.title')}</TRCard.Title>\n <TRCard.Description>\n {t('profile.security.description')}\n </TRCard.Description>\n </TRCard.Header>\n {showTotpSection && user.totp_recovery_codes_missing && (\n <div\n className=\"border-tinyrack-border border-b-tinyrack-default px-tinyrack-lg py-tinyrack-md\"\n data-testid=\"profile-totp-recovery-warning\"\n >\n <Alert icon={CircleAlertIcon} type=\"warning\">\n {t('profile.totp.recoveryCodesMissing')}\n </Alert>\n </div>\n )}\n <TRCard.Content className=\"divide-y divide-tinyrack-border p-0\">\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 </TRCard.Content>\n </TRCard.Root>\n )}\n\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 <DangerZoneSection\n isConfigManaged={isConfigManaged}\n isDeletionEnabled={accountDeletionEnabled}\n onDeleteClick={() => setShowDeleteModal(true)}\n />\n\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 <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 <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 <UnlinkOAuthModal\n isOpen={unlinkModal !== null}\n isPending={unlinkMutation.isPending}\n onClose={() => setUnlinkModal(null)}\n onConfirm={handleUnlinkConfirm}\n providerName={unlinkModal?.name ?? ''}\n />\n\n <DeleteAccountModal\n isOpen={showDeleteModal}\n onClose={() => setShowDeleteModal(false)}\n retentionDays={retentionDays}\n />\n </AppLayout>\n );\n}\n"],"mappings":"qGAgEA,SAASI,EAAaC,EAA4B,CAChD,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,GAAIA,EACJ,mBAAsB,CACpBE,OAAOC,SAASC,KAAO,QACzB,CAAE,CAAA,CAGR"}
|