@serve.zone/dcrouter 18.1.0 → 18.1.1

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 (47) hide show
  1. package/deno.json +1 -1
  2. package/dist_serve/bundle.js +8 -8
  3. package/dist_ts/00_commitinfo_data.js +1 -1
  4. package/dist_ts/classes.dcrouter.d.ts +4 -1
  5. package/dist_ts/classes.dcrouter.js +30 -6
  6. package/dist_ts/db/documents/classes.authentication-event.doc.d.ts +25 -0
  7. package/dist_ts/db/documents/classes.authentication-event.doc.js +273 -0
  8. package/dist_ts/db/documents/classes.email-traffic-bucket.doc.d.ts +25 -0
  9. package/dist_ts/db/documents/classes.email-traffic-bucket.doc.js +200 -0
  10. package/dist_ts/db/documents/index.d.ts +2 -0
  11. package/dist_ts/db/documents/index.js +3 -1
  12. package/dist_ts/email/classes.accepted-email-spool.d.ts +1 -0
  13. package/dist_ts/email/classes.accepted-email-spool.js +9 -1
  14. package/dist_ts/monitoring/classes.metricsmanager.d.ts +19 -0
  15. package/dist_ts/monitoring/classes.metricsmanager.js +240 -44
  16. package/dist_ts/opsserver/handlers/admin.handler.d.ts +1 -0
  17. package/dist_ts/opsserver/handlers/admin.handler.js +61 -14
  18. package/dist_ts/opsserver/handlers/security.handler.js +21 -3
  19. package/dist_ts/opsserver/handlers/stats.handler.js +27 -10
  20. package/dist_ts/security/classes.authentication-event-manager.d.ts +35 -0
  21. package/dist_ts/security/classes.authentication-event-manager.js +185 -0
  22. package/dist_ts/security/index.d.ts +1 -0
  23. package/dist_ts/security/index.js +2 -1
  24. package/dist_ts_interfaces/data/stats.d.ts +16 -0
  25. package/dist_ts_migrations/index.js +74 -15
  26. package/dist_ts_web/00_commitinfo_data.js +1 -1
  27. package/dist_ts_web/elements/overview/ops-view-overview.js +3 -2
  28. package/dist_ts_web/elements/security/ops-view-security-authentication.js +20 -13
  29. package/dist_ts_web/elements/security/ops-view-security-overview.js +8 -11
  30. package/package.json +1 -1
  31. package/readme.md +8 -0
  32. package/ts/00_commitinfo_data.ts +1 -1
  33. package/ts/classes.dcrouter.ts +31 -5
  34. package/ts/db/documents/classes.authentication-event.doc.ts +248 -0
  35. package/ts/db/documents/classes.email-traffic-bucket.doc.ts +161 -0
  36. package/ts/db/documents/index.ts +2 -0
  37. package/ts/email/classes.accepted-email-spool.ts +8 -0
  38. package/ts/monitoring/classes.metricsmanager.ts +287 -50
  39. package/ts/opsserver/handlers/admin.handler.ts +74 -15
  40. package/ts/opsserver/handlers/security.handler.ts +23 -2
  41. package/ts/opsserver/handlers/stats.handler.ts +29 -9
  42. package/ts/security/classes.authentication-event-manager.ts +221 -0
  43. package/ts/security/index.ts +1 -0
  44. package/ts_web/00_commitinfo_data.ts +1 -1
  45. package/ts_web/elements/overview/ops-view-overview.ts +2 -1
  46. package/ts_web/elements/security/ops-view-security-authentication.ts +20 -13
  47. package/ts_web/elements/security/ops-view-security-overview.ts +7 -12
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/dcrouter",
3
- "version": "18.1.0",
3
+ "version": "18.1.1",
4
4
  "exports": "./binary/dcrouter.ts",
5
5
  "compile": {
6
6
  "include": [
@@ -48403,7 +48403,7 @@ Minimum version required to store current data is: `+o+`.
48403
48403
  <dees-heading level="hr">Activity Charts</dees-heading>
48404
48404
  <div class="chartGrid">
48405
48405
  <dees-chart-area
48406
- .label=${"Email Traffic (24h)"}
48406
+ .label=${"Email Traffic \u2014 Last 24 Hours"}
48407
48407
  .series=${this.getEmailTrafficSeries()}
48408
48408
  .realtimeMode=${!0}
48409
48409
  .rollingWindow=${864e5}
@@ -48443,7 +48443,7 @@ Minimum version required to store current data is: `+o+`.
48443
48443
  `}renderVpnStats(){if(!this.statsState.vpnStats)return x``;let t=this.statsState.vpnStats,a=[{id:"vpnStatus",title:"VPN Status",value:t.running?"Running":"Stopped",type:"text",icon:"lucide:Shield",color:t.running?"#22c55e":"#ef4444",description:`Subnet: ${t.subnet}`},{id:"connectedClients",title:"Connected Clients",value:t.connectedClients,type:"number",icon:"lucide:Wifi",color:"#3b82f6",description:`${t.registeredClients} registered`},{id:"wgPort",title:"WireGuard Port",value:t.wgListenPort,type:"number",icon:"lucide:Network",color:"#8b5cf6"}];return x`
48444
48444
  <dees-heading level="hr">VPN Statistics</dees-heading>
48445
48445
  <dees-statsgrid .tiles=${a}></dees-statsgrid>
48446
- `}getRecentEventEntries(){return this.logState.recentLogs.map(t=>({timestamp:new Date(t.timestamp).toISOString(),level:t.level,message:t.message,source:t.category}))}getSecurityAlertEntries(){return(this.statsState.securityMetrics?.recentEvents||[]).map(a=>({timestamp:new Date(a.timestamp).toISOString(),level:a.level==="critical"||a.level==="error"?"error":a.level==="warn"?"warn":"info",message:a.message,source:a.type}))}getDnsQueryEntries(){return(this.statsState.dnsStats?.recentQueries||[]).map(a=>({timestamp:new Date(a.timestamp).toISOString(),level:a.answered?"info":"warn",message:`${a.type} ${a.domain} (${a.responseTimeMs}ms)`,source:"dns"}))}getEmailTrafficSeries(){let t=this.statsState.emailStats?.timeSeries;return t?[{name:"Sent",color:"#22c55e",data:(t.sent||[]).map(a=>({x:a.timestamp,y:a.value}))},{name:"Received",color:"#3b82f6",data:(t.received||[]).map(a=>({x:a.timestamp,y:a.value}))}]:[]}getDnsQuerySeries(){let t=this.statsState.dnsStats?.timeSeries;return t?[{name:"Queries",color:"#8b5cf6",data:(t.queries||[]).map(a=>({x:a.timestamp,y:a.value}))}]:[]}};Qp=zt(aPt),fKe=new WeakMap,mKe=new WeakMap,Ge(Qp,4,"statsState",rPt,Xp,fKe),Ge(Qp,4,"logState",tPt,Xp,mKe),Xp=Ge(Qp,0,"OpsViewOverview",sPt,Xp),s(Xp,"OpsViewOverview"),ut(Xp,"styles",[w.defaultStyles,jt,ee`
48446
+ `}getRecentEventEntries(){return this.logState.recentLogs.map(t=>({timestamp:new Date(t.timestamp).toISOString(),level:t.level,message:t.message,source:t.category}))}getSecurityAlertEntries(){return(this.statsState.securityMetrics?.recentEvents||[]).map(a=>({timestamp:new Date(a.timestamp).toISOString(),level:a.level==="critical"||a.level==="error"?"error":a.level==="warn"?"warn":"info",message:a.message,source:a.type}))}getDnsQueryEntries(){return(this.statsState.dnsStats?.recentQueries||[]).map(a=>({timestamp:new Date(a.timestamp).toISOString(),level:a.answered?"info":"warn",message:`${a.type} ${a.domain} (${a.responseTimeMs}ms)`,source:"dns"}))}getEmailTrafficSeries(){let t=this.statsState.emailStats?.timeSeries;return t?[{name:"Sent",color:"#22c55e",data:(t.sent||[]).map(a=>({x:a.timestamp,y:a.value}))},{name:"Received",color:"#3b82f6",data:(t.received||[]).map(a=>({x:a.timestamp,y:a.value}))},{name:"Failed",color:"#ef4444",data:(t.failed||[]).map(a=>({x:a.timestamp,y:a.value}))}]:[]}getDnsQuerySeries(){let t=this.statsState.dnsStats?.timeSeries;return t?[{name:"Queries",color:"#8b5cf6",data:(t.queries||[]).map(a=>({x:a.timestamp,y:a.value}))}]:[]}};Qp=zt(aPt),fKe=new WeakMap,mKe=new WeakMap,Ge(Qp,4,"statsState",rPt,Xp,fKe),Ge(Qp,4,"logState",tPt,Xp,mKe),Xp=Ge(Qp,0,"OpsViewOverview",sPt,Xp),s(Xp,"OpsViewOverview"),ut(Xp,"styles",[w.defaultStyles,jt,ee`
48447
48447
  .chartGrid {
48448
48448
  display: grid;
48449
48449
  grid-template-columns: repeat(2, 1fr);
@@ -50532,11 +50532,11 @@ Minimum version required to store current data is: `+o+`.
50532
50532
  <div class="loadingMessage">
50533
50533
  <p>Loading security metrics...</p>
50534
50534
  </div>
50535
- `;let a=this.calculateThreatLevel(t),i=this.getThreatScore(t),o=t.recentEvents||[],n=Date.now()-36e5,l=o.filter(d=>d.type==="authentication"&&d.success===!0&&d.timestamp>=n).length,c=[{id:"threatLevel",title:"Threat Level",value:i,type:"gauge",icon:"lucide:Shield",gaugeOptions:{min:0,max:100,thresholds:[{value:0,color:"#ef4444"},{value:30,color:"#f59e0b"},{value:70,color:"#22c55e"}]},description:`Status: ${a.toUpperCase()}`},{id:"blockedThreats",title:"Blocked Threats",value:(t.blockedIPs?.length||0)+t.spamDetected,type:"number",icon:"lucide:ShieldCheck",color:"#ef4444",description:"Total threats blocked today"},{id:"activeSessions",title:"Active Sessions",value:l,type:"number",icon:"lucide:Users",color:"#22c55e",description:"Authenticated in last hour"},{id:"authFailures",title:"Auth Failures",value:t.authenticationFailures,type:"number",icon:"lucide:LockOpen",color:t.authenticationFailures>10?"#ef4444":"#f59e0b",description:"Failed login attempts today"}];return x`
50535
+ `;let a=this.calculateThreatLevel(t),i=this.getThreatScore(t),o=t.authenticationSuccesses||0,n=[{id:"threatLevel",title:"Threat Level",value:i,type:"gauge",icon:"lucide:Shield",gaugeOptions:{min:0,max:100,thresholds:[{value:0,color:"#ef4444"},{value:30,color:"#f59e0b"},{value:70,color:"#22c55e"}]},description:`Status: ${a.toUpperCase()}`},{id:"blockedThreats",title:"Blocked Threats",value:(t.blockedIPs?.length||0)+t.spamDetected,type:"number",icon:"lucide:ShieldCheck",color:"#ef4444",description:"Threats observed in the last 24 hours"},{id:"successfulLogins",title:"Successful Logins",value:o,type:"number",icon:"lucide:Users",color:"#22c55e",description:"Successful logins in the last 24 hours"},{id:"authFailures",title:"Auth Failures",value:t.authenticationFailures,type:"number",icon:"lucide:LockOpen",color:t.authenticationFailures>10?"#ef4444":"#f59e0b",description:"Failed login attempts in the last 24 hours"}];return x`
50536
50536
  <dees-heading level="3">Overview</dees-heading>
50537
50537
 
50538
50538
  <dees-statsgrid
50539
- .tiles=${c}
50539
+ .tiles=${n}
50540
50540
  .minTileWidth=${200}
50541
50541
  ></dees-statsgrid>
50542
50542
 
@@ -50545,7 +50545,7 @@ Minimum version required to store current data is: `+o+`.
50545
50545
  .heading1=${"Security Events"}
50546
50546
  .heading2=${"Last 24 hours"}
50547
50547
  .data=${this.getSecurityEvents(t)}
50548
- .displayFunction=${d=>({Time:new Date(d.timestamp).toLocaleTimeString(),Event:d.event,Severity:d.severity,Details:d.details})}
50548
+ .displayFunction=${l=>({Time:new Date(l.timestamp).toLocaleTimeString(),Event:l.event,Severity:l.severity,Details:l.details})}
50549
50549
  ></dees-table>
50550
50550
  `}calculateThreatLevel(t){let a=this.getThreatScore(t);return a<30?"alert":a<70?"warning":"success"}getThreatScore(t){let a=100,i=Array.isArray(t.blockedIPs)?t.blockedIPs.length:t.blockedIPs||0;return a-=i*2,a-=(t.authenticationFailures||0)*1,a-=(t.spamDetected||0)*.5,a-=(t.malwareDetected||0)*3,a-=(t.phishingDetected||0)*3,a-=(t.suspiciousActivities||0)*2,Math.max(0,Math.min(100,Math.round(a)))}getSecurityEvents(t){return(t.recentEvents||[]).map(i=>({timestamp:i.timestamp,event:i.message,severity:i.level==="critical"?"critical":i.level==="error"?"high":i.level==="warn"?"warning":"info",details:i.ipAddress?`IP: ${i.ipAddress}`:i.domain?`Domain: ${i.domain}`:i.type}))}};aS=zt(UEt),pYe=new WeakMap,Ge(aS,4,"statsState",jEt,dm,pYe),dm=Ge(aS,0,"OpsViewSecurityOverview",WEt,dm),s(dm,"OpsViewSecurityOverview"),ut(dm,"styles",[w.defaultStyles,jt,ee`
50551
50551
  h2 {
@@ -50704,11 +50704,11 @@ Minimum version required to store current data is: `+o+`.
50704
50704
  <div class="loadingMessage">
50705
50705
  <p>Loading security metrics...</p>
50706
50706
  </div>
50707
- `;let i=(t.recentEvents||[]).filter(c=>c.type==="authentication"),o=i.filter(c=>c.success===!0).length,n=[{id:"authFailures",title:"Authentication Failures",value:t.authenticationFailures,type:"number",icon:"lucide:LockOpen",color:t.authenticationFailures>10?"#ef4444":"#f59e0b",description:"Failed authentication attempts today"},{id:"successfulLogins",title:"Successful Logins",value:o,type:"number",icon:"lucide:Lock",color:"#22c55e",description:"Successful logins today"}],l=i.map(c=>({timestamp:c.timestamp,username:c.details?.username||"unknown",ipAddress:c.ipAddress||"unknown",success:c.success??!1,reason:c.success?"":c.message||"Authentication failed"}));return x`
50707
+ `;let a=t.authenticationEvents||[],i=t.authenticationSuccesses||0,o=[{id:"authFailures",title:"Authentication Failures",value:t.authenticationFailures,type:"number",icon:"lucide:LockOpen",color:t.authenticationFailures>10?"#ef4444":"#f59e0b",description:"Failed authentication attempts in the last 24 hours"},{id:"successfulLogins",title:"Successful Logins",value:i,type:"number",icon:"lucide:Lock",color:"#22c55e",description:"Successful logins in the last 24 hours"}],n={invalidCredentials:"Invalid credentials",serviceUnavailable:"Authentication service unavailable",identityIssuanceFailed:"Session identity could not be issued",internalError:"Internal authentication error"},l=a.map(c=>({timestamp:c.timestamp,username:c.username,source:c.resolvedAuthSource?c.requestedAuthSource==="auto"?`Auto \u2192 ${c.resolvedAuthSource}`:c.resolvedAuthSource:c.requestedAuthSource,success:c.success,reason:c.success?"":n[c.failureReason||""]||"Authentication failed"}));return x`
50708
50708
  <dees-heading level="3">Authentication</dees-heading>
50709
50709
 
50710
50710
  <dees-statsgrid
50711
- .tiles=${n}
50711
+ .tiles=${o}
50712
50712
  .minTileWidth=${200}
50713
50713
  ></dees-statsgrid>
50714
50714
 
@@ -50717,7 +50717,7 @@ Minimum version required to store current data is: `+o+`.
50717
50717
  .heading1=${"Login History"}
50718
50718
  .heading2=${"Recent authentication attempts"}
50719
50719
  .data=${l}
50720
- .displayFunction=${c=>({Time:new Date(c.timestamp).toLocaleString(),Username:c.username,"IP Address":c.ipAddress,Status:c.success?"Success":"Failed",Reason:c.reason||"-"})}
50720
+ .displayFunction=${c=>({Time:new Date(c.timestamp).toLocaleString(),Username:c.username,Source:c.source,Status:c.success?"Success":"Failed",Reason:c.reason||"-"})}
50721
50721
  ></dees-table>
50722
50722
  `}};iS=zt(QEt),fYe=new WeakMap,Ge(iS,4,"statsState",ZEt,pm,fYe),pm=Ge(iS,0,"OpsViewSecurityAuthentication",XEt,pm),s(pm,"OpsViewSecurityAuthentication"),ut(pm,"styles",[w.defaultStyles,jt,ee`
50723
50723
  h2 {
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '18.1.0',
6
+ version: '18.1.1',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
@@ -9,7 +9,7 @@ import { RadiusServer, type IRadiusServerConfig } from './radius/index.js';
9
9
  import { RemoteIngressHubLifecycle, RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
10
10
  import { VpnAccessResolver, VpnManager } from './vpn/index.js';
11
11
  import { RouteConfigManager, ApiTokenManager, GatewayClientManager, ReferenceResolver, TargetProfileManager } from './config/index.js';
12
- import { SecurityPolicyManager, RoutePolicyAugmenter } from './security/index.js';
12
+ import { SecurityPolicyManager, RoutePolicyAugmenter, AuthenticationEventManager } from './security/index.js';
13
13
  import { type IHttp3Config } from './http3/index.js';
14
14
  import { DnsManager } from './dns/manager.dns.js';
15
15
  import { DnsAuthorityManager } from './dns/manager.dns-authority.js';
@@ -226,6 +226,7 @@ export declare class DcRouter {
226
226
  emailServer?: UnifiedEmailServer;
227
227
  radiusServer?: RadiusServer;
228
228
  opsServer: OpsServer;
229
+ private opsServerStopped;
229
230
  metricsManager?: MetricsManager;
230
231
  private emailEventSubscriptions;
231
232
  storageManager: IStorageManagerLike;
@@ -260,6 +261,7 @@ export declare class DcRouter {
260
261
  mailDnsSync: MailDnsSync;
261
262
  mailEdgeEligibility: MailEdgeEligibility;
262
263
  securityPolicyManager?: SecurityPolicyManager;
264
+ authenticationEventManager: AuthenticationEventManager;
263
265
  detectedPublicIp: string | null;
264
266
  certificateStatusMap: Map<string, {
265
267
  status: "valid" | "failed";
@@ -328,6 +330,7 @@ export declare class DcRouter {
328
330
  * Find ALL route names that match a given domain
329
331
  */
330
332
  findRouteNamesForDomain(domain: string): string[];
333
+ private stopOpsServer;
331
334
  stop(): Promise<void>;
332
335
  /**
333
336
  * Update SmartProxy configuration