dns-worker 1.0.24 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -109
- package/dist/serverfull.mjs +5319 -911
- package/migrations/0052_add_e2ee_to_logs.sql +6 -0
- package/migrations/0053_add_e2ee_key_tables.sql +31 -0
- package/migrations/0054_drop_hourly_rollups.sql +12 -0
- package/migrations/0055_add_is_active_to_user_log_keys.sql +2 -0
- package/migrations/0056_add_kem_keys_and_encrypt_version.sql +21 -0
- package/migrations/0057_add_idx_logs_kem_key_id.sql +2 -0
- package/package.json +8 -5
- package/static/_headers +8 -0
- package/static/assets/AccountView-CdfTI-rw.js +4 -0
- package/static/assets/AnalyticsView-DE25Td6t.js +2 -0
- package/static/assets/AuthView-DeKX1gG-.js +2 -0
- package/static/assets/DestinationMap-CRCdjD4S.js +1 -0
- package/static/assets/FilteringView-9SF7vAn0.js +1 -0
- package/static/assets/LogsView-DGXuCkRb.js +5 -0
- package/static/assets/QRCodeCanvas-9YjBSnzo.js +2 -0
- package/static/assets/RulesView-C8mXn9m8.js +1 -0
- package/static/assets/SettingsView-yiZeyh7q.js +1 -0
- package/static/assets/SetupView-r5GQKPN4.js +1 -0
- package/static/assets/{SwipeableDrawer-CzMJdF3W.js → SwipeableDrawer-DuXKmSrw.js} +1 -1
- package/static/assets/{TrendChart-Dl9UU7gA.js → TrendChart-BbPOeC8w.js} +3 -3
- package/static/assets/browser-BqNNtPRD.js +1 -0
- package/static/assets/date-dnUzoLoj.js +1 -0
- package/static/assets/de-DE-Bvn6LW48.js +10 -0
- package/static/assets/es-ES-BHMlKDw4.js +10 -0
- package/static/assets/fr-FR-DEgfea4H.js +10 -0
- package/static/assets/index-Ct0QwtUk.js +14 -0
- package/static/assets/index-D53KGRYV.css +2 -0
- package/static/assets/ja-JP-C1UasoOt.js +10 -0
- package/static/assets/ko-KR-DRVmuXAK.js +10 -0
- package/static/assets/ru-RU-BrUQ8HMM.js +10 -0
- package/static/assets/services-unF2tLc7.js +1 -0
- package/static/assets/sqlite.worker-C50yoTbX.js +186 -0
- package/static/assets/sqlite3-Con_VOcu.wasm +0 -0
- package/static/assets/sqlite3-opfs-async-proxy-Ck-yCayi.js +881 -0
- package/static/assets/sqlite3-opfs-async-proxy.js +881 -0
- package/static/assets/sqlite3-worker1-DZ2OAEkd.js +44 -0
- package/static/assets/vendor-react-GZisTXSQ.js +11 -0
- package/static/assets/{vendor-ui-core-CCxBtqRD.js → vendor-ui-core-BjAOArGo.js} +1 -1
- package/static/assets/vendor-utils-C-1rF3VB.js +9 -0
- package/static/assets/vi-VN-_fj_hwx9.js +10 -0
- package/static/assets/zh-CN-DRUEP9Sg.js +10 -0
- package/static/assets/zh-TW-v7FvDwjG.js +10 -0
- package/static/index.html +5 -5
- package/static/sqlite3-opfs-async-proxy.js +881 -0
- package/static/sw.js +1 -1
- package/static/assets/AccountView-yBM8r7xk.js +0 -4
- package/static/assets/AnalyticsView-CW9l8krm.js +0 -2
- package/static/assets/AuthView-BpLHhuif.js +0 -2
- package/static/assets/DestinationMap-DUZnyLyb.js +0 -1
- package/static/assets/FilteringView-BvOw_liH.js +0 -1
- package/static/assets/LogsView-CYxZaJPW.js +0 -5
- package/static/assets/QRCodeCanvas-vzXe_hzQ.js +0 -2
- package/static/assets/RulesView-CbToiqT1.js +0 -1
- package/static/assets/SettingsView-mSkxdlrh.js +0 -1
- package/static/assets/SetupView-Dzbc8NmG.js +0 -1
- package/static/assets/browser-BskSZoIg.js +0 -1
- package/static/assets/date-WF-_cJDs.js +0 -1
- package/static/assets/de-DE-CXKS_pep.js +0 -10
- package/static/assets/es-ES-B2e3ea35.js +0 -10
- package/static/assets/fr-FR-1qQHEpoW.js +0 -10
- package/static/assets/index-DLmOvLdX.js +0 -16
- package/static/assets/index-DdQuGqR5.css +0 -2
- package/static/assets/ja-JP-CCVeJXwX.js +0 -10
- package/static/assets/ko-KR-bQ1okpC2.js +0 -10
- package/static/assets/ru-RU-DeRsms_o.js +0 -10
- package/static/assets/services-C-uSOjyn.js +0 -1
- package/static/assets/vendor-react-DifRgRH3.js +0 -11
- package/static/assets/vendor-utils-D17P9mkD.js +0 -9
- package/static/assets/vi-VN-BcXfqmzH.js +0 -10
- package/static/assets/zh-CN-D8YK7j27.js +0 -12
- package/static/assets/zh-TW-C2_-uaZk.js +0 -12
package/static/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=`dns-worker-icons-v2`,t=`/api/icon/`,n=1440*60*1e3;15*n,30*n;function r(){return new Response(`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>`,{headers:{"Content-Type":`image/svg+xml`,"Cache-Control":`public, max-age=86400`}})}async function i(e){try{return await fetch(e,{mode:`cors`})}catch{return fetch(e,{mode:`no-cors`})}}function a(e){return e.startsWith(t)}async function o(e,t,n){let r=typeof t==`string`?t:t.url,i=new Request(r+`?sw-cached-at`),a=new Response(Date.now().toString());await e.put(t,n),await e.put(i,a)}async function s(e,t){try{let n=new Request(t.url+`?sw-cached-at`),r=await e.match(n);if(!r)return 1/0;let i=await r.text(),a=parseInt(i,10);return isNaN(a)?1/0:Date.now()-a}catch{return 1/0}}async function c(t){let n=await caches.open(e),a=await n.match(t.request);if(a){let e=await s(n,t.request);if(e<1296e6)return a;if(e<2592e6)return i(t.request.url).then(e=>{e&&(e.ok||e.status===0)&&o(n,t.request,e)}).catch(()=>{}),a}try{let e=await i(t.request.url);return e&&(e.ok||e.status===0)?(await o(n,t.request,e.clone()),e):a??r()}catch{return a??r()}}function l(n=[]){caches.open(e).then(e=>{n.forEach(n=>{let r=`${t}${n.replace(/^\*\./,``)}.ico`,a=new Request(r);e.match(a).then(t=>{t||i(r).then(t=>{t&&(t.ok||t.status===0)&&o(e,a,t)}).catch(()=>{})})})})}async function u(){try{let t=await caches.open(e),n=await t.keys(),r=Date.now(),i=n.filter(e=>e.url.includes(`?sw-cached-at`));for(let e of i){let n=await t.match(e);if(n){let i=await n.text(),a=parseInt(i,10);if(!isNaN(a)&&r-a>2592e6){let n=e.url.split(`?`)[0];await t.delete(new Request(n)),await t.delete(e)}}}}catch(e){console.error(`Failed to execute service worker cache cleanup:`,e)}}async function d(){try{let e=await caches.keys();for(let t of e)t.startsWith(`dns-worker-icons-`)&&t!==`dns-worker-icons-v2`&&await caches.delete(t)}catch(e){console.error(`Failed to clean up old caches:`,e)}}const f=`dns-worker-logs-v1`;function p(e){try{let t=new URL(e);return/^\/api\/profiles\/[^/]+\/logs\/\d+$/.test(t.pathname)}catch{return!1}}async function m(e){let t=await caches.open(f),n=await t.match(e.request);if(n)return n;try{let n=await fetch(e.request);return n.ok&&await o(t,e.request,n.clone()),n}catch{return new Response(JSON.stringify({error:`Network error fetching log details`}),{status:503,headers:{"Content-Type":`application/json`}})}}async function h(){try{let e=await caches.open(f),t=await e.keys(),n=Date.now(),r=t.filter(e=>e.url.includes(`?sw-cached-at`));for(let t of r){let r=await e.match(t);if(r){let i=await r.text(),a=parseInt(i,10);if(!isNaN(a)&&n-a>864e5){let n=t.url.split(`?`)[0];await e.delete(new Request(n)),await e.delete(t)}}}}catch(e){console.error(`Failed to execute service worker log cache cleanup:`,e)}}[{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"
|
|
1
|
+
const e=`dns-worker-icons-v2`,t=`/api/icon/`,n=1440*60*1e3;15*n,30*n;function r(){return new Response(`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>`,{headers:{"Content-Type":`image/svg+xml`,"Cache-Control":`public, max-age=86400`}})}async function i(e){try{return await fetch(e,{mode:`cors`})}catch{return fetch(e,{mode:`no-cors`})}}function a(e){return e.startsWith(t)}async function o(e,t,n){let r=typeof t==`string`?t:t.url,i=new Request(r+`?sw-cached-at`),a=new Response(Date.now().toString());await e.put(t,n),await e.put(i,a)}async function s(e,t){try{let n=new Request(t.url+`?sw-cached-at`),r=await e.match(n);if(!r)return 1/0;let i=await r.text(),a=parseInt(i,10);return isNaN(a)?1/0:Date.now()-a}catch{return 1/0}}async function c(t){let n=await caches.open(e),a=await n.match(t.request);if(a){let e=await s(n,t.request);if(e<1296e6)return a;if(e<2592e6)return i(t.request.url).then(e=>{e&&(e.ok||e.status===0)&&o(n,t.request,e)}).catch(()=>{}),a}try{let e=await i(t.request.url);return e&&(e.ok||e.status===0)?(await o(n,t.request,e.clone()),e):a??r()}catch{return a??r()}}function l(n=[]){caches.open(e).then(e=>{n.forEach(n=>{let r=`${t}${n.replace(/^\*\./,``)}.ico`,a=new Request(r);e.match(a).then(t=>{t||i(r).then(t=>{t&&(t.ok||t.status===0)&&o(e,a,t)}).catch(()=>{})})})})}async function u(){try{let t=await caches.open(e),n=await t.keys(),r=Date.now(),i=n.filter(e=>e.url.includes(`?sw-cached-at`));for(let e of i){let n=await t.match(e);if(n){let i=await n.text(),a=parseInt(i,10);if(!isNaN(a)&&r-a>2592e6){let n=e.url.split(`?`)[0];await t.delete(new Request(n)),await t.delete(e)}}}}catch(e){console.error(`Failed to execute service worker cache cleanup:`,e)}}async function d(){try{let e=await caches.keys();for(let t of e)t.startsWith(`dns-worker-icons-`)&&t!==`dns-worker-icons-v2`&&await caches.delete(t)}catch(e){console.error(`Failed to clean up old caches:`,e)}}const f=`dns-worker-logs-v1`;function p(e){try{let t=new URL(e);return/^\/api\/profiles\/[^/]+\/logs\/\d+$/.test(t.pathname)}catch{return!1}}async function m(e){let t=await caches.open(f),n=await t.match(e.request);if(n)return n;try{let n=await fetch(e.request);return n.ok&&await o(t,e.request,n.clone()),n}catch{return new Response(JSON.stringify({error:`Network error fetching log details`}),{status:503,headers:{"Content-Type":`application/json`}})}}async function h(){try{let e=await caches.open(f),t=await e.keys(),n=Date.now(),r=t.filter(e=>e.url.includes(`?sw-cached-at`));for(let t of r){let r=await e.match(t);if(r){let i=await r.text(),a=parseInt(i,10);if(!isNaN(a)&&n-a>864e5){let n=t.url.split(`?`)[0];await e.delete(new Request(n)),await e.delete(t)}}}}catch(e){console.error(`Failed to execute service worker log cache cleanup:`,e)}}[{"revision":"237335bb4b54a5c99e2df044caa514b2","url":"sqlite3-opfs-async-proxy.js"},{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"378a0e13bde392451c5c94fb0c275dc7","url":"index.html"},{"revision":null,"url":"assets/zh-TW-v7FvDwjG.js"},{"revision":null,"url":"assets/zh-CN-DRUEP9Sg.js"},{"revision":null,"url":"assets/vi-VN-_fj_hwx9.js"},{"revision":null,"url":"assets/vendor-utils-C-1rF3VB.js"},{"revision":null,"url":"assets/vendor-ui-core-BjAOArGo.js"},{"revision":null,"url":"assets/vendor-react-GZisTXSQ.js"},{"revision":null,"url":"assets/vendor-icons-other-Bme3ywH9.js"},{"revision":null,"url":"assets/vendor-icons-20-X5NPN60g.js"},{"revision":null,"url":"assets/vendor-icons-16-BgwRBCeU.js"},{"revision":null,"url":"assets/vendor-i18next-cO7FDf_e.js"},{"revision":null,"url":"assets/sqlite3-worker1-DZ2OAEkd.js"},{"revision":null,"url":"assets/sqlite3-opfs-async-proxy.js"},{"revision":null,"url":"assets/sqlite3-opfs-async-proxy-Ck-yCayi.js"},{"revision":null,"url":"assets/sqlite3-Con_VOcu.wasm"},{"revision":null,"url":"assets/sqlite.worker-C50yoTbX.js"},{"revision":null,"url":"assets/splitPathsBySizeLoader-BgBwSA38.js"},{"revision":null,"url":"assets/services-unF2tLc7.js"},{"revision":null,"url":"assets/ru-RU-BrUQ8HMM.js"},{"revision":null,"url":"assets/rolldown-runtime-C4Xdq4VV.js"},{"revision":null,"url":"assets/paths-cc-gUzxh.js"},{"revision":null,"url":"assets/paths-CfqdBnl8.js"},{"revision":null,"url":"assets/ko-KR-DRVmuXAK.js"},{"revision":null,"url":"assets/ja-JP-C1UasoOt.js"},{"revision":null,"url":"assets/index-D53KGRYV.css"},{"revision":null,"url":"assets/index-Ct0QwtUk.js"},{"revision":null,"url":"assets/getFlagEmoji-_Wxhq0lT.js"},{"revision":null,"url":"assets/fr-FR-DEgfea4H.js"},{"revision":null,"url":"assets/formatCountryName-CSBD8pP8.js"},{"revision":null,"url":"assets/es-ES-BHMlKDw4.js"},{"revision":null,"url":"assets/de-DE-Bvn6LW48.js"},{"revision":null,"url":"assets/date-dnUzoLoj.js"},{"revision":null,"url":"assets/browser-BqNNtPRD.js"},{"revision":null,"url":"assets/allPathsLoader-DM2JAMeC.js"},{"revision":null,"url":"assets/allPaths-BEI3QvIM.js"},{"revision":null,"url":"assets/TrendChart-BbPOeC8w.js"},{"revision":null,"url":"assets/SwipeableDrawer-DuXKmSrw.js"},{"revision":null,"url":"assets/SetupView-r5GQKPN4.js"},{"revision":null,"url":"assets/SettingsView-yiZeyh7q.js"},{"revision":null,"url":"assets/RulesView-C8mXn9m8.js"},{"revision":null,"url":"assets/QRCodeCanvas-9YjBSnzo.js"},{"revision":null,"url":"assets/LogsView-DGXuCkRb.js"},{"revision":null,"url":"assets/FilteringView-9SF7vAn0.js"},{"revision":null,"url":"assets/DestinationMap-CRCdjD4S.js"},{"revision":null,"url":"assets/AuthView-DeKX1gG-.js"},{"revision":null,"url":"assets/AnalyticsView-DE25Td6t.js"},{"revision":null,"url":"assets/AccountView-CdfTI-rw.js"},{"revision":"edbf27fdbbc78a5a7269553eed5447b1","url":"manifest.webmanifest"}],self.addEventListener(`install`,()=>{self.skipWaiting()}),self.addEventListener(`activate`,e=>{e.waitUntil(Promise.all([self.clients.claim(),u(),d(),h()]))}),self.addEventListener(`fetch`,e=>{let t=e.request.url;a(t)&&e.respondWith(c(e)),p(t)&&e.respondWith(m(e))}),self.addEventListener(`message`,e=>{e.data&&e.data.type===`PREFETCH_ICONS`&&l(e.data.domains)});
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/date-WF-_cJDs.js","assets/index-DLmOvLdX.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-DifRgRH3.js","assets/vendor-ui-core-CCxBtqRD.js","assets/vendor-utils-D17P9mkD.js","assets/vendor-i18next-cO7FDf_e.js","assets/index-DdQuGqR5.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,G as s,M as c,R as l,S as u,X as d,Xt as f,Y as p,Z as m,b as h,ct as g,et as _,it as v,j as y,k as b,mt as x,pt as S,rt as C,wt as w,x as T,y as E,z as D}from"./vendor-react-DifRgRH3.js";import{S as O,b as k,x as A}from"./vendor-icons-other-Bme3ywH9.js";import{r as j}from"./vendor-i18next-cO7FDf_e.js";import{B as M,C as N,D as ee,F as te,H as P,L as F,N as I,O as L,P as ne,R,S as z,V as B,_ as V,d as re,f as H,h as ie,j as U,p as W,r as G,u as ae,v as K,x as q,z as oe}from"./vendor-ui-core-CCxBtqRD.js";import{_t as se}from"./vendor-utils-D17P9mkD.js";import{A as ce,At as le,C as J,Ct as ue,D as de,Dt as fe,E as pe,Ft as me,It as he,Lt as ge,Mt as _e,Nt as ve,O as ye,Ot as be,Pt as xe,Rt as Se,St as Ce,Tt as we,Ut as Te,Xt as Ee,_ as De,_t as Oe,a as ke,bt as Ae,c as je,d as Y,f as Me,gt as Ne,ht as Pe,jt as Fe,k as Ie,kt as Le,mt as Re,n as X,o as ze,p as Be,u as Z,vt as Ve,wt as He,xt as Ue,yt as We}from"./index-DLmOvLdX.js";import{i as Ge,n as Ke,r as qe,t as Je}from"./QRCodeCanvas-vzXe_hzQ.js";var Q=e(O(),1),$=e(k(),1);const Ye=({recoveryKeys:e,copied:t,onCopy:r,onDone:i})=>{let{t:a}=f();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)(U,{style:{margin:0},children:a(`account.totp.recoveryKeysTitle`,`Save Your Recovery Keys`)})]}),(0,$.jsx)(z,{intent:B.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)(I,{fill:!0,icon:(0,$.jsx)(g,{size:14}),text:t?a(`account.totp.copied`,`Copied!`):a(`account.totp.copyKeys`,`Copy All Keys`),intent:t?B.SUCCESS:B.NONE,onClick:r}),(0,$.jsx)(I,{fill:!0,intent:B.PRIMARY,text:a(`account.totp.done`,`Done, I've saved them`),onClick:i})]})]})},Xe=({onRefresh:e})=>{let{t}=f(),[n,r]=(0,Q.useState)([]),[i,a]=(0,Q.useState)(!0),[o,s]=(0,Q.useState)(!0),[c,l]=(0,Q.useState)(null),[u,d]=(0,Q.useState)(!1),[p,m]=(0,Q.useState)(!1),[h,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(!1),[y,b]=(0,Q.useState)(!1),[x,S]=(0,Q.useState)(``),[C,w]=(0,Q.useState)(null),[T,E]=(0,Q.useState)(``),[D,O]=(0,Q.useState)(!1),[k,A]=(0,Q.useState)(!1),[j,M]=(0,Q.useState)(``),[N,ee]=(0,Q.useState)(null),[te,P]=(0,Q.useState)(!1),[F,I]=(0,Q.useState)(null),L=(0,Q.useCallback)(async()=>{a(!0);try{r(await He()||[])}catch{}finally{a(!1)}},[]);return(0,Q.useEffect)(()=>{s(Ke()),L()},[L]),{passkeys:n,loading:i,supported:o,recoveryKeys:c,setRecoveryKeys:l,copiedKeys:u,handleCopyRecoveryKeys:()=>{c&&navigator.clipboard.writeText(c.join(`
|
|
3
|
-
`)).then(()=>{d(!0),setTimeout(()=>d(!1),2e3)})},isAddOpen:p,setIsAddOpen:m,passkeyName:h,setPasskeyName:g,nameFocused:_,setNameFocused:v,registering:y,addError:x,setAddError:S,handleOpenAdd:()=>{g(``),S(``),v(!1),m(!0)},handleRegister:async n=>{n.preventDefault();let r=h.trim();if(!De(r)){S(t(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`));return}b(!0),S(``);try{let t=await ge({name:r,credential:await Ge(await ue())});m(!1),g(``),await L(),e?.(),t?.recovery_keys&&t.recovery_keys.length>0&&l(t.recovery_keys)}catch(e){console.error(`Passkey registration failed:`,e),S(e instanceof Error?e.message:t(`account.passkey.regFailed`,`Registration failed`))}finally{b(!1)}},editingPasskey:C,setEditingPasskey:w,editName:T,setEditName:E,renameFocused:D,setRenameFocused:O,renaming:k,renameError:j,setRenameError:M,handleOpenRename:e=>{w(e),E(e.name),M(``),O(!1)},handleRenameSubmit:async e=>{e.preventDefault();let n=T.trim();if(!(!C||!n)){if(!De(n)){M(t(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`));return}A(!0),M(``);try{await fe(C.id,n),w(null),await L()}catch(e){M(e instanceof Error?e.message:t(`common.errorNetwork`))}finally{A(!1)}}},deletingId:N,deleteConfirmOpen:te,setDeleteConfirmOpen:P,targetToDelete:F,handleOpenDelete:e=>{I(e),P(!0)},handleDeleteSubmit:async()=>{if(F){ee(F.id);try{await Ve(F.id),P(!1),I(null),await L(),e?.()}catch(e){let n=e instanceof Error?e.message:t(`common.errorNetwork`);alert(n)}finally{ee(null)}}},fetchPasskeys:L}},Ze=({passkeys:e,loading:t,deletingId:n,onOpenRename:a,onOpenDelete:o})=>{let{t:s}=f();return t?(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)(_,{size:28,className:`mx-auto mb-2 opacity-40`}),(0,$.jsx)(`p`,{children:s(`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)(_,{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:[s(`account.passkey.created`,`Added`),`:`,` `,J(new Date(e.created_at*1e3))]}),e.last_used_at?(0,$.jsxs)(`span`,{children:[s(`account.passkey.lastUsed`,`Last used`),`:`,` `,J(new Date(e.last_used_at*1e3))]}):(0,$.jsx)(`span`,{children:s(`account.passkey.neverUsed`,`Never used`)})]})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,$.jsx)(I,{minimal:!0,small:!0,icon:(0,$.jsx)(r,{size:14}),title:s(`common.rename`,`Rename`),onClick:()=>a(e)}),(0,$.jsx)(I,{minimal:!0,small:!0,intent:B.DANGER,icon:(0,$.jsx)(i,{size:14}),title:s(`common.delete`,`Delete`),loading:n===e.id,onClick:()=>o(e)})]})]},e.id))})},Qe=({isOpen:e,onClose:t,passkeyName:n,setPasskeyName:r,nameFocused:i,setNameFocused:a,registering:o,addError:s,setAddError:c,onSubmit:l})=>{let{t:u}=f();return(0,$.jsx)(L,{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:F,children:[s&&(0,$.jsx)(z,{intent:B.DANGER,className:`mb-4`,children:s}),(0,$.jsx)(W,{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)(K,{content:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),isOpen:i,position:M.TOP,intent:B.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(H,{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:R,children:(0,$.jsxs)(`div`,{className:oe,children:[(0,$.jsx)(I,{text:u(`common.cancel`,`Cancel`),onClick:t,disabled:o}),(0,$.jsx)(I,{intent:B.PRIMARY,type:`submit`,text:u(`account.passkey.continue`,`Continue`),loading:o,disabled:!De(n.trim())||o})]})})]})})},$e=({isOpen:e,onClose:t,editName:n,setEditName:r,renameFocused:i,setRenameFocused:a,renaming:o,renameError:s,setRenameError:c,onSubmit:l})=>{let{t:u}=f();return(0,$.jsx)(L,{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:F,children:[s&&(0,$.jsx)(z,{intent:B.DANGER,className:`mb-4`,children:s}),(0,$.jsx)(W,{label:u(`account.passkey.appNameLabel`,`Application (Domain)`),children:(0,$.jsx)(H,{readOnly:!0,disabled:!0,leftIcon:`globe`,value:window.location.hostname})}),(0,$.jsx)(W,{label:u(`account.passkey.nameLabel`,`Passkey Name`),helperText:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),children:(0,$.jsx)(K,{content:u(`account.passkey.formatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),isOpen:i,position:M.TOP,intent:B.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(H,{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:R,children:(0,$.jsxs)(`div`,{className:oe,children:[(0,$.jsx)(I,{text:u(`common.cancel`,`Cancel`),onClick:t,disabled:o}),(0,$.jsx)(I,{intent:B.PRIMARY,type:`submit`,text:u(`common.save`,`Save`),loading:o,disabled:!De(n.trim())||o})]})})]})})},et=({isOpen:e,onClose:t,targetToDelete:n,deleting:r,onConfirm:i})=>{let{t:a}=f();return(0,$.jsxs)(L,{isOpen:e,onClose:()=>!r&&t(),title:a(`account.passkey.deleteTitle`,`Delete Passkey`),className:`max-w-md`,children:[(0,$.jsx)(`div`,{className:F,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:R,children:(0,$.jsxs)(`div`,{className:oe,children:[(0,$.jsx)(I,{text:a(`common.cancel`,`Cancel`),onClick:t,disabled:r}),(0,$.jsx)(I,{intent:B.DANGER,text:a(`common.delete`,`Delete`),onClick:i,loading:r})]})})]})},tt=({onRefresh:e})=>{let{t:n}=f(),{passkeys:r,loading:i,supported:a,recoveryKeys:o,setRecoveryKeys:s,copiedKeys:c,handleCopyRecoveryKeys:l,isAddOpen:u,setIsAddOpen:d,passkeyName:p,setPasskeyName:m,nameFocused:h,setNameFocused:g,registering:_,addError:v,setAddError:b,handleOpenAdd:x,handleRegister:S,editingPasskey:C,setEditingPasskey:w,editName:T,setEditName:E,renameFocused:O,setRenameFocused:k,renaming:A,renameError:j,setRenameError:M,handleOpenRename:N,handleRenameSubmit:ee,deletingId:te,deleteConfirmOpen:P,setDeleteConfirmOpen:F,targetToDelete:L,handleOpenDelete:ne,handleDeleteSubmit:R}=Xe({onRefresh:e});return o?(0,$.jsx)(Ye,{recoveryKeys:o,copied:c,onCopy:l,onDone:()=>s(null)}):(0,$.jsxs)(`div`,{className:`space-y-4`,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)(t,{size:20,className:`text-purple-500`}),(0,$.jsx)(U,{style:{margin:0},children:n(`account.passkey.title`,`Passkeys`)}),(0,$.jsx)(G,{intent:r.length>0?B.SUCCESS:B.NONE,minimal:!0,round:!0,children:r.length>0?n(`account.passkey.count`,{count:r.length,defaultValue:`${r.length} configured`}):n(`account.passkey.none`,`None configured`)})]}),a&&(0,$.jsx)(I,{intent:B.PRIMARY,icon:(0,$.jsx)(D,{size:16}),text:n(`account.passkey.addBtn`,`Add Passkey`),onClick:x})]}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:n(`account.passkey.desc`,`Authenticate securely with biometrics (Touch ID, Face ID, Windows Hello) or a hardware security key (YubiKey) as an MFA factor.`)}),!a&&(0,$.jsx)(z,{intent:B.WARNING,icon:(0,$.jsx)(y,{size:16}),className:`mb-4`,children:n(`account.passkey.notSupported`,`Your browser or device does not support Passkeys (WebAuthn).`)}),(0,$.jsx)(Ze,{passkeys:r,loading:i,deletingId:te,onOpenRename:N,onOpenDelete:ne}),(0,$.jsx)(Qe,{isOpen:u,onClose:()=>d(!1),passkeyName:p,setPasskeyName:m,nameFocused:h,setNameFocused:g,registering:_,addError:v,setAddError:b,onSubmit:S}),(0,$.jsx)($e,{isOpen:!!C,onClose:()=>w(null),editName:T,setEditName:E,renameFocused:O,setRenameFocused:k,renaming:A,renameError:j,setRenameError:M,onSubmit:ee}),(0,$.jsx)(et,{isOpen:P,onClose:()=>F(!1),targetToDelete:L,deleting:!!te,onConfirm:R})]})},nt=({user:e,disableDialogOpen:t,setDisableDialogOpen:n,disablePassword:r,setDisablePassword:i,disableError:a,setDisableError:s,disableLoading:c,onDisable:l})=>{let{t:u}=f(),[d,p]=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)(U,{style:{margin:0},children:u(`account.totp.title`,`Authenticator App (TOTP)`)}),(0,$.jsx)(G,{intent:B.SUCCESS,minimal:!0,round:!0,children:u(`account.totp.enabled`,`Enabled`)})]}),(0,$.jsx)(I,{intent:B.DANGER,outlined:!0,icon:(0,$.jsx)(b,{size:14}),text:u(`account.totp.disable`,`Disable Authenticator App (TOTP)`),onClick:()=>n(!0)})]}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:u(`account.totp.activeDesc`,`Authenticator app (TOTP) is active and generating 6-digit verification codes for your account.`)})}),(0,$.jsx)(L,{isOpen:t,onClose:()=>{n(!1),i(``),s(``),p(!1)},title:u(`account.totp.disableTitle`,`Disable Authenticator App (TOTP)`),icon:`shield`,children:(0,$.jsxs)(`div`,{className:`p-6 space-y-4`,children:[(0,$.jsx)(z,{intent:B.WARNING,children:u(`account.totp.disableWarning`,`After disabling TOTP, if no Passkeys are configured, your account will only be protected by password.`)}),a&&(0,$.jsx)(z,{intent:B.DANGER,children:a}),!e.totp_skip_password&&(0,$.jsxs)(`form`,{onSubmit:l,className:`space-y-4`,children:[(0,$.jsx)(W,{label:u(`account.currentPassword`),children:(0,$.jsx)(H,{type:d?`text`:`password`,leftIcon:`lock`,value:r,onChange:e=>i(e.target.value),rightElement:(0,$.jsx)(I,{minimal:!0,icon:d?`eye-open`:`eye-off`,onClick:()=>p(!d),title:d?u(`auth.hidePassword`,`Hide password`):u(`auth.showPassword`,`Show password`)}),required:!0})}),(0,$.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,$.jsx)(I,{text:u(`account.cancel`),onClick:()=>n(!1)}),(0,$.jsx)(I,{intent:B.DANGER,text:u(`account.totp.confirmDisable`,`Disable TOTP`),type:`submit`,loading:c})]})]}),e.totp_skip_password&&(0,$.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,$.jsx)(I,{text:u(`account.cancel`),onClick:()=>n(!1)}),(0,$.jsx)(I,{intent:B.DANGER,text:u(`account.totp.confirmDisable`,`Disable TOTP`),loading:c,onClick:l})]})]})})]})},rt=({setupData:e,setupToken:t,setSetupToken:n,setupError:r,setupLoading:i,onStartSetup:s,onConfirmSetup:c,onCancel:l})=>{let{t:u}=f();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)(U,{style:{margin:0},children:u(`account.totp.title`,`Authenticator App (TOTP)`)}),(0,$.jsx)(G,{minimal:!0,round:!0,intent:B.NONE,children:u(`account.totp.disabled`,`Disabled`)})]}),!e&&(0,$.jsx)(I,{intent:B.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)(Je,{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)(V,{}),r&&(0,$.jsx)(z,{intent:B.DANGER,children:r}),(0,$.jsxs)(`form`,{onSubmit:c,className:`space-y-3`,children:[(0,$.jsx)(W,{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)(X,{length:6,value:t,onChange:n,disabled:i})}),(0,$.jsxs)(`div`,{className:`flex gap-2`,children:[(0,$.jsx)(I,{text:u(`account.cancel`),onClick:l}),(0,$.jsx)(I,{intent:B.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)(z,{intent:B.DANGER,children:r})]})]})},it=({user:e,onRefresh:t})=>{let{t:n}=f(),[r,i]=(0,Q.useState)(null),[a,o]=(0,Q.useState)(``),[s,c]=(0,Q.useState)(null),[l,u]=(0,Q.useState)(!1),[d,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)(Ye,{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)(nt,{user:e,settingsLoading:w,onToggleSkipPassword:async e=>{T(!0);try{await he(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 Y(v,e.username)),await We(n),_(!1),y(``),t()}catch(e){C(e.message||n(`common.errorNetwork`))}finally{x(!1)}}}):(0,$.jsx)(rt,{setupData:r,setupToken:a,setSetupToken:o,setupError:d,setupLoading:l,onStartSetup:async()=>{u(!0),p(``);try{i(await _e())}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 Ne({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(``)}})};var at=e=>e?.passkeys_count&&e.passkeys_count>0?`passkey`:e?.totp_enabled?`totp`:`password`;const ot=({isOpen:e,onClose:r,user:i,title:a,onVerify:o})=>{let{t:s}=f(),c=!!(i?.passkeys_count&&i.passkeys_count>0),l=!!i?.totp_enabled,u=at(i),[d,p]=(0,Q.useState)(u),[h,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(!1),[y,b]=(0,Q.useState)(``),[x,S]=(0,Q.useState)(!1),[C,w]=(0,Q.useState)(``),[T,E]=(0,Q.useState)(e);!T&&e?(E(!0),p(u),g(``),v(!1),b(``),w(``)):T&&!e&&E(!1),(0,Q.useEffect)(()=>{d===`passkey`&&!c?p(l?`totp`:`password`):d===`totp`&&!l&&p(c?`passkey`:`password`)},[c,l,d]);let D=async e=>{if(e&&e.preventDefault(),!h){w(s(`auth.passwordRequired`,`Password is required`));return}S(!0),w(``);try{let e=h;i?.password_version===2&&i?.username&&(e=await Y(h,i.username)),await o({password:e}),r()}catch(e){w(Z(e,s))}finally{S(!1)}},O=async()=>{S(!0),w(``);try{await o({passkeyAssertion:await qe(await Ce())}),r()}catch(e){w(Z(e,s))}finally{S(!1)}},k=async e=>{let t=e||y;if(t.length!==6){w(s(`account.totp.invalidCode`,`Please enter a 6-digit code`));return}S(!0),w(``);try{let e=crypto.randomUUID(),n=new TextEncoder().encode(t+e),i=await crypto.subtle.digest(`SHA-256`,n);await o({totpTokenHash:Array.from(new Uint8Array(i)).map(e=>e.toString(16).padStart(2,`0`)).join(``),totpSalt:e}),r()}catch(e){w(Z(e,s))}finally{S(!1)}};return(0,$.jsx)(L,{isOpen:e,onClose:r,title:a||s(`account.verifyIdentity`,`Security Verification`),icon:`shield`,className:`max-w-md w-full`,children:(0,$.jsxs)(`div`,{className:F,children:[(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:s(`account.verifyIdentityDesc`,`To protect your account security, please verify your identity before proceeding.`)}),(c||l)&&(0,$.jsx)(`div`,{className:`flex justify-center mb-5 isolate`,style:{isolation:`isolate`},children:(0,$.jsx)(`div`,{className:`w-full bg-gray-100/70 dark:bg-gray-800/70 p-1 rounded-lg`,children:(0,$.jsxs)(N,{fill:!0,variant:`minimal`,style:{isolation:`isolate`},children:[c&&(0,$.jsx)(I,{small:!0,active:d===`passkey`,intent:d===`passkey`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(t,{size:14}),text:s(`account.mfa.passkey`,`Passkey`),onClick:()=>{p(`passkey`),w(``)}}),l&&(0,$.jsx)(I,{small:!0,active:d===`totp`,intent:d===`totp`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(n,{size:14}),text:s(`account.mfa.totp`,`TOTP`),onClick:()=>{p(`totp`),w(``)}}),(0,$.jsx)(I,{small:!0,active:d===`password`,intent:d===`password`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(m,{size:14}),text:s(`account.mfa.password`,`Password`),onClick:()=>{p(`password`),w(``)}})]})})}),C&&(0,$.jsx)(z,{intent:B.DANGER,className:`mb-4`,children:C}),d===`passkey`&&(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)(t,{size:48})})}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-300`,children:s(`account.passkey.verifyPrompt`,`Authenticate using your device's biometric sensor (Face ID, Touch ID, Windows Hello) or security key.`)}),(0,$.jsx)(I,{fill:!0,large:!0,intent:B.PRIMARY,loading:x,onClick:O,icon:(0,$.jsx)(t,{size:16}),text:s(`account.usePasskeyInstead`,`Authenticate with Passkey`)})]}),d===`totp`&&(0,$.jsxs)(`div`,{className:`py-2 space-y-4`,children:[(0,$.jsx)(W,{label:s(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(X,{length:6,value:y,onChange:e=>{b(e),e.length===6&&k(e)},disabled:x})}),(0,$.jsx)(I,{fill:!0,intent:B.PRIMARY,loading:x,disabled:y.length!==6,onClick:()=>k(),text:s(`common.confirm`,`Confirm`)})]}),d===`password`&&(0,$.jsxs)(`form`,{onSubmit:D,className:`py-2 space-y-4`,children:[(0,$.jsx)(W,{label:s(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(H,{leftIcon:`lock`,type:_?`text`:`password`,value:h,onChange:e=>g(e.target.value),autoFocus:!0,rightElement:(0,$.jsx)(I,{minimal:!0,icon:_?`eye-open`:`eye-off`,onClick:()=>v(!_)})})}),(0,$.jsx)(I,{fill:!0,intent:B.PRIMARY,type:`submit`,loading:x,text:s(`common.confirm`,`Confirm`)})]})]})})},st=({user:e,onRefresh:n})=>{let{t:r}=f(),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(`view`),[c,u]=(0,Q.useState)(!1),[d,p]=(0,Q.useState)(null),[h,_]=(0,Q.useState)(!1),[b,S]=(0,Q.useState)(!0),[w,T]=(0,Q.useState)(!1),[E,D]=(0,Q.useState)(null),O=!!(e.has_recovery_keys||e.recovery_keys_encrypted),k=!!e.recovery_keys_encrypted,A=()=>{D(null),s(`view`),S(!0),a(!0)},j=()=>{D(null),u(!0)},N=()=>{u(!1),s(`rotate`),a(!0)},te=async e=>{if(o===`view`){let t=await Se(e);t.is_legacy&&(!t.recovery_keys||t.recovery_keys.length===0)?(_(!0),p(null),D({text:r(`account.recoveryKey.legacyNotice`,`Your recovery key is stored as a legacy one-way hash and cannot be decrypted for display. Please rotate your recovery key to generate a new KEK envelope-encrypted key.`),intent:B.WARNING})):(_(!1),p(t.recovery_keys),S(!0))}else o===`rotate`&&(p([(await le(e)).recovery_key]),_(!1),S(!1),D({text:r(`account.recoveryKey.rotateSuccess`,`Recovery key rotated successfully! Please store your new key in a safe place immediately.`),intent:B.SUCCESS}),n())},F=e=>{navigator.clipboard.writeText(e),T(!0),setTimeout(()=>T(!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)(t,{size:18,className:`text-amber-500`}),(0,$.jsx)(U,{style:{margin:0},children:r(`account.recoveryKey.title`,`Emergency Recovery Key`)}),(0,$.jsx)(G,{intent:O?B.SUCCESS:B.NONE,minimal:!0,round:!0,children:O?r(`account.recoveryKey.configured`,`Configured`):r(`account.recoveryKey.notConfigured`,`Not Configured`)}),k&&(0,$.jsx)(K,{content:r(`account.recoveryKey.kekTooltip`,`Protected with AES-256-GCM Envelope Encryption backed by Key Encryption Key (KEK).`),position:M.TOP,children:(0,$.jsx)(G,{intent:B.SUCCESS,minimal:!0,round:!0,icon:(0,$.jsx)(m,{size:12,style:{display:`inline-flex`,alignItems:`center`,marginRight:`4px`}}),children:r(`account.recoveryKey.kekProtected`,`KEK Encrypted`)})})]}),(0,$.jsx)(`div`,{className:`flex items-center gap-2`,children:O&&(0,$.jsx)(I,{small:!0,icon:(0,$.jsx)(C,{size:14}),text:r(`account.recoveryKey.viewBtn`,`View Recovery Key`),onClick:A})})]}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400`,children:r(`account.recoveryKey.desc`,`An emergency recovery key allows you to regain access or reset your password if you lose all registered Passkeys or Authenticator Apps. Store it securely offline.`)}),E&&(0,$.jsx)(z,{intent:E.intent,className:`my-2`,children:E.text}),h&&(0,$.jsx)(z,{intent:B.WARNING,icon:(0,$.jsx)(y,{size:16}),className:`my-2`,children:(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-2`,children:[(0,$.jsx)(`span`,{children:r(`account.recoveryKey.legacyNotice`,`Your recovery key is stored as a legacy one-way hash and cannot be decrypted for display. Please rotate your recovery key to generate a new KEK envelope-encrypted key.`)}),(0,$.jsx)(I,{small:!0,intent:B.WARNING,icon:(0,$.jsx)(l,{size:14}),text:r(`account.recoveryKey.rotateBtn`,`Rotate Key`),onClick:j,className:`shrink-0`})]})}),d&&d.length>0&&(0,$.jsxs)(q,{elevation:P.ZERO,className:`bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 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,$.jsx)(`span`,{className:`text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider`,children:r(`account.recoveryKey.yourKey`,`Your 30-Digit Recovery Key`)}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[(0,$.jsx)(I,{small:!0,minimal:!0,intent:B.WARNING,icon:(0,$.jsx)(l,{size:14}),text:r(`account.recoveryKey.rotateBtn`,`Rotate Key`),onClick:j}),(0,$.jsx)(`div`,{className:`h-4 w-px bg-gray-300 dark:bg-gray-600 mx-1 hidden sm:block`}),(0,$.jsx)(I,{minimal:!0,small:!0,icon:b?(0,$.jsx)(C,{size:14}):(0,$.jsx)(v,{size:14}),onClick:()=>S(!b),title:r(b?`auth.showPassword`:`auth.hidePassword`)}),(0,$.jsx)(I,{minimal:!0,small:!0,icon:w?(0,$.jsx)(x,{size:14,className:`text-green-500`}):(0,$.jsx)(g,{size:14}),onClick:()=>F(d[0]),title:r(`common.copy`)}),(0,$.jsx)(I,{minimal:!0,small:!0,icon:`cross`,onClick:()=>p(null),title:r(`common.close`)})]})]}),(0,$.jsx)(`div`,{className:`p-3 bg-white dark:bg-gray-900 rounded border border-gray-200 dark:border-gray-700 font-mono text-center text-lg sm:text-xl font-bold tracking-widest select-all text-gray-800 dark:text-gray-100`,children:b?`••••••-••••••-••••••-••••••-••••••`:d[0]}),(0,$.jsxs)(`p`,{className:`text-xs text-amber-600 dark:text-amber-400 flex items-center gap-1`,children:[(0,$.jsx)(y,{size:14,className:`shrink-0`}),r(`account.recoveryKey.securityTip`,`Keep this recovery key secret. Anyone with access to this key can regain access to your account.`)]})]}),(0,$.jsx)(ee,{isOpen:c,onConfirm:N,onCancel:()=>u(!1),cancelButtonText:r(`common.cancel`,`Cancel`),confirmButtonText:r(`account.recoveryKey.confirmRotateBtn`,`Proceed to Rotate`),intent:B.DANGER,icon:`warning-sign`,children:(0,$.jsx)(`p`,{children:r(`account.recoveryKey.rotateConfirm`,`Rotating your recovery key will immediately invalidate the current recovery key. You will need to verify your identity to complete this action.`)})}),(0,$.jsx)(ot,{isOpen:i,onClose:()=>a(!1),user:e,title:o===`view`?r(`account.recoveryKey.viewVerifyTitle`,`Verify Identity to View Key`):r(`account.recoveryKey.rotateVerifyTitle`,`Verify Identity to Rotate Key`),onVerify:te})]})},ct=({user:e,onRefresh:t})=>{let{t:r}=f(),[i,a]=(0,Q.useState)(!1),o=!!(e.mfa_enabled??(e.totp_enabled||e.passkeys_count&&e.passkeys_count>0)),s=async e=>{a(!0);try{await xe(e),t()}catch(e){alert(e.message||r(`common.errorNetwork`,`Network error`))}finally{a(!1)}};return(0,$.jsxs)(q,{elevation:P.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:o?`text-green-500`:`text-gray-400`}),(0,$.jsx)(U,{style:{margin:0},children:r(`account.mfa.title`,`Multi-Factor Authentication (MFA)`)}),(0,$.jsx)(G,{intent:o?B.SUCCESS:B.NONE,minimal:!0,round:!0,children:o?r(`account.mfa.enabled`,`Configured`):r(`account.mfa.notConfigured`,`Not Configured`)})]})}),(0,$.jsx)(`p`,{className:`text-sm text-gray-600 dark:text-gray-400 mb-4`,children:r(`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.`)}),o?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(V,{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:r(`account.mfa.passwordlessTitle`,`Passwordless Login`)}),(0,$.jsx)(`div`,{className:`text-xs text-gray-500 dark:text-gray-400`,children:r(`account.mfa.passwordlessDesc`,`When enabled, logging in will skip the password requirement and verify your identity directly via Passkey or TOTP.`)})]}),(0,$.jsx)(ie,{checked:!!e.totp_skip_password,onChange:e=>s(e.currentTarget.checked),disabled:i,className:`mb-0 shrink-0`})]})]}):(0,$.jsx)(z,{intent:B.PRIMARY,icon:(0,$.jsx)(_,{size:16,style:{display:`inline-flex`,alignItems:`center`,marginRight:`8px`}}),children:r(`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)(V,{}),(0,$.jsx)(tt,{onRefresh:t}),(0,$.jsx)(V,{}),(0,$.jsx)(it,{user:e,onRefresh:t}),(0,$.jsx)(V,{}),(0,$.jsx)(st,{user:e,onRefresh:t})]})},lt={signup:{label:`account.activity.signup`,icon:(0,$.jsx)(T,{size:14}),intent:B.SUCCESS},login_success:{label:`account.activity.loginSuccess`,icon:(0,$.jsx)(d,{size:14}),intent:B.SUCCESS},login_fail:{label:`account.activity.loginFail`,icon:(0,$.jsx)(u,{size:14}),intent:B.DANGER},logout:{label:`account.activity.logout`,icon:(0,$.jsx)(p,{size:14}),intent:B.NONE},password_change_success:{label:`account.activity.pwChangeSuccess`,icon:(0,$.jsx)(t,{size:14}),intent:B.SUCCESS},password_change_fail:{label:`account.activity.pwChangeFail`,icon:(0,$.jsx)(u,{size:14}),intent:B.DANGER},totp_verify_success:{label:`account.activity.totpVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:B.SUCCESS},totp_verify_fail:{label:`account.activity.totpVerifyFail`,icon:(0,$.jsx)(u,{size:14}),intent:B.DANGER},totp_setup:{label:`account.activity.totpSetup`,icon:(0,$.jsx)(a,{size:14}),intent:B.PRIMARY},totp_removed:{label:`account.activity.totpRemoved`,icon:(0,$.jsx)(b,{size:14}),intent:B.WARNING},recovery_key_used:{label:`account.activity.recoveryKeyUsed`,icon:(0,$.jsx)(t,{size:14}),intent:B.WARNING},recovery_key_rotated:{label:`account.activity.recoveryKeyRotated`,icon:(0,$.jsx)(t,{size:14}),intent:B.WARNING},session_revoked:{label:`account.activity.sessionRevoked`,icon:(0,$.jsx)(p,{size:14}),intent:B.WARNING},passkey_registered:{label:`account.activity.passkeyRegistered`,icon:(0,$.jsx)(t,{size:14}),intent:B.PRIMARY},passkey_deleted:{label:`account.activity.passkeyDeleted`,icon:(0,$.jsx)(b,{size:14}),intent:B.WARNING},passkey_verify_success:{label:`account.activity.passkeyVerifySuccess`,icon:(0,$.jsx)(n,{size:14}),intent:B.SUCCESS},passkey_verify_fail:{label:`account.activity.passkeyVerifyFail`,icon:(0,$.jsx)(u,{size:14}),intent:B.DANGER}},ut=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`},dt=(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},ft=({userAgent:e})=>{let{t}=f();if(!e)return(0,$.jsx)(`span`,{className:`text-gray-500`,children:`—`});let n=dt(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:ut(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})]})},pt=({hoveredSessionId:e,setHoveredSessionId:t})=>{let{t:n}=f(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[s,c]=(0,Q.useState)(!0),[u,d]=(0,Q.useState)(!1),p=(0,Q.useCallback)(async e=>{o(!0);try{let t=new URLSearchParams({limit:`20`});e&&t.set(`before`,String(e));let n=await Ae(t.toString());i(e?e=>[...e,...n]:n),c(n.length===20)}catch{}finally{o(!1)}},[]);(0,Q.useEffect)(()=>{p()},[p]);let m=()=>{let e=r[r.length-1];e&&p(e.timestamp)},h=e=>lt[e]??{label:e,icon:(0,$.jsx)(w,{size:14}),intent:B.NONE};return(0,$.jsxs)(q,{elevation:P.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between cursor-pointer`,onClick:()=>d(!u),children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(w,{size:20,className:`text-purple-500`}),(0,$.jsx)(U,{style:{margin:0},children:n(`account.activity.title`,`Account Activity`)}),r.length>0&&(0,$.jsxs)(G,{minimal:!0,round:!0,intent:B.NONE,children:[r.length,s?`+`:``]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(I,{minimal:!0,icon:(0,$.jsx)(l,{size:14}),onClick:e=>{e.stopPropagation(),p()}}),(0,$.jsx)(S,{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)(ae,{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=h(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)(G,{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:J(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)(ft,{userAgent:r.user_agent||null})})]},r.id)})})]}),s&&(0,$.jsx)(`div`,{className:`flex justify-center mt-3`,children:(0,$.jsx)(I,{minimal:!0,loading:a,text:n(`account.activity.loadMore`,`Load More`),onClick:m})})]})})]})},mt=({hoveredSessionId:e,setHoveredSessionId:t})=>{let{t:n}=f(),[r,i]=(0,Q.useState)([]),[a,o]=(0,Q.useState)(!0),[c,u]=(0,Q.useState)(null),[d,m]=(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 we(),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=>{u(e);try{(await Le(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{u(null)}};return(0,$.jsxs)(q,{elevation:P.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)(s,{size:20,className:`text-green-500`}),(0,$.jsx)(U,{style:{margin:0},children:n(`account.sessions.title`,`Active Sessions`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[_>0&&(0,$.jsx)(I,{small:!0,minimal:!0,intent:B.DANGER,icon:(0,$.jsx)(p,{size:14}),text:n(`account.sessions.revokeOthers`,`Revoke Other Sessions`),loading:d,onClick:()=>g(!0)}),(0,$.jsx)(I,{minimal:!0,icon:(0,$.jsx)(l,{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)(ae,{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)(ft,{userAgent:r.user_agent}),r.is_current&&(0,$.jsx)(G,{minimal:!0,intent:B.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?J(new Date(r.created_at*1e3)):`—`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500 align-middle`,children:J(new Date(r.expires_at*1e3))}),(0,$.jsx)(`td`,{className:`align-middle`,children:(0,$.jsx)(I,{small:!0,minimal:!0,intent:B.DANGER,disabled:r.is_current,icon:(0,$.jsx)(p,{size:14}),text:n(`account.sessions.revoke`,`Revoke`),loading:c===r.id,onClick:()=>y(r.id)})})]},r.id))})]})}),(0,$.jsx)(ee,{isOpen:h,cancelButtonText:n(`common.cancel`,`Cancel`),confirmButtonText:n(`account.sessions.confirmRevokeOthers`,`Revoke Other Sessions`),intent:B.DANGER,icon:`log-out`,onCancel:()=>g(!1),onConfirm:async()=>{m(!0);try{await be(),i(e=>e.filter(e=>e.is_current)),g(!1)}catch(e){alert(e.message||n(`account.sessions.revokeFailed`,`Failed to revoke session.`))}finally{m(!1)}},loading:d,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.`)})})]})},ht=({users:e,currentUserId:t,onRefresh:r,registrationEnabled:a=!0,onRefreshSettings:o})=>{let{t:s}=f(),[c,l]=(0,Q.useState)(!1),[u,d]=(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 E=async e=>{S(e),w(!0);try{await ce({registration_enabled:String(e)}),o?.()}catch(t){console.error(t),S(!e),alert(t.message||s(`common.errorNetwork`,`Network error`))}finally{w(!1)}},D=async()=>{if(!je.test(u)){alert(s(`account.formatTipUsername`));return}if(!ke.test(p)){alert(s(`account.formatTipPassword`));return}v(!0);try{await pe({username:u,password:await Y(p,u),role:h}),l(!1),d(``),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 de(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)(U,{style:{margin:0},children:s(`account.userManagement`)})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,$.jsx)(ie,{label:s(`account.enableRegistration`,`开放新用户注册`),checked:x,disabled:C,onChange:e=>E(e.currentTarget.checked),className:`mb-0`}),(0,$.jsx)(I,{className:`whitespace-nowrap`,icon:(0,$.jsx)(T,{size:16}),intent:B.SUCCESS,text:s(`account.createUser`),onClick:()=>l(!0)})]})]}),(0,$.jsx)(q,{elevation:P.ONE,className:`p-0 overflow-hidden overflow-x-auto`,children:(0,$.jsxs)(ae,{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)(G,{minimal:!0,intent:e.role===`admin`?B.DANGER:B.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)(G,{minimal:!0,intent:B.SUCCESS,children:`TOTP`}),!!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(G,{minimal:!0,intent:B.PRIMARY,children:`Passkey`}),!e.totp_enabled&&!(e.passkeys_count&&e.passkeys_count>0)&&(0,$.jsx)(G,{minimal:!0,intent:B.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?J(new Date(e.created_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_active_at?J(new Date(e.last_active_at*1e3)):`-`}),(0,$.jsx)(`td`,{className:`text-xs text-gray-500`,children:e.last_resolve_at?J(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)(I,{minimal:!0,intent:B.DANGER,icon:(0,$.jsx)(i,{size:14}),disabled:e.id===t,onClick:()=>O(e.id)})})})]},e.id))})]})}),(0,$.jsx)(L,{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)(W,{label:s(`account.username`),children:(0,$.jsx)(H,{value:u,onChange:e=>d(e.target.value),placeholder:s(`auth.usernamePlaceholder`)})}),(0,$.jsx)(W,{label:s(`account.initialPassword`),children:(0,$.jsx)(H,{type:y?`text`:`password`,value:p,onChange:e=>m(e.target.value),placeholder:s(`auth.passwordPlaceholder`),rightElement:(0,$.jsx)(I,{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)(W,{label:s(`account.userRole`),children:(0,$.jsx)(re,{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)(I,{text:s(`account.cancel`),onClick:()=>l(!1)}),(0,$.jsx)(I,{intent:B.PRIMARY,text:s(`account.createNow`),loading:_,onClick:D})]})]})})]})},gt=({initialSettings:e,onRefresh:t})=>{let{t:n}=f(),[r,i]=(0,Q.useState)(e),[a,o]=(0,Q.useState)(!1),[s,l]=(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)(c,{size:20,className:`text-gray-500`}),(0,$.jsx)(U,{style:{margin:0},children:n(`account.systemSettings`,`System Settings`)})]}),(0,$.jsxs)(q,{elevation:P.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)(U,{className:`text-sm font-bold opacity-70 text-blue-500`,children:`Cloudflare Turnstile`}),(0,$.jsx)(W,{label:`Site Key`,children:(0,$.jsx)(H,{value:r.turnstile_site_key||``,onChange:e=>i({...r,turnstile_site_key:e.target.value}),placeholder:`0x000...`})}),(0,$.jsx)(W,{label:`Secret Key`,children:(0,$.jsx)(H,{type:s?`text`:`password`,value:r.turnstile_secret_key||``,onChange:e=>i({...r,turnstile_secret_key:e.target.value}),placeholder:`0x000...`,rightElement:(0,$.jsx)(I,{minimal:!0,icon:s?`eye-open`:`eye-off`,onClick:()=>l(!s),title:s?n(`auth.hidePassword`,`Hide password`):n(`auth.showPassword`,`Show password`)})})})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(U,{className:`text-sm font-bold opacity-70 text-green-500`,children:n(`account.featureToggle`,`Feature Toggle`)}),(0,$.jsx)(ie,{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)(ie,{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)(V,{className:`my-4`}),(0,$.jsx)(`div`,{className:`flex justify-end`,children:(0,$.jsx)(I,{intent:B.PRIMARY,icon:`floppy-disk`,text:n(`common.save`,`Save`),loading:a,onClick:async()=>{o(!0);try{await ce({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)}}})})]})]})},_t=({isAdmin:e})=>{let{t}=f();return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(U,{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)(q,{elevation:P.ONE,children:[(0,$.jsx)(U,{children:t(`account.clearLogs`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-4`,children:t(`account.clearLogsDesc`)}),(0,$.jsx)(I,{fill:!0,intent:B.DANGER,text:t(`account.clearLogsBtn`),icon:`trash`,onClick:async()=>{if(confirm(t(`account.confirmClearLogs`)))try{await Re(),alert(t(`account.clearLogsSuccess`))}catch(e){console.error(e)}}})]}),!e&&(0,$.jsxs)(q,{elevation:P.ONE,children:[(0,$.jsx)(U,{children:t(`account.deleteAccount`)}),(0,$.jsx)(`p`,{className:`text-xs opacity-60 mb-4`,children:t(`account.deleteAccountDesc`)}),(0,$.jsx)(I,{fill:!0,intent:B.DANGER,text:t(`account.deleteAccountBtn`),icon:`delete`,onClick:async()=>{if(confirm(t(`account.confirmDeleteAccount`)))try{await Oe(),window.location.href=`/`}catch(e){console.error(e),alert(e.message||t(`common.errorNetwork`))}}})]})]}),(0,$.jsx)(z,{intent:B.WARNING,icon:`info-sign`,title:t(`account.inactivityPolicy`),children:(0,$.jsx)(`p`,{className:`text-sm`,children:t(`account.inactivityDesc`)})})]})},vt=[{label:j(`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`}],yt=({me:e,isEditingUsername:t,setIsEditingUsername:n,editUsername:i,setEditUsername:a,usernameLoading:o,usernameFocused:s,setUsernameFocused:c,onUpdateUsername:l,onUpdateTimezone:u})=>{let{t:d}=f();return(0,$.jsxs)(q,{elevation:P.ONE,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 mb-4`,children:[(0,$.jsx)(h,{size:20,className:`text-blue-500`}),(0,$.jsx)(U,{style:{margin:0},children:d(`account.personalInfo`)})]}),(0,$.jsxs)(`div`,{className:`space-y-4`,children:[(0,$.jsx)(W,{label:d(`account.username`),children:(0,$.jsx)(`div`,{className:`flex gap-2`,children:t?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(K,{content:d(`account.formatTipUsername`),isOpen:s,position:M.TOP,intent:B.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(H,{fill:!0,value:i,onChange:e=>a(e.target.value),onFocus:()=>c(!0),onBlur:()=>c(!1),autoFocus:!0})})}),(0,$.jsxs)(N,{children:[(0,$.jsx)(I,{icon:(0,$.jsx)(x,{size:16}),intent:B.SUCCESS,loading:o,onClick:l}),(0,$.jsx)(I,{icon:(0,$.jsx)(E,{size:16}),onClick:()=>{n(!1),a(e?.username||``)}})]})]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(H,{fill:!0,value:e?.username,readOnly:!0}),(0,$.jsx)(I,{icon:(0,$.jsx)(r,{size:16}),onClick:()=>n(!0)})]})})}),(0,$.jsx)(W,{label:d(`account.userId`),children:(0,$.jsx)(H,{leftIcon:`id-number`,value:e?.id,disabled:!0})}),(0,$.jsx)(W,{label:d(`account.timezone`,`Timezone`),children:(0,$.jsx)(re,{fill:!0,value:e?.timezone||``,onChange:e=>u?.(e.target.value||null),options:vt})})]})]})},bt=({me:e,onRefresh:r})=>{let{t:i}=f(),a=!!(e?.passkeys_count&&e.passkeys_count>0),o=!!e?.totp_enabled,[s,c]=(0,Q.useState)(`password`),[l,u]=(0,Q.useState)(``),[d,p]=(0,Q.useState)(!1),[h,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)(()=>{s===`passkey`&&!a?c(o?`totp`:`password`):s===`totp`&&!o&&c(a?`passkey`:`password`)},[a,o,s]),(0,$.jsxs)(q,{elevation:P.ONE,className:`isolate`,style:{isolation:`isolate`},children:[(0,$.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-2 mb-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(t,{size:20,className:`text-orange-500`}),(0,$.jsx)(U,{style:{margin:0},children:i(`account.changePassword`,`Change Password`)})]}),(a||o)&&(0,$.jsx)(`div`,{className:`flex items-center isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(I,{small:!0,active:s===`password`,intent:s===`password`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(m,{size:14}),text:i(`account.mfa.password`,`Password`),onClick:()=>{c(`password`),E(null)}}),a&&(0,$.jsx)(I,{small:!0,active:s===`passkey`,intent:s===`passkey`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(t,{size:14}),text:i(`account.mfa.passkey`,`Passkey`),onClick:()=>{c(`passkey`),E(null)}}),o&&(0,$.jsx)(I,{small:!0,active:s===`totp`,intent:s===`totp`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(n,{size:14}),text:i(`account.mfa.totp`,`TOTP`),onClick:()=>{c(`totp`),E(null)}})]})})]}),T&&(0,$.jsx)(z,{intent:T.intent,className:`mb-4`,children:T.text}),(0,$.jsxs)(`form`,{onSubmit:async t=>{if(t.preventDefault(),!ke.test(_)){E({text:i(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),intent:B.DANGER});return}if(!e?.username){E({text:i(`auth.sessionExpired`,`Session expired. Please log in again.`),intent:B.DANGER});return}w(!0),E(null);try{let t=await Y(_,e.username);if(s===`passkey`)await me({passkeyAssertion:await qe(await Ce()),newPassword:t});else if(s===`totp`){if(h.length!==6){E({text:i(`account.totp.invalidCode`,`Please enter a 6-digit code`),intent:B.DANGER}),w(!1);return}let e=crypto.randomUUID(),n=new TextEncoder().encode(h+e),r=await crypto.subtle.digest(`SHA-256`,n);await me({totpTokenHash:Array.from(new Uint8Array(r)).map(e=>e.toString(16).padStart(2,`0`)).join(``),totpSalt:e,newPassword:t})}else{if(!l){E({text:i(`auth.passwordRequired`,`Current password is required`),intent:B.DANGER}),w(!1);return}let n=l;(e.password_version??1)===2&&(n=await Y(l,e.username)),await me({oldPassword:n,newPassword:t})}E({text:i(`account.passwordSuccess`,`Password updated successfully!`),intent:B.SUCCESS}),u(``),g(``),v(``),r&&r()}catch(e){E({text:Z(e,i),intent:B.DANGER})}finally{w(!1)}},className:`space-y-4`,children:[s===`password`&&(0,$.jsx)(W,{label:i(`account.currentPassword`,`Current Password`),children:(0,$.jsx)(H,{leftIcon:`lock`,type:d?`text`:`password`,value:l,onChange:e=>u(e.target.value),rightElement:(0,$.jsx)(I,{minimal:!0,icon:d?`eye-open`:`eye-off`,onClick:()=>p(!d),title:i(d?`auth.hidePassword`:`auth.showPassword`)}),required:!0})}),s===`totp`&&(0,$.jsx)(W,{label:i(`account.totpCode`,`Authenticator Code`),children:(0,$.jsx)(X,{length:6,value:h,onChange:g,disabled:C})}),s===`passkey`&&(0,$.jsx)(z,{intent:B.PRIMARY,children:(0,$.jsx)(`span`,{className:`text-xs`,children:i(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`)})}),(0,$.jsx)(W,{label:i(`account.newPassword`,`New Password`),children:(0,$.jsx)(K,{content:i(`account.formatTipPassword`,`Password must be 12-100 characters and contain letters, numbers, and symbols.`),isOpen:x,position:M.TOP,intent:B.PRIMARY,className:`w-full`,children:(0,$.jsx)(`div`,{className:`w-full block`,children:(0,$.jsx)(H,{leftIcon:`lock`,type:y?`text`:`password`,value:_,onChange:e=>v(e.target.value),onFocus:()=>S(!0),onBlur:()=>S(!1),rightElement:(0,$.jsx)(I,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:i(y?`auth.hidePassword`:`auth.showPassword`)}),required:!0})})})}),(0,$.jsx)(I,{fill:!0,intent:s===`passkey`?B.PRIMARY:B.WARNING,type:`submit`,loading:C,icon:s===`passkey`?(0,$.jsx)(t,{size:16}):void 0,text:s===`passkey`?i(`account.changePasswordWithPasskey`,`Verify with Passkey & Update`):i(`account.updatePassword`,`Update Password`)})]})]})},xt=({isOpen:e,onClose:r,user:i,onSuccess:a})=>{let{t:o}=f(),s=!!(i?.passkeys_count&&i.passkeys_count>0),c=!!i?.totp_enabled,[l,u]=(0,Q.useState)(`password`),[d,p]=(0,Q.useState)(``),[h,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)(()=>{l===`passkey`&&!s?u(c?`totp`:`password`):l===`totp`&&!c&&u(s?`passkey`:`password`)},[s,c,l]);let k=async(e,t)=>{if(e&&e.preventDefault(),d.length!==4||!ze.test(d)){E(o(`auth.pinFormatTip`,`PIN must be exactly 4 digits`));return}if(d!==h){E(o(`auth.pinMatchTip`,`PINs do not match`));return}w(!0),E(``);try{let e=i?.id||sessionStorage.getItem(`dns_worker_user_id`);if(!e){E(o(`auth.sessionExpired`,`Session expired. Logging out...`)),setTimeout(()=>{A()},1500);return}let n=await Me(d,e),r={};if(l===`passkey`)r.passkeyAssertion=await qe(await Ce());else if(l===`totp`){let e=(t||x).replace(/\s/g,``);if(e.length!==6){E(o(`account.totp.invalidCode`,`Please enter a 6-digit code`)),w(!1);return}let n=crypto.randomUUID();r.totpTokenHash=await Be(e,n),r.totpSalt=n}else{if(!_){E(o(`auth.passwordRequired`,`Password is required for verification`)),w(!1);return}let e=_;i?.password_version===2&&i?.username&&(e=await Y(_,i.username)),r.password=e}await Fe(n,r),p(``),g(``),v(``),S(``),a()}catch(e){E(Z(e,o))}finally{w(!1)}},A=()=>{E(``),p(``),g(``),v(``),b(!1),S(``),u(`password`),r()};return(0,$.jsx)(L,{isOpen:e,onClose:A,title:i?.pin_enabled?o(`auth.changePin`,`Change PIN`):o(`auth.configurePin`,`Configure PIN`),icon:`key`,className:`pb-0`,style:{width:`420px`},children:(0,$.jsxs)(`form`,{onSubmit:k,children:[(0,$.jsxs)(`div`,{className:F,children:[T&&(0,$.jsx)(z,{intent:B.DANGER,className:`mb-4`,children:T}),(0,$.jsx)(W,{label:o(`auth.newPin`,`New 4-Digit PIN`),labelFor:`new-pin-input`,helperText:o(`auth.pinHelper`,`Digits only, e.g., 1234`),children:(0,$.jsx)(X,{length:4,value:d,onChange:p,type:`password`,disabled:C,autoFocus:!0,onComplete:()=>D.current?.focus()})}),(0,$.jsx)(W,{label:o(`auth.confirmPin`,`Confirm New PIN`),labelFor:`confirm-pin-input`,children:(0,$.jsx)(X,{ref:D,length:4,value:h,onChange:g,type:`password`,disabled:C,onComplete:()=>{l===`totp`?O.current?.focus():l===`password`&&document.getElementById(`verify-pw-input`)?.focus()}})}),(0,$.jsx)(V,{className:`my-4`}),(0,$.jsxs)(`div`,{className:`flex justify-between items-center mb-3`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm`,children:o(`auth.verifyIdentity`,`Verify Identity`)}),(s||c)&&(0,$.jsx)(`div`,{className:`flex items-center isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(I,{small:!0,active:l===`password`,intent:l===`password`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(m,{size:14}),text:o(`account.mfa.password`,`Password`),onClick:()=>{u(`password`),E(``)}}),s&&(0,$.jsx)(I,{small:!0,active:l===`passkey`,intent:l===`passkey`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(t,{size:14}),text:o(`account.mfa.passkey`,`Passkey`),onClick:()=>{u(`passkey`),E(``)}}),c&&(0,$.jsx)(I,{small:!0,active:l===`totp`,intent:l===`totp`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(n,{size:14}),text:o(`account.mfa.totp`,`TOTP`),onClick:()=>{u(`totp`),E(``)}})]})})]}),l===`password`&&(0,$.jsx)(W,{label:o(`auth.currentPassword`,`Current Password`),labelFor:`verify-pw-input`,children:(0,$.jsx)(H,{id:`verify-pw-input`,type:y?`text`:`password`,placeholder:o(`auth.passwordPlaceholder`,`Enter current password`),value:_,onChange:e=>v(e.target.value),leftIcon:`lock`,rightElement:(0,$.jsx)(I,{minimal:!0,icon:y?`eye-open`:`eye-off`,onClick:()=>b(!y),title:y?o(`auth.hidePassword`,`Hide password`):o(`auth.showPassword`,`Show password`)}),required:!0})}),l===`totp`&&(0,$.jsx)(W,{label:o(`auth.totpCode`,`TOTP Code`),labelFor:`verify-totp-input`,children:(0,$.jsx)(X,{ref:O,length:6,value:x,onChange:S,disabled:C,onComplete:e=>k(void 0,e),autoFocus:!0})}),l===`passkey`&&(0,$.jsx)(z,{intent:B.PRIMARY,icon:(0,$.jsx)(t,{size:16}),children:(0,$.jsx)(`span`,{className:`text-xs`,children:o(`account.passkey.submitNotice`,o(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`))})})]}),(0,$.jsx)(`div`,{className:R,children:(0,$.jsxs)(`div`,{className:oe,children:[(0,$.jsx)(I,{onClick:A,children:o(`common.cancel`,`Cancel`)}),(0,$.jsx)(I,{type:`submit`,intent:B.PRIMARY,loading:C,children:o(`common.save`,`Save`)})]})})]})})},St=({isOpen:e,onClose:r,user:i,onSuccess:a})=>{let{t:o}=f(),s=!!(i?.passkeys_count&&i.passkeys_count>0),c=!!i?.totp_enabled,[l,u]=(0,Q.useState)(`password`),[d,p]=(0,Q.useState)(``),[h,g]=(0,Q.useState)(!1),[_,v]=(0,Q.useState)(``),[b,x]=(0,Q.useState)(!1),[S,C]=(0,Q.useState)(``);(0,Q.useEffect)(()=>{l===`passkey`&&!s?u(c?`totp`:`password`):l===`totp`&&!c&&u(s?`passkey`:`password`)},[s,c,l]);let w=async(e,t)=>{e&&e.preventDefault(),x(!0),C(``);try{let e={};if(l===`passkey`)e.passkeyAssertion=await qe(await Ce());else if(l===`totp`){let n=(t||_).replace(/\s/g,``);if(n.length!==6){C(o(`account.totp.invalidCode`,`Please enter a 6-digit code`)),x(!1);return}let r=crypto.randomUUID();e.totpTokenHash=await Be(n,r),e.totpSalt=r}else{if(!d){C(o(`auth.passwordRequired`,`Password is required for verification`)),x(!1);return}let t=d;i?.password_version===2&&i?.username&&(t=await Y(d,i.username)),e.password=t}await Pe(e),p(``),v(``),a()}catch(e){C(Z(e,o))}finally{x(!1)}},T=()=>{C(``),p(``),g(!1),v(``),u(`password`),r()};return(0,$.jsx)(L,{isOpen:e,onClose:T,title:o(`auth.disablePin`,`Disable Session Lock`),icon:`trash`,className:`pb-0`,style:{width:`420px`},children:(0,$.jsxs)(`form`,{onSubmit:w,children:[(0,$.jsxs)(`div`,{className:F,children:[S&&(0,$.jsx)(z,{intent:B.DANGER,className:`mb-4`,children:S}),(0,$.jsx)(z,{intent:B.WARNING,className:`mb-4`,icon:(0,$.jsx)(y,{size:20}),children:o(`auth.disablePinWarning`,`Disabling the PIN will disable the inactivity session locking feature completely.`)}),(0,$.jsxs)(`div`,{className:`flex justify-between items-center mb-3`,children:[(0,$.jsx)(`span`,{className:`font-semibold text-sm`,children:o(`auth.verifyIdentity`,`Verify Identity`)}),(s||c)&&(0,$.jsx)(`div`,{className:`flex items-center isolate`,style:{isolation:`isolate`},children:(0,$.jsxs)(N,{variant:`minimal`,style:{isolation:`isolate`},children:[(0,$.jsx)(I,{small:!0,active:l===`password`,intent:l===`password`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(m,{size:14}),text:o(`account.mfa.password`,`Password`),onClick:()=>{u(`password`),C(``)}}),s&&(0,$.jsx)(I,{small:!0,active:l===`passkey`,intent:l===`passkey`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(t,{size:14}),text:o(`account.mfa.passkey`,`Passkey`),onClick:()=>{u(`passkey`),C(``)}}),c&&(0,$.jsx)(I,{small:!0,active:l===`totp`,intent:l===`totp`?B.PRIMARY:B.NONE,icon:(0,$.jsx)(n,{size:14}),text:o(`account.mfa.totp`,`TOTP`),onClick:()=>{u(`totp`),C(``)}})]})})]}),l===`password`&&(0,$.jsx)(W,{label:o(`auth.currentPassword`,`Current Password`),labelFor:`disable-pw-input`,children:(0,$.jsx)(H,{id:`disable-pw-input`,type:h?`text`:`password`,placeholder:o(`auth.passwordPlaceholder`,`Enter current password`),value:d,onChange:e=>p(e.target.value),leftIcon:`lock`,rightElement:(0,$.jsx)(I,{minimal:!0,icon:h?`eye-open`:`eye-off`,onClick:()=>g(!h),title:h?o(`auth.hidePassword`,`Hide password`):o(`auth.showPassword`,`Show password`)}),required:!0})}),l===`totp`&&(0,$.jsx)(W,{label:o(`auth.totpCode`,`TOTP Code`),labelFor:`disable-totp-input`,children:(0,$.jsx)(X,{length:6,value:_,onChange:v,disabled:b,onComplete:e=>w(void 0,e),autoFocus:!0})}),l===`passkey`&&(0,$.jsx)(z,{intent:B.PRIMARY,icon:(0,$.jsx)(t,{size:16}),children:(0,$.jsx)(`span`,{className:`text-xs`,children:o(`account.passkey.submitNotice`,o(`account.passkey.changePwNotice`,`You will be prompted to verify via biometric authentication or your security key when submitting.`))})})]}),(0,$.jsx)(`div`,{className:R,children:(0,$.jsxs)(`div`,{className:oe,children:[(0,$.jsx)(I,{onClick:T,children:o(`common.cancel`,`Cancel`)}),(0,$.jsx)(I,{type:`submit`,intent:B.DANGER,loading:b,children:o(`common.disable`,`Disable`)})]})})]})})},Ct=({user:e,onRefresh:t})=>{let{t:r}=f(),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(!1),[c,l]=(0,Q.useState)(!1),u=!!e?.pin_enabled,d=e?.session_lock_timeout||15,p=async e=>{let n=Number(e.currentTarget.value);a(!0);try{await ve({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)(q,{elevation:P.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)(U,{className:`m-0!`,children:r(`auth.sessionLockTitle`,`Idle Session Lock`)})]}),!u&&(0,$.jsx)(I,{icon:`key`,intent:B.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)(re,{value:d,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)(I,{icon:`edit`,onClick:m,disabled:i,children:r(`auth.changePin`,`Change PIN`)}),(0,$.jsx)(I,{icon:`trash`,intent:B.DANGER,onClick:()=>{l(!0)},disabled:i,children:r(`auth.disablePin`,`Disable PIN & Lock`)}),(0,$.jsx)(I,{icon:`lock`,intent:B.WARNING,onClick:async()=>{a(!0);try{await Te(),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)(xt,{isOpen:o,onClose:()=>s(!1),user:e,onSuccess:()=>{s(!1),t()}}),(0,$.jsx)(St,{isOpen:c,onClose:()=>l(!1),user:e,onSuccess:()=>{l(!1),t()}})]})},wt=()=>{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:d}=f(),p=Ee(),[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 Ie())}catch(e){console.error(e)}},T=async()=>{try{C(await ye())}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 A(async()=>{let{setSystemTimeZone:e}=await import(`./date-WF-_cJDs.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 A(async()=>{let{setSystemLocale:e}=await import(`./date-WF-_cJDs.js`);return{setSystemLocale:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));t(e.locale),d.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:se(`max-w-5xl mx-auto space-y-8`,p?`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)(G,{large:!0,round:!0,intent:e.role===`admin`?B.DANGER:B.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)(z,{intent:B.WARNING,icon:(0,$.jsx)(u,{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)(yt,{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(!je.test(g)){alert(l(`account.formatTipUsername`));return}y(!0);try{await ve({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 ve({timezone:e||``}),t(t=>t?{...t,timezone:e}:null);let{setSystemTimeZone:n}=await A(async()=>{let{setSystemTimeZone:e}=await import(`./date-WF-_cJDs.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)(bt,{me:e,onRefresh:E})]}),e&&(0,$.jsx)(ct,{user:e,onRefresh:E}),e&&(0,$.jsx)(Ct,{user:e,onRefresh:E}),e&&(0,$.jsx)(mt,{hoveredSessionId:s,setHoveredSessionId:c}),e&&(0,$.jsx)(pt,{hoveredSessionId:s,setHoveredSessionId:c}),e?.role===`admin`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(V,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(ht,{users:r,currentUserId:e.id,onRefresh:w,registrationEnabled:S.registration_enabled!==`false`,onRefreshSettings:T})}),(0,$.jsx)(V,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(gt,{initialSettings:S,onRefresh:T})})]}),(0,$.jsx)(V,{}),(0,$.jsx)(`div`,{className:`space-y-4`,children:(0,$.jsx)(_t,{isAdmin:e?.role===`admin`})})]})};export{wt as AccountView};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TrendChart-Dl9UU7gA.js","assets/index-DLmOvLdX.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-DifRgRH3.js","assets/vendor-ui-core-CCxBtqRD.js","assets/vendor-utils-D17P9mkD.js","assets/vendor-i18next-cO7FDf_e.js","assets/index-DdQuGqR5.css","assets/DestinationMap-DUZnyLyb.js","assets/formatCountryName-CSBD8pP8.js","assets/getFlagEmoji-_Wxhq0lT.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{D as t,J as n,L as r,Xt as i,gt as a,j as o,tt as s,v as c}from"./vendor-react-DifRgRH3.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 ee,V as _,d as v,f as y,o as b,p as x,r as S,u as C,x as w}from"./vendor-ui-core-CCxBtqRD.js";import{_t as T}from"./vendor-utils-D17P9mkD.js";import{$ as E,Q as D,Xt as O,et as k}from"./index-DLmOvLdX.js";import{t as A}from"./getFlagEmoji-_Wxhq0lT.js";var j=e(l(),1);function te(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 M=e(u(),1);const N=({title:e,value:t,icon:n})=>(0,M.jsxs)(w,{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,M.jsx)(`div`,{className:`p-3 bg-gray-50 dark:bg-gray-800 rounded-lg`,children:n}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`div`,{className:`text-xs text-gray-500 font-medium uppercase tracking-wider`,children:e}),(0,M.jsx)(`div`,{className:`text-xl font-bold dark:text-white`,children:t})]})]}),P=({title:e,data:t,intent:n})=>{let{t:r}=i(),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,M.jsx)(S,{minimal:!0,intent:n,className:`font-bold`,children:e.count})}];return(0,M.jsxs)(w,{elevation:p.ZERO,className:`dark:bg-gray-900 dark:border-gray-800 border border-gray-100 shadow-sm`,children:[(0,M.jsx)(m,{className:`mb-4 font-bold`,children:e}),(0,M.jsx)(C,{striped:!0,className:`w-full`,children:(0,M.jsxs)(`tbody`,{children:[t.map((e,t)=>(0,M.jsx)(`tr`,{children:a.map(n=>(0,M.jsx)(`td`,{className:n.cellClassName,children:n.render(e,t)},n.key))},t)),t.length===0&&(0,M.jsx)(`tr`,{children:(0,M.jsx)(`td`,{colSpan:a.length,className:`text-center py-8 opacity-50`,children:r(`analytics.noData`)})})]})})]})};var F=(0,j.lazy)(()=>d(()=>import(`./TrendChart-Dl9UU7gA.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10])).then(e=>({default:e.TrendChart}))),I=(0,j.lazy)(()=>d(()=>import(`./DestinationMap-DUZnyLyb.js`),__vite__mapDeps([11,1,2,3,4,5,6,7,8,9,10,12,13])).then(e=>({default:e.DestinationMap}))),L=()=>(0,M.jsx)(`div`,{className:`h-64 flex items-center justify-center`,children:(0,M.jsx)(g,{size:30})});const R=({profileId:e})=>{let[l,u]=(0,j.useState)(null),[d,R]=(0,j.useState)(!0),{t:z}=i(),ne=O(),[B,V]=(0,j.useState)(`24h`),[H,U]=(0,j.useState)({start:``,end:``}),[W,G]=(0,j.useState)(null),[K,q]=(0,j.useState)([]),[J,Y]=(0,j.useState)(30);(0,j.useEffect)(()=>{D(e).then(e=>q(e)).catch(e=>console.error(`Failed to load access points`,e))},[e]),(0,j.useEffect)(()=>{k(e).then(e=>{try{let t=JSON.parse(e.settings||`{}`);Y(t.log_retention_days===void 0?30:Number(t.log_retention_days))}catch(e){console.error(`Failed to parse settings`,e)}}).catch(e=>console.error(`Failed to fetch profile settings`,e))},[e]);let X=async(t,n,r,i)=>{R(!0);try{let a=`?range=${t}`;if(t===`custom`&&n&&r){let e=Math.floor(new Date(n).getTime()/1e3),t=Math.floor(new Date(r).getTime()/1e3);a+=`&start=${e}&end=${t}`}i&&(a+=`&access_point_id=${i}`);let[o,s,c,l,d,f]=await Promise.all([E(e,`summary`,a),E(e,`trend`,a),E(e,`top_allowed`,a),E(e,`top_blocked`,a),E(e,`clients`,a),E(e,`destinations`,a)]);u({summary:o,trend:s,top_allowed:c,top_blocked:l,clients:d,destinations:f})}catch(e){console.error(`Failed to fetch analytics`,e)}finally{R(!1)}};if((0,j.useEffect)(()=>{B!==`custom`&&X(B,void 0,void 0,W)},[e,B,W]),d&&!l)return(0,M.jsx)(`div`,{className:`p-20 flex justify-center`,children:(0,M.jsx)(g,{size:50})});let re=te(l,B,H),Z=l?.summary.reduce((e,t)=>e+t.count,0)||0,Q=l?.summary.find(e=>e.action===`BLOCK`)?.count||0,ie=l?.summary.find(e=>e.action===`REDIRECT`)?.count||0,ae=Z>0?(Q/Z*100).toFixed(1):`0.0`,$=new Date().toLocaleString(`sv-SE`).replace(` `,`T`).slice(0,16),oe=[{title:z(`analytics.totalQueries`),value:Z.toLocaleString(),icon:(0,M.jsx)(c,{className:`text-blue-500`,size:20})},{title:z(`analytics.blocked`),value:Q.toLocaleString(),icon:(0,M.jsx)(o,{className:`text-red-500`,size:20})},{title:z(`analytics.redirected`),value:ie.toLocaleString(),icon:(0,M.jsx)(r,{className:`text-amber-500`,size:20})},{title:z(`analytics.blockRate`),value:`${ae}%`,icon:(0,M.jsx)(t,{className:`text-green-500`,size:20})},{title:z(`analytics.activeIPs`),value:l?.clients.length.toString()||`0`,icon:(0,M.jsx)(s,{className:`text-purple-500`,size:20})}],se=[{key:`10m`,days:.007},{key:`1h`,days:.0416},{key:`24h`,days:1},{key:`7d`,days:7},{key:`30d`,days:30}].filter(e=>e.days<=J).map(e=>e.key);return(0,M.jsxs)(`div`,{className:T(`max-w-7xl mx-auto space-y-6`,ne?`p-0`:`p-6`),children:[(0,M.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,M.jsxs)(f,{variant:`minimal`,children:[se.map(e=>(0,M.jsx)(h,{active:B===e,onClick:()=>V(e),text:e.toUpperCase()},e)),(0,M.jsx)(ee,{content:(0,M.jsxs)(`div`,{className:`p-4 space-y-4 w-64`,children:[(0,M.jsx)(m,{children:z(`analytics.customRange`)}),(0,M.jsx)(x,{label:z(`analytics.startTime`),children:(0,M.jsx)(y,{type:`datetime-local`,max:H.end||$,value:H.start,onChange:e=>U({...H,start:e.target.value})})}),(0,M.jsx)(x,{label:z(`analytics.endTime`),children:(0,M.jsx)(y,{type:`datetime-local`,min:H.start,max:$,value:H.end,onChange:e=>U({...H,end:e.target.value})})}),(0,M.jsx)(h,{fill:!0,intent:_.PRIMARY,text:z(`analytics.apply`),onClick:()=>{V(`custom`),X(`custom`,H.start,H.end,W)}})]}),children:(0,M.jsx)(h,{active:B===`custom`,icon:(0,M.jsx)(a,{size:14,className:`mr-1`}),text:z(`analytics.custom`)})})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-4`,children:[K.length>0&&(0,M.jsx)(v,{value:W||``,onChange:e=>G(e.target.value||null),options:[{label:`${z(`logs.allAccessPoint`)}`,value:``},...K.map(e=>({label:e.name,value:e.id}))],minimal:!0}),d&&(0,M.jsx)(g,{size:16})]})]}),(0,M.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:oe.map((e,t)=>(0,M.jsx)(N,{title:e.title,value:e.value,icon:e.icon},t))}),(0,M.jsxs)(w,{elevation:p.ONE,className:`dark:bg-gray-900 dark:border-gray-800 relative`,children:[(0,M.jsxs)(m,{className:`mb-4 font-bold flex items-center gap-2`,children:[z(`analytics.queryTrend`),(0,M.jsx)(S,{minimal:!0,round:!0,children:B===`custom`?z(`analytics.custom`):B.toUpperCase()})]}),(0,M.jsx)(j.Suspense,{fallback:(0,M.jsx)(L,{}),children:(0,M.jsx)(F,{chartData:re,range:B})})]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-6`,children:[(0,M.jsx)(P,{title:z(`analytics.topAllowed`),data:l?.top_allowed||[],intent:_.SUCCESS}),(0,M.jsx)(P,{title:z(`analytics.topBlocked`),data:l?.top_blocked||[],intent:_.DANGER})]}),(0,M.jsxs)(`div`,{className:`grid gap-6 grid-cols-1`,children:[(0,M.jsx)(b,{title:z(`analytics.destinationDistribution`),icon:(0,M.jsx)(n,{size:16}),children:(0,M.jsx)(j.Suspense,{fallback:(0,M.jsx)(L,{}),children:(0,M.jsx)(I,{destinations:l?.destinations||[],profileId:e||``,range:B,customRange:H,accessPointId:W||void 0})})}),(0,M.jsx)(b,{title:z(`analytics.clientActivity`),icon:(0,M.jsx)(s,{size:16}),children:(0,M.jsxs)(C,{striped:!0,className:`w-full mt-2`,children:[(0,M.jsx)(`thead`,{children:(0,M.jsxs)(`tr`,{children:[(0,M.jsx)(`th`,{className:`text-xs uppercase opacity-60`,children:z(`analytics.ipAddress`)}),(0,M.jsx)(`th`,{className:`text-xs uppercase opacity-60`,children:z(`analytics.location`)}),(0,M.jsx)(`th`,{className:`text-xs uppercase opacity-60 text-right`,children:z(`analytics.queries`)})]})}),(0,M.jsx)(`tbody`,{children:l?.clients.map((e,t)=>(0,M.jsxs)(`tr`,{children:[(0,M.jsx)(`td`,{className:`font-mono text-xs`,children:e.client_ip}),(0,M.jsx)(`td`,{children:(0,M.jsx)(S,{minimal:!0,children:A(e.geo_country)})}),(0,M.jsx)(`td`,{className:`text-right font-bold`,children:e.count})]},t))})]})})]})]})};export{R as AnalyticsView};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{$ as t,E as n,Xt as r,ct as i,et as a,xt as o}from"./vendor-react-DifRgRH3.js";import{S as s,b as c}from"./vendor-icons-other-Bme3ywH9.js";import"./vendor-i18next-cO7FDf_e.js";import{A as l,B as u,H as d,N as f,S as p,V as m,f as h,m as g,p as _,r as v,v as y,x as b}from"./vendor-ui-core-CCxBtqRD.js";import{_t as x}from"./vendor-utils-D17P9mkD.js";import{Bt as S,Ct as C,Et as w,Jt as T,Kt as E,Lt as D,Mt as O,S as k,Vt as A,Wt as j,b as M,d as N,g as P,gt as F,h as I,l as ee,m as L,n as R,p as te,r as ne,t as z,u as B,v as V,x as H,y as U,zt as re}from"./index-DLmOvLdX.js";import{i as ie,r as ae,t as W}from"./QRCodeCanvas-vzXe_hzQ.js";var G=e(s(),1),K=e(c(),1);const q=({username:e,setUsername:t,isTurnstileEnabled:n,turnstileRef:i,loading:a,turnstileStatus:o,onSubmit:s})=>{let{t:c}=r();return(0,K.jsxs)(`form`,{onSubmit:s,className:`space-y-4`,children:[(0,K.jsx)(_,{label:c(`auth.username`),labelFor:`username`,children:(0,K.jsx)(h,{id:`username`,leftIcon:`user`,placeholder:c(`auth.usernamePlaceholder`),size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,required:!0})}),n&&(0,K.jsx)(`div`,{className:`py-2 flex justify-center min-h-16.25`,children:(0,K.jsx)(`div`,{ref:i})}),(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:a||o===`verifying`,disabled:!!n&&o!==`success`,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:o===`verifying`?c(`auth.verifying`):c(`auth.next`,`Next`)})]})},oe=({password:e,setPassword:t,hasMfa:n,onSwitchToMfa:i,loading:a,onSubmit:o,keepLoggedIn:s,setKeepLoggedIn:c,optionalSessionExpirationDays:l})=>{let[u,d]=G.useState(!1),{t:p}=r();return(0,K.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,K.jsx)(_,{label:p(`auth.password`),labelFor:`password`,children:(0,K.jsx)(h,{id:`password`,leftIcon:`lock`,placeholder:p(`auth.passwordPlaceholder`),type:u?`text`:`password`,size:`large`,className:`rounded-xl`,value:e,onChange:e=>t(e.target.value),rightElement:(()=>(0,K.jsxs)(`div`,{className:`flex items-center`,children:[e&&(0,K.jsx)(f,{minimal:!0,icon:`cross`,onClick:()=>t(``)}),(0,K.jsx)(f,{minimal:!0,icon:u?`eye-open`:`eye-off`,onClick:()=>d(!u),title:u?p(`auth.hidePassword`,`Hide password`):p(`auth.showPassword`,`Show password`)})]}))(),autoFocus:!0,required:!0})}),(0,K.jsx)(g,{checked:s,onChange:e=>c(e.currentTarget.checked),label:p(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:l}),className:`mt-4 text-left`}),(0,K.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:a,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:n?p(`auth.next`,`Next`):p(`auth.loginBtn`,`Login`)}),n&&i&&(0,K.jsx)(f,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:a,onClick:i,className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:p(`auth.otherOptions`,`其他选项`)})]})]})},J=({value:e,onChange:t,disabled:n=!1,autoFocus:i=!0,className:a=``})=>{let{t:o}=r(),s=(0,G.useRef)([]),c=(e=>{let t=e.replace(/\D/g,``).slice(0,30),n=[];for(let e=0;e<5;e++)n.push(t.slice(e*6,(e+1)*6));return n})(e);(0,G.useEffect)(()=>{i&&s.current[0]&&s.current[0].focus()},[i]);let l=(e,n)=>{let r=n.replace(/\D/g,``).slice(0,6),i=[...c];i[e]=r,t(i.join(`-`)),r.length===6&&e<4&&s.current[e+1]?.focus()},u=(e,t)=>{if(t.key===`Backspace`&&c[e].length===0&&e>0){t.preventDefault();let n=s.current[e-1];n&&n.focus()}else t.key===`ArrowLeft`&&(t.currentTarget.selectionStart??0)===0&&e>0?(t.preventDefault(),s.current[e-1]?.focus()):t.key===`ArrowRight`&&(t.currentTarget.selectionStart??0)===c[e].length&&e<4&&(t.preventDefault(),s.current[e+1]?.focus())},d=(e,n)=>{let r=n.clipboardData.getData(`text`).replace(/\D/g,``);if(r.length>6){n.preventDefault();let i=[...c],a=0;for(let t=e;t<5&&a<r.length;t++){let e=r.slice(a,a+6);i[t]=e,a+=e.length}t(i.join(`-`));let o=Math.min(4,e+Math.ceil(r.length/6)-1);s.current[o]?.focus()}},f=c.map((e,t)=>e.length===6&&!U(e)?t:-1).filter(e=>e!==-1);return(0,K.jsxs)(`div`,{className:`space-y-2 ${a}`,children:[(0,K.jsx)(`div`,{className:`flex items-center justify-between gap-1 sm:gap-2`,children:c.map((e,t)=>{let r=e.length===6,i=r&&!U(e),a=r&&!i,c=`border-gray-300 dark:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20`;return i?c=`border-red-500 ring-2 ring-red-500/30 bg-red-50/40 dark:bg-red-950/20 text-red-600 dark:text-red-400`:a&&(c=`border-green-500/80 dark:border-green-500/60 bg-green-50/20 dark:bg-green-950/10 text-gray-900 dark:text-gray-100`),(0,K.jsxs)(G.Fragment,{children:[(0,K.jsx)(`input`,{ref:e=>{s.current[t]=e},type:`text`,inputMode:`numeric`,pattern:`[0-9]*`,maxLength:6,value:e,disabled:n,placeholder:`000000`,onChange:e=>l(t,e.target.value),onKeyDown:e=>u(t,e),onPaste:e=>d(t,e),className:`w-full min-w-0 text-center font-mono text-xs sm:text-sm tracking-wider py-2 sm:py-2.5 px-1 rounded-lg border transition-all duration-150 outline-none ${c}`,title:i?o(`auth.recoveryChecksumError`,{defaultValue:`校验码错误:该组 6 位数无法被 11 整除`,group:t+1}):void 0}),t<4&&(0,K.jsx)(`span`,{className:`text-gray-400 dark:text-gray-500 font-bold select-none text-xs`,children:`-`})]},t)})}),f.length>0&&(0,K.jsx)(`p`,{className:`text-xs text-red-500 dark:text-red-400 text-center font-medium mt-1`,children:o(`auth.recoveryChecksumErrorDesc`,{defaultValue:`第 {{groups}} 组校验码错误,请核对后重试`,groups:f.map(e=>e+1).join(`、`)})})]})},Y=({hasPasskey:e,requiresTotp:n,mfaMethod:i,setMfaMethod:o,passkeyLoading:s,onPasskeyLogin:c,totpToken:l,setTotpToken:u,recoveryKey:d,setRecoveryKey:p,loading:h,onClearError:v,onSubmit:y,keepLoggedIn:b,setKeepLoggedIn:x,optionalSessionExpirationDays:S})=>{let{t:C}=r(),w=e=>{o(e),v()};return(0,K.jsxs)(`form`,{onSubmit:e=>{if(e.preventDefault(),i===`passkey`){c();return}y(e)},className:`space-y-4`,children:[i===`passkey`&&(0,K.jsxs)(`div`,{className:`space-y-5 text-center py-2`,children:[(0,K.jsx)(`div`,{className:`mx-auto w-16 h-16 rounded-2xl bg-blue-50 dark:bg-blue-950/40 flex items-center justify-center text-blue-600 dark:text-blue-400`,children:(0,K.jsx)(t,{size:36})}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(`h4`,{className:`text-base font-semibold text-gray-900 dark:text-gray-100 m-0`,children:C(`auth.passkeyVerification`,`Passkey Verification`)}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 max-w-xs mx-auto leading-relaxed`,children:C(`auth.passkeyPromptDesc`,`Use your registered device's biometric or hardware security key to verify`)})]}),(0,K.jsx)(g,{checked:b,onChange:e=>x(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:S}),className:`text-left inline-block mt-2`}),(0,K.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,K.jsxs)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`button`,loading:s,disabled:h,onClick:c,className:`font-semibold py-6 rounded-xl shadow-lg shadow-blue-500/20 flex items-center justify-center space-x-2`,children:[(0,K.jsx)(t,{size:20,className:`inline mr-1.5`}),(0,K.jsx)(`span`,{children:C(`auth.verifyWithPasskey`,`Verify with Passkey`)})]}),n&&(0,K.jsx)(f,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:s||h,onClick:()=>w(`totp`),className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:C(`auth.otherOptions`,`Other Options`)}),(0,K.jsx)(`div`,{className:`pt-1`,children:(0,K.jsxs)(`button`,{type:`button`,onClick:()=>w(`recovery`),className:`text-xs text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal inline-flex items-center gap-1`,children:[(0,K.jsx)(a,{size:12}),(0,K.jsx)(`span`,{children:C(`auth.totpUseRecovery`,`Use Recovery Key`)})]})})]})]}),i===`totp`&&(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(_,{label:C(`account.totp.title`,`Time-based One-time Password (TOTP)`),helperText:C(`auth.totpPrompt`,`Please enter the 6-digit code from your authentication app`),children:(0,K.jsx)(`div`,{className:`pt-2`,children:(0,K.jsx)(R,{length:6,value:l,onChange:u,disabled:h,autoFocus:!0})})}),(0,K.jsx)(g,{checked:b,onChange:e=>x(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:S}),className:`mt-4 text-left`}),(0,K.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:h,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:C(`auth.loginBtn`,`Login`)}),e&&(0,K.jsx)(f,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:h,onClick:()=>w(`passkey`),className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:C(`auth.otherOptions`,`Other Options`)}),(0,K.jsx)(`div`,{className:`text-center pt-1`,children:(0,K.jsxs)(`button`,{type:`button`,onClick:()=>w(`recovery`),className:`text-xs text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal inline-flex items-center gap-1`,children:[(0,K.jsx)(a,{size:12}),(0,K.jsx)(`span`,{children:C(`auth.totpUseRecovery`,`Use Recovery Key`)})]})})]})]}),i===`recovery`&&(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(_,{label:C(`account.totp.recoveryKeysTitle`,`Recovery Keys`),helperText:C(`auth.recoveryPrompt`,`Please enter your 30-character recovery key (5 groups of 6 digits)`),children:(0,K.jsx)(`div`,{className:`pt-2`,children:(0,K.jsx)(J,{value:d,onChange:p,disabled:h,autoFocus:!0})})}),(0,K.jsx)(g,{checked:b,onChange:e=>x(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:S}),className:`mt-4 text-left`}),(0,K.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:h,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:C(`auth.loginBtn`,`Login`)}),(0,K.jsx)(`div`,{className:`text-center pt-1`,children:(0,K.jsx)(`button`,{type:`button`,onClick:()=>w(e?`passkey`:`totp`),className:`text-xs text-blue-600 dark:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal`,children:e?C(`auth.backToPasskey`,`Back to Passkey Verification`):C(`auth.totpUseApp`,`Use Authentication App`)})})]})]})]})},X=({authConfig:e,turnstileReady:t,onSuccess:n})=>{let[i,a]=(0,G.useState)(1),[o,s]=(0,G.useState)(``),[c,l]=(0,G.useState)(``),[u,d]=(0,G.useState)(``),[f,p]=(0,G.useState)(``),[m,h]=(0,G.useState)(!1),[g,_]=(0,G.useState)(1),[v,y]=(0,G.useState)(void 0),[b,x]=(0,G.useState)(void 0),[S,C]=(0,G.useState)(!0),[T,D]=(0,G.useState)(!1),[O,k]=(0,G.useState)(!1),[A,P]=(0,G.useState)(null),[F,R]=(0,G.useState)(!1),[z,V]=(0,G.useState)(`passkey`),[H,U]=(0,G.useState)(!1),[ie,W]=(0,G.useState)(``),[K,q]=(0,G.useState)(null),[oe,J]=(0,G.useState)(`idle`),Y=(0,G.useRef)(null),X=(0,G.useRef)(null),{t:Z}=r(),Q=e?.turnstile_enabled_login;(0,G.useEffect)(()=>{if(i===1&&Q&&e?.turnstile_site_key&&(t||window.turnstile)&&Y.current)try{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null),J(`verifying`),Y.current.innerHTML=``,X.current=window.turnstile.render(Y.current,{sitekey:e.turnstile_site_key,callback:e=>{q(e),J(`success`),W(``)},"expired-callback":()=>{q(null),J(`idle`)},"error-callback":e=>{console.error(`Turnstile error:`,e),J(`error`),W(Z(`auth.turnstileError`,`Verification service failed to load. Please reload and try again.`)),q(null)}})}catch(e){console.error(`Turnstile render error:`,e),J(`error`)}return()=>{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null)}},[Q,e,i,t,Z]);let se=async t=>{if(t.preventDefault(),!M(o)){W(Z(`auth.formatTipUsername`));return}if(Q&&e?.turnstile_site_key&&!K){W(Z(`auth.turnstileRequired`));return}U(!0),W(``);try{let e=await E({username:o,turnstileToken:K});C(e.requires_password),D(e.requires_totp),k(!!e.has_passkey),P(e.passkey_options||null),_(e.password_version??1),y(e.nonce),x(e.serverSalt),V(e.has_passkey?`passkey`:`totp`),e.requires_password?a(2):a(3)}catch(e){W(B(e,Z)),window.turnstile&&window.turnstile.reset(),q(null)}finally{U(!1)}},$=async e=>{U(!0),W(``);try{let t={keepLoggedIn:m,passkeyAssertion:e.passkeyAssertion,totpTokenHash:e.totpTokenHash,totpSalt:e.totpSalt,recoveryKey:e.recoveryKey};if(e.useEnteredPassword&&c)if(g===2){if(!v||!b)throw Error(Z(`auth.sessionExpired`,`Session expired, please start over`));t.password=await L(await ee(await N(c,o),b),v)}else t.password=c;let r=await j(t);r.accessToken&&ne(r.accessToken),r.needsMigration&&c&&await w(await N(c,o)),n()}catch(e){e instanceof re&&I({status:e.status},e.bodyText)?W(Z(`auth.passwordLeaked`)):W(B(e,Z))}finally{U(!1)}},ce=async e=>{if(e.preventDefault(),!c){W(Z(`auth.passwordRequiredFirst`,`Please enter your password first`));return}O||T?(W(``),a(3),V(O?`passkey`:`totp`)):await $({useEnteredPassword:!0})},le=()=>{l(``),W(``),a(3),V(O?`passkey`:`totp`)},ue=async()=>{if(A){R(!0),W(``);try{let e=await ae(A);await $({useEnteredPassword:!!c,passkeyAssertion:e})}catch(e){console.error(`Passkey authentication error:`,e),W(B(e,Z))}finally{R(!1)}}},de=async e=>{if(e.preventDefault(),z===`totp`){let e=u.replace(/\s/g,``);if(e.length!==6){W(Z(`auth.totpFormatError`,`Please enter a valid 6-digit code`));return}let t=crypto.randomUUID(),n=await te(e,t);await $({useEnteredPassword:!!c,totpTokenHash:n,totpSalt:t})}else if(z===`recovery`){let e=f.replace(/[-\s]/g,``);if(!e){W(Z(`auth.recoveryKeyRequired`,`Please enter your recovery key`));return}await $({useEnteredPassword:!!c,recoveryKey:e})}},fe=()=>{W(``),i===2?pe():i===3&&(S?a(2):pe())},pe=()=>{a(1),l(``),d(``),p(``),W(``),q(null),y(void 0),x(void 0),k(!1),P(null),R(!1),V(`passkey`)};return{loginStep:i,username:o,setUsername:s,password:c,setPassword:l,totpToken:u,setTotpToken:d,recoveryKey:f,setRecoveryKey:p,requiresPassword:S,requiresTotp:T,hasPasskey:O,mfaMethod:z,setMfaMethod:V,passkeyLoading:F,loading:H,error:ie,setError:W,turnstileStatus:oe,turnstileRef:Y,isTurnstileEnabled:Q,keepLoggedIn:m,setKeepLoggedIn:h,handleStep1Submit:se,handleStep2Submit:ce,handleStep3Submit:de,handleSwitchToMfa:le,handlePasskeyLogin:ue,handleBack:fe,resetToStep1:pe}},Z=({authConfig:e,turnstileReady:t,onSuccess:n,onToggleMode:i})=>{let{t:a}=r(),{loginStep:s,username:c,setUsername:u,password:d,setPassword:f,totpToken:h,setTotpToken:g,recoveryKey:_,setRecoveryKey:v,requiresTotp:y,hasPasskey:b,mfaMethod:x,setMfaMethod:S,passkeyLoading:C,loading:w,error:T,setError:E,turnstileStatus:D,turnstileRef:O,isTurnstileEnabled:k,keepLoggedIn:A,setKeepLoggedIn:j,handleStep1Submit:M,handleStep2Submit:N,handleStep3Submit:P,handleSwitchToMfa:F,handlePasskeyLogin:I,handleBack:ee}=X({authConfig:e,turnstileReady:t,onSuccess:n});return(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`flex flex-col items-center mb-8 relative`,children:[s!==1&&(0,K.jsx)(`button`,{type:`button`,onClick:ee,className:`absolute left-0 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 bg-transparent border-none cursor-pointer p-1 rounded-lg transition-colors`,title:a(`common.back`,`返回`),children:(0,K.jsx)(o,{size:24})}),(0,K.jsx)(`img`,{src:H,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,K.jsx)(l,{className:`font-bold tracking-tight text-2xl mt-4`,children:(()=>{switch(s){case 1:return a(`auth.login`);case 2:return a(`auth.password`);case 3:return a(`auth.mfaVerification`,`多因素认证`)}})()}),(0,K.jsx)(`p`,{className:`text-gray-500 mt-2 text-center text-sm leading-relaxed`,children:s===1?a(`auth.protectInternet`):c})]}),e?.has_users===!1&&(0,K.jsx)(p,{intent:m.PRIMARY,icon:`info-sign`,className:`mb-6 rounded-xl`,children:(0,K.jsxs)(`div`,{className:`flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3`,children:[(0,K.jsx)(`span`,{className:`text-sm font-medium`,children:a(`auth.noUsersRegistered`,`系统尚无账号,请注册成为管理员。`)}),(0,K.jsx)(`button`,{type:`button`,onClick:i,className:`text-xs bg-blue-600 hover:bg-blue-700 text-white font-semibold py-1.5 px-3 rounded-lg border-none cursor-pointer whitespace-nowrap transition-colors`,children:a(`auth.goToRegisterAdmin`,`注册管理员`)})]})}),T&&(0,K.jsx)(p,{intent:m.DANGER,className:`mb-6 rounded-xl`,title:a(`auth.error`),children:T}),s===1&&(0,K.jsx)(q,{username:c,setUsername:u,isTurnstileEnabled:k,turnstileRef:O,loading:w,turnstileStatus:D,onSubmit:M}),s===2&&(0,K.jsx)(oe,{password:d,setPassword:f,hasMfa:b||y,onSwitchToMfa:F,loading:w,onSubmit:N,keepLoggedIn:A,setKeepLoggedIn:j,optionalSessionExpirationDays:e?.optional_session_expiration_days??7}),s===3&&(0,K.jsx)(Y,{hasPasskey:b,requiresTotp:y,mfaMethod:x,setMfaMethod:S,passkeyLoading:C,onPasskeyLogin:I,totpToken:h,setTotpToken:g,recoveryKey:_,setRecoveryKey:v,loading:w,onClearError:()=>E(``),onSubmit:P,keepLoggedIn:A,setKeepLoggedIn:j,optionalSessionExpirationDays:e?.optional_session_expiration_days??7}),s===1&&(e?.has_users===!1||e?.registration_enabled!==!1)&&(0,K.jsx)(`div`,{className:`mt-8 pt-6 border-t border-gray-100 dark:border-gray-800 flex justify-center items-center text-sm`,children:(0,K.jsx)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer`,children:a(`auth.noAccount`)})})]})},Q=({username:e,setUsername:t,usernameFocused:n,setUsernameFocused:i,checkUsernameDuplicate:a,loading:o,onSubmit:s,onClearError:c})=>{let{t:l}=r();return(0,K.jsxs)(`form`,{onSubmit:s,className:`space-y-4`,children:[(0,K.jsx)(_,{label:l(`auth.username`),labelFor:`username`,children:(0,K.jsx)(y,{content:l(`auth.formatTipUsername`),isOpen:n,position:u.TOP,intent:m.PRIMARY,className:`w-full`,children:(0,K.jsx)(`div`,{className:`w-full block`,children:(0,K.jsx)(h,{id:`username`,leftIcon:`user`,placeholder:l(`auth.usernamePlaceholder`),size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>{t(e.target.value),c()},onFocus:()=>i(!0),onBlur:()=>{i(!1),a(e)},autoFocus:!0,required:!0})})})}),(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:o,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:l(`auth.next`,`Next`)})]})},se=({password:e,setPassword:t,passwordFocused:n,setPasswordFocused:i,loading:a,onSubmit:o,isTurnstileEnabled:s,turnstileRef:c,turnstileStatus:l})=>{let[d,p]=G.useState(!1),{t:g}=r();return(0,K.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,K.jsx)(_,{label:g(`auth.password`),labelFor:`password`,children:(0,K.jsx)(y,{content:g(`auth.formatTipPassword`),isOpen:n,position:u.TOP,intent:m.PRIMARY,className:`w-full`,children:(0,K.jsx)(`div`,{className:`w-full block`,children:(0,K.jsx)(h,{id:`password`,leftIcon:`lock`,placeholder:g(`auth.passwordPlaceholder`),type:d?`text`:`password`,size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>t(e.target.value),onFocus:()=>i(!0),onBlur:()=>i(!1),rightElement:(()=>(0,K.jsxs)(`div`,{className:`flex items-center`,children:[e&&(0,K.jsx)(f,{minimal:!0,icon:`cross`,onClick:()=>t(``)}),(0,K.jsx)(f,{minimal:!0,icon:d?`eye-open`:`eye-off`,onClick:()=>p(!d),title:d?g(`auth.hidePassword`,`Hide password`):g(`auth.showPassword`,`Show password`)})]}))(),required:!0,autoFocus:!0})})})}),s&&(0,K.jsx)(`div`,{className:`py-2 flex justify-center min-h-16.25`,children:(0,K.jsx)(`div`,{ref:c})}),(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:a||l===`verifying`,disabled:!!s&&l!==`success`,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:g(l===`verifying`?`auth.verifying`:`auth.signupBtn`)})]})},$=({mfaChoice:e,setMfaChoice:i,onRegisterPasskey:a,passkeyRegLoading:s,passkeyRegError:c,onStartTotp:l,totpSetupData:u,totpSetupToken:h,setTotpSetupToken:g,totpSetupError:y,totpSetupLoading:x,onTotpSubmit:S,onSkip:C})=>{let{t:w}=r();return e===`choose`?(0,K.jsxs)(`div`,{className:`space-y-4`,children:[c&&(0,K.jsx)(p,{intent:m.DANGER,className:`rounded-xl`,children:c}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(b,{elevation:d.ONE,className:`p-4 rounded-xl border border-blue-100 dark:border-blue-900/40 hover:border-blue-300 dark:hover:border-blue-700 transition-colors cursor-pointer`,onClick:s?void 0:a,children:[(0,K.jsx)(`div`,{className:`flex items-start justify-between`,children:(0,K.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,K.jsx)(`div`,{className:`p-2.5 bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 rounded-xl`,children:(0,K.jsx)(t,{size:24})}),(0,K.jsxs)(`div`,{children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`h4`,{className:`text-sm font-bold text-gray-800 dark:text-gray-100 m-0`,children:w(`account.passkey.title`,`通行密钥 (Passkey)`)}),(0,K.jsx)(v,{intent:m.PRIMARY,minimal:!0,round:!0,children:w(`auth.mfaRecommended`,`推荐 · 无密码`)})]}),(0,K.jsx)(`div`,{className:`text-xs text-blue-600 dark:text-blue-400 font-mono mt-0.5`,children:window.location.hostname}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mt-1 mb-0 leading-relaxed`,children:w(`auth.passkeySignupDesc`,`使用本设备生物识别 (Touch ID / Face ID / Windows Hello) 或硬件密钥 (YubiKey),一键快捷且防钓鱼。`)})]})]})}),(0,K.jsx)(`div`,{className:`mt-3 text-right`,children:(0,K.jsx)(f,{intent:m.PRIMARY,loading:s,text:w(`auth.bindPasskeyNow`,`绑定通行密钥`),className:`rounded-lg font-medium`})})]}),(0,K.jsxs)(b,{elevation:d.ONE,className:`p-4 rounded-xl border border-gray-100 dark:border-gray-800 hover:border-gray-300 dark:hover:border-gray-700 transition-colors cursor-pointer`,onClick:l,children:[(0,K.jsx)(`div`,{className:`flex items-start justify-between`,children:(0,K.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,K.jsx)(`div`,{className:`p-2.5 bg-purple-50 dark:bg-purple-950/40 text-purple-600 dark:text-purple-400 rounded-xl`,children:(0,K.jsx)(n,{size:24})}),(0,K.jsxs)(`div`,{children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`h4`,{className:`text-sm font-bold text-gray-800 dark:text-gray-100 m-0`,children:w(`auth.mfaMethodTotp`,`数字验证器 (TOTP)`)}),(0,K.jsx)(v,{intent:m.NONE,minimal:!0,round:!0,children:w(`auth.mfaUniversal`,`通用应用`)})]}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mt-1 mb-0 leading-relaxed`,children:w(`account.totp.setupDesc`,`使用 Google Authenticator、1Password 等验证器应用扫码绑定 6 位动态验证码。`)})]})]})}),(0,K.jsx)(`div`,{className:`mt-3 text-right`,children:(0,K.jsx)(f,{minimal:!0,text:w(`auth.setupTotpBtn`,`扫码配置验证器`),className:`rounded-lg font-medium text-gray-700 dark:text-gray-200`})})]})]}),(0,K.jsx)(`div`,{className:`text-center pt-2`,children:(0,K.jsx)(f,{minimal:!0,text:w(`auth.skipMfaSetup`,`跳过多因素认证配置,直接进入系统`),onClick:C,className:`text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200`})})]}):(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(`div`,{className:`flex items-center justify-between`,children:(0,K.jsxs)(`button`,{type:`button`,onClick:()=>i(`choose`),className:`text-xs text-blue-600 hover:underline flex items-center gap-1 bg-transparent border-none cursor-pointer p-0`,children:[(0,K.jsx)(o,{size:14}),(0,K.jsx)(`span`,{children:w(`auth.backToMfaOptions`,`选择其他认证方式`)})]})}),u&&(0,K.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,K.jsx)(W,{uri:u.uri}),(0,K.jsxs)(`div`,{className:`text-center`,children:[(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mb-1`,children:w(`account.totp.orEnterManually`,`Or enter the key manually:`)}),(0,K.jsx)(`code`,{className:`text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded select-all`,children:u.secret})]})]}),y&&(0,K.jsx)(p,{intent:m.DANGER,className:`rounded-xl`,children:y}),(0,K.jsxs)(`form`,{onSubmit:S,className:`space-y-4`,children:[(0,K.jsx)(_,{label:w(`account.totp.enterCode`,`Enter the 6-digit code:`),helperText:w(`account.totp.enterCodeHint`,`Enter the 6-digit code to confirm.`),children:(0,K.jsx)(R,{length:6,value:h,onChange:g,disabled:x,autoFocus:!0})}),(0,K.jsx)(f,{fill:!0,size:`large`,intent:m.PRIMARY,type:`submit`,loading:x,disabled:h.length!==6,className:`rounded-xl font-bold py-3`,children:w(`account.totp.activate`,`Activate`)})]})]})},ce=({totpRecoveryKeys:e,copiedRecovery:t,onCopy:n,onSuccess:a})=>{let{t:o}=r();return G.useEffect(()=>{let e=e=>{e.key===`Enter`&&a()};return window.addEventListener(`keydown`,e),()=>{window.removeEventListener(`keydown`,e)}},[a]),(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.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,K.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,K.jsxs)(`div`,{className:`flex gap-2`,children:[(0,K.jsx)(f,{fill:!0,icon:(0,K.jsx)(i,{size:14}),text:t?o(`account.totp.copied`,`Copied!`):o(`account.totp.copyKeys`,`Copy All Keys`),intent:t?m.SUCCESS:m.NONE,onClick:n}),(0,K.jsx)(f,{fill:!0,intent:m.PRIMARY,text:o(`account.totp.done`,`Done`),onClick:a})]})]})},le=({authConfig:e,turnstileReady:t,onSuccess:n})=>{let[i,a]=(0,G.useState)(`username`),[o,s]=(0,G.useState)(``),[c,l]=(0,G.useState)(``),[u,d]=(0,G.useState)(``),[f,p]=(0,G.useState)(null),[m,h]=(0,G.useState)(null),[g,_]=(0,G.useState)(!1),[v,y]=(0,G.useState)(``),[b,x]=(0,G.useState)(!1),[w,E]=(0,G.useState)(!1),[k,A]=(0,G.useState)(!1),[j,P]=(0,G.useState)(!1),[ee,L]=(0,G.useState)(``),[R,z]=(0,G.useState)(`choose`),[H,U]=(0,G.useState)(!1),[ae,W]=(0,G.useState)(``),[K,q]=(0,G.useState)(null),[oe,J]=(0,G.useState)(`idle`),Y=(0,G.useRef)(null),X=(0,G.useRef)(null),{t:Z}=r(),Q=e?.turnstile_enabled_signup;(0,G.useEffect)(()=>{if(i===`password`&&Q&&e?.turnstile_site_key&&(t||window.turnstile)&&Y.current)try{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null),J(`verifying`),Y.current.innerHTML=``,X.current=window.turnstile.render(Y.current,{sitekey:e.turnstile_site_key,callback:e=>{q(e),J(`success`),y(``)},"expired-callback":()=>{q(null),J(`idle`)},"error-callback":e=>{console.error(`Turnstile error:`,e),J(`error`),y(Z(`auth.turnstileError`,`Verification service failed to load. Please reload and try again.`)),q(null)}})}catch(e){console.error(`Turnstile render error:`,e),J(`error`)}return()=>{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null)}},[Q,e,i,t,Z]);let se=async e=>{if(!(!e||!M(e)))try{await S(e)?y(Z(`auth.usernameExists`)):y(e=>e===Z(`auth.usernameExists`)?``:e)}catch(e){console.error(`Failed to check username duplicate`,e)}},$=async e=>{if(e.preventDefault(),!M(o)){y(Z(`auth.formatTipUsername`));return}_(!0),y(``);try{await S(o)?y(Z(`auth.usernameExists`)):a(`password`)}catch{y(Z(`auth.networkError`))}finally{_(!1)}},ce=async()=>{P(!0),L(``);try{p(await O()),a(`totp`)}catch(e){console.error(`Network error during signup TOTP setup:`,e),n()}finally{P(!1)}};return{signupStep:i,setSignupStep:a,username:o,setUsername:s,password:c,setPassword:l,mfaChoice:R,setMfaChoice:z,passkeyRegLoading:H,passkeyRegError:ae,handleRegisterPasskey:async()=>{U(!0),W(``);try{let e=await D({name:`primary_passkey`,credential:await ie(await C())});e.recovery_keys&&e.recovery_keys.length>0?(h(e.recovery_keys),a(`recovery`)):n()}catch(e){console.error(`Passkey registration failed:`,e),W(B(e,Z))}finally{U(!1)}},handleChooseTotp:async()=>{z(`totp`),await ce()},totpSetupToken:u,setTotpSetupToken:d,totpSetupData:f,setTotpSetupData:p,totpRecoveryKeys:m,setTotpRecoveryKeys:h,loading:g,error:v,setError:y,usernameFocused:b,setUsernameFocused:x,passwordFocused:w,setPasswordFocused:E,copiedRecovery:k,totpSetupLoading:j,totpSetupError:ee,turnstileStatus:oe,turnstileRef:Y,isTurnstileEnabled:Q,checkUsernameDuplicate:se,handleSignupUsernameSubmit:$,handleSignupTotpConfirm:async e=>{if(e.preventDefault(),f){P(!0),L(``);try{let e=u.replace(/\s/g,``),t=crypto.randomUUID(),n=await te(e,t);h((await F({secret:f.secret,totpTokenHash:n,salt:t})).recovery_keys),a(`recovery`)}catch(e){L(e.message||Z(`common.errorNetwork`))}finally{P(!1)}}},handleCopySignupRecoveryKeys:()=>{m&&navigator.clipboard.writeText(m.join(`
|
|
2
|
-
`)).then(()=>{A(!0),setTimeout(()=>A(!1),2e3)})},handleSignupSubmit:async t=>{if(t.preventDefault(),!M(o)){y(Z(`auth.formatTipUsername`));return}if(!V(c)){y(Z(`auth.formatTipPassword`));return}if(Q&&e?.turnstile_site_key&&!K){y(Z(`auth.turnstileRequired`));return}_(!0),y(``);try{let e=await T({username:o,password:await N(c,o),turnstileToken:K});e.accessToken&&ne(e.accessToken),z(`choose`),a(`totp`)}catch(e){e instanceof re&&I({status:e.status},e.bodyText)?y(Z(`auth.passwordLeaked`)):y(B(e,Z)),window.turnstile&&window.turnstile.reset(),q(null)}finally{_(!1)}}}},ue=({authConfig:e,turnstileReady:t,onSuccess:n,onToggleMode:i})=>{let{t:a}=r(),{signupStep:s,setSignupStep:c,username:u,setUsername:d,password:f,setPassword:h,mfaChoice:g,setMfaChoice:_,passkeyRegLoading:v,passkeyRegError:y,handleRegisterPasskey:b,handleChooseTotp:x,totpSetupToken:S,setTotpSetupToken:C,totpSetupData:w,totpRecoveryKeys:T,loading:E,error:D,setError:O,usernameFocused:k,setUsernameFocused:A,passwordFocused:j,setPasswordFocused:M,copiedRecovery:N,totpSetupLoading:P,totpSetupError:F,turnstileStatus:I,turnstileRef:ee,isTurnstileEnabled:L,checkUsernameDuplicate:R,handleSignupUsernameSubmit:te,handleSignupTotpConfirm:ne,handleCopySignupRecoveryKeys:z,handleSignupSubmit:B}=le({authConfig:e,turnstileReady:t,onSuccess:n});return e&&e.has_users!==!1&&e.registration_enabled===!1?(0,K.jsxs)(`div`,{className:`space-y-6 text-center`,children:[(0,K.jsxs)(`div`,{className:`flex flex-col items-center`,children:[(0,K.jsx)(`img`,{src:H,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,K.jsx)(l,{className:`font-bold tracking-tight text-2xl mt-4`,children:a(`auth.signup`)})]}),(0,K.jsx)(p,{intent:m.WARNING,icon:`lock`,title:a(`auth.registrationDisabledTitle`,`注册已停用`),children:a(`auth.registrationDisabledDesc`,`当前系统已暂停开放新用户注册,请联系系统管理员分配账号。`)}),(0,K.jsx)(`div`,{className:`pt-4 border-t border-gray-100 dark:border-gray-800 flex justify-center items-center text-sm`,children:(0,K.jsxs)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer flex items-center gap-1`,children:[(0,K.jsx)(o,{size:16}),a(`auth.backToLogin`,`返回登录`)]})})]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`flex flex-col items-center mb-8 relative`,children:[s===`password`&&(0,K.jsx)(`button`,{onClick:()=>{c(`username`),O(``)},className:`absolute left-0 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 bg-transparent border-none cursor-pointer`,title:`Back to username`,children:(0,K.jsx)(o,{size:24})}),(0,K.jsx)(`img`,{src:H,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,K.jsx)(l,{className:`font-bold tracking-tight text-2xl mt-4`,children:s===`username`||s===`password`?e?.has_users===!1?a(`auth.registerAdminTitle`,`注册管理员账号`):a(`auth.signup`):s===`totp`?a(`auth.mfaSetupTitle`,`配置多因素认证 (MFA)`):a(`account.totp.recoveryKeysTitle`,`Save Recovery Keys`)}),(0,K.jsx)(`p`,{className:`text-gray-500 mt-2 text-center text-sm leading-relaxed`,children:s===`username`||s===`password`?s===`password`?u:e?.has_users===!1?a(`auth.registerAdminDesc`,`系统尚无账号,首位注册用户将自动成为系统管理员。`):a(`auth.protectInternet`):s===`totp`?a(`auth.mfaSetupDesc`,`任选一种认证方式即可完成配置,保障账号安全。`):a(`account.totp.recoveryKeysWarning`,`Store keys safely.`)})]}),D&&(0,K.jsx)(p,{intent:m.DANGER,className:`mb-6 rounded-xl`,title:a(`auth.error`),children:D}),s===`username`&&(0,K.jsx)(Q,{username:u,setUsername:d,usernameFocused:k,setUsernameFocused:A,checkUsernameDuplicate:R,loading:E,onSubmit:te,onClearError:()=>O(e=>e===a(`auth.usernameExists`)?``:e)}),s===`password`&&(0,K.jsx)(se,{password:f,setPassword:h,passwordFocused:j,setPasswordFocused:M,loading:E,onSubmit:B,isTurnstileEnabled:L,turnstileRef:ee,turnstileStatus:I}),s===`totp`&&(0,K.jsx)($,{mfaChoice:g,setMfaChoice:_,onRegisterPasskey:b,passkeyRegLoading:v,passkeyRegError:y,onStartTotp:x,totpSetupData:w,totpSetupToken:S,setTotpSetupToken:C,totpSetupError:F,totpSetupLoading:P,onTotpSubmit:ne,onSkip:n}),s===`recovery`&&T&&(0,K.jsx)(ce,{totpRecoveryKeys:T,copiedRecovery:N,onCopy:z,onSuccess:n}),s===`username`&&(0,K.jsx)(`div`,{className:`mt-8 pt-6 border-t border-gray-100 dark:border-gray-800 text-center`,children:(0,K.jsx)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer text-sm`,children:a(`auth.haveAccount`)})})]})},de=({onSuccess:e})=>{let[t,n]=(0,G.useState)(!0),[i,a]=(0,G.useState)(!0),[o,s]=(0,G.useState)(!1),{t:c}=r(),l=()=>{s(!0),setTimeout(()=>{n(e=>!e),s(!1)},300)},[u,p]=(0,G.useState)(null),[m,h]=(0,G.useState)(!1);(0,G.useEffect)(()=>{(async()=>{try{let e=await A();p(e),e&&e.has_users===!1&&n(!1)}catch(e){console.error(`Failed to load auth config`,e)}})()},[]);let g=t?u?.turnstile_enabled_login:u?.turnstile_enabled_signup;return(0,G.useEffect)(()=>{g&&u?.turnstile_site_key&&P(()=>{h(!0)})},[g,u]),(0,K.jsxs)(`div`,{className:`flex flex-row min-h-screen bg-white dark:bg-gray-950 overflow-hidden relative`,children:[(0,K.jsx)(`div`,{className:`hidden lg:block w-1/2 h-screen overflow-hidden border-r border-gray-100 dark:border-gray-900`,children:(0,K.jsx)(z,{})}),(0,K.jsx)(`div`,{className:`lg:hidden absolute inset-0 z-0 transition-opacity duration-500 cursor-pointer ${i?`opacity-25`:`opacity-70`}`,onClick:()=>a(!0),children:(0,K.jsx)(z,{})}),!i&&(0,K.jsx)(`div`,{className:`lg:hidden fixed bottom-12 left-1/2 -translate-x-1/2 z-50 animate-bounce`,children:(0,K.jsx)(f,{large:!0,intent:`primary`,icon:`log-in`,text:c(`auth.loginBtn`),onClick:()=>a(!0),className:`shadow-2xl px-8 py-4 rounded-full`})}),(0,K.jsxs)(`div`,{className:`flex-1 flex items-center justify-center p-4 relative z-10 bg-gray-50/50 dark:bg-gray-900/30 lg:bg-gray-50 lg:dark:bg-gray-900/50 transition-all duration-500 ease-in-out ${i?`translate-x-0 opacity-100`:`max-lg:translate-x-full max-lg:opacity-0 max-lg:pointer-events-none`}`,onClick:e=>{window.innerWidth<1024&&e.target===e.currentTarget&&a(!1)},children:[(0,K.jsx)(`div`,{className:`absolute top-4 right-4 z-50`,children:(0,K.jsx)(k,{})}),(0,K.jsx)(`div`,{className:x(`w-full max-w-md transition-all duration-200 ease-in-out transform-gpu`,o?`blur-lg opacity-20 scale-95`:`blur-0 opacity-100 scale-100`),children:(0,K.jsx)(b,{elevation:d.FOUR,className:`w-full p-8 rounded-2xl shadow-none! z-10 dark:bg-gray-900 border border-gray-100 dark:border-gray-800`,onClick:e=>e.stopPropagation(),children:t?(0,K.jsx)(Z,{authConfig:u,turnstileReady:m,onSuccess:e,onToggleMode:l}):(0,K.jsx)(ue,{authConfig:u,turnstileReady:m,onSuccess:e,onToggleMode:l})})})]})]})};export{de as AuthView};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{L as t,Xt as n,_ as r,a as i,c as a,g as o,i as s,l as c,o as l,r as u,s as d,y as f}from"./vendor-react-DifRgRH3.js";import{S as p,b as m}from"./vendor-icons-other-Bme3ywH9.js";import{$ as h,M as g}from"./index-DLmOvLdX.js";import{n as _,t as v}from"./formatCountryName-CSBD8pP8.js";import{t as y}from"./getFlagEmoji-_Wxhq0lT.js";var b=e(p(),1);function x(e){let[t,n]=(0,b.useState)(null);(0,b.useEffect)(()=>{g().then(e=>{if(e&&e.objects){let t={};e.objects.countries&&(t.countries=e.objects.countries),e.objects.land&&(t.land=e.objects.land),e.objects=t}e&&e.objects&&e.objects.countries&&Array.isArray(e.objects.countries.geometries)&&e.objects.countries.geometries.forEach(e=>{e.id!==void 0&&e.id!==null&&(e.id=String(e.id).padStart(3,`0`))}),n(e)}).catch(e=>console.error(`Failed to load map topology`,e))},[]);let r=(0,b.useMemo)(()=>e.reduce((e,t)=>e+t.count,0),[e]),i=(0,b.useMemo)(()=>{if(r<=0)return{maxThreshold:10,step:1};if(r<=1e3)return{maxThreshold:100,step:10};let e=10**Math.floor(Math.log10(r));return{maxThreshold:e,step:e/10}},[r]);return{geographyData:t,destinationMap:(0,b.useMemo)(()=>{let t={};return e.forEach(e=>{if(e.country_code){let n=e.country_code.toUpperCase();t[n]={count:e.count,name:e.country,countryCode:n}}}),t},[e]),scaleConfig:i,getLevel:e=>!e||e<=0?0:Math.min(10,Math.floor(e/i.step)+1),formatNumber:e=>{if(e>=1e6){let t=e/1e6;return Number.isInteger(t)?`${t}M`:`${t.toFixed(1)}M`}if(e>=1e3){let t=e/1e3;return Number.isInteger(t)?`${t}K`:`${t.toFixed(1)}K`}return e.toString()}}}var S=e(m(),1);const C=({onZoomIn:e,onZoomOut:n,onReset:i})=>(0,S.jsxs)(`div`,{className:`absolute top-3 right-3 flex flex-col gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-1.5 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10`,children:[(0,S.jsx)(`button`,{type:`button`,onClick:e,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom In`,children:(0,S.jsx)(r,{size:16})}),(0,S.jsx)(`button`,{type:`button`,onClick:n,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom Out`,children:(0,S.jsx)(o,{size:16})}),(0,S.jsx)(`button`,{type:`button`,onClick:i,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Reset Zoom`,children:(0,S.jsx)(t,{size:16})})]}),w=({maxThreshold:e,formatNumber:t})=>{let{t:r}=n();return(0,S.jsxs)(`div`,{className:`sm:absolute sm:bottom-3 sm:left-3 relative m-3 sm:m-0 flex flex-col shrink-0 gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-2 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10 max-w-70`,children:[(0,S.jsx)(`span`,{className:`text-[9px] font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider`,children:r(`analytics.queries`)}),(0,S.jsx)(`div`,{className:`flex items-center gap-0.5`,children:Array.from({length:11}).map((e,t)=>(0,S.jsx)(`div`,{className:`w-4 h-2.5 rounded-sm border border-black/5 dark:border-white/5`,style:{backgroundColor:`var(--map-color-${t})`}},t))}),(0,S.jsxs)(`div`,{className:`flex justify-between text-[9px] text-gray-500 dark:text-gray-400 font-semibold px-0.5`,children:[(0,S.jsx)(`span`,{children:`0`}),(0,S.jsx)(`span`,{children:t(e/2)}),(0,S.jsxs)(`span`,{children:[t(e),`+`]})]})]})},T=({name:e,count:t,flag:r,x:i,y:a,countryCode:o,profileId:s,range:c,customRange:l,accessPointId:u,ispCache:d,onCacheIsp:p,isPinned:m,onClose:g})=>{let{t:_}=n(),v=(0,b.useRef)(null),[y,x]=(0,b.useState)({left:i,top:a-10,alignBottom:!1}),[C,w]=(0,b.useState)([]),[T,E]=(0,b.useState)(!1),D=(0,b.useRef)(d);D.current=d;let O=(0,b.useRef)(p);return O.current=p,(0,b.useEffect)(()=>{if(!o||!s)return;if(t<=0){w([]),E(!1);return}let e=D.current[o];if(e){w(e),E(!1);return}E(!0);let n=`?country_code=${o}&range=${c}`;if(c===`custom`&&l.start&&l.end){let e=Math.floor(new Date(l.start).getTime()/1e3),t=Math.floor(new Date(l.end).getTime()/1e3);n+=`&start=${e}&end=${t}`}u&&(n+=`&access_point_id=${u}`);let r=!0,i=setTimeout(()=>{h(s,`isps`,n).then(e=>{O.current(o,e),r&&w(e)}).catch(e=>{console.error(`Failed to fetch ISPs`,e)}).finally(()=>{r&&E(!1)})},200);return()=>{r=!1,clearTimeout(i)}},[o,s,c,l,u,t]),(0,b.useEffect)(()=>{if(!m)return;let e=e=>{if(v.current&&!v.current.contains(e.target)){let t=e.target,n=t.classList.contains(`rsm-geography`)||t.closest(`.rsm-geography`),r=t.classList.contains(`map-marker-circle`)||t.closest(`.map-marker-circle`);!n&&!r&&g()}},t=setTimeout(()=>{document.addEventListener(`click`,e,!0)},0);return()=>{clearTimeout(t),document.removeEventListener(`click`,e,!0)}},[m,g]),(0,b.useLayoutEffect)(()=>{if(!v.current)return;let e=v.current.getBoundingClientRect(),t=v.current.parentElement;if(!t)return;let n=t.getBoundingClientRect(),r=i,o=e.width/2;i-o<4?r=o+4:i+o>n.width-4&&(r=n.width-o-4);let s=a-10,c=!1;a-e.height-15<4&&(s=a+15,c=!0),x({left:r,top:s,alignBottom:c})},[i,a,C]),(0,S.jsxs)(`div`,{ref:v,onMouseLeave:m?g:void 0,className:`absolute bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm px-3 py-2 rounded-lg shadow-xl border border-gray-200/50 dark:border-slate-800/50 text-xs z-50 flex flex-col gap-1 transition-all duration-75 text-gray-900 dark:text-gray-100 ${m?`pointer-events-auto cursor-default`:`pointer-events-none`}`,style:{left:`${y.left}px`,top:`${y.top}px`,transform:y.alignBottom?`translate(-50%, 0)`:`translate(-50%, -100%)`},children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,S.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-1.5 font-semibold whitespace-nowrap`,children:[(0,S.jsx)(`span`,{className:`text-sm`,children:r}),(0,S.jsx)(`span`,{children:e})]}),(0,S.jsxs)(`div`,{className:`text-gray-500 dark:text-gray-400 whitespace-nowrap`,children:[t.toLocaleString(),` `,_(`analytics.queries`)]})]}),m&&(0,S.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g()},className:`flex items-center justify-center p-2 rounded-lg border border-gray-200 dark:border-slate-800 text-gray-500 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20 hover:border-red-200 dark:hover:border-red-900/50 transition-colors cursor-pointer self-stretch aspect-square`,title:_(`common.close`,`Close`),children:(0,S.jsx)(f,{size:18})})]}),T?(0,S.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-850 flex flex-col gap-1 min-w-36`,children:[(0,S.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:_(`analytics.topIsps`,`Top ISPs`)}),(0,S.jsx)(`div`,{className:`text-[11px] text-gray-400 dark:text-gray-500 italic`,children:_(`analytics.loading`,`Loading...`)})]}):C.length>0&&(0,S.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-800 flex flex-col gap-1`,children:[(0,S.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:_(`analytics.topIsps`,`Top ISPs`)}),(0,S.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-36 max-w-48 ${m?`max-h-36 overflow-y-auto pr-1`:``}`,children:[(m?C:C.slice(0,5)).map(e=>(0,S.jsxs)(`div`,{className:`flex justify-between gap-3 text-[11px] text-gray-600 dark:text-gray-300`,children:[(0,S.jsx)(`span`,{className:`truncate`,title:e.name,children:e.name}),(0,S.jsx)(`span`,{className:`font-mono text-gray-400 dark:text-gray-500`,children:e.count.toLocaleString()})]},e.name)),!m&&C.length>5&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`text-center text-gray-400 dark:text-gray-500 leading-none py-0.5 font-bold`,children:`...`}),(0,S.jsx)(`div`,{className:`text-[10px] text-center text-blue-500 dark:text-blue-400 font-medium whitespace-nowrap mt-0.5`,children:_(`analytics.pressToShowMore`,`Click to show more`)})]})]})]})]})},E=({geographyData:e,destinationMap:t,getLevel:r,containerRef:i,hoveredCountry:o,setHoveredCountry:s})=>{let{i18n:c}=n();return e?(0,S.jsx)(a,{geography:e,children:({geographies:e})=>e.map(e=>{let n=_[e.id],a=n?t[n]:null,l=a?.count||0,u=r(l);return(0,S.jsx)(d,{geography:e,onMouseEnter:e=>{if(!n||o?.isPinned)return;let t=v(n,c.language)||a?.name||n,r=y(n),u=i.current?.getBoundingClientRect();s({name:t,code:n,count:l,flag:r,x:e.clientX-(u?.left||0),y:e.clientY-(u?.top||0)-15})},onMouseMove:e=>{s(t=>{if(t?.isPinned)return t;let n=i.current?.getBoundingClientRect(),r=e.clientX-(n?.left||0),a=e.clientY-(n?.top||0)-15;return t?{...t,x:r,y:a}:null})},onMouseLeave:()=>{s(e=>e?.isPinned?e:null)},onClick:e=>{if(e.stopPropagation(),!n)return;let t=v(n,c.language)||a?.name||n,r=y(n),o=i.current?.getBoundingClientRect(),u=e.clientX-(o?.left||0),d=e.clientY-(o?.top||0)-15;s(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:l,flag:r,x:u,y:d,isPinned:!0})},style:{default:{fill:`var(--map-color-${u})`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,transition:`fill 250ms, stroke 250ms`},hover:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,cursor:`pointer`},pressed:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`}}},e.rsmKey)})}):null},D={SG:{name:`Singapore`,coordinates:[103.8198,1.3521]},HK:{name:`Hong Kong`,coordinates:[114.1694,22.3193]},MO:{name:`Macau`,coordinates:[113.5439,22.1987]},VA:{name:`Vatican City`,coordinates:[12.4534,41.9029]},MC:{name:`Monaco`,coordinates:[7.4246,43.7384]},SM:{name:`San Marino`,coordinates:[12.4578,43.9424]},LI:{name:`Liechtenstein`,coordinates:[9.5209,47.141]},AD:{name:`Andorra`,coordinates:[1.5218,42.5063]},MT:{name:`Malta`,coordinates:[14.3754,35.9375]},GI:{name:`Gibraltar`,coordinates:[-5.3536,36.1408]},BM:{name:`Bermuda`,coordinates:[-64.7505,32.3078]},MV:{name:`Maldives`,coordinates:[73.5089,4.1755]},MU:{name:`Mauritius`,coordinates:[57.5522,-20.3484]}},O=({destinationMap:e,getLevel:t,containerRef:r,hoveredCountry:i,setHoveredCountry:a})=>{let{i18n:o}=n();return(0,S.jsx)(S.Fragment,{children:Object.entries(D).map(([n,s])=>{let u=e[n],d=u?.count||0,f=t(d),p=d>0,m=p?4:1.5;return(0,S.jsx)(c,{coordinates:l(s.coordinates[0],s.coordinates[1]),onMouseEnter:e=>{if(i?.isPinned)return;let t=v(n,o.language)||u?.name||n,s=y(n),c=r.current?.getBoundingClientRect();a({name:t,code:n,count:d,flag:s,x:e.clientX-(c?.left||0),y:e.clientY-(c?.top||0)-15})},onMouseMove:e=>{a(t=>{if(t?.isPinned)return t;let n=r.current?.getBoundingClientRect(),i=e.clientX-(n?.left||0),a=e.clientY-(n?.top||0)-15;return t?{...t,x:i,y:a}:null})},onMouseLeave:()=>{a(e=>e?.isPinned?e:null)},onClick:e=>{e.stopPropagation();let t=v(n,o.language)||u?.name||n,i=y(n),s=r.current?.getBoundingClientRect(),c=e.clientX-(s?.left||0),l=e.clientY-(s?.top||0)-15;a(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:d,flag:i,x:c,y:l,isPinned:!0})},children:p?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`circle`,{r:m+3,fill:`var(--map-color-${f})`,opacity:.4,className:`animate-ping map-marker-circle`}),(0,S.jsx)(`circle`,{r:m,fill:`var(--map-color-${f})`,stroke:`var(--map-stroke)`,strokeWidth:.75,style:{cursor:`pointer`},className:`map-marker-circle`})]}):(0,S.jsx)(`circle`,{r:m,fill:`var(--text-color)`,opacity:.25,style:{pointerEvents:`none`}})},n)})})},k=({destinations:e,profileId:t,range:n,customRange:r,accessPointId:a})=>{let{geographyData:o,destinationMap:c,scaleConfig:d,getLevel:f,formatNumber:p}=x(e),[m,h]=(0,b.useState)({coordinates:l(0,0),zoom:1.2}),[g,_]=(0,b.useState)(null),[v,y]=(0,b.useState)(null),[D,k]=(0,b.useState)({}),A=(0,b.useRef)(null);A.current=g,(0,b.useEffect)(()=>{if(!g){y(null);return}if(g.isPinned){y(g);return}if(v&&v.code===g.code)return;let e=setTimeout(()=>{A.current&&A.current.code===g.code&&y(A.current)},100);return()=>clearTimeout(e)},[g?.code,g?.isPinned,v?.code]),(0,b.useEffect)(()=>{g&&v&&g.code===v.code&&(g.x!==v.x||g.y!==v.y||g.isPinned!==v.isPinned)&&y(g)},[g?.x,g?.y,g?.isPinned,v]);let j=(0,b.useRef)(null);b.useEffect(()=>{k({})},[t,n,r,a]);let M=b.useCallback((e,t)=>{k(n=>({...n,[e]:t}))},[]),N=b.useMemo(()=>u(l(-100,-50),l(900,600)),[]);return(0,S.jsxs)(`div`,{className:`relative w-full min-h-85 max-h-120 aspect-800/566 bg-gray-50 dark:bg-slate-950 rounded-xl overflow-hidden border border-gray-100 dark:border-slate-800 flex flex-col justify-between shadow-sm`,children:[(0,S.jsxs)(`div`,{ref:j,className:`relative w-full flex-1 min-h-0 overflow-hidden select-none cursor-grab active:cursor-grabbing`,onClick:e=>{(e.target===e.currentTarget||e.target.tagName===`svg`)&&_(null)},children:[(0,S.jsx)(s,{projection:`geoEqualEarth`,width:800,height:566,style:{width:`100%`,height:`100%`},children:(0,S.jsxs)(i,{zoom:m.zoom,center:m.coordinates,onMoveEnd:e=>h({coordinates:l(e.coordinates[0],e.coordinates[1]),zoom:e.zoom}),maxZoom:8,minZoom:1,enablePan:!0,translateExtent:N,children:[(0,S.jsx)(E,{geographyData:o,destinationMap:c,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_}),(0,S.jsx)(O,{destinationMap:c,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_})]})}),v&&(0,S.jsx)(T,{name:v.name,count:v.count,flag:v.flag,x:v.x,y:v.y,countryCode:v.code,profileId:t,range:n,customRange:r,accessPointId:a,ispCache:D,onCacheIsp:M,isPinned:v.isPinned||!1,onClose:()=>_(null)})]}),(0,S.jsx)(C,{onZoomIn:()=>{m.zoom>=8||h(e=>({...e,zoom:e.zoom*1.5}))},onZoomOut:()=>{m.zoom<=1||h(e=>({...e,zoom:e.zoom/1.5}))},onReset:()=>{h({coordinates:l(0,0),zoom:1.2})}}),(0,S.jsx)(w,{maxThreshold:d.maxThreshold,formatNumber:p})]})};export{k as DestinationMap};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{At as t,C as n,F as r,R as i,Xt as a,at as o,ct as s,k as c}from"./vendor-react-DifRgRH3.js";import{S as l,b as u}from"./vendor-icons-other-Bme3ywH9.js";import{C as d,E as f,H as p,N as m,O as h,S as g,T as _,V as v,f as y,h as b,r as x,u as S,w as C,x as w}from"./vendor-ui-core-CCxBtqRD.js";import{_t as T}from"./vendor-utils-D17P9mkD.js";import{B as E,C as D,G as O,P as k,U as A,Xt as j,dt as M,lt as N,q as P,tt as F}from"./index-DLmOvLdX.js";var I=e(l(),1);const L=()=>{let{t:e}=a(),[t,n]=(0,I.useState)([]);return(0,I.useEffect)(()=>{k().then(t=>{t&&Array.isArray(t)&&n(t.map(t=>({label:e(t.label),url:t.url})))}).catch(e=>console.warn(`Failed to fetch preset filters from API`,e))},[e]),t};var R=e(u(),1);const z=({newUrl:e,setNewUrl:t,onAddList:n,syncing:r,loading:i,lists:o})=>{let{t:s}=a(),c=(0,R.jsx)(f,{className:`min-w-96`,children:L().map((e,t)=>(0,R.jsx)(C,{text:e.label,onClick:()=>n(e.url),disabled:o.some(t=>t.url===e.url),labelElement:(0,R.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,R.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-xl truncate`,title:e.url,children:e.url})})},t))});return(0,R.jsx)(w,{elevation:p.ONE,className:`mb-6`,children:(0,R.jsxs)(`div`,{className:`flex gap-2 flex-col sm:flex-row`,children:[(0,R.jsx)(y,{fill:!0,size:`large`,placeholder:s(`filtering.urlPlaceholder`),value:e,onChange:e=>t(e.target.value),leftIcon:`globe`,rightElement:(0,R.jsx)(_,{content:c,placement:`bottom-end`,animation:`minimal`,arrow:!1,usePortal:!0,children:(0,R.jsx)(m,{variant:`minimal`,icon:`chevron-down`})})}),(0,R.jsx)(m,{intent:v.PRIMARY,size:`large`,icon:`plus`,onClick:()=>n(),className:`shrink-0`,loading:r||i,disabled:r||i,children:s(`filtering.addSubscription`)})]})})},B=({lists:e,onSelect:t})=>{let{t:n}=a(),r=[{key:`url`,header:n(`filtering.tableUrl`),cellClassName:`font-mono text-sm max-w-md truncate`,render:e=>e.url},{key:`lastSync`,header:n(`filtering.tableLastSync`),cellClassName:`text-xs opacity-60`,render:e=>e.last_synced_at?D(new Date(e.last_synced_at*1e3)):n(`filtering.neverSynced`)},{key:`status`,header:n(`filtering.tableStatus`),render:e=>{if(!e.enabled)return(0,R.jsx)(x,{intent:v.NONE,minimal:!0,children:n(`filtering.statusDisabled`,`Disabled`)});let t=!!e.sync_error,r=!!e.last_synced_at,i=n(`filtering.statusNormal`,`Active`),a=v.SUCCESS;return t&&(r?(i=n(`filtering.statusOutdated`,`Outdated`),a=v.WARNING):(i=n(`filtering.statusMissing`,`Missing`),a=v.DANGER)),(0,R.jsx)(x,{intent:a,minimal:!0,children:i})}}];return(0,R.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,R.jsxs)(S,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,R.jsx)(`thead`,{children:(0,R.jsx)(`tr`,{children:r.map(e=>(0,R.jsx)(`th`,{className:e.headerClassName,children:e.header},e.key))})}),(0,R.jsx)(`tbody`,{children:e.map(e=>(0,R.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:r.map(t=>(0,R.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},V=({profileId:e,selectedList:t,onClose:i,onCopy:l,onDelete:u,onToggleEnabled:d,onAllowDomain:f})=>{let{t:p}=a(),[_,S]=(0,I.useState)(``),[C,w]=(0,I.useState)(!1),[T,E]=(0,I.useState)(null),[k,A]=(0,I.useState)(null),[j,M]=(0,I.useState)(!1),[N,P]=(0,I.useState)(!1),[F,L]=(0,I.useState)(!1),z=(0,I.useRef)(0),B=()=>{z.current++,w(!1),S(``),E(null),A(null),P(!1)},V=async()=>{let n=_.trim().toLowerCase();if(!n||!t||(n=n.replace(/^https?:\/\//,``).split(`/`)[0].split(`:`)[0].replace(/\.+$/,``),!n))return;S(n);let r=++z.current,i=t.id;w(!0),A(null),E(null),P(!1);try{let t=await O(e,i,n);z.current===r&&E(t)}catch(e){z.current===r&&A(e instanceof Error?e.message:String(e))}finally{z.current===r&&w(!1)}},H=async e=>{if(t){L(!0);try{await d(t.id,e)}finally{L(!1)}}},U=async()=>{if(T?.matchedEntry){M(!0);try{await f(T.domain),P(!0)}catch(e){A(e instanceof Error?e.message:String(e))}finally{M(!1)}}};return(0,R.jsxs)(h,{isOpen:t!==null,onClose:()=>{B(),i()},title:p(`filtering.listDetails`,`List Details`),icon:`info-sign`,children:[(0,R.jsxs)(`div`,{className:`p-6 space-y-4`,children:[t?.sync_error&&(0,R.jsx)(g,{intent:v.WARNING,title:p(`filtering.syncError`),icon:`warning-sign`,children:t.sync_error}),(0,R.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700 break-all font-mono text-sm`,children:t?.url}),(0,R.jsxs)(`div`,{className:`flex items-center justify-between border border-gray-200 dark:border-gray-700 rounded-lg p-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.listEnabled`,`List active`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.listEnabledHint`,`Disable to stop filtering with this list without deleting it. Its subscription and sync history are kept.`)})]}),(0,R.jsx)(b,{large:!0,checked:!!t?.enabled,disabled:F,onChange:e=>H(e.target.checked)})]}),(0,R.jsxs)(`div`,{className:`border border-gray-200 dark:border-gray-700 rounded-lg p-3 space-y-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.checkDomain`,`Check a domain`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.checkDomainHint`,`Lists are stored as compact filters, so their entries cannot be browsed. You can test any domain against this list instantly.`)})]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(y,{fill:!0,placeholder:`example.com`,value:_,disabled:C,leftIcon:`globe-network`,onChange:e=>{S(e.target.value),E(null)},onKeyDown:e=>{e.key===`Enter`&&V()}}),(0,R.jsx)(m,{icon:(0,R.jsx)(r,{size:14}),text:p(`filtering.check`,`Check`),loading:C,disabled:!_.trim(),onClick:()=>void V()})]}),k&&(0,R.jsx)(g,{intent:v.DANGER,className:`text-xs`,children:k}),T&&!T.synced&&(0,R.jsx)(g,{intent:v.WARNING,className:`text-xs`,children:p(`filtering.checkNotSynced`,`This list has not finished syncing yet, so there is nothing to check against.`)}),T?.synced&&T.enabled===!1&&(0,R.jsx)(g,{intent:v.NONE,className:`text-xs`,children:p(`filtering.checkListDisabled`,`This list is currently disabled, so it is not filtering anything right now.`)}),T?.synced&&(0,R.jsx)(g,{intent:T.blocked?v.WARNING:v.SUCCESS,className:`text-xs`,icon:T.blocked?`ban-circle`:`tick-circle`,children:T.blocked?(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`div`,{children:[p(`filtering.checkBlocked`,`Blocked by this list`),T.matchedEntry&&T.matchedEntry!==T.domain&&(0,R.jsxs)(R.Fragment,{children:[` `,(0,R.jsx)(x,{minimal:!0,className:`font-mono`,children:T.matchedEntry}),` `,p(`filtering.checkViaParent`,`(matched a parent domain)`)]})]}),(0,R.jsx)(`div`,{className:`opacity-75`,children:T.falsePositiveRate?p(`filtering.checkProbabilisticRate`,{defaultValue:`Filters are probabilistic: roughly 1 match in {{odds}} is a false positive. Adding an exception also covers every subdomain of it.`,odds:Math.round(1/T.falsePositiveRate).toLocaleString()}):p(`filtering.checkProbabilistic`,`Filters are probabilistic, so a small share of matches are false positives. Adding an exception also covers every subdomain of it.`)}),N?(0,R.jsx)(x,{intent:v.SUCCESS,minimal:!0,children:p(`filtering.checkAllowed`,`Exception added - this domain now resolves`)}):(0,R.jsx)(m,{small:!0,icon:(0,R.jsx)(c,{size:12}),intent:v.PRIMARY,loading:j,text:p(`filtering.checkAllowAction`,`Allow anyway`),onClick:()=>void U()})]}):p(`filtering.checkNotBlocked`,`Not blocked by this list`)})]}),(0,R.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,R.jsxs)(`span`,{className:`text-xs opacity-50`,children:[p(`filtering.tableLastSync`),`:`,` `,t?.last_synced_at?D(new Date(t.last_synced_at*1e3)):`-`]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(s,{size:14}),text:p(`setup.copyUrl`,`Copy link`),onClick:()=>{t&&l(t.url)}}),(0,R.jsx)(m,{icon:(0,R.jsx)(o,{size:14}),text:p(`setup.learnMore`,`Open link`),onClick:()=>{t&&window.open(t.url,`_blank`)}})]})]})]}),(0,R.jsxs)(`div`,{className:`p-4 border-t border-gray-100 dark:border-gray-800 flex justify-between`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(n,{size:14}),intent:v.DANGER,text:p(`rules.delete`,`Delete`),onClick:()=>{if(!t)return;let e=t.id;B(),u(e)}}),(0,R.jsx)(m,{onClick:()=>{B(),i()},text:p(`rules.close`,`Close`)})]})]})},H=({profileId:e,toasterRef:n})=>{let r=t(),o=j(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(``),[f,p]=(0,I.useState)(!0),[h,_]=(0,I.useState)(!1),{t:y}=a(),[b,x]=(0,I.useState)(null),S=async()=>{p(!0);try{c(await F(e))}catch(e){console.error(`Failed to fetch filters`,e)}finally{p(!1)}},C=e=>{navigator.clipboard.writeText(e),n?.current?.show({message:y(`setup.copied`,`已复制到剪贴板`),intent:v.SUCCESS,icon:`duplicate`})},w=async t=>{let n=new Map(t.map(e=>[e.id,e.last_synced_at])),r=0;for(;r<15;){await new Promise(e=>setTimeout(e,2e3));try{let t=await F(e),r=!0;for(let e of t){if(n.has(e.id)&&e.last_synced_at===n.get(e.id)){r=!1;break}if(!n.has(e.id)&&!e.last_synced_at){r=!1;break}}if(r&&t.length>0)return c(t),!0}catch{}r++}return await S(),!1};return(0,I.useEffect)(()=>{S()},[e]),(0,R.jsxs)(`div`,{className:T(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,o?`p-1`:`px-8`),children:[(0,R.jsxs)(`div`,{className:`mb-8 flex flex-col md:flex-row justify-between items-start md:items-end gap-4`,children:[(0,R.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[o?(0,R.jsxs)(d,{minimal:!0,fill:o,children:[(0,R.jsx)(m,{active:!1,onClick:()=>r(`/dash/${e}/rules`),text:y(`rules.title`),large:!0}),(0,R.jsx)(m,{active:!0,onClick:()=>r(`/dash/${e}/filter`),text:y(`filtering.title`),large:!0})]}):(0,R.jsx)(`h1`,{className:`bp6-heading`,children:y(`rules.title`)}),(0,R.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:y(`filtering.subtitle`)})]}),(0,R.jsx)(m,{icon:(0,R.jsx)(i,{size:16}),text:y(`filtering.syncAll`),onClick:async()=>{_(!0);try{await N(e),n?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&n?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}},loading:h||f,disabled:h||f||s.length===0,className:o?`w-full`:``})]}),(0,R.jsx)(g,{intent:v.WARNING,icon:`info-sign`,className:`mb-6`,children:(0,R.jsx)(`p`,{children:y(`filtering.formatDisclaimer`,`本系统只支持有限的 AdGuard 格式列表和纯域名列表。仅支持基础的拦截规则(如 ||example.com^),会绕过 "@@" 白名单,暂不支持 "$" 重写规则以及 "*" 省略规则。系统会自动匹配域名的所有子域名。`)})}),(0,R.jsx)(z,{newUrl:l,setNewUrl:u,onAddList:async t=>{let r=t||l;if(r){_(!0);try{await E(e,r),n?.current?.show({message:y(`filtering.addSuccess`),intent:v.SUCCESS,icon:`tick`}),u(``),n?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&n?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}}},syncing:h,loading:f,lists:s}),(0,R.jsx)(B,{lists:s,onSelect:x}),(0,R.jsx)(V,{profileId:e,selectedList:b,onClose:()=>x(null),onCopy:C,onDelete:async t=>{try{await P(e,t),n?.current?.show({message:y(`filtering.deleteSuccess`),intent:v.PRIMARY,icon:`trash`}),x(null),await S()}catch(e){console.error(e)}},onToggleEnabled:async(t,r)=>{try{await M(e,t,r),x(e=>e&&e.id===t?{...e,enabled:r}:e),n?.current?.show({message:r?y(`filtering.listEnabledToast`,`List enabled - rebuilding filter`):y(`filtering.listDisabledToast`,`List disabled - rebuilding filter`),intent:v.PRIMARY,icon:r?`tick`:`disable`}),await S()}catch(e){console.error(e),n?.current?.show({message:e instanceof Error?e.message:String(e),intent:v.DANGER,icon:`error`})}},onAllowDomain:async t=>{await A(e,{type:`ALLOW`,pattern:t}),n?.current?.show({message:y(`filtering.allowRuleAdded`,`Exception added for {{domain}}`,{domain:t}),intent:v.SUCCESS,icon:`tick`})}})]})};export{H as FilteringView};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/services-C-uSOjyn.js","assets/index-DLmOvLdX.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-DifRgRH3.js","assets/vendor-ui-core-CCxBtqRD.js","assets/vendor-utils-D17P9mkD.js","assets/vendor-i18next-cO7FDf_e.js","assets/index-DdQuGqR5.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{A as t,H as n,J as r,K as i,V as a,Xt as o,b as s,gt as c,j as l,nt as u,tt as d,wt as f,yt as p}from"./vendor-react-DifRgRH3.js";import{S as m,b as h,x as g}from"./vendor-icons-other-Bme3ywH9.js";import{C as _,E as v,M as y,N as b,P as x,S,T as C,V as w,a as T,f as E,h as D,l as O,o as k,p as A,r as j,u as M,w as N,x as P}from"./vendor-ui-core-CCxBtqRD.js";import{_t as F}from"./vendor-utils-D17P9mkD.js";import{$ as I,C as L,Q as R,Xt as ee,et as te,nt as z,rt as B}from"./index-DLmOvLdX.js";import{n as ne,t as V}from"./formatCountryName-CSBD8pP8.js";import{t as H}from"./getFlagEmoji-_Wxhq0lT.js";import{t as U}from"./SwipeableDrawer-CzMJdF3W.js";var W=e(m(),1),G=e(h(),1);const K=({range:e,setRange:t,customRange:n,setCustomRange:r,nowStr:i,fetchLogs:a,isMobile:s,logRetentionDays:l})=>{let{t:u}=o(),d=[{key:`10m`,days:.007},{key:`1h`,days:.0416},{key:`24h`,days:1},{key:`7d`,days:7},{key:`30d`,days:30}].filter(e=>e.days<=l).map(e=>e.key);return(0,G.jsx)(`div`,{className:`overflow-x-auto pb-1 -mx-4 px-4 md:mx-0 md:px-0`,children:(0,G.jsxs)(_,{minimal:s,variant:s?void 0:`minimal`,children:[d.map(n=>(0,G.jsx)(b,{active:e===n,onClick:()=>t(n),text:n.toUpperCase(),small:s},n)),(0,G.jsx)(C,{content:(0,G.jsxs)(`div`,{className:`p-4 space-y-2 w-64`,children:[(0,G.jsx)(y,{children:u(`analytics.customRange`)}),(0,G.jsx)(A,{label:u(`analytics.startTime`),children:(0,G.jsx)(E,{type:`datetime-local`,max:n.end||i,value:n.start,onChange:e=>r({...n,start:e.target.value})})}),(0,G.jsx)(A,{label:u(`analytics.endTime`),children:(0,G.jsx)(E,{type:`datetime-local`,min:n.start,max:i,value:n.end,onChange:e=>r({...n,end:e.target.value})})}),(0,G.jsx)(b,{fill:!0,intent:w.PRIMARY,text:u(`analytics.apply`),onClick:()=>{t(`custom`),a(`custom`,!0)}})]}),children:(0,G.jsx)(b,{active:e===`custom`,icon:(0,G.jsx)(c,{size:14}),text:s?``:u(`analytics.custom`),small:s})})]})})},q=({statusFilter:e,setStatusFilter:t,isMobile:n})=>{let{t:r}=o(),i=(0,G.jsxs)(v,{children:[(0,G.jsx)(N,{icon:e===null?`tick`:void 0,text:r(`logs.allStatus`),onClick:()=>t(null)}),(0,G.jsx)(O,{}),(0,G.jsx)(N,{icon:e===`PASS`?`tick`:void 0,intent:w.SUCCESS,text:r(`logs.onlyPass`),onClick:()=>t(`PASS`)}),(0,G.jsx)(N,{icon:e===`BLOCK`?`tick`:void 0,intent:w.DANGER,text:r(`logs.onlyBlock`),onClick:()=>t(`BLOCK`)}),(0,G.jsx)(N,{icon:e===`REDIRECT`?`tick`:void 0,intent:w.WARNING,text:r(`logs.onlyRedirect`),onClick:()=>t(`REDIRECT`)})]}),a=(()=>{switch(e){case`PASS`:return{text:r(`logs.statusPass`),intent:w.SUCCESS};case`BLOCK`:return{text:r(`logs.statusBlock`),intent:w.DANGER};case`REDIRECT`:return{text:r(`logs.statusRedirect`),intent:w.WARNING};default:return{text:r(`logs.allStatus`),intent:w.NONE}}})();return(0,G.jsx)(C,{content:i,placement:`bottom-start`,children:(0,G.jsx)(b,{icon:(0,G.jsx)(u,{size:14}),rightIcon:`caret-down`,intent:a.intent,text:a.text,variant:`outlined`,fill:n})})},J=({accessPointIdFilter:e,setAccessPointIdFilter:t,accessPoints:n,isMobile:r})=>{let{t:a}=o(),s=(0,G.jsxs)(v,{children:[(0,G.jsx)(N,{icon:e===null?`tick`:void 0,text:a(`logs.allAccessPoint`),onClick:()=>t(null)}),(0,G.jsx)(O,{}),n.map(n=>(0,G.jsx)(N,{icon:e===n.id?`tick`:void 0,text:n.name,onClick:()=>t(n.id)},n.id))]}),c=e&&n.find(t=>t.id===e)?.name||a(`logs.allAccessPoint`);return(0,G.jsx)(C,{content:s,placement:`bottom-start`,children:(0,G.jsx)(b,{icon:(0,G.jsx)(i,{size:14}),rightIcon:`caret-down`,intent:e?w.PRIMARY:w.NONE,text:c,variant:`outlined`,fill:r})})},Y=Array.from(new Set(Object.values(ne))).sort((e,t)=>e.localeCompare(t)),X=({destCountryFilter:e,setDestCountryFilter:t,isMobile:n})=>{let{t:r,i18n:i}=o(),[a,s]=(0,W.useState)(!1),[c,l]=(0,W.useState)(``),u=(0,W.useMemo)(()=>{let e=i.language;return Y.map(t=>{let n=V(t,e),r=V(t,`en`);return{code:t,name:n||r||t,searchStr:`${t} ${n} ${r}`.toLowerCase()}})},[i.language]),f=(0,W.useMemo)(()=>{let e=c.trim().toLowerCase();return e?u.filter(t=>t.searchStr.includes(e)):u},[u,c]),p=(0,G.jsxs)(`div`,{className:`w-72 flex flex-col p-1.5`,children:[(0,G.jsx)(`div`,{className:`pb-1.5`,children:(0,G.jsx)(E,{leftIcon:`search`,placeholder:r(`logs.searchCountry`,`Search country...`),value:c,onChange:e=>l(e.target.value),small:!0,autoFocus:!0,rightElement:c?(0,G.jsx)(b,{icon:`cross`,variant:`minimal`,small:!0,onClick:()=>l(``)}):void 0})}),(0,G.jsxs)(v,{className:`max-h-64 overflow-y-auto`,children:[!c&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(N,{icon:e===null?`tick`:void 0,text:r(`logs.allCountry`),onClick:()=>{t(null),s(!1)}}),(0,G.jsx)(O,{})]}),f.length===0?(0,G.jsx)(N,{disabled:!0,text:r(`logs.noMatchingCountries`,`No matching countries found`)}):f.map(n=>(0,G.jsx)(N,{icon:e===n.code?`tick`:void 0,text:(0,G.jsxs)(`span`,{className:`flex items-center justify-between gap-2 w-full`,children:[(0,G.jsxs)(`span`,{className:`truncate`,children:[H(n.code),` `,n.name]}),(0,G.jsx)(`span`,{className:`text-xs text-gray-400 shrink-0 font-mono`,children:n.code})]}),onClick:()=>{t(n.code),s(!1)}},n.code))]})]}),m=e?`${H(e)} ${V(e,i.language)||e} (${e})`:r(`logs.allCountry`);return(0,G.jsx)(C,{content:p,placement:`bottom-start`,isOpen:a,onInteraction:e=>{s(e),e||l(``)},children:(0,G.jsx)(b,{icon:(0,G.jsx)(d,{size:14}),rightIcon:`caret-down`,intent:e?w.PRIMARY:w.NONE,text:m,variant:`outlined`,fill:n})})},re=({profileId:e,range:t,customRange:r,destCountryFilter:i,accessPointIdFilter:a,ispFilter:s,setIspFilter:c,isMobile:l})=>{let{t:u}=o(),[d,f]=(0,W.useState)(!1),[p,m]=(0,W.useState)([]),[h,g]=(0,W.useState)(!1),[_,y]=(0,W.useState)(``),S=(0,W.useRef)(``),T=`${e}:${t}:${r.start?Math.floor(new Date(r.start).getTime()/1e3):``}:${r.end?Math.floor(new Date(r.end).getTime()/1e3):``}:${i||``}:${a||``}`,D=async()=>{g(!0);try{let n=new URLSearchParams;if(t===`custom`&&r.start&&r.end){let e=Math.floor(new Date(r.start).getTime()/1e3),t=Math.floor(new Date(r.end).getTime()/1e3);n.set(`range`,`custom`),n.set(`start`,String(e)),n.set(`end`,String(t))}else n.set(`range`,t);i&&n.set(`country_code`,i),a&&n.set(`access_point_id`,a);let o=await I(e,`isps`,n.toString());m(Array.isArray(o)?o:[]),S.current=T}catch(e){console.error(`Failed to fetch ISPs for filter`,e)}finally{g(!1)}},k=e=>{f(e),e?S.current!==T&&D():y(``)},A=(0,W.useMemo)(()=>{let e=_.trim().toLowerCase();return e?p.filter(t=>t.name.toLowerCase().includes(e)):p},[p,_]),j=(0,G.jsxs)(`div`,{className:`w-72 flex flex-col p-1.5`,children:[(0,G.jsx)(`div`,{className:`pb-1.5`,children:(0,G.jsx)(E,{leftIcon:`search`,placeholder:u(`logs.searchIsp`,`Search ISP...`),value:_,onChange:e=>y(e.target.value),small:!0,autoFocus:!0,rightElement:_?(0,G.jsx)(b,{icon:`cross`,variant:`minimal`,small:!0,onClick:()=>y(``)}):void 0})}),(0,G.jsx)(v,{className:`max-h-64 overflow-y-auto`,children:h?(0,G.jsxs)(`div`,{className:`flex items-center justify-center p-6 text-gray-500 gap-2`,children:[(0,G.jsx)(x,{size:16}),(0,G.jsx)(`span`,{className:`text-xs`,children:u(`logs.loadingIsps`,`Loading ISPs...`)})]}):(0,G.jsxs)(G.Fragment,{children:[!_&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(N,{icon:s===null?`tick`:void 0,text:u(`logs.allIsp`),onClick:()=>{c(null),f(!1)}}),(0,G.jsx)(O,{})]}),A.length===0?(0,G.jsx)(N,{disabled:!0,text:u(`logs.noMatchingIsps`,`No matching ISPs found`)}):A.map(e=>(0,G.jsx)(N,{icon:s===e.name?`tick`:void 0,text:(0,G.jsxs)(`span`,{className:`flex items-center justify-between gap-2 w-full`,children:[(0,G.jsx)(`span`,{className:`truncate`,title:e.name,children:e.name}),(0,G.jsx)(`span`,{className:`text-xs text-gray-400 shrink-0 font-mono`,children:e.count.toLocaleString()})]}),onClick:()=>{c(e.name),f(!1)}},e.name))]})})]}),M=s||u(`logs.allIsp`);return(0,G.jsx)(C,{content:j,placement:`bottom-start`,isOpen:d,onInteraction:k,children:(0,G.jsx)(b,{icon:(0,G.jsx)(n,{size:14}),rightIcon:`caret-down`,intent:s?w.PRIMARY:w.NONE,text:M,variant:`outlined`,fill:l})})},ie=({profileId:e,range:t,setRange:n,customRange:r,setCustomRange:i,nowStr:a,fetchLogs:s,isMobile:c,realtimeRefresh:l,setRealtimeRefresh:u,statusFilter:d,setStatusFilter:f,accessPointIdFilter:p,setAccessPointIdFilter:m,accessPoints:h,destCountryFilter:g,setDestCountryFilter:_,ispFilter:v,setIspFilter:y,searchQuery:x,setSearchQuery:S,stats:C,logRetentionDays:T,onExport:O,exporting:k})=>{let{t:A}=o(),[M,N]=(0,W.useState)(!0),P=d!==null||p!==null||g!==null||v!==null;return(0,G.jsxs)(`div`,{className:`p-4 ${c&&M?`space-y-0`:`space-y-4`} shrink-0 bg-white/50 dark:bg-gray-900/50 backdrop-blur-sm border-b border-gray-100 dark:border-gray-800`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col md:flex-row md:items-center justify-between gap-4`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between w-full md:w-auto`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`h2`,{className:`bp6-heading flex flex-wrap items-center gap-2 text-xl md:text-2xl m-0`,children:[A(`logs.title`),` `,(!c||!M)&&(0,G.jsx)(j,{minimal:!0,round:!0,children:t===`custom`?A(`analytics.custom`):t.toUpperCase()}),C&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(j,{minimal:!0,round:!0,children:C.total.toLocaleString()}),(0,G.jsx)(j,{minimal:!0,round:!0,intent:w.SUCCESS,children:C.pass.toLocaleString()}),(0,G.jsx)(j,{minimal:!0,round:!0,intent:w.DANGER,children:C.block.toLocaleString()}),(0,G.jsx)(j,{minimal:!0,round:!0,intent:w.WARNING,children:C.redirect.toLocaleString()})]})]}),!c&&(0,G.jsx)(`p`,{className:`bp6-text-muted mt-1`,children:A(`logs.subtitle`)})]}),c&&(0,G.jsx)(b,{icon:M?`chevron-down`:`chevron-up`,variant:`minimal`,onClick:()=>N(!M)})]}),(!c||!M)&&(0,G.jsxs)(`div`,{className:`flex flex-col items-stretch md:items-end gap-2`,children:[(0,G.jsx)(K,{range:t,setRange:n,customRange:r,setCustomRange:i,nowStr:a,fetchLogs:s,isMobile:c,logRetentionDays:T}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-4`,children:[(0,G.jsx)(b,{icon:`download`,onClick:O,loading:k,title:A(`logs.export`,`Export Logs`),text:c?void 0:A(`logs.export`,`Export Logs`)}),(0,G.jsx)(D,{label:A(`logs.realtime`),checked:l,onChange:e=>u(e.target.checked),className:`mb-0!`}),(0,G.jsx)(b,{icon:`refresh`,onClick:()=>s(t,!0),variant:`minimal`,small:c})]})]})]}),(!c||!M)&&(0,G.jsxs)(`div`,{className:`flex flex-col md:flex-row items-stretch md:items-center justify-between gap-3`,children:[(0,G.jsxs)(`div`,{className:`grid grid-cols-2 md:flex md:items-center gap-2`,children:[P&&(0,G.jsx)(`div`,{className:`col-span-2 md:contents`,children:(0,G.jsx)(b,{icon:`filter-remove`,onClick:()=>{f(null),m(null),_(null),y(null)},variant:`minimal`,title:A(`logs.clearFilters`),text:c?A(`logs.clearFilters`):void 0,fill:c})}),(0,G.jsx)(q,{statusFilter:d,setStatusFilter:f,isMobile:c}),h.length>0&&(0,G.jsx)(J,{accessPointIdFilter:p,setAccessPointIdFilter:m,accessPoints:h,isMobile:c}),(0,G.jsx)(X,{destCountryFilter:g,setDestCountryFilter:_,isMobile:c}),(0,G.jsx)(re,{profileId:e,range:t,customRange:r,destCountryFilter:g,accessPointIdFilter:p,ispFilter:v,setIspFilter:y,isMobile:c})]}),(0,G.jsx)(`div`,{className:`flex items-center gap-2 flex-1 md:max-w-md justify-end`,children:(0,G.jsx)(`div`,{className:`flex-1 md:max-w-xs`,children:(0,G.jsx)(E,{leftIcon:`search`,placeholder:A(`logs.searchPlaceholder`),value:x,onChange:e=>S(e.target.value),rightElement:x?(0,G.jsx)(b,{icon:`cross`,minimal:!0,onClick:()=>S(``)}):void 0,fill:!0})})})]})]})},ae=({logs:e,setSelectedLog:t,setIsDrawerOpen:n,lastLogElementRef:r,prevLatestTimestamp:i,realtimeRefresh:a})=>(0,G.jsx)(`div`,{className:`space-y-3 py-4`,children:e.map((o,s)=>{let c=a&&i!==null&&o.timestamp>i;return(0,G.jsxs)(P,{interactive:!0,onClick:()=>{t(o),n(!0)},className:F(`p-3 dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 shadow-sm overflow-hidden`,{"animate-row-glow":c}),ref:s===e.length-1?r:null,children:[(0,G.jsxs)(`div`,{className:`flex justify-between items-start mb-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,G.jsx)(`img`,{src:`/api/icon/${o.domain.replace(/^\*\./,``)}.ico`,className:`w-4 h-4 rounded-sm shrink-0`,alt:``,referrerPolicy:`no-referrer`,onError:e=>e.currentTarget.style.opacity=`0`}),(0,G.jsx)(`span`,{className:`font-bold text-sm truncate`,children:o.domain})]}),(0,G.jsx)(j,{minimal:!0,round:!0,intent:o.action===`PASS`?w.SUCCESS:o.action===`BLOCK`?w.DANGER:w.WARNING,className:`text-[10px] shrink-0`,children:o.action})]}),(0,G.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,G.jsxs)(`div`,{className:`flex gap-2 items-center`,children:[(0,G.jsx)(`span`,{className:`text-[10px] font-mono opacity-50`,children:new Date(o.timestamp*1e3).toLocaleTimeString([],{hour12:!1})}),(0,G.jsx)(`span`,{className:`text-[10px] bg-gray-100 dark:bg-gray-800 px-1 rounded opacity-60`,children:o.record_type}),o.access_point_name&&(0,G.jsx)(`span`,{className:`text-[10px] opacity-50 truncate max-w-25`,children:o.access_point_name})]}),(0,G.jsx)(`div`,{className:`text-[10px] opacity-40 font-mono italic`,children:o.latency?`${o.latency}ms`:``})]})]},o.id)})}),oe=({logs:e,setSelectedLog:t,setIsDrawerOpen:n,lastLogElementRef:r,prevLatestTimestamp:i,realtimeRefresh:a})=>{let{t:s}=o(),c=[{key:`time`,header:s(`logs.tableTime`),headerClassName:`w-24 rounded-tl-xl`,cellClassName:`font-mono text-[11px] opacity-60`,render:e=>new Date(e.timestamp*1e3).toLocaleTimeString([],{hour12:!1})},{key:`domain`,header:s(`logs.tableDomain`),headerClassName:`w-1/4`,render:e=>(0,G.jsxs)(`div`,{className:`flex items-center gap-2 truncate`,children:[(0,G.jsx)(`img`,{src:`/api/icon/${e.domain.replace(/^\*\./,``)}.ico`,className:`w-4 h-4 rounded-sm`,alt:``,referrerPolicy:`no-referrer`}),(0,G.jsx)(`span`,{className:`font-bold text-sm truncate`,children:e.domain})]})},{key:`answer`,header:s(`logs.tableAnswer`),headerClassName:`w-1/4`,cellClassName:`truncate font-mono text-[11px] opacity-70`,render:e=>e.answer||`-`},{key:`source`,header:s(`logs.tableSource`),headerClassName:`w-32`,render:e=>(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(j,{minimal:!0,className:`font-mono text-[10px]`,children:H(e.geo_country||`UN`)}),e.access_point_name&&(0,G.jsx)(`span`,{className:`text-xs opacity-70 truncate max-w-20`,title:e.access_point_name,children:e.access_point_name})]})},{key:`type`,header:s(`logs.tableType`),headerClassName:`w-20`,cellClassName:`text-center`,render:e=>(0,G.jsx)(`code`,{className:`text-[10px]`,children:e.record_type})},{key:`status`,header:s(`logs.tableStatus`),headerClassName:`w-28`,cellClassName:`text-center`,render:e=>(0,G.jsx)(`span`,{className:F(`bp6-tag`,`bp6-fill`,`bp6-minimal`,`bp6-round`,{"bp6-intent-success":e.action===`PASS`,"bp6-intent-danger":e.action===`BLOCK`,"bp6-intent-warning":e.action===`REDIRECT`}),children:(0,G.jsx)(`span`,{className:`bp6-text-overflow-ellipsis bp6-fill text-center`,children:e.action})})},{key:`reason`,header:s(`logs.tableReason`),headerClassName:`rounded-tr-xl`,cellClassName:`text-xs text-gray-500 italic truncate`,render:e=>e.reason||`-`}];return(0,G.jsx)(`div`,{className:`min-w-full inline-block align-middle py-0`,children:(0,G.jsx)(`div`,{className:`bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 shadow-sm overflow-visible`,children:(0,G.jsxs)(M,{interactive:!0,striped:!0,className:`w-full table-fixed`,children:[(0,G.jsx)(`thead`,{className:`sticky top-0 z-20 backdrop-blur-md`,children:(0,G.jsx)(`tr`,{children:c.map(e=>(0,G.jsx)(`th`,{className:F(`px-4 py-3 text-xs font-bold uppercase text-gray-500 bg-white/80 dark:bg-gray-900/80 border-b border-gray-100 dark:border-gray-800`,e.headerClassName),children:e.header},e.key))})}),(0,G.jsx)(`tbody`,{className:`divide-y divide-gray-100 dark:divide-gray-800`,children:e.map((o,s)=>{let l=a&&i!==null&&o.timestamp>i;return(0,G.jsx)(`tr`,{onClick:()=>{t(o),n(!0)},className:F(`cursor-pointer`,{"animate-row-glow":l}),ref:s===e.length-1?r:null,children:c.map(e=>(0,G.jsx)(`td`,{className:F(`px-4 py-3`,e.cellClassName),children:e.render(o,s)},e.key))},o.id)})})]})})})},se=({logs:e,loading:t,loadingMore:n,hasMore:r,realtimeRefresh:i,isMobile:a,searchQuery:s,scrollContainerRef:c,lastLogElementRef:l,prevLatestTimestamp:u,setSelectedLog:d,setIsDrawerOpen:f,logRetentionDays:p})=>{let{t:m}=o();return(0,G.jsxs)(`div`,{ref:c,className:F(`flex-1 overflow-y-auto relative`,a?`px-1`:`px-4`),children:[e.length===0&&!t?(0,G.jsx)(`div`,{className:`py-20`,children:(0,G.jsx)(S,{title:p===0?m(`logs.loggingDisabledTitle`,`日志记录已关闭`):m(s?`logs.noResults`:`logs.noRecords`),icon:p===0?`disable`:s?`search`:`outdated`,intent:p===0?w.WARNING:w.NONE,children:p===0?m(`logs.loggingDisabledDesc`,`当前配置的日志留存已设置为“关闭”,系统不记录任何查询日志。如需查看,请在设置中启用日志留存。`):s?m(`logs.noResultsDesc`,{query:s}):m(`logs.noRecordsDesc`)})}):a?(0,G.jsx)(ae,{logs:e,setSelectedLog:d,setIsDrawerOpen:f,lastLogElementRef:l,prevLatestTimestamp:u,realtimeRefresh:i}):(0,G.jsx)(oe,{logs:e,setSelectedLog:d,setIsDrawerOpen:f,lastLogElementRef:l,prevLatestTimestamp:u,realtimeRefresh:i}),(0,G.jsx)(`div`,{className:`p-6 flex flex-col items-center`,children:n?(0,G.jsx)(x,{size:16}):i?e.length>0&&(0,G.jsx)(`span`,{className:`text-[10px] opacity-30 italic`,children:m(`logs.realtimeLoadMoreTip`)}):!r&&e.length>0&&(0,G.jsx)(`span`,{className:`text-[10px] opacity-30 italic`,children:m(`logs.loadedAll`,{count:e.length})})})]})};function ce(e,t,n){let[r,i]=(0,W.useState)(null),[a,o]=(0,W.useState)(!1);return(0,W.useEffect)(()=>{if(e&&t?.id){o(!0),i(null);let e=new AbortController;return z(n,t.id,t.timestamp,{signal:e.signal}).then(e=>{i(e)}).catch(e=>{e.name!==`AbortError`&&console.error(e)}).finally(()=>{o(!1)}),()=>{e.abort()}}else i(null)},[e,t?.id,n]),{detailedLog:r,loading:a}}const Z=({label:e,value:t,bold:n,italic:r})=>(0,G.jsxs)(`div`,{className:`flex justify-between items-start gap-4`,children:[(0,G.jsx)(`span`,{className:`text-xs opacity-50 mt-1`,children:e}),(0,G.jsx)(`span`,{className:F(`text-sm text-right`,n&&`font-bold`,r&&`italic`),children:t})]}),le=({selectedLog:e,detailedLog:t,loading:n})=>{let{t:r}=o();return(0,G.jsx)(k,{title:r(`logs.basicInfo`),icon:(0,G.jsx)(f,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,G.jsx)(T,{children:(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsx)(Z,{label:r(`logs.detailDomain`),value:(0,G.jsxs)(`div`,{className:`flex items-center gap-2 justify-end font-bold`,children:[(0,G.jsx)(`img`,{src:`/api/icon/${e.domain.replace(/^\*\./,``)}.ico`,className:`w-4 h-4 rounded-sm`,alt:``,referrerPolicy:`no-referrer`,onError:e=>e.currentTarget.style.display=`none`}),(0,G.jsx)(`span`,{children:e.domain})]}),bold:!0}),(0,G.jsx)(Z,{label:r(`logs.detailType`),value:e.record_type}),(0,G.jsx)(Z,{label:r(`logs.detailLatency`),value:e.latency?`${e.latency} ms`:`-`}),e.access_point_name&&(0,G.jsx)(Z,{label:r(`logs.detailAccessPoint`),value:e.access_point_name}),(0,G.jsx)(Z,{label:r(`logs.detailProfile`),value:n?(0,G.jsx)(x,{size:12}):t?.profile_name||t?.client_ip||`-`}),(0,G.jsx)(Z,{label:r(`logs.detailTime`),value:L(new Date(e.timestamp*1e3))}),(0,G.jsx)(Z,{label:r(`logs.detailStatus`),value:(0,G.jsx)(j,{minimal:!0,intent:e.action===`PASS`?w.SUCCESS:e.action===`BLOCK`?w.DANGER:w.WARNING,children:e.action})}),(0,G.jsx)(Z,{label:r(`logs.detailUpstream`),value:n?(0,G.jsx)(x,{size:12}):t?.upstream||`-`}),(0,G.jsx)(Z,{label:r(`logs.detailReason`),value:e.reason||r(`logs.detailNoReason`),italic:!0}),(0,G.jsx)(Z,{label:r(`logs.detailECS`),value:n?(0,G.jsx)(x,{size:12}):t?.ecs||`-`,italic:!0})]})})})},ue=({selectedLog:e})=>{let{t}=o(),n=e.record_type===`HTTPS`||e.record_type===`SVCB`||e.record_type===`TYPE65`||e.record_type===`TYPE64`,r=n&&(e.reason===`ECH Rewritten`||(e.reason?.toLowerCase().includes(`rewritten`)??!1));return(0,G.jsx)(k,{title:(0,G.jsxs)(`div`,{className:`flex items-center justify-between w-full pr-2`,children:[(0,G.jsx)(`span`,{children:t(`logs.resolutionResult`)}),r&&(0,G.jsx)(j,{minimal:!0,intent:w.PRIMARY,className:`text-xs`,children:t(`logs.rewritten`,`已重写`)})]}),icon:(0,G.jsx)(d,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,G.jsx)(T,{children:(0,G.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-3 font-mono text-xs break-all leading-relaxed rounded-lg`,children:(()=>{if(!e.answer)return t(`logs.noResult`);let r=e.answer.split(`
|
|
3
|
-
`).map(e=>e.trim()).filter(Boolean);return r.length===0?t(`logs.noResult`):(0,G.jsx)(`div`,{className:`space-y-2`,children:r.map((e,t)=>{let r=e.match(/^(\d+)\s+([^\s]+)(?:\s+(.*))?$/);if(r&&(n||e.includes(`alpn=`)||e.includes(`ech=`)||e.includes(`ipv4hint=`))){let e=r[1],n=r[2],i=(r[3]||``).split(/\s+/).filter(Boolean);return(0,G.jsxs)(`div`,{className:`bg-white dark:bg-gray-900 p-2.5 rounded-md space-y-2 border border-gray-200 dark:border-gray-700`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,G.jsxs)(j,{minimal:!0,intent:w.PRIMARY,children:[`Priority `,e]}),(0,G.jsxs)(`span`,{className:`font-semibold text-gray-700 dark:text-gray-300`,children:[`Target: `,n]})]}),i.length>0&&(0,G.jsx)(`div`,{className:`flex flex-wrap gap-1.5 pt-1 border-t border-gray-100 dark:border-gray-800 text-xs`,children:i.map((e,t)=>{let n=e.indexOf(`=`);if(n===-1)return(0,G.jsx)(j,{minimal:!0,className:`font-mono`,children:e},t);let r=e.substring(0,n),i=e.substring(n+1);return r===`ech`?(0,G.jsxs)(j,{minimal:!0,intent:w.SUCCESS,className:`font-mono break-all max-w-full select-all text-left whitespace-normal h-auto py-1 inline-block`,title:i,children:[(0,G.jsx)(`span`,{className:`font-bold`,children:`ech:`}),` `,i]},t):r===`alpn`?(0,G.jsxs)(j,{minimal:!0,intent:w.WARNING,className:`font-mono`,children:[(0,G.jsx)(`span`,{className:`font-bold`,children:`alpn:`}),` `,i]},t):(0,G.jsxs)(j,{minimal:!0,className:`font-mono`,children:[(0,G.jsxs)(`span`,{className:`font-bold`,children:[r,`:`]}),` `,i]},t)})})]},t)}return(0,G.jsx)(`div`,{className:`space-y-1`,children:e.split(`,`).map(e=>e.trim()).filter(Boolean).map((e,t)=>(0,G.jsx)(`div`,{className:`text-xs font-mono text-gray-800 dark:text-gray-200 select-all`,children:e},t))},t)})})})()})})})},de=({selectedLog:e,detailedLog:t,loading:n})=>{let{t:i}=o();return(0,G.jsx)(k,{title:i(`logs.networkDetails`),icon:(0,G.jsx)(s,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,G.jsx)(T,{children:(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-50 mb-1`,children:i(`logs.clientSource`)}),(0,G.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,G.jsx)(`span`,{className:`font-mono`,children:n?(0,G.jsx)(x,{size:12}):t?.client_ip||`-`}),(0,G.jsx)(j,{minimal:!0,title:e.geo_country||`Unknown`,children:H(e.geo_country||``)})]})]}),n?(0,G.jsx)(`div`,{className:`flex items-center justify-center py-2`,children:(0,G.jsx)(x,{size:16})}):t?.dest_geoip&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-50 mb-1`,children:i(`logs.destination`)}),(()=>{try{let e=JSON.parse(t.dest_geoip);return(0,G.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-3 rounded-lg`,children:(0,G.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,G.jsx)(r,{size:16,className:`oklch(60.9% 0.126 221.723) mt-1 shrink-0`}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`font-bold text-sm`,children:[e.city,e.region,e.country].filter(Boolean).join(`, `)}),(0,G.jsxs)(`div`,{className:`text-xs opacity-70 mt-1`,children:[e.isp,e.as&&(0,G.jsx)(`span`,{className:`opacity-60 block mt-0.5`,children:e.as})]})]})]})})}catch{return null}})()]})]})})})},fe=({selectedLog:e,onQuickAction:n})=>{let{t:r}=o();return(0,G.jsx)(k,{title:r(`logs.quickActions`),icon:(0,G.jsx)(a,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,G.jsx)(T,{children:(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(b,{fill:!0,intent:w.SUCCESS,icon:(0,G.jsx)(t,{size:16}),text:r(`logs.actionAllow`),onClick:()=>n?.(e.domain,`ALLOW`)}),(0,G.jsx)(b,{fill:!0,intent:w.DANGER,icon:(0,G.jsx)(l,{size:16}),text:r(`logs.actionBlock`),onClick:()=>n?.(e.domain,`BLOCK`)}),(0,G.jsx)(b,{fill:!0,icon:(0,G.jsx)(p,{size:16}),text:r(`logs.actionRedirect`),onClick:()=>n?.(e.domain,`REDIRECT`,e.record_type)})]})})})},pe=({isDrawerOpen:e,setIsDrawerOpen:t,selectedLog:n,profileId:r,isMobile:i,onQuickAction:a})=>{let{t:s}=o(),{detailedLog:c,loading:l}=ce(e,n,r);return(0,G.jsx)(U,{isOpen:e&&n!==null,onClose:()=>t(!1),title:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(f,{size:18}),(0,G.jsx)(`span`,{children:s(`logs.logDetails`)})]}),icon:`info-sign`,size:i?`100%`:`450px`,children:n&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(le,{selectedLog:n,detailedLog:c,loading:l}),(0,G.jsx)(ue,{selectedLog:n}),(0,G.jsx)(de,{selectedLog:n,detailedLog:c,loading:l}),(0,G.jsx)(fe,{selectedLog:n,onQuickAction:a})]})})};function me(e){let[t,n]=(0,W.useState)(`24h`),[r,i]=(0,W.useState)({start:``,end:``}),[a,o]=(0,W.useState)(null),[s,c]=(0,W.useState)(null),[l,u]=(0,W.useState)([]),[d,f]=(0,W.useState)(null),[p,m]=(0,W.useState)(null),[h,g]=(0,W.useState)(``);return(0,W.useEffect)(()=>{R(e).then(u).catch(console.error)},[e]),(0,W.useEffect)(()=>{m(null)},[d]),{range:t,setRange:n,customRange:r,setCustomRange:i,statusFilter:a,setStatusFilter:o,accessPointIdFilter:s,setAccessPointIdFilter:c,accessPoints:l,destCountryFilter:d,setDestCountryFilter:f,ispFilter:p,setIspFilter:m,searchQuery:h,setSearchQuery:g}}var Q=50,he=25;function ge({profileId:e,range:t,customRange:n,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:o,searchQuery:s,realtimeRefresh:c}){let[l,u]=(0,W.useState)([]),[d,f]=(0,W.useState)(!0),[p,m]=(0,W.useState)(!1),[h,g]=(0,W.useState)(!0),[_,v]=(0,W.useState)(null),[y,b]=(0,W.useState)(30),[x,S]=(0,W.useState)(null),C=(0,W.useRef)([]);(0,W.useEffect)(()=>{C.current=l},[l]);let w=(0,W.useRef)(null),T=(0,W.useRef)(null),E=(0,W.useRef)(null),D=(0,W.useRef)(!1);(0,W.useEffect)(()=>()=>{E.current&&E.current.abort()},[]),(0,W.useEffect)(()=>{te(e).then(e=>{try{let t=JSON.parse(e.settings||`{}`);b(t.log_retention_days===void 0?30:Number(t.log_retention_days))}catch(e){console.error(`Failed to parse settings`,e)}}).catch(e=>console.error(`Failed to fetch profile settings`,e))},[e]);let O=async(t,d=!0,p=!1)=>{E.current&&E.current.abort();let h=new AbortController;E.current=h,D.current=!0,d?f(!0):m(!0);try{let f=c?he:Q,m=new URLSearchParams({range:t,limit:String(f)});if(t===`custom`&&n.start&&n.end){let e=Math.floor(new Date(n.start).getTime()/1e3),t=Math.floor(new Date(n.end).getTime()/1e3);m.set(`start`,String(e)),m.set(`end`,String(t))}r&&m.set(`status`,r),i&&m.set(`access_point_id`,i),a&&m.set(`dest_country`,a),o&&m.set(`isp`,o),s&&m.set(`search`,s),!d&&l.length>0&&m.set(`before`,String(l[l.length-1].timestamp));let _=B(e,m.toString(),{signal:h.signal}),y=Promise.resolve(null);if(d){let r=new URLSearchParams({range:t});if(t===`custom`&&n.start&&n.end){let e=Math.floor(new Date(n.start).getTime()/1e3),t=Math.floor(new Date(n.end).getTime()/1e3);r.set(`start`,String(e)),r.set(`end`,String(t))}s&&r.set(`search`,s),y=I(e,`summary`,r.toString(),{signal:h.signal})}let[b,x]=await Promise.all([_,y]);if(d){if(S(p&&C.current.length>0?C.current[0].timestamp:null),u(b),g(c?!1:b.length>=f),x){let e={total:0,pass:0,block:0,redirect:0};x.forEach(t=>{let n=t.count;e.total+=n,t.action===`PASS`?e.pass=n:t.action===`BLOCK`?e.block=n:t.action===`REDIRECT`&&(e.redirect=n)}),v(e)}}else u(e=>[...e,...b]),g(c?!1:b.length>=f);if(b&&b.length>0){let e=Array.from(new Set(b.map(e=>e.domain)));`serviceWorker`in navigator&&navigator.serviceWorker.controller&&navigator.serviceWorker.controller.postMessage({type:`PREFETCH_ICONS`,domains:e})}}catch(e){e.name!==`AbortError`&&console.error(e)}finally{E.current===h&&(f(!1),m(!1),D.current=!1)}},k=(0,W.useCallback)(()=>{c||!d&&!p&&h&&O(t,!1)},[d,p,h,t,e,r,i,a,o,s,l,n,c]),A=(0,W.useCallback)(e=>{T.current&&T.current.disconnect(),!(d||p||c)&&(T.current=new IntersectionObserver(e=>{e[0].isIntersecting&&h&&k()},{root:w.current,rootMargin:`200px`}),e&&T.current.observe(e))},[d,p,h,k,c]);return(0,W.useEffect)(()=>{if(t===`custom`&&(!n.start||!n.end))return;let e=setTimeout(()=>O(t,!0),s?500:0);return()=>clearTimeout(e)},[e,t,r,i,a,o,s,n,c]),{logs:l,loading:d,loadingMore:p,hasMore:h,stats:_,logRetentionDays:y,prevLatestTimestamp:x,scrollContainerRef:w,lastLogElementRef:A,fetchLogs:O,isFetchingRef:D}}function _e({profileId:e,range:t,searchQuery:n,realtimeRefresh:r,statusFilter:i,accessPointIdFilter:a,destCountryFilter:o,ispFilter:s,scrollContainerRef:c,isFetchingRef:l,fetchLogs:u}){(0,W.useEffect)(()=>{if(!r)return;let e=()=>{document.visibilityState===`visible`&&c.current&&c.current.scrollTop<50&&!l.current&&!n&&t!==`custom`&&u(t,!0,!0)},i=setInterval(e,6e3),a=()=>{document.visibilityState===`visible`&&e()};return document.addEventListener(`visibilitychange`,a),()=>{clearInterval(i),document.removeEventListener(`visibilitychange`,a)}},[e,t,n,r,i,a,o,s,c,l,u])}function $(e){let t=new Date(e*1e3),n=-t.getTimezoneOffset(),r=n>=0?`+`:`-`,i=e=>String(e).padStart(2,`0`);return t.getFullYear()+`-`+i(t.getMonth()+1)+`-`+i(t.getDate())+`T`+i(t.getHours())+`:`+i(t.getMinutes())+`:`+i(t.getSeconds())+`.`+(e=>String(e).padStart(3,`0`))(t.getMilliseconds())+(n===0?`Z`:r+i(Math.floor(Math.abs(n)/60))+`:`+i(Math.abs(n)%60))}function ve(e){let t=[`profile_id`,`access_point_id`,`time`,`client_ip`,`geo_country`,`domain`,`record_type`,`action`,`reason`,`answer`,`dest_geoip`,`ecs`,`upstream`,`latency`],n=[t.join(`,`)];for(let r of e){let e=t.map(e=>{let t=``;t=e===`time`?$(r.timestamp):r[e]!==null&&r[e]!==void 0?String(r[e]):``;let n=t.replace(/"/g,`""`);return n.includes(`,`)||n.includes(`
|
|
4
|
-
`)||n.includes(`\r`)||n.includes(`"`)?`"${n}"`:n});n.push(e.join(`,`))}return n.join(`
|
|
5
|
-
`)}function ye(e,t){let n=new Blob([e],{type:`text/csv;charset=utf-8;`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.setAttribute(`href`,r),i.setAttribute(`download`,t),document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}function be(e,t,n,r){return`query_logs_${e}_${$(t)}_${$(n)}_${r.toString()}.csv`}function xe({profileId:e,range:t,customRange:n,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:s,searchQuery:c,toasterRef:l}){let{t:u}=o(),[d,f]=(0,W.useState)(!1);return{exporting:d,handleExportLogs:async()=>{f(!0);try{let o=new URLSearchParams({range:t});if(t===`custom`&&n.start&&n.end){let e=Math.floor(new Date(n.start).getTime()/1e3),t=Math.floor(new Date(n.end).getTime()/1e3);o.set(`start`,String(e)),o.set(`end`,String(t))}r&&o.set(`status`,r),i&&o.set(`access_point_id`,i),a&&o.set(`dest_country`,a),s&&o.set(`isp`,s),c&&o.set(`search`,c);let{exportProfileLogs:d}=await g(async()=>{let{exportProfileLogs:e}=await import(`./services-C-uSOjyn.js`);return{exportProfileLogs:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10])),f=await d(e,o.toString());if(!f||f.length===0){l?.current?.show({message:u(`logs.noResults`,`No logs found to export`),intent:w.WARNING});return}ye(ve(f),be(e,f[0].timestamp,f[f.length-1].timestamp,o)),l?.current?.show({message:u(`logs.exportSuccess`,`Logs exported successfully`),intent:w.SUCCESS})}catch(e){console.error(`Failed to export logs`,e),l?.current?.show({message:u(`logs.exportError`,`Failed to export logs`),intent:w.DANGER})}finally{f(!1)}}}}function Se({profileId:e,toasterRef:t}){let[n,r]=(0,W.useState)(!1),i=me(e),a=ge({profileId:e,realtimeRefresh:n,range:i.range,customRange:i.customRange,statusFilter:i.statusFilter,accessPointIdFilter:i.accessPointIdFilter,destCountryFilter:i.destCountryFilter,ispFilter:i.ispFilter,searchQuery:i.searchQuery});_e({profileId:e,realtimeRefresh:n,range:i.range,statusFilter:i.statusFilter,accessPointIdFilter:i.accessPointIdFilter,destCountryFilter:i.destCountryFilter,ispFilter:i.ispFilter,searchQuery:i.searchQuery,scrollContainerRef:a.scrollContainerRef,isFetchingRef:a.isFetchingRef,fetchLogs:a.fetchLogs});let o=xe({profileId:e,range:i.range,customRange:i.customRange,statusFilter:i.statusFilter,accessPointIdFilter:i.accessPointIdFilter,destCountryFilter:i.destCountryFilter,ispFilter:i.ispFilter,searchQuery:i.searchQuery,toasterRef:t});return{realtimeRefresh:n,setRealtimeRefresh:r,...i,...a,...o}}const Ce=({profileId:e,onQuickAction:t,toasterRef:n})=>{let r=ee(),[i,a]=(0,W.useState)(null),[o,s]=(0,W.useState)(!1),{realtimeRefresh:c,setRealtimeRefresh:l,range:u,setRange:d,customRange:f,setCustomRange:p,statusFilter:m,setStatusFilter:h,accessPointIdFilter:g,setAccessPointIdFilter:_,accessPoints:v,destCountryFilter:y,setDestCountryFilter:b,ispFilter:S,setIspFilter:C,searchQuery:w,setSearchQuery:T,logs:E,loading:D,loadingMore:O,hasMore:k,stats:A,logRetentionDays:j,prevLatestTimestamp:M,scrollContainerRef:N,lastLogElementRef:P,fetchLogs:F,exporting:I,handleExportLogs:L}=Se({profileId:e,toasterRef:n}),R=new Date().toLocaleString(`sv-SE`).replace(` `,`T`).slice(0,16);return D&&E.length===0?(0,G.jsx)(`div`,{className:`h-full flex items-center justify-center`,children:(0,G.jsx)(x,{})}):(0,G.jsxs)(`div`,{className:`h-full flex flex-col overflow-hidden bg-gray-50/30 dark:bg-gray-950/10 max-w-7xl mx-auto w-full pt-14`,children:[(0,G.jsx)(ie,{profileId:e,range:u,setRange:d,customRange:f,setCustomRange:p,nowStr:R,fetchLogs:F,isMobile:r,realtimeRefresh:c,setRealtimeRefresh:l,statusFilter:m,setStatusFilter:h,accessPointIdFilter:g,setAccessPointIdFilter:_,accessPoints:v,destCountryFilter:y,setDestCountryFilter:b,ispFilter:S,setIspFilter:C,searchQuery:w,setSearchQuery:T,stats:A,logRetentionDays:j,onExport:L,exporting:I}),(0,G.jsx)(se,{logs:E,loading:D,loadingMore:O,hasMore:k,realtimeRefresh:c,isMobile:r,searchQuery:w,scrollContainerRef:N,lastLogElementRef:P,prevLatestTimestamp:M,setSelectedLog:a,setIsDrawerOpen:s,logRetentionDays:j}),(0,G.jsx)(pe,{isDrawerOpen:o,setIsDrawerOpen:s,selectedLog:i,profileId:e,isMobile:r,onQuickAction:t})]})};export{Ce as LogsView};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/browser-BskSZoIg.js","assets/vendor-utils-D17P9mkD.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-DifRgRH3.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{i as e,r as t}from"./rolldown-runtime-C4Xdq4VV.js";import{S as n,b as r,x as i}from"./vendor-icons-other-Bme3ywH9.js";function a(){return typeof window<`u`&&window.PublicKeyCredential!==void 0&&typeof window.PublicKeyCredential==`function`}function o(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`);for(;t.length%4!=0;)t+=`=`;let n=atob(t),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return r}function s(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=``;for(let e=0;e<t.length;e++)n+=String.fromCharCode(t[e]);return btoa(n).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}async function c(e){if(!a())throw Error(`Passkeys are not supported by this browser.`);let t={...e,challenge:o(e.challenge),user:{...e.user,id:o(e.user.id)},excludeCredentials:(e.excludeCredentials||[]).map(e=>({...e,id:o(e.id)}))},n=await navigator.credentials.create({publicKey:t});if(!n)throw Error(`Credential creation was cancelled or failed.`);let r=n.response,i=r.getTransports?r.getTransports():[];return{id:n.id,rawId:s(n.rawId),response:{clientDataJSON:s(r.clientDataJSON),attestationObject:s(r.attestationObject),transports:i}}}async function l(e){if(!a())throw Error(`Passkeys are not supported by this browser.`);let t={...e,challenge:o(e.challenge),allowCredentials:(e.allowCredentials||[]).map(e=>({...e,id:o(e.id)}))},n=await navigator.credentials.get({publicKey:t});if(!n)throw Error(`Passkey authentication was cancelled.`);let r=n.response;return{id:n.id,rawId:s(n.rawId),response:{clientDataJSON:s(r.clientDataJSON),authenticatorData:s(r.authenticatorData),signature:s(r.signature),userHandle:r.userHandle?s(r.userHandle):null}}}var u=e(n(),1),d=e(r(),1);const f=({uri:e})=>{let n=(0,u.useRef)(null),[r,a]=(0,u.useState)(!1);return(0,u.useEffect)(()=>{!n.current||!e||i(()=>import(`./browser-BskSZoIg.js`).then(t(1)),__vite__mapDeps([0,1,2,3,4,5,6])).then(t=>{t.toCanvas(n.current,e,{width:200,margin:2,color:{dark:`#1a1a2e`,light:`#ffffff`}},e=>{e&&(console.error(e),a(!0))})}).catch(()=>a(!0))},[e]),r?(0,d.jsx)(`div`,{className:`w-50 h-50 border border-gray-200 rounded-lg flex flex-col items-center justify-center text-center p-4 text-xs text-gray-500`,children:(0,d.jsx)(`p`,{className:`break-all`,children:e})}):(0,d.jsx)(`canvas`,{ref:n,className:`rounded-lg border border-gray-100`})};export{c as i,a as n,l as r,f as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{At as t,C as n,O as r,St as i,Xt as a,_t as o,bt as s,dt as c,tt as l,vt as u,z as d}from"./vendor-react-DifRgRH3.js";import{S as f,b as p}from"./vendor-icons-other-Bme3ywH9.js";import{C as m,H as h,N as g,O as _,S as v,V as y,b,d as x,f as S,p as C,r as w,u as T,x as E,y as D}from"./vendor-ui-core-CCxBtqRD.js";import{_t as O}from"./vendor-utils-D17P9mkD.js";import{C as k,U as A,X as j,Xt as M,et as N,ft as P,it as F}from"./index-DLmOvLdX.js";var I=e(f(),1),L=e(p(),1);const R=({newRule:e,setNewRule:t,addRule:n})=>{let{t:r}=a();return(0,L.jsx)(E,{elevation:h.ONE,className:`mb-8 p-6`,children:(0,L.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,L.jsxs)(`div`,{className:`flex flex-col lg:flex-row justify-between gap-4 items-start lg:items-end`,children:[(0,L.jsx)(`div`,{className:`w-full lg:w-48`,children:(0,L.jsx)(C,{label:r(`rules.action`),labelFor:`rule-type`,children:(0,L.jsx)(x,{id:`rule-type`,fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),options:[{label:r(`rules.typeBlock`),value:`BLOCK`},{label:r(`rules.typeAllow`),value:`ALLOW`},{label:r(`rules.typeRedirect`),value:`REDIRECT`}]})})}),(0,L.jsx)(`div`,{className:`flex-1 w-full lg:w-48`,children:(0,L.jsx)(C,{label:r(`rules.pattern`),labelFor:`rule-pattern`,children:(0,L.jsx)(S,{id:`rule-pattern`,size:`large`,placeholder:r(`rules.patternPlaceholder`),value:e.pattern,onChange:n=>t({...e,pattern:n.target.value})})})}),e.type!==`REDIRECT`&&(0,L.jsx)(C,{label:``,labelFor:``,children:(0,L.jsx)(g,{intent:y.PRIMARY,size:`large`,icon:(0,L.jsx)(d,{size:18}),onClick:n,children:r(`rules.addRule`)})})]}),e.type===`REDIRECT`&&(0,L.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-200 dark:border-gray-700`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,L.jsx)(l,{size:16}),(0,L.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:r(`rules.redirectSettings`)})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,L.jsx)(C,{label:r(`rules.aRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.ipv4Placeholder`),value:e.v_a,onChange:n=>t({...e,v_a:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.aaaaRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.ipv6Placeholder`),value:e.v_aaaa,onChange:n=>t({...e,v_aaaa:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.cnameRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.cnamePlaceholder`),value:e.v_cname,onChange:n=>t({...e,v_cname:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.txtRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.txtPlaceholder`),value:e.v_txt,onChange:n=>t({...e,v_txt:n.target.value})})})]}),(0,L.jsx)(`div`,{className:`mt-6 pt-4 border-t border-gray-200 dark:border-gray-700 flex justify-end`,children:(0,L.jsx)(g,{intent:y.PRIMARY,large:!0,icon:(0,L.jsx)(d,{size:18}),onClick:n,text:r(`rules.saveRedirectRule`)})})]})]})})},z=({rules:e,startEdit:t,getBlockDetail:n})=>{let{t:l}=a(),[d,f]=(0,I.useState)(`created_at`),[p,m]=(0,I.useState)(`desc`),h=e=>{d===e?m(e=>e===`asc`?`desc`:`asc`):(f(e),m(e===`created_at`?`desc`:`asc`))},g=e=>e.type===`REDIRECT`?[e.v_a,e.v_aaaa,e.v_cname,e.v_txt].filter(Boolean).join(` `):e.type===`BLOCK`?n():l(`rules.detailAllow`,`Forward to upstream`),_=(0,I.useMemo)(()=>[...e].sort((e,t)=>{let n=0;switch(d){case`action`:n=e.type.localeCompare(t.type);break;case`pattern`:n=e.pattern.localeCompare(t.pattern);break;case`details`:n=g(e).localeCompare(g(t));break;case`created_at`:n=(e.created_at??e.id)-(t.created_at??t.id);break}return n===0&&(n=e.id-t.id),p===`asc`?n:-n}),[e,d,p,n,l]),v=[{key:`action`,header:l(`rules.tableAction`),headerClassName:`w-32`,render:e=>(0,L.jsxs)(L.Fragment,{children:[e.type===`BLOCK`&&(0,L.jsx)(w,{intent:y.DANGER,minimal:!0,icon:(0,L.jsx)(r,{size:12,className:`mr-1`}),children:l(`rules.labelBlock`)}),e.type===`ALLOW`&&(0,L.jsx)(w,{intent:y.SUCCESS,minimal:!0,icon:(0,L.jsx)(c,{size:12,className:`mr-1`}),children:l(`rules.labelAllow`)}),e.type===`REDIRECT`&&(0,L.jsx)(w,{intent:y.WARNING,minimal:!0,icon:(0,L.jsx)(s,{size:12,className:`mr-1`}),children:l(`rules.labelRedirect`)})]})},{key:`pattern`,header:l(`rules.tablePattern`),headerClassName:`w-1/4`,cellClassName:`font-mono font-bold`,render:e=>e.pattern},{key:`details`,header:l(`rules.tableDetails`),cellClassName:`py-2`,render:e=>(0,L.jsx)(L.Fragment,{children:e.type===`REDIRECT`?(0,L.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.v_a&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`A: `,e.v_a]}),e.v_aaaa&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`AAAA: `,e.v_aaaa]}),e.v_cname&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`CNAME: `,e.v_cname]}),e.v_txt&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`TXT: `,e.v_txt]})]}):e.type===`BLOCK`?(0,L.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,L.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:l(`rules.detailBlock`)}),(0,L.jsx)(w,{minimal:!0,round:!0,className:`text-[9px] px-1.5 opacity-70`,children:n()})]}):(0,L.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:l(`rules.detailAllow`)})})},{key:`created_at`,header:l(`rules.tableCreatedAt`,`添加时间`),headerClassName:`w-44`,cellClassName:`text-xs text-gray-500 align-middle`,render:e=>e.created_at?k(new Date(e.created_at*1e3)):`—`}];return(0,L.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,L.jsxs)(T,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,L.jsx)(`thead`,{children:(0,L.jsx)(`tr`,{children:v.map(e=>(0,L.jsx)(`th`,{onClick:()=>h(e.key),className:O(e.headerClassName,`cursor-pointer select-none transition-colors hover:text-blue-500`),title:l(`rules.clickToSort`,`点击排序`),children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`span`,{children:e.header}),d===e.key?p===`asc`?(0,L.jsx)(o,{size:13,className:`text-blue-500 shrink-0`}):(0,L.jsx)(i,{size:13,className:`text-blue-500 shrink-0`}):(0,L.jsx)(u,{size:12,className:`opacity-30 hover:opacity-75 shrink-0`})]})},e.key))})}),(0,L.jsx)(`tbody`,{children:_.map(e=>(0,L.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:v.map(t=>(0,L.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},B=({editRule:e,setEditRule:t,saveEditRule:r,cancelEdit:i,deleteRule:o})=>{let{t:s}=a();return(0,L.jsxs)(_,{isOpen:!!e,onClose:i,title:s(`rules.editRule`,`Edit Rule`),style:{width:`600px`},children:[(0,L.jsx)(b,{children:e&&(0,L.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,L.jsxs)(`div`,{className:`flex gap-4`,children:[(0,L.jsx)(C,{label:s(`rules.action`),className:`w-40 mb-0`,children:(0,L.jsx)(x,{fill:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),options:[{label:s(`rules.typeBlock`),value:`BLOCK`},{label:s(`rules.typeAllow`),value:`ALLOW`},{label:s(`rules.typeRedirect`),value:`REDIRECT`}]})}),(0,L.jsx)(C,{label:s(`rules.pattern`),className:`flex-1 mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.patternPlaceholder`),value:e.pattern,onChange:n=>t({...e,pattern:n.target.value})})})]}),e.type===`REDIRECT`&&(0,L.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,L.jsx)(l,{size:14}),(0,L.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:s(`rules.redirectSettings`)})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,L.jsx)(C,{label:s(`rules.aRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.ipv4Placeholder`),value:e.v_a||``,onChange:n=>t({...e,v_a:n.target.value})})}),(0,L.jsx)(C,{label:s(`rules.aaaaRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.ipv6Placeholder`),value:e.v_aaaa||``,onChange:n=>t({...e,v_aaaa:n.target.value})})}),(0,L.jsx)(C,{label:s(`rules.cnameRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.cnamePlaceholder`),value:e.v_cname||``,onChange:n=>t({...e,v_cname:n.target.value})})}),(0,L.jsx)(C,{label:s(`rules.txtRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.txtPlaceholder`),value:e.v_txt||``,onChange:n=>t({...e,v_txt:n.target.value})})})]})]})]})}),(0,L.jsx)(D,{actions:(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(g,{onClick:i,children:s(`rules.cancel`,`Cancel`)}),(0,L.jsx)(g,{intent:y.PRIMARY,onClick:r,children:s(`rules.saveChanges`,`Save Changes`)})]}),children:(0,L.jsx)(g,{icon:(0,L.jsx)(n,{size:14}),intent:y.DANGER,text:s(`rules.delete`,`Delete`),onClick:()=>{e&&o(e.id)}})})]})},V=({profileId:e,prefill:n,onPrefillUsed:r,toasterRef:i})=>{let o=t(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(null),[,d]=(0,I.useState)(!0),{t:f}=a(),p=M(),[h,_]=(0,I.useState)({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),[b,x]=(0,I.useState)(null);(0,I.useEffect)(()=>{n&&(_({type:n.type,pattern:n.domain,v_a:n.recordType===`A`?`0.0.0.0`:``,v_aaaa:n.recordType===`AAAA`?`::`:``,v_txt:n.recordType===`TXT`?`Pre-filled`:``,v_cname:n.recordType===`CNAME`?`target.com`:``}),r?.())},[n,r]);let S=async()=>{d(!0);try{let[t,n]=await Promise.all([F(e),N(e)]);c(t),u(JSON.parse(n.settings||`{}`))}catch(e){console.error(`Failed to fetch data`,e)}finally{d(!1)}};return(0,I.useEffect)(()=>{S()},[e]),(0,L.jsxs)(`div`,{className:O(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,p?`p-1`:`px-8`),children:[(0,L.jsx)(`div`,{className:`mb-8`,children:(0,L.jsx)(`div`,{className:`flex flex-col md:flex-row justify-between items-start gap-4`,children:(0,L.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[p?(0,L.jsxs)(m,{minimal:!0,fill:p,children:[(0,L.jsx)(g,{active:!0,onClick:()=>o(`/dash/${e}/rules`),text:f(`rules.title`),large:!0}),(0,L.jsx)(g,{active:!1,onClick:()=>o(`/dash/${e}/filter`),text:f(`filtering.title`),large:!0})]}):(0,L.jsx)(`h1`,{className:`bp6-heading`,children:f(`rules.title`)}),(0,L.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:f(`rules.subtitle`)})]})})}),(0,L.jsx)(R,{newRule:h,setNewRule:_,addRule:async()=>{let t=h.pattern.trim();if(!t){i?.current?.show({message:f(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:y.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.pattern.trim().toLowerCase()===n)){i?.current?.show({message:f(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:y.DANGER});return}try{await A(e,{...h,pattern:t}),i?.current?.show({message:f(`rules.addSuccess`,`Rule added successfully`),intent:y.SUCCESS}),_({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),S()}catch(e){i?.current?.show({message:e.message||f(`rules.addFailed`,`Failed to add rule`),intent:y.DANGER})}}}),s.length===0?(0,L.jsx)(v,{title:f(`rules.noRulesTitle`),children:f(`rules.noRulesDesc`)}):(0,L.jsx)(z,{rules:s,startEdit:e=>{x({...e})},getBlockDetail:()=>{if(!l)return f(`rules.detailBlock`);switch(l.block_mode||`NULL_IP`){case`NXDOMAIN`:return`NXDOMAIN`;case`NODATA`:return`NODATA`;case`CUSTOM_IP`:return`${l.custom_block_ipv4||`0.0.0.0`} / ${l.custom_block_ipv6||`::`}`;default:return`0.0.0.0 / ::`}}}),(0,L.jsx)(B,{editRule:b,setEditRule:x,saveEditRule:async()=>{if(!b)return;let t=b.pattern.trim();if(!t){i?.current?.show({message:f(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:y.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.id!==b.id&&e.pattern.trim().toLowerCase()===n)){i?.current?.show({message:f(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:y.DANGER});return}try{await P(e,{...b,pattern:t}),i?.current?.show({message:f(`rules.updateSuccess`,`Rule updated successfully`),intent:y.SUCCESS}),x(null),S()}catch(e){i?.current?.show({message:e.message||f(`rules.updateFailed`,`Failed to update rule`),intent:y.DANGER})}},cancelEdit:()=>{x(null)},deleteRule:async t=>{try{await j(e,t)}catch(e){console.error(e)}x(null),S()}})]})};export{V as RulesView};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{B as t,D as n,J as r,P as i,Xt as a,Z as o,at as s,mt as c,ot as l,tt as u,ut as d,v as f,wt as p,y as m}from"./vendor-react-DifRgRH3.js";import{S as h,b as g}from"./vendor-icons-other-Bme3ywH9.js";import{B as _,E as v,H as y,M as b,N as x,P as S,S as C,T as w,V as T,_ as E,d as D,f as O,h as k,p as A,r as j,v as M,w as N,x as P}from"./vendor-ui-core-CCxBtqRD.js";import{F,N as I,et as L,it as R,ot as z,pt as B,s as V,tt as H,ut as U}from"./index-DLmOvLdX.js";var W=e(h(),1),G=e(g(),1);const K=({profile:e,isEditingName:n,setIsEditingName:r,editName:i,setEditName:o,updateProfileName:s,exportProfile:u})=>{let{t:d}=a(),[f,p]=(0,W.useState)(!1);return(0,G.jsxs)(`div`,{className:`mb-6 flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col justify-start`,children:[n?(0,G.jsxs)(`div`,{className:`flex items-center gap-2 mb-1`,children:[(0,G.jsx)(M,{content:d(`common.profileNameFormatTip`,`Profile Name tip: 1-30 characters, duplicates not allowed`),isOpen:f,position:_.TOP,intent:T.PRIMARY,className:`flex-1`,children:(0,G.jsx)(`div`,{className:`w-full block`,children:(0,G.jsx)(O,{value:i,onChange:e=>o(e.target.value),onFocus:()=>p(!0),onBlur:()=>p(!1),autoFocus:!0,onKeyDown:t=>{t.key===`Enter`&&s(),t.key===`Escape`&&(r(!1),o(e?.name||``))}})})}),(0,G.jsx)(x,{icon:(0,G.jsx)(c,{size:16}),intent:T.SUCCESS,minimal:!0,onClick:s,disabled:!V.test(i)}),(0,G.jsx)(x,{icon:(0,G.jsx)(m,{size:16}),minimal:!0,onClick:()=>{r(!1),o(e?.name||``)}})]}):(0,G.jsxs)(`div`,{className:`group flex items-center gap-2 mb-1 cursor-pointer`,onClick:()=>r(!0),children:[(0,G.jsx)(`h2`,{className:`bp6-heading mb-0`,children:e?.name}),(0,G.jsx)(x,{icon:(0,G.jsx)(t,{size:14}),minimal:!0,className:`opacity-30 group-hover:opacity-100 transition-opacity`})]}),(0,G.jsx)(`p`,{className:`bp6-text-muted`,children:d(`settings.subtitle`)})]}),(0,G.jsx)(`div`,{className:`flex gap-2 items-center`,children:(0,G.jsx)(x,{size:`large`,icon:(0,G.jsx)(l,{size:18}),text:d(`settings.export`,`导出配置`),onClick:u})})]})},q=()=>{let{t:e}=a(),[t,n]=(0,W.useState)([]);return(0,W.useEffect)(()=>{F().then(t=>{t&&Array.isArray(t)&&n(t.map(t=>({label:e(t.label),url:t.url})))}).catch(e=>console.warn(`Failed to fetch preset upstreams from API`,e))},[e]),t},J=(e,t)=>{let{t:n}=a();return(0,W.useMemo)(()=>{let e=[{label:n(`settings.retentionDisabled`,`关闭 (隐私需要)`),value:0},{label:n(`settings.retention10m`,`10 分钟`),value:.007},{label:n(`settings.retention1h`),value:.0416},{label:n(`settings.retention24h`),value:1},{label:n(`settings.retention7d`),value:7},{label:n(`settings.retention30d`),value:30},{label:n(`settings.retention90d`),value:90}],r=t>0?t:30,i=e.filter(e=>e.value<=r);return i.length>0?i:[e[0]]},[n,t])},Y=({settings:e,setSettings:t})=>{let{t:n}=a(),r=(0,G.jsx)(v,{className:`min-w-96`,children:q().map((n,r)=>(0,G.jsx)(N,{text:n.label,onClick:()=>t({...e,upstream:[n.url]}),labelElement:(0,G.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,G.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-64 truncate`,title:n.url,children:n.url})})},r))});return(0,G.jsxs)(P,{elevation:y.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,G.jsxs)(b,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,G.jsx)(i,{size:18,className:`text-blue-500`}),` `,n(`settings.upstreamTitle`)]}),(0,G.jsx)(A,{label:`DoH (https://) / DoT (tls://) / DNS Stamp (sdns://) / ${n(`settings.classicDns`)}`,children:(0,G.jsx)(O,{fill:!0,placeholder:`https://... | tls://... | sdns://... | 1.1.1.1`,value:e.upstream?.[0]||``,onChange:n=>t({...e,upstream:[n.target.value]}),onFocus:e=>e.target.select(),rightElement:(0,G.jsx)(w,{content:r,placement:`bottom-end`,animation:`minimal`,arrow:!1,children:(0,G.jsx)(x,{variant:`minimal`,icon:`chevron-down`})})})}),(0,G.jsx)(`p`,{className:`text-xs opacity-60`,children:n(`settings.upstreamDesc`)})]})},X=({settings:e,setSettings:t})=>{let{t:r}=a();return(0,G.jsxs)(P,{elevation:y.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,G.jsxs)(b,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,G.jsx)(n,{size:18,className:`text-green-500`}),` `,r(`settings.defaultPolicyTitle`)]}),(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(A,{label:r(`settings.onNoMatch`),children:(0,G.jsxs)(D,{fill:!0,value:e.default_policy,onChange:n=>t({...e,default_policy:n.target.value}),children:[(0,G.jsx)(`option`,{value:`ALLOW`,children:r(`settings.allowAll`)}),(0,G.jsx)(`option`,{value:`BLOCK`,children:r(`settings.blockAll`)})]})}),(0,G.jsx)(E,{}),(0,G.jsx)(A,{label:r(`settings.blockModeTitle`),helperText:r(`settings.blockModeDesc`),children:(0,G.jsxs)(D,{fill:!0,value:e.block_mode||`NULL_IP`,onChange:n=>t({...e,block_mode:n.target.value}),children:[(0,G.jsxs)(`option`,{value:`NULL_IP`,children:[`0.0.0.0 / :: (`,r(`settings.default`),`)`]}),(0,G.jsxs)(`option`,{value:`NXDOMAIN`,children:[`NXDOMAIN (`,r(`settings.NXDOMAIN`),`)`]}),(0,G.jsxs)(`option`,{value:`NODATA`,children:[`NODATA (`,r(`settings.NODATA`),`)`]}),(0,G.jsx)(`option`,{value:`CUSTOM_IP`,children:r(`settings.customIP`)})]})}),e.block_mode===`CUSTOM_IP`&&(0,G.jsxs)(`div`,{className:`space-y-2 animate-in fade-in slide-in-from-top-1`,children:[(0,G.jsx)(O,{placeholder:`IPv4: 127.0.0.1`,value:e.custom_block_ipv4||``,onChange:n=>t({...e,custom_block_ipv4:n.target.value})}),(0,G.jsx)(O,{placeholder:`IPv6: ::1`,value:e.custom_block_ipv6||``,onChange:n=>t({...e,custom_block_ipv6:n.target.value})})]})]})]})},Z=({settings:e,setSettings:t,isAdmin:n,maxRetentionDays:r})=>{let{t:i}=a(),o=J(n,r);W.useEffect(()=>{if(r>0&&e.log_retention_days>r&&o.length>0){let n=o[o.length-1];n&&e.log_retention_days!==n.value&&t({...e,log_retention_days:n.value})}},[r,e.log_retention_days,o,t]);let s=e.log_retention_days===0;return(0,G.jsxs)(P,{elevation:y.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,G.jsxs)(b,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,G.jsx)(d,{size:18,className:`text-purple-500`}),` `,i(`settings.logRetentionTitle`)]}),(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(A,{label:i(`settings.retentionDuration`),children:(0,G.jsx)(D,{fill:!0,value:e.log_retention_days,onChange:n=>t({...e,log_retention_days:parseFloat(n.target.value)}),children:o.map(e=>(0,G.jsx)(`option`,{value:e.value,children:e.label},e.value))})}),(0,G.jsx)(`p`,{className:`text-xs opacity-60`,children:s?i(`settings.retentionDisabledDesc`,`已关闭日志记录。系统将不会记录任何 DNS 查询日志并立即清空历史日志。`):i(`settings.retentionDesc`)}),(0,G.jsxs)(`div`,{className:`pt-3 border-t border-gray-100 dark:border-gray-800/80`,children:[(0,G.jsx)(k,{label:i(`settings.skipLogOnPass`,`不记录放行记录`),checked:!s&&!!e.skip_log_on_pass,disabled:s,onChange:n=>t({...e,skip_log_on_pass:n.currentTarget.checked})}),(0,G.jsx)(`p`,{className:`text-xs opacity-60 mt-1`,children:i(`settings.skipLogOnPassDesc`,`启用后不记录正常放行的 DNS 查询,仅记录被拦截、重定向或解析失败的记录。可大幅减少存储占用与写操作。`)})]})]})]})},Q=({settings:e,setSettings:t})=>{let{t:n}=a();return(0,G.jsxs)(P,{elevation:y.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,G.jsxs)(b,{className:`flex items-center gap-2 mb-3 font-bold`,children:[(0,G.jsx)(u,{size:18,className:`text-orange-500`}),` `,n(`settings.ecsTitle`)]}),(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(k,{label:n(`settings.sendEcs`),checked:e.ecs.enabled,onChange:n=>t({...e,ecs:{...e.ecs,enabled:n.currentTarget.checked}})}),(0,G.jsx)(k,{label:n(`settings.customSubnet`),disabled:!e.ecs.enabled,checked:!e.ecs.use_client_ip,onChange:n=>t({...e,ecs:{...e.ecs,use_client_ip:!n.currentTarget.checked}})}),(0,G.jsxs)(`div`,{className:`space-y-3 pt-2 border-t border-gray-100 dark:border-gray-800`,children:[(0,G.jsx)(A,{label:n(`settings.customIpv4`),labelInfo:n(`settings.ipv4Hint`),disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),children:(0,G.jsx)(O,{placeholder:`0.0.0.0/0`,value:e.ecs.ipv4_cidr||``,disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),onChange:n=>t({...e,ecs:{...e.ecs,ipv4_cidr:n.target.value}})})}),(0,G.jsx)(A,{label:n(`settings.customIpv6`),labelInfo:n(`settings.ipv6Hint`),disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),children:(0,G.jsx)(O,{placeholder:`::/0`,value:e.ecs.ipv6_cidr||``,disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),onChange:n=>t({...e,ecs:{...e.ecs,ipv6_cidr:n.target.value}})})})]}),(0,G.jsx)(`p`,{className:`text-xs opacity-60`,children:n(`settings.ecsUpstreamHint`)})]})]})};var $=[{domain:`cloudflare-ech.com`,isPreferred:!0},{domain:`crypto.cloudflare.com`,isPreferred:!1},{domain:`one.one.one.one`,isPreferred:!1},{domain:`www.cloudflare.com`,isPreferred:!1},{domain:`encryptedsni.com`,isPreferred:!1},{domain:`cdnjs.com`,isPreferred:!1}];const ee=({settings:e,setSettings:t})=>{let{t:n}=a(),[r,i]=W.useState($);W.useEffect(()=>{I().then(e=>{Array.isArray(e)&&e.length>0&&i(e.map(e=>typeof e==`string`?{domain:e,isPreferred:e===`cloudflare-ech.com`}:{domain:e.domain,isPreferred:!!e.isPreferred}))}).catch(e=>console.warn(`Failed to fetch preset ECH fronting domains from API`,e))},[]);let c=typeof e.best_effort_ech==`boolean`?e.best_effort_ech:!!e.best_effort_ech?.enabled,l=typeof e.best_effort_ech==`object`&&e.best_effort_ech?.fronting_domain?e.best_effort_ech.fronting_domain:`cloudflare-ech.com`,u=n=>{t({...e,best_effort_ech:{enabled:n,fronting_domain:l||`cloudflare-ech.com`}})},d=n=>{t({...e,best_effort_ech:{enabled:c,fronting_domain:n}})},f=(0,G.jsx)(v,{className:`min-w-72`,children:r.map(e=>(0,G.jsx)(N,{text:e.domain,onClick:()=>d(e.domain),labelElement:e.isPreferred?(0,G.jsx)(j,{minimal:!0,intent:T.PRIMARY,className:`text-[10px]`,children:n(`settings.echPreferred`,`首选`)}):void 0},e.domain))});return(0,G.jsxs)(P,{elevation:y.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,G.jsxs)(b,{className:`flex items-center gap-2 m-0 font-bold text-purple-600 dark:text-purple-400`,children:[(0,G.jsx)(o,{size:18}),` `,n(`settings.echTitle`)]}),(0,G.jsx)(w,{placement:`bottom-end`,usePortal:!0,content:(0,G.jsxs)(`div`,{className:`p-4 max-w-sm`,children:[(0,G.jsx)(b,{children:n(`settings.whatIsEch`,`何为 ECH (Encrypted Client Hello)?`)}),(0,G.jsx)(`p`,{className:`text-sm mb-2`,children:n(`settings.echHelpDesc`)}),(0,G.jsxs)(`ul`,{className:`list-disc list-inside text-sm opacity-80 mb-3 space-y-1`,children:[(0,G.jsx)(`li`,{children:n(`settings.echHelpBenefit1`)}),(0,G.jsx)(`li`,{children:n(`settings.echHelpBenefit2`)})]}),(0,G.jsx)(`div`,{className:`text-xs border-t border-gray-100 dark:border-gray-700 pt-2`,children:(0,G.jsxs)(`a`,{href:`https://en.wikipedia.org/wiki/Encrypted_Client_Hello`,target:`_blank`,rel:`noreferrer`,className:`flex items-center gap-1 text-blue-500 hover:underline`,children:[(0,G.jsx)(s,{size:10}),` `,n(`setup.learnMore`,`了解更多`)]})})]}),children:(0,G.jsx)(x,{icon:`help`,variant:`minimal`,intent:T.NONE})})]}),(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(k,{label:n(`settings.enableEch`,`启用重写 ECH`),checked:c,onChange:e=>u(e.currentTarget.checked)}),(0,G.jsx)(`p`,{className:`text-xs opacity-60 leading-relaxed`,children:n(`settings.echDesc`,`针对由 Cloudflare 代理的域名,当查询 HTTPS (Type 65) 或 SVCB (Type 64) 记录且上游未配置 ECH 时,自动重写注入 ECH 参数以保护 SNI 隐私。`)}),c&&(0,G.jsx)(`div`,{className:`space-y-3 pt-3 border-t border-gray-100 dark:border-gray-800`,children:(0,G.jsx)(A,{label:n(`settings.echFrontingTitle`,`表层 SNI (ECH Fronting)`),labelInfo:(0,G.jsx)(`span`,{className:`text-xs opacity-60`,children:n(`settings.echFrontingDesc`,`TLS 握手外层可见的伪装域名`)}),children:(0,G.jsx)(O,{fill:!0,placeholder:n(`settings.echFrontingCustomPlaceholder`,`输入自定义表层域名,例如 crypto.cloudflare.com`),value:l,onChange:e=>d(e.target.value),onFocus:e=>e.target.select(),className:`font-mono text-sm`,rightElement:(0,G.jsx)(w,{content:f,placement:`bottom-end`,animation:`minimal`,arrow:!1,children:(0,G.jsx)(x,{variant:`minimal`,icon:`chevron-down`})})})})})]})]})},te=({testInput:e,setTestInput:t,handleDnsTest:n,testing:i,testResult:o})=>{let{t:s}=a();return(0,G.jsxs)(P,{elevation:y.TWO,className:`dark:bg-gray-900 border-t-2 border-blue-500`,children:[(0,G.jsxs)(b,{className:`flex items-center gap-2 mb-6 font-bold`,children:[(0,G.jsx)(f,{size:20,className:`text-yellow-500 fill-yellow-500`}),` `,s(`settings.testToolTitle`)]}),(0,G.jsxs)(`div`,{className:`flex flex-col space-y-6`,children:[(0,G.jsx)(A,{label:s(`settings.testDomain`),className:`mb-0`,children:(0,G.jsx)(O,{fill:!0,large:!0,placeholder:s(`settings.domainPlaceholder`),value:e.domain,onChange:n=>t({...e,domain:n.target.value}),onKeyDown:e=>e.key===`Enter`&&n()})}),(0,G.jsxs)(`div`,{className:`flex justify-end gap-4 items-end`,children:[(0,G.jsx)(A,{label:s(`settings.recordType`),className:`w-32 mb-0`,children:(0,G.jsxs)(D,{fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),children:[(0,G.jsx)(`option`,{value:`A`,children:`A`}),(0,G.jsx)(`option`,{value:`AAAA`,children:`AAAA`}),(0,G.jsx)(`option`,{value:`CNAME`,children:`CNAME`}),(0,G.jsx)(`option`,{value:`TXT`,children:`TXT`})]})}),(0,G.jsx)(A,{label:`\xA0`,className:`mb-0`,children:(0,G.jsx)(x,{size:`large`,intent:T.PRIMARY,icon:`search`,text:s(`settings.runTest`),onClick:n,loading:i})})]}),o&&(0,G.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-100 dark:border-gray-800 space-y-6 animate-in fade-in slide-in-from-top-4`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap gap-4 items-center`,children:[(0,G.jsx)(j,{large:!0,round:!0,intent:o.action===`PASS`?T.SUCCESS:o.action===`BLOCK`?T.DANGER:T.WARNING,className:`px-4 font-bold`,children:o.action}),(0,G.jsxs)(`div`,{className:`flex flex-col`,children:[(0,G.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40`,children:s(`settings.hitRule`)}),(0,G.jsx)(`span`,{className:`text-sm font-bold`,children:o.reason||s(`settings.defaultAllow`)})]}),(0,G.jsxs)(`div`,{className:`flex flex-col border-l border-gray-200 dark:border-gray-700 pl-4`,children:[(0,G.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40`,children:s(`settings.parseLatency`)}),(0,G.jsx)(`span`,{className:`text-sm font-mono font-bold`,children:o.latency?`${o.latency}ms`:`-`})]}),o.timings&&(0,G.jsx)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-1 border-l border-gray-200 dark:border-gray-700 pl-4 max-w-md`,children:Object.entries(o.timings).map(([e,t])=>(0,G.jsxs)(`div`,{className:`flex gap-1 items-baseline`,children:[(0,G.jsxs)(`span`,{className:`text-[9px] opacity-40 uppercase font-mono`,children:[e,`:`]}),(0,G.jsxs)(`span`,{className:`text-[10px] font-mono font-bold`,children:[t,`ms`]})]},e))}),(0,G.jsx)(E,{}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2 bg-white dark:bg-gray-900 px-3 py-1.5 rounded-lg shadow-sm border border-gray-100 dark:border-gray-800`,children:[(0,G.jsx)(r,{size:14,className:`text-red-500`}),(0,G.jsxs)(`div`,{className:`flex flex-col`,children:[(0,G.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40 leading-none`,children:s(`settings.sourceIp`)}),(0,G.jsxs)(`span`,{className:`text-xs font-mono`,children:[o.client_ip,` (`,o.geo_country,`)`]})]})]})]}),(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(`div`,{className:`text-[10px] uppercase font-bold opacity-40 flex items-center gap-1`,children:[(0,G.jsx)(p,{size:10}),` `,s(`settings.answerSection`)]}),(0,G.jsx)(`div`,{className:`font-mono text-sm leading-relaxed bg-white dark:bg-gray-900 p-4 rounded-xl border border-gray-100 dark:border-gray-800 shadow-inner`,children:o.answers&&o.answers.length>0?o.answers.map((e,t)=>(0,G.jsxs)(`div`,{className:`flex gap-4 py-1 border-b border-gray-50 dark:border-gray-800 last:border-0 hover:bg-blue-50/50 dark:hover:bg-blue-900/10 transition-colors px-2`,children:[(0,G.jsx)(`span`,{className:`w-16 font-bold text-blue-500`,children:e.type}),(0,G.jsx)(`span`,{className:`flex-1 dark:text-gray-300`,children:e.data}),(0,G.jsxs)(`span`,{className:`text-[10px] opacity-30 italic`,children:[`TTL: `,e.ttl,`s`]})]},t)):(0,G.jsx)(`div`,{className:`p-4 opacity-40 italic text-center`,children:s(`settings.noRecordsReturned`)})})]}),o.diagnostics&&(0,G.jsx)(C,{minimal:!0,intent:o.action===`FAIL`?T.DANGER:T.NONE,className:`text-xs font-mono`,children:(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,G.jsx)(`span`,{className:`font-bold uppercase tracking-wider`,children:s(`settings.diagnostics`)}),(0,G.jsx)(`span`,{className:`font-bold`,children:o.action===`FAIL`?o.diagnostics.status>0?`HTTP ${o.diagnostics.status}${o.diagnostics.status_text?` (${o.diagnostics.status_text})`:``}`:`Network / Connection Error`:o.diagnostics.method===`POST`||o.diagnostics.method===`GET`?`HTTP ${o.diagnostics.status}${o.diagnostics.status_text?` (${o.diagnostics.status_text})`:``}`:`Connected (OK)`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2 text-xs opacity-80`,children:[(0,G.jsx)(`span`,{className:`px-1.5 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-[10px] font-bold`,children:o.diagnostics.method}),(0,G.jsx)(`span`,{className:`break-all`,children:o.diagnostics.upstream_url})]}),o.diagnostics.cf_ray&&(0,G.jsxs)(`div`,{className:`text-[11px] opacity-75`,children:[`CF-Ray: `,(0,G.jsx)(`span`,{className:`font-bold`,children:o.diagnostics.cf_ray})]}),o.diagnostics.error_detail&&o.action===`FAIL`&&(0,G.jsxs)(`div`,{className:`p-2 bg-red-50 dark:bg-red-950/40 rounded border border-red-200 dark:border-red-900/50 text-red-700 dark:text-red-300 break-words`,children:[(0,G.jsxs)(`div`,{className:`font-bold mb-0.5`,children:[s(`settings.errorDetail`),`:`]}),(0,G.jsx)(`div`,{children:o.diagnostics.error_detail})]}),o.diagnostics.response_body&&(0,G.jsxs)(`div`,{className:`p-2 bg-gray-100 dark:bg-gray-900 rounded border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300 break-words text-[11px]`,children:[(0,G.jsxs)(`div`,{className:`font-bold mb-0.5 opacity-60`,children:[s(`settings.upstreamResponse`),`:`]}),(0,G.jsx)(`div`,{className:`line-clamp-3`,children:o.diagnostics.response_body})]})]})})]})]})]})},ne=({profileId:e,toasterRef:t,currentUser:n,onSavingChange:r})=>{let[i,o]=(0,W.useState)(null),[s,c]=(0,W.useState)(null),[l,u]=(0,W.useState)(!0),[d,f]=(0,W.useState)(!1),{t:p}=a();(0,W.useEffect)(()=>(r?.(d),()=>{r?.(!1)}),[d,r]);let m=(0,W.useRef)(!0),h=(0,W.useRef)(null),[g,_]=(0,W.useState)(!1),[v,y]=(0,W.useState)(``),[b,x]=(0,W.useState)({domain:`o-o.myaddr.l.google.com`,type:`TXT`}),[C,w]=(0,W.useState)(null),[E,D]=(0,W.useState)(!1);(0,W.useEffect)(()=>{(async()=>{try{let t=await L(e);return o(t),y(t.name),c(JSON.parse(t.settings)),i}catch(e){console.error(e)}finally{u(!1)}})()},[e]),(0,W.useEffect)(()=>{if(!l&&s){let e=setTimeout(()=>{m.current=!1},500);return()=>clearTimeout(e)}},[l,s]),(0,W.useEffect)(()=>()=>{h.current&&clearTimeout(h.current)},[]);let O=async()=>{if(!v||v===i?.name){_(!1);return}try{await z(e,v),o(e=>e?{...e,name:v}:null),_(!1),t?.current?.show({message:p(`settings.nameUpdateSuccess`,`名称已更新`),intent:T.SUCCESS})}catch(e){console.error(e);let n=e.message,r=n;n===`The profile name already exists`?r=p(`common.profileNameExists`,`The profile name already exists`):n===`Invalid Profile Name format`&&(r=p(`common.profileNameFormatError`,`Invalid Profile Name format`)),t?.current?.show({message:r||p(`settings.nameUpdateFailed`,`更新失败`),intent:T.DANGER})}},k=(0,W.useCallback)(async n=>{if(n){f(!0);try{await B(e,n)}catch(e){console.error(e),t?.current?.show({message:p(`settings.saveError`),intent:T.DANGER,icon:`error`})}finally{f(!1)}}},[e,t,p]),A=(0,W.useCallback)(e=>{h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{k(e)},600)},[k]),j=(0,W.useCallback)(e=>{c(e),m.current||A(e)},[A]);return l||!s?(0,G.jsx)(`div`,{className:`p-20 flex justify-center`,children:(0,G.jsx)(S,{})}):(0,G.jsxs)(`div`,{className:`p-0 sm:px-4 lg:px-8 max-w-5xl mx-auto space-y-8 pb-20`,children:[(0,G.jsx)(K,{profile:i,isEditingName:g,setIsEditingName:_,editName:v,setEditName:y,updateProfileName:O,exportProfile:async()=>{if(!(!i||!s))try{let[n,r]=await Promise.all([R(e).catch(()=>[]),H(e).catch(()=>[])]),a=new Set,o=(n||[]).filter(e=>{let t=(e.pattern||``).trim().toLowerCase();return!t||a.has(t)?!1:(a.add(t),!0)}),c=new Set,l=(r||[]).filter(e=>{let t=(e.url||``).trim().toLowerCase();return!t||c.has(t)?!1:(c.add(t),!0)}).map(e=>({url:e.url,enabled:!!e.enabled})),u={version:2,name:i.name,settings:s,rules:o,filters:l,exported_at:Math.floor(Date.now()/1e3)},d=new Blob([JSON.stringify(u,null,2)],{type:`application/json`}),f=URL.createObjectURL(d),m=document.createElement(`a`);m.href=f,m.download=`dns-worker-${i.name||e}.json`,document.body.appendChild(m),m.click(),document.body.removeChild(m),URL.revokeObjectURL(f),t?.current?.show({message:p(`settings.exportSuccess`,`配置成功导出`),intent:T.SUCCESS,icon:`download`})}catch(e){console.error(e),t?.current?.show({message:p(`settings.exportError`,`导出失败`),intent:T.DANGER,icon:`error`})}}}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,G.jsx)(Y,{settings:s,setSettings:j}),(0,G.jsx)(X,{settings:s,setSettings:j}),(0,G.jsx)(Z,{settings:s,setSettings:j,isAdmin:n?.role===`admin`,maxRetentionDays:n?.max_log_retention_days??(n?.role===`admin`?30:7)}),(0,G.jsx)(Q,{settings:s,setSettings:j}),(0,G.jsx)(ee,{settings:s,setSettings:j})]}),(0,G.jsx)(te,{testInput:b,setTestInput:x,handleDnsTest:async()=>{if(b.domain){D(!0),w(null);try{w(await U(e,b))}catch(e){console.error(e)}finally{D(!1)}}},testing:E,testResult:C})]})};export{ne as SettingsView};
|