@serve.zone/dcrouter 13.17.9 → 13.19.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.
Files changed (43) hide show
  1. package/dist_serve/bundle.js +6 -5
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/classes.dcrouter.d.ts +9 -5
  4. package/dist_ts/classes.dcrouter.js +152 -120
  5. package/dist_ts/config/classes.route-config-manager.d.ts +13 -5
  6. package/dist_ts/config/classes.route-config-manager.js +76 -36
  7. package/dist_ts/db/documents/classes.route.doc.d.ts +2 -0
  8. package/dist_ts/db/documents/classes.route.doc.js +11 -2
  9. package/dist_ts/email/classes.email-domain.manager.d.ts +7 -0
  10. package/dist_ts/email/classes.email-domain.manager.js +118 -55
  11. package/dist_ts/email/classes.smartmta-storage-manager.d.ts +13 -0
  12. package/dist_ts/email/classes.smartmta-storage-manager.js +101 -0
  13. package/dist_ts/email/email-dns-records.d.ts +14 -0
  14. package/dist_ts/email/email-dns-records.js +34 -0
  15. package/dist_ts/email/index.d.ts +2 -0
  16. package/dist_ts/email/index.js +3 -1
  17. package/dist_ts/opsserver/handlers/email-ops.handler.js +6 -15
  18. package/dist_ts/opsserver/handlers/route-management.handler.js +5 -7
  19. package/dist_ts/opsserver/handlers/stats.handler.js +41 -7
  20. package/dist_ts_interfaces/data/route-management.d.ts +2 -0
  21. package/dist_ts_migrations/index.js +25 -1
  22. package/dist_ts_web/00_commitinfo_data.js +1 -1
  23. package/dist_ts_web/appstate.js +13 -4
  24. package/dist_ts_web/elements/network/ops-view-routes.d.ts +2 -0
  25. package/dist_ts_web/elements/network/ops-view-routes.js +44 -21
  26. package/package.json +2 -2
  27. package/readme.md +190 -1543
  28. package/ts/00_commitinfo_data.ts +1 -1
  29. package/ts/classes.dcrouter.ts +190 -138
  30. package/ts/config/classes.route-config-manager.ts +97 -42
  31. package/ts/db/documents/classes.route.doc.ts +7 -0
  32. package/ts/email/classes.email-domain.manager.ts +136 -51
  33. package/ts/email/classes.smartmta-storage-manager.ts +108 -0
  34. package/ts/email/email-dns-records.ts +53 -0
  35. package/ts/email/index.ts +2 -0
  36. package/ts/opsserver/handlers/email-ops.handler.ts +5 -19
  37. package/ts/opsserver/handlers/route-management.handler.ts +4 -6
  38. package/ts/opsserver/handlers/stats.handler.ts +43 -7
  39. package/ts_apiclient/readme.md +69 -195
  40. package/ts_web/00_commitinfo_data.ts +1 -1
  41. package/ts_web/appstate.ts +16 -4
  42. package/ts_web/elements/network/ops-view-routes.ts +47 -29
  43. package/ts_web/readme.md +41 -242
@@ -42458,7 +42458,7 @@ Customer Support Team`}};async onActivate(b){this.appui=b.appui,this.appui.setCo
42458
42458
  }
42459
42459
  `];render(){return w`
42460
42460
  <dees-appui></dees-appui>
42461
- `}async firstUpdated(){let n=this.shadowRoot?.querySelector("dees-appui");n&&(n.configure({branding:{logoIcon:"lucide:Box",logoText:"serve.zone"},appBar:{showSearch:!0,breadcrumbs:"serve.zone",menuItems:[{name:"File",action:i(async()=>{},"action"),submenu:[{name:"New Service",shortcut:"Cmd+N",action:i(async()=>{console.log("New Service")},"action")},{name:"Import Configuration",action:i(async()=>{console.log("Import")},"action")},{name:"Export Configuration",action:i(async()=>{console.log("Export")},"action")},{divider:!0},{name:"Preferences",shortcut:"Cmd+,",action:i(async()=>{n.navigateToView("settings")},"action")}]},{name:"View",action:i(async()=>{},"action"),submenu:[{name:"Dashboard",shortcut:"Cmd+1",action:i(async()=>{n.navigateToView("dashboard")},"action")},{name:"Services",shortcut:"Cmd+2",action:i(async()=>{n.navigateToView("services")},"action")},{name:"Network",shortcut:"Cmd+3",action:i(async()=>{n.navigateToView("network")},"action")},{divider:!0},{name:"Activity Log",shortcut:"Cmd+Shift+A",action:i(async()=>{n.toggleActivityLog()},"action")},{name:"Toggle Sidebar",shortcut:"Cmd+B",action:i(async()=>{n.setMainMenuCollapsed(!n.mainmenuCollapsed)},"action")}]},{name:"Services",action:i(async()=>{},"action"),submenu:[{name:"Deploy New Service",action:i(async()=>{console.log("Deploy")},"action")},{name:"Start All",action:i(async()=>{console.log("Start all")},"action")},{name:"Stop All",action:i(async()=>{console.log("Stop all")},"action")},{divider:!0},{name:"Garbage Collect",action:i(async()=>{console.log("GC")},"action")}]},{name:"Help",action:i(async()=>{},"action"),submenu:[{name:"Documentation",action:i(async()=>{window.open("https://docs.serve.zone","_blank")},"action")},{name:"Release Notes",action:i(async()=>{console.log("Release notes")},"action")},{divider:!0},{name:"About serve.zone",action:i(async()=>{console.log("About")},"action")}]}]},views:[{id:"dashboard",name:"Dashboard",iconName:"lucide:LayoutDashboard",content:"sz-demo-view-dashboard"},{id:"services",name:"Services",iconName:"lucide:Server",content:"sz-demo-view-services"},{id:"network",name:"Network",iconName:"lucide:Network",content:"sz-demo-view-network"},{id:"registries",name:"Registries",iconName:"lucide:Archive",content:"sz-demo-view-registries"},{id:"tokens",name:"Tokens",iconName:"lucide:Key",content:"sz-demo-view-tokens"},{id:"mta",name:"Email / MTA",iconName:"lucide:Mail",content:"sz-demo-view-mta"},{id:"routes",name:"Routes",iconName:"lucide:Route",content:"sz-demo-view-routes"},{id:"settings",name:"Settings",iconName:"lucide:Settings",content:"sz-demo-view-settings"}],mainMenu:{sections:[{name:"Overview",views:["dashboard"]},{name:"Infrastructure",views:["services","network","registries","mta","routes"]},{name:"Administration",views:["tokens","settings"]}]},defaultView:"dashboard",onViewChange:i((l,c)=>{console.log("View changed to:",l,c)},"onViewChange")}),n.setUser({name:"Admin User",email:"admin@serve.zone",status:"online"}),n.setProfileMenuItems([{name:"Profile",iconName:"lucide:User",action:i(async()=>{console.log("Profile")},"action")},{name:"Preferences",iconName:"lucide:SlidersHorizontal",action:i(async()=>{console.log("Preferences")},"action")},{divider:!0},{name:"Sign Out",iconName:"lucide:LogOut",action:i(async()=>{console.log("Sign Out")},"action")}]))}static{UHa(r,a)}};return o=r})();var qm={};pt(qm,{TypedSocket:()=>bJe});var mJe={};pt(mJe,{sha256FromString:()=>KHa});var FW={};pt(FW,{Smartenv:()=>hJe});var fJe=Oi(o5a(),1);var hJe=class{static{i(this,"Smartenv")}constructor(){this.loadedScripts=[]}async getEnvAwareModule(e){if(this.isNode)return await this.getSafeNodeModule(e.nodeModuleName);if(this.isBrowser)return await this.getSafeWebModule(e.webUrlArg,e.getFunction);console.error("platform for loading not supported by smartenv")}async getSafeNodeModule(e){if(!this.isNode){console.error(`You tried to load a node module in a wrong context: ${e}`);return}return new Function(`return import('${e}')`)()}async getSafeWebModule(e,a){if(!this.isBrowser){console.error("You tried to load a web module in a wrong context");return}if(this.loadedScripts.includes(e))return a();this.loadedScripts.push(e);let r=fJe.defer();if(globalThis.importScripts)globalThis.importScripts(e),r.resolve();else{let s=document.createElement("script");s.onload=()=>{r.resolve()},s.src=e,document.head.appendChild(s)}return await r.promise,a()}get runtimeEnv(){return typeof process<"u"?"node":"browser"}get isBrowser(){return!this.isNode}get userAgent(){return this.isBrowser?navigator.userAgent:"undefined"}get isNode(){return this.runtimeEnv==="node"}get nodeVersion(){return process.version}get isCI(){return this.isNode?!!process.env.CI:!1}async isMacAsync(){return this.isNode?(await this.getSafeNodeModule("os")).platform()==="darwin":!1}async isWindowsAsync(){return this.isNode?(await this.getSafeNodeModule("os")).platform()==="win32":!1}async isLinuxAsync(){return this.isNode?(await this.getSafeNodeModule("os")).platform()==="linux":!1}async printEnv(){this.isNode?(console.log("running on NODE"),console.log("node version is "+this.nodeVersion)):(console.log("running on BROWSER"),console.log("browser is "+this.userAgent))}};var YHa=i(t=>{let e=[],a=new DataView(t);for(let r=0;r<a.byteLength;r+=4){let o=a.getUint32(r).toString(16),n="00000000",l=(n+o).slice(-n.length);e.push(l)}return e.join("")},"hex"),KHa=i(async t=>{let e=new FW.Smartenv;if(e.isBrowser){let a=new TextEncoder().encode(t),r=await crypto.subtle.digest("SHA-256",a);return YHa(r)}else if(e.isNode)return await(await e.getSafeNodeModule("@pushrocks/smarthash")).sha256FromString(t)},"sha256FromString");Fh();j4();Y2();F3e();ms();jn();o3();kQ();var gJe="__typedsocket_tag__";function XHa(t){return{peer:t,async getTagById(e){if(!t.tags.has(e))return;let a=t.data.get(`${gJe}${e}`);return{id:e,payload:a}}}}i(XHa,"wrapSmartServePeer");var bJe=class t{static{i(this,"TypedSocket")}static async createClient(e,a,r={}){let o={...{autoReconnect:!0,maxRetries:100,initialBackoffMs:1e3,maxBackoffMs:6e4},...r},n=new t("client",e);return n.clientOptions=o,n.serverUrl=a,n.currentBackoff=o.initialBackoffMs,await n.connect(),n}static{this.useWindowLocationOriginUrl=()=>pn.Smarturl.createFromUrl(globalThis.location.origin).toString()}static fromSmartServe(e,a){let r=new Map;t.registerTagHandlers(a);let s=new t("server",a);return s.smartServeRef=e,s.smartServeConnectionWrappers=r,s}static registerTagHandlers(e){e.addTypedHandler(new Nr.TypedHandler("__typedsocket_setTag",async(a,r)=>{let s=r?.localData?.peer;return s?(s.tags.add(a.name),s.data.set(`${gJe}${a.name}`,a.payload),{success:!0}):(console.warn("setTag: No peer found in request context"),{success:!1})})),e.addTypedHandler(new Nr.TypedHandler("__typedsocket_removeTag",async(a,r)=>{let s=r?.localData?.peer;return s?(s.tags.delete(a.name),s.data.delete(`${gJe}${a.name}`),{success:!0}):(console.warn("removeTag: No peer found in request context"),{success:!1})}))}constructor(e,a){this.statusSubject=new Ma.rxjs.Subject,this.connectionStatus="new",this.websocket=null,this.clientOptions=null,this.serverUrl="",this.retryCount=0,this.currentBackoff=1e3,this.pendingRequests=new Map,this.smartServeRef=null,this.smartServeConnectionWrappers=new Map,this.side=e,this.typedrouter=a}async connect(){let e=ft.defer();this.updateStatus("connecting");let a=this.toWebSocketUrl(this.serverUrl);console.log(`TypedSocket connecting to ${a}...`),this.websocket=new WebSocket(a);let r=setTimeout(()=>{this.connectionStatus!=="connected"&&(console.warn("TypedSocket connection timeout"),this.websocket?.close(),e.reject(new Error("Connection timeout")))},1e4);this.websocket.onopen=()=>{clearTimeout(r),console.log("TypedSocket connected!"),this.updateStatus("connected"),this.retryCount=0,this.currentBackoff=this.clientOptions?.initialBackoffMs??1e3,e.resolve()},this.websocket.onmessage=async s=>{await this.handleMessage(s.data)},this.websocket.onclose=()=>{clearTimeout(r),this.handleDisconnect()},this.websocket.onerror=s=>{console.error("TypedSocket WebSocket error:",s)};try{await e.promise}catch(s){if(clearTimeout(r),this.clientOptions?.autoReconnect)await this.scheduleReconnect();else throw s}}toWebSocketUrl(e){let a=new URL(e);return`${a.protocol==="https:"?"wss:":"ws:"}//${a.host}${a.pathname}`}async handleMessage(e){try{let a=typeof e=="string"?e:new TextDecoder().decode(e),r=So.parse(a);if(r.correlation?.id&&this.pendingRequests.has(r.correlation.id)){let o=this.pendingRequests.get(r.correlation.id);this.pendingRequests.delete(r.correlation.id),o.resolve(r);return}let s=await this.typedrouter.routeAndAddResponse(r);s&&this.websocket?.readyState===WebSocket.OPEN&&this.websocket.send(So.stringify(s))}catch(a){console.error("TypedSocket failed to process message:",a)}}handleDisconnect(){if(this.connectionStatus!=="disconnected"){this.updateStatus("disconnected");for(let[e,a]of this.pendingRequests)a.reject(new Error("TypedSocket disconnected"));this.pendingRequests.clear(),this.clientOptions?.autoReconnect&&this.retryCount<this.clientOptions.maxRetries&&this.scheduleReconnect()}}async scheduleReconnect(){if(!this.clientOptions)return;this.updateStatus("reconnecting"),this.retryCount++;let e=this.currentBackoff*.2*(Math.random()*2-1),a=Math.min(this.currentBackoff+e,this.clientOptions.maxBackoffMs);console.log(`TypedSocket reconnecting in ${Math.round(a)}ms (attempt ${this.retryCount}/${this.clientOptions.maxRetries})`),await Wt.delayFor(a),this.currentBackoff=Math.min(this.currentBackoff*2,this.clientOptions.maxBackoffMs);try{await this.connect()}catch(r){console.error("TypedSocket reconnection failed:",r)}}updateStatus(e){this.connectionStatus!==e&&(this.connectionStatus=e,this.statusSubject.next(e))}async sendRequest(e){if(!this.websocket||this.websocket.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");return new Promise((a,r)=>{let s=setTimeout(()=>{this.pendingRequests.delete(e.correlation.id),r(new Error("Request timeout"))},3e4);this.pendingRequests.set(e.correlation.id,{resolve:i(o=>{clearTimeout(s),a(o)},"resolve"),reject:i(o=>{clearTimeout(s),r(o)},"reject")}),this.websocket.send(So.stringify(e))})}createTypedRequest(e,a){let r=i(async s=>{if(this.side==="client")return this.sendRequest(s);if(!this.smartServeRef)throw new Error("Server not initialized");let o=a;if(!o){let l=this.smartServeRef.getWebSocketConnections();if(l.length===1){let c=l[0];o=this.getOrCreateWrapper(c)}else throw l.length===0?new Error("No WebSocket connections available"):new Error("Multiple connections available - specify targetConnection")}let n=await this.typedrouter.fireEventInterestMap.addInterest(s.correlation.id,s);return o.peer.send(So.stringify(s)),await n.interestFullfilled},"postMethod");return new Nr.TypedRequest(new Nr.TypedTarget({postMethod:r}),e)}getStatus(){return this.connectionStatus}async stop(){this.side==="client"?(this.clientOptions&&(this.clientOptions.autoReconnect=!1),this.websocket&&(this.websocket.close(),this.websocket=null),this.pendingRequests.clear()):this.smartServeConnectionWrappers.clear()}async setTag(e,a){if(this.side!=="client")throw new Error("setTag is only available on clients");if(!(await this.createTypedRequest("__typedsocket_setTag").fire({name:e,payload:a})).success)throw new Error("Failed to set tag on server")}async removeTag(e){if(this.side!=="client")throw new Error("removeTag is only available on clients");if(!(await this.createTypedRequest("__typedsocket_removeTag").fire({name:e})).success)throw new Error("Failed to remove tag on server")}getOrCreateWrapper(e){let a=this.smartServeConnectionWrappers.get(e.id);return a||(a=XHa(e),this.smartServeConnectionWrappers.set(e.id,a)),a}async findAllTargetConnections(e){if(this.side!=="server"||!this.smartServeRef)throw new Error("findAllTargetConnections is only available on servers");let a=[];for(let r of this.smartServeRef.getWebSocketConnections()){let s=this.getOrCreateWrapper(r);await e(s)&&a.push(s)}return a}async findTargetConnection(e){return(await this.findAllTargetConnections(e))[0]}async findAllTargetConnectionsByTag(e,a){if(this.side!=="server"||!this.smartServeRef)throw new Error("findAllTargetConnectionsByTag is only available on servers");let r=this.smartServeRef.getWebSocketConnectionsByTag(e),s=[];for(let o of r){let n=this.getOrCreateWrapper(o);if(a!==void 0){let l=await n.getTagById(e);if(So.stringify(l?.payload)!==So.stringify(a))continue}s.push(n)}return s}async findTargetConnectionByTag(e,a){return(await this.findAllTargetConnectionsByTag(e,a))[0]}};le();Tt();var Oie=Oi(oha(),1),Ke=At;j4();var qJe={};pt(qJe,{DCROUTER_BUILTIN_PROVIDER_ID:()=>UVa,dnsProviderTypeDescriptors:()=>nha,getDnsProviderTypeDescriptor:()=>WVa});var UVa="__dcrouter__",nha=[{type:"dcrouter",displayName:"DcRouter (built-in)",description:"Built-in authoritative DNS. Records are served directly by dcrouter \u2014 delegate the domain's NS records to make this effective.",credentialFields:[]},{type:"cloudflare",displayName:"Cloudflare",description:"External DNS provider. The provider stays authoritative; dcrouter pushes record changes via its API.",credentialFields:[{key:"apiToken",label:"API Token",helpText:"A Cloudflare API token with Zone:Read and DNS:Edit permissions for the target zones.",required:!0,secret:!0}]}];function WVa(t){return nha.find(e=>e.type===t)}i(WVa,"getDnsProviderTypeDescriptor");var lha={};var fs=new Ke.plugins.smartstate.Smartstate,Ia=await fs.getStatePart("login",{identity:null,isLoggedIn:!1},"persistent"),nr=await fs.getStatePart("stats",{serverStats:null,emailStats:null,dnsStats:null,securityMetrics:null,radiusStats:null,vpnStats:null,lastUpdated:0,isLoading:!1,error:null},"soft"),h4=await fs.getStatePart("config",{config:null,isLoading:!1,error:null}),GVa=i(()=>{let t=typeof window<"u"?window.location.pathname:"/",e=["overview","network","email","logs","access","security","domains"],r=t.split("/").filter(Boolean)[0];return e.includes(r)?r:"overview"},"getInitialView"),YVa=i(()=>(typeof window<"u"?window.location.pathname:"/").split("/").filter(Boolean)[1]??null,"getInitialSubview"),Os=await fs.getStatePart("ui",{activeView:GVa(),activeSubview:YVa(),sidebarCollapsed:!1,autoRefresh:!0,refreshInterval:1e3,theme:"light"}),pc=await fs.getStatePart("logs",{recentLogs:[],isStreaming:!1,filters:{}},"soft"),p4=await fs.getStatePart("network",{connections:[],connectionsByIP:{},throughputRate:{bytesInPerSecond:0,bytesOutPerSecond:0},totalBytes:{in:0,out:0},topIPs:[],topIPsByBandwidth:[],throughputByIP:[],domainActivity:[],throughputHistory:[],requestsPerSecond:0,requestsTotal:0,backends:[],frontendProtocols:null,backendProtocols:null,lastUpdated:0,isLoading:!1,error:null},"soft"),qie=await fs.getStatePart("emailOps",{emails:[],isLoading:!1,error:null,lastUpdated:0},"soft"),Ao=await fs.getStatePart("certificates",{certificates:[],summary:{total:0,valid:0,expiring:0,expired:0,failed:0,unknown:0},isLoading:!1,error:null,lastUpdated:0},"soft"),z5=await fs.getStatePart("acmeConfig",{config:null,isLoading:!1,error:null,lastUpdated:0},"soft"),Ri=await fs.getStatePart("remoteIngress",{edges:[],statuses:[],selectedEdgeId:null,newEdgeId:null,isLoading:!1,error:null,lastUpdated:0},"soft"),Fa=await fs.getStatePart("routeManagement",{mergedRoutes:[],warnings:[],apiTokens:[],isLoading:!1,error:null,lastUpdated:0},"soft"),GW=await fs.getStatePart("users",{users:[],isLoading:!1,error:null,lastUpdated:0},"soft"),ut=i(()=>{let t=Ia.getState().identity;return t&&t.expiresAt&&t.expiresAt<Date.now()?{identity:null}:{identity:t}},"getActionContext"),hha=Ia.createAction(async(t,e)=>{let a=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","adminLoginWithUsernameAndPassword");try{let r=await a.fire({username:e.username,password:e.password});return r.identity?{identity:r.identity,isLoggedIn:!0}:t.getState()}catch(r){return console.error("Login failed:",r),t.getState()}}),Gm=Ia.createAction(async t=>{let e=ut();if(e.identity){let a=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","adminLogout");try{await a.fire({identity:e.identity})}catch(r){console.error("Logout error:",r)}}return{identity:null,isLoggedIn:!1}}),Ym=nr.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:e.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:!1,radius:!0,vpn:!0}});return{serverStats:s.metrics.server||a.serverStats,emailStats:s.metrics.email||a.emailStats,dnsStats:s.metrics.dns||a.dnsStats,securityMetrics:s.metrics.security||a.securityMetrics,radiusStats:s.metrics.radius||a.radiusStats,vpnStats:s.metrics.vpn||a.vpnStats,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(r){return{...a,isLoading:!1,error:r.message||"Failed to fetch statistics"}}}),Hie=h4.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{config:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getConfiguration").fire({identity:e.identity})).config,isLoading:!1,error:null}}catch(r){return{...a,isLoading:!1,error:r.message||"Failed to fetch configuration"}}}),Vie=pc.createAction(async(t,e)=>{let a=ut();if(!a.identity)return t.getState();let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRecentLogs").fire({identity:a.identity,limit:e.limit||100,level:e.level,category:e.category});return{...t.getState(),recentLogs:s.logs}}),Pmo=Os.createAction(async t=>{let e=t.getState();return{...e,autoRefresh:!e.autoRefresh}}),Emo=Os.createAction(async(t,e)=>{let a=t.getState();return e==="network"&&a.activeView!=="network"&&setTimeout(()=>{p4.dispatchAction(WJe,null)},100),e==="domains"&&a.activeView!=="domains"&&setTimeout(()=>{Ao.dispatchAction(u4,null)},100),{...a,activeView:e}}),WJe=p4.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getActiveConnections").fire({identity:e.identity}),n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getNetworkStats").fire({identity:e.identity}),l={};return n.connectionsByIP&&Array.isArray(n.connectionsByIP)?n.connectionsByIP.forEach(c=>{l[c.ip]=c.count}):s.connections.forEach(c=>{let d=c.remoteAddress;l[d]=(l[d]||0)+1}),{connections:s.connections,connectionsByIP:l,throughputRate:n.throughputRate||{bytesInPerSecond:0,bytesOutPerSecond:0},totalBytes:n.totalDataTransferred?{in:n.totalDataTransferred.bytesIn,out:n.totalDataTransferred.bytesOut}:{in:0,out:0},topIPs:n.topIPs||[],topIPsByBandwidth:n.topIPsByBandwidth||[],throughputByIP:n.throughputByIP||[],domainActivity:n.domainActivity||[],throughputHistory:n.throughputHistory||[],requestsPerSecond:n.requestsPerSecond||0,requestsTotal:n.requestsTotal||0,backends:n.backends||[],frontendProtocols:n.frontendProtocols||null,backendProtocols:n.backendProtocols||null,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(r){return console.error("Failed to fetch network stats:",r),{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch network stats"}}}),mha=qie.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{emails:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getAllEmails").fire({identity:e.identity})).emails,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch emails"}}}),u4=Ao.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getCertificateOverview").fire({identity:e.identity});return{certificates:s.certificates,summary:s.summary,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch certificate overview"}}}),gha=Ao.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","reprovisionCertificateDomain").fire({identity:r.identity,domain:e.domain,forceRenew:e.forceRenew}),await a.dispatch(u4,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to reprovision certificate"}}}),bha=Ao.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteCertificate").fire({identity:r.identity,domain:e}),await a.dispatch(u4,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete certificate"}}}),vha=Ao.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","importCertificate").fire({identity:r.identity,cert:e}),await a.dispatch(u4,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to import certificate"}}});async function xha(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","exportCertificate").fire({identity:e.identity,domain:t})}i(xha,"fetchCertificateExport");async function GJe(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRemoteIngressConnectionToken").fire({identity:e.identity,edgeId:t})}i(GJe,"fetchConnectionToken");var k5=Ri.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRemoteIngresses"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRemoteIngressStatus"),[o,n]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity})]);return{...a,edges:o.edges,statuses:n.statuses,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch remote ingress data"}}}),yha=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createRemoteIngress").fire({identity:r.identity,name:e.name,listenPorts:e.listenPorts,autoDerivePorts:e.autoDerivePorts,tags:e.tags});return n.success?(await a.dispatch(k5,null),{...t.getState(),newEdgeId:n.edge.id}):s}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to create edge"}}}),wha=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteRemoteIngress").fire({identity:r.identity,id:e}),await a.dispatch(k5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete edge"}}}),Mha=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateRemoteIngress").fire({identity:r.identity,id:e.id,name:e.name,listenPorts:e.listenPorts,autoDerivePorts:e.autoDerivePorts,tags:e.tags}),await a.dispatch(k5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to update edge"}}}),kha=Ri.createAction(async(t,e)=>{let a=ut(),r=t.getState();try{return(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","regenerateRemoteIngressSecret").fire({identity:a.identity,id:e})).success?{...r,newEdgeId:e}:r}catch(s){return{...r,error:s instanceof Error?s.message:"Failed to regenerate secret"}}}),Sha=Ri.createAction(async t=>({...t.getState(),newEdgeId:null})),YJe=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateRemoteIngress").fire({identity:r.identity,id:e.id,enabled:e.enabled}),await a.dispatch(k5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle edge"}}}),Fi=await fs.getStatePart("vpn",{clients:[],connectedClients:[],status:null,isLoading:!1,error:null,lastUpdated:0,newClientConfig:null},"soft"),S5=Fi.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getVpnClients"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getVpnStatus"),o=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getVpnConnectedClients"),[n,l,c]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity}),o.fire({identity:e.identity})]);return{...a,clients:n.clients,connectedClients:c.connectedClients,status:l.status,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch VPN data"}}}),Cha=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createVpnClient").fire({identity:r.identity,clientId:e.clientId,targetProfileIds:e.targetProfileIds,description:e.description,destinationAllowList:e.destinationAllowList,destinationBlockList:e.destinationBlockList,useHostIp:e.useHostIp,useDhcp:e.useDhcp,staticIp:e.staticIp,forceVlan:e.forceVlan,vlanId:e.vlanId});return n.success?{...await a.dispatch(S5,null),newClientConfig:n.wireguardConfig||null}:{...s,error:n.message||"Failed to create client"}}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to create VPN client"}}}),zha=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteVpnClient").fire({identity:r.identity,clientId:e}),await a.dispatch(S5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete VPN client"}}}),KJe=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let o=e.enabled?"enableVpnClient":"disableVpnClient";return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest",o).fire({identity:r.identity,clientId:e.clientId}),await a.dispatch(S5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle VPN client"}}}),Tha=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateVpnClient").fire({identity:r.identity,clientId:e.clientId,description:e.description,targetProfileIds:e.targetProfileIds,destinationAllowList:e.destinationAllowList,destinationBlockList:e.destinationBlockList,useHostIp:e.useHostIp,useDhcp:e.useDhcp,staticIp:e.staticIp,forceVlan:e.forceVlan,vlanId:e.vlanId});return n.success?await a.dispatch(S5,null):{...s,error:n.message||"Failed to update client"}}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to update VPN client"}}}),_ha=Fi.createAction(async t=>({...t.getState(),newClientConfig:null})),Zi=await fs.getStatePart("targetProfiles",{profiles:[],isLoading:!1,error:null,lastUpdated:0},"soft"),f4=Zi.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{profiles:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getTargetProfiles").fire({identity:e.identity})).profiles,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch target profiles"}}}),Lha=Zi.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createTargetProfile").fire({identity:r.identity,name:e.name,description:e.description,domains:e.domains,targets:e.targets,routeRefs:e.routeRefs});return o.success?await a.dispatch(f4,null):{...t.getState(),error:o.message||"Failed to create target profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create target profile"}}}),$ha=Zi.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateTargetProfile").fire({identity:r.identity,id:e.id,name:e.name,description:e.description,domains:e.domains,targets:e.targets,routeRefs:e.routeRefs});return o.success?await a.dispatch(f4,null):{...t.getState(),error:o.message||"Failed to update target profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update target profile"}}}),ZJe=Zi.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteTargetProfile").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(f4,null):{...t.getState(),error:o.message||"Failed to delete target profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete target profile"}}}),Ua=await fs.getStatePart("profilesTargets",{profiles:[],targets:[],isLoading:!1,error:null,lastUpdated:0},"soft"),Io=Ua.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getSourceProfiles"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getNetworkTargets"),[o,n]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity})]);return{profiles:o.profiles,targets:n.targets,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch profiles/targets"}}}),Dha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createSourceProfile").fire({identity:r.identity,name:e.name,description:e.description,security:e.security,extendsProfiles:e.extendsProfiles}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create profile"}}}),Aha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateSourceProfile").fire({identity:r.identity,id:e.id,name:e.name,description:e.description,security:e.security,extendsProfiles:e.extendsProfiles}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update profile"}}}),XJe=Ua.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteSourceProfile").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(Io,null):{...t.getState(),error:o.message||"Failed to delete profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete profile"}}}),Iha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createNetworkTarget").fire({identity:r.identity,name:e.name,description:e.description,host:e.host,port:e.port}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create target"}}}),Pha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateNetworkTarget").fire({identity:r.identity,id:e.id,name:e.name,description:e.description,host:e.host,port:e.port}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update target"}}}),QJe=Ua.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteNetworkTarget").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(Io,null):{...t.getState(),error:o.message||"Failed to delete target"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete target"}}}),Bt=await fs.getStatePart("domains",{providers:[],domains:[],records:[],selectedDomainId:null,isLoading:!1,error:null,lastUpdated:0},"soft"),Ni=Bt.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getDnsProviders"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getDomains"),[o,n]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity})]);return{...a,providers:o.providers,domains:n.domains,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch domains/providers"}}}),fc=Bt.createAction(async(t,e)=>{let a=ut(),r=t.getState();if(!a.identity)return r;try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getDnsRecords").fire({identity:a.identity,domainId:e.domainId});return{...r,records:o.records,selectedDomainId:e.domainId,error:null}}catch(s){return{...r,error:s instanceof Error?s.message:"Failed to fetch DNS records"}}}),Eha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createDnsProvider").fire({identity:r.identity,name:e.name,type:e.type,credentials:e.credentials});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to create provider"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create provider"}}}),Nha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateDnsProvider").fire({identity:r.identity,id:e.id,name:e.name,credentials:e.credentials});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to update provider"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update provider"}}}),Rha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteDnsProvider").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to delete provider"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete provider"}}}),Fha=Bt.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","testDnsProvider").fire({identity:r.identity,id:e.id}),await a.dispatch(Ni,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to test provider"}}});async function Oha(t){let e=ut();return e.identity?await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","listProviderDomains").fire({identity:e.identity,providerId:t}):{success:!1,message:"Not authenticated"}}i(Oha,"fetchProviderDomains");var Bha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createDomain").fire({identity:r.identity,name:e.name,description:e.description});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to create domain"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create domain"}}}),qha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","importDomain").fire({identity:r.identity,providerId:e.providerId,domainNames:e.domainNames});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to import domains"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to import domains"}}}),Hha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteDomain").fire({identity:r.identity,id:e.id});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to delete domain"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete domain"}}}),Vha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","syncDomain").fire({identity:r.identity,id:e.id});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to sync domain"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to sync domain"}}}),jha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","migrateDomain").fire({identity:r.identity,...e});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Migration failed"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Migration failed"}}}),Uha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createDnsRecord").fire({identity:r.identity,domainId:e.domainId,name:e.name,type:e.type,value:e.value,ttl:e.ttl,proxied:e.proxied});return o.success?await a.dispatch(fc,{domainId:e.domainId}):{...t.getState(),error:o.message||"Failed to create record"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create record"}}}),Wha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateDnsRecord").fire({identity:r.identity,id:e.id,name:e.name,value:e.value,ttl:e.ttl,proxied:e.proxied});return o.success?await a.dispatch(fc,{domainId:e.domainId}):{...t.getState(),error:o.message||"Failed to update record"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update record"}}}),Gha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteDnsRecord").fire({identity:r.identity,id:e.id});return o.success?await a.dispatch(fc,{domainId:e.domainId}):{...t.getState(),error:o.message||"Failed to delete record"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete record"}}}),JJe=z5.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{config:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getAcmeConfig").fire({identity:e.identity})).config,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch ACME config"}}}),Yha=z5.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateAcmeConfig").fire({identity:r.identity,accountEmail:e.accountEmail,enabled:e.enabled,useProduction:e.useProduction,autoRenew:e.autoRenew,renewThresholdDays:e.renewThresholdDays});return o.success?await a.dispatch(JJe,null):{...t.getState(),error:o.message||"Failed to update ACME config"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update ACME config"}}}),E2=Fa.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getMergedRoutes").fire({identity:e.identity});return{...a,mergedRoutes:s.routes,warnings:s.warnings,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch routes"}}}),Kha=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createRoute").fire({identity:r.identity,route:e.route,enabled:e.enabled,metadata:e.metadata}),await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to create route"}}}),Zha=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateRoute").fire({identity:r.identity,id:e.id,route:e.route,enabled:e.enabled,metadata:e.metadata}),await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to update route"}}}),eet=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteRoute").fire({identity:r.identity,id:e}),await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete route"}}}),Xha=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","toggleRoute").fire({identity:r.identity,id:e.id,enabled:e.enabled}),await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle route"}}}),T5=Fa.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","listApiTokens").fire({identity:e.identity});return{...a,apiTokens:s.tokens}}catch(r){return{...a,error:r instanceof Error?r.message:"Failed to fetch tokens"}}}),tet=GW.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","listUsers").fire({identity:e.identity});return{...a,users:s.users,error:null,lastUpdated:Date.now()}}catch(r){return{...a,error:r instanceof Error?r.message:"Failed to fetch users"}}});async function Qha(t,e,a){let r=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createApiToken").fire({identity:r.identity,name:t,scopes:e,expiresInDays:a})}i(Qha,"createApiToken");async function Jha(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","rollApiToken").fire({identity:e.identity,id:t})}i(Jha,"rollApiToken");var e8a=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","revokeApiToken").fire({identity:r.identity,id:e}),await a.dispatch(T5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to revoke token"}}}),aet=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","toggleApiToken").fire({identity:r.identity,id:e.id,enabled:e.enabled}),await a.dispatch(T5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle token"}}}),fo=await fs.getStatePart("emailDomains",{domains:[],isLoading:!1,lastUpdated:0},"soft"),C5=fo.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getEmailDomains").fire({identity:e.identity});return{...a,domains:s.domains,isLoading:!1,lastUpdated:Date.now()}}catch{return{...a,isLoading:!1}}}),t8a=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createEmailDomain").fire({identity:r.identity,...e}),await a.dispatch(C5,null)}catch{return s}}),a8a=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteEmailDomain").fire({identity:r.identity,id:e}),await a.dispatch(C5,null)}catch{return s}}),r8a=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","validateEmailDomain").fire({identity:r.identity,id:e}),await a.dispatch(C5,null)}catch{return s}}),ret=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","provisionEmailDomainDns").fire({identity:r.identity,id:e}),await a.dispatch(C5,null)}catch{return s}});async function i8a(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getEmailDomainDnsRecords").fire({identity:e.identity,id:t})}i(i8a,"fetchEmailDomainDnsRecords");var w5=null,cha=new Ke.plugins.typedrequest.TypedRouter,Bie=[],HJe=!1;function KVa(){if(HJe=!1,Bie.length===0)return;let t=pc.getState(),e=[...t.recentLogs,...Bie];Bie=[],e.length>2e3&&e.splice(0,e.length-2e3),pc.setState({...t,recentLogs:e})}i(KVa,"flushLogEntries"),cha.addTypedHandler(new Ke.plugins.typedrequest.TypedHandler("pushLogEntry",async t=>(Bie.push(t.entry),HJe||(HJe=!0,requestAnimationFrame(KVa)),{})));async function VJe(){if(!w5)try{w5=await qm.TypedSocket.createClient(cha,qm.TypedSocket.useWindowLocationOriginUrl()),await w5.setTag("role","ops_dashboard")}catch(t){console.error("TypedSocket connection failed:",t),w5=null}}i(VJe,"connectSocket");async function dha(){if(w5){try{await w5.stop()}catch{}w5=null}}i(dha,"disconnectSocket");var jJe=!1;async function ZVa(){if(!jJe){jJe=!0;try{await XVa()}finally{jJe=!1}}}i(ZVa,"dispatchCombinedRefreshAction");async function XVa(){let t=ut();if(!t.identity)return;let e=Os.getState().activeView,a=Os.getState().activeSubview;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:t.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:e==="network",radius:!0,vpn:!0}}),o=nr.getState();if(nr.setState({...o,serverStats:s.metrics.server||o.serverStats,emailStats:s.metrics.email||o.emailStats,dnsStats:s.metrics.dns||o.dnsStats,securityMetrics:s.metrics.security||o.securityMetrics,radiusStats:s.metrics.radius||o.radiusStats,vpnStats:s.metrics.vpn||o.vpnStats,lastUpdated:Date.now(),isLoading:!1,error:null}),s.metrics.network&&e==="network"){let n=s.metrics.network,l={};n.connectionDetails.forEach(d=>{l[d.remoteAddress]=(l[d.remoteAddress]||0)+1});let c=n.connectionDetails.map((d,u)=>({id:`ip-${d.remoteAddress}`,remoteAddress:d.remoteAddress,localAddress:"server",startTime:d.startTime,protocol:d.protocol,state:d.state,bytesReceived:d.bytesIn,bytesSent:d.bytesOut}));p4.setState({...p4.getState(),connections:c,connectionsByIP:l,throughputRate:{bytesInPerSecond:n.totalBandwidth.in,bytesOutPerSecond:n.totalBandwidth.out},totalBytes:n.totalBytes||{in:0,out:0},topIPs:n.topEndpoints.map(d=>({ip:d.endpoint,count:d.connections})),topIPsByBandwidth:(n.topEndpointsByBandwidth||[]).map(d=>({ip:d.endpoint,count:d.connections,bwIn:d.bandwidth?.in||0,bwOut:d.bandwidth?.out||0})),throughputByIP:n.topEndpoints.map(d=>({ip:d.endpoint,in:d.bandwidth?.in||0,out:d.bandwidth?.out||0})),domainActivity:n.domainActivity||[],throughputHistory:n.throughputHistory||[],requestsPerSecond:n.requestsPerSecond||0,requestsTotal:n.requestsTotal||0,backends:n.backends||[],frontendProtocols:n.frontendProtocols||null,backendProtocols:n.backendProtocols||null,lastUpdated:Date.now(),isLoading:!1,error:null})}if(e==="domains"&&a==="certificates")try{await Ao.dispatchAction(u4,null)}catch(n){console.error("Certificate refresh failed:",n)}if(e==="network"&&a==="remoteingress")try{await Ri.dispatchAction(k5,null)}catch(n){console.error("Remote ingress refresh failed:",n)}if(e==="network"&&a==="vpn")try{await Fi.dispatchAction(S5,null)}catch(n){console.error("VPN refresh failed:",n)}}catch(r){console.error("Combined refresh failed:",r);let s=String(r);(s.includes("invalid")||s.includes("unauthorized")||s.includes("401"))&&(await Ia.dispatchAction(Gm,null),window.location.reload())}}i(XVa,"dispatchCombinedRefreshActionInner");var QVa=nr.createAction(async t=>(await ZVa(),t.getState())),M5=null,UJe=i(()=>{let t=Os.getState(),e=Ia.getState();t.autoRefresh&&e.isLoggedIn?(M5&&(M5.dispose(),M5=null),M5=nr.createScheduledAction({action:QVa,payload:void 0,intervalMs:t.refreshInterval,autoPause:"visibility"})):M5&&(M5.dispose(),M5=null)},"startAutoRefresh"),uha=Os.getState().autoRefresh,pha=Os.getState().refreshInterval,fha=Ia.getState().isLoggedIn;Os.select(t=>({autoRefresh:t.autoRefresh,refreshInterval:t.refreshInterval})).subscribe(t=>{(t.autoRefresh!==uha||t.refreshInterval!==pha)&&(uha=t.autoRefresh,pha=t.refreshInterval,UJe())}),Ia.select(t=>t.isLoggedIn).subscribe(t=>{t!==fha&&(fha=t,UJe(),t?VJe():dha())}),document.addEventListener("visibilitychange",()=>{document.hidden?dha():Ia.getState().isLoggedIn&&VJe()}),UJe(),Ia.getState().isLoggedIn&&VJe();j4();var N2={};pt(N2,{DCROUTER_BUILTIN_PROVIDER_ID:()=>JVa,dnsProviderTypeDescriptors:()=>s8a,getDnsProviderTypeDescriptor:()=>eja});var JVa="__dcrouter__",s8a=[{type:"dcrouter",displayName:"DcRouter (built-in)",description:"Built-in authoritative DNS. Records are served directly by dcrouter \u2014 delegate the domain's NS records to make this effective.",credentialFields:[]},{type:"cloudflare",displayName:"Cloudflare",description:"External DNS provider. The provider stays authoritative; dcrouter pushes record changes via its API.",credentialFields:[{key:"apiToken",label:"API Token",helpText:"A Cloudflare API token with Zone:Read and DNS:Edit permissions for the target zones.",required:!0,secret:!0}]}];function eja(t){return s8a.find(e=>e.type===t)}i(eja,"getDnsProviderTypeDescriptor");var o8a={};var tja=Ke.plugins.smartrouter.SmartRouter,l8a=["logs"],Km={overview:["stats","configuration"],network:["activity","routes","sourceprofiles","networktargets","targetprofiles","remoteingress","vpn"],email:["log","security","domains"],access:["apitokens","users"],security:["overview","blocked","authentication"],domains:["providers","domains","dns","certificates"]},iet={overview:"stats",network:"activity",email:"log",access:"apitokens",security:"overview",domains:"domains"},aja=[...l8a,...Object.keys(Km)];function c8a(t){return aja.includes(t)}i(c8a,"isValidView");function d8a(t,e){return Km[t]?.includes(e)??!1}i(d8a,"isValidSubview");var set=class{static{i(this,"AppRouter")}router;initialized=!1;suppressStateUpdate=!1;constructor(){this.router=new tja({debug:!1})}init(){this.initialized||(this.setupRoutes(),this.setupStateSync(),this.handleInitialRoute(),this.initialized=!0)}setupRoutes(){for(let e of l8a)this.router.on(`/${e}`,async()=>{this.updateViewState(e,null)});for(let e of Object.keys(Km)){this.router.on(`/${e}`,async()=>{this.navigateTo(`/${e}/${iet[e]}`)});for(let a of Km[e])this.router.on(`/${e}/${a}`,async()=>{this.updateViewState(e,a)})}this.router.on("/",async()=>{this.navigateTo("/overview")})}setupStateSync(){Os.select().subscribe(e=>{if(this.suppressStateUpdate)return;let a=window.location.pathname,r=e.activeSubview?`/${e.activeView}/${e.activeSubview}`:`/${e.activeView}`;a!==r&&(this.suppressStateUpdate=!0,this.router.pushUrl(r),this.suppressStateUpdate=!1)})}handleInitialRoute(){let e=window.location.pathname;if(!e||e==="/"){this.router.pushUrl("/overview");return}let a=e.split("/").filter(Boolean),r=a[0],s=a[1];if(!c8a(r)){this.router.pushUrl("/overview");return}Km[r]?s&&d8a(r,s)?this.updateViewState(r,s):this.router.pushUrl(`/${r}/${iet[r]}`):this.updateViewState(r,null)}updateViewState(e,a){this.suppressStateUpdate=!0;let r=Os.getState();(r.activeView!==e||r.activeSubview!==a)&&Os.setState({...r,activeView:e,activeSubview:a}),this.suppressStateUpdate=!1}navigateTo(e){this.router.pushUrl(e)}navigateToView(e,a){if(!c8a(e)){this.navigateTo("/overview");return}a&&d8a(e,a)?this.navigateTo(`/${e}/${a}`):Km[e]?this.navigateTo(`/${e}/${iet[e]}`):this.navigateTo(`/${e}`)}getCurrentView(){return Os.getState().activeView}destroy(){this.router.destroy(),this.initialized=!1}},hc=new set;le();var Yt=W`
42461
+ `}async firstUpdated(){let n=this.shadowRoot?.querySelector("dees-appui");n&&(n.configure({branding:{logoIcon:"lucide:Box",logoText:"serve.zone"},appBar:{showSearch:!0,breadcrumbs:"serve.zone",menuItems:[{name:"File",action:i(async()=>{},"action"),submenu:[{name:"New Service",shortcut:"Cmd+N",action:i(async()=>{console.log("New Service")},"action")},{name:"Import Configuration",action:i(async()=>{console.log("Import")},"action")},{name:"Export Configuration",action:i(async()=>{console.log("Export")},"action")},{divider:!0},{name:"Preferences",shortcut:"Cmd+,",action:i(async()=>{n.navigateToView("settings")},"action")}]},{name:"View",action:i(async()=>{},"action"),submenu:[{name:"Dashboard",shortcut:"Cmd+1",action:i(async()=>{n.navigateToView("dashboard")},"action")},{name:"Services",shortcut:"Cmd+2",action:i(async()=>{n.navigateToView("services")},"action")},{name:"Network",shortcut:"Cmd+3",action:i(async()=>{n.navigateToView("network")},"action")},{divider:!0},{name:"Activity Log",shortcut:"Cmd+Shift+A",action:i(async()=>{n.toggleActivityLog()},"action")},{name:"Toggle Sidebar",shortcut:"Cmd+B",action:i(async()=>{n.setMainMenuCollapsed(!n.mainmenuCollapsed)},"action")}]},{name:"Services",action:i(async()=>{},"action"),submenu:[{name:"Deploy New Service",action:i(async()=>{console.log("Deploy")},"action")},{name:"Start All",action:i(async()=>{console.log("Start all")},"action")},{name:"Stop All",action:i(async()=>{console.log("Stop all")},"action")},{divider:!0},{name:"Garbage Collect",action:i(async()=>{console.log("GC")},"action")}]},{name:"Help",action:i(async()=>{},"action"),submenu:[{name:"Documentation",action:i(async()=>{window.open("https://docs.serve.zone","_blank")},"action")},{name:"Release Notes",action:i(async()=>{console.log("Release notes")},"action")},{divider:!0},{name:"About serve.zone",action:i(async()=>{console.log("About")},"action")}]}]},views:[{id:"dashboard",name:"Dashboard",iconName:"lucide:LayoutDashboard",content:"sz-demo-view-dashboard"},{id:"services",name:"Services",iconName:"lucide:Server",content:"sz-demo-view-services"},{id:"network",name:"Network",iconName:"lucide:Network",content:"sz-demo-view-network"},{id:"registries",name:"Registries",iconName:"lucide:Archive",content:"sz-demo-view-registries"},{id:"tokens",name:"Tokens",iconName:"lucide:Key",content:"sz-demo-view-tokens"},{id:"mta",name:"Email / MTA",iconName:"lucide:Mail",content:"sz-demo-view-mta"},{id:"routes",name:"Routes",iconName:"lucide:Route",content:"sz-demo-view-routes"},{id:"settings",name:"Settings",iconName:"lucide:Settings",content:"sz-demo-view-settings"}],mainMenu:{sections:[{name:"Overview",views:["dashboard"]},{name:"Infrastructure",views:["services","network","registries","mta","routes"]},{name:"Administration",views:["tokens","settings"]}]},defaultView:"dashboard",onViewChange:i((l,c)=>{console.log("View changed to:",l,c)},"onViewChange")}),n.setUser({name:"Admin User",email:"admin@serve.zone",status:"online"}),n.setProfileMenuItems([{name:"Profile",iconName:"lucide:User",action:i(async()=>{console.log("Profile")},"action")},{name:"Preferences",iconName:"lucide:SlidersHorizontal",action:i(async()=>{console.log("Preferences")},"action")},{divider:!0},{name:"Sign Out",iconName:"lucide:LogOut",action:i(async()=>{console.log("Sign Out")},"action")}]))}static{UHa(r,a)}};return o=r})();var qm={};pt(qm,{TypedSocket:()=>bJe});var mJe={};pt(mJe,{sha256FromString:()=>KHa});var FW={};pt(FW,{Smartenv:()=>hJe});var fJe=Oi(o5a(),1);var hJe=class{static{i(this,"Smartenv")}constructor(){this.loadedScripts=[]}async getEnvAwareModule(e){if(this.isNode)return await this.getSafeNodeModule(e.nodeModuleName);if(this.isBrowser)return await this.getSafeWebModule(e.webUrlArg,e.getFunction);console.error("platform for loading not supported by smartenv")}async getSafeNodeModule(e){if(!this.isNode){console.error(`You tried to load a node module in a wrong context: ${e}`);return}return new Function(`return import('${e}')`)()}async getSafeWebModule(e,a){if(!this.isBrowser){console.error("You tried to load a web module in a wrong context");return}if(this.loadedScripts.includes(e))return a();this.loadedScripts.push(e);let r=fJe.defer();if(globalThis.importScripts)globalThis.importScripts(e),r.resolve();else{let s=document.createElement("script");s.onload=()=>{r.resolve()},s.src=e,document.head.appendChild(s)}return await r.promise,a()}get runtimeEnv(){return typeof process<"u"?"node":"browser"}get isBrowser(){return!this.isNode}get userAgent(){return this.isBrowser?navigator.userAgent:"undefined"}get isNode(){return this.runtimeEnv==="node"}get nodeVersion(){return process.version}get isCI(){return this.isNode?!!process.env.CI:!1}async isMacAsync(){return this.isNode?(await this.getSafeNodeModule("os")).platform()==="darwin":!1}async isWindowsAsync(){return this.isNode?(await this.getSafeNodeModule("os")).platform()==="win32":!1}async isLinuxAsync(){return this.isNode?(await this.getSafeNodeModule("os")).platform()==="linux":!1}async printEnv(){this.isNode?(console.log("running on NODE"),console.log("node version is "+this.nodeVersion)):(console.log("running on BROWSER"),console.log("browser is "+this.userAgent))}};var YHa=i(t=>{let e=[],a=new DataView(t);for(let r=0;r<a.byteLength;r+=4){let o=a.getUint32(r).toString(16),n="00000000",l=(n+o).slice(-n.length);e.push(l)}return e.join("")},"hex"),KHa=i(async t=>{let e=new FW.Smartenv;if(e.isBrowser){let a=new TextEncoder().encode(t),r=await crypto.subtle.digest("SHA-256",a);return YHa(r)}else if(e.isNode)return await(await e.getSafeNodeModule("@pushrocks/smarthash")).sha256FromString(t)},"sha256FromString");Fh();j4();Y2();F3e();ms();jn();o3();kQ();var gJe="__typedsocket_tag__";function XHa(t){return{peer:t,async getTagById(e){if(!t.tags.has(e))return;let a=t.data.get(`${gJe}${e}`);return{id:e,payload:a}}}}i(XHa,"wrapSmartServePeer");var bJe=class t{static{i(this,"TypedSocket")}static async createClient(e,a,r={}){let o={...{autoReconnect:!0,maxRetries:100,initialBackoffMs:1e3,maxBackoffMs:6e4},...r},n=new t("client",e);return n.clientOptions=o,n.serverUrl=a,n.currentBackoff=o.initialBackoffMs,await n.connect(),n}static{this.useWindowLocationOriginUrl=()=>pn.Smarturl.createFromUrl(globalThis.location.origin).toString()}static fromSmartServe(e,a){let r=new Map;t.registerTagHandlers(a);let s=new t("server",a);return s.smartServeRef=e,s.smartServeConnectionWrappers=r,s}static registerTagHandlers(e){e.addTypedHandler(new Nr.TypedHandler("__typedsocket_setTag",async(a,r)=>{let s=r?.localData?.peer;return s?(s.tags.add(a.name),s.data.set(`${gJe}${a.name}`,a.payload),{success:!0}):(console.warn("setTag: No peer found in request context"),{success:!1})})),e.addTypedHandler(new Nr.TypedHandler("__typedsocket_removeTag",async(a,r)=>{let s=r?.localData?.peer;return s?(s.tags.delete(a.name),s.data.delete(`${gJe}${a.name}`),{success:!0}):(console.warn("removeTag: No peer found in request context"),{success:!1})}))}constructor(e,a){this.statusSubject=new Ma.rxjs.Subject,this.connectionStatus="new",this.websocket=null,this.clientOptions=null,this.serverUrl="",this.retryCount=0,this.currentBackoff=1e3,this.pendingRequests=new Map,this.smartServeRef=null,this.smartServeConnectionWrappers=new Map,this.side=e,this.typedrouter=a}async connect(){let e=ft.defer();this.updateStatus("connecting");let a=this.toWebSocketUrl(this.serverUrl);console.log(`TypedSocket connecting to ${a}...`),this.websocket=new WebSocket(a);let r=setTimeout(()=>{this.connectionStatus!=="connected"&&(console.warn("TypedSocket connection timeout"),this.websocket?.close(),e.reject(new Error("Connection timeout")))},1e4);this.websocket.onopen=()=>{clearTimeout(r),console.log("TypedSocket connected!"),this.updateStatus("connected"),this.retryCount=0,this.currentBackoff=this.clientOptions?.initialBackoffMs??1e3,e.resolve()},this.websocket.onmessage=async s=>{await this.handleMessage(s.data)},this.websocket.onclose=()=>{clearTimeout(r),this.handleDisconnect()},this.websocket.onerror=s=>{console.error("TypedSocket WebSocket error:",s)};try{await e.promise}catch(s){if(clearTimeout(r),this.clientOptions?.autoReconnect)await this.scheduleReconnect();else throw s}}toWebSocketUrl(e){let a=new URL(e);return`${a.protocol==="https:"?"wss:":"ws:"}//${a.host}${a.pathname}`}async handleMessage(e){try{let a=typeof e=="string"?e:new TextDecoder().decode(e),r=So.parse(a);if(r.correlation?.id&&this.pendingRequests.has(r.correlation.id)){let o=this.pendingRequests.get(r.correlation.id);this.pendingRequests.delete(r.correlation.id),o.resolve(r);return}let s=await this.typedrouter.routeAndAddResponse(r);s&&this.websocket?.readyState===WebSocket.OPEN&&this.websocket.send(So.stringify(s))}catch(a){console.error("TypedSocket failed to process message:",a)}}handleDisconnect(){if(this.connectionStatus!=="disconnected"){this.updateStatus("disconnected");for(let[e,a]of this.pendingRequests)a.reject(new Error("TypedSocket disconnected"));this.pendingRequests.clear(),this.clientOptions?.autoReconnect&&this.retryCount<this.clientOptions.maxRetries&&this.scheduleReconnect()}}async scheduleReconnect(){if(!this.clientOptions)return;this.updateStatus("reconnecting"),this.retryCount++;let e=this.currentBackoff*.2*(Math.random()*2-1),a=Math.min(this.currentBackoff+e,this.clientOptions.maxBackoffMs);console.log(`TypedSocket reconnecting in ${Math.round(a)}ms (attempt ${this.retryCount}/${this.clientOptions.maxRetries})`),await Wt.delayFor(a),this.currentBackoff=Math.min(this.currentBackoff*2,this.clientOptions.maxBackoffMs);try{await this.connect()}catch(r){console.error("TypedSocket reconnection failed:",r)}}updateStatus(e){this.connectionStatus!==e&&(this.connectionStatus=e,this.statusSubject.next(e))}async sendRequest(e){if(!this.websocket||this.websocket.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");return new Promise((a,r)=>{let s=setTimeout(()=>{this.pendingRequests.delete(e.correlation.id),r(new Error("Request timeout"))},3e4);this.pendingRequests.set(e.correlation.id,{resolve:i(o=>{clearTimeout(s),a(o)},"resolve"),reject:i(o=>{clearTimeout(s),r(o)},"reject")}),this.websocket.send(So.stringify(e))})}createTypedRequest(e,a){let r=i(async s=>{if(this.side==="client")return this.sendRequest(s);if(!this.smartServeRef)throw new Error("Server not initialized");let o=a;if(!o){let l=this.smartServeRef.getWebSocketConnections();if(l.length===1){let c=l[0];o=this.getOrCreateWrapper(c)}else throw l.length===0?new Error("No WebSocket connections available"):new Error("Multiple connections available - specify targetConnection")}let n=await this.typedrouter.fireEventInterestMap.addInterest(s.correlation.id,s);return o.peer.send(So.stringify(s)),await n.interestFullfilled},"postMethod");return new Nr.TypedRequest(new Nr.TypedTarget({postMethod:r}),e)}getStatus(){return this.connectionStatus}async stop(){this.side==="client"?(this.clientOptions&&(this.clientOptions.autoReconnect=!1),this.websocket&&(this.websocket.close(),this.websocket=null),this.pendingRequests.clear()):this.smartServeConnectionWrappers.clear()}async setTag(e,a){if(this.side!=="client")throw new Error("setTag is only available on clients");if(!(await this.createTypedRequest("__typedsocket_setTag").fire({name:e,payload:a})).success)throw new Error("Failed to set tag on server")}async removeTag(e){if(this.side!=="client")throw new Error("removeTag is only available on clients");if(!(await this.createTypedRequest("__typedsocket_removeTag").fire({name:e})).success)throw new Error("Failed to remove tag on server")}getOrCreateWrapper(e){let a=this.smartServeConnectionWrappers.get(e.id);return a||(a=XHa(e),this.smartServeConnectionWrappers.set(e.id,a)),a}async findAllTargetConnections(e){if(this.side!=="server"||!this.smartServeRef)throw new Error("findAllTargetConnections is only available on servers");let a=[];for(let r of this.smartServeRef.getWebSocketConnections()){let s=this.getOrCreateWrapper(r);await e(s)&&a.push(s)}return a}async findTargetConnection(e){return(await this.findAllTargetConnections(e))[0]}async findAllTargetConnectionsByTag(e,a){if(this.side!=="server"||!this.smartServeRef)throw new Error("findAllTargetConnectionsByTag is only available on servers");let r=this.smartServeRef.getWebSocketConnectionsByTag(e),s=[];for(let o of r){let n=this.getOrCreateWrapper(o);if(a!==void 0){let l=await n.getTagById(e);if(So.stringify(l?.payload)!==So.stringify(a))continue}s.push(n)}return s}async findTargetConnectionByTag(e,a){return(await this.findAllTargetConnectionsByTag(e,a))[0]}};le();Tt();var Oie=Oi(oha(),1),Ke=At;j4();var qJe={};pt(qJe,{DCROUTER_BUILTIN_PROVIDER_ID:()=>UVa,dnsProviderTypeDescriptors:()=>nha,getDnsProviderTypeDescriptor:()=>WVa});var UVa="__dcrouter__",nha=[{type:"dcrouter",displayName:"DcRouter (built-in)",description:"Built-in authoritative DNS. Records are served directly by dcrouter \u2014 delegate the domain's NS records to make this effective.",credentialFields:[]},{type:"cloudflare",displayName:"Cloudflare",description:"External DNS provider. The provider stays authoritative; dcrouter pushes record changes via its API.",credentialFields:[{key:"apiToken",label:"API Token",helpText:"A Cloudflare API token with Zone:Read and DNS:Edit permissions for the target zones.",required:!0,secret:!0}]}];function WVa(t){return nha.find(e=>e.type===t)}i(WVa,"getDnsProviderTypeDescriptor");var lha={};var fs=new Ke.plugins.smartstate.Smartstate,Ia=await fs.getStatePart("login",{identity:null,isLoggedIn:!1},"persistent"),nr=await fs.getStatePart("stats",{serverStats:null,emailStats:null,dnsStats:null,securityMetrics:null,radiusStats:null,vpnStats:null,lastUpdated:0,isLoading:!1,error:null},"soft"),h4=await fs.getStatePart("config",{config:null,isLoading:!1,error:null}),GVa=i(()=>{let t=typeof window<"u"?window.location.pathname:"/",e=["overview","network","email","logs","access","security","domains"],r=t.split("/").filter(Boolean)[0];return e.includes(r)?r:"overview"},"getInitialView"),YVa=i(()=>(typeof window<"u"?window.location.pathname:"/").split("/").filter(Boolean)[1]??null,"getInitialSubview"),Os=await fs.getStatePart("ui",{activeView:GVa(),activeSubview:YVa(),sidebarCollapsed:!1,autoRefresh:!0,refreshInterval:1e3,theme:"light"}),pc=await fs.getStatePart("logs",{recentLogs:[],isStreaming:!1,filters:{}},"soft"),p4=await fs.getStatePart("network",{connections:[],connectionsByIP:{},throughputRate:{bytesInPerSecond:0,bytesOutPerSecond:0},totalBytes:{in:0,out:0},topIPs:[],topIPsByBandwidth:[],throughputByIP:[],domainActivity:[],throughputHistory:[],requestsPerSecond:0,requestsTotal:0,backends:[],frontendProtocols:null,backendProtocols:null,lastUpdated:0,isLoading:!1,error:null},"soft"),qie=await fs.getStatePart("emailOps",{emails:[],isLoading:!1,error:null,lastUpdated:0},"soft"),Ao=await fs.getStatePart("certificates",{certificates:[],summary:{total:0,valid:0,expiring:0,expired:0,failed:0,unknown:0},isLoading:!1,error:null,lastUpdated:0},"soft"),z5=await fs.getStatePart("acmeConfig",{config:null,isLoading:!1,error:null,lastUpdated:0},"soft"),Ri=await fs.getStatePart("remoteIngress",{edges:[],statuses:[],selectedEdgeId:null,newEdgeId:null,isLoading:!1,error:null,lastUpdated:0},"soft"),Fa=await fs.getStatePart("routeManagement",{mergedRoutes:[],warnings:[],apiTokens:[],isLoading:!1,error:null,lastUpdated:0},"soft"),GW=await fs.getStatePart("users",{users:[],isLoading:!1,error:null,lastUpdated:0},"soft"),ut=i(()=>{let t=Ia.getState().identity;return t&&t.expiresAt&&t.expiresAt<Date.now()?{identity:null}:{identity:t}},"getActionContext"),hha=Ia.createAction(async(t,e)=>{let a=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","adminLoginWithUsernameAndPassword");try{let r=await a.fire({username:e.username,password:e.password});return r.identity?{identity:r.identity,isLoggedIn:!0}:t.getState()}catch(r){return console.error("Login failed:",r),t.getState()}}),Gm=Ia.createAction(async t=>{let e=ut();if(e.identity){let a=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","adminLogout");try{await a.fire({identity:e.identity})}catch(r){console.error("Logout error:",r)}}return{identity:null,isLoggedIn:!1}}),Ym=nr.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:e.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:!1,radius:!0,vpn:!0}});return{serverStats:s.metrics.server||a.serverStats,emailStats:s.metrics.email||a.emailStats,dnsStats:s.metrics.dns||a.dnsStats,securityMetrics:s.metrics.security||a.securityMetrics,radiusStats:s.metrics.radius||a.radiusStats,vpnStats:s.metrics.vpn||a.vpnStats,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(r){return{...a,isLoading:!1,error:r.message||"Failed to fetch statistics"}}}),Hie=h4.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{config:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getConfiguration").fire({identity:e.identity})).config,isLoading:!1,error:null}}catch(r){return{...a,isLoading:!1,error:r.message||"Failed to fetch configuration"}}}),Vie=pc.createAction(async(t,e)=>{let a=ut();if(!a.identity)return t.getState();let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRecentLogs").fire({identity:a.identity,limit:e.limit||100,level:e.level,category:e.category});return{...t.getState(),recentLogs:s.logs}}),Pmo=Os.createAction(async t=>{let e=t.getState();return{...e,autoRefresh:!e.autoRefresh}}),Emo=Os.createAction(async(t,e)=>{let a=t.getState();return e==="network"&&a.activeView!=="network"&&setTimeout(()=>{p4.dispatchAction(WJe,null)},100),e==="domains"&&a.activeView!=="domains"&&setTimeout(()=>{Ao.dispatchAction(u4,null)},100),{...a,activeView:e}}),WJe=p4.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getActiveConnections").fire({identity:e.identity}),n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getNetworkStats").fire({identity:e.identity}),l={};return n.connectionsByIP&&Array.isArray(n.connectionsByIP)?n.connectionsByIP.forEach(c=>{l[c.ip]=c.count}):s.connections.forEach(c=>{let d=c.remoteAddress;l[d]=(l[d]||0)+1}),{connections:s.connections,connectionsByIP:l,throughputRate:n.throughputRate||{bytesInPerSecond:0,bytesOutPerSecond:0},totalBytes:n.totalDataTransferred?{in:n.totalDataTransferred.bytesIn,out:n.totalDataTransferred.bytesOut}:{in:0,out:0},topIPs:n.topIPs||[],topIPsByBandwidth:n.topIPsByBandwidth||[],throughputByIP:n.throughputByIP||[],domainActivity:n.domainActivity||[],throughputHistory:n.throughputHistory||[],requestsPerSecond:n.requestsPerSecond||0,requestsTotal:n.requestsTotal||0,backends:n.backends||[],frontendProtocols:n.frontendProtocols||null,backendProtocols:n.backendProtocols||null,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(r){return console.error("Failed to fetch network stats:",r),{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch network stats"}}}),mha=qie.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{emails:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getAllEmails").fire({identity:e.identity})).emails,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch emails"}}}),u4=Ao.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getCertificateOverview").fire({identity:e.identity});return{certificates:s.certificates,summary:s.summary,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch certificate overview"}}}),gha=Ao.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","reprovisionCertificateDomain").fire({identity:r.identity,domain:e.domain,forceRenew:e.forceRenew}),await a.dispatch(u4,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to reprovision certificate"}}}),bha=Ao.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteCertificate").fire({identity:r.identity,domain:e}),await a.dispatch(u4,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete certificate"}}}),vha=Ao.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","importCertificate").fire({identity:r.identity,cert:e}),await a.dispatch(u4,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to import certificate"}}});async function xha(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","exportCertificate").fire({identity:e.identity,domain:t})}i(xha,"fetchCertificateExport");async function GJe(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRemoteIngressConnectionToken").fire({identity:e.identity,edgeId:t})}i(GJe,"fetchConnectionToken");var k5=Ri.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRemoteIngresses"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getRemoteIngressStatus"),[o,n]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity})]);return{...a,edges:o.edges,statuses:n.statuses,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch remote ingress data"}}}),yha=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createRemoteIngress").fire({identity:r.identity,name:e.name,listenPorts:e.listenPorts,autoDerivePorts:e.autoDerivePorts,tags:e.tags});return n.success?(await a.dispatch(k5,null),{...t.getState(),newEdgeId:n.edge.id}):s}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to create edge"}}}),wha=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteRemoteIngress").fire({identity:r.identity,id:e}),await a.dispatch(k5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete edge"}}}),Mha=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateRemoteIngress").fire({identity:r.identity,id:e.id,name:e.name,listenPorts:e.listenPorts,autoDerivePorts:e.autoDerivePorts,tags:e.tags}),await a.dispatch(k5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to update edge"}}}),kha=Ri.createAction(async(t,e)=>{let a=ut(),r=t.getState();try{return(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","regenerateRemoteIngressSecret").fire({identity:a.identity,id:e})).success?{...r,newEdgeId:e}:r}catch(s){return{...r,error:s instanceof Error?s.message:"Failed to regenerate secret"}}}),Sha=Ri.createAction(async t=>({...t.getState(),newEdgeId:null})),YJe=Ri.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateRemoteIngress").fire({identity:r.identity,id:e.id,enabled:e.enabled}),await a.dispatch(k5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle edge"}}}),Fi=await fs.getStatePart("vpn",{clients:[],connectedClients:[],status:null,isLoading:!1,error:null,lastUpdated:0,newClientConfig:null},"soft"),S5=Fi.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getVpnClients"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getVpnStatus"),o=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getVpnConnectedClients"),[n,l,c]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity}),o.fire({identity:e.identity})]);return{...a,clients:n.clients,connectedClients:c.connectedClients,status:l.status,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch VPN data"}}}),Cha=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createVpnClient").fire({identity:r.identity,clientId:e.clientId,targetProfileIds:e.targetProfileIds,description:e.description,destinationAllowList:e.destinationAllowList,destinationBlockList:e.destinationBlockList,useHostIp:e.useHostIp,useDhcp:e.useDhcp,staticIp:e.staticIp,forceVlan:e.forceVlan,vlanId:e.vlanId});return n.success?{...await a.dispatch(S5,null),newClientConfig:n.wireguardConfig||null}:{...s,error:n.message||"Failed to create client"}}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to create VPN client"}}}),zha=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteVpnClient").fire({identity:r.identity,clientId:e}),await a.dispatch(S5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete VPN client"}}}),KJe=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let o=e.enabled?"enableVpnClient":"disableVpnClient";return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest",o).fire({identity:r.identity,clientId:e.clientId}),await a.dispatch(S5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle VPN client"}}}),Tha=Fi.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateVpnClient").fire({identity:r.identity,clientId:e.clientId,description:e.description,targetProfileIds:e.targetProfileIds,destinationAllowList:e.destinationAllowList,destinationBlockList:e.destinationBlockList,useHostIp:e.useHostIp,useDhcp:e.useDhcp,staticIp:e.staticIp,forceVlan:e.forceVlan,vlanId:e.vlanId});return n.success?await a.dispatch(S5,null):{...s,error:n.message||"Failed to update client"}}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to update VPN client"}}}),_ha=Fi.createAction(async t=>({...t.getState(),newClientConfig:null})),Zi=await fs.getStatePart("targetProfiles",{profiles:[],isLoading:!1,error:null,lastUpdated:0},"soft"),f4=Zi.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{profiles:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getTargetProfiles").fire({identity:e.identity})).profiles,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch target profiles"}}}),Lha=Zi.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createTargetProfile").fire({identity:r.identity,name:e.name,description:e.description,domains:e.domains,targets:e.targets,routeRefs:e.routeRefs});return o.success?await a.dispatch(f4,null):{...t.getState(),error:o.message||"Failed to create target profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create target profile"}}}),$ha=Zi.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateTargetProfile").fire({identity:r.identity,id:e.id,name:e.name,description:e.description,domains:e.domains,targets:e.targets,routeRefs:e.routeRefs});return o.success?await a.dispatch(f4,null):{...t.getState(),error:o.message||"Failed to update target profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update target profile"}}}),ZJe=Zi.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteTargetProfile").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(f4,null):{...t.getState(),error:o.message||"Failed to delete target profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete target profile"}}}),Ua=await fs.getStatePart("profilesTargets",{profiles:[],targets:[],isLoading:!1,error:null,lastUpdated:0},"soft"),Io=Ua.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getSourceProfiles"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getNetworkTargets"),[o,n]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity})]);return{profiles:o.profiles,targets:n.targets,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch profiles/targets"}}}),Dha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createSourceProfile").fire({identity:r.identity,name:e.name,description:e.description,security:e.security,extendsProfiles:e.extendsProfiles}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create profile"}}}),Aha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateSourceProfile").fire({identity:r.identity,id:e.id,name:e.name,description:e.description,security:e.security,extendsProfiles:e.extendsProfiles}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update profile"}}}),XJe=Ua.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteSourceProfile").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(Io,null):{...t.getState(),error:o.message||"Failed to delete profile"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete profile"}}}),Iha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createNetworkTarget").fire({identity:r.identity,name:e.name,description:e.description,host:e.host,port:e.port}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create target"}}}),Pha=Ua.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateNetworkTarget").fire({identity:r.identity,id:e.id,name:e.name,description:e.description,host:e.host,port:e.port}),await a.dispatch(Io,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update target"}}}),QJe=Ua.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteNetworkTarget").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(Io,null):{...t.getState(),error:o.message||"Failed to delete target"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete target"}}}),Bt=await fs.getStatePart("domains",{providers:[],domains:[],records:[],selectedDomainId:null,isLoading:!1,error:null,lastUpdated:0},"soft"),Ni=Bt.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let r=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getDnsProviders"),s=new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getDomains"),[o,n]=await Promise.all([r.fire({identity:e.identity}),s.fire({identity:e.identity})]);return{...a,providers:o.providers,domains:n.domains,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch domains/providers"}}}),fc=Bt.createAction(async(t,e)=>{let a=ut(),r=t.getState();if(!a.identity)return r;try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getDnsRecords").fire({identity:a.identity,domainId:e.domainId});return{...r,records:o.records,selectedDomainId:e.domainId,error:null}}catch(s){return{...r,error:s instanceof Error?s.message:"Failed to fetch DNS records"}}}),Eha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createDnsProvider").fire({identity:r.identity,name:e.name,type:e.type,credentials:e.credentials});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to create provider"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create provider"}}}),Nha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateDnsProvider").fire({identity:r.identity,id:e.id,name:e.name,credentials:e.credentials});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to update provider"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update provider"}}}),Rha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteDnsProvider").fire({identity:r.identity,id:e.id,force:e.force});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to delete provider"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete provider"}}}),Fha=Bt.createAction(async(t,e,a)=>{let r=ut();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","testDnsProvider").fire({identity:r.identity,id:e.id}),await a.dispatch(Ni,null)}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to test provider"}}});async function Oha(t){let e=ut();return e.identity?await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","listProviderDomains").fire({identity:e.identity,providerId:t}):{success:!1,message:"Not authenticated"}}i(Oha,"fetchProviderDomains");var Bha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createDomain").fire({identity:r.identity,name:e.name,description:e.description});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to create domain"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create domain"}}}),qha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","importDomain").fire({identity:r.identity,providerId:e.providerId,domainNames:e.domainNames});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to import domains"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to import domains"}}}),Hha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteDomain").fire({identity:r.identity,id:e.id});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to delete domain"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete domain"}}}),Vha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","syncDomain").fire({identity:r.identity,id:e.id});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Failed to sync domain"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to sync domain"}}}),jha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","migrateDomain").fire({identity:r.identity,...e});return o.success?await a.dispatch(Ni,null):{...t.getState(),error:o.message||"Migration failed"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Migration failed"}}}),Uha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createDnsRecord").fire({identity:r.identity,domainId:e.domainId,name:e.name,type:e.type,value:e.value,ttl:e.ttl,proxied:e.proxied});return o.success?await a.dispatch(fc,{domainId:e.domainId}):{...t.getState(),error:o.message||"Failed to create record"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to create record"}}}),Wha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateDnsRecord").fire({identity:r.identity,id:e.id,name:e.name,value:e.value,ttl:e.ttl,proxied:e.proxied});return o.success?await a.dispatch(fc,{domainId:e.domainId}):{...t.getState(),error:o.message||"Failed to update record"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update record"}}}),Gha=Bt.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteDnsRecord").fire({identity:r.identity,id:e.id});return o.success?await a.dispatch(fc,{domainId:e.domainId}):{...t.getState(),error:o.message||"Failed to delete record"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to delete record"}}}),JJe=z5.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{return{config:(await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getAcmeConfig").fire({identity:e.identity})).config,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch ACME config"}}}),Yha=z5.createAction(async(t,e,a)=>{let r=ut();try{let o=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateAcmeConfig").fire({identity:r.identity,accountEmail:e.accountEmail,enabled:e.enabled,useProduction:e.useProduction,autoRenew:e.autoRenew,renewThresholdDays:e.renewThresholdDays});return o.success?await a.dispatch(JJe,null):{...t.getState(),error:o.message||"Failed to update ACME config"}}catch(s){return{...t.getState(),error:s instanceof Error?s.message:"Failed to update ACME config"}}}),E2=Fa.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getMergedRoutes").fire({identity:e.identity});return{...a,mergedRoutes:s.routes,warnings:s.warnings,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(r){return{...a,isLoading:!1,error:r instanceof Error?r.message:"Failed to fetch routes"}}}),Kha=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createRoute").fire({identity:r.identity,route:e.route,enabled:e.enabled,metadata:e.metadata}),await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to create route"}}}),Zha=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","updateRoute").fire({identity:r.identity,id:e.id,route:e.route,enabled:e.enabled,metadata:e.metadata});if(!n.success)throw new Error(n.message||"Failed to update route");return await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to update route"}}}),eet=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteRoute").fire({identity:r.identity,id:e});if(!n.success)throw new Error(n.message||"Failed to delete route");return await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to delete route"}}}),Xha=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{let n=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","toggleRoute").fire({identity:r.identity,id:e.id,enabled:e.enabled});if(!n.success)throw new Error(n.message||"Failed to toggle route");return await a.dispatch(E2,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle route"}}}),T5=Fa.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","listApiTokens").fire({identity:e.identity});return{...a,apiTokens:s.tokens}}catch(r){return{...a,error:r instanceof Error?r.message:"Failed to fetch tokens"}}}),tet=GW.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","listUsers").fire({identity:e.identity});return{...a,users:s.users,error:null,lastUpdated:Date.now()}}catch(r){return{...a,error:r instanceof Error?r.message:"Failed to fetch users"}}});async function Qha(t,e,a){let r=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createApiToken").fire({identity:r.identity,name:t,scopes:e,expiresInDays:a})}i(Qha,"createApiToken");async function Jha(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","rollApiToken").fire({identity:e.identity,id:t})}i(Jha,"rollApiToken");var e8a=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","revokeApiToken").fire({identity:r.identity,id:e}),await a.dispatch(T5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to revoke token"}}}),aet=Fa.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","toggleApiToken").fire({identity:r.identity,id:e.id,enabled:e.enabled}),await a.dispatch(T5,null)}catch(o){return{...s,error:o instanceof Error?o.message:"Failed to toggle token"}}}),fo=await fs.getStatePart("emailDomains",{domains:[],isLoading:!1,lastUpdated:0},"soft"),C5=fo.createAction(async t=>{let e=ut(),a=t.getState();if(!e.identity)return a;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getEmailDomains").fire({identity:e.identity});return{...a,domains:s.domains,isLoading:!1,lastUpdated:Date.now()}}catch{return{...a,isLoading:!1}}}),t8a=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","createEmailDomain").fire({identity:r.identity,...e}),await a.dispatch(C5,null)}catch{return s}}),a8a=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","deleteEmailDomain").fire({identity:r.identity,id:e}),await a.dispatch(C5,null)}catch{return s}}),r8a=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","validateEmailDomain").fire({identity:r.identity,id:e}),await a.dispatch(C5,null)}catch{return s}}),ret=fo.createAction(async(t,e,a)=>{let r=ut(),s=t.getState();try{return await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","provisionEmailDomainDns").fire({identity:r.identity,id:e}),await a.dispatch(C5,null)}catch{return s}});async function i8a(t){let e=ut();return new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getEmailDomainDnsRecords").fire({identity:e.identity,id:t})}i(i8a,"fetchEmailDomainDnsRecords");var w5=null,cha=new Ke.plugins.typedrequest.TypedRouter,Bie=[],HJe=!1;function KVa(){if(HJe=!1,Bie.length===0)return;let t=pc.getState(),e=[...t.recentLogs,...Bie];Bie=[],e.length>2e3&&e.splice(0,e.length-2e3),pc.setState({...t,recentLogs:e})}i(KVa,"flushLogEntries"),cha.addTypedHandler(new Ke.plugins.typedrequest.TypedHandler("pushLogEntry",async t=>(Bie.push(t.entry),HJe||(HJe=!0,requestAnimationFrame(KVa)),{})));async function VJe(){if(!w5)try{w5=await qm.TypedSocket.createClient(cha,qm.TypedSocket.useWindowLocationOriginUrl()),await w5.setTag("role","ops_dashboard")}catch(t){console.error("TypedSocket connection failed:",t),w5=null}}i(VJe,"connectSocket");async function dha(){if(w5){try{await w5.stop()}catch{}w5=null}}i(dha,"disconnectSocket");var jJe=!1;async function ZVa(){if(!jJe){jJe=!0;try{await XVa()}finally{jJe=!1}}}i(ZVa,"dispatchCombinedRefreshAction");async function XVa(){let t=ut();if(!t.identity)return;let e=Os.getState().activeView,a=Os.getState().activeSubview;try{let s=await new Ke.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:t.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:e==="network",radius:!0,vpn:!0}}),o=nr.getState();if(nr.setState({...o,serverStats:s.metrics.server||o.serverStats,emailStats:s.metrics.email||o.emailStats,dnsStats:s.metrics.dns||o.dnsStats,securityMetrics:s.metrics.security||o.securityMetrics,radiusStats:s.metrics.radius||o.radiusStats,vpnStats:s.metrics.vpn||o.vpnStats,lastUpdated:Date.now(),isLoading:!1,error:null}),s.metrics.network&&e==="network"){let n=s.metrics.network,l={};n.connectionDetails.forEach(d=>{l[d.remoteAddress]=(l[d.remoteAddress]||0)+1});let c=n.connectionDetails.map((d,u)=>({id:`ip-${d.remoteAddress}`,remoteAddress:d.remoteAddress,localAddress:"server",startTime:d.startTime,protocol:d.protocol,state:d.state,bytesReceived:d.bytesIn,bytesSent:d.bytesOut}));p4.setState({...p4.getState(),connections:c,connectionsByIP:l,throughputRate:{bytesInPerSecond:n.totalBandwidth.in,bytesOutPerSecond:n.totalBandwidth.out},totalBytes:n.totalBytes||{in:0,out:0},topIPs:n.topEndpoints.map(d=>({ip:d.endpoint,count:d.connections})),topIPsByBandwidth:(n.topEndpointsByBandwidth||[]).map(d=>({ip:d.endpoint,count:d.connections,bwIn:d.bandwidth?.in||0,bwOut:d.bandwidth?.out||0})),throughputByIP:n.topEndpoints.map(d=>({ip:d.endpoint,in:d.bandwidth?.in||0,out:d.bandwidth?.out||0})),domainActivity:n.domainActivity||[],throughputHistory:n.throughputHistory||[],requestsPerSecond:n.requestsPerSecond||0,requestsTotal:n.requestsTotal||0,backends:n.backends||[],frontendProtocols:n.frontendProtocols||null,backendProtocols:n.backendProtocols||null,lastUpdated:Date.now(),isLoading:!1,error:null})}if(e==="domains"&&a==="certificates")try{await Ao.dispatchAction(u4,null)}catch(n){console.error("Certificate refresh failed:",n)}if(e==="network"&&a==="remoteingress")try{await Ri.dispatchAction(k5,null)}catch(n){console.error("Remote ingress refresh failed:",n)}if(e==="network"&&a==="vpn")try{await Fi.dispatchAction(S5,null)}catch(n){console.error("VPN refresh failed:",n)}}catch(r){console.error("Combined refresh failed:",r);let s=String(r);(s.includes("invalid")||s.includes("unauthorized")||s.includes("401"))&&(await Ia.dispatchAction(Gm,null),window.location.reload())}}i(XVa,"dispatchCombinedRefreshActionInner");var QVa=nr.createAction(async t=>(await ZVa(),t.getState())),M5=null,UJe=i(()=>{let t=Os.getState(),e=Ia.getState();t.autoRefresh&&e.isLoggedIn?(M5&&(M5.dispose(),M5=null),M5=nr.createScheduledAction({action:QVa,payload:void 0,intervalMs:t.refreshInterval,autoPause:"visibility"})):M5&&(M5.dispose(),M5=null)},"startAutoRefresh"),uha=Os.getState().autoRefresh,pha=Os.getState().refreshInterval,fha=Ia.getState().isLoggedIn;Os.select(t=>({autoRefresh:t.autoRefresh,refreshInterval:t.refreshInterval})).subscribe(t=>{(t.autoRefresh!==uha||t.refreshInterval!==pha)&&(uha=t.autoRefresh,pha=t.refreshInterval,UJe())}),Ia.select(t=>t.isLoggedIn).subscribe(t=>{t!==fha&&(fha=t,UJe(),t?VJe():dha())}),document.addEventListener("visibilitychange",()=>{document.hidden?dha():Ia.getState().isLoggedIn&&VJe()}),UJe(),Ia.getState().isLoggedIn&&VJe();j4();var N2={};pt(N2,{DCROUTER_BUILTIN_PROVIDER_ID:()=>JVa,dnsProviderTypeDescriptors:()=>s8a,getDnsProviderTypeDescriptor:()=>eja});var JVa="__dcrouter__",s8a=[{type:"dcrouter",displayName:"DcRouter (built-in)",description:"Built-in authoritative DNS. Records are served directly by dcrouter \u2014 delegate the domain's NS records to make this effective.",credentialFields:[]},{type:"cloudflare",displayName:"Cloudflare",description:"External DNS provider. The provider stays authoritative; dcrouter pushes record changes via its API.",credentialFields:[{key:"apiToken",label:"API Token",helpText:"A Cloudflare API token with Zone:Read and DNS:Edit permissions for the target zones.",required:!0,secret:!0}]}];function eja(t){return s8a.find(e=>e.type===t)}i(eja,"getDnsProviderTypeDescriptor");var o8a={};var tja=Ke.plugins.smartrouter.SmartRouter,l8a=["logs"],Km={overview:["stats","configuration"],network:["activity","routes","sourceprofiles","networktargets","targetprofiles","remoteingress","vpn"],email:["log","security","domains"],access:["apitokens","users"],security:["overview","blocked","authentication"],domains:["providers","domains","dns","certificates"]},iet={overview:"stats",network:"activity",email:"log",access:"apitokens",security:"overview",domains:"domains"},aja=[...l8a,...Object.keys(Km)];function c8a(t){return aja.includes(t)}i(c8a,"isValidView");function d8a(t,e){return Km[t]?.includes(e)??!1}i(d8a,"isValidSubview");var set=class{static{i(this,"AppRouter")}router;initialized=!1;suppressStateUpdate=!1;constructor(){this.router=new tja({debug:!1})}init(){this.initialized||(this.setupRoutes(),this.setupStateSync(),this.handleInitialRoute(),this.initialized=!0)}setupRoutes(){for(let e of l8a)this.router.on(`/${e}`,async()=>{this.updateViewState(e,null)});for(let e of Object.keys(Km)){this.router.on(`/${e}`,async()=>{this.navigateTo(`/${e}/${iet[e]}`)});for(let a of Km[e])this.router.on(`/${e}/${a}`,async()=>{this.updateViewState(e,a)})}this.router.on("/",async()=>{this.navigateTo("/overview")})}setupStateSync(){Os.select().subscribe(e=>{if(this.suppressStateUpdate)return;let a=window.location.pathname,r=e.activeSubview?`/${e.activeView}/${e.activeSubview}`:`/${e.activeView}`;a!==r&&(this.suppressStateUpdate=!0,this.router.pushUrl(r),this.suppressStateUpdate=!1)})}handleInitialRoute(){let e=window.location.pathname;if(!e||e==="/"){this.router.pushUrl("/overview");return}let a=e.split("/").filter(Boolean),r=a[0],s=a[1];if(!c8a(r)){this.router.pushUrl("/overview");return}Km[r]?s&&d8a(r,s)?this.updateViewState(r,s):this.router.pushUrl(`/${r}/${iet[r]}`):this.updateViewState(r,null)}updateViewState(e,a){this.suppressStateUpdate=!0;let r=Os.getState();(r.activeView!==e||r.activeSubview!==a)&&Os.setState({...r,activeView:e,activeSubview:a}),this.suppressStateUpdate=!1}navigateTo(e){this.router.pushUrl(e)}navigateToView(e,a){if(!c8a(e)){this.navigateTo("/overview");return}a&&d8a(e,a)?this.navigateTo(`/${e}/${a}`):Km[e]?this.navigateTo(`/${e}/${iet[e]}`):this.navigateTo(`/${e}`)}getCurrentView(){return Os.getState().activeView}destroy(){this.router.destroy(),this.initialized=!1}},hc=new set;le();var Yt=W`
42462
42462
  :host {
42463
42463
  display: block;
42464
42464
  margin: auto;
@@ -42941,15 +42941,16 @@ Customer Support Team`}};async onActivate(b){this.appui=b.appui,this.appui.setCo
42941
42941
  </div>
42942
42942
  `}
42943
42943
  </div>
42944
- `}async handleRouteClick(a){let r=a.detail;if(!r)return;let s=this.routeState.mergedRoutes.find(l=>l.route.name===r.name);if(!s)return;let{DeesModal:o}=await Promise.resolve().then(()=>(Tt(),zt)),n=s.metadata;await o.createAndShow({heading:`Route: ${s.route.name}`,content:w`
42944
+ `}async handleRouteClick(a){let r=a.detail;if(!r)return;let s=this.findMergedRoute(r);if(!s)return;let{DeesModal:o}=await Promise.resolve().then(()=>(Tt(),zt)),n=s.metadata,l=this.isSystemManagedRoute(s);await o.createAndShow({heading:`Route: ${s.route.name}`,content:w`
42945
42945
  <div style="color: #ccc; padding: 8px 0;">
42946
42946
  <p>Origin: <strong style="color: #0af;">${s.origin}</strong></p>
42947
42947
  <p>Status: <strong>${s.enabled?"Enabled":"Disabled"}</strong></p>
42948
42948
  <p>ID: <code style="color: #888;">${s.id}</code></p>
42949
+ ${l?w`<p>This route is system-managed. Change its source config to modify it directly.</p>`:""}
42949
42950
  ${n?.sourceProfileName?w`<p>Source Profile: <strong style="color: #a78bfa;">${n.sourceProfileName}</strong></p>`:""}
42950
42951
  ${n?.networkTargetName?w`<p>Network Target: <strong style="color: #a78bfa;">${n.networkTargetName}</strong></p>`:""}
42951
42952
  </div>
42952
- `,menuOptions:[{name:s.enabled?"Disable":"Enable",iconName:s.enabled?"lucide:pause":"lucide:play",action:i(async l=>{await Fa.dispatchAction(Xha,{id:s.id,enabled:!s.enabled}),await l.destroy()},"action")},{name:"Edit",iconName:"lucide:pencil",action:i(async l=>{await l.destroy(),this.showEditRouteDialog(s)},"action")},{name:"Delete",iconName:"lucide:trash-2",action:i(async l=>{await Fa.dispatchAction(eet,s.id),await l.destroy()},"action")},{name:"Close",iconName:"lucide:x",action:i(async l=>await l.destroy(),"action")}]})}async handleRouteEdit(a){let r=a.detail;if(!r)return;let s=this.routeState.mergedRoutes.find(o=>o.route.name===r.name);s&&this.showEditRouteDialog(s)}async handleRouteDelete(a){let r=a.detail;if(!r)return;let s=this.routeState.mergedRoutes.find(n=>n.route.name===r.name);if(!s)return;let{DeesModal:o}=await Promise.resolve().then(()=>(Tt(),zt));await o.createAndShow({heading:`Delete Route: ${s.route.name}`,content:w`
42953
+ `,menuOptions:[{name:s.enabled?"Disable":"Enable",iconName:s.enabled?"lucide:pause":"lucide:play",action:i(async c=>{await Fa.dispatchAction(Xha,{id:s.id,enabled:!s.enabled}),await c.destroy()},"action")},...l?[]:[{name:"Edit",iconName:"lucide:pencil",action:i(async c=>{await c.destroy(),this.showEditRouteDialog(s)},"action")},{name:"Delete",iconName:"lucide:trash-2",action:i(async c=>{await Fa.dispatchAction(eet,s.id),await c.destroy()},"action")}],{name:"Close",iconName:"lucide:x",action:i(async c=>await c.destroy(),"action")}]})}async handleRouteEdit(a){let r=a.detail;if(!r)return;let s=this.findMergedRoute(r);s&&(this.isSystemManagedRoute(s)||this.showEditRouteDialog(s))}async handleRouteDelete(a){let r=a.detail;if(!r)return;let s=this.findMergedRoute(r);if(!s||this.isSystemManagedRoute(s))return;let{DeesModal:o}=await Promise.resolve().then(()=>(Tt(),zt));await o.createAndShow({heading:`Delete Route: ${s.route.name}`,content:w`
42953
42954
  <div style="color: #ccc; padding: 8px 0;">
42954
42955
  <p>Are you sure you want to delete this route? This action cannot be undone.</p>
42955
42956
  </div>
@@ -42991,7 +42992,7 @@ Customer Support Team`}};async onActivate(b){this.appui=b.appui,this.appui.setCo
42991
42992
  </div>
42992
42993
  </div>
42993
42994
  </dees-form>
42994
- `,menuOptions:[{name:"Cancel",iconName:"lucide:x",action:i(async d=>await d.destroy(),"action")},{name:"Create",iconName:"lucide:plus",action:i(async d=>{let u=d.shadowRoot?.querySelector(".content")?.querySelector("dees-form");if(!u)return;let p=await u.collectFormData();if(!p.name||!p.ports)return;let m=p.ports.split(",").map(E=>parseInt(E.trim(),10)).filter(E=>!isNaN(E)),v=Array.isArray(p.domains)?p.domains.filter(Boolean):[],x=p.priority?parseInt(p.priority,10):void 0,b={name:p.name,match:{ports:m,...v.length>0?{domains:v}:{}},action:{type:"forward",targets:[{host:p.targetHost||"localhost",port:parseInt(p.targetPort,10)||443}]},...x!=null&&!isNaN(x)?{priority:x}:{}},g=p.tlsMode,y=typeof g=="string"?g:g?.key;if(y&&y!=="none"){let E={mode:y};if(y!=="passthrough"){let _=p.tlsCertificate;(typeof _=="string"?_:_?.key)==="custom"&&p.tlsCertKey&&p.tlsCertCert?E.certificate={key:p.tlsCertKey,cert:p.tlsCertCert}:E.certificate="auto"}b.action.tls=E}let k={},C=p.sourceProfileRef,R=typeof C=="string"?C:C?.key;R&&(k.sourceProfileRef=R);let T=p.networkTargetRef,S=typeof T=="string"?T:T?.key;S&&(k.networkTargetRef=S),await Fa.dispatchAction(Kha,{route:b,metadata:Object.keys(k).length>0?k:void 0}),await d.destroy()},"action")}]}))?.shadowRoot?.querySelector(".content")?.querySelector("dees-form");c&&(await c.updateComplete,T8a(c))}refreshData(){Fa.dispatchAction(E2,null)}async firstUpdated(){await Fa.dispatchAction(E2,null);let a=this.shadowRoot.querySelector(".routeFilterToggle");if(a){let r=a.changeSubject.subscribe(()=>{this.routeFilter=a.selectedOption});this.rxSubscriptions.push(r)}}};In=qt(D8a),met=new WeakMap,get=new WeakMap,bet=new WeakMap,Qe(In,4,"routeFilter",$8a,R2,met),Qe(In,4,"routeState",L8a,R2,get),Qe(In,4,"profilesTargetsState",_8a,R2,bet),R2=Qe(In,0,"OpsViewRoutes",A8a,R2),i(R2,"OpsViewRoutes"),Mt(R2,"styles",[h.defaultStyles,Yt,W`
42995
+ `,menuOptions:[{name:"Cancel",iconName:"lucide:x",action:i(async d=>await d.destroy(),"action")},{name:"Create",iconName:"lucide:plus",action:i(async d=>{let u=d.shadowRoot?.querySelector(".content")?.querySelector("dees-form");if(!u)return;let p=await u.collectFormData();if(!p.name||!p.ports)return;let m=p.ports.split(",").map(E=>parseInt(E.trim(),10)).filter(E=>!isNaN(E)),v=Array.isArray(p.domains)?p.domains.filter(Boolean):[],x=p.priority?parseInt(p.priority,10):void 0,b={name:p.name,match:{ports:m,...v.length>0?{domains:v}:{}},action:{type:"forward",targets:[{host:p.targetHost||"localhost",port:parseInt(p.targetPort,10)||443}]},...x!=null&&!isNaN(x)?{priority:x}:{}},g=p.tlsMode,y=typeof g=="string"?g:g?.key;if(y&&y!=="none"){let E={mode:y};if(y!=="passthrough"){let _=p.tlsCertificate;(typeof _=="string"?_:_?.key)==="custom"&&p.tlsCertKey&&p.tlsCertCert?E.certificate={key:p.tlsCertKey,cert:p.tlsCertCert}:E.certificate="auto"}b.action.tls=E}let k={},C=p.sourceProfileRef,R=typeof C=="string"?C:C?.key;R&&(k.sourceProfileRef=R);let T=p.networkTargetRef,S=typeof T=="string"?T:T?.key;S&&(k.networkTargetRef=S),await Fa.dispatchAction(Kha,{route:b,metadata:Object.keys(k).length>0?k:void 0}),await d.destroy()},"action")}]}))?.shadowRoot?.querySelector(".content")?.querySelector("dees-form");c&&(await c.updateComplete,T8a(c))}refreshData(){Fa.dispatchAction(E2,null)}findMergedRoute(a){if(a.id){let r=this.routeState.mergedRoutes.find(s=>s.id===a.id);if(r)return r}if(a.name)return this.routeState.mergedRoutes.find(r=>r.route.name===a.name)}isSystemManagedRoute(a){return a.origin!=="api"}async firstUpdated(){await Fa.dispatchAction(E2,null);let a=this.shadowRoot.querySelector(".routeFilterToggle");if(a){let r=a.changeSubject.subscribe(()=>{this.routeFilter=a.selectedOption});this.rxSubscriptions.push(r)}}};In=qt(D8a),met=new WeakMap,get=new WeakMap,bet=new WeakMap,Qe(In,4,"routeFilter",$8a,R2,met),Qe(In,4,"routeState",L8a,R2,get),Qe(In,4,"profilesTargetsState",_8a,R2,bet),R2=Qe(In,0,"OpsViewRoutes",A8a,R2),i(R2,"OpsViewRoutes"),Mt(R2,"styles",[h.defaultStyles,Yt,W`
42995
42996
  .routesContainer {
42996
42997
  display: flex;
42997
42998
  flex-direction: column;
@@ -46314,4 +46315,4 @@ ibantools/jsnext/ibantools.js:
46314
46315
  * @preferred
46315
46316
  *)
46316
46317
  */
46317
- //# sourceMappingURL=bundle-1776159268031.js.map
46318
+ //# sourceMappingURL=bundle-1776283191133.js.map
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '13.17.9',
6
+ version: '13.19.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
@@ -1,6 +1,6 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import * as paths from './paths.js';
3
- import { UnifiedEmailServer, type IUnifiedEmailServerOptions, type IEmailRoute } from '@push.rocks/smartmta';
3
+ import { UnifiedEmailServer, type IUnifiedEmailServerOptions, type IEmailRoute, type IStorageManagerLike } from '@push.rocks/smartmta';
4
4
  import { CertProvisionScheduler } from './classes.cert-provision-scheduler.js';
5
5
  import { DcRouterDb, CacheCleaner } from './db/index.js';
6
6
  import { OpsServer } from './opsserver/index.js';
@@ -12,7 +12,7 @@ import { RouteConfigManager, ApiTokenManager, ReferenceResolver, TargetProfileMa
12
12
  import { type IHttp3Config } from './http3/index.js';
13
13
  import { DnsManager } from './dns/manager.dns.js';
14
14
  import { AcmeConfigManager } from './acme/manager.acme-config.js';
15
- import { EmailDomainManager } from './email/classes.email-domain.manager.js';
15
+ import { EmailDomainManager } from './email/index.js';
16
16
  export interface IDcRouterOptions {
17
17
  /** Base directory for all dcrouter data. Defaults to ~/.serve.zone/dcrouter */
18
18
  baseDir?: string;
@@ -211,7 +211,8 @@ export declare class DcRouter {
211
211
  radiusServer?: RadiusServer;
212
212
  opsServer: OpsServer;
213
213
  metricsManager?: MetricsManager;
214
- storageManager: any;
214
+ private emailEventSubscriptions;
215
+ storageManager: IStorageManagerLike;
215
216
  dcRouterDb?: DcRouterDb;
216
217
  cacheCleaner?: CacheCleaner;
217
218
  remoteIngressManager?: RemoteIngressManager;
@@ -244,6 +245,7 @@ export declare class DcRouter {
244
245
  typedrouter: plugins.typedrequest.TypedRouter<import("@api.global/typedrequest-interfaces").ITypedRequest>;
245
246
  private seedConfigRoutes;
246
247
  private seedEmailRoutes;
248
+ private seedDnsRoutes;
247
249
  private runtimeDnsRoutes;
248
250
  private qenv;
249
251
  constructor(optionsArg: IDcRouterOptions);
@@ -278,6 +280,7 @@ export declare class DcRouter {
278
280
  * Generate SmartProxy routes for DNS configuration
279
281
  */
280
282
  private generateDnsRoutes;
283
+ private hydrateStoredRouteForRuntime;
281
284
  /**
282
285
  * Check if a domain matches a pattern (including wildcard support)
283
286
  * @param domain The domain to check
@@ -347,8 +350,7 @@ export declare class DcRouter {
347
350
  */
348
351
  private generateEmailDnsRecords;
349
352
  /**
350
- * Load DKIM records from JSON files
351
- * Reads all *.dkimrecord.json files from the DNS records directory
353
+ * Generate DKIM DNS records for internal-dns domains from smartmta's selector-aware DKIM state.
352
354
  */
353
355
  private loadDkimRecords;
354
356
  /**
@@ -369,6 +371,8 @@ export declare class DcRouter {
369
371
  * Apply proxy IP replacement logic to DNS records
370
372
  */
371
373
  private applyProxyIpReplacement;
374
+ private addEmailEventSubscription;
375
+ private clearEmailEventSubscriptions;
372
376
  /**
373
377
  * Detect the server's public IP address
374
378
  */