dns-worker 1.1.2 → 1.1.3-canary.eba4e13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/serverfull.mjs +1 -1
- package/dist/serverfull.mjs.map +1 -1
- package/package.json +4 -2
- package/static/assets/{AccountView-p5jSjMAE.js → AccountView-CDS0x_Sp.js} +3 -3
- package/static/assets/{AnalyticsView-BywwDzah.js → AnalyticsView-8XjTrN9w.js} +2 -2
- package/static/assets/{AuthView-qoUKd5PS.js → AuthView-WWzYl3-y.js} +1 -1
- package/static/assets/{DestinationMap-9Yc54Mdj.js → DestinationMap-BYS-QPrT.js} +1 -1
- package/static/assets/{FilteringView-Bs3__NpV.js → FilteringView-5LHP2DfX.js} +1 -1
- package/static/assets/LogsView-Cz6SjOgh.js +5 -0
- package/static/assets/{RulesView-B2kL1QhI.js → RulesView-BWOftzzI.js} +1 -1
- package/static/assets/{SettingsView-DTGI6eSd.js → SettingsView-tB83dkYR.js} +1 -1
- package/static/assets/{SetupView-DE9MM-32.js → SetupView-BWHg9Njb.js} +1 -1
- package/static/assets/{TrendChart-CCR1W3fC.js → TrendChart-CvhWAoL-.js} +1 -1
- package/static/assets/date-DxXxDqte.js +1 -0
- package/static/assets/{getFlagEmoji-DRubsb7D.js → getFlagEmoji-sHq5YwT3.js} +1 -1
- package/static/assets/{index-dXN_pYn1.js → index-CP2FJpkF.js} +4 -4
- package/static/assets/{services-BVnEJBDq.js → services-DM_tzwVp.js} +1 -1
- package/static/index.html +1 -1
- package/static/sw.js +1 -1
- package/static/assets/LogsView-B-U9oaxB.js +0 -5
- package/static/assets/date-CpvuBM37.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dns-worker",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3-canary.eba4e13",
|
|
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",
|
|
@@ -52,7 +52,9 @@
|
|
|
52
52
|
"keywords": [
|
|
53
53
|
"dns",
|
|
54
54
|
"cloudflare-workers",
|
|
55
|
-
"doh"
|
|
55
|
+
"doh",
|
|
56
|
+
"ad-blocking",
|
|
57
|
+
"privacy"
|
|
56
58
|
],
|
|
57
59
|
"author": "Hugo Koo",
|
|
58
60
|
"license": "AGPL-3.0-or-later",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/date-
|
|
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,st as E,x as D,y as O,z as k}from"./vendor-react-BmoHsW1x.js";import{S as A,b as j,x as M}from"./vendor-icons-other-Bme3ywH9.js";import{r as ee}from"./vendor-i18next-BKUzkAKP.js";import{B as N,C as P,D as F,F as te,H as I,L,M as R,N as z,O as B,P as ne,R as V,S as H,T as re,V as U,_ as W,d as ie,f as G,h as ae,j as K,p as q,r as J,t as oe,u as se,v as ce,x as Y,z as X}from"./vendor-ui-core-CY_WyMIf.js";import{_t as le}from"./vendor-utils-BWSB0jGn.js";import{At as ue,Bt as de,Ct as fe,Dt as pe,Et as me,F as he,Gt as ge,Ht as _e,I as ve,It as ye,Jt as be,Kt as xe,Lt as Se,M as Ce,Mt as we,N as Te,Nt as Ee,Ot as De,P as Oe,Pt as ke,Rt as Ae,St as je,Tt as Me,Ut as Ne,Vt as Pe,Wt as Fe,Xt as Ie,Yt as Le,Zt as Re,d as ze,f as Be,i as Ve,j as Z,jt as He,kt as Ue,l as We,ln as Ge,m as Ke,nn as qe,o as Je,p as Ye,qt as Xe,s as Ze,v as Qe,w as $e,wt as et,zt as tt}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/date-DxXxDqte.js","assets/index-CP2FJpkF.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-BmoHsW1x.js","assets/vendor-ui-core-CY_WyMIf.js","assets/vendor-utils-BWSB0jGn.js","assets/vendor-i18next-BKUzkAKP.js","assets/index-Bheo8y3N.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,st as E,x as D,y as O,z as k}from"./vendor-react-BmoHsW1x.js";import{S as A,b as j,x as M}from"./vendor-icons-other-Bme3ywH9.js";import{r as ee}from"./vendor-i18next-BKUzkAKP.js";import{B as N,C as P,D as F,F as te,H as I,L,M as R,N as z,O as B,P as ne,R as V,S as H,T as re,V as U,_ as W,d as ie,f as G,h as ae,j as K,p as q,r as J,t as oe,u as se,v as ce,x as Y,z as X}from"./vendor-ui-core-CY_WyMIf.js";import{_t as le}from"./vendor-utils-BWSB0jGn.js";import{At as ue,Bt as de,Ct as fe,Dt as pe,Et as me,F as he,Gt as ge,Ht as _e,I as ve,It as ye,Jt as be,Kt as xe,Lt as Se,M as Ce,Mt as we,N as Te,Nt as Ee,Ot as De,P as Oe,Pt as ke,Rt as Ae,St as je,Tt as Me,Ut as Ne,Vt as Pe,Wt as Fe,Xt as Ie,Yt as Le,Zt as Re,d as ze,f as Be,i as Ve,j as Z,jt as He,kt as Ue,l as We,ln as Ge,m as Ke,nn as qe,o as Je,p as Ye,qt as Xe,s as Ze,v as Qe,w as $e,wt as et,zt as tt}from"./index-CP2FJpkF.js";import{t as nt}from"./QRCodeCanvas-DQ-xNuwF.js";var Q=e(A(),1),$=e(j(),1);const rt=({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)(K,{style:{margin:0},children:a(`account.totp.recoveryKeysTitle`,`Save Your Recovery Keys`)})]}),(0,$.jsx)(H,{intent:U.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)(z,{fill:!0,icon:(0,$.jsx)(w,{size:14}),text:t?a(`account.totp.copied`,`Copied!`):a(`account.totp.copyKeys`,`Copy All Keys`),intent:t?U.SUCCESS:U.NONE,onClick:r}),(0,$.jsx)(z,{fill:!0,intent:U.PRIMARY,text:a(`account.totp.done`,`Done, I've saved them`),onClick:i})]})]})},it=({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),[M,ee]=(0,Q.useState)(!1),[N,P]=(0,Q.useState)(``),[F,te]=(0,Q.useState)(null),[I,L]=(0,Q.useState)(!1),[R,z]=(0,Q.useState)(null),B=(0,Q.useCallback)(async()=>{o(!0);try{i(await Ee()||[])}catch{}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{c(Le()),B()},[B]),{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(!Qe(r)){T(n(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`));return}C(!0),T(``);try{let t=await be({name:r,credential:await Re(await we())}),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 B(),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:M,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(!Qe(t)){P(n(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`));return}ee(!0),P(``);try{await ye(E.id,t),D(null),await B()}catch(e){P(e instanceof Error?e.message:n(`common.errorNetwork`))}finally{ee(!1)}}},deletingId:F,deleteConfirmOpen:I,setDeleteConfirmOpen:L,targetToDelete:R,handleOpenDelete:e=>{z(e),L(!0)},handleDeleteSubmit:async()=>{if(R){te(R.id);try{await me(R.id),L(!1),z(null),await B(),e?.()}catch(e){let t=e instanceof Error?e.message:n(`common.errorNetwork`);alert(t)}finally{te(null)}}},testingId:m,handleTestPasskey:async e=>{h(e?e.id:`all`);try{let r=await _e(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:U.SUCCESS,icon:`tick-circle`}),await B())}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:U.WARNING,icon:`warning-sign`}):t?.current?.show({message:r||n(`account.passkey.testFailed`,`Passkey verification failed`),intent:U.DANGER,icon:`error`})}finally{h(null)}},fetchPasskeys:B}},at=({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)(ne,{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`),`:`,` `,$e(new Date(e.created_at*1e3))]}),e.last_used_at?(0,$.jsxs)(`span`,{children:[f(`account.passkey.lastUsed`,`Last used`),`:`,` `,$e(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)(z,{minimal:!0,small:!0,intent:U.PRIMARY,icon:(0,$.jsx)(n,{size:14}),title:f(`account.passkey.testThis`,`Test this passkey`),loading:s===e.id,onClick:()=>c?.(e)}),(0,$.jsx)(z,{minimal:!0,small:!0,icon:(0,$.jsx)(r,{size:14}),title:f(`common.rename`,`Rename`),onClick:()=>l(e)}),(0,$.jsx)(z,{minimal:!0,small:!0,intent:U.DANGER,icon:(0,$.jsx)(i,{size:14}),title:f(`common.delete`,`Delete`),loading:o===e.id,onClick:()=>u(e)})]})]},e.id))})},ot=({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)(B,{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:L,children:[s&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:s}),(0,$.jsx)(q,{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:N.TOP,intent:U.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(G,{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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{text:u(`common.cancel`,`Cancel`),onClick:t,disabled:o}),(0,$.jsx)(z,{intent:U.PRIMARY,type:`submit`,text:u(`account.passkey.continue`,`Continue`),loading:o,disabled:!Qe(n.trim())||o})]})})]})})},st=({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)(B,{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:L,children:[s&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:s}),(0,$.jsx)(q,{label:u(`account.passkey.appNameLabel`,`Application (Domain)`),children:(0,$.jsx)(G,{readOnly:!0,disabled:!0,leftIcon:`globe`,value:window.location.hostname})}),(0,$.jsx)(q,{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:N.TOP,intent:U.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(G,{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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{text:u(`common.cancel`,`Cancel`),onClick:t,disabled:o}),(0,$.jsx)(z,{intent:U.PRIMARY,type:`submit`,text:u(`common.save`,`Save`),loading:o,disabled:!Qe(n.trim())||o})]})})]})})},ct=({isOpen:e,onClose:t,targetToDelete:n,deleting:r,onConfirm:i})=>{let{t:a}=d();return(0,$.jsxs)(B,{isOpen:e,onClose:()=>!r&&t(),title:a(`account.passkey.deleteTitle`,`Delete Passkey`),className:`max-w-md`,children:[(0,$.jsx)(`div`,{className:L,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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{text:a(`common.cancel`,`Cancel`),onClick:t,disabled:r}),(0,$.jsx)(z,{intent:U.DANGER,text:a(`common.delete`,`Delete`),onClick:i,loading:r})]})})]})},lt=({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:O,renameFocused:A,setRenameFocused:j,renaming:M,renameError:ee,setRenameError:N,handleOpenRename:P,handleRenameSubmit:F,deletingId:te,deleteConfirmOpen:I,setDeleteConfirmOpen:L,targetToDelete:R,handleOpenDelete:B,handleDeleteSubmit:ne,testingId:V,handleTestPasskey:re}=it({onRefresh:e,toasterRef:r});return s?(0,$.jsx)(rt,{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)(K,{style:{margin:0},children:t(`account.passkey.title`,`Passkeys`)}),(0,$.jsx)(J,{intent:i.length>0?U.SUCCESS:U.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)(z,{intent:U.NONE,outlined:!0,icon:(0,$.jsx)(n,{size:16}),text:t(`account.passkey.testBtn`,`Test Passkey`),onClick:()=>re(),loading:V===`all`}),o&&(0,$.jsx)(z,{intent:U.PRIMARY,icon:(0,$.jsx)(k,{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)(H,{intent:U.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)(at,{passkeys:i,loading:a,deletingId:te,testingId:V,onTestPasskey:re,onOpenRename:P,onOpenDelete:B}),(0,$.jsx)(ot,{isOpen:p,onClose:()=>m(!1),passkeyName:h,setPasskeyName:g,nameFocused:_,setNameFocused:v,registering:y,addError:b,setAddError:x,onSubmit:w}),(0,$.jsx)(st,{isOpen:!!T,onClose:()=>E(null),editName:D,setEditName:O,renameFocused:A,setRenameFocused:j,renaming:M,renameError:ee,setRenameError:N,onSubmit:F}),(0,$.jsx)(ct,{isOpen:I,onClose:()=>L(!1),targetToDelete:R,deleting:!!te,onConfirm:ne})]})},ut=({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 Ne(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)(B,{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)(H,{intent:U.SUCCESS,icon:(0,$.jsx)(v,{size:16}),children:r(`account.totp.testSuccess`,`Verification successful! Your authenticator app is configured properly.`)}),c&&(0,$.jsx)(H,{intent:U.DANGER,children:c}),(0,$.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),p()},className:`space-y-4`,children:[(0,$.jsx)(q,{label:r(`account.totp.verificationCode`,`6-Digit Verification Code`),labelFor:`test-totp-input`,children:(0,$.jsx)(G,{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)(z,{text:u?r(`common.close`,`Close`):r(`common.cancel`,`Cancel`),onClick:n}),!u&&(0,$.jsx)(z,{intent:U.PRIMARY,text:r(`account.totp.verifyBtn`,`Verify`),type:`submit`,loading:o,disabled:i.length!==6})]})]})]})})},dt=({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)(K,{style:{margin:0},children:f(`account.totp.title`,`Authenticator App (TOTP)`)}),(0,$.jsx)(J,{intent:U.SUCCESS,minimal:!0,round:!0,children:f(`account.totp.enabled`,`Enabled`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(z,{outlined:!0,icon:(0,$.jsx)(t,{size:14}),text:f(`account.totp.testBtn`,`Test Code`),onClick:()=>g(!0)}),(0,$.jsx)(z,{intent:U.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)(B,{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)(H,{intent:U.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)(H,{intent:U.DANGER,children:s}),!e.totp_skip_password&&(0,$.jsxs)(`form`,{onSubmit:u,className:`space-y-4`,children:[(0,$.jsx)(q,{label:f(`account.currentPassword`),children:(0,$.jsx)(G,{type:p?`text`:`password`,leftIcon:`lock`,value:i,onChange:e=>a(e.target.value),rightElement:(0,$.jsx)(z,{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)(z,{text:f(`account.cancel`),onClick:()=>r(!1)}),(0,$.jsx)(z,{intent:U.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)(z,{text:f(`account.cancel`),onClick:()=>r(!1)}),(0,$.jsx)(z,{intent:U.DANGER,text:f(`account.totp.confirmDisable`,`Disable TOTP`),loading:l,onClick:u})]})]})}),(0,$.jsx)(ut,{isOpen:h,onClose:()=>g(!1)})]})},ft=({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)(K,{style:{margin:0},children:u(`account.totp.title`,`Authenticator App (TOTP)`)}),(0,$.jsx)(J,{minimal:!0,round:!0,intent:U.NONE,children:u(`account.totp.disabled`,`Disabled`)})]}),!e&&(0,$.jsx)(z,{intent:U.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)(nt,{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)(W,{}),r&&(0,$.jsx)(H,{intent:U.DANGER,children:r}),(0,$.jsxs)(`form`,{onSubmit:c,className:`space-y-3`,children:[(0,$.jsx)(q,{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)(Ve,{length:6,value:t,onChange:n,disabled:i})}),(0,$.jsxs)(`div`,{className:`flex gap-2`,children:[(0,$.jsx)(z,{text:u(`account.cancel`),onClick:l}),(0,$.jsx)(z,{intent:U.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)(H,{intent:U.DANGER,children:r})]})]})},pt=({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)(rt,{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)(dt,{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 Be(v,e.username)),await pe(n),_(!1),y(``),t()}catch(e){C(e.message||n(`common.errorNetwork`))}finally{x(!1)}}}):(0,$.jsx)(ft,{setupData:r,setupToken:a,setSetupToken:o,setupError:f,setupLoading:l,onStartSetup:async()=>{u(!0),p(``);try{i(await Pe())}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 et({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(``)}})},mt=({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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[r&&(0,$.jsx)(z,{small:!0,active:e===`passkey`,intent:e===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.mfa.passkey`,`Passkey`),onClick:()=>t(`passkey`)}),i&&(0,$.jsx)(z,{small:!0,active:e===`recovery_key`,intent:e===`recovery_key`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.recoveryKey.verifyBtn`,`Recovery Key`),onClick:()=>t(`recovery_key`)}),a&&(0,$.jsx)(z,{small:!0,active:e===`totp`,intent:e===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:s(`account.mfa.totp`,`TOTP`),onClick:()=>t(`totp`)}),o&&(0,$.jsx)(z,{small:!0,active:e===`password`,intent:e===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:s(`account.mfa.password`,`Password`),onClick:()=>t(`password`)})]})})})},ht=({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)(z,{fill:!0,large:!0,intent:U.PRIMARY,loading:e,onClick:t,icon:(0,$.jsx)(u,{size:16}),text:n(`account.usePasskeyInstead`,`Authenticate with Passkey`)})]})},gt=({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)(q,{label:i(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Ve,{length:6,value:e,onChange:e=>{t(e),e.length===6&&r(e)},disabled:n})}),(0,$.jsx)(z,{fill:!0,intent:U.PRIMARY,loading:n,disabled:e.length!==6,onClick:()=>r(),text:i(`common.confirm`,`Confirm`)})]})},_t=({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)(q,{label:o(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(G,{leftIcon:`lock`,type:n?`text`:`password`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,rightElement:(0,$.jsx)(z,{minimal:!0,icon:n?`eye-open`:`eye-off`,onClick:()=>r(!n)})})}),(0,$.jsx)(z,{fill:!0,intent:U.PRIMARY,type:`submit`,loading:i,text:o(`common.confirm`,`Confirm`)})]})},vt=({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)(q,{label:i(`account.recoveryKey.verifyPromptLabel`,`原恢复密钥 (Original Recovery Key)`),children:(0,$.jsx)(G,{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)(z,{fill:!0,intent:U.PRIMARY,type:`submit`,loading:n,disabled:!e.trim(),text:i(`common.confirm`,`Confirm`)})]})};var yt=(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 bt=({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=yt(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 Be(g,n.username)),await i({password:e}),t()}catch(e){D(ze(e,o))}finally{T(!1)}},j=async()=>{T(!0),D(``);try{await i({passkeyAssertion:await Ie(await He())}),t()}catch(e){D(ze(e,o))}finally{T(!1)}},M=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(ze(e,o))}finally{T(!1)}},ee=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(ze(e,o))}finally{T(!1)}},N=(c?1:0)+(f?1:0)+(l?1:0)+(u?1:0);return(0,$.jsx)(B,{isOpen:e,onClose:t,title:r||o(`account.verifyIdentity`,`Security Verification`),icon:`shield`,className:`max-w-md w-full`,children:(0,$.jsxs)(`div`,{className:L,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)(mt,{method:m,onSelectMethod:e=>{h(e),D(``)},hasPasskey:c,hasRecoveryKey:f,hasTotp:l,hasPassword:u}),E&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:E}),m===`recovery_key`&&(0,$.jsx)(vt,{recoveryKey:S,setRecoveryKey:C,loading:w,onSubmit:ee}),m===`passkey`&&(0,$.jsx)(ht,{loading:w,onVerify:j}),m===`totp`&&(0,$.jsx)(gt,{totpCode:b,setTotpCode:x,loading:w,onVerify:M}),m===`password`&&(0,$.jsx)(_t,{password:g,setPassword:_,showPassword:v,setShowPassword:y,loading:w,onSubmit:A})]})})},xt=({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 tt(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:U.WARNING}),t();return}}catch{}b({text:r(`account.recoveryKey.rotateSuccess`,`恢复密钥已成功轮换!请立即妥善离线保存新密钥,旧密钥已失效。`),intent:U.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)(K,{style:{margin:0},children:r(`account.recoveryKey.title`,`紧急恢复密钥`)}),(0,$.jsx)(J,{intent:C?U.SUCCESS:U.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:N.TOP,children:(0,$.jsx)(J,{intent:U.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)(z,{small:!0,intent:U.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)(H,{intent:v.intent,className:`my-2`,children:v.text}),c&&(0,$.jsxs)(Y,{elevation:I.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)(z,{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)(z,{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)(z,{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)(F,{isOpen:o,onConfirm:D,onCancel:()=>s(!1),cancelButtonText:r(`common.cancel`,`取消`),confirmButtonText:r(`account.recoveryKey.confirmRotateBtn`,`确认进入轮换验证`),intent:U.DANGER,icon:`warning-sign`,children:(0,$.jsx)(`p`,{children:r(`account.recoveryKey.rotateConfirm`,`轮换恢复密钥将立即使原恢复密钥失效,并重新派生信封加密密钥。仅允许通过现有通行密钥 (Passkey) 或原恢复密钥完成轮换验证。是否继续?`)})}),(0,$.jsx)(bt,{isOpen:i,onClose:()=>a(!1),user:e,allowedMethods:[`passkey`,`recovery_key`],title:r(`account.recoveryKey.rotateVerifyTitle`,`验证身份以轮换恢复密钥`),onVerify:O})]})},St=({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 ge(e),r()}catch(e){alert(e.message||i(`common.errorNetwork`,`Network error`))}finally{o(!1)}};return(0,$.jsxs)(Y,{elevation:I.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)(K,{style:{margin:0},children:i(`account.mfa.title`,`Multi-Factor Authentication (MFA)`)}),(0,$.jsx)(J,{intent:s?U.SUCCESS:U.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)(W,{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)(H,{intent:U.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)(W,{}),(0,$.jsx)(lt,{onRefresh:r}),(0,$.jsx)(W,{}),(0,$.jsx)(pt,{user:e,onRefresh:r}),(0,$.jsx)(W,{}),(0,$.jsx)(xt,{user:e,onRefresh:r})]})},Ct={signup:{label:`account.activity.signup`,icon:(0,$.jsx)(D,{size:14}),intent:U.SUCCESS},login_success:{label:`account.activity.loginSuccess`,icon:(0,$.jsx)(g,{size:14}),intent:U.SUCCESS},login_fail:{label:`account.activity.loginFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER},logout:{label:`account.activity.logout`,icon:(0,$.jsx)(c,{size:14}),intent:U.NONE},password_change_success:{label:`account.activity.pwChangeSuccess`,icon:(0,$.jsx)(u,{size:14}),intent:U.SUCCESS},password_change_fail:{label:`account.activity.pwChangeFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER},totp_verify_success:{label:`account.activity.totpVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:U.SUCCESS},totp_verify_fail:{label:`account.activity.totpVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER},totp_setup:{label:`account.activity.totpSetup`,icon:(0,$.jsx)(a,{size:14}),intent:U.PRIMARY},totp_removed:{label:`account.activity.totpRemoved`,icon:(0,$.jsx)(C,{size:14}),intent:U.WARNING},recovery_key_used:{label:`account.activity.recoveryKeyUsed`,icon:(0,$.jsx)(u,{size:14}),intent:U.WARNING},recovery_key_rotated:{label:`account.activity.recoveryKeyRotated`,icon:(0,$.jsx)(u,{size:14}),intent:U.WARNING},session_revoked:{label:`account.activity.sessionRevoked`,icon:(0,$.jsx)(c,{size:14}),intent:U.WARNING},passkey_registered:{label:`account.activity.passkeyRegistered`,icon:(0,$.jsx)(u,{size:14}),intent:U.PRIMARY},passkey_deleted:{label:`account.activity.passkeyDeleted`,icon:(0,$.jsx)(C,{size:14}),intent:U.WARNING},passkey_verify_success:{label:`account.activity.passkeyVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:U.SUCCESS},passkey_verify_fail:{label:`account.activity.passkeyVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER}},wt=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`},Tt=(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},Et=({userAgent:e})=>{let{t}=d();if(!e)return(0,$.jsx)(`span`,{className:`text-gray-500`,children:`—`});let n=Tt(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:wt(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})]})},Dt=({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 De(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=>Ct[e]??{label:e,icon:(0,$.jsx)(s,{size:14}),intent:U.NONE};return(0,$.jsxs)(Y,{elevation:I.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)(K,{style:{margin:0},children:n(`account.activity.title`,`Account Activity`)}),r.length>0&&(0,$.jsxs)(J,{minimal:!0,round:!0,intent:U.NONE,children:[r.length,c?`+`:``]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(z,{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)(ne,{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)(J,{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:$e(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)(Et,{userAgent:r.user_agent||null})})]},r.id)})})]}),c&&(0,$.jsx)(`div`,{className:`flex justify-center mt-3`,children:(0,$.jsx)(z,{minimal:!0,loading:a,text:n(`account.activity.loadMore`,`Load More`),onClick:h})})]})})]})},Ot=({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 ke(),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 Ae(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)(Y,{elevation:I.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)(K,{style:{margin:0},children:n(`account.sessions.title`,`Active Sessions`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[_>0&&(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.DANGER,icon:(0,$.jsx)(c,{size:14}),text:n(`account.sessions.revokeOthers`,`Revoke Other Sessions`),loading:u,onClick:()=>g(!0)}),(0,$.jsx)(z,{minimal:!0,icon:(0,$.jsx)(f,{size:14}),onClick:()=>v()})]})]}),a?(0,$.jsx)(`div`,{className:`flex justify-center py-4`,children:(0,$.jsx)(ne,{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)(Et,{userAgent:r.user_agent}),r.is_current&&(0,$.jsx)(J,{minimal:!0,intent:U.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?$e(new Date(r.created_at*1e3)):`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:$e(new Date(r.expires_at*1e3))}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.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)(F,{isOpen:h,cancelButtonText:n(`common.cancel`,`Cancel`),confirmButtonText:n(`account.sessions.confirmRevokeOthers`,`Revoke Other Sessions`),intent:U.DANGER,icon:`log-out`,onCancel:()=>g(!1),onConfirm:async()=>{p(!0);try{await Se(),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.`)})})]})},kt=({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 ve({registration_enabled:String(e)}),o?.()}catch(t){console.error(t),S(!e),alert(t.message||s(`common.errorNetwork`,`Network error`))}finally{w(!1)}},E=async()=>{if(!We.test(u)){alert(s(`account.formatTipUsername`));return}if(!Je.test(p)){alert(s(`account.formatTipPassword`));return}v(!0);try{await Ce({username:u,password:await Be(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 Te(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)(K,{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)(z,{className:`whitespace-nowrap`,icon:(0,$.jsx)(D,{size:16}),intent:U.SUCCESS,text:s(`account.createUser`),onClick:()=>l(!0)})]})]}),(0,$.jsx)(Y,{elevation:I.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)(J,{minimal:!0,intent:e.role===`admin`?U.DANGER:U.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)(J,{minimal:!0,intent:U.SUCCESS,children:`TOTP`}),!!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(J,{minimal:!0,intent:U.PRIMARY,children:`Passkey`}),!e.totp_enabled&&!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(J,{minimal:!0,intent:U.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?$e(new Date(e.created_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_active_at?$e(new Date(e.last_active_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_resolve_at?$e(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)(z,{minimal:!0,intent:U.DANGER,icon:(0,$.jsx)(i,{size:14}),disabled:e.id===t,onClick:()=>O(e.id)})})})]},e.id))})]})}),(0,$.jsx)(B,{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)(q,{label:s(`account.username`),children:(0,$.jsx)(G,{value:u,onChange:e=>f(e.target.value),placeholder:s(`auth.usernamePlaceholder`)})}),(0,$.jsx)(q,{label:s(`account.initialPassword`),children:(0,$.jsx)(G,{type:y?`text`:`password`,value:p,onChange:e=>m(e.target.value),placeholder:s(`auth.passwordPlaceholder`),rightElement:(0,$.jsx)(z,{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)(q,{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)(z,{text:s(`account.cancel`),onClick:()=>l(!1)}),(0,$.jsx)(z,{intent:U.PRIMARY,text:s(`account.createNow`),loading:_,onClick:E})]})]})})]})},At=({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 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)(K,{style:{margin:0},children:n(`account.systemSettings`,`System Settings`)})]}),(0,$.jsxs)(Y,{elevation:I.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)(K,{className:`text-sm font-bold opacity-70 text-blue-500`,children:`Cloudflare Turnstile`}),(0,$.jsx)(q,{label:`Site Key`,children:(0,$.jsx)(G,{value:r.turnstile_site_key||``,onChange:e=>i({...r,turnstile_site_key:e.target.value}),placeholder:`0x000...`})}),(0,$.jsx)(q,{label:`Secret Key`,children:(0,$.jsx)(G,{type:s?`text`:`password`,value:r.turnstile_secret_key||``,onChange:e=>i({...r,turnstile_secret_key:e.target.value}),placeholder:`0x000...`,rightElement:(0,$.jsx)(z,{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)(K,{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)(W,{className:`my-4`}),(0,$.jsx)(`div`,{className:`flex justify-end`,children:(0,$.jsx)(z,{intent:U.PRIMARY,icon:`floppy-disk`,text:n(`common.save`,`Save`),loading:a,onClick:async()=>{o(!0);try{await ve({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)}}})})]})]})},jt=({isAdmin:e})=>{let{t}=d(),[n,r]=(0,Q.useState)(null),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(!1),l=(0,Q.useCallback)(async()=>{o(!0);try{r(await Ue())}catch(e){console.error(`Failed to fetch database size:`,e)}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{l()},[l]),(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(K,{className:`text-red-500 flex items-center gap-2`,children:[(0,$.jsx)(i,{size:20}),` `,t(`account.dangerZone`)]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,$.jsxs)(Y,{elevation:I.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(K,{children:t(`account.clearLogs`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-3`,children:t(`account.clearLogsDesc`)}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between p-2.5 mb-4 bg-gray-50 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,$.jsx)(E,{size:15,className:`text-gray-500 flex-shrink-0`}),(0,$.jsxs)(`span`,{className:`text-gray-700 dark:text-gray-300 font-medium`,children:[t(`account.currentDbSize`),`:`]}),a?(0,$.jsx)(ne,{size:14}):(0,$.jsx)(J,{minimal:!0,round:!0,intent:U.PRIMARY,className:`font-mono font-semibold`,children:n?.formatted||`0 B`})]}),(0,$.jsx)(z,{minimal:!0,small:!0,icon:`refresh`,loading:a,onClick:l,title:t(`common.refresh`)||`Refresh`})]})]}),(0,$.jsx)(z,{fill:!0,intent:U.DANGER,text:t(`account.clearLogsBtn`),icon:`trash`,loading:s,onClick:async()=>{if(confirm(t(`account.confirmClearLogs`))){c(!0);try{await je(),alert(t(`account.clearLogsSuccess`)),await l()}catch(e){console.error(e)}finally{c(!1)}}}})]}),!e&&(0,$.jsxs)(Y,{elevation:I.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(K,{children:t(`account.deleteAccount`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-4`,children:t(`account.deleteAccountDesc`)})]}),(0,$.jsx)(z,{fill:!0,intent:U.DANGER,text:t(`account.deleteAccountBtn`),icon:`delete`,onClick:async()=>{if(confirm(t(`account.confirmDeleteAccount`)))try{await Me(),window.location.href=`/`}catch(e){console.error(e),alert(e.message||t(`common.errorNetwork`))}}})]})]}),(0,$.jsx)(H,{intent:U.WARNING,icon:`info-sign`,title:t(`account.inactivityPolicy`),children:(0,$.jsx)(`p`,{className:`text-sm`,children:t(`account.inactivityDesc`)})})]})},Mt=[{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`}],Nt=({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)(Y,{elevation:I.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(_,{size:20,className:`text-blue-500`}),(0,$.jsx)(K,{style:{margin:0},children:f(`account.personalInfo`)})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(q,{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:N.TOP,intent:U.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(G,{fill:!0,value:i,onChange:e=>a(e.target.value),onFocus:()=>c(!0),onBlur:()=>c(!1),autoFocus:!0})})}),(0,$.jsxs)(P,{children:[(0,$.jsx)(z,{icon:(0,$.jsx)(y,{size:16}),intent:U.SUCCESS,loading:o,onClick:l}),(0,$.jsx)(z,{icon:(0,$.jsx)(O,{size:16}),onClick:()=>{n(!1),a(e?.username||``)}})]})]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(G,{fill:!0,value:e?.username,readOnly:!0}),(0,$.jsx)(z,{icon:(0,$.jsx)(r,{size:16}),onClick:()=>n(!0)})]})})}),(0,$.jsx)(q,{label:f(`account.userId`),children:(0,$.jsx)(G,{leftIcon:`id-number`,value:e?.id,disabled:!0})}),(0,$.jsx)(q,{label:f(`account.timezone`,`Timezone`),children:(0,$.jsx)(ie,{fill:!0,value:e?.timezone||``,onChange:e=>u?.(e.target.value||null),options:Mt})})]})]})},Pt=({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)(Y,{elevation:I.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)(K,{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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(z,{small:!0,active:o===`password`,intent:o===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:r(`account.mfa.password`,`Password`),onClick:()=>{s(`password`),E(null)}}),i&&(0,$.jsx)(z,{small:!0,active:o===`passkey`,intent:o===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:r(`account.mfa.passkey`,`Passkey`),onClick:()=>{s(`passkey`),E(null)}}),a&&(0,$.jsx)(z,{small:!0,active:o===`totp`,intent:o===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:r(`account.mfa.totp`,`TOTP`),onClick:()=>{s(`totp`),E(null)}})]})})}),T&&(0,$.jsx)(H,{intent:T.intent,className:`mb-4`,children:T.text}),(0,$.jsxs)(`form`,{onSubmit:async n=>{if(n.preventDefault(),!Je.test(_)){E({text:r(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),intent:U.DANGER});return}if(!e?.username){E({text:r(`auth.sessionExpired`,`Session expired. Please log in again.`),intent:U.DANGER});return}w(!0),E(null);try{let n=await Be(_,e.username);if(o===`passkey`)await xe({passkeyAssertion:await Ie(await He()),newPassword:n});else if(o===`totp`){if(m.length!==6){E({text:r(`account.totp.invalidCode`,`Please enter a 6-digit code`),intent:U.DANGER}),w(!1);return}let e=crypto.randomUUID(),t=new TextEncoder().encode(m+e),i=await crypto.subtle.digest(`SHA-256`,t);await xe({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:U.DANGER}),w(!1);return}let t=c;(e.password_version??1)===2&&(t=await Be(c,e.username)),await xe({oldPassword:t,newPassword:n})}E({text:r(`account.passwordSuccess`,`Password updated successfully!`),intent:U.SUCCESS}),l(``),g(``),v(``),t&&t()}catch(e){E({text:ze(e,r),intent:U.DANGER})}finally{w(!1)}},className:`space-y-4`,children:[o===`password`&&(0,$.jsx)(q,{label:r(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(G,{leftIcon:`lock`,type:f?`text`:`password`,value:c,onChange:e=>l(e.target.value),rightElement:(0,$.jsx)(z,{minimal:!0,icon:f?`eye-open`:`eye-off`,onClick:()=>p(!f),title:r(f?`auth.hidePassword`:`auth.showPassword`)}),required:!0})}),o===`totp`&&(0,$.jsx)(q,{label:r(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Ve,{length:6,value:m,onChange:g,disabled:C})}),o===`passkey`&&(0,$.jsx)(H,{intent:U.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)(q,{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:N.TOP,intent:U.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(G,{leftIcon:`lock`,type:y?`text`:`password`,value:_,onChange:e=>v(e.target.value),onFocus:()=>S(!0),onBlur:()=>S(!1),rightElement:(0,$.jsx)(z,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:r(y?`auth.hidePassword`:`auth.showPassword`)}),required:!0})})})}),(0,$.jsx)(z,{fill:!0,intent:o===`passkey`?U.PRIMARY:U.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`)})]})]})},Ft=({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||!Ze.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 Ye(f,e),o={};if(c===`passkey`)o.passkeyAssertion=await Ie(await He());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 Ke(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 Be(_,r.username)),o.password=e}await de(n,o),p(``),g(``),v(``),S(``),i()}catch(e){E(ze(e,a))}finally{w(!1)}},A=()=>{E(``),p(``),g(``),v(``),b(!1),S(``),l(`password`),t()};return(0,$.jsx)(B,{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:L,children:[T&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:T}),(0,$.jsx)(q,{label:a(`auth.newPin`,`New 4-Digit PIN`),labelFor:`new-pin-input`,helperText:a(`auth.pinHelper`,`Digits only, e.g., 1234`),children:(0,$.jsx)(Ve,{length:4,value:f,onChange:p,type:`password`,disabled:C,autoFocus:!0,onComplete:()=>D.current?.focus()})}),(0,$.jsx)(q,{label:a(`auth.confirmPin`,`Confirm New PIN`),labelFor:`confirm-pin-input`,children:(0,$.jsx)(Ve,{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)(W,{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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(z,{small:!0,active:c===`password`,intent:c===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),E(``)}}),o&&(0,$.jsx)(z,{small:!0,active:c===`passkey`,intent:c===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),E(``)}}),s&&(0,$.jsx)(z,{small:!0,active:c===`totp`,intent:c===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),E(``)}})]})})]}),c===`password`&&(0,$.jsx)(q,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`verify-pw-input`,children:(0,$.jsx)(G,{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)(z,{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)(q,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`verify-totp-input`,children:(0,$.jsx)(Ve,{ref:O,length:6,value:x,onChange:S,disabled:C,onComplete:e=>k(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(H,{intent:U.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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:A,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.PRIMARY,loading:C,children:a(`common.save`,`Save`)})]})})]})})},It=({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 Ie(await He());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 Ke(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 Be(f,r.username)),e.password=t}await fe(e),p(``),v(``),i()}catch(e){C(ze(e,a))}finally{b(!1)}},T=()=>{C(``),p(``),g(!1),v(``),l(`password`),t()};return(0,$.jsx)(B,{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:L,children:[x&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:x}),(0,$.jsx)(H,{intent:U.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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(z,{small:!0,active:c===`password`,intent:c===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),C(``)}}),o&&(0,$.jsx)(z,{small:!0,active:c===`passkey`,intent:c===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),C(``)}}),s&&(0,$.jsx)(z,{small:!0,active:c===`totp`,intent:c===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),C(``)}})]})})]}),c===`password`&&(0,$.jsx)(q,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`disable-pw-input`,children:(0,$.jsx)(G,{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)(z,{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)(q,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`disable-totp-input`,children:(0,$.jsx)(Ve,{length:6,value:_,onChange:v,disabled:y,onComplete:e=>w(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(H,{intent:U.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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:T,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.DANGER,loading:y,children:a(`common.disable`,`Disable`)})]})})]})})},Lt=({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 Fe({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)(Y,{elevation:I.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)(K,{className:`m-0!`,children:r(`auth.sessionLockTitle`,`Idle Session Lock`)})]}),!u&&(0,$.jsx)(z,{icon:`key`,intent:U.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)(z,{icon:`edit`,onClick:m,disabled:i,children:r(`auth.changePin`,`Change PIN`)}),(0,$.jsx)(z,{icon:`trash`,intent:U.DANGER,onClick:()=>{l(!0)},disabled:i,children:r(`auth.disablePin`,`Disable PIN & Lock`)}),(0,$.jsx)(z,{icon:`lock`,intent:U.WARNING,onClick:async()=>{a(!0);try{await qe(),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)(Ft,{isOpen:o,onClose:()=>s(!1),user:e,onSuccess:()=>{s(!1),t()}}),(0,$.jsx)(It,{isOpen:c,onClose:()=>l(!1),user:e,onSuccess:()=>{l(!1),t()}})]})};function Rt({user:e,onRefresh:t,toasterRef:n}){let{t:r}=d(),[i,a]=(0,Q.useState)(null),[o,s]=(0,Q.useState)(!0),[c,l]=(0,Q.useState)(!1),[u,f]=(0,Q.useState)(!1),[p,m]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(!1),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(``),[x,S]=(0,Q.useState)(!1),[C,w]=(0,Q.useState)(``),[T,E]=(0,Q.useState)(``),[D,O]=(0,Q.useState)(null),[k,A]=(0,Q.useState)(!1),j=(0,Q.useCallback)(async()=>{s(!0);try{a(await Z.getUserStatus()),m(Z.isUnlocked())}catch(e){console.error(`[useE2eeCardState] Failed to fetch E2EE status:`,e)}finally{s(!1)}},[]);(0,Q.useEffect)(()=>{j()},[j]);let M=e.passkeys_count&&e.passkeys_count>0||(i?.userPasskeyCount||0)>0,ee=!!i?.enabled,N=(0,Q.useMemo)(()=>{if(!i?.publicKey)return!1;try{let e=JSON.parse(i.publicKey);return e.alg===`P256-MLKEM768`||!!e.pqc_pk}catch{return!1}},[i?.publicKey]),P=async e=>{if(e){l(!0);try{await Z.enableUserE2ee(),n.current?.show({message:r(`account.e2ee.enableSuccess`),intent:U.SUCCESS,icon:`lock`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Failed to enable E2EE:`,e),n.current?.show({message:e.message||r(`account.e2ee.enableError`),intent:U.DANGER,icon:`error`})}finally{l(!1)}}else f(!0)},F=async()=>{l(!0);try{await Z.disableUserE2ee(),n.current?.show({message:r(`account.e2ee.disableSuccess`),intent:U.WARNING,icon:`unlock`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Failed to disable E2EE:`,e),n.current?.show({message:e.message||r(`account.e2ee.disableError`),intent:U.DANGER,icon:`error`})}finally{l(!1),f(!1)}},te=async()=>{l(!0);try{await Z.unlockUser()&&(m(!0),n.current?.show({message:r(`account.e2ee.unlockSuccess`),intent:U.SUCCESS,icon:`tick`}))}catch(e){console.error(`[useE2eeCardState] Failed to unlock private key:`,e),n.current?.show({message:e.message||r(`account.e2ee.unlockError`),intent:U.DANGER,icon:`error`})}finally{l(!1)}},I=async e=>{e.preventDefault();let i=_.trim();if(i){l(!0),b(``);try{await Z.unlockWithRecoveryKey(i);try{let e=await tt({recoveryKey:i});await Z.wrapCurrentKeyForRecovery(e.recovery_key),O(e.recovery_key)}catch(e){console.warn(`[useE2eeCardState] Recovery key auto-rotation failed:`,e)}m(!0),g(!1),v(``),n.current?.show({message:r(`account.e2ee.unlockSuccess`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Recovery unlock failed:`,e),b(e.message||r(`account.e2ee.recoveryUnlockFailed`))}finally{l(!1)}}},L=async()=>{l(!0);try{await Z.enableUserE2ee(),n.current?.show({message:r(`account.e2ee.keypairGenSuccess`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Generate key with Passkey failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.keypairGenError`),intent:U.DANGER,icon:`error`})}finally{l(!1)}},R=async()=>{l(!0);try{await Z.rotateUserE2eeKey(),n.current?.show({message:r(`account.e2ee.upgradePqcSuccess`,`已成功升级到后量子混合加密 (P256-MLKEM768)`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Upgrade to PQC failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.upgradePqcError`,`升级到后量子加密失败`),intent:U.DANGER,icon:`error`})}finally{l(!1)}},z=async e=>{e.preventDefault();let i=C.trim();if(i){l(!0),E(``);try{await Z.initUserE2eeWithRecoveryKey(i);try{let e=await tt({recoveryKey:i});await Z.wrapCurrentKeyForRecovery(e.recovery_key),O(e.recovery_key)}catch(e){console.warn(`[useE2eeCardState] Recovery key auto-rotation failed:`,e)}S(!1),w(``),m(!0),n.current?.show({message:r(`account.e2ee.keypairGenSuccess`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Init keypair with recovery key failed:`,e),E(e.message||r(`account.e2ee.initFailed`))}finally{l(!1)}}},B=()=>{Z.clearStorage(),m(!1),n.current?.show({message:r(`account.e2ee.lockSuccess`,`已锁定,私钥已从本地清除`),intent:U.NONE})},[ne,V]=(0,Q.useState)(!1);return{status:i,loading:o,processing:c,isUnlocked:p,isPqc:N,isLogsE2eeEnabled:ee,hasPasskey:M,isDisableAlertOpen:u,setIsDisableAlertOpen:f,isRecoveryDialogOpen:h,setIsRecoveryDialogOpen:g,recoveryKeyInput:_,setRecoveryKeyInput:v,recoveryUnlockError:y,setRecoveryUnlockError:b,initRecoveryDialogOpen:x,setInitRecoveryDialogOpen:S,initRecoveryKeyInput:C,setInitRecoveryKeyInput:w,initRecoveryError:T,setInitRecoveryError:E,rotatedKey:D,setRotatedKey:O,copiedKey:k,handleToggleLogs:P,handleConfirmDisable:F,handleUnlock:te,handleUnlockWithRecoveryKey:I,handleGenerateKeyWithPasskey:L,handleUpgradeToPqc:R,handleInitWithRecoveryKey:z,handleLockDevice:B,handleCopyRotatedKey:e=>{navigator.clipboard.writeText(e),A(!0),setTimeout(()=>A(!1),2e3)},isResetAlertOpen:ne,setIsResetAlertOpen:V,handleResetAndReinit:async()=>{l(!0);try{await fetch(`/api/account/e2ee?purge=true`,{method:`DELETE`}),Z.clearStorage(),M?(await Z.enableUserE2ee(),n.current?.show({message:r(`account.e2ee.resetAndInitPasskeySuccess`,`密钥对已成功重置并使用通行密钥重新加密!`),intent:U.SUCCESS,icon:`tick`})):(n.current?.show({message:r(`account.e2ee.resetSuccessEnterRecovery`,`旧密钥已清除,请使用恢复密钥初始化新密钥对。`),intent:U.WARNING,icon:`refresh`}),S(!0)),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Reset keypair failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.resetFailed`,`重置密钥对失败`),intent:U.DANGER,icon:`error`})}finally{l(!1),V(!1)}},handleEnrollPasskey:async()=>{l(!0);try{let e=await Ee(),i=e.length>0?e[0].id:`primary`;if(await Z.wrapCurrentKeyForPasskey(i))n.current?.show({message:r(`account.e2ee.enrollPasskeySuccess`,`已成功将通行密钥关联至端到端加密!`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.();else throw Error(r(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`))}catch(e){console.error(`[useE2eeCardState] Enroll passkey failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`),intent:U.DANGER,icon:`error`})}finally{l(!1)}}}}const zt=({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)(K,{style:{margin:0},children:t(`account.e2ee.title`,`E2EE`)}),(0,$.jsx)(J,{intent:e?U.SUCCESS:U.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)(R,{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)(z,{icon:`help`,variant:`minimal`,intent:U.NONE})})]})},Bt=({hasPasskey:e,processing:n,onGenerateKeyWithPasskey:r,onOpenInitRecoveryDialog:i})=>{let{t:a}=d();return(0,$.jsx)(H,{intent:U.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)(z,{intent:U.PRIMARY,small:!0,icon:(0,$.jsx)(t,{size:14}),text:a(`account.e2ee.initPasskeyBtn`),loading:n,onClick:r}):(0,$.jsx)(z,{intent:U.PRIMARY,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.addPasskeyBtn`),onClick:()=>{document.getElementById(`passkeys-section`)?.scrollIntoView({behavior:`smooth`})}}),(0,$.jsx)(z,{intent:U.NONE,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.initRecoveryBtn`),onClick:i})]})]})})},Vt=({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)(W,{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)(J,{intent:r?U.SUCCESS:U.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)(J,{minimal:!0,intent:U.PRIMARY,className:`text-[10px]`,children:v(`account.e2ee.pqcTag`,`PQC / NIST FIPS 203`)}):(0,$.jsx)(z,{small:!0,intent:U.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)(J,{minimal:!0,intent:U.SUCCESS,className:`text-[10px]`,children:v(`account.e2ee.unlocked`)}),o&&(e?.wrappedPasskeys?.length||0)===0&&g&&(0,$.jsx)(z,{small:!0,intent:U.PRIMARY,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.enrollPasskeyBtn`,`关联当前通行密钥`),loading:s,onClick:g}),(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.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)(z,{small:!0,minimal:!0,intent:U.PRIMARY,icon:(0,$.jsx)(f,{size:12}),text:v(`account.e2ee.unlockButton`),loading:s,onClick:m}),(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.NONE,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.unlockRecoveryButton`),onClick:h}),_&&(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.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`)]})]})]})]})},Ht=({isOpen:e,processing:t,onConfirm:n,onCancel:r})=>{let{t:i}=d();return(0,$.jsx)(F,{isOpen:e,confirmButtonText:i(`common.confirmDisable`),cancelButtonText:i(`common.cancel`),intent:U.DANGER,icon:`unlock`,onConfirm:n,onCancel:r,loading:t,children:(0,$.jsx)(`p`,{children:i(`account.e2ee.disableConfirm`)})})},Ut=({isOpen:e,onClose:t,recoveryKeyInput:n,setRecoveryKeyInput:r,recoveryUnlockError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(B,{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:L,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.unlockWithRecoveryDesc`)}),i&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(q,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`recovery-key-input`,children:(0,$.jsx)(G,{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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.unlockConfirm`)})]})})]})})},Wt=({isOpen:e,onClose:t,initRecoveryKeyInput:n,setInitRecoveryKeyInput:r,initRecoveryError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(B,{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:L,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.initWithRecoveryDesc`)}),i&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(q,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`init-recovery-key-input`,children:(0,$.jsx)(G,{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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.generateKeypairBtn`)})]})})]})})},Gt=({rotatedKey:e,onClose:t,copiedKey:n,onCopyKey:r})=>{let{t:i}=d();return(0,$.jsxs)(B,{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:L,children:[(0,$.jsx)(H,{intent:U.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)(z,{intent:U.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:V,children:(0,$.jsx)(`div`,{className:X,children:(0,$.jsx)(z,{intent:U.SUCCESS,onClick:t,text:i(`account.recoveryKey.savedAndClose`)})})})]})},Kt=({isOpen:e,processing:t,hasPasskey:n,onConfirm:r,onCancel:i})=>{let{t:a}=d();return(0,$.jsx)(F,{isOpen:e,confirmButtonText:a(`account.e2ee.confirmResetBtn`,`确认重置并重新生成`),cancelButtonText:a(`common.cancel`,`取消`),intent:U.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`,`确认后将引导您输入当前恢复密钥以完成新密钥对的生成与加密。`)})]})})},qt=({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:M,handleUpgradeToPqc:ee,handleInitWithRecoveryKey:N,handleLockDevice:P,handleCopyRotatedKey:F,isResetAlertOpen:te,setIsResetAlertOpen:L,handleResetAndReinit:R,handleEnrollPasskey:z}=Rt({user:e,onRefresh:t,toasterRef:r});return(0,$.jsxs)(Y,{elevation:I.ONE,className:`space-y-6`,children:[(0,$.jsx)(oe,{ref:r}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(zt,{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)(ne,{size:20})}):i?.hasKeys?(0,$.jsx)(Vt,{status:i,isLogsE2eeEnabled:l,isUnlocked:s,isPqc:c,hasPasskey:u,processing:o,loading:a,onToggleLogs:O,onUpgradeToPqc:ee,onLockDevice:P,onUnlockPasskey:A,onOpenRecoveryUnlockDialog:()=>{_(``),h(!0)},onEnrollPasskey:z,onOpenResetAlert:()=>L(!0)}):(0,$.jsx)(Bt,{hasPasskey:u,processing:o,onGenerateKeyWithPasskey:M,onOpenInitRecoveryDialog:()=>{w(``),S(``),b(!0)}})]}),(0,$.jsx)(Ht,{isOpen:f,processing:o,onConfirm:k,onCancel:()=>p(!1)}),(0,$.jsx)(Kt,{isOpen:te,processing:o,hasPasskey:u,onConfirm:R,onCancel:()=>L(!1)}),(0,$.jsx)(Ut,{isOpen:m,onClose:()=>h(!1),recoveryKeyInput:g,setRecoveryKeyInput:_,recoveryUnlockError:v,processing:o,onSubmit:j}),(0,$.jsx)(Wt,{isOpen:y,onClose:()=>b(!1),initRecoveryKeyInput:x,setInitRecoveryKeyInput:S,initRecoveryError:C,processing:o,onSubmit:N}),(0,$.jsx)(Gt,{rotatedKey:T,onClose:()=>E(null),copiedKey:D,onCopyKey:F})]})},Jt=()=>{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=Ge(),[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 he())}catch(e){console.error(e)}},T=async()=>{try{C(await Oe())}catch(e){console.error(e)}},E=(0,Q.useCallback)(async()=>{try{let e=await ue();if(t(e),_(e.username),window.dispatchEvent(new Event(`user_updated`)),e.timezone){let{setSystemTimeZone:t}=await M(async()=>{let{setSystemTimeZone:e}=await import(`./date-CpvuBM37.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 M(async()=>{let{setSystemLocale:e}=await import(`./date-CpvuBM37.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)(J,{large:!0,round:!0,intent:e.role===`admin`?U.DANGER:U.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)(H,{intent:U.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)(Nt,{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(!We.test(g)){alert(l(`account.formatTipUsername`));return}y(!0);try{await Fe({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 Fe({timezone:e||``}),t(t=>t?{...t,timezone:e}:null);let{setSystemTimeZone:n}=await M(async()=>{let{setSystemTimeZone:e}=await import(`./date-CpvuBM37.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)(Pt,{me:e,onRefresh:E})]}),e&&(0,$.jsx)(St,{user:e,onRefresh:E}),e&&(0,$.jsx)(qt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Lt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Ot,{hoveredSessionId:s,setHoveredSessionId:c}),e&&(0,$.jsx)(Dt,{hoveredSessionId:s,setHoveredSessionId:c}),e?.role===`admin`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(W,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(kt,{users:r,currentUserId:e.id,onRefresh:w,registrationEnabled:S.registration_enabled!==`false`,onRefreshSettings:T})}),(0,$.jsx)(W,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(At,{initialSettings:S,onRefresh:T})})]}),(0,$.jsx)(W,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(jt,{isAdmin:e?.role===`admin`})})]})};export{Jt as AccountView};
|
|
4
|
+
`)).then(()=>{h(!0),setTimeout(()=>h(!1),2e3)})},onDone:()=>c(null)}):e.totp_enabled?(0,$.jsx)(dt,{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 Be(v,e.username)),await pe(n),_(!1),y(``),t()}catch(e){C(e.message||n(`common.errorNetwork`))}finally{x(!1)}}}):(0,$.jsx)(ft,{setupData:r,setupToken:a,setSetupToken:o,setupError:f,setupLoading:l,onStartSetup:async()=>{u(!0),p(``);try{i(await Pe())}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 et({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(``)}})},mt=({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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[r&&(0,$.jsx)(z,{small:!0,active:e===`passkey`,intent:e===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.mfa.passkey`,`Passkey`),onClick:()=>t(`passkey`)}),i&&(0,$.jsx)(z,{small:!0,active:e===`recovery_key`,intent:e===`recovery_key`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:s(`account.recoveryKey.verifyBtn`,`Recovery Key`),onClick:()=>t(`recovery_key`)}),a&&(0,$.jsx)(z,{small:!0,active:e===`totp`,intent:e===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:s(`account.mfa.totp`,`TOTP`),onClick:()=>t(`totp`)}),o&&(0,$.jsx)(z,{small:!0,active:e===`password`,intent:e===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:s(`account.mfa.password`,`Password`),onClick:()=>t(`password`)})]})})})},ht=({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)(z,{fill:!0,large:!0,intent:U.PRIMARY,loading:e,onClick:t,icon:(0,$.jsx)(u,{size:16}),text:n(`account.usePasskeyInstead`,`Authenticate with Passkey`)})]})},gt=({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)(q,{label:i(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Ve,{length:6,value:e,onChange:e=>{t(e),e.length===6&&r(e)},disabled:n})}),(0,$.jsx)(z,{fill:!0,intent:U.PRIMARY,loading:n,disabled:e.length!==6,onClick:()=>r(),text:i(`common.confirm`,`Confirm`)})]})},_t=({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)(q,{label:o(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(G,{leftIcon:`lock`,type:n?`text`:`password`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,rightElement:(0,$.jsx)(z,{minimal:!0,icon:n?`eye-open`:`eye-off`,onClick:()=>r(!n)})})}),(0,$.jsx)(z,{fill:!0,intent:U.PRIMARY,type:`submit`,loading:i,text:o(`common.confirm`,`Confirm`)})]})},vt=({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)(q,{label:i(`account.recoveryKey.verifyPromptLabel`,`原恢复密钥 (Original Recovery Key)`),children:(0,$.jsx)(G,{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)(z,{fill:!0,intent:U.PRIMARY,type:`submit`,loading:n,disabled:!e.trim(),text:i(`common.confirm`,`Confirm`)})]})};var yt=(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 bt=({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=yt(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 Be(g,n.username)),await i({password:e}),t()}catch(e){D(ze(e,o))}finally{T(!1)}},j=async()=>{T(!0),D(``);try{await i({passkeyAssertion:await Ie(await He())}),t()}catch(e){D(ze(e,o))}finally{T(!1)}},M=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(ze(e,o))}finally{T(!1)}},ee=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(ze(e,o))}finally{T(!1)}},N=(c?1:0)+(f?1:0)+(l?1:0)+(u?1:0);return(0,$.jsx)(B,{isOpen:e,onClose:t,title:r||o(`account.verifyIdentity`,`Security Verification`),icon:`shield`,className:`max-w-md w-full`,children:(0,$.jsxs)(`div`,{className:L,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)(mt,{method:m,onSelectMethod:e=>{h(e),D(``)},hasPasskey:c,hasRecoveryKey:f,hasTotp:l,hasPassword:u}),E&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:E}),m===`recovery_key`&&(0,$.jsx)(vt,{recoveryKey:S,setRecoveryKey:C,loading:w,onSubmit:ee}),m===`passkey`&&(0,$.jsx)(ht,{loading:w,onVerify:j}),m===`totp`&&(0,$.jsx)(gt,{totpCode:b,setTotpCode:x,loading:w,onVerify:M}),m===`password`&&(0,$.jsx)(_t,{password:g,setPassword:_,showPassword:v,setShowPassword:y,loading:w,onSubmit:A})]})})},xt=({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 tt(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:U.WARNING}),t();return}}catch{}b({text:r(`account.recoveryKey.rotateSuccess`,`恢复密钥已成功轮换!请立即妥善离线保存新密钥,旧密钥已失效。`),intent:U.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)(K,{style:{margin:0},children:r(`account.recoveryKey.title`,`紧急恢复密钥`)}),(0,$.jsx)(J,{intent:C?U.SUCCESS:U.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:N.TOP,children:(0,$.jsx)(J,{intent:U.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)(z,{small:!0,intent:U.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)(H,{intent:v.intent,className:`my-2`,children:v.text}),c&&(0,$.jsxs)(Y,{elevation:I.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)(z,{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)(z,{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)(z,{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)(F,{isOpen:o,onConfirm:D,onCancel:()=>s(!1),cancelButtonText:r(`common.cancel`,`取消`),confirmButtonText:r(`account.recoveryKey.confirmRotateBtn`,`确认进入轮换验证`),intent:U.DANGER,icon:`warning-sign`,children:(0,$.jsx)(`p`,{children:r(`account.recoveryKey.rotateConfirm`,`轮换恢复密钥将立即使原恢复密钥失效,并重新派生信封加密密钥。仅允许通过现有通行密钥 (Passkey) 或原恢复密钥完成轮换验证。是否继续?`)})}),(0,$.jsx)(bt,{isOpen:i,onClose:()=>a(!1),user:e,allowedMethods:[`passkey`,`recovery_key`],title:r(`account.recoveryKey.rotateVerifyTitle`,`验证身份以轮换恢复密钥`),onVerify:O})]})},St=({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 ge(e),r()}catch(e){alert(e.message||i(`common.errorNetwork`,`Network error`))}finally{o(!1)}};return(0,$.jsxs)(Y,{elevation:I.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)(K,{style:{margin:0},children:i(`account.mfa.title`,`Multi-Factor Authentication (MFA)`)}),(0,$.jsx)(J,{intent:s?U.SUCCESS:U.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)(W,{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)(H,{intent:U.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)(W,{}),(0,$.jsx)(lt,{onRefresh:r}),(0,$.jsx)(W,{}),(0,$.jsx)(pt,{user:e,onRefresh:r}),(0,$.jsx)(W,{}),(0,$.jsx)(xt,{user:e,onRefresh:r})]})},Ct={signup:{label:`account.activity.signup`,icon:(0,$.jsx)(D,{size:14}),intent:U.SUCCESS},login_success:{label:`account.activity.loginSuccess`,icon:(0,$.jsx)(g,{size:14}),intent:U.SUCCESS},login_fail:{label:`account.activity.loginFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER},logout:{label:`account.activity.logout`,icon:(0,$.jsx)(c,{size:14}),intent:U.NONE},password_change_success:{label:`account.activity.pwChangeSuccess`,icon:(0,$.jsx)(u,{size:14}),intent:U.SUCCESS},password_change_fail:{label:`account.activity.pwChangeFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER},totp_verify_success:{label:`account.activity.totpVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:U.SUCCESS},totp_verify_fail:{label:`account.activity.totpVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER},totp_setup:{label:`account.activity.totpSetup`,icon:(0,$.jsx)(a,{size:14}),intent:U.PRIMARY},totp_removed:{label:`account.activity.totpRemoved`,icon:(0,$.jsx)(C,{size:14}),intent:U.WARNING},recovery_key_used:{label:`account.activity.recoveryKeyUsed`,icon:(0,$.jsx)(u,{size:14}),intent:U.WARNING},recovery_key_rotated:{label:`account.activity.recoveryKeyRotated`,icon:(0,$.jsx)(u,{size:14}),intent:U.WARNING},session_revoked:{label:`account.activity.sessionRevoked`,icon:(0,$.jsx)(c,{size:14}),intent:U.WARNING},passkey_registered:{label:`account.activity.passkeyRegistered`,icon:(0,$.jsx)(u,{size:14}),intent:U.PRIMARY},passkey_deleted:{label:`account.activity.passkeyDeleted`,icon:(0,$.jsx)(C,{size:14}),intent:U.WARNING},passkey_verify_success:{label:`account.activity.passkeyVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:U.SUCCESS},passkey_verify_fail:{label:`account.activity.passkeyVerifyFail`,icon:(0,$.jsx)(p,{size:14}),intent:U.DANGER}},wt=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`},Tt=(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},Et=({userAgent:e})=>{let{t}=d();if(!e)return(0,$.jsx)(`span`,{className:`text-gray-500`,children:`—`});let n=Tt(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:wt(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})]})},Dt=({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 De(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=>Ct[e]??{label:e,icon:(0,$.jsx)(s,{size:14}),intent:U.NONE};return(0,$.jsxs)(Y,{elevation:I.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)(K,{style:{margin:0},children:n(`account.activity.title`,`Account Activity`)}),r.length>0&&(0,$.jsxs)(J,{minimal:!0,round:!0,intent:U.NONE,children:[r.length,c?`+`:``]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(z,{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)(ne,{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)(J,{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:$e(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)(Et,{userAgent:r.user_agent||null})})]},r.id)})})]}),c&&(0,$.jsx)(`div`,{className:`flex justify-center mt-3`,children:(0,$.jsx)(z,{minimal:!0,loading:a,text:n(`account.activity.loadMore`,`Load More`),onClick:h})})]})})]})},Ot=({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 ke(),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 Ae(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)(Y,{elevation:I.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)(K,{style:{margin:0},children:n(`account.sessions.title`,`Active Sessions`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[_>0&&(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.DANGER,icon:(0,$.jsx)(c,{size:14}),text:n(`account.sessions.revokeOthers`,`Revoke Other Sessions`),loading:u,onClick:()=>g(!0)}),(0,$.jsx)(z,{minimal:!0,icon:(0,$.jsx)(f,{size:14}),onClick:()=>v()})]})]}),a?(0,$.jsx)(`div`,{className:`flex justify-center py-4`,children:(0,$.jsx)(ne,{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)(Et,{userAgent:r.user_agent}),r.is_current&&(0,$.jsx)(J,{minimal:!0,intent:U.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?$e(new Date(r.created_at*1e3)):`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:$e(new Date(r.expires_at*1e3))}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.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)(F,{isOpen:h,cancelButtonText:n(`common.cancel`,`Cancel`),confirmButtonText:n(`account.sessions.confirmRevokeOthers`,`Revoke Other Sessions`),intent:U.DANGER,icon:`log-out`,onCancel:()=>g(!1),onConfirm:async()=>{p(!0);try{await Se(),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.`)})})]})},kt=({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 ve({registration_enabled:String(e)}),o?.()}catch(t){console.error(t),S(!e),alert(t.message||s(`common.errorNetwork`,`Network error`))}finally{w(!1)}},E=async()=>{if(!We.test(u)){alert(s(`account.formatTipUsername`));return}if(!Je.test(p)){alert(s(`account.formatTipPassword`));return}v(!0);try{await Ce({username:u,password:await Be(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 Te(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)(K,{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)(z,{className:`whitespace-nowrap`,icon:(0,$.jsx)(D,{size:16}),intent:U.SUCCESS,text:s(`account.createUser`),onClick:()=>l(!0)})]})]}),(0,$.jsx)(Y,{elevation:I.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)(J,{minimal:!0,intent:e.role===`admin`?U.DANGER:U.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)(J,{minimal:!0,intent:U.SUCCESS,children:`TOTP`}),!!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(J,{minimal:!0,intent:U.PRIMARY,children:`Passkey`}),!e.totp_enabled&&!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(J,{minimal:!0,intent:U.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?$e(new Date(e.created_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_active_at?$e(new Date(e.last_active_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_resolve_at?$e(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)(z,{minimal:!0,intent:U.DANGER,icon:(0,$.jsx)(i,{size:14}),disabled:e.id===t,onClick:()=>O(e.id)})})})]},e.id))})]})}),(0,$.jsx)(B,{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)(q,{label:s(`account.username`),children:(0,$.jsx)(G,{value:u,onChange:e=>f(e.target.value),placeholder:s(`auth.usernamePlaceholder`)})}),(0,$.jsx)(q,{label:s(`account.initialPassword`),children:(0,$.jsx)(G,{type:y?`text`:`password`,value:p,onChange:e=>m(e.target.value),placeholder:s(`auth.passwordPlaceholder`),rightElement:(0,$.jsx)(z,{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)(q,{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)(z,{text:s(`account.cancel`),onClick:()=>l(!1)}),(0,$.jsx)(z,{intent:U.PRIMARY,text:s(`account.createNow`),loading:_,onClick:E})]})]})})]})},At=({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 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)(K,{style:{margin:0},children:n(`account.systemSettings`,`System Settings`)})]}),(0,$.jsxs)(Y,{elevation:I.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)(K,{className:`text-sm font-bold opacity-70 text-blue-500`,children:`Cloudflare Turnstile`}),(0,$.jsx)(q,{label:`Site Key`,children:(0,$.jsx)(G,{value:r.turnstile_site_key||``,onChange:e=>i({...r,turnstile_site_key:e.target.value}),placeholder:`0x000...`})}),(0,$.jsx)(q,{label:`Secret Key`,children:(0,$.jsx)(G,{type:s?`text`:`password`,value:r.turnstile_secret_key||``,onChange:e=>i({...r,turnstile_secret_key:e.target.value}),placeholder:`0x000...`,rightElement:(0,$.jsx)(z,{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)(K,{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)(W,{className:`my-4`}),(0,$.jsx)(`div`,{className:`flex justify-end`,children:(0,$.jsx)(z,{intent:U.PRIMARY,icon:`floppy-disk`,text:n(`common.save`,`Save`),loading:a,onClick:async()=>{o(!0);try{await ve({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)}}})})]})]})},jt=({isAdmin:e})=>{let{t}=d(),[n,r]=(0,Q.useState)(null),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(!1),l=(0,Q.useCallback)(async()=>{o(!0);try{r(await Ue())}catch(e){console.error(`Failed to fetch database size:`,e)}finally{o(!1)}},[]);return(0,Q.useEffect)(()=>{l()},[l]),(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(K,{className:`text-red-500 flex items-center gap-2`,children:[(0,$.jsx)(i,{size:20}),` `,t(`account.dangerZone`)]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,$.jsxs)(Y,{elevation:I.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(K,{children:t(`account.clearLogs`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-3`,children:t(`account.clearLogsDesc`)}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between p-2.5 mb-4 bg-gray-50 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,$.jsx)(E,{size:15,className:`text-gray-500 flex-shrink-0`}),(0,$.jsxs)(`span`,{className:`text-gray-700 dark:text-gray-300 font-medium`,children:[t(`account.currentDbSize`),`:`]}),a?(0,$.jsx)(ne,{size:14}):(0,$.jsx)(J,{minimal:!0,round:!0,intent:U.PRIMARY,className:`font-mono font-semibold`,children:n?.formatted||`0 B`})]}),(0,$.jsx)(z,{minimal:!0,small:!0,icon:`refresh`,loading:a,onClick:l,title:t(`common.refresh`)||`Refresh`})]})]}),(0,$.jsx)(z,{fill:!0,intent:U.DANGER,text:t(`account.clearLogsBtn`),icon:`trash`,loading:s,onClick:async()=>{if(confirm(t(`account.confirmClearLogs`))){c(!0);try{await je(),alert(t(`account.clearLogsSuccess`)),await l()}catch(e){console.error(e)}finally{c(!1)}}}})]}),!e&&(0,$.jsxs)(Y,{elevation:I.ONE,className:`flex flex-col justify-between`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(K,{children:t(`account.deleteAccount`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-4`,children:t(`account.deleteAccountDesc`)})]}),(0,$.jsx)(z,{fill:!0,intent:U.DANGER,text:t(`account.deleteAccountBtn`),icon:`delete`,onClick:async()=>{if(confirm(t(`account.confirmDeleteAccount`)))try{await Me(),window.location.href=`/`}catch(e){console.error(e),alert(e.message||t(`common.errorNetwork`))}}})]})]}),(0,$.jsx)(H,{intent:U.WARNING,icon:`info-sign`,title:t(`account.inactivityPolicy`),children:(0,$.jsx)(`p`,{className:`text-sm`,children:t(`account.inactivityDesc`)})})]})},Mt=[{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`}],Nt=({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)(Y,{elevation:I.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(_,{size:20,className:`text-blue-500`}),(0,$.jsx)(K,{style:{margin:0},children:f(`account.personalInfo`)})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(q,{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:N.TOP,intent:U.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(G,{fill:!0,value:i,onChange:e=>a(e.target.value),onFocus:()=>c(!0),onBlur:()=>c(!1),autoFocus:!0})})}),(0,$.jsxs)(P,{children:[(0,$.jsx)(z,{icon:(0,$.jsx)(y,{size:16}),intent:U.SUCCESS,loading:o,onClick:l}),(0,$.jsx)(z,{icon:(0,$.jsx)(O,{size:16}),onClick:()=>{n(!1),a(e?.username||``)}})]})]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(G,{fill:!0,value:e?.username,readOnly:!0}),(0,$.jsx)(z,{icon:(0,$.jsx)(r,{size:16}),onClick:()=>n(!0)})]})})}),(0,$.jsx)(q,{label:f(`account.userId`),children:(0,$.jsx)(G,{leftIcon:`id-number`,value:e?.id,disabled:!0})}),(0,$.jsx)(q,{label:f(`account.timezone`,`Timezone`),children:(0,$.jsx)(ie,{fill:!0,value:e?.timezone||``,onChange:e=>u?.(e.target.value||null),options:Mt})})]})]})},Pt=({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)(Y,{elevation:I.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)(K,{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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(z,{small:!0,active:o===`password`,intent:o===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:r(`account.mfa.password`,`Password`),onClick:()=>{s(`password`),E(null)}}),i&&(0,$.jsx)(z,{small:!0,active:o===`passkey`,intent:o===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:r(`account.mfa.passkey`,`Passkey`),onClick:()=>{s(`passkey`),E(null)}}),a&&(0,$.jsx)(z,{small:!0,active:o===`totp`,intent:o===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:r(`account.mfa.totp`,`TOTP`),onClick:()=>{s(`totp`),E(null)}})]})})}),T&&(0,$.jsx)(H,{intent:T.intent,className:`mb-4`,children:T.text}),(0,$.jsxs)(`form`,{onSubmit:async n=>{if(n.preventDefault(),!Je.test(_)){E({text:r(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),intent:U.DANGER});return}if(!e?.username){E({text:r(`auth.sessionExpired`,`Session expired. Please log in again.`),intent:U.DANGER});return}w(!0),E(null);try{let n=await Be(_,e.username);if(o===`passkey`)await xe({passkeyAssertion:await Ie(await He()),newPassword:n});else if(o===`totp`){if(m.length!==6){E({text:r(`account.totp.invalidCode`,`Please enter a 6-digit code`),intent:U.DANGER}),w(!1);return}let e=crypto.randomUUID(),t=new TextEncoder().encode(m+e),i=await crypto.subtle.digest(`SHA-256`,t);await xe({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:U.DANGER}),w(!1);return}let t=c;(e.password_version??1)===2&&(t=await Be(c,e.username)),await xe({oldPassword:t,newPassword:n})}E({text:r(`account.passwordSuccess`,`Password updated successfully!`),intent:U.SUCCESS}),l(``),g(``),v(``),t&&t()}catch(e){E({text:ze(e,r),intent:U.DANGER})}finally{w(!1)}},className:`space-y-4`,children:[o===`password`&&(0,$.jsx)(q,{label:r(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(G,{leftIcon:`lock`,type:f?`text`:`password`,value:c,onChange:e=>l(e.target.value),rightElement:(0,$.jsx)(z,{minimal:!0,icon:f?`eye-open`:`eye-off`,onClick:()=>p(!f),title:r(f?`auth.hidePassword`:`auth.showPassword`)}),required:!0})}),o===`totp`&&(0,$.jsx)(q,{label:r(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(Ve,{length:6,value:m,onChange:g,disabled:C})}),o===`passkey`&&(0,$.jsx)(H,{intent:U.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)(q,{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:N.TOP,intent:U.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(G,{leftIcon:`lock`,type:y?`text`:`password`,value:_,onChange:e=>v(e.target.value),onFocus:()=>S(!0),onBlur:()=>S(!1),rightElement:(0,$.jsx)(z,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:r(y?`auth.hidePassword`:`auth.showPassword`)}),required:!0})})})}),(0,$.jsx)(z,{fill:!0,intent:o===`passkey`?U.PRIMARY:U.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`)})]})]})},Ft=({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||!Ze.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 Ye(f,e),o={};if(c===`passkey`)o.passkeyAssertion=await Ie(await He());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 Ke(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 Be(_,r.username)),o.password=e}await de(n,o),p(``),g(``),v(``),S(``),i()}catch(e){E(ze(e,a))}finally{w(!1)}},A=()=>{E(``),p(``),g(``),v(``),b(!1),S(``),l(`password`),t()};return(0,$.jsx)(B,{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:L,children:[T&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:T}),(0,$.jsx)(q,{label:a(`auth.newPin`,`New 4-Digit PIN`),labelFor:`new-pin-input`,helperText:a(`auth.pinHelper`,`Digits only, e.g., 1234`),children:(0,$.jsx)(Ve,{length:4,value:f,onChange:p,type:`password`,disabled:C,autoFocus:!0,onComplete:()=>D.current?.focus()})}),(0,$.jsx)(q,{label:a(`auth.confirmPin`,`Confirm New PIN`),labelFor:`confirm-pin-input`,children:(0,$.jsx)(Ve,{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)(W,{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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(z,{small:!0,active:c===`password`,intent:c===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),E(``)}}),o&&(0,$.jsx)(z,{small:!0,active:c===`passkey`,intent:c===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),E(``)}}),s&&(0,$.jsx)(z,{small:!0,active:c===`totp`,intent:c===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),E(``)}})]})})]}),c===`password`&&(0,$.jsx)(q,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`verify-pw-input`,children:(0,$.jsx)(G,{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)(z,{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)(q,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`verify-totp-input`,children:(0,$.jsx)(Ve,{ref:O,length:6,value:x,onChange:S,disabled:C,onComplete:e=>k(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(H,{intent:U.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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:A,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.PRIMARY,loading:C,children:a(`common.save`,`Save`)})]})})]})})},It=({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 Ie(await He());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 Ke(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 Be(f,r.username)),e.password=t}await fe(e),p(``),v(``),i()}catch(e){C(ze(e,a))}finally{b(!1)}},T=()=>{C(``),p(``),g(!1),v(``),l(`password`),t()};return(0,$.jsx)(B,{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:L,children:[x&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-4`,children:x}),(0,$.jsx)(H,{intent:U.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)(P,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(z,{small:!0,active:c===`password`,intent:c===`password`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(h,{size:14}),text:a(`account.mfa.password`,`Password`),onClick:()=>{l(`password`),C(``)}}),o&&(0,$.jsx)(z,{small:!0,active:c===`passkey`,intent:c===`passkey`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(u,{size:14}),text:a(`account.mfa.passkey`,`Passkey`),onClick:()=>{l(`passkey`),C(``)}}),s&&(0,$.jsx)(z,{small:!0,active:c===`totp`,intent:c===`totp`?U.PRIMARY:U.NONE,icon:(0,$.jsx)(n,{size:14}),text:a(`account.mfa.totp`,`TOTP`),onClick:()=>{l(`totp`),C(``)}})]})})]}),c===`password`&&(0,$.jsx)(q,{label:a(`auth.currentPassword`,`Current Password`),labelFor:`disable-pw-input`,children:(0,$.jsx)(G,{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)(z,{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)(q,{label:a(`auth.totpCode`,`TOTP Code`),labelFor:`disable-totp-input`,children:(0,$.jsx)(Ve,{length:6,value:_,onChange:v,disabled:y,onComplete:e=>w(void 0,e),autoFocus:!0})}),c===`passkey`&&(0,$.jsx)(H,{intent:U.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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:T,children:a(`common.cancel`,`Cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.DANGER,loading:y,children:a(`common.disable`,`Disable`)})]})})]})})},Lt=({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 Fe({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)(Y,{elevation:I.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)(K,{className:`m-0!`,children:r(`auth.sessionLockTitle`,`Idle Session Lock`)})]}),!u&&(0,$.jsx)(z,{icon:`key`,intent:U.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)(z,{icon:`edit`,onClick:m,disabled:i,children:r(`auth.changePin`,`Change PIN`)}),(0,$.jsx)(z,{icon:`trash`,intent:U.DANGER,onClick:()=>{l(!0)},disabled:i,children:r(`auth.disablePin`,`Disable PIN & Lock`)}),(0,$.jsx)(z,{icon:`lock`,intent:U.WARNING,onClick:async()=>{a(!0);try{await qe(),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)(Ft,{isOpen:o,onClose:()=>s(!1),user:e,onSuccess:()=>{s(!1),t()}}),(0,$.jsx)(It,{isOpen:c,onClose:()=>l(!1),user:e,onSuccess:()=>{l(!1),t()}})]})};function Rt({user:e,onRefresh:t,toasterRef:n}){let{t:r}=d(),[i,a]=(0,Q.useState)(null),[o,s]=(0,Q.useState)(!0),[c,l]=(0,Q.useState)(!1),[u,f]=(0,Q.useState)(!1),[p,m]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(!1),[_,v]=(0,Q.useState)(``),[y,b]=(0,Q.useState)(``),[x,S]=(0,Q.useState)(!1),[C,w]=(0,Q.useState)(``),[T,E]=(0,Q.useState)(``),[D,O]=(0,Q.useState)(null),[k,A]=(0,Q.useState)(!1),j=(0,Q.useCallback)(async()=>{s(!0);try{a(await Z.getUserStatus()),m(Z.isUnlocked())}catch(e){console.error(`[useE2eeCardState] Failed to fetch E2EE status:`,e)}finally{s(!1)}},[]);(0,Q.useEffect)(()=>{j()},[j]);let M=e.passkeys_count&&e.passkeys_count>0||(i?.userPasskeyCount||0)>0,ee=!!i?.enabled,N=(0,Q.useMemo)(()=>{if(!i?.publicKey)return!1;try{let e=JSON.parse(i.publicKey);return e.alg===`P256-MLKEM768`||!!e.pqc_pk}catch{return!1}},[i?.publicKey]),P=async e=>{if(e){l(!0);try{await Z.enableUserE2ee(),n.current?.show({message:r(`account.e2ee.enableSuccess`),intent:U.SUCCESS,icon:`lock`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Failed to enable E2EE:`,e),n.current?.show({message:e.message||r(`account.e2ee.enableError`),intent:U.DANGER,icon:`error`})}finally{l(!1)}}else f(!0)},F=async()=>{l(!0);try{await Z.disableUserE2ee(),n.current?.show({message:r(`account.e2ee.disableSuccess`),intent:U.WARNING,icon:`unlock`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Failed to disable E2EE:`,e),n.current?.show({message:e.message||r(`account.e2ee.disableError`),intent:U.DANGER,icon:`error`})}finally{l(!1),f(!1)}},te=async()=>{l(!0);try{await Z.unlockUser()&&(m(!0),n.current?.show({message:r(`account.e2ee.unlockSuccess`),intent:U.SUCCESS,icon:`tick`}))}catch(e){console.error(`[useE2eeCardState] Failed to unlock private key:`,e),n.current?.show({message:e.message||r(`account.e2ee.unlockError`),intent:U.DANGER,icon:`error`})}finally{l(!1)}},I=async e=>{e.preventDefault();let i=_.trim();if(i){l(!0),b(``);try{await Z.unlockWithRecoveryKey(i);try{let e=await tt({recoveryKey:i});await Z.wrapCurrentKeyForRecovery(e.recovery_key),O(e.recovery_key)}catch(e){console.warn(`[useE2eeCardState] Recovery key auto-rotation failed:`,e)}m(!0),g(!1),v(``),n.current?.show({message:r(`account.e2ee.unlockSuccess`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Recovery unlock failed:`,e),b(e.message||r(`account.e2ee.recoveryUnlockFailed`))}finally{l(!1)}}},L=async()=>{l(!0);try{await Z.enableUserE2ee(),n.current?.show({message:r(`account.e2ee.keypairGenSuccess`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Generate key with Passkey failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.keypairGenError`),intent:U.DANGER,icon:`error`})}finally{l(!1)}},R=async()=>{l(!0);try{await Z.rotateUserE2eeKey(),n.current?.show({message:r(`account.e2ee.upgradePqcSuccess`,`已成功升级到后量子混合加密 (P256-MLKEM768)`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Upgrade to PQC failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.upgradePqcError`,`升级到后量子加密失败`),intent:U.DANGER,icon:`error`})}finally{l(!1)}},z=async e=>{e.preventDefault();let i=C.trim();if(i){l(!0),E(``);try{await Z.initUserE2eeWithRecoveryKey(i);try{let e=await tt({recoveryKey:i});await Z.wrapCurrentKeyForRecovery(e.recovery_key),O(e.recovery_key)}catch(e){console.warn(`[useE2eeCardState] Recovery key auto-rotation failed:`,e)}S(!1),w(``),m(!0),n.current?.show({message:r(`account.e2ee.keypairGenSuccess`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Init keypair with recovery key failed:`,e),E(e.message||r(`account.e2ee.initFailed`))}finally{l(!1)}}},B=()=>{Z.clearStorage(),m(!1),n.current?.show({message:r(`account.e2ee.lockSuccess`,`已锁定,私钥已从本地清除`),intent:U.NONE})},[ne,V]=(0,Q.useState)(!1);return{status:i,loading:o,processing:c,isUnlocked:p,isPqc:N,isLogsE2eeEnabled:ee,hasPasskey:M,isDisableAlertOpen:u,setIsDisableAlertOpen:f,isRecoveryDialogOpen:h,setIsRecoveryDialogOpen:g,recoveryKeyInput:_,setRecoveryKeyInput:v,recoveryUnlockError:y,setRecoveryUnlockError:b,initRecoveryDialogOpen:x,setInitRecoveryDialogOpen:S,initRecoveryKeyInput:C,setInitRecoveryKeyInput:w,initRecoveryError:T,setInitRecoveryError:E,rotatedKey:D,setRotatedKey:O,copiedKey:k,handleToggleLogs:P,handleConfirmDisable:F,handleUnlock:te,handleUnlockWithRecoveryKey:I,handleGenerateKeyWithPasskey:L,handleUpgradeToPqc:R,handleInitWithRecoveryKey:z,handleLockDevice:B,handleCopyRotatedKey:e=>{navigator.clipboard.writeText(e),A(!0),setTimeout(()=>A(!1),2e3)},isResetAlertOpen:ne,setIsResetAlertOpen:V,handleResetAndReinit:async()=>{l(!0);try{await fetch(`/api/account/e2ee?purge=true`,{method:`DELETE`}),Z.clearStorage(),M?(await Z.enableUserE2ee(),n.current?.show({message:r(`account.e2ee.resetAndInitPasskeySuccess`,`密钥对已成功重置并使用通行密钥重新加密!`),intent:U.SUCCESS,icon:`tick`})):(n.current?.show({message:r(`account.e2ee.resetSuccessEnterRecovery`,`旧密钥已清除,请使用恢复密钥初始化新密钥对。`),intent:U.WARNING,icon:`refresh`}),S(!0)),await j(),t?.()}catch(e){console.error(`[useE2eeCardState] Reset keypair failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.resetFailed`,`重置密钥对失败`),intent:U.DANGER,icon:`error`})}finally{l(!1),V(!1)}},handleEnrollPasskey:async()=>{l(!0);try{let e=await Ee(),i=e.length>0?e[0].id:`primary`;if(await Z.wrapCurrentKeyForPasskey(i))n.current?.show({message:r(`account.e2ee.enrollPasskeySuccess`,`已成功将通行密钥关联至端到端加密!`),intent:U.SUCCESS,icon:`tick`}),await j(),t?.();else throw Error(r(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`))}catch(e){console.error(`[useE2eeCardState] Enroll passkey failed:`,e),n.current?.show({message:e.message||r(`account.e2ee.enrollPasskeyFailed`,`关联通行密钥失败`),intent:U.DANGER,icon:`error`})}finally{l(!1)}}}}const zt=({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)(K,{style:{margin:0},children:t(`account.e2ee.title`,`E2EE`)}),(0,$.jsx)(J,{intent:e?U.SUCCESS:U.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)(R,{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)(z,{icon:`help`,variant:`minimal`,intent:U.NONE})})]})},Bt=({hasPasskey:e,processing:n,onGenerateKeyWithPasskey:r,onOpenInitRecoveryDialog:i})=>{let{t:a}=d();return(0,$.jsx)(H,{intent:U.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)(z,{intent:U.PRIMARY,small:!0,icon:(0,$.jsx)(t,{size:14}),text:a(`account.e2ee.initPasskeyBtn`),loading:n,onClick:r}):(0,$.jsx)(z,{intent:U.PRIMARY,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.addPasskeyBtn`),onClick:()=>{document.getElementById(`passkeys-section`)?.scrollIntoView({behavior:`smooth`})}}),(0,$.jsx)(z,{intent:U.NONE,small:!0,icon:(0,$.jsx)(u,{size:14}),text:a(`account.e2ee.initRecoveryBtn`),onClick:i})]})]})})},Vt=({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)(W,{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)(J,{intent:r?U.SUCCESS:U.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)(J,{minimal:!0,intent:U.PRIMARY,className:`text-[10px]`,children:v(`account.e2ee.pqcTag`,`PQC / NIST FIPS 203`)}):(0,$.jsx)(z,{small:!0,intent:U.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)(J,{minimal:!0,intent:U.SUCCESS,className:`text-[10px]`,children:v(`account.e2ee.unlocked`)}),o&&(e?.wrappedPasskeys?.length||0)===0&&g&&(0,$.jsx)(z,{small:!0,intent:U.PRIMARY,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.enrollPasskeyBtn`,`关联当前通行密钥`),loading:s,onClick:g}),(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.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)(z,{small:!0,minimal:!0,intent:U.PRIMARY,icon:(0,$.jsx)(f,{size:12}),text:v(`account.e2ee.unlockButton`),loading:s,onClick:m}),(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.NONE,icon:(0,$.jsx)(t,{size:12}),text:v(`account.e2ee.unlockRecoveryButton`),onClick:h}),_&&(0,$.jsx)(z,{small:!0,minimal:!0,intent:U.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`)]})]})]})]})},Ht=({isOpen:e,processing:t,onConfirm:n,onCancel:r})=>{let{t:i}=d();return(0,$.jsx)(F,{isOpen:e,confirmButtonText:i(`common.confirmDisable`),cancelButtonText:i(`common.cancel`),intent:U.DANGER,icon:`unlock`,onConfirm:n,onCancel:r,loading:t,children:(0,$.jsx)(`p`,{children:i(`account.e2ee.disableConfirm`)})})},Ut=({isOpen:e,onClose:t,recoveryKeyInput:n,setRecoveryKeyInput:r,recoveryUnlockError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(B,{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:L,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.unlockWithRecoveryDesc`)}),i&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(q,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`recovery-key-input`,children:(0,$.jsx)(G,{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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.unlockConfirm`)})]})})]})})},Wt=({isOpen:e,onClose:t,initRecoveryKeyInput:n,setInitRecoveryKeyInput:r,initRecoveryError:i,processing:a,onSubmit:o})=>{let{t:s}=d();return(0,$.jsx)(B,{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:L,children:[(0,$.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:s(`account.e2ee.initWithRecoveryDesc`)}),i&&(0,$.jsx)(H,{intent:U.DANGER,className:`mb-3 text-xs`,children:i}),(0,$.jsx)(q,{label:s(`account.e2ee.recoveryKeyInputLabel`),labelFor:`init-recovery-key-input`,children:(0,$.jsx)(G,{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:V,children:(0,$.jsxs)(`div`,{className:X,children:[(0,$.jsx)(z,{onClick:t,text:s(`common.cancel`)}),(0,$.jsx)(z,{type:`submit`,intent:U.PRIMARY,loading:a,disabled:!n.trim(),text:s(`account.e2ee.generateKeypairBtn`)})]})})]})})},Gt=({rotatedKey:e,onClose:t,copiedKey:n,onCopyKey:r})=>{let{t:i}=d();return(0,$.jsxs)(B,{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:L,children:[(0,$.jsx)(H,{intent:U.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)(z,{intent:U.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:V,children:(0,$.jsx)(`div`,{className:X,children:(0,$.jsx)(z,{intent:U.SUCCESS,onClick:t,text:i(`account.recoveryKey.savedAndClose`)})})})]})},Kt=({isOpen:e,processing:t,hasPasskey:n,onConfirm:r,onCancel:i})=>{let{t:a}=d();return(0,$.jsx)(F,{isOpen:e,confirmButtonText:a(`account.e2ee.confirmResetBtn`,`确认重置并重新生成`),cancelButtonText:a(`common.cancel`,`取消`),intent:U.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`,`确认后将引导您输入当前恢复密钥以完成新密钥对的生成与加密。`)})]})})},qt=({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:M,handleUpgradeToPqc:ee,handleInitWithRecoveryKey:N,handleLockDevice:P,handleCopyRotatedKey:F,isResetAlertOpen:te,setIsResetAlertOpen:L,handleResetAndReinit:R,handleEnrollPasskey:z}=Rt({user:e,onRefresh:t,toasterRef:r});return(0,$.jsxs)(Y,{elevation:I.ONE,className:`space-y-6`,children:[(0,$.jsx)(oe,{ref:r}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(zt,{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)(ne,{size:20})}):i?.hasKeys?(0,$.jsx)(Vt,{status:i,isLogsE2eeEnabled:l,isUnlocked:s,isPqc:c,hasPasskey:u,processing:o,loading:a,onToggleLogs:O,onUpgradeToPqc:ee,onLockDevice:P,onUnlockPasskey:A,onOpenRecoveryUnlockDialog:()=>{_(``),h(!0)},onEnrollPasskey:z,onOpenResetAlert:()=>L(!0)}):(0,$.jsx)(Bt,{hasPasskey:u,processing:o,onGenerateKeyWithPasskey:M,onOpenInitRecoveryDialog:()=>{w(``),S(``),b(!0)}})]}),(0,$.jsx)(Ht,{isOpen:f,processing:o,onConfirm:k,onCancel:()=>p(!1)}),(0,$.jsx)(Kt,{isOpen:te,processing:o,hasPasskey:u,onConfirm:R,onCancel:()=>L(!1)}),(0,$.jsx)(Ut,{isOpen:m,onClose:()=>h(!1),recoveryKeyInput:g,setRecoveryKeyInput:_,recoveryUnlockError:v,processing:o,onSubmit:j}),(0,$.jsx)(Wt,{isOpen:y,onClose:()=>b(!1),initRecoveryKeyInput:x,setInitRecoveryKeyInput:S,initRecoveryError:C,processing:o,onSubmit:N}),(0,$.jsx)(Gt,{rotatedKey:T,onClose:()=>E(null),copiedKey:D,onCopyKey:F})]})},Jt=()=>{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=Ge(),[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 he())}catch(e){console.error(e)}},T=async()=>{try{C(await Oe())}catch(e){console.error(e)}},E=(0,Q.useCallback)(async()=>{try{let e=await ue();if(t(e),_(e.username),window.dispatchEvent(new Event(`user_updated`)),e.timezone){let{setSystemTimeZone:t}=await M(async()=>{let{setSystemTimeZone:e}=await import(`./date-DxXxDqte.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 M(async()=>{let{setSystemLocale:e}=await import(`./date-DxXxDqte.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)(J,{large:!0,round:!0,intent:e.role===`admin`?U.DANGER:U.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)(H,{intent:U.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)(Nt,{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(!We.test(g)){alert(l(`account.formatTipUsername`));return}y(!0);try{await Fe({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 Fe({timezone:e||``}),t(t=>t?{...t,timezone:e}:null);let{setSystemTimeZone:n}=await M(async()=>{let{setSystemTimeZone:e}=await import(`./date-DxXxDqte.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)(Pt,{me:e,onRefresh:E})]}),e&&(0,$.jsx)(St,{user:e,onRefresh:E}),e&&(0,$.jsx)(qt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Lt,{user:e,onRefresh:E}),e&&(0,$.jsx)(Ot,{hoveredSessionId:s,setHoveredSessionId:c}),e&&(0,$.jsx)(Dt,{hoveredSessionId:s,setHoveredSessionId:c}),e?.role===`admin`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(W,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(kt,{users:r,currentUserId:e.id,onRefresh:w,registrationEnabled:S.registration_enabled!==`false`,onRefreshSettings:T})}),(0,$.jsx)(W,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(At,{initialSettings:S,onRefresh:T})})]}),(0,$.jsx)(W,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(jt,{isAdmin:e?.role===`admin`})})]})};export{Jt as AccountView};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TrendChart-
|
|
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-BmoHsW1x.js";import{S as l,b as u,x as d}from"./vendor-icons-other-Bme3ywH9.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-CY_WyMIf.js";import{_t as E}from"./vendor-utils-BWSB0jGn.js";import{at as D,j as O,k,ln as A,ot as j,st as M}from"./index-dXN_pYn1.js";import{t as N}from"./getFlagEmoji-DRubsb7D.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)(()=>{D(e).then(e=>f(e)).catch(e=>console.error(`[useAnalyticsData] Failed to load access points:`,e))},[e]),(0,P.useEffect)(()=>{M(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{O.isUnlocked()&&await k.reDecryptLocalLogs(e)}catch{}try{if(await k.init()){let t=await k.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 j(e,``,i)}catch{let[t,n,r,a,o,c]=await Promise.all([j(e,`summary`,i),j(e,`trend`,i),j(e,`top_allowed`,i),j(e,`top_blocked`,i),j(e,`clients`,i),j(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{k.syncProfileLogs(e,void 0,c).then(async t=>{if(t>0)try{let t=await k.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-CCR1W3fC.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-9Yc54Mdj.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=A(),{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};
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TrendChart-CvhWAoL-.js","assets/index-CP2FJpkF.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-BmoHsW1x.js","assets/vendor-ui-core-CY_WyMIf.js","assets/vendor-utils-BWSB0jGn.js","assets/vendor-i18next-BKUzkAKP.js","assets/index-Bheo8y3N.css","assets/DestinationMap-BYS-QPrT.js","assets/formatCountryName-CSBD8pP8.js","assets/getFlagEmoji-sHq5YwT3.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-BmoHsW1x.js";import{S as l,b as u,x as d}from"./vendor-icons-other-Bme3ywH9.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-CY_WyMIf.js";import{_t as E}from"./vendor-utils-BWSB0jGn.js";import{at as D,j as O,k,ln as A,ot as j,st as M}from"./index-CP2FJpkF.js";import{t as N}from"./getFlagEmoji-sHq5YwT3.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)(()=>{D(e).then(e=>f(e)).catch(e=>console.error(`[useAnalyticsData] Failed to load access points:`,e))},[e]),(0,P.useEffect)(()=>{M(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{O.isUnlocked()&&await k.reDecryptLocalLogs(e)}catch{}try{if(await k.init()){let t=await k.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 j(e,``,i)}catch{let[t,n,r,a,o,c]=await Promise.all([j(e,`summary`,i),j(e,`trend`,i),j(e,`top_allowed`,i),j(e,`top_blocked`,i),j(e,`clients`,i),j(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{k.syncProfileLogs(e,void 0,c).then(async t=>{if(t>0)try{let t=await k.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-CvhWAoL-.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-BYS-QPrT.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=A(),{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};
|