dns-worker 1.1.5-canary.b03cc84 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +1 -0
  2. package/package.json +1 -1
  3. package/static/assets/{AccountView-7oJOJSs9.js → AccountView-t2HnohwK.js} +3 -3
  4. package/static/assets/AnalyticsView-DDNyezYl.js +2 -0
  5. package/static/assets/DestinationMap-Bwv9zW4k.js +1 -0
  6. package/static/assets/FilteringView-hYm_mlJ0.js +1 -0
  7. package/static/assets/{LogsView-ByLxHplT.js → LogsView-BSRCO63V.js} +3 -3
  8. package/static/assets/RulesView-DLhxdWLq.js +1 -0
  9. package/static/assets/SettingsView-VR3JolCU.js +1 -0
  10. package/static/assets/SetupView-BEaDE8T8.js +1 -0
  11. package/static/assets/{SwipeableDrawer-Ds0f8Ay4.js → SwipeableDrawer-DkPacJ1O.js} +1 -1
  12. package/static/assets/{TrendChart-DqTU1pRG.js → TrendChart-wcrIRt7R.js} +1 -1
  13. package/static/assets/allPaths-ZKIw3HqD.js +1 -0
  14. package/static/assets/allPathsLoader-CvGx1ejI.js +1 -0
  15. package/static/assets/browser-EPpuyQfw.js +1 -0
  16. package/static/assets/date-DG8jTrEB.js +1 -0
  17. package/static/assets/index-CrB_HdIL.js +17 -0
  18. package/static/assets/index-DZNm9qiP.css +2 -0
  19. package/static/assets/{services-C1W8eXRs.js → services-BYhiWUn8.js} +1 -1
  20. package/static/assets/splitPathsBySizeLoader-htHoS0DT.js +1 -0
  21. package/static/assets/sqlite.worker-_5i1w8Ie.js +186 -0
  22. package/static/assets/sqlite3-k2cTanUO.wasm +0 -0
  23. package/static/assets/{sqlite3-opfs-async-proxy-Ck-yCayi.js → sqlite3-opfs-async-proxy-DeAec6oc.js} +2 -3
  24. package/static/assets/sqlite3-opfs-async-proxy.js +2 -3
  25. package/static/assets/sqlite3-worker1-Cx6t16S_.js +44 -0
  26. package/static/assets/vendor-i18next-CevVzhh3.js +1 -0
  27. package/static/assets/{vendor-icons-other-Bme3ywH9.js → vendor-icons-other-BTYC6Wvz.js} +2 -2
  28. package/static/assets/vendor-react-De1zEwOV.js +11 -0
  29. package/static/assets/{vendor-ui-core-VafIkVkV.js → vendor-ui-core-ClwQiwMI.js} +1 -1
  30. package/static/assets/{vendor-utils-CnVXi31Q.js → vendor-utils-rmW6cqPl.js} +1 -1
  31. package/static/index.html +7 -7
  32. package/static/sqlite3-opfs-async-proxy.js +2 -3
  33. package/static/sw.js +1 -1
  34. package/static/assets/AnalyticsView-D-WRJtwS.js +0 -2
  35. package/static/assets/DestinationMap-e-Yw_mmW.js +0 -1
  36. package/static/assets/FilteringView-CJD9MW4f.js +0 -1
  37. package/static/assets/RulesView-i_14b5L8.js +0 -1
  38. package/static/assets/SettingsView-CjEOc4bE.js +0 -1
  39. package/static/assets/SetupView-BsF3kBJ-.js +0 -1
  40. package/static/assets/allPaths-BEI3QvIM.js +0 -1
  41. package/static/assets/allPathsLoader-DM2JAMeC.js +0 -1
  42. package/static/assets/browser-DaEGnZD0.js +0 -1
  43. package/static/assets/date-GC_sRpuZ.js +0 -1
  44. package/static/assets/index-47a3qWX-.css +0 -2
  45. package/static/assets/index-D2fmrnG9.js +0 -17
  46. package/static/assets/splitPathsBySizeLoader-BgBwSA38.js +0 -1
  47. package/static/assets/sqlite.worker-C50yoTbX.js +0 -186
  48. package/static/assets/sqlite3-Con_VOcu.wasm +0 -0
  49. package/static/assets/sqlite3-worker1-DZ2OAEkd.js +0 -44
  50. package/static/assets/vendor-i18next-cO7FDf_e.js +0 -1
  51. package/static/assets/vendor-react-BNdvqHuD.js +0 -11
package/README.md CHANGED
@@ -12,6 +12,7 @@
12
12
  [![Docker: hugokoo/dns-worker](https://img.shields.io/badge/docker-hugokoo%2Fdns--worker-2496ED.svg?logo=docker)](https://hub.docker.com/r/hugokoo/dns-worker)
13
13
  [![Platform: Cloudflare Workers](https://img.shields.io/badge/Platform-Cloudflare%20Workers-orange.svg)](https://workers.cloudflare.com/)
14
14
  [![Runtime: Node.js / Bun](https://img.shields.io/badge/Runtime-Node.js%20%7C%20Bun-green.svg)](https://nodejs.org/)
15
+ [![Database: D1 | Turso | File](https://img.shields.io/badge/Database-D1%20%7C%20Turso%20%7C%20File-blue.svg)](https://obein.github.io/DNS-Worker/deployment/database/)
15
16
  [![Security: NIST FIPS 203 PQC](https://img.shields.io/badge/Security-NIST%20FIPS%20203%20PQC-purple.svg)](https://csrc.nist.gov/pubs/fips/203/final)
16
17
  [![Docs: Astro Starlight](https://img.shields.io/badge/Docs-Astro%20Starlight-blueviolet.svg)](https://obein.github.io/DNS-Worker/)
17
18
  [![Protocols: UDP 53 · DoT / DoQ · DoH (H2/H3)](https://img.shields.io/badge/Protocols-UDP%2053%20%7C%20DoT%20%2F%20DoQ%20%7C%20DoH%20(H2%2FH3)-brightgreen.svg)](https://obein.github.io/DNS-Worker/deployment/matrix/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dns-worker",
3
- "version": "1.1.5-canary.b03cc84",
3
+ "version": "1.1.5",
4
4
  "private": false,
5
5
  "description": "Privacy-first DNS & DoH Resolver with modern Web Dashboard, built for Cloudflare Workers & Node.js",
6
6
  "main": "./dist/serverfull.mjs",
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/date-GC_sRpuZ.js","assets/index-D2fmrnG9.js","assets/vendor-icons-other-Bme3ywH9.js","assets/vendor-icons-16-BgwRBCeU.js","assets/rolldown-runtime-C4Xdq4VV.js","assets/vendor-icons-20-X5NPN60g.js","assets/vendor-react-BNdvqHuD.js","assets/vendor-ui-core-VafIkVkV.js","assets/vendor-utils-CnVXi31Q.js","assets/vendor-i18next-cO7FDf_e.js","assets/index-47a3qWX-.css"])))=>i.map(i=>d[i]);
2
- import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{$ as t,A as n,B as r,C as i,D as a,E as o,Et as s,J as c,M as l,Q as u,Qt as d,R as f,S as p,W as m,X as h,Y as g,b as _,ft as v,gt as y,ht as b,it as x,j as S,k as C,lt as w,rt as T,x as E,y as D,z as O}from"./vendor-react-BNdvqHuD.js";import{S as k,b as A,x as j}from"./vendor-icons-other-Bme3ywH9.js";import{r as ee}from"./vendor-i18next-cO7FDf_e.js";import{B as M,C as N,D as P,F as te,H as F,L as I,M as ne,N as L,O as R,P as z,R as B,S as V,T as re,V as H,_ as U,d as ie,f as W,h as ae,j as G,p as K,r as q,t as oe,u as se,v as ce,x as J,z as Y}from"./vendor-ui-core-VafIkVkV.js";import{_t as le}from"./vendor-utils-CnVXi31Q.js";import{$t as ue,At as de,Bt as fe,C as pe,Ct as me,Dt as he,E as ge,Et as _e,Ft as ve,It as ye,Kt as be,Lt as xe,Mt as Se,Nt as Ce,Ot as we,Pt as Te,Rt as Ee,S as De,St as Oe,T as ke,Vt as Ae,_t as je,bt as Me,d as Ne,f as Pe,gt as Fe,h as X,ht as Ie,i as Le,jt as Re,kt as ze,l as Be,m as Ve,mt as He,o as Ue,p as We,pt as Ge,r as Ke,s as qe,u as Je,vt as Ye,w as Xe,wt as Ze,x as Z,xt as Qe,yt as $e,zt as et}from"./index-D2fmrnG9.js";var Q=e(k(),1),$=e(A(),1);const tt=({recoveryKeys:e,copied:t,onCopy:r,onDone:i})=>{let{t:a}=d();return(0,$.jsxs)(`div`,{className:`p-4 bg-gray-50 dark:bg-gray-900/50 rounded-lg border border-gray-200 dark:border-gray-800`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(n,{size:20,className:`text-green-500`}),(0,$.jsx)(G,{style:{margin:0},children:a(`account.totp.recoveryKeysTitle`,`Save Your Recovery Keys`)})]}),(0,$.jsx)(V,{intent:H.WARNING,className:`mb-4`,children:a(`account.totp.recoveryKeysWarning`,`Store these keys safely. Each key can only be used once.`)}),(0,$.jsx)(`div`,{className:e.length===1?`space-y-2 mb-4`:`grid grid-cols-2 gap-2 mb-4`,children:e.map((e,t)=>(0,$.jsx)(`code`,{className:`block font-mono text-sm sm:text-base font-semibold bg-gray-100 dark:bg-gray-800 text-blue-600 dark:text-blue-400 px-4 py-3 rounded-xl text-center tracking-widest break-all select-all border border-gray-200 dark:border-gray-700`,children:e},t))}),(0,$.jsxs)(`div`,{className:`flex gap-2`,children:[(0,$.jsx)(L,{fill:!0,icon:(0,$.jsx)(w,{size:14}),text:t?a(`account.totp.copied`,`Copied!`):a(`account.totp.copyKeys`,`Copy All Keys`),intent:t?H.SUCCESS:H.NONE,onClick:r}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,text:a(`account.totp.done`,`Done, I've saved them`),onClick:i})]})]})},nt=({onRefresh:e,toasterRef:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(!0),[l,u]=(0,Q.useState)(null),[f,p]=(0,Q.useState)(!1),[m,h]=(0,Q.useState)(null),[g,_]=(0,Q.useState)(!1),[v,y]=(0,Q.useState)(``),[b,x]=(0,Q.useState)(!1),[S,C]=(0,Q.useState)(!1),[w,T]=(0,Q.useState)(``),[E,D]=(0,Q.useState)(null),[O,k]=(0,Q.useState)(``),[A,j]=(0,Q.useState)(!1),[ee,M]=(0,Q.useState)(!1),[N,P]=(0,Q.useState)(``),[te,F]=(0,Q.useState)(null),[I,ne]=(0,Q.useState)(!1),[L,R]=(0,Q.useState)(null),z=(0,Q.useCallback)(async()=>{o(!0);try{i(await me()||[])}catch{}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{c(et()),z()},[z]),{passkeys:r,loading:a,supported:s,recoveryKeys:l,setRecoveryKeys:u,copiedKeys:f,handleCopyRecoveryKeys:()=>{l&&navigator.clipboard.writeText(l.join(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/date-DG8jTrEB.js","assets/index-CrB_HdIL.js","assets/vendor-icons-other-BTYC6Wvz.js","assets/vendor-icons-16-BgwRBCeU.js","assets/rolldown-runtime-C4Xdq4VV.js","assets/vendor-icons-20-X5NPN60g.js","assets/vendor-react-De1zEwOV.js","assets/vendor-i18next-CevVzhh3.js","assets/vendor-ui-core-ClwQiwMI.js","assets/vendor-utils-rmW6cqPl.js","assets/index-DZNm9qiP.css"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{$ as t,A as n,B as r,C as i,D as a,E as o,Et as s,J as c,N as l,Q as u,Qt as d,R as f,S as p,W as m,X as h,Y as g,b as _,ft as v,gt as y,ht as b,it as x,j as S,k as C,lt as w,rt as T,x as E,y as D,z as O}from"./vendor-react-De1zEwOV.js";import{S as k,b as A,x as j}from"./vendor-icons-other-BTYC6Wvz.js";import{i as ee}from"./vendor-i18next-CevVzhh3.js";import{B as M,C as N,D as P,F as te,H as F,L as I,M as ne,N as L,O as R,P as z,R as B,S as V,T as re,V as H,_ as U,d as ie,f as W,h as ae,j as G,p as K,r as q,t as oe,u as se,v as ce,x as J,z as Y}from"./vendor-ui-core-ClwQiwMI.js";import{_t as le}from"./vendor-utils-rmW6cqPl.js";import{$t as ue,At as de,Bt as fe,C as pe,Ct as me,Dt as he,E as ge,Et as _e,Ft as ve,It as ye,Kt as be,Lt as xe,Mt as Se,Nt as Ce,Ot as we,Pt as Te,Rt as Ee,S as De,St as Oe,T as ke,Vt as Ae,_t as je,bt as Me,d as Ne,f as Pe,gt as Fe,h as X,ht as Ie,i as Le,jt as Re,kt as ze,l as Be,m as Ve,mt as He,o as Ue,p as We,pt as Ge,r as Ke,s as qe,u as Je,vt as Ye,w as Xe,wt as Ze,x as Z,xt as Qe,yt as $e,zt as et}from"./index-CrB_HdIL.js";var Q=e(k(),1),$=e(A(),1);const tt=({recoveryKeys:e,copied:t,onCopy:r,onDone:i})=>{let{t:a}=d();return(0,$.jsxs)(`div`,{className:`p-4 bg-gray-50 dark:bg-gray-900/50 rounded-lg border border-gray-200 dark:border-gray-800`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(n,{size:20,className:`text-green-500`}),(0,$.jsx)(G,{style:{margin:0},children:a(`account.totp.recoveryKeysTitle`,`Save Your Recovery Keys`)})]}),(0,$.jsx)(V,{intent:H.WARNING,className:`mb-4`,children:a(`account.totp.recoveryKeysWarning`,`Store these keys safely. Each key can only be used once.`)}),(0,$.jsx)(`div`,{className:e.length===1?`space-y-2 mb-4`:`grid grid-cols-2 gap-2 mb-4`,children:e.map((e,t)=>(0,$.jsx)(`code`,{className:`block font-mono text-sm sm:text-base font-semibold bg-gray-100 dark:bg-gray-800 text-blue-600 dark:text-blue-400 px-4 py-3 rounded-xl text-center tracking-widest break-all select-all border border-gray-200 dark:border-gray-700`,children:e},t))}),(0,$.jsxs)(`div`,{className:`flex gap-2`,children:[(0,$.jsx)(L,{fill:!0,icon:(0,$.jsx)(w,{size:14}),text:t?a(`account.totp.copied`,`Copied!`):a(`account.totp.copyKeys`,`Copy All Keys`),intent:t?H.SUCCESS:H.NONE,onClick:r}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,text:a(`account.totp.done`,`Done, I've saved them`),onClick:i})]})]})},nt=({onRefresh:e,toasterRef:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(!0),[l,u]=(0,Q.useState)(null),[f,p]=(0,Q.useState)(!1),[m,h]=(0,Q.useState)(null),[g,_]=(0,Q.useState)(!1),[v,y]=(0,Q.useState)(``),[b,x]=(0,Q.useState)(!1),[S,C]=(0,Q.useState)(!1),[w,T]=(0,Q.useState)(``),[E,D]=(0,Q.useState)(null),[O,k]=(0,Q.useState)(``),[A,j]=(0,Q.useState)(!1),[ee,M]=(0,Q.useState)(!1),[N,P]=(0,Q.useState)(``),[te,F]=(0,Q.useState)(null),[I,ne]=(0,Q.useState)(!1),[L,R]=(0,Q.useState)(null),z=(0,Q.useCallback)(async()=>{o(!0);try{i(await me()||[])}catch{}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{c(et()),z()},[z]),{passkeys:r,loading:a,supported:s,recoveryKeys:l,setRecoveryKeys:u,copiedKeys:f,handleCopyRecoveryKeys:()=>{l&&navigator.clipboard.writeText(l.join(`
3
3
  `)).then(()=>{p(!0),setTimeout(()=>p(!1),2e3)})},isAddOpen:g,setIsAddOpen:_,passkeyName:v,setPasskeyName:y,nameFocused:b,setNameFocused:x,registering:S,addError:w,setAddError:T,handleOpenAdd:()=>{y(``),T(``),x(!1),_(!0)},handleRegister:async t=>{t.preventDefault();let r=v.trim();if(!Ve(r)){T(n(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`));return}C(!0),T(``);try{let t=await Ee({name:r,credential:await Ae(await Oe())}),n=t?.passkey?.id||t?.id;if(n&&Z.isUnlocked())try{await Z.wrapCurrentKeyForPasskey(n)}catch(e){console.warn(`[Passkeys] Failed to wrap existing E2EE key for new passkey:`,e)}_(!1),y(``),await z(),e?.(),t?.recovery_keys&&t.recovery_keys.length>0&&u(t.recovery_keys)}catch(e){console.error(`Passkey registration failed:`,e),T(e instanceof Error?e.message:n(`account.passkey.regFailed`,`Registration failed`))}finally{C(!1)}},editingPasskey:E,setEditingPasskey:D,editName:O,setEditName:k,renameFocused:A,setRenameFocused:j,renaming:ee,renameError:N,setRenameError:P,handleOpenRename:e=>{D(e),k(e.name),P(``),j(!1)},handleRenameSubmit:async e=>{e.preventDefault();let t=O.trim();if(!(!E||!t)){if(!Ve(t)){P(n(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`));return}M(!0),P(``);try{await _e(E.id,t),D(null),await z()}catch(e){P(e instanceof Error?e.message:n(`common.errorNetwork`))}finally{M(!1)}}},deletingId:te,deleteConfirmOpen:I,setDeleteConfirmOpen:ne,targetToDelete:L,handleOpenDelete:e=>{R(e),ne(!0)},handleDeleteSubmit:async()=>{if(L){F(L.id);try{await je(L.id),ne(!1),R(null),await z(),e?.()}catch(e){let t=e instanceof Error?e.message:n(`common.errorNetwork`);alert(t)}finally{F(null)}}},testingId:m,handleTestPasskey:async e=>{h(e?e.id:`all`);try{let r=await Se(e?.id);r.success&&(t?.current?.show({message:n(`account.passkey.testSuccess`,{name:r.passkey?.name||e?.name||``,defaultValue:`Passkey verified successfully: ${r.passkey?.name||e?.name||``}`}),intent:H.SUCCESS,icon:`tick-circle`}),await z())}catch(e){let r=e instanceof Error?e.message:String(e);r.includes(`cancelled`)||r.includes(`NotAllowedError`)||r.includes(`timed out`)||r.includes(`abort`)?t?.current?.show({message:n(`account.passkey.testCancelled`,`Passkey verification cancelled`),intent:H.WARNING,icon:`warning-sign`}):t?.current?.show({message:r||n(`account.passkey.testFailed`,`Passkey verification failed`),intent:H.DANGER,icon:`error`})}finally{h(null)}},fetchPasskeys:z}},rt=({passkeys:e,loading:a,deletingId:o,testingId:s,onTestPasskey:c,onOpenRename:l,onOpenDelete:u})=>{let{t:f}=d();return a?(0,$.jsx)(`div`,{className:`py-6 text-center`,children:(0,$.jsx)(z,{size:24})}):e.length===0?(0,$.jsxs)(`div`,{className:`py-6 text-center text-sm text-gray-500 dark:text-gray-400 border border-dashed border-gray-200 dark:border-gray-800 rounded-lg`,children:[(0,$.jsx)(t,{size:28,className:`mx-auto mb-2 opacity-40`}),(0,$.jsx)(`p`,{children:f(`account.passkey.empty`,`No passkeys added yet.`)})]}):(0,$.jsx)(`div`,{className:`divide-y divide-gray-100 dark:divide-gray-800 border border-gray-200 dark:border-gray-800 rounded-lg overflow-hidden`,children:e.map(e=>(0,$.jsxs)(`div`,{className:`p-3 sm:p-4 flex items-center justify-between gap-3 hover:bg-gray-50 dark:hover:bg-gray-900/40 transition-colors`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[(0,$.jsx)(`div`,{className:`p-2 bg-purple-50 dark:bg-purple-950/40 text-purple-600 dark:text-purple-400 rounded-lg shrink-0`,children:(0,$.jsx)(t,{size:18})}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`font-semibold text-sm truncate text-gray-900 dark:text-gray-100`,children:e.name}),(0,$.jsxs)(`div`,{className:`text-xs text-gray-500 dark:text-gray-400 flex flex-wrap gap-x-3 gap-y-1 mt-0.5`,children:[(0,$.jsxs)(`span`,{children:[f(`account.passkey.created`,`Added`),`:`,` `,X(new Date(e.created_at*1e3))]}),e.last_used_at?(0,$.jsxs)(`span`,{children:[f(`account.passkey.lastUsed`,`Last used`),`:`,` `,X(new Date(e.last_used_at*1e3))]}):(0,$.jsx)(`span`,{children:f(`account.passkey.neverUsed`,`Never used`)})]})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,$.jsx)(L,{minimal:!0,small:!0,intent:H.PRIMARY,icon:(0,$.jsx)(n,{size:14}),title:f(`account.passkey.testThis`,`Test this passkey`),loading:s===e.id,onClick:()=>c?.(e)}),(0,$.jsx)(L,{minimal:!0,small:!0,icon:(0,$.jsx)(r,{size:14}),title:f(`common.rename`,`Rename`),onClick:()=>l(e)}),(0,$.jsx)(L,{minimal:!0,small:!0,intent:H.DANGER,icon:(0,$.jsx)(i,{size:14}),title:f(`common.delete`,`Delete`),loading:o===e.id,onClick:()=>u(e)})]})]},e.id))})},it=({isOpen:e,onClose:t,passkeyName:n,setPasskeyName:r,nameFocused:i,setNameFocused:a,registering:o,addError:s,setAddError:c,onSubmit:l})=>{let{t:u}=d();return(0,$.jsx)(R,{isOpen:e,onClose:()=>!o&&t(),title:u(`account.passkey.addTitle`,`Add New Passkey`),className:`max-w-md`,children:(0,$.jsxs)(`form`,{onSubmit:l,children:[(0,$.jsxs)(`div`,{className:I,children:[s&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:s}),(0,$.jsx)(K,{label:u(`account.passkey.nameLabel`,`Passkey Name`),labelFor:`passkey-name-input`,helperText:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),children:(0,$.jsx)(ce,{content:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),isOpen:i,position:M.TOP,intent:H.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(W,{id:`passkey-name-input`,autoFocus:!0,placeholder:u(`account.passkey.namePlaceholder`,`e.g. my_passkey`),value:n,onChange:e=>{r(e.target.value),s&&c(``)},onFocus:()=>a(!0),onBlur:()=>a(!1),disabled:o})})})}),(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400`,children:u(`account.passkey.promptNotice`,`After clicking continue, your browser will prompt you to authenticate via Key, face scan, PIN, or hardware key.`)})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{text:u(`common.cancel`,`Cancel`),onClick:t,disabled:o}),(0,$.jsx)(L,{intent:H.PRIMARY,type:`submit`,text:u(`account.passkey.continue`,`Continue`),loading:o,disabled:!Ve(n.trim())||o})]})})]})})},at=({isOpen:e,onClose:t,editName:n,setEditName:r,renameFocused:i,setRenameFocused:a,renaming:o,renameError:s,setRenameError:c,onSubmit:l})=>{let{t:u}=d();return(0,$.jsx)(R,{isOpen:e,onClose:()=>!o&&t(),title:u(`account.passkey.renameTitle`,`Rename Passkey`),className:`max-w-md`,children:(0,$.jsxs)(`form`,{onSubmit:l,children:[(0,$.jsxs)(`div`,{className:I,children:[s&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:s}),(0,$.jsx)(K,{label:u(`account.passkey.appNameLabel`,`Application (Domain)`),children:(0,$.jsx)(W,{readOnly:!0,disabled:!0,leftIcon:`globe`,value:window.location.hostname})}),(0,$.jsx)(K,{label:u(`account.passkey.nameLabel`,`Passkey Name`),helperText:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),children:(0,$.jsx)(ce,{content:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),isOpen:i,position:M.TOP,intent:H.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(W,{autoFocus:!0,placeholder:u(`account.passkey.namePlaceholder`,`e.g. my_passkey`),value:n,onChange:e=>{r(e.target.value),s&&c(``)},onFocus:()=>a(!0),onBlur:()=>a(!1),disabled:o})})})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{text:u(`common.cancel`,`Cancel`),onClick:t,disabled:o}),(0,$.jsx)(L,{intent:H.PRIMARY,type:`submit`,text:u(`common.save`,`Save`),loading:o,disabled:!Ve(n.trim())||o})]})})]})})},ot=({isOpen:e,onClose:t,targetToDelete:n,deleting:r,onConfirm:i})=>{let{t:a}=d();return(0,$.jsxs)(R,{isOpen:e,onClose:()=>!r&&t(),title:a(`account.passkey.deleteTitle`,`Delete Passkey`),className:`max-w-md`,children:[(0,$.jsx)(`div`,{className:I,children:(0,$.jsx)(`p`,{children:a(`account.passkey.deleteConfirm`,`Are you sure you want to delete passkey "{{name}}"? You will no longer be able to use this passkey for MFA.`,{name:n?.name})})}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{text:a(`common.cancel`,`Cancel`),onClick:t,disabled:r}),(0,$.jsx)(L,{intent:H.DANGER,text:a(`common.delete`,`Delete`),onClick:i,loading:r})]})})]})},st=({onRefresh:e})=>{let{t}=d(),r=(0,Q.useRef)(null),{passkeys:i,loading:a,supported:o,recoveryKeys:s,setRecoveryKeys:c,copiedKeys:l,handleCopyRecoveryKeys:f,isAddOpen:p,setIsAddOpen:m,passkeyName:h,setPasskeyName:g,nameFocused:_,setNameFocused:v,registering:y,addError:b,setAddError:x,handleOpenAdd:C,handleRegister:w,editingPasskey:T,setEditingPasskey:E,editName:D,setEditName:k,renameFocused:A,setRenameFocused:j,renaming:ee,renameError:M,setRenameError:N,handleOpenRename:P,handleRenameSubmit:te,deletingId:F,deleteConfirmOpen:I,setDeleteConfirmOpen:ne,targetToDelete:R,handleOpenDelete:z,handleDeleteSubmit:B,testingId:re,handleTestPasskey:U}=nt({onRefresh:e,toasterRef:r});return s?(0,$.jsx)(tt,{recoveryKeys:s,copied:l,onCopy:f,onDone:()=>c(null)}):(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(oe,{ref:r}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(u,{size:20,className:`text-purple-500`}),(0,$.jsx)(G,{style:{margin:0},children:t(`account.passkey.title`,`Passkeys`)}),(0,$.jsx)(q,{intent:i.length>0?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:i.length>0?t(`account.passkey.count`,{count:i.length,defaultValue:`${i.length} configured`}):t(`account.passkey.none`,`None configured`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[o&&i.length>0&&(0,$.jsx)(L,{intent:H.NONE,outlined:!0,icon:(0,$.jsx)(n,{size:16}),text:t(`account.passkey.testBtn`,`Test Passkey`),onClick:()=>U(),loading:re===`all`}),o&&(0,$.jsx)(L,{intent:H.PRIMARY,icon:(0,$.jsx)(O,{size:16}),text:t(`account.passkey.addBtn`,`Add Passkey`),onClick:C})]})]}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:t(`account.passkey.desc`,`Authenticate securely with biometrics (Touch ID, Face ID, Windows Hello) or a hardware security key (YubiKey) as an MFA factor.`)}),!o&&(0,$.jsx)(V,{intent:H.WARNING,icon:(0,$.jsx)(S,{size:16}),className:`mb-4`,children:t(`account.passkey.notSupported`,`Your browser or device does not support Passkeys (WebAuthn).`)}),(0,$.jsx)(rt,{passkeys:i,loading:a,deletingId:F,testingId:re,onTestPasskey:U,onOpenRename:P,onOpenDelete:z}),(0,$.jsx)(it,{isOpen:p,onClose:()=>m(!1),passkeyName:h,setPasskeyName:g,nameFocused:_,setNameFocused:v,registering:y,addError:b,setAddError:x,onSubmit:w}),(0,$.jsx)(at,{isOpen:!!T,onClose:()=>E(null),editName:D,setEditName:k,renameFocused:A,setRenameFocused:j,renaming:ee,renameError:M,setRenameError:N,onSubmit:te}),(0,$.jsx)(ot,{isOpen:I,onClose:()=>ne(!1),targetToDelete:R,deleting:!!F,onConfirm:B})]})},ct=({isOpen:e,onClose:n})=>{let{t:r}=d(),[i,a]=(0,Q.useState)(``),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(``),[u,f]=(0,Q.useState)(!1);(0,Q.useEffect)(()=>{e&&(a(``),l(``),f(!1),s(!1))},[e]);let p=async e=>{let t=(e??i).trim().replace(/\s/g,``);if(t.length!==6){l(r(`account.totp.invalidCode`,`Please enter a 6-digit code`));return}s(!0),l(``),f(!1);try{await Ce(t),f(!0)}catch(e){l((e instanceof Error?e.message:String(e))||r(`account.totp.testFailed`,`Invalid verification code`))}finally{s(!1)}};return(0,$.jsx)(R,{isOpen:e,onClose:n,title:r(`account.totp.testTitle`,`Test Authenticator App (TOTP)`),icon:(0,$.jsx)(t,{size:18}),children:(0,$.jsxs)(`div`,{className:`p-6 space-y-4`,children:[(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:r(`account.totp.testDesc`,`Enter the 6-digit verification code from your authenticator app to verify that it is generating valid codes.`)}),u&&(0,$.jsx)(V,{intent:H.SUCCESS,icon:(0,$.jsx)(v,{size:16}),children:r(`account.totp.testSuccess`,`Verification successful! Your authenticator app is configured properly.`)}),c&&(0,$.jsx)(V,{intent:H.DANGER,children:c}),(0,$.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),p()},className:`space-y-4`,children:[(0,$.jsx)(K,{label:r(`account.totp.verificationCode`,`6-Digit Verification Code`),labelFor:`test-totp-input`,children:(0,$.jsx)(W,{id:`test-totp-input`,value:i,onChange:e=>{let t=e.target.value.replace(/\D/g,``).slice(0,6);a(t),l(``),f(!1),t.length===6&&p(t)},placeholder:`123456`,maxLength:6,autoFocus:!0,inputMode:`numeric`,autoComplete:`one-time-code`,className:`font-mono text-lg tracking-widest`,disabled:o})}),(0,$.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,$.jsx)(L,{text:u?r(`common.close`,`Close`):r(`common.cancel`,`Cancel`),onClick:n}),!u&&(0,$.jsx)(L,{intent:H.PRIMARY,text:r(`account.totp.verifyBtn`,`Verify`),type:`submit`,loading:o,disabled:i.length!==6})]})]})]})})},lt=({user:e,disableDialogOpen:n,setDisableDialogOpen:r,disablePassword:i,setDisablePassword:a,disableError:s,setDisableError:c,disableLoading:l,onDisable:u})=>{let{t:f}=d(),[p,m]=Q.useState(!1),[h,g]=Q.useState(!1);return(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2 mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(o,{size:20,className:`text-blue-500`}),(0,$.jsx)(G,{style:{margin:0},children:f(`account.totp.title`,`Authenticator App (TOTP)`)}),(0,$.jsx)(q,{intent:H.SUCCESS,minimal:!0,round:!0,children:f(`account.totp.enabled`,`Enabled`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(L,{outlined:!0,icon:(0,$.jsx)(t,{size:14}),text:f(`account.totp.testBtn`,`Test Code`),onClick:()=>g(!0)}),(0,$.jsx)(L,{intent:H.DANGER,outlined:!0,icon:(0,$.jsx)(C,{size:14}),text:f(`account.totp.disable`,`Disable Authenticator App (TOTP)`),onClick:()=>r(!0)})]})]}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:f(`account.totp.activeDesc`,`Authenticator app (TOTP) is active and generating 6-digit verification codes for your account.`)})}),(0,$.jsx)(R,{isOpen:n,onClose:()=>{r(!1),a(``),c(``),m(!1)},title:f(`account.totp.disableTitle`,`Disable Authenticator App (TOTP)`),icon:`shield`,children:(0,$.jsxs)(`div`,{className:`p-6 space-y-4`,children:[(0,$.jsx)(V,{intent:H.WARNING,children:f(`account.totp.disableWarning`,`After disabling TOTP, if no Passkeys are configured, your account will only be protected by password.`)}),s&&(0,$.jsx)(V,{intent:H.DANGER,children:s}),!e.totp_skip_password&&(0,$.jsxs)(`form`,{onSubmit:u,className:`space-y-4`,children:[(0,$.jsx)(K,{label:f(`account.currentPassword`),children:(0,$.jsx)(W,{type:p?`text`:`password`,leftIcon:`lock`,value:i,onChange:e=>a(e.target.value),rightElement:(0,$.jsx)(L,{minimal:!0,icon:p?`eye-open`:`eye-off`,onClick:()=>m(!p),title:p?f(`auth.hidePassword`,`Hide password`):f(`auth.showPassword`,`Show password`)}),required:!0})}),(0,$.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,$.jsx)(L,{text:f(`account.cancel`),onClick:()=>r(!1)}),(0,$.jsx)(L,{intent:H.DANGER,text:f(`account.totp.confirmDisable`,`Disable TOTP`),type:`submit`,loading:l})]})]}),e.totp_skip_password&&(0,$.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,$.jsx)(L,{text:f(`account.cancel`),onClick:()=>r(!1)}),(0,$.jsx)(L,{intent:H.DANGER,text:f(`account.totp.confirmDisable`,`Disable TOTP`),loading:l,onClick:u})]})]})}),(0,$.jsx)(ct,{isOpen:h,onClose:()=>g(!1)})]})},ut=({setupData:e,setupToken:t,setSetupToken:n,setupError:r,setupLoading:i,onStartSetup:s,onConfirmSetup:c,onCancel:l})=>{let{t:u}=d();return(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2 mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(o,{size:20,className:`text-blue-500`}),(0,$.jsx)(G,{style:{margin:0},children:u(`account.totp.title`,`Authenticator App (TOTP)`)}),(0,$.jsx)(q,{minimal:!0,round:!0,intent:H.NONE,children:u(`account.totp.disabled`,`Disabled`)})]}),!e&&(0,$.jsx)(L,{intent:H.PRIMARY,icon:(0,$.jsx)(a,{size:14}),text:u(`account.totp.setupBtn`,`Set Up Authenticator App (TOTP)`),loading:i,onClick:s})]}),e?(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(`p`,{className:`text-sm font-medium`,children:u(`account.totp.scanQR`,`Scan this QR code with your authenticator app:`)}),(0,$.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,$.jsx)(Ke,{uri:e.uri}),(0,$.jsxs)(`div`,{className:`text-center`,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 mb-1`,children:u(`account.totp.orEnterManually`,`Or enter the key manually:`)}),(0,$.jsx)(`code`,{className:`text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded select-all`,children:e.secret})]})]}),(0,$.jsx)(U,{}),r&&(0,$.jsx)(V,{intent:H.DANGER,children:r}),(0,$.jsxs)(`form`,{onSubmit:c,className:`space-y-3`,children:[(0,$.jsx)(K,{label:u(`account.totp.enterCode`,`Enter the 6-digit code to confirm:`),helperText:u(`account.totp.enterCodeHint`,`This verifies the key was scanned correctly.`),children:(0,$.jsx)(Le,{length:6,value:t,onChange:n,disabled:i})}),(0,$.jsxs)(`div`,{className:`flex gap-2`,children:[(0,$.jsx)(L,{text:u(`account.cancel`),onClick:l}),(0,$.jsx)(L,{intent:H.SUCCESS,type:`submit`,loading:i,text:u(`account.totp.activate`,`Activate`),disabled:t.length<6})]})]})]}):(0,$.jsxs)(`div`,{className:`space-y-3`,children:[(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:u(`account.totp.setupDesc`,`Add an extra layer of security. Use Google Authenticator, Authy, or any TOTP app.`)}),r&&(0,$.jsx)(V,{intent:H.DANGER,children:r})]})]})},dt=({user:e,onRefresh:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)(null),[a,o]=(0,Q.useState)(``),[s,c]=(0,Q.useState)(null),[l,u]=(0,Q.useState)(!1),[f,p]=(0,Q.useState)(``),[m,h]=(0,Q.useState)(!1),[g,_]=(0,Q.useState)(!1),[v,y]=(0,Q.useState)(``),[b,x]=(0,Q.useState)(!1),[S,C]=(0,Q.useState)(``),[w,T]=(0,Q.useState)(!1);return s?(0,$.jsx)(tt,{recoveryKeys:s,copied:m,onCopy:()=>{s&&navigator.clipboard.writeText(s.join(`
4
- `)).then(()=>{h(!0),setTimeout(()=>h(!1),2e3)})},onDone:()=>c(null)}):e.totp_enabled?(0,$.jsx)(lt,{user:e,settingsLoading:w,onToggleSkipPassword:async e=>{T(!0);try{await xe(e),t()}catch{}finally{T(!1)}},disableDialogOpen:g,setDisableDialogOpen:_,disablePassword:v,setDisablePassword:y,disableError:S,setDisableError:C,disableLoading:b,onDisable:async r=>{r.preventDefault(),x(!0),C(``);try{let n=v;e.password_version===2&&(n=await Ne(v,e.username)),await Ye(n),_(!1),y(``),t()}catch(e){C(e.message||n(`common.errorNetwork`))}finally{x(!1)}}}):(0,$.jsx)(ut,{setupData:r,setupToken:a,setSetupToken:o,setupError:f,setupLoading:l,onStartSetup:async()=>{u(!0),p(``);try{i(await Re())}catch(e){p(e.message||n(`common.errorNetwork`))}finally{u(!1)}},onConfirmSetup:async e=>{if(e.preventDefault(),r){u(!0),p(``);try{let e=a.replace(/\s/g,``),n=crypto.randomUUID(),s=new TextEncoder().encode(e+n),l=await crypto.subtle.digest(`SHA-256`,s),u=Array.from(new Uint8Array(l)).map(e=>e.toString(16).padStart(2,`0`)).join(``);c((await Ie({secret:r.secret,totpTokenHash:u,salt:n})).recovery_keys),i(null),o(``),t()}catch(e){p(e.message||n(`common.errorNetwork`))}finally{u(!1)}}},onCancel:()=>{i(null),o(``),p(``)}})},ft=({method:e,onSelectMethod:t,hasPasskey:r,hasRecoveryKey:i,hasTotp:a,hasPassword:o})=>{let{t:s}=d();return(0,$.jsx)(`div`,{className:`flex justify-center mb-5 isolate`,style:{isolation:`isolate`},children:(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg`,children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[r&&(0,$.jsx)(L,{small:!0,active:e===`passkey`,intent:e===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.mfa.passkey`,`Passkey`),onClick:()=>t(`passkey`)}),i&&(0,$.jsx)(L,{small:!0,active:e===`recovery_key`,intent:e===`recovery_key`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.recoveryKey.verifyBtn`,`Recovery Key`),onClick:()=>t(`recovery_key`)}),a&&(0,$.jsx)(L,{small:!0,active:e===`totp`,intent:e===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:s(`account.mfa.totp`,`TOTP`),onClick:()=>t(`totp`)}),o&&(0,$.jsx)(L,{small:!0,active:e===`password`,intent:e===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:s(`account.mfa.password`,`Password`),onClick:()=>t(`password`)})]})})})},pt=({loading:e,onVerify:t})=>{let{t:n}=d();return(0,$.jsxs)(`div`,{className:`text-center py-4 space-y-4`,children:[(0,$.jsx)(`div`,{className:`flex justify-center`,children:(0,$.jsx)(`div`,{className:`p-4 rounded-full bg-blue-50 dark:bg-blue-900/30 text-blue-500`,children:(0,$.jsx)(u,{size:48})})}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-300`,children:n(`account.passkey.verifyPrompt`,`Authenticate using your device's biometric sensor (Face ID, Touch ID, Windows Hello) or security key.`)}),(0,$.jsx)(L,{fill:!0,large:!0,intent:H.PRIMARY,loading:e,onClick:t,icon:(0,$.jsx)(u,{size:16}),text:n(`account.usePasskeyInstead`,`Authenticate with Passkey`)})]})},mt=({totpCode:e,setTotpCode:t,loading:n,onVerify:r})=>{let{t:i}=d();return(0,$.jsxs)(`div`,{className:`py-2 space-y-4`,children:[(0,$.jsx)(K,{label:i(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Le,{length:6,value:e,onChange:e=>{t(e),e.length===6&&r(e)},disabled:n})}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,loading:n,disabled:e.length!==6,onClick:()=>r(),text:i(`common.confirm`,`Confirm`)})]})},ht=({password:e,setPassword:t,showPassword:n,setShowPassword:r,loading:i,onSubmit:a})=>{let{t:o}=d();return(0,$.jsxs)(`form`,{onSubmit:a,className:`py-2 space-y-4`,children:[(0,$.jsx)(K,{label:o(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(W,{leftIcon:`lock`,type:n?`text`:`password`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,rightElement:(0,$.jsx)(L,{minimal:!0,icon:n?`eye-open`:`eye-off`,onClick:()=>r(!n)})})}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,type:`submit`,loading:i,text:o(`common.confirm`,`Confirm`)})]})},gt=({recoveryKey:e,setRecoveryKey:t,loading:n,onSubmit:r})=>{let{t:i}=d();return(0,$.jsxs)(`form`,{onSubmit:r,autoComplete:`off`,className:`py-2 space-y-4`,children:[(0,$.jsx)(K,{label:i(`account.recoveryKey.verifyPromptLabel`,`原恢复密钥 (Original Recovery Key)`),children:(0,$.jsx)(W,{leftIcon:`key`,type:`text`,id:`verify-recovery-key-input`,name:`verify_recovery_key_input`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,className:`font-mono text-xs`})}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,type:`submit`,loading:n,disabled:!e.trim(),text:i(`common.confirm`,`Confirm`)})]})};var _t=(e,t)=>{let n=t||[`passkey`,`totp`,`password`];return n.includes(`passkey`)&&e?.passkeys_count&&e.passkeys_count>0?`passkey`:n.includes(`recovery_key`)?`recovery_key`:n.includes(`totp`)&&e?.totp_enabled?`totp`:n.includes(`password`)?`password`:n[0]||`password`};const vt=({isOpen:e,onClose:t,user:n,title:r,onVerify:i,allowedMethods:a})=>{let{t:o}=d(),s=a||[`passkey`,`totp`,`password`],c=!!(n?.passkeys_count&&n.passkeys_count>0)&&s.includes(`passkey`),l=!!n?.totp_enabled&&s.includes(`totp`),u=s.includes(`password`),f=s.includes(`recovery_key`),p=_t(n,a),[m,h]=(0,Q.useState)(p),[g,_]=(0,Q.useState)(``),[v,y]=(0,Q.useState)(!1),[b,x]=(0,Q.useState)(``),[S,C]=(0,Q.useState)(``),[w,T]=(0,Q.useState)(!1),[E,D]=(0,Q.useState)(``),[O,k]=(0,Q.useState)(e);!O&&e?(k(!0),h(p),_(``),y(!1),x(``),C(``),D(``)):O&&!e&&k(!1),(0,Q.useEffect)(()=>{m===`passkey`&&!c?h(f?`recovery_key`:l?`totp`:`password`):m===`totp`&&!l?h(c?`passkey`:f?`recovery_key`:`password`):m===`recovery_key`&&!f&&h(c?`passkey`:l?`totp`:`password`)},[c,l,f,m]);let A=async e=>{if(e&&e.preventDefault(),!g){D(o(`auth.passwordRequired`,`Password is required`));return}T(!0),D(``);try{let e=g;n?.password_version===2&&n?.username&&(e=await Ne(g,n.username)),await i({password:e}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},j=async()=>{T(!0),D(``);try{await i({passkeyAssertion:await fe(await Qe())}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},ee=async e=>{let n=e||b;if(n.length!==6){D(o(`account.totp.invalidCode`,`Please enter a 6-digit code`));return}T(!0),D(``);try{let e=crypto.randomUUID(),r=new TextEncoder().encode(n+e),a=await crypto.subtle.digest(`SHA-256`,r);await i({totpTokenHash:Array.from(new Uint8Array(a)).map(e=>e.toString(16).padStart(2,`0`)).join(``),totpSalt:e}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},M=async e=>{e&&e.preventDefault();let n=S.trim();if(!n){D(o(`account.recoveryKey.keyRequired`,`Recovery key is required`));return}T(!0),D(``);try{await i({recoveryKey:n}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},N=(c?1:0)+(f?1:0)+(l?1:0)+(u?1:0);return(0,$.jsx)(R,{isOpen:e,onClose:t,title:r||o(`account.verifyIdentity`,`Security Verification`),icon:`shield`,className:`max-w-md w-full`,children:(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:o(`account.verifyIdentityDesc`,`To protect your account security, please verify your identity before proceeding.`)}),N>1&&(0,$.jsx)(ft,{method:m,onSelectMethod:e=>{h(e),D(``)},hasPasskey:c,hasRecoveryKey:f,hasTotp:l,hasPassword:u}),E&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:E}),m===`recovery_key`&&(0,$.jsx)(gt,{recoveryKey:S,setRecoveryKey:C,loading:w,onSubmit:M}),m===`passkey`&&(0,$.jsx)(pt,{loading:w,onVerify:j}),m===`totp`&&(0,$.jsx)(mt,{totpCode:b,setTotpCode:x,loading:w,onVerify:ee}),m===`password`&&(0,$.jsx)(ht,{password:g,setPassword:_,showPassword:v,setShowPassword:y,loading:w,onSubmit:A})]})})},yt=({user:e,onRefresh:t})=>{let{t:r}=d(),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(null),[p,m]=(0,Q.useState)(!1),[g,_]=(0,Q.useState)(!1),[v,b]=(0,Q.useState)(null),C=!!(e.has_recovery_keys||e.recovery_keys_encrypted),E=()=>{b(null),s(!0)},D=()=>{s(!1),a(!0)},O=async e=>{let n=await ze(e);l(n.recovery_key),m(!1);let i=!1;if(Z.isUnlocked())try{await Z.wrapCurrentKeyForRecovery(n.recovery_key),i=!0}catch(e){console.warn(`[RecoveryKey] Failed to wrap E2EE key with new recovery key:`,e)}else if(e.recoveryKey)try{await Z.unlockWithRecoveryKey(e.recoveryKey),await Z.wrapCurrentKeyForRecovery(n.recovery_key),i=!0}catch(e){console.warn(`[RecoveryKey] Failed to unlock and re-wrap with new recovery key:`,e)}else if(e.passkeyAssertion)try{await Z.unlockUser(),await Z.wrapCurrentKeyForRecovery(n.recovery_key),i=!0}catch(e){console.warn(`[RecoveryKey] Failed to unlock via Passkey and re-wrap:`,e)}try{if((await Z.getUserStatus()).hasKeys&&!i){b({text:r(`account.recoveryKey.rotateSuccessE2eeWarning`,`恢复密钥已成功轮换!注意:由于端到端加密此前处于锁定状态且未能解密,旧 E2EE 密文仍需使用轮换前的旧恢复密钥解锁,或可在下方端到端加密卡片中点击「重置密钥对」。`),intent:H.WARNING}),t();return}}catch{}b({text:r(`account.recoveryKey.rotateSuccess`,`恢复密钥已成功轮换!请立即妥善离线保存新密钥,旧密钥已失效。`),intent:H.SUCCESS}),t()},k=e=>{navigator.clipboard.writeText(e),_(!0),setTimeout(()=>_(!1),2e3)};return(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,$.jsx)(u,{size:18,className:`text-amber-500`}),(0,$.jsx)(G,{style:{margin:0},children:r(`account.recoveryKey.title`,`紧急恢复密钥`)}),(0,$.jsx)(q,{intent:C?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:C?r(`account.recoveryKey.configured`,`已配置`):r(`account.recoveryKey.notConfigured`,`未配置`)}),(0,$.jsx)(ce,{content:r(`account.recoveryKey.oneWayTooltip`,`采用 SHA-256 单向密码学散列保护,服务端不存储明文且不可解密,仅支持身份轮换验证。`),position:M.TOP,children:(0,$.jsx)(q,{intent:H.PRIMARY,minimal:!0,round:!0,icon:(0,$.jsx)(n,{size:12,style:{display:`inline-flex`,alignItems:`center`,marginRight:`4px`}}),children:r(`account.recoveryKey.oneWayHash`,`单向不可逆散列`)})})]}),(0,$.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,$.jsx)(L,{small:!0,intent:H.WARNING,icon:(0,$.jsx)(f,{size:14}),text:r(`account.recoveryKey.rotateBtn`,`轮换恢复密钥`),onClick:E})})]}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:r(`account.recoveryKey.descOneWay`,`紧急恢复密钥是在您丢失所有通行密钥 (Passkey) 或身份验证器时,恢复账号访问及端到端解密数据的唯一凭据。为确保零知识安全,恢复密钥采用单向不可逆散列存储,无法在网页端查看明文,仅支持通过原恢复密钥或现有 Passkey 进行轮换。密钥一旦被使用将立即自动轮换。`)}),v&&(0,$.jsx)(V,{intent:v.intent,className:`my-2`,children:v.text}),c&&(0,$.jsxs)(J,{elevation:F.ZERO,className:`bg-amber-50/50 dark:bg-amber-950/20 border border-amber-300 dark:border-amber-800 p-4 space-y-3`,children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-2`,children:[(0,$.jsxs)(`span`,{className:`text-xs font-semibold text-amber-800 dark:text-amber-300 uppercase tracking-wider flex items-center gap-1.5`,children:[(0,$.jsx)(S,{size:14}),r(`account.recoveryKey.newKeyGenerated`,`已生成全新 30 位恢复密钥(请立即保存)`)]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[(0,$.jsx)(L,{minimal:!0,small:!0,icon:p?(0,$.jsx)(T,{size:14}):(0,$.jsx)(x,{size:14}),onClick:()=>m(!p),title:p?r(`auth.showPassword`,`显示`):r(`auth.hidePassword`,`隐藏`)}),(0,$.jsx)(L,{minimal:!0,small:!0,icon:g?(0,$.jsx)(y,{size:14,className:`text-green-500`}):(0,$.jsx)(w,{size:14}),onClick:()=>k(c),title:r(`common.copy`,`复制`),text:g?r(`common.copied`,`已复制`):r(`common.copy`,`复制`)}),(0,$.jsx)(L,{minimal:!0,small:!0,icon:`cross`,onClick:()=>l(null),title:r(`common.close`,`关闭`)})]})]}),(0,$.jsx)(`div`,{className:`p-3 bg-white dark:bg-gray-900 rounded border border-amber-200 dark:border-amber-800/80 font-mono text-center text-lg sm:text-xl font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:p?`••••••-••••••-••••••-••••••-••••••`:c}),(0,$.jsxs)(`p`,{className:`text-xs text-amber-700 dark:text-amber-400 flex items-center gap-1`,children:[(0,$.jsx)(h,{size:14,className:`shrink-0`}),r(`account.recoveryKey.oneWayWarning`,`注意:此密钥仅在此显示一次,关闭后将无法再次查看!服务端仅保存不可逆散列,请务必将其妥善复制并离线安全保存。`)]})]}),(0,$.jsx)(P,{isOpen:o,onConfirm:D,onCancel:()=>s(!1),cancelButtonText:r(`common.cancel`,`取消`),confirmButtonText:r(`account.recoveryKey.confirmRotateBtn`,`确认进入轮换验证`),intent:H.DANGER,icon:`warning-sign`,children:(0,$.jsx)(`p`,{children:r(`account.recoveryKey.rotateConfirm`,`轮换恢复密钥将立即使原恢复密钥失效,并重新派生信封加密密钥。仅允许通过现有通行密钥 (Passkey) 或原恢复密钥完成轮换验证。是否继续?`)})}),(0,$.jsx)(vt,{isOpen:i,onClose:()=>a(!1),user:e,allowedMethods:[`passkey`,`recovery_key`],title:r(`account.recoveryKey.rotateVerifyTitle`,`验证身份以轮换恢复密钥`),onVerify:O})]})},bt=({user:e,onRefresh:r})=>{let{t:i}=d(),[a,o]=(0,Q.useState)(!1),s=!!(e.mfa_enabled??(e.totp_enabled||e.passkeys_count&&e.passkeys_count>0)),c=async e=>{o(!0);try{await ve(e),r()}catch(e){alert(e.message||i(`common.errorNetwork`,`Network error`))}finally{o(!1)}};return(0,$.jsxs)(J,{elevation:F.ONE,className:`space-y-6`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`flex items-center justify-between mb-3`,children:(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(n,{size:20,className:s?`text-green-500`:`text-gray-400`}),(0,$.jsx)(G,{style:{margin:0},children:i(`account.mfa.title`,`Multi-Factor Authentication (MFA)`)}),(0,$.jsx)(q,{intent:s?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:s?i(`account.mfa.enabled`,`Configured`):i(`account.mfa.notConfigured`,`Not Configured`)})]})}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:i(`account.mfa.desc`,`Passkeys and Authenticator Apps (TOTP) both serve as MFA authentication methods. Configuring at least one factor protects your account and enables passwordless login and self-service password recovery.`)}),s?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(U,{className:`my-3`}),(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-2 py-1`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`font-medium text-sm text-gray-900 dark:text-gray-100`,children:i(`account.mfa.passwordlessTitle`,`Passwordless Login`)}),(0,$.jsx)(`div`,{className:`text-xs text-gray-500 dark:text-gray-400`,children:i(`account.mfa.passwordlessDesc`,`When enabled, logging in will skip the password requirement and verify your identity directly via Passkey or TOTP.`)})]}),(0,$.jsx)(ae,{checked:!!e.totp_skip_password,onChange:e=>c(e.currentTarget.checked),disabled:a,className:`mb-0 shrink-0`})]})]}):(0,$.jsx)(V,{intent:H.PRIMARY,icon:(0,$.jsx)(t,{size:16,style:{display:`inline-flex`,alignItems:`center`,marginRight:`8px`}}),children:i(`account.mfa.unconfiguredHint`,`No MFA method configured yet. Set up either a Passkey or Authenticator App below to safeguard your account and unlock passwordless login and account recovery.`)})]}),(0,$.jsx)(U,{}),(0,$.jsx)(st,{onRefresh:r}),(0,$.jsx)(U,{}),(0,$.jsx)(dt,{user:e,onRefresh:r}),(0,$.jsx)(U,{}),(0,$.jsx)(yt,{user:e,onRefresh:r})]})},xt={signup:{label:`account.activity.signup`,icon:(0,$.jsx)(E,{size:14}),intent:H.SUCCESS},login_success:{label:`account.activity.loginSuccess`,icon:(0,$.jsx)(g,{size:14}),intent:H.SUCCESS},login_fail:{label:`account.activity.loginFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER},logout:{label:`account.activity.logout`,icon:(0,$.jsx)(c,{size:14}),intent:H.NONE},password_change_success:{label:`account.activity.pwChangeSuccess`,icon:(0,$.jsx)(u,{size:14}),intent:H.SUCCESS},password_change_fail:{label:`account.activity.pwChangeFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER},totp_verify_success:{label:`account.activity.totpVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:H.SUCCESS},totp_verify_fail:{label:`account.activity.totpVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER},totp_setup:{label:`account.activity.totpSetup`,icon:(0,$.jsx)(a,{size:14}),intent:H.PRIMARY},totp_removed:{label:`account.activity.totpRemoved`,icon:(0,$.jsx)(C,{size:14}),intent:H.WARNING},recovery_key_used:{label:`account.activity.recoveryKeyUsed`,icon:(0,$.jsx)(u,{size:14}),intent:H.WARNING},recovery_key_rotated:{label:`account.activity.recoveryKeyRotated`,icon:(0,$.jsx)(u,{size:14}),intent:H.WARNING},session_revoked:{label:`account.activity.sessionRevoked`,icon:(0,$.jsx)(c,{size:14}),intent:H.WARNING},passkey_registered:{label:`account.activity.passkeyRegistered`,icon:(0,$.jsx)(u,{size:14}),intent:H.PRIMARY},passkey_deleted:{label:`account.activity.passkeyDeleted`,icon:(0,$.jsx)(C,{size:14}),intent:H.WARNING},passkey_verify_success:{label:`account.activity.passkeyVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:H.SUCCESS},passkey_verify_fail:{label:`account.activity.passkeyVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER}},St=e=>{if(!e)return`desktop`;let t=e.toLowerCase();return t.includes(`mobile`)||t.includes(`android`)||t.includes(`iphone`)||t.includes(`tablet`)||t.includes(`ipad`)?`mobile-phone`:`desktop`},Ct=(e,t)=>{if(!e)return t;let n=e;return n.includes(`Edg/`)?`Edge`:n.includes(`Chrome/`)&&!n.includes(`Edg/`)?`Chrome`:n.includes(`Firefox/`)?`Firefox`:n.includes(`Safari/`)&&!n.includes(`Chrome/`)?`Safari`:t},wt=({userAgent:e})=>{let{t}=d();if(!e)return(0,$.jsx)(`span`,{className:`text-gray-500`,children:`—`});let n=Ct(e,t(`account.sessions.unknownDevice`,`Unknown Device`));return(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(te,{icon:St(e),className:`text-gray-400`}),(0,$.jsx)(`span`,{children:n})]}),(0,$.jsx)(`div`,{className:`text-xs text-gray-400 mt-1 max-w-xs truncate`,title:e,children:e})]})},Tt=({hoveredSessionId:e,setHoveredSessionId:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[c,l]=(0,Q.useState)(!0),[u,p]=(0,Q.useState)(!1),m=(0,Q.useCallback)(async e=>{o(!0);try{let t=new URLSearchParams({limit:`20`});e&&t.set(`before`,String(e));let n=await $e(t.toString());i(e?e=>[...e,...n]:n),l(n.length===20)}catch{}finally{o(!1)}},[]);(0,Q.useEffect)(()=>{m()},[m]);let h=()=>{let e=r[r.length-1];e&&m(e.timestamp)},g=e=>xt[e]??{label:e,icon:(0,$.jsx)(s,{size:14}),intent:H.NONE};return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between cursor-pointer`,onClick:()=>p(!u),children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(s,{size:20,className:`text-purple-500`}),(0,$.jsx)(G,{style:{margin:0},children:n(`account.activity.title`,`Account Activity`)}),r.length>0&&(0,$.jsxs)(q,{minimal:!0,round:!0,intent:H.NONE,children:[r.length,c?`+`:``]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(L,{minimal:!0,icon:(0,$.jsx)(f,{size:14}),onClick:e=>{e.stopPropagation(),m()}}),(0,$.jsx)(b,{size:16,className:`text-gray-400 transition-transform ${u?`rotate-180`:``}`})]})]}),u&&(0,$.jsx)(`div`,{className:`mt-4`,children:a&&r.length===0?(0,$.jsx)(`div`,{className:`flex justify-center py-8`,children:(0,$.jsx)(z,{size:24})}):r.length===0?(0,$.jsx)(`p`,{className:`text-sm text-gray-500 text-center py-6`,children:n(`account.activity.empty`,`No activity recorded yet.`)}):(0,$.jsxs)(`div`,{className:`overflow-x-auto`,children:[(0,$.jsxs)(se,{interactive:!0,striped:!0,className:`w-full text-sm`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{children:n(`account.activity.action`,`Action`)}),(0,$.jsx)(`th`,{children:n(`account.activity.time`,`Time`)}),(0,$.jsx)(`th`,{children:n(`account.activity.session`,`Session`)}),(0,$.jsx)(`th`,{children:n(`account.activity.ip`,`IP Address`)}),(0,$.jsx)(`th`,{children:n(`account.activity.device`,`Device`)})]})}),(0,$.jsx)(`tbody`,{children:r.map(r=>{let i=g(r.action),a=``,o=r.session_id_hash||``;if(r.extra)try{let e=JSON.parse(r.extra);if(e.reason){let t=`account.activity.reasons.${e.reason}`,r=n(t);a=r&&r!==t?r:e.reason.replace(/[_-]+/g,` `).replace(/\b\w/g,e=>e.toUpperCase())}}catch{}return(0,$.jsxs)(`tr`,{onMouseEnter:()=>{o&&t?.(o)},onMouseLeave:()=>{o&&t?.(null)},className:e&&e===o?`bg-gray-100/80 dark:bg-slate-800/80`:``,children:[(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsxs)(`div`,{className:`flex flex-col items-start gap-1`,children:[(0,$.jsx)(q,{minimal:!0,intent:i.intent,icon:i.icon,children:n(i.label,r.action)}),a&&(0,$.jsx)(`span`,{className:`text-xs text-gray-500 italic ml-1`,children:a})]})}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 whitespace-nowrap align-middle`,children:X(new Date(r.timestamp*1e3))}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:o?o.slice(0,8):`—`}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:r.ip_address||`—`}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(wt,{userAgent:r.user_agent||null})})]},r.id)})})]}),c&&(0,$.jsx)(`div`,{className:`flex justify-center mt-3`,children:(0,$.jsx)(L,{minimal:!0,loading:a,text:n(`account.activity.loadMore`,`Load More`),onClick:h})})]})})]})},Et=({hoveredSessionId:e,setHoveredSessionId:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,l]=(0,Q.useState)(null),[u,p]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(!1),_=r.filter(e=>!e.is_current).length,v=(0,Q.useCallback)(async()=>{o(!0);try{let e=await Ze(),t=Date.now();i((e||[]).filter(e=>e.expires_at*1e3>t))}catch{}finally{o(!1)}},[]);(0,Q.useEffect)(()=>{v()},[v]);let y=async e=>{l(e);try{(await we(e)).is_current?window.location.reload():i(t=>t.filter(t=>t.id!==e))}catch(e){alert(e.message||n(`account.sessions.revokeFailed`,`Failed to revoke session.`))}finally{l(null)}};return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(m,{size:20,className:`text-green-500`}),(0,$.jsx)(G,{style:{margin:0},children:n(`account.sessions.title`,`Active Sessions`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[_>0&&(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.DANGER,icon:(0,$.jsx)(c,{size:14}),text:n(`account.sessions.revokeOthers`,`Revoke Other Sessions`),loading:u,onClick:()=>g(!0)}),(0,$.jsx)(L,{minimal:!0,icon:(0,$.jsx)(f,{size:14}),onClick:()=>v()})]})]}),a?(0,$.jsx)(`div`,{className:`flex justify-center py-4`,children:(0,$.jsx)(z,{size:24})}):r.length===0?(0,$.jsx)(`p`,{className:`text-sm text-gray-500 text-center py-4`,children:n(`account.sessions.empty`,`No active sessions found.`)}):(0,$.jsx)(`div`,{className:`overflow-x-auto`,children:(0,$.jsxs)(se,{interactive:!0,striped:!0,className:`w-full text-sm`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{children:n(`account.sessions.device`,`Device`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.session`,`Session`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.ip`,`IP Address`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.loginTime`,`Login Time`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.expires`,`Expires`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.action`,`Action`)})]})}),(0,$.jsx)(`tbody`,{children:r.map(r=>(0,$.jsxs)(`tr`,{onMouseEnter:()=>t?.(r.id),onMouseLeave:()=>t?.(null),className:e===r.id?`bg-gray-100/80 dark:bg-slate-800/80`:``,children:[(0,$.jsx)(`td`,{children:(0,$.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,$.jsx)(wt,{userAgent:r.user_agent}),r.is_current&&(0,$.jsx)(q,{minimal:!0,intent:H.SUCCESS,className:`mt-0.5`,children:n(`account.sessions.current`,`Current`)})]})}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:r.id?r.id.slice(0,8):`—`}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:r.ip_address||`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:r.created_at?X(new Date(r.created_at*1e3)):`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:X(new Date(r.expires_at*1e3))}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.DANGER,disabled:r.is_current,icon:(0,$.jsx)(c,{size:14}),text:n(`account.sessions.revoke`,`Revoke`),loading:s===r.id,onClick:()=>y(r.id)})})]},r.id))})]})}),(0,$.jsx)(P,{isOpen:h,cancelButtonText:n(`common.cancel`,`Cancel`),confirmButtonText:n(`account.sessions.confirmRevokeOthers`,`Revoke Other Sessions`),intent:H.DANGER,icon:`log-out`,onCancel:()=>g(!1),onConfirm:async()=>{p(!0);try{await he(),i(e=>e.filter(e=>e.is_current)),g(!1)}catch(e){alert(e.message||n(`account.sessions.revokeFailed`,`Failed to revoke session.`))}finally{p(!1)}},loading:u,children:(0,$.jsx)(`p`,{children:n(`account.sessions.revokeOthersConfirmText`,`Are you sure you want to revoke all other active sessions? All other logged-in devices will be signed out immediately.`)})})]})},Dt=({users:e,currentUserId:t,onRefresh:r,registrationEnabled:a=!0,onRefreshSettings:o})=>{let{t:s}=d(),[c,l]=(0,Q.useState)(!1),[u,f]=(0,Q.useState)(``),[p,m]=(0,Q.useState)(``),[h,g]=(0,Q.useState)(`user`),[_,v]=(0,Q.useState)(!1),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(a),[C,w]=(0,Q.useState)(!1);(0,Q.useEffect)(()=>{S(a)},[a]);let T=async e=>{S(e),w(!0);try{await ge({registration_enabled:String(e)}),o?.()}catch(t){console.error(t),S(!e),alert(t.message||s(`common.errorNetwork`,`Network error`))}finally{w(!1)}},D=async()=>{if(!Be.test(u)){alert(s(`account.formatTipUsername`));return}if(!Ue.test(p)){alert(s(`account.formatTipPassword`));return}v(!0);try{await De({username:u,password:await Ne(p,u),role:h}),l(!1),f(``),m(``),b(!1),r()}catch(e){console.error(e),alert(e.message||s(`common.errorNetwork`))}finally{v(!1)}},O=async e=>{if(confirm(s(`account.confirmDeleteUser`)))try{await pe(e),r()}catch(e){console.error(e)}};return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(n,{size:20,className:`text-red-500`}),(0,$.jsx)(G,{style:{margin:0},children:s(`account.userManagement`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,$.jsx)(ae,{label:s(`account.enableRegistration`,`开放新用户注册`),checked:x,disabled:C,onChange:e=>T(e.currentTarget.checked),className:`mb-0`}),(0,$.jsx)(L,{className:`whitespace-nowrap`,icon:(0,$.jsx)(E,{size:16}),intent:H.SUCCESS,text:s(`account.createUser`),onClick:()=>l(!0)})]})]}),(0,$.jsx)(J,{elevation:F.ONE,className:`p-0 overflow-hidden overflow-x-auto`,children:(0,$.jsxs)(se,{interactive:!0,striped:!0,className:`w-full`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{children:s(`account.username`)}),(0,$.jsx)(`th`,{children:s(`account.role`)}),(0,$.jsx)(`th`,{children:`MFA`}),(0,$.jsx)(`th`,{children:`ID`}),(0,$.jsx)(`th`,{children:s(`account.createdAt`)}),(0,$.jsx)(`th`,{children:s(`account.lastActive`)}),(0,$.jsx)(`th`,{children:s(`account.lastResolve`)}),(0,$.jsx)(`th`,{className:`text-right`,children:s(`account.actions`)})]})}),(0,$.jsx)(`tbody`,{children:e.map(e=>(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`td`,{className:`font-bold`,children:e.username}),(0,$.jsx)(`td`,{children:(0,$.jsx)(q,{minimal:!0,intent:e.role===`admin`?H.DANGER:H.NONE,children:e.role===`admin`?s(`account.roleAdmin`):s(`account.roleUser`)})}),(0,$.jsx)(`td`,{children:(0,$.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[!!e.totp_enabled&&(0,$.jsx)(q,{minimal:!0,intent:H.SUCCESS,children:`TOTP`}),!!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(q,{minimal:!0,intent:H.PRIMARY,children:`Passkey`}),!e.totp_enabled&&!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(q,{minimal:!0,intent:H.NONE,style:{color:`#8a9ba8`},children:s(`account.mfaNone`,`无`)})]})}),(0,$.jsx)(`td`,{children:(0,$.jsx)(`code`,{className:`text-xs`,children:e.id})}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.created_at?X(new Date(e.created_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_active_at?X(new Date(e.last_active_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_resolve_at?X(new Date(e.last_resolve_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-right`,children:(0,$.jsx)(`div`,{className:`inline-flex items-center gap-1`,children:(0,$.jsx)(L,{minimal:!0,intent:H.DANGER,icon:(0,$.jsx)(i,{size:14}),disabled:e.id===t,onClick:()=>O(e.id)})})})]},e.id))})]})}),(0,$.jsx)(R,{isOpen:c,onClose:()=>{l(!1),b(!1)},title:s(`account.createNewUser`),icon:`user`,children:(0,$.jsxs)(`div`,{className:`p-6 space-y-4`,children:[(0,$.jsx)(K,{label:s(`account.username`),children:(0,$.jsx)(W,{value:u,onChange:e=>f(e.target.value),placeholder:s(`auth.usernamePlaceholder`)})}),(0,$.jsx)(K,{label:s(`account.initialPassword`),children:(0,$.jsx)(W,{type:y?`text`:`password`,value:p,onChange:e=>m(e.target.value),placeholder:s(`auth.passwordPlaceholder`),rightElement:(0,$.jsx)(L,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:y?s(`auth.hidePassword`,`Hide password`):s(`auth.showPassword`,`Show password`)})})}),(0,$.jsx)(K,{label:s(`account.userRole`),children:(0,$.jsx)(ie,{fill:!0,value:h,onChange:e=>g(e.target.value),options:[{label:s(`account.roleUser`),value:`user`},{label:s(`account.roleAdmin`),value:`admin`}]})}),(0,$.jsxs)(`div`,{className:`flex justify-end gap-2 mt-6`,children:[(0,$.jsx)(L,{text:s(`account.cancel`),onClick:()=>l(!1)}),(0,$.jsx)(L,{intent:H.PRIMARY,text:s(`account.createNow`),loading:_,onClick:D})]})]})})]})},Ot=({initialSettings:e,onRefresh:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)(e),[a,o]=(0,Q.useState)(!1),[s,c]=(0,Q.useState)(!1);return(0,Q.useEffect)(()=>{i(e)},[e]),(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(l,{size:20,className:`text-gray-500`}),(0,$.jsx)(G,{style:{margin:0},children:n(`account.systemSettings`,`System Settings`)})]}),(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(G,{className:`text-sm font-bold opacity-70 text-blue-500`,children:`Cloudflare Turnstile`}),(0,$.jsx)(K,{label:`Site Key`,children:(0,$.jsx)(W,{value:r.turnstile_site_key||``,onChange:e=>i({...r,turnstile_site_key:e.target.value}),placeholder:`0x000...`})}),(0,$.jsx)(K,{label:`Secret Key`,children:(0,$.jsx)(W,{type:s?`text`:`password`,value:r.turnstile_secret_key||``,onChange:e=>i({...r,turnstile_secret_key:e.target.value}),placeholder:`0x000...`,rightElement:(0,$.jsx)(L,{minimal:!0,icon:s?`eye-open`:`eye-off`,onClick:()=>c(!s),title:s?n(`auth.hidePassword`,`Hide password`):n(`auth.showPassword`,`Show password`)})})})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(G,{className:`text-sm font-bold opacity-70 text-green-500`,children:n(`account.featureToggle`,`Feature Toggle`)}),(0,$.jsx)(ae,{label:n(`account.enableTurnstileSignup`,`Enable verification on Signup`),checked:r.turnstile_enabled_signup===`true`,onChange:e=>i({...r,turnstile_enabled_signup:String(e.currentTarget.checked)})}),(0,$.jsx)(ae,{label:n(`account.enableTurnstileLogin`,`Enable verification on Login`),checked:r.turnstile_enabled_login===`true`,onChange:e=>i({...r,turnstile_enabled_login:String(e.currentTarget.checked)})})]})]}),(0,$.jsx)(U,{className:`my-4`}),(0,$.jsx)(`div`,{className:`flex justify-end`,children:(0,$.jsx)(L,{intent:H.PRIMARY,icon:`floppy-disk`,text:n(`common.save`,`Save`),loading:a,onClick:async()=>{o(!0);try{await ge({turnstile_site_key:r.turnstile_site_key||``,turnstile_secret_key:r.turnstile_secret_key||``,turnstile_enabled_signup:r.turnstile_enabled_signup||`false`,turnstile_enabled_login:r.turnstile_enabled_login||`false`}),alert(n(`common.saveSuccess`,`Settings saved`)),t()}catch(e){console.error(e)}finally{o(!1)}}})})]})]})},kt=({isAdmin:e,onLogsCleared:t})=>{let{t:n}=d(),[r,a]=(0,Q.useState)(!1);return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(G,{className:`text-red-500 flex items-center gap-2`,children:[(0,$.jsx)(i,{size:20}),` `,n(`account.dangerZone`)]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,$.jsxs)(J,{elevation:F.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(G,{children:n(`account.clearLogs`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-3`,children:n(`account.clearLogsDesc`)})]}),(0,$.jsx)(L,{fill:!0,intent:H.DANGER,text:n(`account.clearLogsBtn`),icon:`trash`,loading:r,onClick:async()=>{if(confirm(n(`account.confirmClearLogs`))){a(!0);try{await Ge(),alert(n(`account.clearLogsSuccess`)),t?.()}catch(e){console.error(e)}finally{a(!1)}}}})]}),!e&&(0,$.jsxs)(J,{elevation:F.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(G,{children:n(`account.deleteAccount`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-4`,children:n(`account.deleteAccountDesc`)})]}),(0,$.jsx)(L,{fill:!0,intent:H.DANGER,text:n(`account.deleteAccountBtn`),icon:`delete`,onClick:async()=>{if(confirm(n(`account.confirmDeleteAccount`)))try{await Fe(),window.location.href=`/`}catch(e){console.error(e),alert(e.message||n(`common.errorNetwork`))}}})]})]}),(0,$.jsx)(V,{intent:H.WARNING,icon:`info-sign`,title:n(`account.inactivityPolicy`),children:(0,$.jsx)(`p`,{className:`text-sm`,children:n(`account.inactivityDesc`)})})]})},At=[{label:ee(`account.timezoneAuto`,`Auto (Browser Default)`),value:``},{label:`Pacific/Midway (Midway Island) (Standard: UTC-11)`,value:`Pacific/Midway`},{label:`Pacific/Honolulu (Honolulu, Hawaii) (Standard: UTC-10)`,value:`Pacific/Honolulu`},{label:`America/Anchorage (Anchorage, Alaska) (Standard: UTC-9 / DST: UTC-8)`,value:`America/Anchorage`},{label:`America/Los_Angeles (Pacific Time) (Standard: UTC-8 / DST: UTC-7)`,value:`America/Los_Angeles`},{label:`America/Denver (Mountain Time) (Standard: UTC-7 / DST: UTC-6)`,value:`America/Denver`},{label:`America/Chicago (Central Time) (Standard: UTC-6 / DST: UTC-5)`,value:`America/Chicago`},{label:`America/New_York (Eastern Time) (Standard: UTC-5 / DST: UTC-4)`,value:`America/New_York`},{label:`America/Halifax (Atlantic Time) (Standard: UTC-4 / DST: UTC-3)`,value:`America/Halifax`},{label:`America/Argentina/Buenos_Aires (Buenos Aires) (Standard: UTC-3)`,value:`America/Argentina/Buenos_Aires`},{label:`America/Noronha (Fernando de Noronha) (Standard: UTC-2)`,value:`America/Noronha`},{label:`Atlantic/Azores (Azores) (Standard: UTC-1 / DST: UTC+0)`,value:`Atlantic/Azores`},{label:`UTC (Coordinated Universal Time) (Standard: UTC+0)`,value:`UTC`},{label:`Europe/London (London) (Standard: UTC+0 / DST: UTC+1)`,value:`Europe/London`},{label:`Europe/Paris (Paris, Berlin, Rome) (Standard: UTC+1 / DST: UTC+2)`,value:`Europe/Paris`},{label:`Europe/Kyiv (Kyiv, Helsinki, Cairo) (Standard: UTC+2 / DST: UTC+3)`,value:`Europe/Kyiv`},{label:`Europe/Moscow (Moscow) (Standard: UTC+3)`,value:`Europe/Moscow`},{label:`Asia/Dubai (Dubai, Baku) (Standard: UTC+4)`,value:`Asia/Dubai`},{label:`Asia/Karachi (Karachi, Tashkent) (Standard: UTC+5)`,value:`Asia/Karachi`},{label:`Asia/Dhaka (Dhaka, Almaty) (Standard: UTC+6)`,value:`Asia/Dhaka`},{label:`Asia/Bangkok (Bangkok, Jakarta) (Standard: UTC+7)`,value:`Asia/Bangkok`},{label:`Asia/Singapore (Beijing, Shanghai, Singapore, Taipei) (Standard: UTC+8)`,value:`Asia/Singapore`},{label:`Asia/Tokyo (Tokyo, Seoul) (Standard: UTC+9)`,value:`Asia/Tokyo`},{label:`Australia/Sydney (Sydney, Melbourne) (Standard: UTC+10 / DST: UTC+11)`,value:`Australia/Sydney`},{label:`Pacific/Noumea (Nouméa) (Standard: UTC+11)`,value:`Pacific/Noumea`},{label:`Pacific/Auckland (Auckland, Suva) (Standard: UTC+12 / DST: UTC+13)`,value:`Pacific/Auckland`}],jt=({me:e,isEditingUsername:t,setIsEditingUsername:n,editUsername:i,setEditUsername:a,usernameLoading:o,usernameFocused:s,setUsernameFocused:c,onUpdateUsername:l,onUpdateTimezone:u})=>{let{t:f}=d();return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(_,{size:20,className:`text-blue-500`}),(0,$.jsx)(G,{style:{margin:0},children:f(`account.personalInfo`)})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(K,{label:f(`account.username`),children:(0,$.jsx)(`div`,{className:`flex gap-2`,children:t?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(ce,{content:f(`account.formatTipUsername`),isOpen:s,position:M.TOP,intent:H.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(W,{fill:!0,value:i,onChange:e=>a(e.target.value),onFocus:()=>c(!0),onBlur:()=>c(!1),autoFocus:!0})})}),(0,$.jsxs)(N,{children:[(0,$.jsx)(L,{icon:(0,$.jsx)(y,{size:16}),intent:H.SUCCESS,loading:o,onClick:l}),(0,$.jsx)(L,{icon:(0,$.jsx)(D,{size:16}),onClick:()=>{n(!1),a(e?.username||``)}})]})]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(W,{fill:!0,value:e?.username,readOnly:!0}),(0,$.jsx)(L,{icon:(0,$.jsx)(r,{size:16}),onClick:()=>n(!0)})]})})}),(0,$.jsx)(K,{label:f(`account.userId`),children:(0,$.jsx)(W,{leftIcon:`id-number`,value:e?.id,disabled:!0})}),(0,$.jsx)(K,{label:f(`account.timezone`,`Timezone`),children:(0,$.jsx)(ie,{fill:!0,value:e?.timezone||``,onChange:e=>u?.(e.target.value||null),options:At})})]})]})},Mt=({me:e,onRefresh:t})=>{let{t:r}=d(),i=!!(e?.passkeys_count&&e.passkeys_count>0),a=!!e?.totp_enabled,[o,s]=(0,Q.useState)(`password`),[c,l]=(0,Q.useState)(``),[f,p]=(0,Q.useState)(!1),[m,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(!1),[C,w]=(0,Q.useState)(!1),[T,E]=(0,Q.useState)(null);return(0,Q.useEffect)(()=>{o===`passkey`&&!i?s(a?`totp`:`password`):o===`totp`&&!a&&s(i?`passkey`:`password`)},[i,a,o]),(0,$.jsxs)(J,{elevation:F.ONE,className:`isolate`,style:{isolation:`isolate`},children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(u,{size:20,className:`text-orange-500`}),(0,$.jsx)(G,{style:{margin:0},children:r(`account.changePassword`,`Change Password`)})]}),(i||a)&&(0,$.jsx)(`div`,{className:`mb-4 isolate`,style:{isolation:`isolate`},children:(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg`,children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(L,{small:!0,active:o===`password`,intent:o===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:r(`account.mfa.password`,`Password`),onClick:()=>{s(`password`),E(null)}}),i&&(0,$.jsx)(L,{small:!0,active:o===`passkey`,intent:o===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:r(`account.mfa.passkey`,`Passkey`),onClick:()=>{s(`passkey`),E(null)}}),a&&(0,$.jsx)(L,{small:!0,active:o===`totp`,intent:o===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:r(`account.mfa.totp`,`TOTP`),onClick:()=>{s(`totp`),E(null)}})]})})}),T&&(0,$.jsx)(V,{intent:T.intent,className:`mb-4`,children:T.text}),(0,$.jsxs)(`form`,{onSubmit:async n=>{if(n.preventDefault(),!Ue.test(_)){E({text:r(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),intent:H.DANGER});return}if(!e?.username){E({text:r(`auth.sessionExpired`,`Session expired. Please log in again.`),intent:H.DANGER});return}w(!0),E(null);try{let n=await Ne(_,e.username);if(o===`passkey`)await ye({passkeyAssertion:await fe(await Qe()),newPassword:n});else if(o===`totp`){if(m.length!==6){E({text:r(`account.totp.invalidCode`,`Please enter a 6-digit code`),intent:H.DANGER}),w(!1);return}let e=crypto.randomUUID(),t=new TextEncoder().encode(m+e),i=await crypto.subtle.digest(`SHA-256`,t);await ye({totpTokenHash:Array.from(new Uint8Array(i)).map(e=>e.toString(16).padStart(2,`0`)).join(``),totpSalt:e,newPassword:n})}else{if(!c){E({text:r(`auth.passwordRequired`,`Current password is required`),intent:H.DANGER}),w(!1);return}let t=c;(e.password_version??1)===2&&(t=await Ne(c,e.username)),await ye({oldPassword:t,newPassword:n})}E({text:r(`account.passwordSuccess`,`Password updated successfully!`),intent:H.SUCCESS}),l(``),g(``),v(``),t&&t()}catch(e){E({text:Je(e,r),intent:H.DANGER})}finally{w(!1)}},className:`space-y-4`,children:[o===`password`&&(0,$.jsx)(K,{label:r(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(W,{leftIcon:`lock`,type:f?`text`:`password`,value:c,onChange:e=>l(e.target.value),rightElement:(0,$.jsx)(L,{minimal:!0,icon:f?`eye-open`:`eye-off`,onClick:()=>p(!f),title:r(f?`auth.hidePassword`:`auth.showPassword`)}),required:!0})}),o===`totp`&&(0,$.jsx)(K,{label:r(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Le,{length:6,value:m,onChange:g,disabled:C})}),o===`passkey`&&(0,$.jsx)(V,{intent:H.PRIMARY,children:(0,$.jsx)(`span`,{className:`text-xs`,children:r(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`)})}),(0,$.jsx)(K,{label:r(`account.newPassword`,`New Password`),children:(0,$.jsx)(ce,{content:r(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),isOpen:x,position:M.TOP,intent:H.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(W,{leftIcon:`lock`,type:y?`text`:`password`,value:_,onChange:e=>v(e.target.value),onFocus:()=>S(!0),onBlur:()=>S(!1),rightElement:(0,$.jsx)(L,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:r(y?`auth.hidePassword`:`auth.showPassword`)}),required:!0})})})}),(0,$.jsx)(L,{fill:!0,intent:o===`passkey`?H.PRIMARY:H.WARNING,type:`submit`,loading:C,icon:o===`passkey`?(0,$.jsx)(u,{size:16}):void 0,text:o===`passkey`?r(`account.changePasswordWithPasskey`,`Verify with Passkey & Update`):r(`account.updatePassword`,`Update Password`)})]})]})},Nt=({isOpen:e,onClose:t,user:r,onSuccess:i})=>{let{t:a}=d(),o=!!(r?.passkeys_count&&r.passkeys_count>0),s=!!r?.totp_enabled,[c,l]=(0,Q.useState)(`password`),[f,p]=(0,Q.useState)(``),[m,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(``),[C,w]=(0,Q.useState)(!1),[T,E]=(0,Q.useState)(``),D=(0,Q.useRef)(null),O=(0,Q.useRef)(null);(0,Q.useEffect)(()=>{c===`passkey`&&!o?l(s?`totp`:`password`):c===`totp`&&!s&&l(o?`passkey`:`password`)},[o,s,c]);let k=async(e,t)=>{if(e&&e.preventDefault(),f.length!==4||!qe.test(f)){E(a(`auth.pinFormatTip`,`PIN must be exactly 4 digits`));return}if(f!==m){E(a(`auth.pinMatchTip`,`PINs do not match`));return}w(!0),E(``);try{let e=r?.id||sessionStorage.getItem(`dns_worker_user_id`);if(!e){E(a(`auth.sessionExpired`,`Session expired. Logging out...`)),setTimeout(()=>{A()},1500);return}let n=await Pe(f,e),o={};if(c===`passkey`)o.passkeyAssertion=await fe(await Qe());else if(c===`totp`){let e=(t||x).replace(/\s/g,``);if(e.length!==6){E(a(`account.totp.invalidCode`,`Please enter a 6-digit code`)),w(!1);return}let n=crypto.randomUUID();o.totpTokenHash=await We(e,n),o.totpSalt=n}else{if(!_){E(a(`auth.passwordRequired`,`Password is required for verification`)),w(!1);return}let e=_;r?.password_version===2&&r?.username&&(e=await Ne(_,r.username)),o.password=e}await de(n,o),p(``),g(``),v(``),S(``),i()}catch(e){E(Je(e,a))}finally{w(!1)}},A=()=>{E(``),p(``),g(``),v(``),b(!1),S(``),l(`password`),t()};return(0,$.jsx)(R,{isOpen:e,onClose:A,title:r?.pin_enabled?a(`auth.changePin`,`Change PIN`):a(`auth.configurePin`,`Configure PIN`),icon:`key`,className:`pb-0`,style:{width:`420px`},children:(0,$.jsxs)(`form`,{onSubmit:k,children:[(0,$.jsxs)(`div`,{className:I,children:[T&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:T}),(0,$.jsx)(K,{label:a(`auth.newPin`,`New 4-Digit PIN`),labelFor:`new-pin-input`,helperText:a(`auth.pinHelper`,`Digits only, e.g., 1234`),children:(0,$.jsx)(Le,{length:4,value:f,onChange:p,type:`password`,disabled:C,autoFocus:!0,onComplete:()=>D.current?.focus()})}),(0,$.jsx)(K,{label:a(`auth.confirmPin`,`Confirm New PIN`),labelFor:`confirm-pin-input`,children:(0,$.jsx)(Le,{ref:D,length:4,value:m,onChange:g,type:`password`,disabled:C,onComplete:()=>{c===`totp`?O.current?.focus():c===`password`&&document.getElementById(`verify-pw-input`)?.focus()}})}),(0,$.jsx)(U,{className:`my-4`}),(0,$.jsxs)(`div`,{className:`mb-3 space-y-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm block`,children:a(`auth.verifyIdentity`,`Verify Identity`)}),(o||s)&&(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(L,{small:!0,active:c===`password`,intent:c===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),E(``)}}),o&&(0,$.jsx)(L,{small:!0,active:c===`passkey`,intent:c===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),E(``)}}),s&&(0,$.jsx)(L,{small:!0,active:c===`totp`,intent:c===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),E(``)}})]})})]}),c===`password`&&(0,$.jsx)(K,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`verify-pw-input`,children:(0,$.jsx)(W,{id:`verify-pw-input`,type:y?`text`:`password`,placeholder:a(`auth.passwordPlaceholder`,`Enter current password`),value:_,onChange:e=>v(e.target.value),leftIcon:`lock`,rightElement:(0,$.jsx)(L,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:y?a(`auth.hidePassword`,`Hide password`):a(`auth.showPassword`,`Show password`)}),required:!0})}),c===`totp`&&(0,$.jsx)(K,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`verify-totp-input`,children:(0,$.jsx)(Le,{ref:O,length:6,value:x,onChange:S,disabled:C,onComplete:e=>k(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(V,{intent:H.PRIMARY,icon:(0,$.jsx)(u,{size:16}),children:(0,$.jsx)(`span`,{className:`text-xs`,children:a(`account.passkey.submitNotice`,a(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`))})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:A,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.PRIMARY,loading:C,children:a(`common.save`,`Save`)})]})})]})})},Pt=({isOpen:e,onClose:t,user:r,onSuccess:i})=>{let{t:a}=d(),o=!!(r?.passkeys_count&&r.passkeys_count>0),s=!!r?.totp_enabled,[c,l]=(0,Q.useState)(`password`),[f,p]=(0,Q.useState)(``),[m,g]=(0,Q.useState)(!1),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(!1),[x,C]=(0,Q.useState)(``);(0,Q.useEffect)(()=>{c===`passkey`&&!o?l(s?`totp`:`password`):c===`totp`&&!s&&l(o?`passkey`:`password`)},[o,s,c]);let w=async(e,t)=>{e&&e.preventDefault(),b(!0),C(``);try{let e={};if(c===`passkey`)e.passkeyAssertion=await fe(await Qe());else if(c===`totp`){let n=(t||_).replace(/\s/g,``);if(n.length!==6){C(a(`account.totp.invalidCode`,`Please enter a 6-digit code`)),b(!1);return}let r=crypto.randomUUID();e.totpTokenHash=await We(n,r),e.totpSalt=r}else{if(!f){C(a(`auth.passwordRequired`,`Password is required for verification`)),b(!1);return}let t=f;r?.password_version===2&&r?.username&&(t=await Ne(f,r.username)),e.password=t}await He(e),p(``),v(``),i()}catch(e){C(Je(e,a))}finally{b(!1)}},T=()=>{C(``),p(``),g(!1),v(``),l(`password`),t()};return(0,$.jsx)(R,{isOpen:e,onClose:T,title:a(`auth.disablePin`,`Disable Session Lock`),icon:`trash`,className:`pb-0`,style:{width:`420px`},children:(0,$.jsxs)(`form`,{onSubmit:w,children:[(0,$.jsxs)(`div`,{className:I,children:[x&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:x}),(0,$.jsx)(V,{intent:H.WARNING,className:`mb-4`,icon:(0,$.jsx)(S,{size:20}),children:a(`auth.disablePinWarning`,`Disabling the PIN will disable the inactivity session locking feature completely.`)}),(0,$.jsxs)(`div`,{className:`mb-3 space-y-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm block`,children:a(`auth.verifyIdentity`,`Verify Identity`)}),(o||s)&&(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(L,{small:!0,active:c===`password`,intent:c===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),C(``)}}),o&&(0,$.jsx)(L,{small:!0,active:c===`passkey`,intent:c===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),C(``)}}),s&&(0,$.jsx)(L,{small:!0,active:c===`totp`,intent:c===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),C(``)}})]})})]}),c===`password`&&(0,$.jsx)(K,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`disable-pw-input`,children:(0,$.jsx)(W,{id:`disable-pw-input`,type:m?`text`:`password`,placeholder:a(`auth.passwordPlaceholder`,`Enter current password`),value:f,onChange:e=>p(e.target.value),leftIcon:`lock`,rightElement:(0,$.jsx)(L,{minimal:!0,icon:m?`eye-open`:`eye-off`,onClick:()=>g(!m),title:m?a(`auth.hidePassword`,`Hide password`):a(`auth.showPassword`,`Show password`)}),required:!0})}),c===`totp`&&(0,$.jsx)(K,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`disable-totp-input`,children:(0,$.jsx)(Le,{length:6,value:_,onChange:v,disabled:y,onComplete:e=>w(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(V,{intent:H.PRIMARY,icon:(0,$.jsx)(u,{size:16}),children:(0,$.jsx)(`span`,{className:`text-xs`,children:a(`account.passkey.submitNotice`,a(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`))})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:T,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.DANGER,loading:y,children:a(`common.disable`,`Disable`)})]})})]})})},Ft=({user:e,onRefresh:t})=>{let{t:r}=d(),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(!1),u=!!e?.pin_enabled,f=e?.session_lock_timeout||15,p=async e=>{let n=Number(e.currentTarget.value);a(!0);try{await Te({session_lock_timeout:n}),t()}catch(e){console.error(`Failed to change session lock timeout`,e)}finally{a(!1)}},m=()=>{s(!0)};return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(n,{size:20,className:`text-indigo-600`}),(0,$.jsx)(G,{className:`m-0!`,children:r(`auth.sessionLockTitle`,`Idle Session Lock`)})]}),!u&&(0,$.jsx)(L,{icon:`key`,intent:H.PRIMARY,onClick:m,disabled:i,children:r(`auth.configurePin`,`Configure 4-Digit PIN`)})]}),(0,$.jsx)(`p`,{className:`text-gray-500 text-sm mb-4`,children:r(`auth.sessionLockDesc`,`Lock the interface with a 4-digit PIN when the application is idle to protect active sessions from unauthorized physical access.`)}),(0,$.jsx)(`div`,{className:`flex flex-col gap-4 mb-4`,children:(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsx)(`span`,{children:r(`auth.inactivityTimeout`,`Inactivity Timeout`)}),(0,$.jsx)(ie,{value:f,onChange:p,disabled:!u||i,options:[{label:r(`auth.timeout1m`,`1 Minute`),value:1},{label:r(`auth.timeout2m`,`2 Minutes`),value:2},{label:r(`auth.timeout5m`,`5 Minutes`),value:5},{label:r(`auth.timeout15m`,`15 Minutes`),value:15},{label:r(`auth.timeout30m`,`30 Minutes`),value:30},{label:r(`auth.timeout60m`,`60 Minutes`),value:60}]})]})}),u&&(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,$.jsx)(L,{icon:`edit`,onClick:m,disabled:i,children:r(`auth.changePin`,`Change PIN`)}),(0,$.jsx)(L,{icon:`trash`,intent:H.DANGER,onClick:()=>{l(!0)},disabled:i,children:r(`auth.disablePin`,`Disable PIN & Lock`)}),(0,$.jsx)(L,{icon:`lock`,intent:H.WARNING,onClick:async()=>{a(!0);try{await be(),window.dispatchEvent(new Event(`session_paused`))}catch(e){console.error(`Failed to lock session immediately`,e)}finally{a(!1)}},disabled:i,children:r(`auth.lockNow`,`Lock Now`)})]}),(0,$.jsx)(Nt,{isOpen:o,onClose:()=>s(!1),user:e,onSuccess:()=>{s(!1),t()}}),(0,$.jsx)(Pt,{isOpen:c,onClose:()=>l(!1),user:e,onSuccess:()=>{l(!1),t()}})]})};function It({user:e,onRefresh:t,toasterRef:n,setProcessing:r}){let{t:i}=d(),[a,o]=(0,Q.useState)(null),[s,c]=(0,Q.useState)(!0),[l,u]=(0,Q.useState)(!1),[f,p]=(0,Q.useState)(!1),m=(0,Q.useCallback)(async()=>{c(!0);try{o(await Z.getUserStatus()),u(Z.isUnlocked())}catch(e){console.error(`[useE2eeStatus] Failed to fetch E2EE status:`,e)}finally{c(!1)}},[]);(0,Q.useEffect)(()=>{m()},[m]);let h=e.passkeys_count&&e.passkeys_count>0||(a?.userPasskeyCount||0)>0,g=!!a?.enabled;return{status:a,loading:s,isUnlocked:l,setIsUnlocked:u,isPqc:(0,Q.useMemo)(()=>{if(!a?.publicKey)return!1;try{let e=JSON.parse(a.publicKey);return e.alg===`P256-MLKEM768`||!!e.pqc_pk}catch{return!1}},[a?.publicKey]),isLogsE2eeEnabled:g,hasPasskey:h,loadStatus:m,isDisableAlertOpen:f,setIsDisableAlertOpen:p,handleToggleLogs:async e=>{if(e){r(!0);try{await Z.enableUserE2ee(),n.current?.show({message:i(`account.e2ee.enableSuccess`),intent:H.SUCCESS,icon:`lock`}),await m(),t?.()}catch(e){console.error(`[useE2eeStatus] Failed to enable E2EE:`,e),n.current?.show({message:e.message||i(`account.e2ee.enableError`),intent:H.DANGER,icon:`error`})}finally{r(!1)}}else p(!0)},handleConfirmDisable:async()=>{r(!0);try{await Z.disableUserE2ee(),n.current?.show({message:i(`account.e2ee.disableSuccess`),intent:H.WARNING,icon:`unlock`}),await m(),t?.()}catch(e){console.error(`[useE2eeStatus] Failed to disable E2EE:`,e),n.current?.show({message:e.message||i(`account.e2ee.disableError`),intent:H.DANGER,icon:`error`})}finally{r(!1),p(!1)}},handleLockDevice:()=>{Z.clearStorage(),u(!1),n.current?.show({message:i(`account.e2ee.lockSuccess`,`已锁定,私钥已从本地清除`),intent:H.NONE})}}}function Lt({onRefresh:e,loadStatus:t,setIsUnlocked:n,toasterRef:r,setProcessing:i}){let{t:a}=d(),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(``),[u,f]=(0,Q.useState)(``),[p,m]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(null),[x,S]=(0,Q.useState)(!1);return{isRecoveryDialogOpen:o,setIsRecoveryDialogOpen:s,recoveryKeyInput:c,setRecoveryKeyInput:l,recoveryUnlockError:u,setRecoveryUnlockError:f,initRecoveryDialogOpen:p,setInitRecoveryDialogOpen:m,initRecoveryKeyInput:h,setInitRecoveryKeyInput:g,initRecoveryError:_,setInitRecoveryError:v,rotatedKey:y,setRotatedKey:b,copiedKey:x,handleUnlockWithRecoveryKey:async o=>{o.preventDefault();let u=c.trim();if(u){i(!0),f(``);try{await Z.unlockWithRecoveryKey(u);try{let e=await ze({recoveryKey:u});await Z.wrapCurrentKeyForRecovery(e.recovery_key),b(e.recovery_key)}catch(e){console.warn(`[useE2eeRecoveryDialogs] Recovery key auto-rotation failed:`,e)}n(!0),s(!1),l(``),r.current?.show({message:a(`account.e2ee.unlockSuccess`),intent:H.SUCCESS,icon:`tick`}),await t(),e?.()}catch(e){console.error(`[useE2eeRecoveryDialogs] Recovery unlock failed:`,e),f(e.message||a(`account.e2ee.recoveryUnlockFailed`))}finally{i(!1)}}},handleInitWithRecoveryKey:async o=>{o.preventDefault();let s=h.trim();if(s){i(!0),v(``);try{await Z.initUserE2eeWithRecoveryKey(s);try{let e=await ze({recoveryKey:s});await Z.wrapCurrentKeyForRecovery(e.recovery_key),b(e.recovery_key)}catch(e){console.warn(`[useE2eeRecoveryDialogs] Recovery key auto-rotation failed:`,e)}m(!1),g(``),n(!0),r.current?.show({message:a(`account.e2ee.keypairGenSuccess`),intent:H.SUCCESS,icon:`tick`}),await t(),e?.()}catch(e){console.error(`[useE2eeRecoveryDialogs] Init keypair with recovery key failed:`,e),v(e.message||a(`account.e2ee.initFailed`))}finally{i(!1)}}},handleCopyRotatedKey:e=>{navigator.clipboard.writeText(e),S(!0),setTimeout(()=>S(!1),2e3)}}}function Rt({hasPasskey:e,onRefresh:t,loadStatus:n,setIsUnlocked:r,setInitRecoveryDialogOpen:i,toasterRef:a,setProcessing:o}){let{t:s}=d(),[c,l]=(0,Q.useState)(!1);return{handleUnlock:async()=>{o(!0);try{await Z.unlockUser()&&(r(!0),a.current?.show({message:s(`account.e2ee.unlockSuccess`),intent:H.SUCCESS,icon:`tick`}))}catch(e){console.error(`[useE2eeActions] Failed to unlock private key:`,e),a.current?.show({message:e.message||s(`account.e2ee.unlockError`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},handleGenerateKeyWithPasskey:async()=>{o(!0);try{await Z.enableUserE2ee(),a.current?.show({message:s(`account.e2ee.keypairGenSuccess`),intent:H.SUCCESS,icon:`tick`}),await n(),t?.()}catch(e){console.error(`[useE2eeActions] Generate key with Passkey failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.keypairGenError`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},handleUpgradeToPqc:async()=>{o(!0);try{await Z.rotateUserE2eeKey(),a.current?.show({message:s(`account.e2ee.upgradePqcSuccess`,`已成功升级到后量子混合加密 (P256-MLKEM768)`),intent:H.SUCCESS,icon:`tick`}),await n(),t?.()}catch(e){console.error(`[useE2eeActions] Upgrade to PQC failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.upgradePqcError`,`升级到后量子加密失败`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},handleEnrollPasskey:async()=>{o(!0);try{let e=await me(),r=e.length>0?e[0].id:`primary`;if(await Z.wrapCurrentKeyForPasskey(r))a.current?.show({message:s(`account.e2ee.enrollPasskeySuccess`,`已成功将通行密钥关联至端到端加密!`),intent:H.SUCCESS,icon:`tick`}),await n(),t?.();else throw Error(s(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`))}catch(e){console.error(`[useE2eeActions] Enroll passkey failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},isResetAlertOpen:c,setIsResetAlertOpen:l,handleResetAndReinit:async()=>{o(!0);try{await fetch(`/api/account/e2ee?purge=true`,{method:`DELETE`}),Z.clearStorage(),e?(await Z.enableUserE2ee(),a.current?.show({message:s(`account.e2ee.resetAndInitPasskeySuccess`,`密钥对已成功重置并使用通行密钥重新加密!`),intent:H.SUCCESS,icon:`tick`})):(a.current?.show({message:s(`account.e2ee.resetSuccessEnterRecovery`,`旧密钥已清除,请使用恢复密钥初始化新密钥对。`),intent:H.WARNING,icon:`refresh`}),i(!0)),await n(),t?.()}catch(e){console.error(`[useE2eeActions] Reset keypair failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.resetFailed`,`重置密钥对失败`),intent:H.DANGER,icon:`error`})}finally{o(!1),l(!1)}}}}function zt({user:e,onRefresh:t,toasterRef:n}){let[r,i]=(0,Q.useState)(!1),a=It({user:e,onRefresh:t,toasterRef:n,setProcessing:i}),o=Lt({onRefresh:t,loadStatus:a.loadStatus,setIsUnlocked:a.setIsUnlocked,toasterRef:n,setProcessing:i}),s=Rt({hasPasskey:a.hasPasskey,onRefresh:t,loadStatus:a.loadStatus,setIsUnlocked:a.setIsUnlocked,setInitRecoveryDialogOpen:o.setInitRecoveryDialogOpen,toasterRef:n,setProcessing:i});return{status:a.status,loading:a.loading,processing:r,isUnlocked:a.isUnlocked,isPqc:a.isPqc,isLogsE2eeEnabled:a.isLogsE2eeEnabled,hasPasskey:a.hasPasskey,isDisableAlertOpen:a.isDisableAlertOpen,setIsDisableAlertOpen:a.setIsDisableAlertOpen,isRecoveryDialogOpen:o.isRecoveryDialogOpen,setIsRecoveryDialogOpen:o.setIsRecoveryDialogOpen,recoveryKeyInput:o.recoveryKeyInput,setRecoveryKeyInput:o.setRecoveryKeyInput,recoveryUnlockError:o.recoveryUnlockError,setRecoveryUnlockError:o.setRecoveryUnlockError,initRecoveryDialogOpen:o.initRecoveryDialogOpen,setInitRecoveryDialogOpen:o.setInitRecoveryDialogOpen,initRecoveryKeyInput:o.initRecoveryKeyInput,setInitRecoveryKeyInput:o.setInitRecoveryKeyInput,initRecoveryError:o.initRecoveryError,setInitRecoveryError:o.setInitRecoveryError,rotatedKey:o.rotatedKey,setRotatedKey:o.setRotatedKey,copiedKey:o.copiedKey,handleToggleLogs:a.handleToggleLogs,handleConfirmDisable:a.handleConfirmDisable,handleUnlock:s.handleUnlock,handleUnlockWithRecoveryKey:o.handleUnlockWithRecoveryKey,handleGenerateKeyWithPasskey:s.handleGenerateKeyWithPasskey,handleUpgradeToPqc:s.handleUpgradeToPqc,handleInitWithRecoveryKey:o.handleInitWithRecoveryKey,handleLockDevice:a.handleLockDevice,handleCopyRotatedKey:o.handleCopyRotatedKey,isResetAlertOpen:s.isResetAlertOpen,setIsResetAlertOpen:s.setIsResetAlertOpen,handleResetAndReinit:s.handleResetAndReinit,handleEnrollPasskey:s.handleEnrollPasskey}}const Bt=({isLogsE2eeEnabled:e})=>{let{t}=d();return(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(h,{size:20,className:e?`text-emerald-500`:`text-gray-400`}),(0,$.jsx)(G,{style:{margin:0},children:t(`account.e2ee.title`,`E2EE`)}),(0,$.jsx)(q,{intent:e?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:t(e?`account.e2ee.enabled`:`account.e2ee.disabled`)})]}),(0,$.jsx)(re,{placement:`bottom-end`,usePortal:!0,content:(0,$.jsxs)(`div`,{className:`p-4 max-w-sm`,children:[(0,$.jsx)(ne,{children:t(`account.e2ee.trustBoundaryTitle`)}),(0,$.jsx)(`p`,{className:`text-sm text-gray-700 dark:text-gray-300 m-0`,children:t(`account.e2ee.trustBoundaryDesc`,`All DNS query traffic inevitably passes through the hosting server (Cloudflare Workers edge nodes or self-hosted server runtime) during resolution, where queries are processed in memory before being encrypted and saved. This feature strictly protects data at rest in the cloud database (D1 / persistent storage) from data leaks or offline analysis; it does not conceal active network traffic from the hosting server processing the request.`)})]}),children:(0,$.jsx)(L,{icon:`help`,variant:`minimal`,intent:H.NONE})})]})},Vt=({hasPasskey:e,processing:n,onGenerateKeyWithPasskey:r,onOpenInitRecoveryDialog:i})=>{let{t:a}=d();return(0,$.jsx)(V,{intent:H.PRIMARY,icon:`shield`,className:`my-3 text-xs`,children:(0,$.jsxs)(`div`,{className:`space-y-3`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h5`,{className:`font-semibold text-sm mb-1 text-blue-900 dark:text-blue-100`,children:a(`account.e2ee.noKeypairTitle`)}),(0,$.jsx)(`p`,{className:`text-xs text-blue-800 dark:text-blue-200 m-0`,children:a(`account.e2ee.noKeypairDesc`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap pt-1`,children:[e?(0,$.jsx)(L,{intent:H.PRIMARY,small:!0,icon:(0,$.jsx)(t,{size:14}),text:a(`account.e2ee.initPasskeyBtn`),loading:n,onClick:r}):(0,$.jsx)(L,{intent:H.PRIMARY,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.addPasskeyBtn`),onClick:()=>{document.getElementById(`passkeys-section`)?.scrollIntoView({behavior:`smooth`})}}),(0,$.jsx)(L,{intent:H.NONE,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.initRecoveryBtn`),onClick:i})]})]})})},Ht=({status:e,isLogsE2eeEnabled:r,isUnlocked:i,isPqc:a,hasPasskey:o,processing:s,loading:c,onToggleLogs:l,onUpgradeToPqc:u,onLockDevice:p,onUnlockPasskey:m,onOpenRecoveryUnlockDialog:h,onEnrollPasskey:g,onOpenResetAlert:_})=>{let{t:v}=d();return(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(U,{className:`my-2`}),(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-4 p-4 rounded-lg border border-gray-200 dark:border-gray-800 bg-gray-50/70 dark:bg-gray-900/50`,children:[(0,$.jsxs)(`div`,{className:`space-y-1`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm text-gray-900 dark:text-gray-100`,children:v(`account.e2ee.enableSwitch`)}),(0,$.jsx)(q,{intent:r?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:v(r?`account.e2ee.enabled`:`account.e2ee.disabled`)})]}),(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 m-0`,children:v(`account.e2ee.enableSwitchDesc`)})]}),(0,$.jsx)(`div`,{className:`shrink-0 flex items-center`,children:(0,$.jsx)(ae,{checked:r,disabled:s||c,onChange:e=>l(e.currentTarget.checked),large:!0,className:`mb-0`})})]}),(0,$.jsxs)(`div`,{className:`pt-2 border-t border-gray-100 dark:border-gray-800/80 space-y-2 text-xs`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsxs)(`span`,{className:`opacity-70 flex items-center gap-1.5`,children:[(0,$.jsx)(t,{size:13}),v(`account.e2ee.keyType`),`:`]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,$.jsx)(`span`,{className:`font-mono`,children:a?`P256-MLKEM768 + AES-256-GCM`:`ECDH P-256 + AES-256-GCM`}),a?(0,$.jsx)(q,{minimal:!0,intent:H.PRIMARY,className:`text-[10px]`,children:v(`account.e2ee.pqcTag`,`PQC / NIST FIPS 203`)}):(0,$.jsx)(L,{small:!0,intent:H.PRIMARY,minimal:!0,icon:(0,$.jsx)(f,{size:12}),text:v(`account.e2ee.upgradePqcBtn`,`升级到后量子 (PQC)`),loading:s,onClick:u})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsxs)(`span`,{className:`opacity-70 flex items-center gap-1.5`,children:[(0,$.jsx)(n,{size:13}),v(`account.e2ee.deviceState`),`:`]}),i?(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap justify-end`,children:[(0,$.jsx)(q,{minimal:!0,intent:H.SUCCESS,className:`text-[10px]`,children:v(`account.e2ee.unlocked`)}),o&&(e?.wrappedPasskeys?.length||0)===0&&g&&(0,$.jsx)(L,{small:!0,intent:H.PRIMARY,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.enrollPasskeyBtn`,`关联当前通行密钥`),loading:s,onClick:g}),(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.NONE,icon:`lock`,text:v(`account.e2ee.lockDevice`,`锁定此设备`),onClick:p})]}):(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap justify-end`,children:[o&&(e?.wrappedPasskeys?.length||0)>0&&(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.PRIMARY,icon:(0,$.jsx)(f,{size:12}),text:v(`account.e2ee.unlockButton`),loading:s,onClick:m}),(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.NONE,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.unlockRecoveryButton`),onClick:h}),_&&(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.DANGER,icon:`reset`,text:v(`account.e2ee.resetKeypairBtn`,`重置密钥对`),onClick:_})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsxs)(`span`,{className:`opacity-70`,children:[v(`account.e2ee.protectedPasskeys`),`:`]}),(0,$.jsxs)(`span`,{className:`font-mono`,children:[e?.wrappedPasskeys?.length||0,` `,v(`account.e2ee.devicesUnit`)]})]})]})]})},Ut=({isOpen:e,processing:t,onConfirm:n,onCancel:r})=>{let{t:i}=d();return(0,$.jsx)(P,{isOpen:e,confirmButtonText:i(`common.confirmDisable`),cancelButtonText:i(`common.cancel`),intent:H.DANGER,icon:`unlock`,onConfirm:n,onCancel:r,loading:t,children:(0,$.jsx)(`p`,{children:i(`account.e2ee.disableConfirm`)})})},Wt=({isOpen:e,onClose:t,recoveryKeyInput:n,setRecoveryKeyInput:r,recoveryUnlockError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(R,{isOpen:e,onClose:t,title:s(`account.e2ee.unlockWithRecoveryTitle`),icon:`key`,className:`dark:bg-gray-900`,children:(0,$.jsxs)(`form`,{onSubmit:o,autoComplete:`off`,children:[(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.unlockWithRecoveryDesc`)}),i&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(K,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`recovery-key-input`,children:(0,$.jsx)(W,{id:`recovery-key-input`,name:`recovery_key_input`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:n,onChange:e=>r(e.target.value),leftIcon:`key`,className:`font-mono text-xs`,autoFocus:!0})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.unlockConfirm`)})]})})]})})},Gt=({isOpen:e,onClose:t,initRecoveryKeyInput:n,setInitRecoveryKeyInput:r,initRecoveryError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(R,{isOpen:e,onClose:t,title:s(`account.e2ee.initWithRecoveryTitle`),icon:`key`,className:`dark:bg-gray-900`,children:(0,$.jsxs)(`form`,{onSubmit:o,autoComplete:`off`,children:[(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.initWithRecoveryDesc`)}),i&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(K,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`init-recovery-key-input`,children:(0,$.jsx)(W,{id:`init-recovery-key-input`,name:`init_recovery_key_input`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:n,onChange:e=>r(e.target.value),leftIcon:`key`,className:`font-mono text-xs`,autoFocus:!0})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.generateKeypairBtn`)})]})})]})})},Kt=({rotatedKey:e,onClose:t,copiedKey:n,onCopyKey:r})=>{let{t:i}=d();return(0,$.jsxs)(R,{isOpen:!!e,onClose:t,title:i(`account.recoveryKey.autoRotatedTitle`),icon:`warning-sign`,isCloseButtonShown:!1,canOutsideClickClose:!1,className:`dark:bg-gray-900`,children:[(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(V,{intent:H.WARNING,icon:(0,$.jsx)(S,{size:16}),className:`mb-4 text-xs`,children:i(`account.recoveryKey.autoRotatedNotice`)}),e&&(0,$.jsxs)(`div`,{className:`space-y-3`,children:[(0,$.jsx)(`div`,{className:`p-3 bg-gray-100 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 font-mono text-center text-lg font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:e}),(0,$.jsx)(`div`,{className:`flex justify-center`,children:(0,$.jsx)(L,{intent:H.PRIMARY,icon:n?(0,$.jsx)(y,{size:14,className:`text-green-400`}):(0,$.jsx)(w,{size:14}),text:i(n?`common.copied`:`common.copyKey`),onClick:()=>r(e)})})]})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsx)(`div`,{className:Y,children:(0,$.jsx)(L,{intent:H.SUCCESS,onClick:t,text:i(`account.recoveryKey.savedAndClose`)})})})]})},qt=({isOpen:e,processing:t,hasPasskey:n,onConfirm:r,onCancel:i})=>{let{t:a}=d();return(0,$.jsx)(P,{isOpen:e,confirmButtonText:a(`account.e2ee.confirmResetBtn`,`确认重置并重新生成`),cancelButtonText:a(`common.cancel`,`取消`),intent:H.DANGER,icon:`reset`,onConfirm:r,onCancel:i,loading:t,children:(0,$.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,$.jsx)(`p`,{className:`font-semibold text-gray-900 dark:text-gray-100`,children:a(`account.e2ee.resetKeypairTitle`,`重置端到端加密密钥对`)}),(0,$.jsx)(`p`,{children:a(`account.e2ee.resetKeypairDesc`,`如果您的恢复密钥不匹配或无法解密,且未关联通行密钥,重置密钥对将从服务端清除旧密钥,并为您重新生成全新的后量子 (P256-MLKEM768) 密钥对。`)}),(0,$.jsx)(`p`,{className:`text-gray-500 dark:text-gray-400`,children:n?a(`account.e2ee.resetKeypairPasskeyNotice`,`确认后将立即调用您当前已配置的通行密钥 (Passkey) 完成新密钥对的加密与授权。`):a(`account.e2ee.resetKeypairRecoveryNotice`,`确认后将引导您输入当前恢复密钥以完成新密钥对的生成与加密。`)})]})})},Jt=({user:e,onRefresh:t})=>{let{t:n}=d(),r=(0,Q.useRef)(null),{status:i,loading:a,processing:o,isUnlocked:s,isPqc:c,isLogsE2eeEnabled:l,hasPasskey:u,isDisableAlertOpen:f,setIsDisableAlertOpen:p,isRecoveryDialogOpen:m,setIsRecoveryDialogOpen:h,recoveryKeyInput:g,setRecoveryKeyInput:_,recoveryUnlockError:v,initRecoveryDialogOpen:y,setInitRecoveryDialogOpen:b,initRecoveryKeyInput:x,setInitRecoveryKeyInput:S,initRecoveryError:C,setInitRecoveryError:w,rotatedKey:T,setRotatedKey:E,copiedKey:D,handleToggleLogs:O,handleConfirmDisable:k,handleUnlock:A,handleUnlockWithRecoveryKey:j,handleGenerateKeyWithPasskey:ee,handleUpgradeToPqc:M,handleInitWithRecoveryKey:N,handleLockDevice:P,handleCopyRotatedKey:te,isResetAlertOpen:I,setIsResetAlertOpen:ne,handleResetAndReinit:L,handleEnrollPasskey:R}=zt({user:e,onRefresh:t,toasterRef:r});return(0,$.jsxs)(J,{elevation:F.ONE,className:`space-y-6`,children:[(0,$.jsx)(oe,{ref:r}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(Bt,{isLogsE2eeEnabled:l}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-3`,children:n(`account.e2ee.desc`)}),a?(0,$.jsx)(`div`,{className:`flex items-center justify-center p-6`,children:(0,$.jsx)(z,{size:20})}):i?.hasKeys?(0,$.jsx)(Ht,{status:i,isLogsE2eeEnabled:l,isUnlocked:s,isPqc:c,hasPasskey:u,processing:o,loading:a,onToggleLogs:O,onUpgradeToPqc:M,onLockDevice:P,onUnlockPasskey:A,onOpenRecoveryUnlockDialog:()=>{_(``),h(!0)},onEnrollPasskey:R,onOpenResetAlert:()=>ne(!0)}):(0,$.jsx)(Vt,{hasPasskey:u,processing:o,onGenerateKeyWithPasskey:ee,onOpenInitRecoveryDialog:()=>{w(``),S(``),b(!0)}})]}),(0,$.jsx)(Ut,{isOpen:f,processing:o,onConfirm:k,onCancel:()=>p(!1)}),(0,$.jsx)(qt,{isOpen:I,processing:o,hasPasskey:u,onConfirm:L,onCancel:()=>ne(!1)}),(0,$.jsx)(Wt,{isOpen:m,onClose:()=>h(!1),recoveryKeyInput:g,setRecoveryKeyInput:_,recoveryUnlockError:v,processing:o,onSubmit:j}),(0,$.jsx)(Gt,{isOpen:y,onClose:()=>b(!1),initRecoveryKeyInput:x,setInitRecoveryKeyInput:S,initRecoveryError:C,processing:o,onSubmit:N}),(0,$.jsx)(Kt,{rotatedKey:T,onClose:()=>E(null),copiedKey:D,onCopyKey:te})]})},Yt=()=>{let[e,t]=(0,Q.useState)(null),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(null),{t:l,i18n:u}=d(),f=ue(),[m,h]=(0,Q.useState)(!1),[g,_]=(0,Q.useState)(``),[v,y]=(0,Q.useState)(!1),[b,x]=(0,Q.useState)(!1),[S,C]=(0,Q.useState)({}),w=async()=>{try{i(await ke())}catch(e){console.error(e)}},T=async()=>{try{C(await Xe())}catch(e){console.error(e)}},E=(0,Q.useCallback)(async()=>{try{let e=await Me();if(t(e),_(e.username),window.dispatchEvent(new Event(`user_updated`)),e.timezone){let{setSystemTimeZone:t}=await j(async()=>{let{setSystemTimeZone:e}=await import(`./date-GC_sRpuZ.js`);return{setSystemTimeZone:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));t(e.timezone)}if(e.locale){let{setSystemLocale:t}=await j(async()=>{let{setSystemLocale:e}=await import(`./date-GC_sRpuZ.js`);return{setSystemLocale:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));t(e.locale),u.changeLanguage(e.locale)}e.role===`admin`&&(w(),T())}catch(e){console.error(e)}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{E()},[E]),a?(0,$.jsx)(`div`,{className:`p-8 text-center`,children:l(`common.loading`)}):(0,$.jsxs)(`div`,{className:le(`max-w-5xl mx-auto space-y-8`,f?`p-0`:`px-8`),children:[(0,$.jsxs)(`div`,{className:`flex justify-between items-end`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h2`,{className:`bp6-heading`,children:l(`account.title`)}),(0,$.jsx)(`p`,{className:`bp6-text-muted`,children:l(`account.subtitle`)})]}),e&&(0,$.jsx)(q,{large:!0,round:!0,intent:e.role===`admin`?H.DANGER:H.PRIMARY,icon:(0,$.jsx)(n,{size:16}),children:e.role===`admin`?l(`account.roleAdmin`):l(`account.roleUser`)})]}),e?.role===`admin`&&e?.jwt_secret_warning&&(0,$.jsx)(V,{intent:H.WARNING,icon:(0,$.jsx)(p,{size:18}),title:l(`account.jwtSecretWarningTitle`),children:(0,$.jsx)(`div`,{className:`text-sm leading-relaxed mt-1`,children:l(`account.jwtSecretWarningDesc`)})}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,$.jsx)(jt,{me:e,isEditingUsername:m,setIsEditingUsername:h,editUsername:g,setEditUsername:_,usernameLoading:v,usernameFocused:b,setUsernameFocused:x,onUpdateUsername:async()=>{if(g===e?.username){h(!1);return}if(!Be.test(g)){alert(l(`account.formatTipUsername`));return}y(!0);try{await Te({username:g}),t(e=>e?{...e,username:g}:null),h(!1)}catch(e){console.error(e),alert(e.message||l(`common.errorNetwork`))}finally{y(!1)}},onUpdateTimezone:async e=>{try{await Te({timezone:e||``}),t(t=>t?{...t,timezone:e}:null);let{setSystemTimeZone:n}=await j(async()=>{let{setSystemTimeZone:e}=await import(`./date-GC_sRpuZ.js`);return{setSystemTimeZone:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));n(e||``)}catch(e){console.error(e),alert(e.message||l(`common.errorNetwork`))}}}),(0,$.jsx)(Mt,{me:e,onRefresh:E})]}),e&&(0,$.jsx)(bt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Jt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Ft,{user:e,onRefresh:E}),e&&(0,$.jsx)(Et,{hoveredSessionId:s,setHoveredSessionId:c}),e&&(0,$.jsx)(Tt,{hoveredSessionId:s,setHoveredSessionId:c}),e?.role===`admin`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(U,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(Dt,{users:r,currentUserId:e.id,onRefresh:w,registrationEnabled:S.registration_enabled!==`false`,onRefreshSettings:T})}),(0,$.jsx)(U,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(Ot,{initialSettings:S,onRefresh:T})})]}),(0,$.jsx)(U,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(kt,{isAdmin:e?.role===`admin`})})]})};export{Yt as AccountView};
4
+ `)).then(()=>{h(!0),setTimeout(()=>h(!1),2e3)})},onDone:()=>c(null)}):e.totp_enabled?(0,$.jsx)(lt,{user:e,settingsLoading:w,onToggleSkipPassword:async e=>{T(!0);try{await xe(e),t()}catch{}finally{T(!1)}},disableDialogOpen:g,setDisableDialogOpen:_,disablePassword:v,setDisablePassword:y,disableError:S,setDisableError:C,disableLoading:b,onDisable:async r=>{r.preventDefault(),x(!0),C(``);try{let n=v;e.password_version===2&&(n=await Ne(v,e.username)),await Ye(n),_(!1),y(``),t()}catch(e){C(e.message||n(`common.errorNetwork`))}finally{x(!1)}}}):(0,$.jsx)(ut,{setupData:r,setupToken:a,setSetupToken:o,setupError:f,setupLoading:l,onStartSetup:async()=>{u(!0),p(``);try{i(await Re())}catch(e){p(e.message||n(`common.errorNetwork`))}finally{u(!1)}},onConfirmSetup:async e=>{if(e.preventDefault(),r){u(!0),p(``);try{let e=a.replace(/\s/g,``),n=crypto.randomUUID(),s=new TextEncoder().encode(e+n),l=await crypto.subtle.digest(`SHA-256`,s),u=Array.from(new Uint8Array(l)).map(e=>e.toString(16).padStart(2,`0`)).join(``);c((await Ie({secret:r.secret,totpTokenHash:u,salt:n})).recovery_keys),i(null),o(``),t()}catch(e){p(e.message||n(`common.errorNetwork`))}finally{u(!1)}}},onCancel:()=>{i(null),o(``),p(``)}})},ft=({method:e,onSelectMethod:t,hasPasskey:r,hasRecoveryKey:i,hasTotp:a,hasPassword:o})=>{let{t:s}=d();return(0,$.jsx)(`div`,{className:`flex justify-center mb-5 isolate`,style:{isolation:`isolate`},children:(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg`,children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[r&&(0,$.jsx)(L,{small:!0,active:e===`passkey`,intent:e===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.mfa.passkey`,`Passkey`),onClick:()=>t(`passkey`)}),i&&(0,$.jsx)(L,{small:!0,active:e===`recovery_key`,intent:e===`recovery_key`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.recoveryKey.verifyBtn`,`Recovery Key`),onClick:()=>t(`recovery_key`)}),a&&(0,$.jsx)(L,{small:!0,active:e===`totp`,intent:e===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:s(`account.mfa.totp`,`TOTP`),onClick:()=>t(`totp`)}),o&&(0,$.jsx)(L,{small:!0,active:e===`password`,intent:e===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:s(`account.mfa.password`,`Password`),onClick:()=>t(`password`)})]})})})},pt=({loading:e,onVerify:t})=>{let{t:n}=d();return(0,$.jsxs)(`div`,{className:`text-center py-4 space-y-4`,children:[(0,$.jsx)(`div`,{className:`flex justify-center`,children:(0,$.jsx)(`div`,{className:`p-4 rounded-full bg-blue-50 dark:bg-blue-900/30 text-blue-500`,children:(0,$.jsx)(u,{size:48})})}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-300`,children:n(`account.passkey.verifyPrompt`,`Authenticate using your device's biometric sensor (Face ID, Touch ID, Windows Hello) or security key.`)}),(0,$.jsx)(L,{fill:!0,large:!0,intent:H.PRIMARY,loading:e,onClick:t,icon:(0,$.jsx)(u,{size:16}),text:n(`account.usePasskeyInstead`,`Authenticate with Passkey`)})]})},mt=({totpCode:e,setTotpCode:t,loading:n,onVerify:r})=>{let{t:i}=d();return(0,$.jsxs)(`div`,{className:`py-2 space-y-4`,children:[(0,$.jsx)(K,{label:i(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Le,{length:6,value:e,onChange:e=>{t(e),e.length===6&&r(e)},disabled:n})}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,loading:n,disabled:e.length!==6,onClick:()=>r(),text:i(`common.confirm`,`Confirm`)})]})},ht=({password:e,setPassword:t,showPassword:n,setShowPassword:r,loading:i,onSubmit:a})=>{let{t:o}=d();return(0,$.jsxs)(`form`,{onSubmit:a,className:`py-2 space-y-4`,children:[(0,$.jsx)(K,{label:o(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(W,{leftIcon:`lock`,type:n?`text`:`password`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,rightElement:(0,$.jsx)(L,{minimal:!0,icon:n?`eye-open`:`eye-off`,onClick:()=>r(!n)})})}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,type:`submit`,loading:i,text:o(`common.confirm`,`Confirm`)})]})},gt=({recoveryKey:e,setRecoveryKey:t,loading:n,onSubmit:r})=>{let{t:i}=d();return(0,$.jsxs)(`form`,{onSubmit:r,autoComplete:`off`,className:`py-2 space-y-4`,children:[(0,$.jsx)(K,{label:i(`account.recoveryKey.verifyPromptLabel`,`原恢复密钥 (Original Recovery Key)`),children:(0,$.jsx)(W,{leftIcon:`key`,type:`text`,id:`verify-recovery-key-input`,name:`verify_recovery_key_input`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,className:`font-mono text-xs`})}),(0,$.jsx)(L,{fill:!0,intent:H.PRIMARY,type:`submit`,loading:n,disabled:!e.trim(),text:i(`common.confirm`,`Confirm`)})]})};var _t=(e,t)=>{let n=t||[`passkey`,`totp`,`password`];return n.includes(`passkey`)&&e?.passkeys_count&&e.passkeys_count>0?`passkey`:n.includes(`recovery_key`)?`recovery_key`:n.includes(`totp`)&&e?.totp_enabled?`totp`:n.includes(`password`)?`password`:n[0]||`password`};const vt=({isOpen:e,onClose:t,user:n,title:r,onVerify:i,allowedMethods:a})=>{let{t:o}=d(),s=a||[`passkey`,`totp`,`password`],c=!!(n?.passkeys_count&&n.passkeys_count>0)&&s.includes(`passkey`),l=!!n?.totp_enabled&&s.includes(`totp`),u=s.includes(`password`),f=s.includes(`recovery_key`),p=_t(n,a),[m,h]=(0,Q.useState)(p),[g,_]=(0,Q.useState)(``),[v,y]=(0,Q.useState)(!1),[b,x]=(0,Q.useState)(``),[S,C]=(0,Q.useState)(``),[w,T]=(0,Q.useState)(!1),[E,D]=(0,Q.useState)(``),[O,k]=(0,Q.useState)(e);!O&&e?(k(!0),h(p),_(``),y(!1),x(``),C(``),D(``)):O&&!e&&k(!1),(0,Q.useEffect)(()=>{m===`passkey`&&!c?h(f?`recovery_key`:l?`totp`:`password`):m===`totp`&&!l?h(c?`passkey`:f?`recovery_key`:`password`):m===`recovery_key`&&!f&&h(c?`passkey`:l?`totp`:`password`)},[c,l,f,m]);let A=async e=>{if(e&&e.preventDefault(),!g){D(o(`auth.passwordRequired`,`Password is required`));return}T(!0),D(``);try{let e=g;n?.password_version===2&&n?.username&&(e=await Ne(g,n.username)),await i({password:e}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},j=async()=>{T(!0),D(``);try{await i({passkeyAssertion:await fe(await Qe())}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},ee=async e=>{let n=e||b;if(n.length!==6){D(o(`account.totp.invalidCode`,`Please enter a 6-digit code`));return}T(!0),D(``);try{let e=crypto.randomUUID(),r=new TextEncoder().encode(n+e),a=await crypto.subtle.digest(`SHA-256`,r);await i({totpTokenHash:Array.from(new Uint8Array(a)).map(e=>e.toString(16).padStart(2,`0`)).join(``),totpSalt:e}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},M=async e=>{e&&e.preventDefault();let n=S.trim();if(!n){D(o(`account.recoveryKey.keyRequired`,`Recovery key is required`));return}T(!0),D(``);try{await i({recoveryKey:n}),t()}catch(e){D(Je(e,o))}finally{T(!1)}},N=(c?1:0)+(f?1:0)+(l?1:0)+(u?1:0);return(0,$.jsx)(R,{isOpen:e,onClose:t,title:r||o(`account.verifyIdentity`,`Security Verification`),icon:`shield`,className:`max-w-md w-full`,children:(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:o(`account.verifyIdentityDesc`,`To protect your account security, please verify your identity before proceeding.`)}),N>1&&(0,$.jsx)(ft,{method:m,onSelectMethod:e=>{h(e),D(``)},hasPasskey:c,hasRecoveryKey:f,hasTotp:l,hasPassword:u}),E&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:E}),m===`recovery_key`&&(0,$.jsx)(gt,{recoveryKey:S,setRecoveryKey:C,loading:w,onSubmit:M}),m===`passkey`&&(0,$.jsx)(pt,{loading:w,onVerify:j}),m===`totp`&&(0,$.jsx)(mt,{totpCode:b,setTotpCode:x,loading:w,onVerify:ee}),m===`password`&&(0,$.jsx)(ht,{password:g,setPassword:_,showPassword:v,setShowPassword:y,loading:w,onSubmit:A})]})})},yt=({user:e,onRefresh:t})=>{let{t:r}=d(),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(null),[p,m]=(0,Q.useState)(!1),[g,_]=(0,Q.useState)(!1),[v,b]=(0,Q.useState)(null),C=!!(e.has_recovery_keys||e.recovery_keys_encrypted),E=()=>{b(null),s(!0)},D=()=>{s(!1),a(!0)},O=async e=>{let n=await ze(e);l(n.recovery_key),m(!1);let i=!1;if(Z.isUnlocked())try{await Z.wrapCurrentKeyForRecovery(n.recovery_key),i=!0}catch(e){console.warn(`[RecoveryKey] Failed to wrap E2EE key with new recovery key:`,e)}else if(e.recoveryKey)try{await Z.unlockWithRecoveryKey(e.recoveryKey),await Z.wrapCurrentKeyForRecovery(n.recovery_key),i=!0}catch(e){console.warn(`[RecoveryKey] Failed to unlock and re-wrap with new recovery key:`,e)}else if(e.passkeyAssertion)try{await Z.unlockUser(),await Z.wrapCurrentKeyForRecovery(n.recovery_key),i=!0}catch(e){console.warn(`[RecoveryKey] Failed to unlock via Passkey and re-wrap:`,e)}try{if((await Z.getUserStatus()).hasKeys&&!i){b({text:r(`account.recoveryKey.rotateSuccessE2eeWarning`,`恢复密钥已成功轮换!注意:由于端到端加密此前处于锁定状态且未能解密,旧 E2EE 密文仍需使用轮换前的旧恢复密钥解锁,或可在下方端到端加密卡片中点击「重置密钥对」。`),intent:H.WARNING}),t();return}}catch{}b({text:r(`account.recoveryKey.rotateSuccess`,`恢复密钥已成功轮换!请立即妥善离线保存新密钥,旧密钥已失效。`),intent:H.SUCCESS}),t()},k=e=>{navigator.clipboard.writeText(e),_(!0),setTimeout(()=>_(!1),2e3)};return(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,$.jsx)(u,{size:18,className:`text-amber-500`}),(0,$.jsx)(G,{style:{margin:0},children:r(`account.recoveryKey.title`,`紧急恢复密钥`)}),(0,$.jsx)(q,{intent:C?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:C?r(`account.recoveryKey.configured`,`已配置`):r(`account.recoveryKey.notConfigured`,`未配置`)}),(0,$.jsx)(ce,{content:r(`account.recoveryKey.oneWayTooltip`,`采用 SHA-256 单向密码学散列保护,服务端不存储明文且不可解密,仅支持身份轮换验证。`),position:M.TOP,children:(0,$.jsx)(q,{intent:H.PRIMARY,minimal:!0,round:!0,icon:(0,$.jsx)(n,{size:12,style:{display:`inline-flex`,alignItems:`center`,marginRight:`4px`}}),children:r(`account.recoveryKey.oneWayHash`,`单向不可逆散列`)})})]}),(0,$.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,$.jsx)(L,{small:!0,intent:H.WARNING,icon:(0,$.jsx)(f,{size:14}),text:r(`account.recoveryKey.rotateBtn`,`轮换恢复密钥`),onClick:E})})]}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:r(`account.recoveryKey.descOneWay`,`紧急恢复密钥是在您丢失所有通行密钥 (Passkey) 或身份验证器时,恢复账号访问及端到端解密数据的唯一凭据。为确保零知识安全,恢复密钥采用单向不可逆散列存储,无法在网页端查看明文,仅支持通过原恢复密钥或现有 Passkey 进行轮换。密钥一旦被使用将立即自动轮换。`)}),v&&(0,$.jsx)(V,{intent:v.intent,className:`my-2`,children:v.text}),c&&(0,$.jsxs)(J,{elevation:F.ZERO,className:`bg-amber-50/50 dark:bg-amber-950/20 border border-amber-300 dark:border-amber-800 p-4 space-y-3`,children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-2`,children:[(0,$.jsxs)(`span`,{className:`text-xs font-semibold text-amber-800 dark:text-amber-300 uppercase tracking-wider flex items-center gap-1.5`,children:[(0,$.jsx)(S,{size:14}),r(`account.recoveryKey.newKeyGenerated`,`已生成全新 30 位恢复密钥(请立即保存)`)]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[(0,$.jsx)(L,{minimal:!0,small:!0,icon:p?(0,$.jsx)(T,{size:14}):(0,$.jsx)(x,{size:14}),onClick:()=>m(!p),title:p?r(`auth.showPassword`,`显示`):r(`auth.hidePassword`,`隐藏`)}),(0,$.jsx)(L,{minimal:!0,small:!0,icon:g?(0,$.jsx)(y,{size:14,className:`text-green-500`}):(0,$.jsx)(w,{size:14}),onClick:()=>k(c),title:r(`common.copy`,`复制`),text:g?r(`common.copied`,`已复制`):r(`common.copy`,`复制`)}),(0,$.jsx)(L,{minimal:!0,small:!0,icon:`cross`,onClick:()=>l(null),title:r(`common.close`,`关闭`)})]})]}),(0,$.jsx)(`div`,{className:`p-3 bg-white dark:bg-gray-900 rounded border border-amber-200 dark:border-amber-800/80 font-mono text-center text-lg sm:text-xl font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:p?`••••••-••••••-••••••-••••••-••••••`:c}),(0,$.jsxs)(`p`,{className:`text-xs text-amber-700 dark:text-amber-400 flex items-center gap-1`,children:[(0,$.jsx)(h,{size:14,className:`shrink-0`}),r(`account.recoveryKey.oneWayWarning`,`注意:此密钥仅在此显示一次,关闭后将无法再次查看!服务端仅保存不可逆散列,请务必将其妥善复制并离线安全保存。`)]})]}),(0,$.jsx)(P,{isOpen:o,onConfirm:D,onCancel:()=>s(!1),cancelButtonText:r(`common.cancel`,`取消`),confirmButtonText:r(`account.recoveryKey.confirmRotateBtn`,`确认进入轮换验证`),intent:H.DANGER,icon:`warning-sign`,children:(0,$.jsx)(`p`,{children:r(`account.recoveryKey.rotateConfirm`,`轮换恢复密钥将立即使原恢复密钥失效,并重新派生信封加密密钥。仅允许通过现有通行密钥 (Passkey) 或原恢复密钥完成轮换验证。是否继续?`)})}),(0,$.jsx)(vt,{isOpen:i,onClose:()=>a(!1),user:e,allowedMethods:[`passkey`,`recovery_key`],title:r(`account.recoveryKey.rotateVerifyTitle`,`验证身份以轮换恢复密钥`),onVerify:O})]})},bt=({user:e,onRefresh:r})=>{let{t:i}=d(),[a,o]=(0,Q.useState)(!1),s=!!(e.mfa_enabled??(e.totp_enabled||e.passkeys_count&&e.passkeys_count>0)),c=async e=>{o(!0);try{await ve(e),r()}catch(e){alert(e.message||i(`common.errorNetwork`,`Network error`))}finally{o(!1)}};return(0,$.jsxs)(J,{elevation:F.ONE,className:`space-y-6`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`flex items-center justify-between mb-3`,children:(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(n,{size:20,className:s?`text-green-500`:`text-gray-400`}),(0,$.jsx)(G,{style:{margin:0},children:i(`account.mfa.title`,`Multi-Factor Authentication (MFA)`)}),(0,$.jsx)(q,{intent:s?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:s?i(`account.mfa.enabled`,`Configured`):i(`account.mfa.notConfigured`,`Not Configured`)})]})}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:i(`account.mfa.desc`,`Passkeys and Authenticator Apps (TOTP) both serve as MFA authentication methods. Configuring at least one factor protects your account and enables passwordless login and self-service password recovery.`)}),s?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(U,{className:`my-3`}),(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-2 py-1`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`font-medium text-sm text-gray-900 dark:text-gray-100`,children:i(`account.mfa.passwordlessTitle`,`Passwordless Login`)}),(0,$.jsx)(`div`,{className:`text-xs text-gray-500 dark:text-gray-400`,children:i(`account.mfa.passwordlessDesc`,`When enabled, logging in will skip the password requirement and verify your identity directly via Passkey or TOTP.`)})]}),(0,$.jsx)(ae,{checked:!!e.totp_skip_password,onChange:e=>c(e.currentTarget.checked),disabled:a,className:`mb-0 shrink-0`})]})]}):(0,$.jsx)(V,{intent:H.PRIMARY,icon:(0,$.jsx)(t,{size:16,style:{display:`inline-flex`,alignItems:`center`,marginRight:`8px`}}),children:i(`account.mfa.unconfiguredHint`,`No MFA method configured yet. Set up either a Passkey or Authenticator App below to safeguard your account and unlock passwordless login and account recovery.`)})]}),(0,$.jsx)(U,{}),(0,$.jsx)(st,{onRefresh:r}),(0,$.jsx)(U,{}),(0,$.jsx)(dt,{user:e,onRefresh:r}),(0,$.jsx)(U,{}),(0,$.jsx)(yt,{user:e,onRefresh:r})]})},xt={signup:{label:`account.activity.signup`,icon:(0,$.jsx)(E,{size:14}),intent:H.SUCCESS},login_success:{label:`account.activity.loginSuccess`,icon:(0,$.jsx)(g,{size:14}),intent:H.SUCCESS},login_fail:{label:`account.activity.loginFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER},logout:{label:`account.activity.logout`,icon:(0,$.jsx)(c,{size:14}),intent:H.NONE},password_change_success:{label:`account.activity.pwChangeSuccess`,icon:(0,$.jsx)(u,{size:14}),intent:H.SUCCESS},password_change_fail:{label:`account.activity.pwChangeFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER},totp_verify_success:{label:`account.activity.totpVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:H.SUCCESS},totp_verify_fail:{label:`account.activity.totpVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER},totp_setup:{label:`account.activity.totpSetup`,icon:(0,$.jsx)(a,{size:14}),intent:H.PRIMARY},totp_removed:{label:`account.activity.totpRemoved`,icon:(0,$.jsx)(C,{size:14}),intent:H.WARNING},recovery_key_used:{label:`account.activity.recoveryKeyUsed`,icon:(0,$.jsx)(u,{size:14}),intent:H.WARNING},recovery_key_rotated:{label:`account.activity.recoveryKeyRotated`,icon:(0,$.jsx)(u,{size:14}),intent:H.WARNING},session_revoked:{label:`account.activity.sessionRevoked`,icon:(0,$.jsx)(c,{size:14}),intent:H.WARNING},passkey_registered:{label:`account.activity.passkeyRegistered`,icon:(0,$.jsx)(u,{size:14}),intent:H.PRIMARY},passkey_deleted:{label:`account.activity.passkeyDeleted`,icon:(0,$.jsx)(C,{size:14}),intent:H.WARNING},passkey_verify_success:{label:`account.activity.passkeyVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:H.SUCCESS},passkey_verify_fail:{label:`account.activity.passkeyVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:H.DANGER}},St=e=>{if(!e)return`desktop`;let t=e.toLowerCase();return t.includes(`mobile`)||t.includes(`android`)||t.includes(`iphone`)||t.includes(`tablet`)||t.includes(`ipad`)?`mobile-phone`:`desktop`},Ct=(e,t)=>{if(!e)return t;let n=e;return n.includes(`Edg/`)?`Edge`:n.includes(`Chrome/`)&&!n.includes(`Edg/`)?`Chrome`:n.includes(`Firefox/`)?`Firefox`:n.includes(`Safari/`)&&!n.includes(`Chrome/`)?`Safari`:t},wt=({userAgent:e})=>{let{t}=d();if(!e)return(0,$.jsx)(`span`,{className:`text-gray-500`,children:`—`});let n=Ct(e,t(`account.sessions.unknownDevice`,`Unknown Device`));return(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(te,{icon:St(e),className:`text-gray-400`}),(0,$.jsx)(`span`,{children:n})]}),(0,$.jsx)(`div`,{className:`text-xs text-gray-400 mt-1 max-w-xs truncate`,title:e,children:e})]})},Tt=({hoveredSessionId:e,setHoveredSessionId:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[c,l]=(0,Q.useState)(!0),[u,p]=(0,Q.useState)(!1),m=(0,Q.useCallback)(async e=>{o(!0);try{let t=new URLSearchParams({limit:`20`});e&&t.set(`before`,String(e));let n=await $e(t.toString());i(e?e=>[...e,...n]:n),l(n.length===20)}catch{}finally{o(!1)}},[]);(0,Q.useEffect)(()=>{m()},[m]);let h=()=>{let e=r[r.length-1];e&&m(e.timestamp)},g=e=>xt[e]??{label:e,icon:(0,$.jsx)(s,{size:14}),intent:H.NONE};return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between cursor-pointer`,onClick:()=>p(!u),children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(s,{size:20,className:`text-purple-500`}),(0,$.jsx)(G,{style:{margin:0},children:n(`account.activity.title`,`Account Activity`)}),r.length>0&&(0,$.jsxs)(q,{minimal:!0,round:!0,intent:H.NONE,children:[r.length,c?`+`:``]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(L,{minimal:!0,icon:(0,$.jsx)(f,{size:14}),onClick:e=>{e.stopPropagation(),m()}}),(0,$.jsx)(b,{size:16,className:`text-gray-400 transition-transform ${u?`rotate-180`:``}`})]})]}),u&&(0,$.jsx)(`div`,{className:`mt-4`,children:a&&r.length===0?(0,$.jsx)(`div`,{className:`flex justify-center py-8`,children:(0,$.jsx)(z,{size:24})}):r.length===0?(0,$.jsx)(`p`,{className:`text-sm text-gray-500 text-center py-6`,children:n(`account.activity.empty`,`No activity recorded yet.`)}):(0,$.jsxs)(`div`,{className:`overflow-x-auto`,children:[(0,$.jsxs)(se,{interactive:!0,striped:!0,className:`w-full text-sm`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{children:n(`account.activity.action`,`Action`)}),(0,$.jsx)(`th`,{children:n(`account.activity.time`,`Time`)}),(0,$.jsx)(`th`,{children:n(`account.activity.session`,`Session`)}),(0,$.jsx)(`th`,{children:n(`account.activity.ip`,`IP Address`)}),(0,$.jsx)(`th`,{children:n(`account.activity.device`,`Device`)})]})}),(0,$.jsx)(`tbody`,{children:r.map(r=>{let i=g(r.action),a=``,o=r.session_id_hash||``;if(r.extra)try{let e=JSON.parse(r.extra);if(e.reason){let t=`account.activity.reasons.${e.reason}`,r=n(t);a=r&&r!==t?r:e.reason.replace(/[_-]+/g,` `).replace(/\b\w/g,e=>e.toUpperCase())}}catch{}return(0,$.jsxs)(`tr`,{onMouseEnter:()=>{o&&t?.(o)},onMouseLeave:()=>{o&&t?.(null)},className:e&&e===o?`bg-gray-100/80 dark:bg-slate-800/80`:``,children:[(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsxs)(`div`,{className:`flex flex-col items-start gap-1`,children:[(0,$.jsx)(q,{minimal:!0,intent:i.intent,icon:i.icon,children:n(i.label,r.action)}),a&&(0,$.jsx)(`span`,{className:`text-xs text-gray-500 italic ml-1`,children:a})]})}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 whitespace-nowrap align-middle`,children:X(new Date(r.timestamp*1e3))}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:o?o.slice(0,8):`—`}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:r.ip_address||`—`}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(wt,{userAgent:r.user_agent||null})})]},r.id)})})]}),c&&(0,$.jsx)(`div`,{className:`flex justify-center mt-3`,children:(0,$.jsx)(L,{minimal:!0,loading:a,text:n(`account.activity.loadMore`,`Load More`),onClick:h})})]})})]})},Et=({hoveredSessionId:e,setHoveredSessionId:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,l]=(0,Q.useState)(null),[u,p]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(!1),_=r.filter(e=>!e.is_current).length,v=(0,Q.useCallback)(async()=>{o(!0);try{let e=await Ze(),t=Date.now();i((e||[]).filter(e=>e.expires_at*1e3>t))}catch{}finally{o(!1)}},[]);(0,Q.useEffect)(()=>{v()},[v]);let y=async e=>{l(e);try{(await we(e)).is_current?window.location.reload():i(t=>t.filter(t=>t.id!==e))}catch(e){alert(e.message||n(`account.sessions.revokeFailed`,`Failed to revoke session.`))}finally{l(null)}};return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(m,{size:20,className:`text-green-500`}),(0,$.jsx)(G,{style:{margin:0},children:n(`account.sessions.title`,`Active Sessions`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[_>0&&(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.DANGER,icon:(0,$.jsx)(c,{size:14}),text:n(`account.sessions.revokeOthers`,`Revoke Other Sessions`),loading:u,onClick:()=>g(!0)}),(0,$.jsx)(L,{minimal:!0,icon:(0,$.jsx)(f,{size:14}),onClick:()=>v()})]})]}),a?(0,$.jsx)(`div`,{className:`flex justify-center py-4`,children:(0,$.jsx)(z,{size:24})}):r.length===0?(0,$.jsx)(`p`,{className:`text-sm text-gray-500 text-center py-4`,children:n(`account.sessions.empty`,`No active sessions found.`)}):(0,$.jsx)(`div`,{className:`overflow-x-auto`,children:(0,$.jsxs)(se,{interactive:!0,striped:!0,className:`w-full text-sm`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{children:n(`account.sessions.device`,`Device`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.session`,`Session`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.ip`,`IP Address`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.loginTime`,`Login Time`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.expires`,`Expires`)}),(0,$.jsx)(`th`,{children:n(`account.sessions.action`,`Action`)})]})}),(0,$.jsx)(`tbody`,{children:r.map(r=>(0,$.jsxs)(`tr`,{onMouseEnter:()=>t?.(r.id),onMouseLeave:()=>t?.(null),className:e===r.id?`bg-gray-100/80 dark:bg-slate-800/80`:``,children:[(0,$.jsx)(`td`,{children:(0,$.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,$.jsx)(wt,{userAgent:r.user_agent}),r.is_current&&(0,$.jsx)(q,{minimal:!0,intent:H.SUCCESS,className:`mt-0.5`,children:n(`account.sessions.current`,`Current`)})]})}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:r.id?r.id.slice(0,8):`—`}),(0,$.jsx)(`td`,{className:`font-mono text-xs text-gray-500 align-middle`,children:r.ip_address||`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:r.created_at?X(new Date(r.created_at*1e3)):`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:X(new Date(r.expires_at*1e3))}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.DANGER,disabled:r.is_current,icon:(0,$.jsx)(c,{size:14}),text:n(`account.sessions.revoke`,`Revoke`),loading:s===r.id,onClick:()=>y(r.id)})})]},r.id))})]})}),(0,$.jsx)(P,{isOpen:h,cancelButtonText:n(`common.cancel`,`Cancel`),confirmButtonText:n(`account.sessions.confirmRevokeOthers`,`Revoke Other Sessions`),intent:H.DANGER,icon:`log-out`,onCancel:()=>g(!1),onConfirm:async()=>{p(!0);try{await he(),i(e=>e.filter(e=>e.is_current)),g(!1)}catch(e){alert(e.message||n(`account.sessions.revokeFailed`,`Failed to revoke session.`))}finally{p(!1)}},loading:u,children:(0,$.jsx)(`p`,{children:n(`account.sessions.revokeOthersConfirmText`,`Are you sure you want to revoke all other active sessions? All other logged-in devices will be signed out immediately.`)})})]})},Dt=({users:e,currentUserId:t,onRefresh:r,registrationEnabled:a=!0,onRefreshSettings:o})=>{let{t:s}=d(),[c,l]=(0,Q.useState)(!1),[u,f]=(0,Q.useState)(``),[p,m]=(0,Q.useState)(``),[h,g]=(0,Q.useState)(`user`),[_,v]=(0,Q.useState)(!1),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(a),[C,w]=(0,Q.useState)(!1);(0,Q.useEffect)(()=>{S(a)},[a]);let T=async e=>{S(e),w(!0);try{await ge({registration_enabled:String(e)}),o?.()}catch(t){console.error(t),S(!e),alert(t.message||s(`common.errorNetwork`,`Network error`))}finally{w(!1)}},D=async()=>{if(!Be.test(u)){alert(s(`account.formatTipUsername`));return}if(!Ue.test(p)){alert(s(`account.formatTipPassword`));return}v(!0);try{await De({username:u,password:await Ne(p,u),role:h}),l(!1),f(``),m(``),b(!1),r()}catch(e){console.error(e),alert(e.message||s(`common.errorNetwork`))}finally{v(!1)}},O=async e=>{if(confirm(s(`account.confirmDeleteUser`)))try{await pe(e),r()}catch(e){console.error(e)}};return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(n,{size:20,className:`text-red-500`}),(0,$.jsx)(G,{style:{margin:0},children:s(`account.userManagement`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,$.jsx)(ae,{label:s(`account.enableRegistration`,`开放新用户注册`),checked:x,disabled:C,onChange:e=>T(e.currentTarget.checked),className:`mb-0`}),(0,$.jsx)(L,{className:`whitespace-nowrap`,icon:(0,$.jsx)(E,{size:16}),intent:H.SUCCESS,text:s(`account.createUser`),onClick:()=>l(!0)})]})]}),(0,$.jsx)(J,{elevation:F.ONE,className:`p-0 overflow-hidden overflow-x-auto`,children:(0,$.jsxs)(se,{interactive:!0,striped:!0,className:`w-full`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{children:s(`account.username`)}),(0,$.jsx)(`th`,{children:s(`account.role`)}),(0,$.jsx)(`th`,{children:`MFA`}),(0,$.jsx)(`th`,{children:`ID`}),(0,$.jsx)(`th`,{children:s(`account.createdAt`)}),(0,$.jsx)(`th`,{children:s(`account.lastActive`)}),(0,$.jsx)(`th`,{children:s(`account.lastResolve`)}),(0,$.jsx)(`th`,{className:`text-right`,children:s(`account.actions`)})]})}),(0,$.jsx)(`tbody`,{children:e.map(e=>(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`td`,{className:`font-bold`,children:e.username}),(0,$.jsx)(`td`,{children:(0,$.jsx)(q,{minimal:!0,intent:e.role===`admin`?H.DANGER:H.NONE,children:e.role===`admin`?s(`account.roleAdmin`):s(`account.roleUser`)})}),(0,$.jsx)(`td`,{children:(0,$.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[!!e.totp_enabled&&(0,$.jsx)(q,{minimal:!0,intent:H.SUCCESS,children:`TOTP`}),!!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(q,{minimal:!0,intent:H.PRIMARY,children:`Passkey`}),!e.totp_enabled&&!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(q,{minimal:!0,intent:H.NONE,style:{color:`#8a9ba8`},children:s(`account.mfaNone`,`无`)})]})}),(0,$.jsx)(`td`,{children:(0,$.jsx)(`code`,{className:`text-xs`,children:e.id})}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.created_at?X(new Date(e.created_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_active_at?X(new Date(e.last_active_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_resolve_at?X(new Date(e.last_resolve_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-right`,children:(0,$.jsx)(`div`,{className:`inline-flex items-center gap-1`,children:(0,$.jsx)(L,{minimal:!0,intent:H.DANGER,icon:(0,$.jsx)(i,{size:14}),disabled:e.id===t,onClick:()=>O(e.id)})})})]},e.id))})]})}),(0,$.jsx)(R,{isOpen:c,onClose:()=>{l(!1),b(!1)},title:s(`account.createNewUser`),icon:`user`,children:(0,$.jsxs)(`div`,{className:`p-6 space-y-4`,children:[(0,$.jsx)(K,{label:s(`account.username`),children:(0,$.jsx)(W,{value:u,onChange:e=>f(e.target.value),placeholder:s(`auth.usernamePlaceholder`)})}),(0,$.jsx)(K,{label:s(`account.initialPassword`),children:(0,$.jsx)(W,{type:y?`text`:`password`,value:p,onChange:e=>m(e.target.value),placeholder:s(`auth.passwordPlaceholder`),rightElement:(0,$.jsx)(L,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:y?s(`auth.hidePassword`,`Hide password`):s(`auth.showPassword`,`Show password`)})})}),(0,$.jsx)(K,{label:s(`account.userRole`),children:(0,$.jsx)(ie,{fill:!0,value:h,onChange:e=>g(e.target.value),options:[{label:s(`account.roleUser`),value:`user`},{label:s(`account.roleAdmin`),value:`admin`}]})}),(0,$.jsxs)(`div`,{className:`flex justify-end gap-2 mt-6`,children:[(0,$.jsx)(L,{text:s(`account.cancel`),onClick:()=>l(!1)}),(0,$.jsx)(L,{intent:H.PRIMARY,text:s(`account.createNow`),loading:_,onClick:D})]})]})})]})},Ot=({initialSettings:e,onRefresh:t})=>{let{t:n}=d(),[r,i]=(0,Q.useState)(e),[a,o]=(0,Q.useState)(!1),[s,c]=(0,Q.useState)(!1);return(0,Q.useEffect)(()=>{i(e)},[e]),(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(l,{size:20,className:`text-gray-500`}),(0,$.jsx)(G,{style:{margin:0},children:n(`account.systemSettings`,`System Settings`)})]}),(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(G,{className:`text-sm font-bold opacity-70 text-blue-500`,children:`Cloudflare Turnstile`}),(0,$.jsx)(K,{label:`Site Key`,children:(0,$.jsx)(W,{value:r.turnstile_site_key||``,onChange:e=>i({...r,turnstile_site_key:e.target.value}),placeholder:`0x000...`})}),(0,$.jsx)(K,{label:`Secret Key`,children:(0,$.jsx)(W,{type:s?`text`:`password`,value:r.turnstile_secret_key||``,onChange:e=>i({...r,turnstile_secret_key:e.target.value}),placeholder:`0x000...`,rightElement:(0,$.jsx)(L,{minimal:!0,icon:s?`eye-open`:`eye-off`,onClick:()=>c(!s),title:s?n(`auth.hidePassword`,`Hide password`):n(`auth.showPassword`,`Show password`)})})})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(G,{className:`text-sm font-bold opacity-70 text-green-500`,children:n(`account.featureToggle`,`Feature Toggle`)}),(0,$.jsx)(ae,{label:n(`account.enableTurnstileSignup`,`Enable verification on Signup`),checked:r.turnstile_enabled_signup===`true`,onChange:e=>i({...r,turnstile_enabled_signup:String(e.currentTarget.checked)})}),(0,$.jsx)(ae,{label:n(`account.enableTurnstileLogin`,`Enable verification on Login`),checked:r.turnstile_enabled_login===`true`,onChange:e=>i({...r,turnstile_enabled_login:String(e.currentTarget.checked)})})]})]}),(0,$.jsx)(U,{className:`my-4`}),(0,$.jsx)(`div`,{className:`flex justify-end`,children:(0,$.jsx)(L,{intent:H.PRIMARY,icon:`floppy-disk`,text:n(`common.save`,`Save`),loading:a,onClick:async()=>{o(!0);try{await ge({turnstile_site_key:r.turnstile_site_key||``,turnstile_secret_key:r.turnstile_secret_key||``,turnstile_enabled_signup:r.turnstile_enabled_signup||`false`,turnstile_enabled_login:r.turnstile_enabled_login||`false`}),alert(n(`common.saveSuccess`,`Settings saved`)),t()}catch(e){console.error(e)}finally{o(!1)}}})})]})]})},kt=({isAdmin:e,onLogsCleared:t})=>{let{t:n}=d(),[r,a]=(0,Q.useState)(!1);return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(G,{className:`text-red-500 flex items-center gap-2`,children:[(0,$.jsx)(i,{size:20}),` `,n(`account.dangerZone`)]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,$.jsxs)(J,{elevation:F.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(G,{children:n(`account.clearLogs`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-3`,children:n(`account.clearLogsDesc`)})]}),(0,$.jsx)(L,{fill:!0,intent:H.DANGER,text:n(`account.clearLogsBtn`),icon:`trash`,loading:r,onClick:async()=>{if(confirm(n(`account.confirmClearLogs`))){a(!0);try{await Ge(),alert(n(`account.clearLogsSuccess`)),t?.()}catch(e){console.error(e)}finally{a(!1)}}}})]}),!e&&(0,$.jsxs)(J,{elevation:F.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(G,{children:n(`account.deleteAccount`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-4`,children:n(`account.deleteAccountDesc`)})]}),(0,$.jsx)(L,{fill:!0,intent:H.DANGER,text:n(`account.deleteAccountBtn`),icon:`delete`,onClick:async()=>{if(confirm(n(`account.confirmDeleteAccount`)))try{await Fe(),window.location.href=`/`}catch(e){console.error(e),alert(e.message||n(`common.errorNetwork`))}}})]})]}),(0,$.jsx)(V,{intent:H.WARNING,icon:`info-sign`,title:n(`account.inactivityPolicy`),children:(0,$.jsx)(`p`,{className:`text-sm`,children:n(`account.inactivityDesc`)})})]})},At=[{label:ee(`account.timezoneAuto`,`Auto (Browser Default)`),value:``},{label:`Pacific/Midway (Midway Island) (Standard: UTC-11)`,value:`Pacific/Midway`},{label:`Pacific/Honolulu (Honolulu, Hawaii) (Standard: UTC-10)`,value:`Pacific/Honolulu`},{label:`America/Anchorage (Anchorage, Alaska) (Standard: UTC-9 / DST: UTC-8)`,value:`America/Anchorage`},{label:`America/Los_Angeles (Pacific Time) (Standard: UTC-8 / DST: UTC-7)`,value:`America/Los_Angeles`},{label:`America/Denver (Mountain Time) (Standard: UTC-7 / DST: UTC-6)`,value:`America/Denver`},{label:`America/Chicago (Central Time) (Standard: UTC-6 / DST: UTC-5)`,value:`America/Chicago`},{label:`America/New_York (Eastern Time) (Standard: UTC-5 / DST: UTC-4)`,value:`America/New_York`},{label:`America/Halifax (Atlantic Time) (Standard: UTC-4 / DST: UTC-3)`,value:`America/Halifax`},{label:`America/Argentina/Buenos_Aires (Buenos Aires) (Standard: UTC-3)`,value:`America/Argentina/Buenos_Aires`},{label:`America/Noronha (Fernando de Noronha) (Standard: UTC-2)`,value:`America/Noronha`},{label:`Atlantic/Azores (Azores) (Standard: UTC-1 / DST: UTC+0)`,value:`Atlantic/Azores`},{label:`UTC (Coordinated Universal Time) (Standard: UTC+0)`,value:`UTC`},{label:`Europe/London (London) (Standard: UTC+0 / DST: UTC+1)`,value:`Europe/London`},{label:`Europe/Paris (Paris, Berlin, Rome) (Standard: UTC+1 / DST: UTC+2)`,value:`Europe/Paris`},{label:`Europe/Kyiv (Kyiv, Helsinki, Cairo) (Standard: UTC+2 / DST: UTC+3)`,value:`Europe/Kyiv`},{label:`Europe/Moscow (Moscow) (Standard: UTC+3)`,value:`Europe/Moscow`},{label:`Asia/Dubai (Dubai, Baku) (Standard: UTC+4)`,value:`Asia/Dubai`},{label:`Asia/Karachi (Karachi, Tashkent) (Standard: UTC+5)`,value:`Asia/Karachi`},{label:`Asia/Dhaka (Dhaka, Almaty) (Standard: UTC+6)`,value:`Asia/Dhaka`},{label:`Asia/Bangkok (Bangkok, Jakarta) (Standard: UTC+7)`,value:`Asia/Bangkok`},{label:`Asia/Singapore (Beijing, Shanghai, Singapore, Taipei) (Standard: UTC+8)`,value:`Asia/Singapore`},{label:`Asia/Tokyo (Tokyo, Seoul) (Standard: UTC+9)`,value:`Asia/Tokyo`},{label:`Australia/Sydney (Sydney, Melbourne) (Standard: UTC+10 / DST: UTC+11)`,value:`Australia/Sydney`},{label:`Pacific/Noumea (Nouméa) (Standard: UTC+11)`,value:`Pacific/Noumea`},{label:`Pacific/Auckland (Auckland, Suva) (Standard: UTC+12 / DST: UTC+13)`,value:`Pacific/Auckland`}],jt=({me:e,isEditingUsername:t,setIsEditingUsername:n,editUsername:i,setEditUsername:a,usernameLoading:o,usernameFocused:s,setUsernameFocused:c,onUpdateUsername:l,onUpdateTimezone:u})=>{let{t:f}=d();return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(_,{size:20,className:`text-blue-500`}),(0,$.jsx)(G,{style:{margin:0},children:f(`account.personalInfo`)})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(K,{label:f(`account.username`),children:(0,$.jsx)(`div`,{className:`flex gap-2`,children:t?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(ce,{content:f(`account.formatTipUsername`),isOpen:s,position:M.TOP,intent:H.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(W,{fill:!0,value:i,onChange:e=>a(e.target.value),onFocus:()=>c(!0),onBlur:()=>c(!1),autoFocus:!0})})}),(0,$.jsxs)(N,{children:[(0,$.jsx)(L,{icon:(0,$.jsx)(y,{size:16}),intent:H.SUCCESS,loading:o,onClick:l}),(0,$.jsx)(L,{icon:(0,$.jsx)(D,{size:16}),onClick:()=>{n(!1),a(e?.username||``)}})]})]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(W,{fill:!0,value:e?.username,readOnly:!0}),(0,$.jsx)(L,{icon:(0,$.jsx)(r,{size:16}),onClick:()=>n(!0)})]})})}),(0,$.jsx)(K,{label:f(`account.userId`),children:(0,$.jsx)(W,{leftIcon:`id-number`,value:e?.id,disabled:!0})}),(0,$.jsx)(K,{label:f(`account.timezone`,`Timezone`),children:(0,$.jsx)(ie,{fill:!0,value:e?.timezone||``,onChange:e=>u?.(e.target.value||null),options:At})})]})]})},Mt=({me:e,onRefresh:t})=>{let{t:r}=d(),i=!!(e?.passkeys_count&&e.passkeys_count>0),a=!!e?.totp_enabled,[o,s]=(0,Q.useState)(`password`),[c,l]=(0,Q.useState)(``),[f,p]=(0,Q.useState)(!1),[m,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(!1),[C,w]=(0,Q.useState)(!1),[T,E]=(0,Q.useState)(null);return(0,Q.useEffect)(()=>{o===`passkey`&&!i?s(a?`totp`:`password`):o===`totp`&&!a&&s(i?`passkey`:`password`)},[i,a,o]),(0,$.jsxs)(J,{elevation:F.ONE,className:`isolate`,style:{isolation:`isolate`},children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(u,{size:20,className:`text-orange-500`}),(0,$.jsx)(G,{style:{margin:0},children:r(`account.changePassword`,`Change Password`)})]}),(i||a)&&(0,$.jsx)(`div`,{className:`mb-4 isolate`,style:{isolation:`isolate`},children:(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg`,children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(L,{small:!0,active:o===`password`,intent:o===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:r(`account.mfa.password`,`Password`),onClick:()=>{s(`password`),E(null)}}),i&&(0,$.jsx)(L,{small:!0,active:o===`passkey`,intent:o===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:r(`account.mfa.passkey`,`Passkey`),onClick:()=>{s(`passkey`),E(null)}}),a&&(0,$.jsx)(L,{small:!0,active:o===`totp`,intent:o===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:r(`account.mfa.totp`,`TOTP`),onClick:()=>{s(`totp`),E(null)}})]})})}),T&&(0,$.jsx)(V,{intent:T.intent,className:`mb-4`,children:T.text}),(0,$.jsxs)(`form`,{onSubmit:async n=>{if(n.preventDefault(),!Ue.test(_)){E({text:r(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),intent:H.DANGER});return}if(!e?.username){E({text:r(`auth.sessionExpired`,`Session expired. Please log in again.`),intent:H.DANGER});return}w(!0),E(null);try{let n=await Ne(_,e.username);if(o===`passkey`)await ye({passkeyAssertion:await fe(await Qe()),newPassword:n});else if(o===`totp`){if(m.length!==6){E({text:r(`account.totp.invalidCode`,`Please enter a 6-digit code`),intent:H.DANGER}),w(!1);return}let e=crypto.randomUUID(),t=new TextEncoder().encode(m+e),i=await crypto.subtle.digest(`SHA-256`,t);await ye({totpTokenHash:Array.from(new Uint8Array(i)).map(e=>e.toString(16).padStart(2,`0`)).join(``),totpSalt:e,newPassword:n})}else{if(!c){E({text:r(`auth.passwordRequired`,`Current password is required`),intent:H.DANGER}),w(!1);return}let t=c;(e.password_version??1)===2&&(t=await Ne(c,e.username)),await ye({oldPassword:t,newPassword:n})}E({text:r(`account.passwordSuccess`,`Password updated successfully!`),intent:H.SUCCESS}),l(``),g(``),v(``),t&&t()}catch(e){E({text:Je(e,r),intent:H.DANGER})}finally{w(!1)}},className:`space-y-4`,children:[o===`password`&&(0,$.jsx)(K,{label:r(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(W,{leftIcon:`lock`,type:f?`text`:`password`,value:c,onChange:e=>l(e.target.value),rightElement:(0,$.jsx)(L,{minimal:!0,icon:f?`eye-open`:`eye-off`,onClick:()=>p(!f),title:r(f?`auth.hidePassword`:`auth.showPassword`)}),required:!0})}),o===`totp`&&(0,$.jsx)(K,{label:r(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Le,{length:6,value:m,onChange:g,disabled:C})}),o===`passkey`&&(0,$.jsx)(V,{intent:H.PRIMARY,children:(0,$.jsx)(`span`,{className:`text-xs`,children:r(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`)})}),(0,$.jsx)(K,{label:r(`account.newPassword`,`New Password`),children:(0,$.jsx)(ce,{content:r(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),isOpen:x,position:M.TOP,intent:H.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(W,{leftIcon:`lock`,type:y?`text`:`password`,value:_,onChange:e=>v(e.target.value),onFocus:()=>S(!0),onBlur:()=>S(!1),rightElement:(0,$.jsx)(L,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:r(y?`auth.hidePassword`:`auth.showPassword`)}),required:!0})})})}),(0,$.jsx)(L,{fill:!0,intent:o===`passkey`?H.PRIMARY:H.WARNING,type:`submit`,loading:C,icon:o===`passkey`?(0,$.jsx)(u,{size:16}):void 0,text:o===`passkey`?r(`account.changePasswordWithPasskey`,`Verify with Passkey & Update`):r(`account.updatePassword`,`Update Password`)})]})]})},Nt=({isOpen:e,onClose:t,user:r,onSuccess:i})=>{let{t:a}=d(),o=!!(r?.passkeys_count&&r.passkeys_count>0),s=!!r?.totp_enabled,[c,l]=(0,Q.useState)(`password`),[f,p]=(0,Q.useState)(``),[m,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(``),[C,w]=(0,Q.useState)(!1),[T,E]=(0,Q.useState)(``),D=(0,Q.useRef)(null),O=(0,Q.useRef)(null);(0,Q.useEffect)(()=>{c===`passkey`&&!o?l(s?`totp`:`password`):c===`totp`&&!s&&l(o?`passkey`:`password`)},[o,s,c]);let k=async(e,t)=>{if(e&&e.preventDefault(),f.length!==4||!qe.test(f)){E(a(`auth.pinFormatTip`,`PIN must be exactly 4 digits`));return}if(f!==m){E(a(`auth.pinMatchTip`,`PINs do not match`));return}w(!0),E(``);try{let e=r?.id||sessionStorage.getItem(`dns_worker_user_id`);if(!e){E(a(`auth.sessionExpired`,`Session expired. Logging out...`)),setTimeout(()=>{A()},1500);return}let n=await Pe(f,e),o={};if(c===`passkey`)o.passkeyAssertion=await fe(await Qe());else if(c===`totp`){let e=(t||x).replace(/\s/g,``);if(e.length!==6){E(a(`account.totp.invalidCode`,`Please enter a 6-digit code`)),w(!1);return}let n=crypto.randomUUID();o.totpTokenHash=await We(e,n),o.totpSalt=n}else{if(!_){E(a(`auth.passwordRequired`,`Password is required for verification`)),w(!1);return}let e=_;r?.password_version===2&&r?.username&&(e=await Ne(_,r.username)),o.password=e}await de(n,o),p(``),g(``),v(``),S(``),i()}catch(e){E(Je(e,a))}finally{w(!1)}},A=()=>{E(``),p(``),g(``),v(``),b(!1),S(``),l(`password`),t()};return(0,$.jsx)(R,{isOpen:e,onClose:A,title:r?.pin_enabled?a(`auth.changePin`,`Change PIN`):a(`auth.configurePin`,`Configure PIN`),icon:`key`,className:`pb-0`,style:{width:`420px`},children:(0,$.jsxs)(`form`,{onSubmit:k,children:[(0,$.jsxs)(`div`,{className:I,children:[T&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:T}),(0,$.jsx)(K,{label:a(`auth.newPin`,`New 4-Digit PIN`),labelFor:`new-pin-input`,helperText:a(`auth.pinHelper`,`Digits only, e.g., 1234`),children:(0,$.jsx)(Le,{length:4,value:f,onChange:p,type:`password`,disabled:C,autoFocus:!0,onComplete:()=>D.current?.focus()})}),(0,$.jsx)(K,{label:a(`auth.confirmPin`,`Confirm New PIN`),labelFor:`confirm-pin-input`,children:(0,$.jsx)(Le,{ref:D,length:4,value:m,onChange:g,type:`password`,disabled:C,onComplete:()=>{c===`totp`?O.current?.focus():c===`password`&&document.getElementById(`verify-pw-input`)?.focus()}})}),(0,$.jsx)(U,{className:`my-4`}),(0,$.jsxs)(`div`,{className:`mb-3 space-y-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm block`,children:a(`auth.verifyIdentity`,`Verify Identity`)}),(o||s)&&(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(L,{small:!0,active:c===`password`,intent:c===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),E(``)}}),o&&(0,$.jsx)(L,{small:!0,active:c===`passkey`,intent:c===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),E(``)}}),s&&(0,$.jsx)(L,{small:!0,active:c===`totp`,intent:c===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),E(``)}})]})})]}),c===`password`&&(0,$.jsx)(K,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`verify-pw-input`,children:(0,$.jsx)(W,{id:`verify-pw-input`,type:y?`text`:`password`,placeholder:a(`auth.passwordPlaceholder`,`Enter current password`),value:_,onChange:e=>v(e.target.value),leftIcon:`lock`,rightElement:(0,$.jsx)(L,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:y?a(`auth.hidePassword`,`Hide password`):a(`auth.showPassword`,`Show password`)}),required:!0})}),c===`totp`&&(0,$.jsx)(K,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`verify-totp-input`,children:(0,$.jsx)(Le,{ref:O,length:6,value:x,onChange:S,disabled:C,onComplete:e=>k(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(V,{intent:H.PRIMARY,icon:(0,$.jsx)(u,{size:16}),children:(0,$.jsx)(`span`,{className:`text-xs`,children:a(`account.passkey.submitNotice`,a(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`))})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:A,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.PRIMARY,loading:C,children:a(`common.save`,`Save`)})]})})]})})},Pt=({isOpen:e,onClose:t,user:r,onSuccess:i})=>{let{t:a}=d(),o=!!(r?.passkeys_count&&r.passkeys_count>0),s=!!r?.totp_enabled,[c,l]=(0,Q.useState)(`password`),[f,p]=(0,Q.useState)(``),[m,g]=(0,Q.useState)(!1),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(!1),[x,C]=(0,Q.useState)(``);(0,Q.useEffect)(()=>{c===`passkey`&&!o?l(s?`totp`:`password`):c===`totp`&&!s&&l(o?`passkey`:`password`)},[o,s,c]);let w=async(e,t)=>{e&&e.preventDefault(),b(!0),C(``);try{let e={};if(c===`passkey`)e.passkeyAssertion=await fe(await Qe());else if(c===`totp`){let n=(t||_).replace(/\s/g,``);if(n.length!==6){C(a(`account.totp.invalidCode`,`Please enter a 6-digit code`)),b(!1);return}let r=crypto.randomUUID();e.totpTokenHash=await We(n,r),e.totpSalt=r}else{if(!f){C(a(`auth.passwordRequired`,`Password is required for verification`)),b(!1);return}let t=f;r?.password_version===2&&r?.username&&(t=await Ne(f,r.username)),e.password=t}await He(e),p(``),v(``),i()}catch(e){C(Je(e,a))}finally{b(!1)}},T=()=>{C(``),p(``),g(!1),v(``),l(`password`),t()};return(0,$.jsx)(R,{isOpen:e,onClose:T,title:a(`auth.disablePin`,`Disable Session Lock`),icon:`trash`,className:`pb-0`,style:{width:`420px`},children:(0,$.jsxs)(`form`,{onSubmit:w,children:[(0,$.jsxs)(`div`,{className:I,children:[x&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-4`,children:x}),(0,$.jsx)(V,{intent:H.WARNING,className:`mb-4`,icon:(0,$.jsx)(S,{size:20}),children:a(`auth.disablePinWarning`,`Disabling the PIN will disable the inactivity session locking feature completely.`)}),(0,$.jsxs)(`div`,{className:`mb-3 space-y-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm block`,children:a(`auth.verifyIdentity`,`Verify Identity`)}),(o||s)&&(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(L,{small:!0,active:c===`password`,intent:c===`password`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),C(``)}}),o&&(0,$.jsx)(L,{small:!0,active:c===`passkey`,intent:c===`passkey`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),C(``)}}),s&&(0,$.jsx)(L,{small:!0,active:c===`totp`,intent:c===`totp`?H.PRIMARY:H.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),C(``)}})]})})]}),c===`password`&&(0,$.jsx)(K,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`disable-pw-input`,children:(0,$.jsx)(W,{id:`disable-pw-input`,type:m?`text`:`password`,placeholder:a(`auth.passwordPlaceholder`,`Enter current password`),value:f,onChange:e=>p(e.target.value),leftIcon:`lock`,rightElement:(0,$.jsx)(L,{minimal:!0,icon:m?`eye-open`:`eye-off`,onClick:()=>g(!m),title:m?a(`auth.hidePassword`,`Hide password`):a(`auth.showPassword`,`Show password`)}),required:!0})}),c===`totp`&&(0,$.jsx)(K,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`disable-totp-input`,children:(0,$.jsx)(Le,{length:6,value:_,onChange:v,disabled:y,onComplete:e=>w(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(V,{intent:H.PRIMARY,icon:(0,$.jsx)(u,{size:16}),children:(0,$.jsx)(`span`,{className:`text-xs`,children:a(`account.passkey.submitNotice`,a(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`))})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:T,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.DANGER,loading:y,children:a(`common.disable`,`Disable`)})]})})]})})},Ft=({user:e,onRefresh:t})=>{let{t:r}=d(),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(!1),u=!!e?.pin_enabled,f=e?.session_lock_timeout||15,p=async e=>{let n=Number(e.currentTarget.value);a(!0);try{await Te({session_lock_timeout:n}),t()}catch(e){console.error(`Failed to change session lock timeout`,e)}finally{a(!1)}},m=()=>{s(!0)};return(0,$.jsxs)(J,{elevation:F.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(n,{size:20,className:`text-indigo-600`}),(0,$.jsx)(G,{className:`m-0!`,children:r(`auth.sessionLockTitle`,`Idle Session Lock`)})]}),!u&&(0,$.jsx)(L,{icon:`key`,intent:H.PRIMARY,onClick:m,disabled:i,children:r(`auth.configurePin`,`Configure 4-Digit PIN`)})]}),(0,$.jsx)(`p`,{className:`text-gray-500 text-sm mb-4`,children:r(`auth.sessionLockDesc`,`Lock the interface with a 4-digit PIN when the application is idle to protect active sessions from unauthorized physical access.`)}),(0,$.jsx)(`div`,{className:`flex flex-col gap-4 mb-4`,children:(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsx)(`span`,{children:r(`auth.inactivityTimeout`,`Inactivity Timeout`)}),(0,$.jsx)(ie,{value:f,onChange:p,disabled:!u||i,options:[{label:r(`auth.timeout1m`,`1 Minute`),value:1},{label:r(`auth.timeout2m`,`2 Minutes`),value:2},{label:r(`auth.timeout5m`,`5 Minutes`),value:5},{label:r(`auth.timeout15m`,`15 Minutes`),value:15},{label:r(`auth.timeout30m`,`30 Minutes`),value:30},{label:r(`auth.timeout60m`,`60 Minutes`),value:60}]})]})}),u&&(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,$.jsx)(L,{icon:`edit`,onClick:m,disabled:i,children:r(`auth.changePin`,`Change PIN`)}),(0,$.jsx)(L,{icon:`trash`,intent:H.DANGER,onClick:()=>{l(!0)},disabled:i,children:r(`auth.disablePin`,`Disable PIN & Lock`)}),(0,$.jsx)(L,{icon:`lock`,intent:H.WARNING,onClick:async()=>{a(!0);try{await be(),window.dispatchEvent(new Event(`session_paused`))}catch(e){console.error(`Failed to lock session immediately`,e)}finally{a(!1)}},disabled:i,children:r(`auth.lockNow`,`Lock Now`)})]}),(0,$.jsx)(Nt,{isOpen:o,onClose:()=>s(!1),user:e,onSuccess:()=>{s(!1),t()}}),(0,$.jsx)(Pt,{isOpen:c,onClose:()=>l(!1),user:e,onSuccess:()=>{l(!1),t()}})]})};function It({user:e,onRefresh:t,toasterRef:n,setProcessing:r}){let{t:i}=d(),[a,o]=(0,Q.useState)(null),[s,c]=(0,Q.useState)(!0),[l,u]=(0,Q.useState)(!1),[f,p]=(0,Q.useState)(!1),m=(0,Q.useCallback)(async()=>{c(!0);try{o(await Z.getUserStatus()),u(Z.isUnlocked())}catch(e){console.error(`[useE2eeStatus] Failed to fetch E2EE status:`,e)}finally{c(!1)}},[]);(0,Q.useEffect)(()=>{m()},[m]);let h=e.passkeys_count&&e.passkeys_count>0||(a?.userPasskeyCount||0)>0,g=!!a?.enabled;return{status:a,loading:s,isUnlocked:l,setIsUnlocked:u,isPqc:(0,Q.useMemo)(()=>{if(!a?.publicKey)return!1;try{let e=JSON.parse(a.publicKey);return e.alg===`P256-MLKEM768`||!!e.pqc_pk}catch{return!1}},[a?.publicKey]),isLogsE2eeEnabled:g,hasPasskey:h,loadStatus:m,isDisableAlertOpen:f,setIsDisableAlertOpen:p,handleToggleLogs:async e=>{if(e){r(!0);try{await Z.enableUserE2ee(),n.current?.show({message:i(`account.e2ee.enableSuccess`),intent:H.SUCCESS,icon:`lock`}),await m(),t?.()}catch(e){console.error(`[useE2eeStatus] Failed to enable E2EE:`,e),n.current?.show({message:e.message||i(`account.e2ee.enableError`),intent:H.DANGER,icon:`error`})}finally{r(!1)}}else p(!0)},handleConfirmDisable:async()=>{r(!0);try{await Z.disableUserE2ee(),n.current?.show({message:i(`account.e2ee.disableSuccess`),intent:H.WARNING,icon:`unlock`}),await m(),t?.()}catch(e){console.error(`[useE2eeStatus] Failed to disable E2EE:`,e),n.current?.show({message:e.message||i(`account.e2ee.disableError`),intent:H.DANGER,icon:`error`})}finally{r(!1),p(!1)}},handleLockDevice:()=>{Z.clearStorage(),u(!1),n.current?.show({message:i(`account.e2ee.lockSuccess`,`已锁定,私钥已从本地清除`),intent:H.NONE})}}}function Lt({onRefresh:e,loadStatus:t,setIsUnlocked:n,toasterRef:r,setProcessing:i}){let{t:a}=d(),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(``),[u,f]=(0,Q.useState)(``),[p,m]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(null),[x,S]=(0,Q.useState)(!1);return{isRecoveryDialogOpen:o,setIsRecoveryDialogOpen:s,recoveryKeyInput:c,setRecoveryKeyInput:l,recoveryUnlockError:u,setRecoveryUnlockError:f,initRecoveryDialogOpen:p,setInitRecoveryDialogOpen:m,initRecoveryKeyInput:h,setInitRecoveryKeyInput:g,initRecoveryError:_,setInitRecoveryError:v,rotatedKey:y,setRotatedKey:b,copiedKey:x,handleUnlockWithRecoveryKey:async o=>{o.preventDefault();let u=c.trim();if(u){i(!0),f(``);try{await Z.unlockWithRecoveryKey(u);try{let e=await ze({recoveryKey:u});await Z.wrapCurrentKeyForRecovery(e.recovery_key),b(e.recovery_key)}catch(e){console.warn(`[useE2eeRecoveryDialogs] Recovery key auto-rotation failed:`,e)}n(!0),s(!1),l(``),r.current?.show({message:a(`account.e2ee.unlockSuccess`),intent:H.SUCCESS,icon:`tick`}),await t(),e?.()}catch(e){console.error(`[useE2eeRecoveryDialogs] Recovery unlock failed:`,e),f(e.message||a(`account.e2ee.recoveryUnlockFailed`))}finally{i(!1)}}},handleInitWithRecoveryKey:async o=>{o.preventDefault();let s=h.trim();if(s){i(!0),v(``);try{await Z.initUserE2eeWithRecoveryKey(s);try{let e=await ze({recoveryKey:s});await Z.wrapCurrentKeyForRecovery(e.recovery_key),b(e.recovery_key)}catch(e){console.warn(`[useE2eeRecoveryDialogs] Recovery key auto-rotation failed:`,e)}m(!1),g(``),n(!0),r.current?.show({message:a(`account.e2ee.keypairGenSuccess`),intent:H.SUCCESS,icon:`tick`}),await t(),e?.()}catch(e){console.error(`[useE2eeRecoveryDialogs] Init keypair with recovery key failed:`,e),v(e.message||a(`account.e2ee.initFailed`))}finally{i(!1)}}},handleCopyRotatedKey:e=>{navigator.clipboard.writeText(e),S(!0),setTimeout(()=>S(!1),2e3)}}}function Rt({hasPasskey:e,onRefresh:t,loadStatus:n,setIsUnlocked:r,setInitRecoveryDialogOpen:i,toasterRef:a,setProcessing:o}){let{t:s}=d(),[c,l]=(0,Q.useState)(!1);return{handleUnlock:async()=>{o(!0);try{await Z.unlockUser()&&(r(!0),a.current?.show({message:s(`account.e2ee.unlockSuccess`),intent:H.SUCCESS,icon:`tick`}))}catch(e){console.error(`[useE2eeActions] Failed to unlock private key:`,e),a.current?.show({message:e.message||s(`account.e2ee.unlockError`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},handleGenerateKeyWithPasskey:async()=>{o(!0);try{await Z.enableUserE2ee(),a.current?.show({message:s(`account.e2ee.keypairGenSuccess`),intent:H.SUCCESS,icon:`tick`}),await n(),t?.()}catch(e){console.error(`[useE2eeActions] Generate key with Passkey failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.keypairGenError`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},handleUpgradeToPqc:async()=>{o(!0);try{await Z.rotateUserE2eeKey(),a.current?.show({message:s(`account.e2ee.upgradePqcSuccess`,`已成功升级到后量子混合加密 (P256-MLKEM768)`),intent:H.SUCCESS,icon:`tick`}),await n(),t?.()}catch(e){console.error(`[useE2eeActions] Upgrade to PQC failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.upgradePqcError`,`升级到后量子加密失败`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},handleEnrollPasskey:async()=>{o(!0);try{let e=await me(),r=e.length>0?e[0].id:`primary`;if(await Z.wrapCurrentKeyForPasskey(r))a.current?.show({message:s(`account.e2ee.enrollPasskeySuccess`,`已成功将通行密钥关联至端到端加密!`),intent:H.SUCCESS,icon:`tick`}),await n(),t?.();else throw Error(s(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`))}catch(e){console.error(`[useE2eeActions] Enroll passkey failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`),intent:H.DANGER,icon:`error`})}finally{o(!1)}},isResetAlertOpen:c,setIsResetAlertOpen:l,handleResetAndReinit:async()=>{o(!0);try{await fetch(`/api/account/e2ee?purge=true`,{method:`DELETE`}),Z.clearStorage(),e?(await Z.enableUserE2ee(),a.current?.show({message:s(`account.e2ee.resetAndInitPasskeySuccess`,`密钥对已成功重置并使用通行密钥重新加密!`),intent:H.SUCCESS,icon:`tick`})):(a.current?.show({message:s(`account.e2ee.resetSuccessEnterRecovery`,`旧密钥已清除,请使用恢复密钥初始化新密钥对。`),intent:H.WARNING,icon:`refresh`}),i(!0)),await n(),t?.()}catch(e){console.error(`[useE2eeActions] Reset keypair failed:`,e),a.current?.show({message:e.message||s(`account.e2ee.resetFailed`,`重置密钥对失败`),intent:H.DANGER,icon:`error`})}finally{o(!1),l(!1)}}}}function zt({user:e,onRefresh:t,toasterRef:n}){let[r,i]=(0,Q.useState)(!1),a=It({user:e,onRefresh:t,toasterRef:n,setProcessing:i}),o=Lt({onRefresh:t,loadStatus:a.loadStatus,setIsUnlocked:a.setIsUnlocked,toasterRef:n,setProcessing:i}),s=Rt({hasPasskey:a.hasPasskey,onRefresh:t,loadStatus:a.loadStatus,setIsUnlocked:a.setIsUnlocked,setInitRecoveryDialogOpen:o.setInitRecoveryDialogOpen,toasterRef:n,setProcessing:i});return{status:a.status,loading:a.loading,processing:r,isUnlocked:a.isUnlocked,isPqc:a.isPqc,isLogsE2eeEnabled:a.isLogsE2eeEnabled,hasPasskey:a.hasPasskey,isDisableAlertOpen:a.isDisableAlertOpen,setIsDisableAlertOpen:a.setIsDisableAlertOpen,isRecoveryDialogOpen:o.isRecoveryDialogOpen,setIsRecoveryDialogOpen:o.setIsRecoveryDialogOpen,recoveryKeyInput:o.recoveryKeyInput,setRecoveryKeyInput:o.setRecoveryKeyInput,recoveryUnlockError:o.recoveryUnlockError,setRecoveryUnlockError:o.setRecoveryUnlockError,initRecoveryDialogOpen:o.initRecoveryDialogOpen,setInitRecoveryDialogOpen:o.setInitRecoveryDialogOpen,initRecoveryKeyInput:o.initRecoveryKeyInput,setInitRecoveryKeyInput:o.setInitRecoveryKeyInput,initRecoveryError:o.initRecoveryError,setInitRecoveryError:o.setInitRecoveryError,rotatedKey:o.rotatedKey,setRotatedKey:o.setRotatedKey,copiedKey:o.copiedKey,handleToggleLogs:a.handleToggleLogs,handleConfirmDisable:a.handleConfirmDisable,handleUnlock:s.handleUnlock,handleUnlockWithRecoveryKey:o.handleUnlockWithRecoveryKey,handleGenerateKeyWithPasskey:s.handleGenerateKeyWithPasskey,handleUpgradeToPqc:s.handleUpgradeToPqc,handleInitWithRecoveryKey:o.handleInitWithRecoveryKey,handleLockDevice:a.handleLockDevice,handleCopyRotatedKey:o.handleCopyRotatedKey,isResetAlertOpen:s.isResetAlertOpen,setIsResetAlertOpen:s.setIsResetAlertOpen,handleResetAndReinit:s.handleResetAndReinit,handleEnrollPasskey:s.handleEnrollPasskey}}const Bt=({isLogsE2eeEnabled:e})=>{let{t}=d();return(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(h,{size:20,className:e?`text-emerald-500`:`text-gray-400`}),(0,$.jsx)(G,{style:{margin:0},children:t(`account.e2ee.title`,`E2EE`)}),(0,$.jsx)(q,{intent:e?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:t(e?`account.e2ee.enabled`:`account.e2ee.disabled`)})]}),(0,$.jsx)(re,{placement:`bottom-end`,usePortal:!0,content:(0,$.jsxs)(`div`,{className:`p-4 max-w-sm`,children:[(0,$.jsx)(ne,{children:t(`account.e2ee.trustBoundaryTitle`)}),(0,$.jsx)(`p`,{className:`text-sm text-gray-700 dark:text-gray-300 m-0`,children:t(`account.e2ee.trustBoundaryDesc`,`All DNS query traffic inevitably passes through the hosting server (Cloudflare Workers edge nodes or self-hosted server runtime) during resolution, where queries are processed in memory before being encrypted and saved. This feature strictly protects data at rest in the cloud database (D1 / persistent storage) from data leaks or offline analysis; it does not conceal active network traffic from the hosting server processing the request.`)})]}),children:(0,$.jsx)(L,{icon:`help`,variant:`minimal`,intent:H.NONE})})]})},Vt=({hasPasskey:e,processing:n,onGenerateKeyWithPasskey:r,onOpenInitRecoveryDialog:i})=>{let{t:a}=d();return(0,$.jsx)(V,{intent:H.PRIMARY,icon:`shield`,className:`my-3 text-xs`,children:(0,$.jsxs)(`div`,{className:`space-y-3`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h5`,{className:`font-semibold text-sm mb-1 text-blue-900 dark:text-blue-100`,children:a(`account.e2ee.noKeypairTitle`)}),(0,$.jsx)(`p`,{className:`text-xs text-blue-800 dark:text-blue-200 m-0`,children:a(`account.e2ee.noKeypairDesc`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap pt-1`,children:[e?(0,$.jsx)(L,{intent:H.PRIMARY,small:!0,icon:(0,$.jsx)(t,{size:14}),text:a(`account.e2ee.initPasskeyBtn`),loading:n,onClick:r}):(0,$.jsx)(L,{intent:H.PRIMARY,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.addPasskeyBtn`),onClick:()=>{document.getElementById(`passkeys-section`)?.scrollIntoView({behavior:`smooth`})}}),(0,$.jsx)(L,{intent:H.NONE,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.initRecoveryBtn`),onClick:i})]})]})})},Ht=({status:e,isLogsE2eeEnabled:r,isUnlocked:i,isPqc:a,hasPasskey:o,processing:s,loading:c,onToggleLogs:l,onUpgradeToPqc:u,onLockDevice:p,onUnlockPasskey:m,onOpenRecoveryUnlockDialog:h,onEnrollPasskey:g,onOpenResetAlert:_})=>{let{t:v}=d();return(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(U,{className:`my-2`}),(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-4 p-4 rounded-lg border border-gray-200 dark:border-gray-800 bg-gray-50/70 dark:bg-gray-900/50`,children:[(0,$.jsxs)(`div`,{className:`space-y-1`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm text-gray-900 dark:text-gray-100`,children:v(`account.e2ee.enableSwitch`)}),(0,$.jsx)(q,{intent:r?H.SUCCESS:H.NONE,minimal:!0,round:!0,children:v(r?`account.e2ee.enabled`:`account.e2ee.disabled`)})]}),(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 m-0`,children:v(`account.e2ee.enableSwitchDesc`)})]}),(0,$.jsx)(`div`,{className:`shrink-0 flex items-center`,children:(0,$.jsx)(ae,{checked:r,disabled:s||c,onChange:e=>l(e.currentTarget.checked),large:!0,className:`mb-0`})})]}),(0,$.jsxs)(`div`,{className:`pt-2 border-t border-gray-100 dark:border-gray-800/80 space-y-2 text-xs`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsxs)(`span`,{className:`opacity-70 flex items-center gap-1.5`,children:[(0,$.jsx)(t,{size:13}),v(`account.e2ee.keyType`),`:`]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,$.jsx)(`span`,{className:`font-mono`,children:a?`P256-MLKEM768 + AES-256-GCM`:`ECDH P-256 + AES-256-GCM`}),a?(0,$.jsx)(q,{minimal:!0,intent:H.PRIMARY,className:`text-[10px]`,children:v(`account.e2ee.pqcTag`,`PQC / NIST FIPS 203`)}):(0,$.jsx)(L,{small:!0,intent:H.PRIMARY,minimal:!0,icon:(0,$.jsx)(f,{size:12}),text:v(`account.e2ee.upgradePqcBtn`,`升级到后量子 (PQC)`),loading:s,onClick:u})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsxs)(`span`,{className:`opacity-70 flex items-center gap-1.5`,children:[(0,$.jsx)(n,{size:13}),v(`account.e2ee.deviceState`),`:`]}),i?(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap justify-end`,children:[(0,$.jsx)(q,{minimal:!0,intent:H.SUCCESS,className:`text-[10px]`,children:v(`account.e2ee.unlocked`)}),o&&(e?.wrappedPasskeys?.length||0)===0&&g&&(0,$.jsx)(L,{small:!0,intent:H.PRIMARY,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.enrollPasskeyBtn`,`关联当前通行密钥`),loading:s,onClick:g}),(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.NONE,icon:`lock`,text:v(`account.e2ee.lockDevice`,`锁定此设备`),onClick:p})]}):(0,$.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap justify-end`,children:[o&&(e?.wrappedPasskeys?.length||0)>0&&(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.PRIMARY,icon:(0,$.jsx)(f,{size:12}),text:v(`account.e2ee.unlockButton`),loading:s,onClick:m}),(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.NONE,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.unlockRecoveryButton`),onClick:h}),_&&(0,$.jsx)(L,{small:!0,minimal:!0,intent:H.DANGER,icon:`reset`,text:v(`account.e2ee.resetKeypairBtn`,`重置密钥对`),onClick:_})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,$.jsxs)(`span`,{className:`opacity-70`,children:[v(`account.e2ee.protectedPasskeys`),`:`]}),(0,$.jsxs)(`span`,{className:`font-mono`,children:[e?.wrappedPasskeys?.length||0,` `,v(`account.e2ee.devicesUnit`)]})]})]})]})},Ut=({isOpen:e,processing:t,onConfirm:n,onCancel:r})=>{let{t:i}=d();return(0,$.jsx)(P,{isOpen:e,confirmButtonText:i(`common.confirmDisable`),cancelButtonText:i(`common.cancel`),intent:H.DANGER,icon:`unlock`,onConfirm:n,onCancel:r,loading:t,children:(0,$.jsx)(`p`,{children:i(`account.e2ee.disableConfirm`)})})},Wt=({isOpen:e,onClose:t,recoveryKeyInput:n,setRecoveryKeyInput:r,recoveryUnlockError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(R,{isOpen:e,onClose:t,title:s(`account.e2ee.unlockWithRecoveryTitle`),icon:`key`,className:`dark:bg-gray-900`,children:(0,$.jsxs)(`form`,{onSubmit:o,autoComplete:`off`,children:[(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.unlockWithRecoveryDesc`)}),i&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(K,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`recovery-key-input`,children:(0,$.jsx)(W,{id:`recovery-key-input`,name:`recovery_key_input`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:n,onChange:e=>r(e.target.value),leftIcon:`key`,className:`font-mono text-xs`,autoFocus:!0})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.unlockConfirm`)})]})})]})})},Gt=({isOpen:e,onClose:t,initRecoveryKeyInput:n,setInitRecoveryKeyInput:r,initRecoveryError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(R,{isOpen:e,onClose:t,title:s(`account.e2ee.initWithRecoveryTitle`),icon:`key`,className:`dark:bg-gray-900`,children:(0,$.jsxs)(`form`,{onSubmit:o,autoComplete:`off`,children:[(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.initWithRecoveryDesc`)}),i&&(0,$.jsx)(V,{intent:H.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(K,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`init-recovery-key-input`,children:(0,$.jsx)(W,{id:`init-recovery-key-input`,name:`init_recovery_key_input`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:n,onChange:e=>r(e.target.value),leftIcon:`key`,className:`font-mono text-xs`,autoFocus:!0})})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsxs)(`div`,{className:Y,children:[(0,$.jsx)(L,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(L,{type:`submit`,intent:H.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.generateKeypairBtn`)})]})})]})})},Kt=({rotatedKey:e,onClose:t,copiedKey:n,onCopyKey:r})=>{let{t:i}=d();return(0,$.jsxs)(R,{isOpen:!!e,onClose:t,title:i(`account.recoveryKey.autoRotatedTitle`),icon:`warning-sign`,isCloseButtonShown:!1,canOutsideClickClose:!1,className:`dark:bg-gray-900`,children:[(0,$.jsxs)(`div`,{className:I,children:[(0,$.jsx)(V,{intent:H.WARNING,icon:(0,$.jsx)(S,{size:16}),className:`mb-4 text-xs`,children:i(`account.recoveryKey.autoRotatedNotice`)}),e&&(0,$.jsxs)(`div`,{className:`space-y-3`,children:[(0,$.jsx)(`div`,{className:`p-3 bg-gray-100 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 font-mono text-center text-lg font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:e}),(0,$.jsx)(`div`,{className:`flex justify-center`,children:(0,$.jsx)(L,{intent:H.PRIMARY,icon:n?(0,$.jsx)(y,{size:14,className:`text-green-400`}):(0,$.jsx)(w,{size:14}),text:i(n?`common.copied`:`common.copyKey`),onClick:()=>r(e)})})]})]}),(0,$.jsx)(`div`,{className:B,children:(0,$.jsx)(`div`,{className:Y,children:(0,$.jsx)(L,{intent:H.SUCCESS,onClick:t,text:i(`account.recoveryKey.savedAndClose`)})})})]})},qt=({isOpen:e,processing:t,hasPasskey:n,onConfirm:r,onCancel:i})=>{let{t:a}=d();return(0,$.jsx)(P,{isOpen:e,confirmButtonText:a(`account.e2ee.confirmResetBtn`,`确认重置并重新生成`),cancelButtonText:a(`common.cancel`,`取消`),intent:H.DANGER,icon:`reset`,onConfirm:r,onCancel:i,loading:t,children:(0,$.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,$.jsx)(`p`,{className:`font-semibold text-gray-900 dark:text-gray-100`,children:a(`account.e2ee.resetKeypairTitle`,`重置端到端加密密钥对`)}),(0,$.jsx)(`p`,{children:a(`account.e2ee.resetKeypairDesc`,`如果您的恢复密钥不匹配或无法解密,且未关联通行密钥,重置密钥对将从服务端清除旧密钥,并为您重新生成全新的后量子 (P256-MLKEM768) 密钥对。`)}),(0,$.jsx)(`p`,{className:`text-gray-500 dark:text-gray-400`,children:n?a(`account.e2ee.resetKeypairPasskeyNotice`,`确认后将立即调用您当前已配置的通行密钥 (Passkey) 完成新密钥对的加密与授权。`):a(`account.e2ee.resetKeypairRecoveryNotice`,`确认后将引导您输入当前恢复密钥以完成新密钥对的生成与加密。`)})]})})},Jt=({user:e,onRefresh:t})=>{let{t:n}=d(),r=(0,Q.useRef)(null),{status:i,loading:a,processing:o,isUnlocked:s,isPqc:c,isLogsE2eeEnabled:l,hasPasskey:u,isDisableAlertOpen:f,setIsDisableAlertOpen:p,isRecoveryDialogOpen:m,setIsRecoveryDialogOpen:h,recoveryKeyInput:g,setRecoveryKeyInput:_,recoveryUnlockError:v,initRecoveryDialogOpen:y,setInitRecoveryDialogOpen:b,initRecoveryKeyInput:x,setInitRecoveryKeyInput:S,initRecoveryError:C,setInitRecoveryError:w,rotatedKey:T,setRotatedKey:E,copiedKey:D,handleToggleLogs:O,handleConfirmDisable:k,handleUnlock:A,handleUnlockWithRecoveryKey:j,handleGenerateKeyWithPasskey:ee,handleUpgradeToPqc:M,handleInitWithRecoveryKey:N,handleLockDevice:P,handleCopyRotatedKey:te,isResetAlertOpen:I,setIsResetAlertOpen:ne,handleResetAndReinit:L,handleEnrollPasskey:R}=zt({user:e,onRefresh:t,toasterRef:r});return(0,$.jsxs)(J,{elevation:F.ONE,className:`space-y-6`,children:[(0,$.jsx)(oe,{ref:r}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(Bt,{isLogsE2eeEnabled:l}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-3`,children:n(`account.e2ee.desc`)}),a?(0,$.jsx)(`div`,{className:`flex items-center justify-center p-6`,children:(0,$.jsx)(z,{size:20})}):i?.hasKeys?(0,$.jsx)(Ht,{status:i,isLogsE2eeEnabled:l,isUnlocked:s,isPqc:c,hasPasskey:u,processing:o,loading:a,onToggleLogs:O,onUpgradeToPqc:M,onLockDevice:P,onUnlockPasskey:A,onOpenRecoveryUnlockDialog:()=>{_(``),h(!0)},onEnrollPasskey:R,onOpenResetAlert:()=>ne(!0)}):(0,$.jsx)(Vt,{hasPasskey:u,processing:o,onGenerateKeyWithPasskey:ee,onOpenInitRecoveryDialog:()=>{w(``),S(``),b(!0)}})]}),(0,$.jsx)(Ut,{isOpen:f,processing:o,onConfirm:k,onCancel:()=>p(!1)}),(0,$.jsx)(qt,{isOpen:I,processing:o,hasPasskey:u,onConfirm:L,onCancel:()=>ne(!1)}),(0,$.jsx)(Wt,{isOpen:m,onClose:()=>h(!1),recoveryKeyInput:g,setRecoveryKeyInput:_,recoveryUnlockError:v,processing:o,onSubmit:j}),(0,$.jsx)(Gt,{isOpen:y,onClose:()=>b(!1),initRecoveryKeyInput:x,setInitRecoveryKeyInput:S,initRecoveryError:C,processing:o,onSubmit:N}),(0,$.jsx)(Kt,{rotatedKey:T,onClose:()=>E(null),copiedKey:D,onCopyKey:te})]})},Yt=()=>{let[e,t]=(0,Q.useState)(null),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(null),{t:l,i18n:u}=d(),f=ue(),[m,h]=(0,Q.useState)(!1),[g,_]=(0,Q.useState)(``),[v,y]=(0,Q.useState)(!1),[b,x]=(0,Q.useState)(!1),[S,C]=(0,Q.useState)({}),w=async()=>{try{i(await ke())}catch(e){console.error(e)}},T=async()=>{try{C(await Xe())}catch(e){console.error(e)}},E=(0,Q.useCallback)(async()=>{try{let e=await Me();if(t(e),_(e.username),window.dispatchEvent(new Event(`user_updated`)),e.timezone){let{setSystemTimeZone:t}=await j(async()=>{let{setSystemTimeZone:e}=await import(`./date-DG8jTrEB.js`);return{setSystemTimeZone:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));t(e.timezone)}if(e.locale){let{setSystemLocale:t}=await j(async()=>{let{setSystemLocale:e}=await import(`./date-DG8jTrEB.js`);return{setSystemLocale:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));t(e.locale),u.changeLanguage(e.locale)}e.role===`admin`&&(w(),T())}catch(e){console.error(e)}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{E()},[E]),a?(0,$.jsx)(`div`,{className:`p-8 text-center`,children:l(`common.loading`)}):(0,$.jsxs)(`div`,{className:le(`max-w-5xl mx-auto space-y-8`,f?`p-0`:`px-8`),children:[(0,$.jsxs)(`div`,{className:`flex justify-between items-end`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h2`,{className:`bp6-heading`,children:l(`account.title`)}),(0,$.jsx)(`p`,{className:`bp6-text-muted`,children:l(`account.subtitle`)})]}),e&&(0,$.jsx)(q,{large:!0,round:!0,intent:e.role===`admin`?H.DANGER:H.PRIMARY,icon:(0,$.jsx)(n,{size:16}),children:e.role===`admin`?l(`account.roleAdmin`):l(`account.roleUser`)})]}),e?.role===`admin`&&e?.jwt_secret_warning&&(0,$.jsx)(V,{intent:H.WARNING,icon:(0,$.jsx)(p,{size:18}),title:l(`account.jwtSecretWarningTitle`),children:(0,$.jsx)(`div`,{className:`text-sm leading-relaxed mt-1`,children:l(`account.jwtSecretWarningDesc`)})}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,$.jsx)(jt,{me:e,isEditingUsername:m,setIsEditingUsername:h,editUsername:g,setEditUsername:_,usernameLoading:v,usernameFocused:b,setUsernameFocused:x,onUpdateUsername:async()=>{if(g===e?.username){h(!1);return}if(!Be.test(g)){alert(l(`account.formatTipUsername`));return}y(!0);try{await Te({username:g}),t(e=>e?{...e,username:g}:null),h(!1)}catch(e){console.error(e),alert(e.message||l(`common.errorNetwork`))}finally{y(!1)}},onUpdateTimezone:async e=>{try{await Te({timezone:e||``}),t(t=>t?{...t,timezone:e}:null);let{setSystemTimeZone:n}=await j(async()=>{let{setSystemTimeZone:e}=await import(`./date-DG8jTrEB.js`);return{setSystemTimeZone:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));n(e||``)}catch(e){console.error(e),alert(e.message||l(`common.errorNetwork`))}}}),(0,$.jsx)(Mt,{me:e,onRefresh:E})]}),e&&(0,$.jsx)(bt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Jt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Ft,{user:e,onRefresh:E}),e&&(0,$.jsx)(Et,{hoveredSessionId:s,setHoveredSessionId:c}),e&&(0,$.jsx)(Tt,{hoveredSessionId:s,setHoveredSessionId:c}),e?.role===`admin`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(U,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(Dt,{users:r,currentUserId:e.id,onRefresh:w,registrationEnabled:S.registration_enabled!==`false`,onRefreshSettings:T})}),(0,$.jsx)(U,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(Ot,{initialSettings:S,onRefresh:T})})]}),(0,$.jsx)(U,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(kt,{isAdmin:e?.role===`admin`})})]})};export{Yt as AccountView};
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TrendChart-wcrIRt7R.js","assets/index-CrB_HdIL.js","assets/vendor-icons-other-BTYC6Wvz.js","assets/vendor-icons-16-BgwRBCeU.js","assets/rolldown-runtime-C4Xdq4VV.js","assets/vendor-icons-20-X5NPN60g.js","assets/vendor-react-De1zEwOV.js","assets/vendor-i18next-CevVzhh3.js","assets/vendor-ui-core-ClwQiwMI.js","assets/vendor-utils-rmW6cqPl.js","assets/index-DZNm9qiP.css","assets/DestinationMap-Bwv9zW4k.js","assets/formatCountryName-JTcoEopY.js","assets/getFlagEmoji-DiZiGyWX.js"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{D as t,L as n,Qt as r,j as i,q as a,tt as o,v as s,vt as c}from"./vendor-react-De1zEwOV.js";import{S as l,b as u,x as d}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{C as f,H as p,M as m,N as h,P as g,T as _,V as v,d as y,f as b,o as x,p as S,r as C,u as w,x as T}from"./vendor-ui-core-ClwQiwMI.js";import{_t as E}from"./vendor-utils-rmW6cqPl.js";import{$t as D,Q as O,X as k,Z as A,x as j,y as M}from"./index-CrB_HdIL.js";import{t as N}from"./getFlagEmoji-DiZiGyWX.js";var P=e(l(),1);function F(e,t,n){if(!e)return[];let r={},i=Math.floor(Date.now()/1e3),a,o;switch(t){case`10m`:o=60,a=i-600;break;case`1h`:o=60,a=i-3600;break;case`24h`:o=3600,a=i-24*3600;break;case`7d`:o=86400,a=i-7*86400;break;case`30d`:o=86400,a=i-30*86400;break;case`custom`:if(o=3600,n.start&&n.end)a=Math.floor(new Date(n.start).getTime()/1e3),i=Math.floor(new Date(n.end).getTime()/1e3);else{let t=e.trend.map(e=>e.timestamp);a=t.length?Math.min(...t):i-86400,i=t.length?Math.max(...t):i}break;default:o=3600,a=i-24*3600}a=Math.floor(a/o)*o,i=Math.floor(i/o)*o;for(let e=a;e<=i;e+=o)r[e]={timestamp:e,allowed:0,blocked:0,redirected:0};return e.trend.forEach(e=>{let t=Math.floor(e.timestamp/o)*o;r[t]||(r[t]={timestamp:t,allowed:0,blocked:0,redirected:0}),e.action===`PASS`?r[t].allowed+=e.count:e.action===`BLOCK`?r[t].blocked+=e.count:e.action===`REDIRECT`&&(r[t].redirected+=e.count)}),Object.keys(r).sort((e,t)=>Number(e)-Number(t)).map(e=>r[Number(e)])}var I=e(u(),1);const L=({title:e,data:t,intent:n})=>{let{t:i}=r(),a=[{key:`rank`,cellClassName:`w-8 opacity-30 font-mono text-xs`,render:(e,t)=>t+1},{key:`domain`,cellClassName:`font-medium text-sm truncate max-w-50`,render:e=>e.domain},{key:`count`,cellClassName:`text-right`,render:e=>(0,I.jsx)(C,{minimal:!0,intent:n,className:`font-bold`,children:e.count})}];return(0,I.jsxs)(T,{elevation:p.ZERO,className:`dark:bg-gray-900 dark:border-gray-800 border border-gray-100 shadow-sm`,children:[(0,I.jsx)(m,{className:`mb-4 font-bold`,children:e}),(0,I.jsx)(w,{striped:!0,className:`w-full`,children:(0,I.jsxs)(`tbody`,{children:[t.map((e,t)=>(0,I.jsx)(`tr`,{children:a.map(n=>(0,I.jsx)(`td`,{className:n.cellClassName,children:n.render(e,t)},n.key))},t)),t.length===0&&(0,I.jsx)(`tr`,{children:(0,I.jsx)(`td`,{colSpan:a.length,className:`text-center py-8 opacity-50`,children:i(`analytics.noData`)})})]})})]})};function R(e){let[t,n]=(0,P.useState)(null),[r,i]=(0,P.useState)(!0),[a,o]=(0,P.useState)(`24h`),[s,c]=(0,P.useState)({start:``,end:``}),[l,u]=(0,P.useState)(null),[d,f]=(0,P.useState)([]),[p,m]=(0,P.useState)(30);(0,P.useEffect)(()=>{k(e).then(e=>f(e)).catch(e=>console.error(`[useAnalyticsData] Failed to load access points:`,e))},[e]),(0,P.useEffect)(()=>{O(e).then(e=>{try{let t=JSON.parse(e.settings||`{}`);m(t.log_retention_days===void 0?30:Number(t.log_retention_days))}catch(e){console.error(`[useAnalyticsData] Failed to parse settings:`,e)}}).catch(e=>console.error(`[useAnalyticsData] Failed to fetch profile settings:`,e))},[e]);let h=(0,P.useCallback)(async(t,r,a,o)=>{i(!0);let s=Math.floor(Date.now()/1e3),c,l=s,u;if(t===`custom`&&r&&a){c=Math.floor(new Date(r).getTime()/1e3),l=Math.floor(new Date(a).getTime()/1e3);let e=l-c;u=e<=7200?60:e<=172800?3600:86400}else switch(t){case`10m`:c=s-600,u=60;break;case`1h`:c=s-3600,u=60;break;case`24h`:c=s-86400,u=3600;break;case`7d`:c=s-604800,u=86400;break;case`30d`:c=s-2592e3,u=86400;break;default:c=s-86400,u=3600;break}try{j.isUnlocked()&&await M.reDecryptLocalLogs(e)}catch{}try{if(await M.init()){let t=await M.queryAnalytics({profileId:e,since:c,until:l,bucketSec:u,accessPointId:o||void 0});t.summary.some(e=>e.count>0)&&(n(t),i(!1))}}catch(e){console.warn(`[useAnalyticsData] Local SQLite preview failed:`,e)}try{let i=`?range=${t}`;t===`custom`&&r&&a&&(i+=`&start=${c}&end=${l}`),o&&(i+=`&access_point_id=${o}`);let s=null;try{s=await A(e,``,i)}catch{let[t,n,r,a,o,c]=await Promise.all([A(e,`summary`,i),A(e,`trend`,i),A(e,`top_allowed`,i),A(e,`top_blocked`,i),A(e,`clients`,i),A(e,`destinations`,i)]);s={summary:t,trend:n,top_allowed:r,top_blocked:a,clients:o,destinations:c}}s&&n(e=>{let t=e&&(e.top_allowed.some(e=>e.domain&&e.domain!==`[Encrypted]`&&e.domain!==`[Decryption Failed]`)||e.destinations&&e.destinations.length>0);return{...s,trend:s.trend||[],summary:s.summary||[],top_allowed:t&&e?.top_allowed.length?e.top_allowed:s.top_allowed||[],top_blocked:t&&e?.top_blocked.length?e.top_blocked:s.top_blocked||[],clients:t&&e?.clients.length?e.clients:s.clients||[],destinations:(t||(s.destinations||[]).length===0)&&e?.destinations?.length?e.destinations:s.destinations||[]}})}catch(e){console.error(`[useAnalyticsData] Failed to fetch server analytics:`,e)}finally{i(!1)}try{M.syncProfileLogs(e,void 0,c).then(async t=>{if(t>0)try{let t=await M.queryAnalytics({profileId:e,since:c,until:l,bucketSec:u,accessPointId:o||void 0});(t.destinations?.length>0||t.top_allowed?.length>0)&&n(e=>e?{...e,destinations:t.destinations.length>0?t.destinations:e.destinations,top_allowed:t.top_allowed.length>0?t.top_allowed:e.top_allowed,top_blocked:t.top_blocked.length>0?t.top_blocked:e.top_blocked,clients:t.clients.length>0?t.clients:e.clients}:t)}catch{}}).catch(e=>{console.warn(`[useAnalyticsData] Background sync error:`,e)})}catch{}},[e]);return(0,P.useEffect)(()=>{a!==`custom`&&h(a,void 0,void 0,l)},[a,l,h]),{data:t,loading:r,range:a,setRange:o,customRange:s,setCustomRange:c,accessPointIdFilter:l,setAccessPointIdFilter:u,accessPoints:d,logRetentionDays:p,fetchData:h}}var z=[{key:`10m`,days:.007},{key:`1h`,days:.0416},{key:`24h`,days:1},{key:`7d`,days:7},{key:`30d`,days:30}];const B=({range:e,setRange:t,customRange:n,setCustomRange:i,logRetentionDays:a,accessPoints:o,accessPointIdFilter:s,setAccessPointIdFilter:l,loading:u,onApplyCustom:d})=>{let{t:p}=r(),x=new Date().toLocaleString(`sv-SE`).replace(` `,`T`).slice(0,16);return(0,I.jsxs)(`div`,{className:`flex justify-between items-center bg-white dark:bg-gray-900 p-2 rounded-lg shadow-sm border border-gray-100 dark:border-gray-800`,children:[(0,I.jsxs)(f,{variant:`minimal`,children:[z.filter(e=>e.days<=a).map(e=>e.key).map(n=>(0,I.jsx)(h,{active:e===n,onClick:()=>t(n),text:n.toUpperCase()},n)),(0,I.jsx)(_,{content:(0,I.jsxs)(`div`,{className:`p-4 space-y-4 w-64`,children:[(0,I.jsx)(m,{children:p(`analytics.customRange`)}),(0,I.jsx)(S,{label:p(`analytics.startTime`),children:(0,I.jsx)(b,{type:`datetime-local`,max:n.end||x,value:n.start,onChange:e=>i({...n,start:e.target.value})})}),(0,I.jsx)(S,{label:p(`analytics.endTime`),children:(0,I.jsx)(b,{type:`datetime-local`,min:n.start,max:x,value:n.end,onChange:e=>i({...n,end:e.target.value})})}),(0,I.jsx)(h,{fill:!0,intent:v.PRIMARY,text:p(`analytics.apply`),onClick:d})]}),children:(0,I.jsx)(h,{active:e===`custom`,icon:(0,I.jsx)(c,{size:14,className:`mr-1`}),text:p(`analytics.custom`)})})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-4`,children:[o.length>0&&(0,I.jsx)(y,{value:s||``,onChange:e=>l(e.target.value||null),options:[{label:`${p(`logs.allAccessPoint`)}`,value:``},...o.map(e=>({label:e.name,value:e.id}))],minimal:!0}),u&&(0,I.jsx)(g,{size:16})]})]})},V=({title:e,value:t,icon:n})=>(0,I.jsxs)(T,{elevation:p.ZERO,className:`flex items-center gap-4 p-4 dark:bg-gray-900 dark:border-gray-800 border border-gray-100 shadow-sm`,children:[(0,I.jsx)(`div`,{className:`p-3 bg-gray-50 dark:bg-gray-800 rounded-lg`,children:n}),(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`div`,{className:`text-xs text-gray-500 font-medium uppercase tracking-wider`,children:e}),(0,I.jsx)(`div`,{className:`text-xl font-bold dark:text-white`,children:t})]})]}),H=({data:e})=>{let{t:a}=r(),c=e?.summary.reduce((e,t)=>e+t.count,0)||0,l=e?.summary.find(e=>e.action===`BLOCK`)?.count||0,u=e?.summary.find(e=>e.action===`REDIRECT`)?.count||0,d=c>0?(l/c*100).toFixed(1):`0.0`;return(0,I.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-2 lg:gap-4`,children:[{title:a(`analytics.totalQueries`),value:c.toLocaleString(),icon:(0,I.jsx)(s,{className:`text-blue-500`,size:20})},{title:a(`analytics.blocked`),value:l.toLocaleString(),icon:(0,I.jsx)(i,{className:`text-red-500`,size:20})},{title:a(`analytics.redirected`),value:u.toLocaleString(),icon:(0,I.jsx)(n,{className:`text-amber-500`,size:20})},{title:a(`analytics.blockRate`),value:`${d}%`,icon:(0,I.jsx)(t,{className:`text-green-500`,size:20})},{title:a(`analytics.activeIPs`),value:e?.clients.length.toString()||`0`,icon:(0,I.jsx)(o,{className:`text-purple-500`,size:20})}].map((e,t)=>(0,I.jsx)(V,{title:e.title,value:e.value,icon:e.icon},t))})},U=({clients:e})=>{let{t}=r();return(0,I.jsx)(x,{title:t(`analytics.clientActivity`),icon:(0,I.jsx)(o,{size:16}),children:(0,I.jsxs)(w,{striped:!0,className:`w-full mt-2`,children:[(0,I.jsx)(`thead`,{children:(0,I.jsxs)(`tr`,{children:[(0,I.jsx)(`th`,{className:`text-xs uppercase opacity-60`,children:t(`analytics.ipAddress`)}),(0,I.jsx)(`th`,{className:`text-xs uppercase opacity-60`,children:t(`analytics.location`)}),(0,I.jsx)(`th`,{className:`text-xs uppercase opacity-60 text-right`,children:t(`analytics.queries`)})]})}),(0,I.jsxs)(`tbody`,{children:[e?.map((e,t)=>(0,I.jsxs)(`tr`,{children:[(0,I.jsx)(`td`,{className:`font-mono text-xs`,children:e.client_ip||`-`}),(0,I.jsx)(`td`,{children:(0,I.jsx)(C,{minimal:!0,children:N(e.geo_country)})}),(0,I.jsx)(`td`,{className:`text-right font-bold`,children:e.count})]},t)),(!e||e.length===0)&&(0,I.jsx)(`tr`,{children:(0,I.jsx)(`td`,{colSpan:3,className:`text-center py-8 opacity-50`,children:t(`analytics.noData`)})})]})]})})};var W=(0,P.lazy)(()=>d(()=>import(`./TrendChart-wcrIRt7R.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10])).then(e=>({default:e.TrendChart}))),G=(0,P.lazy)(()=>d(()=>import(`./DestinationMap-Bwv9zW4k.js`),__vite__mapDeps([11,1,2,3,4,5,6,7,8,9,10,12,13])).then(e=>({default:e.DestinationMap}))),K=()=>(0,I.jsx)(`div`,{className:`h-64 flex items-center justify-center`,children:(0,I.jsx)(g,{size:30})});const q=({profileId:e})=>{let{t}=r(),n=D(),{data:i,loading:o,range:s,setRange:c,customRange:l,setCustomRange:u,accessPointIdFilter:d,setAccessPointIdFilter:f,accessPoints:h,logRetentionDays:_,fetchData:y}=R(e);if(o&&!i)return(0,I.jsx)(`div`,{className:`p-20 flex justify-center`,children:(0,I.jsx)(g,{size:50})});let b=F(i,s,l);return(0,I.jsxs)(`div`,{className:E(`max-w-7xl mx-auto space-y-6`,n?`p-0`:`p-6`),children:[(0,I.jsx)(B,{range:s,setRange:c,customRange:l,setCustomRange:u,logRetentionDays:_,accessPoints:h,accessPointIdFilter:d,setAccessPointIdFilter:f,loading:o,onApplyCustom:()=>{c(`custom`),y(`custom`,l.start,l.end,d)}}),(0,I.jsx)(H,{data:i}),(0,I.jsxs)(T,{elevation:p.ONE,className:`dark:bg-gray-900 dark:border-gray-800 relative`,children:[(0,I.jsxs)(m,{className:`mb-4 font-bold flex items-center gap-2`,children:[t(`analytics.queryTrend`),(0,I.jsx)(C,{minimal:!0,round:!0,children:s===`custom`?t(`analytics.custom`):s.toUpperCase()})]}),(0,I.jsx)(P.Suspense,{fallback:(0,I.jsx)(K,{}),children:(0,I.jsx)(W,{chartData:b,range:s})})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-6`,children:[(0,I.jsx)(L,{title:t(`analytics.topAllowed`),data:i?.top_allowed||[],intent:v.SUCCESS}),(0,I.jsx)(L,{title:t(`analytics.topBlocked`),data:i?.top_blocked||[],intent:v.DANGER})]}),(0,I.jsxs)(`div`,{className:`grid gap-6 grid-cols-1`,children:[(0,I.jsx)(x,{title:t(`analytics.destinationDistribution`),icon:(0,I.jsx)(a,{size:16}),children:(0,I.jsx)(P.Suspense,{fallback:(0,I.jsx)(K,{}),children:(0,I.jsx)(G,{destinations:i?.destinations||[],profileId:e||``,range:s,customRange:l,accessPointId:d||void 0})})}),(0,I.jsx)(U,{clients:i?.clients})]})]})};export{q as AnalyticsView};
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{L as t,Qt as n,_ as r,d as i,f as a,g as o,i as s,m as c,p as l,r as u,u as d,y as f}from"./vendor-react-De1zEwOV.js";import{S as p,b as m}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import"./vendor-utils-rmW6cqPl.js";import{Z as h,k as g,y as _}from"./index-CrB_HdIL.js";import{n as v,t as y}from"./formatCountryName-JTcoEopY.js";import{t as b}from"./getFlagEmoji-DiZiGyWX.js";var x=e(p(),1);function S(e){let[t,n]=(0,x.useState)(null);(0,x.useEffect)(()=>{g().then(e=>{if(e&&e.objects){let t={};e.objects.countries&&(t.countries=e.objects.countries),e.objects.land&&(t.land=e.objects.land),e.objects=t}e&&e.objects&&e.objects.countries&&Array.isArray(e.objects.countries.geometries)&&e.objects.countries.geometries.forEach(e=>{e.id!==void 0&&e.id!==null&&(e.id=String(e.id).padStart(3,`0`))}),n(e)}).catch(e=>console.error(`Failed to load map topology`,e))},[]);let r=(0,x.useMemo)(()=>e.reduce((e,t)=>e+t.count,0),[e]),i=(0,x.useMemo)(()=>{if(r<=0)return{maxThreshold:10,step:1};if(r<=1e3)return{maxThreshold:100,step:10};let e=10**Math.floor(Math.log10(r));return{maxThreshold:e,step:e/10}},[r]);return{geographyData:t,destinationMap:(0,x.useMemo)(()=>{let t={};return e.forEach(e=>{if(e.country_code){let n=e.country_code.toUpperCase();t[n]={count:e.count,name:e.country,countryCode:n}}}),t},[e]),scaleConfig:i,getLevel:e=>!e||e<=0?0:Math.min(10,Math.floor(e/i.step)+1),formatNumber:e=>{if(e>=1e6){let t=e/1e6;return Number.isInteger(t)?`${t}M`:`${t.toFixed(1)}M`}if(e>=1e3){let t=e/1e3;return Number.isInteger(t)?`${t}K`:`${t.toFixed(1)}K`}return e.toString()}}}var C=e(m(),1);const w=({onZoomIn:e,onZoomOut:n,onReset:i})=>(0,C.jsxs)(`div`,{className:`absolute top-3 right-3 flex flex-col gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-1.5 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10`,children:[(0,C.jsx)(`button`,{type:`button`,onClick:e,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom In`,children:(0,C.jsx)(r,{size:16})}),(0,C.jsx)(`button`,{type:`button`,onClick:n,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom Out`,children:(0,C.jsx)(o,{size:16})}),(0,C.jsx)(`button`,{type:`button`,onClick:i,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Reset Zoom`,children:(0,C.jsx)(t,{size:16})})]}),T=({maxThreshold:e,formatNumber:t})=>{let{t:r}=n();return(0,C.jsxs)(`div`,{className:`sm:absolute sm:bottom-3 sm:left-3 relative m-3 sm:m-0 flex flex-col shrink-0 gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-2 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10 max-w-70`,children:[(0,C.jsx)(`span`,{className:`text-[9px] font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider`,children:r(`analytics.queries`)}),(0,C.jsx)(`div`,{className:`flex items-center gap-0.5`,children:Array.from({length:11}).map((e,t)=>(0,C.jsx)(`div`,{className:`w-4 h-2.5 rounded-sm border border-black/5 dark:border-white/5`,style:{backgroundColor:`var(--map-color-${t})`}},t))}),(0,C.jsxs)(`div`,{className:`flex justify-between text-[9px] text-gray-500 dark:text-gray-400 font-semibold px-0.5`,children:[(0,C.jsx)(`span`,{children:`0`}),(0,C.jsx)(`span`,{children:t(e/2)}),(0,C.jsxs)(`span`,{children:[t(e),`+`]})]})]})},E=({name:e,count:t,flag:r,x:i,y:a,countryCode:o,profileId:s,range:c,customRange:l,accessPointId:u,ispCache:d,onCacheIsp:p,isPinned:m,onClose:g})=>{let{t:v}=n(),y=(0,x.useRef)(null),[b,S]=(0,x.useState)({left:i,top:a-10,alignBottom:!1}),[w,T]=(0,x.useState)([]),[E,D]=(0,x.useState)(!1),O=(0,x.useRef)(d);O.current=d;let k=(0,x.useRef)(p);return k.current=p,(0,x.useEffect)(()=>{if(!o||!s)return;if(t<=0){T([]),D(!1);return}let e=O.current[o];if(e){T(e),D(!1);return}D(!0);let n=Math.floor(Date.now()/1e3),r,i=n,a=`?country_code=${o}&range=${c}`;if(c===`custom`&&l.start&&l.end)r=Math.floor(new Date(l.start).getTime()/1e3),i=Math.floor(new Date(l.end).getTime()/1e3),a+=`&start=${r}&end=${i}`;else switch(c){case`10m`:r=n-600;break;case`1h`:r=n-3600;break;case`24h`:r=n-86400;break;case`7d`:r=n-604800;break;case`30d`:r=n-2592e3;break;default:r=n-86400;break}u&&(a+=`&access_point_id=${u}`);let d=!0,f=setTimeout(async()=>{try{let e=await _.queryISPs({profileId:s,countryCode:o,since:r,until:i,accessPointId:u||void 0});if(e&&e.length>0){k.current(o,e),d&&(T(e),D(!1));return}}catch(e){console.warn(`[MapTooltip] Local SQLite ISP query failed, falling back to server:`,e)}h(s,`isps`,a).then(e=>{let t=Array.isArray(e)?e:[];k.current(o,t),d&&T(t)}).catch(e=>{console.error(`Failed to fetch ISPs`,e)}).finally(()=>{d&&D(!1)})},200);return()=>{d=!1,clearTimeout(f)}},[o,s,c,l,u,t]),(0,x.useEffect)(()=>{if(!m)return;let e=e=>{if(y.current&&!y.current.contains(e.target)){let t=e.target,n=t.classList.contains(`rsm-geography`)||t.closest(`.rsm-geography`),r=t.classList.contains(`map-marker-circle`)||t.closest(`.map-marker-circle`);!n&&!r&&g()}},t=setTimeout(()=>{document.addEventListener(`click`,e,!0)},0);return()=>{clearTimeout(t),document.removeEventListener(`click`,e,!0)}},[m,g]),(0,x.useLayoutEffect)(()=>{if(!y.current)return;let e=y.current.getBoundingClientRect(),t=y.current.parentElement;if(!t)return;let n=t.getBoundingClientRect(),r=i,o=e.width/2;i-o<4?r=o+4:i+o>n.width-4&&(r=n.width-o-4);let s=a-10,c=!1;a-e.height-15<4&&(s=a+15,c=!0),S({left:r,top:s,alignBottom:c})},[i,a,w]),(0,C.jsxs)(`div`,{ref:y,onMouseLeave:m?g:void 0,className:`absolute bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm px-3 py-2 rounded-lg shadow-xl border border-gray-200/50 dark:border-slate-800/50 text-xs z-50 flex flex-col gap-1 transition-all duration-75 text-gray-900 dark:text-gray-100 ${m?`pointer-events-auto cursor-default`:`pointer-events-none`}`,style:{left:`${b.left}px`,top:`${b.top}px`,transform:b.alignBottom?`translate(-50%, 0)`:`translate(-50%, -100%)`},children:[(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,C.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-1.5 font-semibold whitespace-nowrap`,children:[(0,C.jsx)(`span`,{className:`text-sm`,children:r}),(0,C.jsx)(`span`,{children:e})]}),(0,C.jsxs)(`div`,{className:`text-gray-500 dark:text-gray-400 whitespace-nowrap`,children:[t.toLocaleString(),` `,v(`analytics.queries`)]})]}),m&&(0,C.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g()},className:`flex items-center justify-center p-2 rounded-lg border border-gray-200 dark:border-slate-800 text-gray-500 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20 hover:border-red-200 dark:hover:border-red-900/50 transition-colors cursor-pointer self-stretch aspect-square`,title:v(`common.close`,`Close`),children:(0,C.jsx)(f,{size:18})})]}),E?(0,C.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-850 flex flex-col gap-1 min-w-36`,children:[(0,C.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:v(`analytics.topIsps`,`Top ISPs`)}),(0,C.jsx)(`div`,{className:`text-[11px] text-gray-400 dark:text-gray-500 italic`,children:v(`analytics.loading`,`Loading...`)})]}):w.length>0&&(0,C.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-800 flex flex-col gap-1`,children:[(0,C.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:v(`analytics.topIsps`,`Top ISPs`)}),(0,C.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-36 max-w-48 ${m?`max-h-36 overflow-y-auto pr-1`:``}`,children:[(m?w:w.slice(0,5)).map(e=>(0,C.jsxs)(`div`,{className:`flex justify-between gap-3 text-[11px] text-gray-600 dark:text-gray-300`,children:[(0,C.jsx)(`span`,{className:`truncate`,title:e.name,children:e.name}),(0,C.jsx)(`span`,{className:`font-mono text-gray-400 dark:text-gray-500`,children:e.count.toLocaleString()})]},e.name)),!m&&w.length>5&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`div`,{className:`text-center text-gray-400 dark:text-gray-500 leading-none py-0.5 font-bold`,children:`...`}),(0,C.jsx)(`div`,{className:`text-[10px] text-center text-blue-500 dark:text-blue-400 font-medium whitespace-nowrap mt-0.5`,children:v(`analytics.pressToShowMore`,`Click to show more`)})]})]})]})]})},D=({geographyData:e,destinationMap:t,getLevel:r,containerRef:a,hoveredCountry:o,setHoveredCountry:s})=>{let{i18n:c}=n();return e?(0,C.jsx)(i,{geography:e,children:({geographies:e})=>e.map(e=>{let n=e.id==null?void 0:v[String(e.id)],i=n?t[n]:null,l=i?.count||0,u=r(l);return(0,C.jsx)(d,{geography:e,onMouseEnter:e=>{if(!n||o?.isPinned)return;let t=y(n,c.language)||i?.name||n,r=b(n),u=a.current?.getBoundingClientRect();s({name:t,code:n,count:l,flag:r,x:e.clientX-(u?.left||0),y:e.clientY-(u?.top||0)-15})},onMouseMove:e=>{s(t=>{if(t?.isPinned)return t;let n=a.current?.getBoundingClientRect(),r=e.clientX-(n?.left||0),i=e.clientY-(n?.top||0)-15;return t?{...t,x:r,y:i}:null})},onMouseLeave:()=>{s(e=>e?.isPinned?e:null)},onClick:e=>{if(e.stopPropagation(),!n)return;let t=y(n,c.language)||i?.name||n,r=b(n),o=a.current?.getBoundingClientRect(),u=e.clientX-(o?.left||0),d=e.clientY-(o?.top||0)-15;s(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:l,flag:r,x:u,y:d,isPinned:!0})},style:{default:{fill:`var(--map-color-${u})`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,transition:`fill 250ms, stroke 250ms`},hover:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,cursor:`pointer`},pressed:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`}}},e.rsmKey)})}):null},O={SG:{name:`Singapore`,coordinates:[103.8198,1.3521]},HK:{name:`Hong Kong`,coordinates:[114.1694,22.3193]},MO:{name:`Macau`,coordinates:[113.5439,22.1987]},VA:{name:`Vatican City`,coordinates:[12.4534,41.9029]},MC:{name:`Monaco`,coordinates:[7.4246,43.7384]},SM:{name:`San Marino`,coordinates:[12.4578,43.9424]},LI:{name:`Liechtenstein`,coordinates:[9.5209,47.141]},AD:{name:`Andorra`,coordinates:[1.5218,42.5063]},MT:{name:`Malta`,coordinates:[14.3754,35.9375]},GI:{name:`Gibraltar`,coordinates:[-5.3536,36.1408]},BM:{name:`Bermuda`,coordinates:[-64.7505,32.3078]},MV:{name:`Maldives`,coordinates:[73.5089,4.1755]},MU:{name:`Mauritius`,coordinates:[57.5522,-20.3484]}},k=({destinationMap:e,getLevel:t,containerRef:r,hoveredCountry:i,setHoveredCountry:a})=>{let{i18n:o}=n();return(0,C.jsx)(C.Fragment,{children:Object.entries(O).map(([n,s])=>{let l=e[n],d=l?.count||0,f=t(d),p=d>0,m=p?4:1.5;return(0,C.jsx)(u,{coordinates:c(s.coordinates[0],s.coordinates[1]),onMouseEnter:e=>{if(i?.isPinned)return;let t=y(n,o.language)||l?.name||n,s=b(n),c=r.current?.getBoundingClientRect();a({name:t,code:n,count:d,flag:s,x:e.clientX-(c?.left||0),y:e.clientY-(c?.top||0)-15})},onMouseMove:e=>{a(t=>{if(t?.isPinned)return t;let n=r.current?.getBoundingClientRect(),i=e.clientX-(n?.left||0),a=e.clientY-(n?.top||0)-15;return t?{...t,x:i,y:a}:null})},onMouseLeave:()=>{a(e=>e?.isPinned?e:null)},onClick:e=>{e.stopPropagation();let t=y(n,o.language)||l?.name||n,i=b(n),s=r.current?.getBoundingClientRect(),c=e.clientX-(s?.left||0),u=e.clientY-(s?.top||0)-15;a(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:d,flag:i,x:c,y:u,isPinned:!0})},children:p?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`circle`,{r:m+3,fill:`var(--map-color-${f})`,opacity:.4,className:`animate-ping map-marker-circle`}),(0,C.jsx)(`circle`,{r:m,fill:`var(--map-color-${f})`,stroke:`var(--map-stroke)`,strokeWidth:.75,style:{cursor:`pointer`},className:`map-marker-circle`})]}):(0,C.jsx)(`circle`,{r:m,fill:`var(--text-color)`,opacity:.25,style:{pointerEvents:`none`}})},n)})})},A=({destinations:e,profileId:t,range:n,customRange:r,accessPointId:i})=>{let{geographyData:o,destinationMap:u,scaleConfig:d,getLevel:f,formatNumber:p}=S(e),[m,h]=(0,x.useState)({coordinates:c(0,0),zoom:1.2}),[g,_]=(0,x.useState)(null),[v,y]=(0,x.useState)(null),[b,O]=(0,x.useState)({}),A=(0,x.useRef)(null);A.current=g,(0,x.useEffect)(()=>{if(!g){y(null);return}if(g.isPinned){y(g);return}if(v&&v.code===g.code)return;let e=setTimeout(()=>{A.current&&A.current.code===g.code&&y(A.current)},100);return()=>clearTimeout(e)},[g?.code,g?.isPinned,v?.code]),(0,x.useEffect)(()=>{g&&v&&g.code===v.code&&(g.x!==v.x||g.y!==v.y||g.isPinned!==v.isPinned)&&y(g)},[g?.x,g?.y,g?.isPinned,v]);let j=(0,x.useRef)(null);x.useEffect(()=>{O({})},[t,n,r,i]);let M=x.useCallback((e,t)=>{O(n=>({...n,[e]:t}))},[]),N=x.useMemo(()=>l(c(-100,-50),c(900,600)),[]);return(0,C.jsxs)(`div`,{className:`relative w-full min-h-85 max-h-120 aspect-800/566 bg-gray-50 dark:bg-slate-950 rounded-xl overflow-hidden border border-gray-100 dark:border-slate-800 flex flex-col justify-between shadow-sm`,children:[(0,C.jsxs)(`div`,{ref:j,className:`relative w-full flex-1 min-h-0 overflow-hidden select-none cursor-grab active:cursor-grabbing`,onClick:e=>{(e.target===e.currentTarget||e.target.tagName===`svg`)&&_(null)},children:[(0,C.jsx)(a,{projection:`geoEqualEarth`,width:800,height:566,style:{width:`100%`,height:`100%`},children:(0,C.jsxs)(s,{zoom:m.zoom,center:m.coordinates,onMoveEnd:e=>h({coordinates:c(e.coordinates[0],e.coordinates[1]),zoom:e.zoom}),maxZoom:8,minZoom:1,enablePan:!0,translateExtent:N,children:[(0,C.jsx)(D,{geographyData:o,destinationMap:u,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_}),(0,C.jsx)(k,{destinationMap:u,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_})]})}),v&&(0,C.jsx)(E,{name:v.name,count:v.count,flag:v.flag,x:v.x,y:v.y,countryCode:v.code,profileId:t,range:n,customRange:r,accessPointId:i,ispCache:b,onCacheIsp:M,isPinned:v.isPinned||!1,onClose:()=>_(null)})]}),(0,C.jsx)(w,{onZoomIn:()=>{m.zoom>=8||h(e=>({...e,zoom:e.zoom*1.5}))},onZoomOut:()=>{m.zoom<=1||h(e=>({...e,zoom:e.zoom/1.5}))},onReset:()=>{h({coordinates:c(0,0),zoom:1.2})}}),(0,C.jsx)(T,{maxThreshold:d.maxThreshold,formatNumber:p})]})};export{A as DestinationMap};
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{C as t,F as n,Mt as r,Qt as i,R as a,at as o,k as s,lt as c}from"./vendor-react-De1zEwOV.js";import{S as l,b as u}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{C as d,E as f,H as p,N as m,O as h,S as g,T as _,V as v,f as y,h as b,r as x,u as S,w as C,x as w}from"./vendor-ui-core-ClwQiwMI.js";import{_t as T}from"./vendor-utils-rmW6cqPl.js";import{$ as E,$t as D,G as O,R as k,U as A,V as j,ct as M,h as N,j as P,ut as F}from"./index-CrB_HdIL.js";var I=e(l(),1);const L=()=>{let{t:e}=i(),[t,n]=(0,I.useState)([]);return(0,I.useEffect)(()=>{P().then(t=>{t&&Array.isArray(t)&&n(t.map(t=>({label:e(t.label),url:t.url})))}).catch(e=>console.warn(`Failed to fetch preset filters from API`,e))},[e]),t};var R=e(u(),1);const z=({newUrl:e,setNewUrl:t,onAddList:n,syncing:r,loading:a,lists:o})=>{let{t:s}=i(),c=(0,R.jsx)(f,{className:`min-w-96`,children:L().map((e,t)=>(0,R.jsx)(C,{text:e.label,onClick:()=>n(e.url),disabled:o.some(t=>t.url===e.url),labelElement:(0,R.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,R.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-xl truncate`,title:e.url,children:e.url})})},t))});return(0,R.jsx)(w,{elevation:p.ONE,className:`mb-6`,children:(0,R.jsxs)(`div`,{className:`flex gap-2 flex-col sm:flex-row`,children:[(0,R.jsx)(y,{fill:!0,size:`large`,placeholder:s(`filtering.urlPlaceholder`),value:e,onChange:e=>t(e.target.value),leftIcon:`globe`,rightElement:(0,R.jsx)(_,{content:c,placement:`bottom-end`,animation:`minimal`,arrow:!1,usePortal:!0,children:(0,R.jsx)(m,{variant:`minimal`,icon:`chevron-down`})})}),(0,R.jsx)(m,{intent:v.PRIMARY,size:`large`,icon:`plus`,onClick:()=>n(),className:`shrink-0`,loading:r||a,disabled:r||a,children:s(`filtering.addSubscription`)})]})})},B=({lists:e,onSelect:t})=>{let{t:n}=i(),r=[{key:`url`,header:n(`filtering.tableUrl`),cellClassName:`font-mono text-sm max-w-md truncate`,render:e=>e.url},{key:`lastSync`,header:n(`filtering.tableLastSync`),cellClassName:`text-xs opacity-60`,render:e=>e.last_synced_at?N(new Date(e.last_synced_at*1e3)):n(`filtering.neverSynced`)},{key:`status`,header:n(`filtering.tableStatus`),render:e=>{if(!e.enabled)return(0,R.jsx)(x,{intent:v.NONE,minimal:!0,children:n(`filtering.statusDisabled`,`Disabled`)});let t=!!e.sync_error,r=!!e.last_synced_at,i=n(`filtering.statusNormal`,`Active`),a=v.SUCCESS;return t&&(r?(i=n(`filtering.statusOutdated`,`Outdated`),a=v.WARNING):(i=n(`filtering.statusMissing`,`Missing`),a=v.DANGER)),(0,R.jsx)(x,{intent:a,minimal:!0,children:i})}}];return(0,R.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,R.jsxs)(S,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,R.jsx)(`thead`,{children:(0,R.jsx)(`tr`,{children:r.map(e=>(0,R.jsx)(`th`,{className:e.headerClassName,children:e.header},e.key))})}),(0,R.jsx)(`tbody`,{children:e.map(e=>(0,R.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:r.map(t=>(0,R.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},V=({profileId:e,selectedList:r,onClose:a,onCopy:l,onDelete:u,onToggleEnabled:d,onAllowDomain:f})=>{let{t:p}=i(),[_,S]=(0,I.useState)(``),[C,w]=(0,I.useState)(!1),[T,E]=(0,I.useState)(null),[D,O]=(0,I.useState)(null),[k,j]=(0,I.useState)(!1),[M,P]=(0,I.useState)(!1),[F,L]=(0,I.useState)(!1),z=(0,I.useRef)(0),B=()=>{z.current++,w(!1),S(``),E(null),O(null),P(!1)},V=async()=>{let t=_.trim().toLowerCase();if(!t||!r||(t=t.replace(/^https?:\/\//,``).split(`/`)[0].split(`:`)[0].replace(/\.+$/,``),!t))return;S(t);let n=++z.current,i=r.id;w(!0),O(null),E(null),P(!1);try{let r=await A(e,i,t);z.current===n&&E(r)}catch(e){z.current===n&&O(e instanceof Error?e.message:String(e))}finally{z.current===n&&w(!1)}},H=async e=>{if(r){L(!0);try{await d(r.id,e)}finally{L(!1)}}},U=async()=>{if(T?.matchedEntry){j(!0);try{await f(T.domain),P(!0)}catch(e){O(e instanceof Error?e.message:String(e))}finally{j(!1)}}};return(0,R.jsxs)(h,{isOpen:r!==null,onClose:()=>{B(),a()},title:p(`filtering.listDetails`,`List Details`),icon:`info-sign`,children:[(0,R.jsxs)(`div`,{className:`p-6 space-y-4`,children:[r?.sync_error&&(0,R.jsx)(g,{intent:v.WARNING,title:p(`filtering.syncError`),icon:`warning-sign`,children:r.sync_error}),(0,R.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700 break-all font-mono text-sm`,children:r?.url}),(0,R.jsxs)(`div`,{className:`flex items-center justify-between border border-gray-200 dark:border-gray-700 rounded-lg p-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.listEnabled`,`List active`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.listEnabledHint`,`Disable to stop filtering with this list without deleting it. Its subscription and sync history are kept.`)})]}),(0,R.jsx)(b,{large:!0,checked:!!r?.enabled,disabled:F,onChange:e=>H(e.target.checked)})]}),(0,R.jsxs)(`div`,{className:`border border-gray-200 dark:border-gray-700 rounded-lg p-3 space-y-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.checkDomain`,`Check a domain`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.checkDomainHint`,`Lists are stored as compact filters, so their entries cannot be browsed. You can test any domain against this list instantly.`)})]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(y,{fill:!0,placeholder:`example.com`,value:_,disabled:C,leftIcon:`globe-network`,onChange:e=>{S(e.target.value),E(null)},onKeyDown:e=>{e.key===`Enter`&&V()}}),(0,R.jsx)(m,{icon:(0,R.jsx)(n,{size:14}),text:p(`filtering.check`,`Check`),loading:C,disabled:!_.trim(),onClick:()=>void V()})]}),D&&(0,R.jsx)(g,{intent:v.DANGER,className:`text-xs`,children:D}),T&&!T.synced&&(0,R.jsx)(g,{intent:v.WARNING,className:`text-xs`,children:p(`filtering.checkNotSynced`,`This list has not finished syncing yet, so there is nothing to check against.`)}),T?.synced&&T.enabled===!1&&(0,R.jsx)(g,{intent:v.NONE,className:`text-xs`,children:p(`filtering.checkListDisabled`,`This list is currently disabled, so it is not filtering anything right now.`)}),T?.synced&&(0,R.jsx)(g,{intent:T.blocked?v.WARNING:v.SUCCESS,className:`text-xs`,icon:T.blocked?`ban-circle`:`tick-circle`,children:T.blocked?(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`div`,{children:[p(`filtering.checkBlocked`,`Blocked by this list`),T.matchedEntry&&T.matchedEntry!==T.domain&&(0,R.jsxs)(R.Fragment,{children:[` `,(0,R.jsx)(x,{minimal:!0,className:`font-mono`,children:T.matchedEntry}),` `,p(`filtering.checkViaParent`,`(matched a parent domain)`)]})]}),(0,R.jsx)(`div`,{className:`opacity-75`,children:T.falsePositiveRate?p(`filtering.checkProbabilisticRate`,{defaultValue:`Filters are probabilistic: roughly 1 match in {{odds}} is a false positive. Adding an exception also covers every subdomain of it.`,odds:Math.round(1/T.falsePositiveRate).toLocaleString()}):p(`filtering.checkProbabilistic`,`Filters are probabilistic, so a small share of matches are false positives. Adding an exception also covers every subdomain of it.`)}),M?(0,R.jsx)(x,{intent:v.SUCCESS,minimal:!0,children:p(`filtering.checkAllowed`,`Exception added - this domain now resolves`)}):(0,R.jsx)(m,{small:!0,icon:(0,R.jsx)(s,{size:12}),intent:v.PRIMARY,loading:k,text:p(`filtering.checkAllowAction`,`Allow anyway`),onClick:()=>void U()})]}):p(`filtering.checkNotBlocked`,`Not blocked by this list`)})]}),(0,R.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,R.jsxs)(`span`,{className:`text-xs opacity-50`,children:[p(`filtering.tableLastSync`),`:`,` `,r?.last_synced_at?N(new Date(r.last_synced_at*1e3)):`-`]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(c,{size:14}),text:p(`setup.copyUrl`,`Copy link`),onClick:()=>{r&&l(r.url)}}),(0,R.jsx)(m,{icon:(0,R.jsx)(o,{size:14}),text:p(`setup.learnMore`,`Open link`),onClick:()=>{r&&window.open(r.url,`_blank`)}})]})]})]}),(0,R.jsxs)(`div`,{className:`p-4 border-t border-gray-100 dark:border-gray-800 flex justify-between`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(t,{size:14}),intent:v.DANGER,text:p(`rules.delete`,`Delete`),onClick:()=>{if(!r)return;let e=r.id;B(),u(e)}}),(0,R.jsx)(m,{onClick:()=>{B(),a()},text:p(`rules.close`,`Close`)})]})]})},H=({profileId:e,toasterRef:t})=>{let n=r(),o=D(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(``),[f,p]=(0,I.useState)(!0),[h,_]=(0,I.useState)(!1),{t:y}=i(),[b,x]=(0,I.useState)(null),S=async()=>{p(!0);try{c(await E(e))}catch(e){console.error(`Failed to fetch filters`,e)}finally{p(!1)}},C=e=>{navigator.clipboard.writeText(e),t?.current?.show({message:y(`setup.copied`,`已复制到剪贴板`),intent:v.SUCCESS,icon:`duplicate`})},w=async t=>{let n=new Map(t.map(e=>[e.id,e.last_synced_at])),r=0;for(;r<15;){await new Promise(e=>setTimeout(e,2e3));try{let t=await E(e),r=!0;for(let e of t){if(n.has(e.id)&&e.last_synced_at===n.get(e.id)){r=!1;break}if(!n.has(e.id)&&!e.last_synced_at){r=!1;break}}if(r&&t.length>0)return c(t),!0}catch{}r++}return await S(),!1};return(0,I.useEffect)(()=>{S()},[e]),(0,R.jsxs)(`div`,{className:T(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,o?`p-1`:`px-8`),children:[(0,R.jsxs)(`div`,{className:`mb-8 flex flex-col md:flex-row justify-between items-start md:items-end gap-4`,children:[(0,R.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[o?(0,R.jsxs)(d,{minimal:!0,fill:o,children:[(0,R.jsx)(m,{active:!1,onClick:()=>n(`/dash/${e}/rules`),text:y(`rules.title`),large:!0}),(0,R.jsx)(m,{active:!0,onClick:()=>n(`/dash/${e}/filter`),text:y(`filtering.title`),large:!0})]}):(0,R.jsx)(`h1`,{className:`bp6-heading`,children:y(`rules.title`)}),(0,R.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:y(`filtering.subtitle`)})]}),(0,R.jsx)(m,{icon:(0,R.jsx)(a,{size:16}),text:y(`filtering.syncAll`),onClick:async()=>{_(!0);try{await M(e),t?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&t?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}},loading:h||f,disabled:h||f||s.length===0,className:o?`w-full`:``})]}),(0,R.jsx)(g,{intent:v.WARNING,icon:`info-sign`,className:`mb-6`,children:(0,R.jsx)(`p`,{children:y(`filtering.formatDisclaimer`,`本系统只支持有限的 AdGuard 格式列表和纯域名列表。仅支持基础的拦截规则(如 ||example.com^),会绕过 "@@" 白名单,暂不支持 "$" 重写规则以及 "*" 省略规则。系统会自动匹配域名的所有子域名。`)})}),(0,R.jsx)(z,{newUrl:l,setNewUrl:u,onAddList:async n=>{let r=n||l;if(r){_(!0);try{await k(e,r),t?.current?.show({message:y(`filtering.addSuccess`),intent:v.SUCCESS,icon:`tick`}),u(``),t?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&t?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}}},syncing:h,loading:f,lists:s}),(0,R.jsx)(B,{lists:s,onSelect:x}),(0,R.jsx)(V,{profileId:e,selectedList:b,onClose:()=>x(null),onCopy:C,onDelete:async n=>{try{await O(e,n),t?.current?.show({message:y(`filtering.deleteSuccess`),intent:v.PRIMARY,icon:`trash`}),x(null),await S()}catch(e){console.error(e)}},onToggleEnabled:async(n,r)=>{try{await F(e,n,r),x(e=>e&&e.id===n?{...e,enabled:r}:e),t?.current?.show({message:r?y(`filtering.listEnabledToast`,`List enabled - rebuilding filter`):y(`filtering.listDisabledToast`,`List disabled - rebuilding filter`),intent:v.PRIMARY,icon:r?`tick`:`disable`}),await S()}catch(e){console.error(e),t?.current?.show({message:e instanceof Error?e.message:String(e),intent:v.DANGER,icon:`error`})}},onAllowDomain:async n=>{await j(e,{type:`ALLOW`,pattern:n}),t?.current?.show({message:y(`filtering.allowRuleAdded`,`Exception added for {{domain}}`,{domain:n}),intent:v.SUCCESS,icon:`tick`})}})]})};export{H as FilteringView};