@serve.zone/dcrouter 5.5.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_serve/bundle.js +23 -12
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.cert-provision-scheduler.d.ts +49 -0
- package/dist_ts/classes.cert-provision-scheduler.js +104 -0
- package/dist_ts/classes.dcrouter.d.ts +8 -2
- package/dist_ts/classes.dcrouter.js +63 -27
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +12 -1
- package/dist_ts/opsserver/handlers/certificate.handler.js +119 -35
- package/dist_ts_interfaces/requests/certificate.d.ts +18 -2
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.js +4 -4
- package/dist_ts_web/elements/ops-view-certificates.d.ts +2 -1
- package/dist_ts_web/elements/ops-view-certificates.js +46 -19
- package/package.json +4 -4
- package/readme.md +87 -15
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.cert-provision-scheduler.ts +130 -0
- package/ts/classes.dcrouter.ts +66 -27
- package/ts/opsserver/handlers/certificate.handler.ts +137 -33
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +4 -4
- package/ts_web/elements/ops-view-certificates.ts +43 -18
- package/ts_web/readme.md +9 -0
package/dist_serve/bundle.js
CHANGED
|
@@ -29066,7 +29066,7 @@ html\`<dees-button>Click me</dees-button>\`</code></pre>
|
|
|
29066
29066
|
<h1>Markdown Preview</h1>
|
|
29067
29067
|
<p>Content will appear here when markdown is parsed.</p>
|
|
29068
29068
|
</div>
|
|
29069
|
-
`}async firstUpdated(n){await super.firstUpdated(n),this.outlet=this.shadowRoot.querySelector(".outlet")}async updateHtmlText(n){await this.updateComplete,this.outlet||(this.outlet=this.shadowRoot.querySelector(".outlet")),this.outlet.innerHTML=n}static{yUt(i,a)}};return s=i})()});var $yt=v(()=>{Lyt()});var Ayt=v(()=>{Lj()});var Dyt=v(()=>{Aj()});var Eyt=v(()=>{byt();vyt();xyt();wyt();Myt();kyt();$yt();Ayt();Dyt()});var Pyt=v(()=>{});var Nyt=v(()=>{Pyt()});var Iyt=v(()=>{ue()});var Fyt=v(()=>{Iyt()});var Oyt=v(()=>{fi();qe();yft();Aft();Wft();rmt();$mt();Emt();qgt();Abt();qvt();Qvt();Sw();Gxt();dyt();Eyt();Nyt();Fyt()});var Ryt,Byt=v(()=>{Ryt={name:"@design.estate/dees-catalog",version:"3.42.0",description:"A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."}});var bo={};Je(bo,{CanvasPool:()=>El,DeesActionbar:()=>smt,DeesAppui:()=>cft,DeesAppuiActivitylog:()=>cpt,DeesAppuiBar:()=>Spt,DeesAppuiBottombar:()=>_pt,DeesAppuiMaincontent:()=>lft,DeesAppuiMainmenu:()=>tft,DeesAppuiProfileDropdown:()=>zpt,DeesAppuiSecondarymenu:()=>rft,DeesAppuiTabs:()=>oft,DeesAudioViewer:()=>Obt,DeesBadge:()=>dmt,DeesButton:()=>Z9t,DeesButtonExit:()=>zft,DeesButtonGroup:()=>_ft,DeesChartArea:()=>Rft,DeesChartLog:()=>Vft,DeesChips:()=>Ugt,DeesContextmenu:()=>jt,DeesDashboardgrid:()=>dbt,DeesDataviewCodebox:()=>Zft,DeesDataviewStatusobject:()=>emt,DeesForm:()=>W9t,DeesFormSubmit:()=>Ry,DeesFormattingMenu:()=>nw,DeesHeading:()=>gbt,DeesHint:()=>gmt,DeesIcon:()=>ipt,DeesImageViewer:()=>Pbt,DeesInputBase:()=>Ze,DeesInputCheckbox:()=>Ly,DeesInputCode:()=>Ey,DeesInputDatepicker:()=>Py,DeesInputDropdown:()=>By,DeesInputFileupload:()=>qy,DeesInputIban:()=>Uy,DeesInputList:()=>Hmt,DeesInputMultitoggle:()=>Wy,DeesInputPhone:()=>Yy,DeesInputProfilePicture:()=>Hgt,DeesInputQuantitySelector:()=>Iy,DeesInputRadiogroup:()=>Fy,DeesInputRichtext:()=>egt,DeesInputTags:()=>ogt,DeesInputText:()=>Ny,DeesInputToggle:()=>Zy,DeesInputTypelist:()=>Xy,DeesInputWysiwyg:()=>DV,DeesLabel:()=>Vpt,DeesMobilenavigation:()=>bft,DeesModal:()=>s1,DeesPagination:()=>Mbt,DeesPanel:()=>Ept,DeesPdf:()=>avt,DeesPdfPreview:()=>cvt,DeesPdfViewer:()=>Ybt,DeesPreview:()=>Kbt,DeesProgressbar:()=>Mmt,DeesSearchbar:()=>Kxt,DeesShoppingProductcard:()=>t9t,DeesSimpleAppDash:()=>Oxt,DeesSimpleLogin:()=>jxt,DeesSlashMenu:()=>rw,DeesSpeechbubble:()=>Gvt,DeesSpinner:()=>Smt,DeesStatsGrid:()=>X9t,DeesStepper:()=>_bt,DeesTable:()=>Ky,DeesTheme:()=>iyt,DeesTileAudio:()=>zvt,DeesTileBase:()=>ga,DeesTileFolder:()=>Rvt,DeesTileImage:()=>vvt,DeesTileNote:()=>Evt,DeesTilePdf:()=>dw,DeesTileVideo:()=>_vt,DeesToast:()=>Ot,DeesUpdater:()=>kw,DeesVideoViewer:()=>qbt,DeesWindowControls:()=>Mpt,DeesWindowLayer:()=>mi,DeesWorkspace:()=>myt,DeesWorkspaceBottombar:()=>pyt,DeesWorkspaceDiffEditor:()=>fyt,DeesWorkspaceFiletree:()=>hyt,DeesWorkspaceMarkdown:()=>zyt,DeesWorkspaceMarkdownoutlet:()=>_yt,DeesWorkspaceMonaco:()=>jpt,DeesWorkspaceTerminal:()=>yj,DeesWorkspaceTerminalPreview:()=>uyt,DeesWysiwygBlock:()=>Pgt,PROGRAMMING_LANGUAGES:()=>_8,PdfManager:()=>Br,PerformanceMonitor:()=>Pl,TerminalTabManager:()=>ed,TypeScriptIntelliSenseManager:()=>sd,ViewRegistry:()=>z8,WebContainerEnvironment:()=>d4,WysiwygBlockOperations:()=>L8,WysiwygBlocks:()=>A2,WysiwygConverters:()=>wi,WysiwygDragDropHandler:()=>V8,WysiwygFormatting:()=>Is,WysiwygHistory:()=>j8,WysiwygInputHandler:()=>H8,WysiwygKeyboardHandler:()=>q8,WysiwygModalManager:()=>B8,WysiwygSelection:()=>Re,WysiwygShortcuts:()=>q1,ZIndexRegistry:()=>xf,colors:()=>H0,commitinfo:()=>Ryt,componentZIndex:()=>pBt,debounce:()=>Fjt,formatFileSize:()=>Rjt,getZIndex:()=>uBt,icons:()=>Cy,isInViewport:()=>Bjt,registerAllBlockHandlers:()=>Lgt,themeDefaultStyles:()=>ke,themeDefaults:()=>Zn,throttle:()=>Ojt,tileBaseStyles:()=>J2,wysiwygStyles:()=>SV,zIndexLayers:()=>a2,zIndexRegistry:()=>c1});var p4=v(()=>{Oyt();bi();Byt()});ue();p4();var N1=rt;Tc();var Hyt={};var qyt={};var vo=new N1.plugins.smartstate.Smartstate,zi=await vo.getStatePart("login",{identity:null,isLoggedIn:!1},"persistent"),o2=await vo.getStatePart("stats",{serverStats:null,emailStats:null,dnsStats:null,securityMetrics:null,lastUpdated:0,isLoading:!1,error:null},"soft"),Vr=await vo.getStatePart("config",{config:null,isLoading:!1,error:null}),wUt=()=>{let t=typeof window<"u"?window.location.pathname:"/",e=["overview","network","emails","logs","configuration","security","certificates"],i=t.split("/").filter(Boolean)[0];return e.includes(i)?i:"overview"},Da=await vo.getStatePart("ui",{activeView:wUt(),sidebarCollapsed:!1,autoRefresh:!0,refreshInterval:1e3,theme:"light"}),Tw=await vo.getStatePart("logs",{recentLogs:[],isStreaming:!1,filters:{}},"soft"),qr=await vo.getStatePart("network",{connections:[],connectionsByIP:{},throughputRate:{bytesInPerSecond:0,bytesOutPerSecond:0},totalBytes:{in:0,out:0},topIPs:[],throughputByIP:[],throughputHistory:[],requestsPerSecond:0,requestsTotal:0,lastUpdated:0,isLoading:!1,error:null},"soft"),T1=await vo.getStatePart("emailOps",{currentView:"queued",queuedEmails:[],sentEmails:[],failedEmails:[],securityIncidents:[],bounceRecords:[],suppressionList:[],selectedEmailId:null,isLoading:!1,error:null,lastUpdated:0},"soft"),ar=await vo.getStatePart("certificates",{certificates:[],summary:{total:0,valid:0,expiring:0,expired:0,failed:0,unknown:0},isLoading:!1,error:null,lastUpdated:0},"soft"),xa=()=>({identity:zi.getState().identity}),Vyt=zi.createAction(async(t,e)=>{let a=new N1.plugins.typedrequest.TypedRequest("/typedrequest","adminLoginWithUsernameAndPassword");try{let i=await a.fire({username:e.username,password:e.password});return i.identity?{identity:i.identity,isLoggedIn:!0}:t.getState()}catch(i){return console.error("Login failed:",i),t.getState()}}),Pj=zi.createAction(async t=>{let e=xa();if(!e.identity)return t.getState();let a=new N1.plugins.typedrequest.TypedRequest("/typedrequest","adminLogout");try{await a.fire({identity:e.identity})}catch(i){console.error("Logout error:",i)}return{identity:null,isLoggedIn:!1}}),Vl=o2.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:e.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:!1}});return{serverStats:r.metrics.server||a.serverStats,emailStats:r.metrics.email||a.emailStats,dnsStats:r.metrics.dns||a.dnsStats,securityMetrics:r.metrics.security||a.securityMetrics,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(i){return{...a,isLoading:!1,error:i.message||"Failed to fetch statistics"}}}),jl=Vr.createAction(async t=>{let e=xa(),a=t.getState();try{return{config:(await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getConfiguration").fire({identity:e.identity})).config,isLoading:!1,error:null}}catch(i){return{...a,isLoading:!1,error:i.message||"Failed to fetch configuration"}}}),jyt=Tw.createAction(async(t,e)=>{let a=xa(),r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getRecentLogs").fire({identity:a.identity,limit:e.limit||100,level:e.level,category:e.category});return{...t.getState(),recentLogs:r.logs}}),f92=Da.createAction(async t=>{let e=t.getState();return{...e,autoRefresh:!e.autoRefresh}}),m92=Da.createAction(async(t,e)=>{let a=t.getState();return e==="network"&&a.activeView!=="network"&&setTimeout(()=>{qr.dispatchAction(Nj,null)},100),e==="certificates"&&a.activeView!=="certificates"&&setTimeout(()=>{ar.dispatchAction(ql,null)},100),{...a,activeView:e}}),Nj=qr.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getActiveConnections").fire({identity:e.identity}),n=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getNetworkStats").fire({identity:e.identity}),o={};return n.connectionsByIP&&Array.isArray(n.connectionsByIP)?n.connectionsByIP.forEach(d=>{o[d.ip]=d.count}):r.connections.forEach(d=>{let c=d.remoteAddress;o[c]=(o[c]||0)+1}),{connections:r.connections,connectionsByIP:o,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||[],throughputByIP:n.throughputByIP||[],throughputHistory:n.throughputHistory||[],requestsPerSecond:n.requestsPerSecond||0,requestsTotal:n.requestsTotal||0,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(i){return console.error("Failed to fetch network stats:",i),{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch network stats"}}}),g92=T1.createAction(async(t,e)=>({...t.getState(),currentView:e})),Ij=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getQueuedEmails").fire({identity:e.identity,status:"pending",limit:100});return{...a,queuedEmails:r.items,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch queued emails"}}}),Uyt=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getSentEmails").fire({identity:e.identity,limit:100});return{...a,sentEmails:r.items,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch sent emails"}}}),Fj=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getFailedEmails").fire({identity:e.identity,limit:100});return{...a,failedEmails:r.items,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch failed emails"}}}),Wyt=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getSecurityIncidents").fire({identity:e.identity,limit:100});return{...a,securityIncidents:r.incidents,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch security incidents"}}}),MUt=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getBounceRecords").fire({identity:e.identity,limit:100});return{...a,bounceRecords:r.records,suppressionList:r.suppressionList,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch bounce records"}}}),Gyt=T1.createAction(async(t,e)=>{let a=xa(),i=t.getState();try{return(await new N1.plugins.typedrequest.TypedRequest("/typedrequest","resendEmail").fire({identity:a.identity,emailId:e})).success&&(await T1.dispatchAction(Fj,null),await T1.dispatchAction(Ij,null)),t.getState()}catch(r){return{...i,error:r instanceof Error?r.message:"Failed to resend email"}}}),b92=T1.createAction(async(t,e)=>{let a=xa(),i=t.getState();try{return(await new N1.plugins.typedrequest.TypedRequest("/typedrequest","removeFromSuppressionList").fire({identity:a.identity,email:e})).success&&await T1.dispatchAction(MUt,null),t.getState()}catch(r){return{...i,error:r instanceof Error?r.message:"Failed to remove from suppression list"}}}),ql=ar.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getCertificateOverview").fire({identity:e.identity});return{certificates:r.certificates,summary:r.summary,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch certificate overview"}}}),Yyt=ar.createAction(async(t,e)=>{let a=xa(),i=t.getState();try{return await new N1.plugins.typedrequest.TypedRequest("/typedrequest","reprovisionCertificate").fire({identity:a.identity,routeName:e}),await ar.dispatchAction(ql,null),t.getState()}catch(r){return{...i,error:r instanceof Error?r.message:"Failed to reprovision certificate"}}});async function zUt(){let t=xa(),e=Da.getState().activeView;try{let i=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:t.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:e==="network"}});if(o2.setState({...o2.getState(),serverStats:i.metrics.server||o2.getState().serverStats,emailStats:i.metrics.email||o2.getState().emailStats,dnsStats:i.metrics.dns||o2.getState().dnsStats,securityMetrics:i.metrics.security||o2.getState().securityMetrics,lastUpdated:Date.now(),isLoading:!1,error:null}),i.metrics.network&&e==="network"){let r=i.metrics.network,s={};r.connectionDetails.forEach(n=>{s[n.remoteAddress]=(s[n.remoteAddress]||0)+1});try{let o=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getActiveConnections").fire({identity:t.identity});qr.setState({...qr.getState(),connections:o.connections,connectionsByIP:s,throughputRate:{bytesInPerSecond:r.totalBandwidth.in,bytesOutPerSecond:r.totalBandwidth.out},totalBytes:r.totalBytes||{in:0,out:0},topIPs:r.topEndpoints.map(d=>({ip:d.endpoint,count:d.requests})),throughputByIP:r.topEndpoints.map(d=>({ip:d.endpoint,in:d.bandwidth?.in||0,out:d.bandwidth?.out||0})),throughputHistory:r.throughputHistory||[],requestsPerSecond:r.requestsPerSecond||0,requestsTotal:r.requestsTotal||0,lastUpdated:Date.now(),isLoading:!1,error:null})}catch(n){console.error("Failed to fetch connections:",n),qr.setState({...qr.getState(),connections:[],connectionsByIP:s,throughputRate:{bytesInPerSecond:r.totalBandwidth.in,bytesOutPerSecond:r.totalBandwidth.out},totalBytes:r.totalBytes||{in:0,out:0},topIPs:r.topEndpoints.map(o=>({ip:o.endpoint,count:o.requests})),throughputByIP:r.topEndpoints.map(o=>({ip:o.endpoint,in:o.bandwidth?.in||0,out:o.bandwidth?.out||0})),throughputHistory:r.throughputHistory||[],requestsPerSecond:r.requestsPerSecond||0,requestsTotal:r.requestsTotal||0,lastUpdated:Date.now(),isLoading:!1,error:null})}}if(e==="certificates")try{await ar.dispatchAction(ql,null)}catch(r){console.error("Certificate refresh failed:",r)}}catch(a){console.error("Combined refresh failed:",a)}}var od=null,Ej=1e3;(()=>{let t=()=>{let s=Da.getState(),n=zi.getState();s.autoRefresh&&n.isLoggedIn?(!od||Ej!==s.refreshInterval)&&(e(),Ej=s.refreshInterval,od=setInterval(()=>{zUt()},s.refreshInterval)):e()},e=()=>{od&&(clearInterval(od),od=null,Ej=0)},a=Da.getState().autoRefresh,i=Da.getState().refreshInterval,r=zi.getState().isLoggedIn;Da.state.subscribe(s=>{(s.autoRefresh!==a||s.refreshInterval!==i)&&(a=s.autoRefresh,i=s.refreshInterval,t())}),zi.state.subscribe(s=>{s.isLoggedIn!==r&&(r=s.isLoggedIn,t())}),t()})();var SUt=N1.plugins.smartrouter.SmartRouter,Oj=["overview","network","emails","logs","configuration","security","certificates"],Rj=["queued","sent","failed","security"],Bj=class{router;initialized=!1;suppressStateUpdate=!1;constructor(){this.router=new SUt({debug:!1})}init(){this.initialized||(this.setupRoutes(),this.setupStateSync(),this.handleInitialRoute(),this.initialized=!0)}setupRoutes(){for(let e of Oj)e==="emails"?(this.router.on("/emails",async()=>{this.updateViewState("emails"),this.updateEmailFolder("queued")}),this.router.on("/emails/:folder",async a=>{let i=a.params.folder;Rj.includes(i)?(this.updateViewState("emails"),this.updateEmailFolder(i)):this.navigateTo("/emails/queued")})):this.router.on(`/${e}`,async()=>{this.updateViewState(e)});this.router.on("/",async()=>{this.navigateTo("/overview")})}setupStateSync(){Da.state.subscribe(e=>{if(this.suppressStateUpdate)return;let a=window.location.pathname,i=this.getExpectedPath(e.activeView);if(!a.startsWith(i)){if(this.suppressStateUpdate=!0,e.activeView==="emails"){let r=T1.getState();this.router.pushUrl(`/emails/${r.currentView}`)}else this.router.pushUrl(`/${e.activeView}`);this.suppressStateUpdate=!1}})}getExpectedPath(e){return e==="emails"?"/emails":`/${e}`}handleInitialRoute(){let e=window.location.pathname;if(!e||e==="/")this.router.pushUrl("/overview");else{let a=e.split("/").filter(Boolean),i=a[0];if(Oj.includes(i))if(this.updateViewState(i),i==="emails"&&a[1]){let r=a[1];Rj.includes(r)?this.updateEmailFolder(r):this.updateEmailFolder("queued")}else i==="emails"&&this.updateEmailFolder("queued");else this.router.pushUrl("/overview")}}updateViewState(e){this.suppressStateUpdate=!0;let a=Da.getState();a.activeView!==e&&Da.setState({...a,activeView:e}),this.suppressStateUpdate=!1}updateEmailFolder(e){this.suppressStateUpdate=!0;let a=T1.getState();a.currentView!==e&&T1.setState({...a,currentView:e}),this.suppressStateUpdate=!1}navigateTo(e){this.router.pushUrl(e)}navigateToView(e){Oj.includes(e)?this.navigateTo(`/${e}`):this.navigateTo("/overview")}navigateToEmailFolder(e){Rj.includes(e)?this.navigateTo(`/emails/${e}`):this.navigateTo("/emails/queued")}getCurrentView(){return Da.getState().activeView}getCurrentEmailFolder(){return T1.getState().currentView}destroy(){this.router.destroy(),this.initialized=!1}},Ul=new Bj;ue();var Ea=X`
|
|
29069
|
+
`}async firstUpdated(n){await super.firstUpdated(n),this.outlet=this.shadowRoot.querySelector(".outlet")}async updateHtmlText(n){await this.updateComplete,this.outlet||(this.outlet=this.shadowRoot.querySelector(".outlet")),this.outlet.innerHTML=n}static{yUt(i,a)}};return s=i})()});var $yt=v(()=>{Lyt()});var Ayt=v(()=>{Lj()});var Dyt=v(()=>{Aj()});var Eyt=v(()=>{byt();vyt();xyt();wyt();Myt();kyt();$yt();Ayt();Dyt()});var Pyt=v(()=>{});var Nyt=v(()=>{Pyt()});var Iyt=v(()=>{ue()});var Fyt=v(()=>{Iyt()});var Oyt=v(()=>{fi();qe();yft();Aft();Wft();rmt();$mt();Emt();qgt();Abt();qvt();Qvt();Sw();Gxt();dyt();Eyt();Nyt();Fyt()});var Ryt,Byt=v(()=>{Ryt={name:"@design.estate/dees-catalog",version:"3.42.0",description:"A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."}});var bo={};Je(bo,{CanvasPool:()=>El,DeesActionbar:()=>smt,DeesAppui:()=>cft,DeesAppuiActivitylog:()=>cpt,DeesAppuiBar:()=>Spt,DeesAppuiBottombar:()=>_pt,DeesAppuiMaincontent:()=>lft,DeesAppuiMainmenu:()=>tft,DeesAppuiProfileDropdown:()=>zpt,DeesAppuiSecondarymenu:()=>rft,DeesAppuiTabs:()=>oft,DeesAudioViewer:()=>Obt,DeesBadge:()=>dmt,DeesButton:()=>Z9t,DeesButtonExit:()=>zft,DeesButtonGroup:()=>_ft,DeesChartArea:()=>Rft,DeesChartLog:()=>Vft,DeesChips:()=>Ugt,DeesContextmenu:()=>jt,DeesDashboardgrid:()=>dbt,DeesDataviewCodebox:()=>Zft,DeesDataviewStatusobject:()=>emt,DeesForm:()=>W9t,DeesFormSubmit:()=>Ry,DeesFormattingMenu:()=>nw,DeesHeading:()=>gbt,DeesHint:()=>gmt,DeesIcon:()=>ipt,DeesImageViewer:()=>Pbt,DeesInputBase:()=>Ze,DeesInputCheckbox:()=>Ly,DeesInputCode:()=>Ey,DeesInputDatepicker:()=>Py,DeesInputDropdown:()=>By,DeesInputFileupload:()=>qy,DeesInputIban:()=>Uy,DeesInputList:()=>Hmt,DeesInputMultitoggle:()=>Wy,DeesInputPhone:()=>Yy,DeesInputProfilePicture:()=>Hgt,DeesInputQuantitySelector:()=>Iy,DeesInputRadiogroup:()=>Fy,DeesInputRichtext:()=>egt,DeesInputTags:()=>ogt,DeesInputText:()=>Ny,DeesInputToggle:()=>Zy,DeesInputTypelist:()=>Xy,DeesInputWysiwyg:()=>DV,DeesLabel:()=>Vpt,DeesMobilenavigation:()=>bft,DeesModal:()=>s1,DeesPagination:()=>Mbt,DeesPanel:()=>Ept,DeesPdf:()=>avt,DeesPdfPreview:()=>cvt,DeesPdfViewer:()=>Ybt,DeesPreview:()=>Kbt,DeesProgressbar:()=>Mmt,DeesSearchbar:()=>Kxt,DeesShoppingProductcard:()=>t9t,DeesSimpleAppDash:()=>Oxt,DeesSimpleLogin:()=>jxt,DeesSlashMenu:()=>rw,DeesSpeechbubble:()=>Gvt,DeesSpinner:()=>Smt,DeesStatsGrid:()=>X9t,DeesStepper:()=>_bt,DeesTable:()=>Ky,DeesTheme:()=>iyt,DeesTileAudio:()=>zvt,DeesTileBase:()=>ga,DeesTileFolder:()=>Rvt,DeesTileImage:()=>vvt,DeesTileNote:()=>Evt,DeesTilePdf:()=>dw,DeesTileVideo:()=>_vt,DeesToast:()=>Ot,DeesUpdater:()=>kw,DeesVideoViewer:()=>qbt,DeesWindowControls:()=>Mpt,DeesWindowLayer:()=>mi,DeesWorkspace:()=>myt,DeesWorkspaceBottombar:()=>pyt,DeesWorkspaceDiffEditor:()=>fyt,DeesWorkspaceFiletree:()=>hyt,DeesWorkspaceMarkdown:()=>zyt,DeesWorkspaceMarkdownoutlet:()=>_yt,DeesWorkspaceMonaco:()=>jpt,DeesWorkspaceTerminal:()=>yj,DeesWorkspaceTerminalPreview:()=>uyt,DeesWysiwygBlock:()=>Pgt,PROGRAMMING_LANGUAGES:()=>_8,PdfManager:()=>Br,PerformanceMonitor:()=>Pl,TerminalTabManager:()=>ed,TypeScriptIntelliSenseManager:()=>sd,ViewRegistry:()=>z8,WebContainerEnvironment:()=>d4,WysiwygBlockOperations:()=>L8,WysiwygBlocks:()=>A2,WysiwygConverters:()=>wi,WysiwygDragDropHandler:()=>V8,WysiwygFormatting:()=>Is,WysiwygHistory:()=>j8,WysiwygInputHandler:()=>H8,WysiwygKeyboardHandler:()=>q8,WysiwygModalManager:()=>B8,WysiwygSelection:()=>Re,WysiwygShortcuts:()=>q1,ZIndexRegistry:()=>xf,colors:()=>H0,commitinfo:()=>Ryt,componentZIndex:()=>pBt,debounce:()=>Fjt,formatFileSize:()=>Rjt,getZIndex:()=>uBt,icons:()=>Cy,isInViewport:()=>Bjt,registerAllBlockHandlers:()=>Lgt,themeDefaultStyles:()=>ke,themeDefaults:()=>Zn,throttle:()=>Ojt,tileBaseStyles:()=>J2,wysiwygStyles:()=>SV,zIndexLayers:()=>a2,zIndexRegistry:()=>c1});var p4=v(()=>{Oyt();bi();Byt()});ue();p4();var N1=rt;Tc();var Hyt={};var qyt={};var vo=new N1.plugins.smartstate.Smartstate,zi=await vo.getStatePart("login",{identity:null,isLoggedIn:!1},"persistent"),o2=await vo.getStatePart("stats",{serverStats:null,emailStats:null,dnsStats:null,securityMetrics:null,lastUpdated:0,isLoading:!1,error:null},"soft"),Vr=await vo.getStatePart("config",{config:null,isLoading:!1,error:null}),wUt=()=>{let t=typeof window<"u"?window.location.pathname:"/",e=["overview","network","emails","logs","configuration","security","certificates"],i=t.split("/").filter(Boolean)[0];return e.includes(i)?i:"overview"},Da=await vo.getStatePart("ui",{activeView:wUt(),sidebarCollapsed:!1,autoRefresh:!0,refreshInterval:1e3,theme:"light"}),Tw=await vo.getStatePart("logs",{recentLogs:[],isStreaming:!1,filters:{}},"soft"),qr=await vo.getStatePart("network",{connections:[],connectionsByIP:{},throughputRate:{bytesInPerSecond:0,bytesOutPerSecond:0},totalBytes:{in:0,out:0},topIPs:[],throughputByIP:[],throughputHistory:[],requestsPerSecond:0,requestsTotal:0,lastUpdated:0,isLoading:!1,error:null},"soft"),T1=await vo.getStatePart("emailOps",{currentView:"queued",queuedEmails:[],sentEmails:[],failedEmails:[],securityIncidents:[],bounceRecords:[],suppressionList:[],selectedEmailId:null,isLoading:!1,error:null,lastUpdated:0},"soft"),ar=await vo.getStatePart("certificates",{certificates:[],summary:{total:0,valid:0,expiring:0,expired:0,failed:0,unknown:0},isLoading:!1,error:null,lastUpdated:0},"soft"),xa=()=>({identity:zi.getState().identity}),Vyt=zi.createAction(async(t,e)=>{let a=new N1.plugins.typedrequest.TypedRequest("/typedrequest","adminLoginWithUsernameAndPassword");try{let i=await a.fire({username:e.username,password:e.password});return i.identity?{identity:i.identity,isLoggedIn:!0}:t.getState()}catch(i){return console.error("Login failed:",i),t.getState()}}),Pj=zi.createAction(async t=>{let e=xa();if(!e.identity)return t.getState();let a=new N1.plugins.typedrequest.TypedRequest("/typedrequest","adminLogout");try{await a.fire({identity:e.identity})}catch(i){console.error("Logout error:",i)}return{identity:null,isLoggedIn:!1}}),Vl=o2.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:e.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:!1}});return{serverStats:r.metrics.server||a.serverStats,emailStats:r.metrics.email||a.emailStats,dnsStats:r.metrics.dns||a.dnsStats,securityMetrics:r.metrics.security||a.securityMetrics,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(i){return{...a,isLoading:!1,error:i.message||"Failed to fetch statistics"}}}),jl=Vr.createAction(async t=>{let e=xa(),a=t.getState();try{return{config:(await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getConfiguration").fire({identity:e.identity})).config,isLoading:!1,error:null}}catch(i){return{...a,isLoading:!1,error:i.message||"Failed to fetch configuration"}}}),jyt=Tw.createAction(async(t,e)=>{let a=xa(),r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getRecentLogs").fire({identity:a.identity,limit:e.limit||100,level:e.level,category:e.category});return{...t.getState(),recentLogs:r.logs}}),f92=Da.createAction(async t=>{let e=t.getState();return{...e,autoRefresh:!e.autoRefresh}}),m92=Da.createAction(async(t,e)=>{let a=t.getState();return e==="network"&&a.activeView!=="network"&&setTimeout(()=>{qr.dispatchAction(Nj,null)},100),e==="certificates"&&a.activeView!=="certificates"&&setTimeout(()=>{ar.dispatchAction(ql,null)},100),{...a,activeView:e}}),Nj=qr.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getActiveConnections").fire({identity:e.identity}),n=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getNetworkStats").fire({identity:e.identity}),o={};return n.connectionsByIP&&Array.isArray(n.connectionsByIP)?n.connectionsByIP.forEach(d=>{o[d.ip]=d.count}):r.connections.forEach(d=>{let c=d.remoteAddress;o[c]=(o[c]||0)+1}),{connections:r.connections,connectionsByIP:o,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||[],throughputByIP:n.throughputByIP||[],throughputHistory:n.throughputHistory||[],requestsPerSecond:n.requestsPerSecond||0,requestsTotal:n.requestsTotal||0,lastUpdated:Date.now(),isLoading:!1,error:null}}catch(i){return console.error("Failed to fetch network stats:",i),{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch network stats"}}}),g92=T1.createAction(async(t,e)=>({...t.getState(),currentView:e})),Ij=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getQueuedEmails").fire({identity:e.identity,status:"pending",limit:100});return{...a,queuedEmails:r.items,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch queued emails"}}}),Uyt=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getSentEmails").fire({identity:e.identity,limit:100});return{...a,sentEmails:r.items,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch sent emails"}}}),Fj=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getFailedEmails").fire({identity:e.identity,limit:100});return{...a,failedEmails:r.items,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch failed emails"}}}),Wyt=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getSecurityIncidents").fire({identity:e.identity,limit:100});return{...a,securityIncidents:r.incidents,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch security incidents"}}}),MUt=T1.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getBounceRecords").fire({identity:e.identity,limit:100});return{...a,bounceRecords:r.records,suppressionList:r.suppressionList,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch bounce records"}}}),Gyt=T1.createAction(async(t,e)=>{let a=xa(),i=t.getState();try{return(await new N1.plugins.typedrequest.TypedRequest("/typedrequest","resendEmail").fire({identity:a.identity,emailId:e})).success&&(await T1.dispatchAction(Fj,null),await T1.dispatchAction(Ij,null)),t.getState()}catch(r){return{...i,error:r instanceof Error?r.message:"Failed to resend email"}}}),b92=T1.createAction(async(t,e)=>{let a=xa(),i=t.getState();try{return(await new N1.plugins.typedrequest.TypedRequest("/typedrequest","removeFromSuppressionList").fire({identity:a.identity,email:e})).success&&await T1.dispatchAction(MUt,null),t.getState()}catch(r){return{...i,error:r instanceof Error?r.message:"Failed to remove from suppression list"}}}),ql=ar.createAction(async t=>{let e=xa(),a=t.getState();try{let r=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getCertificateOverview").fire({identity:e.identity});return{certificates:r.certificates,summary:r.summary,isLoading:!1,error:null,lastUpdated:Date.now()}}catch(i){return{...a,isLoading:!1,error:i instanceof Error?i.message:"Failed to fetch certificate overview"}}}),Yyt=ar.createAction(async(t,e)=>{let a=xa(),i=t.getState();try{return await new N1.plugins.typedrequest.TypedRequest("/typedrequest","reprovisionCertificateDomain").fire({identity:a.identity,domain:e}),await ar.dispatchAction(ql,null),t.getState()}catch(r){return{...i,error:r instanceof Error?r.message:"Failed to reprovision certificate"}}});async function zUt(){let t=xa(),e=Da.getState().activeView;try{let i=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getCombinedMetrics").fire({identity:t.identity,sections:{server:!0,email:!0,dns:!0,security:!0,network:e==="network"}});if(o2.setState({...o2.getState(),serverStats:i.metrics.server||o2.getState().serverStats,emailStats:i.metrics.email||o2.getState().emailStats,dnsStats:i.metrics.dns||o2.getState().dnsStats,securityMetrics:i.metrics.security||o2.getState().securityMetrics,lastUpdated:Date.now(),isLoading:!1,error:null}),i.metrics.network&&e==="network"){let r=i.metrics.network,s={};r.connectionDetails.forEach(n=>{s[n.remoteAddress]=(s[n.remoteAddress]||0)+1});try{let o=await new N1.plugins.typedrequest.TypedRequest("/typedrequest","getActiveConnections").fire({identity:t.identity});qr.setState({...qr.getState(),connections:o.connections,connectionsByIP:s,throughputRate:{bytesInPerSecond:r.totalBandwidth.in,bytesOutPerSecond:r.totalBandwidth.out},totalBytes:r.totalBytes||{in:0,out:0},topIPs:r.topEndpoints.map(d=>({ip:d.endpoint,count:d.requests})),throughputByIP:r.topEndpoints.map(d=>({ip:d.endpoint,in:d.bandwidth?.in||0,out:d.bandwidth?.out||0})),throughputHistory:r.throughputHistory||[],requestsPerSecond:r.requestsPerSecond||0,requestsTotal:r.requestsTotal||0,lastUpdated:Date.now(),isLoading:!1,error:null})}catch(n){console.error("Failed to fetch connections:",n),qr.setState({...qr.getState(),connections:[],connectionsByIP:s,throughputRate:{bytesInPerSecond:r.totalBandwidth.in,bytesOutPerSecond:r.totalBandwidth.out},totalBytes:r.totalBytes||{in:0,out:0},topIPs:r.topEndpoints.map(o=>({ip:o.endpoint,count:o.requests})),throughputByIP:r.topEndpoints.map(o=>({ip:o.endpoint,in:o.bandwidth?.in||0,out:o.bandwidth?.out||0})),throughputHistory:r.throughputHistory||[],requestsPerSecond:r.requestsPerSecond||0,requestsTotal:r.requestsTotal||0,lastUpdated:Date.now(),isLoading:!1,error:null})}}if(e==="certificates")try{await ar.dispatchAction(ql,null)}catch(r){console.error("Certificate refresh failed:",r)}}catch(a){console.error("Combined refresh failed:",a)}}var od=null,Ej=1e3;(()=>{let t=()=>{let s=Da.getState(),n=zi.getState();s.autoRefresh&&n.isLoggedIn?(!od||Ej!==s.refreshInterval)&&(e(),Ej=s.refreshInterval,od=setInterval(()=>{zUt()},s.refreshInterval)):e()},e=()=>{od&&(clearInterval(od),od=null,Ej=0)},a=Da.getState().autoRefresh,i=Da.getState().refreshInterval,r=zi.getState().isLoggedIn;Da.state.subscribe(s=>{(s.autoRefresh!==a||s.refreshInterval!==i)&&(a=s.autoRefresh,i=s.refreshInterval,t())}),zi.state.subscribe(s=>{s.isLoggedIn!==r&&(r=s.isLoggedIn,t())}),t()})();var SUt=N1.plugins.smartrouter.SmartRouter,Oj=["overview","network","emails","logs","configuration","security","certificates"],Rj=["queued","sent","failed","security"],Bj=class{router;initialized=!1;suppressStateUpdate=!1;constructor(){this.router=new SUt({debug:!1})}init(){this.initialized||(this.setupRoutes(),this.setupStateSync(),this.handleInitialRoute(),this.initialized=!0)}setupRoutes(){for(let e of Oj)e==="emails"?(this.router.on("/emails",async()=>{this.updateViewState("emails"),this.updateEmailFolder("queued")}),this.router.on("/emails/:folder",async a=>{let i=a.params.folder;Rj.includes(i)?(this.updateViewState("emails"),this.updateEmailFolder(i)):this.navigateTo("/emails/queued")})):this.router.on(`/${e}`,async()=>{this.updateViewState(e)});this.router.on("/",async()=>{this.navigateTo("/overview")})}setupStateSync(){Da.state.subscribe(e=>{if(this.suppressStateUpdate)return;let a=window.location.pathname,i=this.getExpectedPath(e.activeView);if(!a.startsWith(i)){if(this.suppressStateUpdate=!0,e.activeView==="emails"){let r=T1.getState();this.router.pushUrl(`/emails/${r.currentView}`)}else this.router.pushUrl(`/${e.activeView}`);this.suppressStateUpdate=!1}})}getExpectedPath(e){return e==="emails"?"/emails":`/${e}`}handleInitialRoute(){let e=window.location.pathname;if(!e||e==="/")this.router.pushUrl("/overview");else{let a=e.split("/").filter(Boolean),i=a[0];if(Oj.includes(i))if(this.updateViewState(i),i==="emails"&&a[1]){let r=a[1];Rj.includes(r)?this.updateEmailFolder(r):this.updateEmailFolder("queued")}else i==="emails"&&this.updateEmailFolder("queued");else this.router.pushUrl("/overview")}}updateViewState(e){this.suppressStateUpdate=!0;let a=Da.getState();a.activeView!==e&&Da.setState({...a,activeView:e}),this.suppressStateUpdate=!1}updateEmailFolder(e){this.suppressStateUpdate=!0;let a=T1.getState();a.currentView!==e&&T1.setState({...a,currentView:e}),this.suppressStateUpdate=!1}navigateTo(e){this.router.pushUrl(e)}navigateToView(e){Oj.includes(e)?this.navigateTo(`/${e}`):this.navigateTo("/overview")}navigateToEmailFolder(e){Rj.includes(e)?this.navigateTo(`/emails/${e}`):this.navigateTo("/emails/queued")}getCurrentView(){return Da.getState().activeView}getCurrentEmailFolder(){return T1.getState().currentView}destroy(){this.router.destroy(),this.initialized=!1}},Ul=new Bj;ue();var Ea=X`
|
|
29070
29070
|
:host {
|
|
29071
29071
|
display: block;
|
|
29072
29072
|
margin: auto;
|
|
@@ -30410,8 +30410,8 @@ ${JSON.stringify(a.details,null,2)}
|
|
|
30410
30410
|
`}renderCertificateTable(){return w`
|
|
30411
30411
|
<dees-table
|
|
30412
30412
|
.data=${this.certState.certificates}
|
|
30413
|
-
.displayFunction=${a=>({
|
|
30414
|
-
.dataActions=${[{name:"Reprovision",iconName:"arrowsRotate",type:["inRow"],actionFunc:async a=>{let i=a.item;if(!i.canReprovision){let{DeesToast:s}=await Promise.resolve().then(()=>(p4(),bo));s.show({message:"This certificate source does not support reprovisioning.",type:"warning",duration:3e3});return}await ar.dispatchAction(Yyt,i.
|
|
30413
|
+
.displayFunction=${a=>({Domain:a.domain,Routes:this.renderRoutePills(a.routeNames),Status:this.renderStatusBadge(a.status),Source:this.renderSourceBadge(a.source),Expires:this.renderExpiry(a.expiryDate),Error:a.backoffInfo?w`<span class="backoffIndicator">${a.backoffInfo.failures} failures, retry ${this.formatRetryTime(a.backoffInfo.retryAfter)}</span>`:a.error?w`<span class="errorText" title="${a.error}">${a.error}</span>`:""})}
|
|
30414
|
+
.dataActions=${[{name:"Reprovision",iconName:"arrowsRotate",type:["inRow"],actionFunc:async a=>{let i=a.item;if(!i.canReprovision){let{DeesToast:s}=await Promise.resolve().then(()=>(p4(),bo));s.show({message:"This certificate source does not support reprovisioning.",type:"warning",duration:3e3});return}await ar.dispatchAction(Yyt,i.domain);let{DeesToast:r}=await Promise.resolve().then(()=>(p4(),bo));r.show({message:`Reprovisioning triggered for ${i.domain}`,type:"success",duration:3e3})}},{name:"View Details",iconName:"magnifyingGlass",type:["doubleClick","contextmenu"],actionFunc:async a=>{let i=a.item,{DeesModal:r}=await Promise.resolve().then(()=>(p4(),bo));await r.createAndShow({heading:`Certificate: ${i.domain}`,content:w`
|
|
30415
30415
|
<div style="padding: 20px;">
|
|
30416
30416
|
<dees-dataview-codebox
|
|
30417
30417
|
.heading=${"Certificate Details"}
|
|
@@ -30419,24 +30419,24 @@ ${JSON.stringify(a.details,null,2)}
|
|
|
30419
30419
|
.codeToDisplay=${JSON.stringify(i,null,2)}
|
|
30420
30420
|
></dees-dataview-codebox>
|
|
30421
30421
|
</div>
|
|
30422
|
-
`,menuOptions:[{name:"Copy
|
|
30422
|
+
`,menuOptions:[{name:"Copy Domain",iconName:"copy",action:async()=>{await navigator.clipboard.writeText(i.domain)}}]})}}]}
|
|
30423
30423
|
heading1="Certificate Status"
|
|
30424
|
-
heading2="TLS certificates
|
|
30424
|
+
heading2="TLS certificates by domain"
|
|
30425
30425
|
searchable
|
|
30426
30426
|
.pagination=${!0}
|
|
30427
30427
|
.paginationSize=${50}
|
|
30428
30428
|
dataName="certificate"
|
|
30429
30429
|
></dees-table>
|
|
30430
|
-
`}
|
|
30431
|
-
<span class="
|
|
30432
|
-
${r.map(n=>w`<span class="
|
|
30430
|
+
`}renderRoutePills(a){let r=a.slice(0,3),s=a.length-3;return w`
|
|
30431
|
+
<span class="routePills">
|
|
30432
|
+
${r.map(n=>w`<span class="routePill">${n}</span>`)}
|
|
30433
30433
|
${s>0?w`<span class="moreCount">+${s} more</span>`:""}
|
|
30434
30434
|
</span>
|
|
30435
30435
|
`}renderStatusBadge(a){return w`<span class="statusBadge ${a}">${a}</span>`}renderSourceBadge(a){return w`<span class="sourceBadge">${{acme:"ACME","provision-function":"Custom",static:"Static",none:"None"}[a]||a}</span>`}renderExpiry(a){if(!a)return w`<span style="color: ${u.bdTheme("#9ca3af","#4b5563")}">--</span>`;let i=new Date(a),r=new Date,s=Math.ceil((i.getTime()-r.getTime())/(1e3*60*60*24)),n=i.toLocaleDateString(),o="",d="";return s<0?(o="danger",d="(expired)"):s<30?(o="warn",d=`(${s}d left)`):d=`(${s}d left)`,w`
|
|
30436
30436
|
<span class="expiryInfo">
|
|
30437
30437
|
${n} <span class="daysLeft ${o}">${d}</span>
|
|
30438
30438
|
</span>
|
|
30439
|
-
`}};Zl=c2($wt),cU=new WeakMap,gt(Zl,4,"certState",Lwt,Xs,cU),Xs=gt(Zl,0,"OpsViewCertificates",Awt,Xs),h1(Xs,"styles",[u.defaultStyles,Ea,X`
|
|
30439
|
+
`}formatRetryTime(a){if(!a)return"soon";let i=new Date(a),r=new Date,s=i.getTime()-r.getTime();if(s<=0)return"now";let n=Math.ceil(s/6e4);return n<60?`in ${n}m`:`in ${Math.ceil(n/60)}h`}};Zl=c2($wt),cU=new WeakMap,gt(Zl,4,"certState",Lwt,Xs,cU),Xs=gt(Zl,0,"OpsViewCertificates",Awt,Xs),h1(Xs,"styles",[u.defaultStyles,Ea,X`
|
|
30440
30440
|
.certificatesContainer {
|
|
30441
30441
|
display: flex;
|
|
30442
30442
|
flex-direction: column;
|
|
@@ -30491,13 +30491,13 @@ ${JSON.stringify(a.details,null,2)}
|
|
|
30491
30491
|
color: ${u.bdTheme("#374151","#d1d5db")};
|
|
30492
30492
|
}
|
|
30493
30493
|
|
|
30494
|
-
.
|
|
30494
|
+
.routePills {
|
|
30495
30495
|
display: flex;
|
|
30496
30496
|
flex-wrap: wrap;
|
|
30497
30497
|
gap: 4px;
|
|
30498
30498
|
}
|
|
30499
30499
|
|
|
30500
|
-
.
|
|
30500
|
+
.routePill {
|
|
30501
30501
|
display: inline-flex;
|
|
30502
30502
|
align-items: center;
|
|
30503
30503
|
padding: 2px 8px;
|
|
@@ -30522,6 +30522,17 @@ ${JSON.stringify(a.details,null,2)}
|
|
|
30522
30522
|
white-space: nowrap;
|
|
30523
30523
|
}
|
|
30524
30524
|
|
|
30525
|
+
.backoffIndicator {
|
|
30526
|
+
display: inline-flex;
|
|
30527
|
+
align-items: center;
|
|
30528
|
+
gap: 4px;
|
|
30529
|
+
font-size: 11px;
|
|
30530
|
+
color: ${u.bdTheme("#9a3412","#fb923c")};
|
|
30531
|
+
padding: 2px 6px;
|
|
30532
|
+
border-radius: 4px;
|
|
30533
|
+
background: ${u.bdTheme("#fff7ed","#431407")};
|
|
30534
|
+
}
|
|
30535
|
+
|
|
30525
30536
|
.expiryInfo {
|
|
30526
30537
|
font-size: 12px;
|
|
30527
30538
|
}
|
|
@@ -30680,4 +30691,4 @@ ibantools/jsnext/ibantools.js:
|
|
|
30680
30691
|
* @preferred
|
|
30681
30692
|
*)
|
|
30682
30693
|
*/
|
|
30683
|
-
//# sourceMappingURL=bundle-
|
|
30694
|
+
//# sourceMappingURL=bundle-1771201612459.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '
|
|
6
|
+
version: '6.2.0',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { StorageManager } from './storage/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages certificate provisioning scheduling with:
|
|
4
|
+
* - Per-domain exponential backoff persisted in StorageManager
|
|
5
|
+
*
|
|
6
|
+
* Note: Serial stagger queue was removed — smartacme v9 handles
|
|
7
|
+
* concurrency, per-domain dedup, and rate limiting internally.
|
|
8
|
+
*/
|
|
9
|
+
export declare class CertProvisionScheduler {
|
|
10
|
+
private storageManager;
|
|
11
|
+
private maxBackoffHours;
|
|
12
|
+
private backoffCache;
|
|
13
|
+
constructor(storageManager: StorageManager, options?: {
|
|
14
|
+
maxBackoffHours?: number;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Storage key for a domain's backoff entry
|
|
18
|
+
*/
|
|
19
|
+
private backoffKey;
|
|
20
|
+
/**
|
|
21
|
+
* Load backoff entry from storage (with in-memory cache)
|
|
22
|
+
*/
|
|
23
|
+
private loadBackoff;
|
|
24
|
+
/**
|
|
25
|
+
* Save backoff entry to both cache and storage
|
|
26
|
+
*/
|
|
27
|
+
private saveBackoff;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a domain is currently in backoff
|
|
30
|
+
*/
|
|
31
|
+
isInBackoff(domain: string): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Record a provisioning failure for a domain.
|
|
34
|
+
* Sets exponential backoff: min(failures^2 * 1h, maxBackoffHours)
|
|
35
|
+
*/
|
|
36
|
+
recordFailure(domain: string, error?: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Clear backoff for a domain (on success or manual override)
|
|
39
|
+
*/
|
|
40
|
+
clearBackoff(domain: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Get backoff info for UI display
|
|
43
|
+
*/
|
|
44
|
+
getBackoffInfo(domain: string): Promise<{
|
|
45
|
+
failures: number;
|
|
46
|
+
retryAfter?: string;
|
|
47
|
+
lastError?: string;
|
|
48
|
+
} | null>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { logger } from './logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages certificate provisioning scheduling with:
|
|
4
|
+
* - Per-domain exponential backoff persisted in StorageManager
|
|
5
|
+
*
|
|
6
|
+
* Note: Serial stagger queue was removed — smartacme v9 handles
|
|
7
|
+
* concurrency, per-domain dedup, and rate limiting internally.
|
|
8
|
+
*/
|
|
9
|
+
export class CertProvisionScheduler {
|
|
10
|
+
storageManager;
|
|
11
|
+
maxBackoffHours;
|
|
12
|
+
// In-memory backoff cache (mirrors storage for fast lookups)
|
|
13
|
+
backoffCache = new Map();
|
|
14
|
+
constructor(storageManager, options) {
|
|
15
|
+
this.storageManager = storageManager;
|
|
16
|
+
this.maxBackoffHours = options?.maxBackoffHours ?? 24;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Storage key for a domain's backoff entry
|
|
20
|
+
*/
|
|
21
|
+
backoffKey(domain) {
|
|
22
|
+
const clean = domain.replace(/\*/g, '_wildcard_').replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
23
|
+
return `/cert-backoff/${clean}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load backoff entry from storage (with in-memory cache)
|
|
27
|
+
*/
|
|
28
|
+
async loadBackoff(domain) {
|
|
29
|
+
const cached = this.backoffCache.get(domain);
|
|
30
|
+
if (cached)
|
|
31
|
+
return cached;
|
|
32
|
+
const entry = await this.storageManager.getJSON(this.backoffKey(domain));
|
|
33
|
+
if (entry) {
|
|
34
|
+
this.backoffCache.set(domain, entry);
|
|
35
|
+
}
|
|
36
|
+
return entry;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Save backoff entry to both cache and storage
|
|
40
|
+
*/
|
|
41
|
+
async saveBackoff(domain, entry) {
|
|
42
|
+
this.backoffCache.set(domain, entry);
|
|
43
|
+
await this.storageManager.setJSON(this.backoffKey(domain), entry);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if a domain is currently in backoff
|
|
47
|
+
*/
|
|
48
|
+
async isInBackoff(domain) {
|
|
49
|
+
const entry = await this.loadBackoff(domain);
|
|
50
|
+
if (!entry)
|
|
51
|
+
return false;
|
|
52
|
+
const retryAfter = new Date(entry.retryAfter);
|
|
53
|
+
return retryAfter.getTime() > Date.now();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Record a provisioning failure for a domain.
|
|
57
|
+
* Sets exponential backoff: min(failures^2 * 1h, maxBackoffHours)
|
|
58
|
+
*/
|
|
59
|
+
async recordFailure(domain, error) {
|
|
60
|
+
const existing = await this.loadBackoff(domain);
|
|
61
|
+
const failures = (existing?.failures ?? 0) + 1;
|
|
62
|
+
// Exponential backoff: failures^2 hours, capped
|
|
63
|
+
const backoffHours = Math.min(failures * failures, this.maxBackoffHours);
|
|
64
|
+
const retryAfter = new Date(Date.now() + backoffHours * 60 * 60 * 1000);
|
|
65
|
+
const entry = {
|
|
66
|
+
failures,
|
|
67
|
+
lastFailure: new Date().toISOString(),
|
|
68
|
+
retryAfter: retryAfter.toISOString(),
|
|
69
|
+
lastError: error,
|
|
70
|
+
};
|
|
71
|
+
await this.saveBackoff(domain, entry);
|
|
72
|
+
logger.log('warn', `Cert backoff for ${domain}: ${failures} failures, retry after ${retryAfter.toISOString()}`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Clear backoff for a domain (on success or manual override)
|
|
76
|
+
*/
|
|
77
|
+
async clearBackoff(domain) {
|
|
78
|
+
this.backoffCache.delete(domain);
|
|
79
|
+
try {
|
|
80
|
+
await this.storageManager.delete(this.backoffKey(domain));
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Ignore delete errors (key may not exist)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get backoff info for UI display
|
|
88
|
+
*/
|
|
89
|
+
async getBackoffInfo(domain) {
|
|
90
|
+
const entry = await this.loadBackoff(domain);
|
|
91
|
+
if (!entry)
|
|
92
|
+
return null;
|
|
93
|
+
// Only return if still in backoff
|
|
94
|
+
const retryAfter = new Date(entry.retryAfter);
|
|
95
|
+
if (retryAfter.getTime() <= Date.now())
|
|
96
|
+
return null;
|
|
97
|
+
return {
|
|
98
|
+
failures: entry.failures,
|
|
99
|
+
retryAfter: entry.retryAfter,
|
|
100
|
+
lastError: entry.lastError,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jZXJ0LXByb3Zpc2lvbi1zY2hlZHVsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jbGFzc2VzLmNlcnQtcHJvdmlzaW9uLXNjaGVkdWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBVXJDOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxzQkFBc0I7SUFDekIsY0FBYyxDQUFpQjtJQUMvQixlQUFlLENBQVM7SUFFaEMsNkRBQTZEO0lBQ3JELFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBeUIsQ0FBQztJQUV4RCxZQUNFLGNBQThCLEVBQzlCLE9BQXNDO1FBRXRDLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxFQUFFLGVBQWUsSUFBSSxFQUFFLENBQUM7SUFDeEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ssVUFBVSxDQUFDLE1BQWM7UUFDL0IsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25GLE9BQU8saUJBQWlCLEtBQUssRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBYztRQUN0QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QyxJQUFJLE1BQU07WUFBRSxPQUFPLE1BQU0sQ0FBQztRQUUxQixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFnQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDeEYsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLElB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
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { UnifiedEmailServer, type IUnifiedEmailServerOptions, type IEmailRoute } from '@push.rocks/smartmta';
|
|
3
3
|
import { StorageManager, type IStorageConfig } from './storage/index.js';
|
|
4
|
+
import { CertProvisionScheduler } from './classes.cert-provision-scheduler.js';
|
|
4
5
|
import { CacheDb, CacheCleaner } from './cache/index.js';
|
|
5
6
|
import { OpsServer } from './opsserver/index.js';
|
|
6
7
|
import { MetricsManager } from './monitoring/index.js';
|
|
@@ -150,12 +151,13 @@ export declare class DcRouter {
|
|
|
150
151
|
cacheCleaner?: CacheCleaner;
|
|
151
152
|
certificateStatusMap: Map<string, {
|
|
152
153
|
status: "valid" | "failed";
|
|
153
|
-
|
|
154
|
+
routeNames: string[];
|
|
154
155
|
expiryDate?: string;
|
|
155
156
|
issuedAt?: string;
|
|
156
157
|
source?: string;
|
|
157
158
|
error?: string;
|
|
158
159
|
}>;
|
|
160
|
+
certProvisionScheduler?: CertProvisionScheduler;
|
|
159
161
|
typedrouter: plugins.typedrequest.TypedRouter;
|
|
160
162
|
private qenv;
|
|
161
163
|
constructor(optionsArg: IDcRouterOptions);
|
|
@@ -188,9 +190,13 @@ export declare class DcRouter {
|
|
|
188
190
|
*/
|
|
189
191
|
private isDomainMatch;
|
|
190
192
|
/**
|
|
191
|
-
* Find the route name that matches a given domain
|
|
193
|
+
* Find the first route name that matches a given domain
|
|
192
194
|
*/
|
|
193
195
|
private findRouteNameForDomain;
|
|
196
|
+
/**
|
|
197
|
+
* Find ALL route names that match a given domain
|
|
198
|
+
*/
|
|
199
|
+
findRouteNamesForDomain(domain: string): string[];
|
|
194
200
|
stop(): Promise<void>;
|
|
195
201
|
/**
|
|
196
202
|
* Update SmartProxy configuration
|