@serve.zone/dcrouter 12.6.6 → 12.8.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.
@@ -15,6 +15,8 @@ export interface IStatsState {
15
15
  emailStats: interfaces.data.IEmailStats | null;
16
16
  dnsStats: interfaces.data.IDnsStats | null;
17
17
  securityMetrics: interfaces.data.ISecurityMetrics | null;
18
+ radiusStats: interfaces.data.IRadiusStats | null;
19
+ vpnStats: interfaces.data.IVpnStats | null;
18
20
  lastUpdated: number;
19
21
  isLoading: boolean;
20
22
  error: string | null;
@@ -91,6 +93,8 @@ export const statsStatePart = await appState.getStatePart<IStatsState>(
91
93
  emailStats: null,
92
94
  dnsStats: null,
93
95
  securityMetrics: null,
96
+ radiusStats: null,
97
+ vpnStats: null,
94
98
  lastUpdated: 0,
95
99
  isLoading: false,
96
100
  error: null,
@@ -319,6 +323,8 @@ export const fetchAllStatsAction = statsStatePart.createAction(async (statePartA
319
323
  dns: true,
320
324
  security: true,
321
325
  network: false, // Network is fetched separately for the network view
326
+ radius: true,
327
+ vpn: true,
322
328
  },
323
329
  });
324
330
 
@@ -328,6 +334,8 @@ export const fetchAllStatsAction = statsStatePart.createAction(async (statePartA
328
334
  emailStats: combinedResponse.metrics.email || currentState.emailStats,
329
335
  dnsStats: combinedResponse.metrics.dns || currentState.dnsStats,
330
336
  securityMetrics: combinedResponse.metrics.security || currentState.securityMetrics,
337
+ radiusStats: combinedResponse.metrics.radius || currentState.radiusStats,
338
+ vpnStats: combinedResponse.metrics.vpn || currentState.vpnStats,
331
339
  lastUpdated: Date.now(),
332
340
  isLoading: false,
333
341
  error: null,
@@ -597,8 +605,8 @@ export const fetchCertificateOverviewAction = certificateStatePart.createAction(
597
605
  }
598
606
  });
599
607
 
600
- export const reprovisionCertificateAction = certificateStatePart.createAction<string>(
601
- async (statePartArg, domain, actionContext): Promise<ICertificateState> => {
608
+ export const reprovisionCertificateAction = certificateStatePart.createAction<{ domain: string; forceRenew?: boolean }>(
609
+ async (statePartArg, dataArg, actionContext): Promise<ICertificateState> => {
602
610
  const context = getActionContext();
603
611
  const currentState = statePartArg.getState()!;
604
612
 
@@ -609,7 +617,8 @@ export const reprovisionCertificateAction = certificateStatePart.createAction<st
609
617
 
610
618
  await request.fire({
611
619
  identity: context.identity!,
612
- domain,
620
+ domain: dataArg.domain,
621
+ forceRenew: dataArg.forceRenew,
613
622
  });
614
623
 
615
624
  // Re-fetch overview after reprovisioning
@@ -1781,6 +1790,8 @@ async function dispatchCombinedRefreshActionInner() {
1781
1790
  dns: true,
1782
1791
  security: true,
1783
1792
  network: currentView === 'network', // Only fetch network if on network view
1793
+ radius: true,
1794
+ vpn: true,
1784
1795
  },
1785
1796
  });
1786
1797
 
@@ -1792,6 +1803,8 @@ async function dispatchCombinedRefreshActionInner() {
1792
1803
  emailStats: combinedResponse.metrics.email || currentStatsState.emailStats,
1793
1804
  dnsStats: combinedResponse.metrics.dns || currentStatsState.dnsStats,
1794
1805
  securityMetrics: combinedResponse.metrics.security || currentStatsState.securityMetrics,
1806
+ radiusStats: combinedResponse.metrics.radius || currentStatsState.radiusStats,
1807
+ vpnStats: combinedResponse.metrics.vpn || currentStatsState.vpnStats,
1795
1808
  lastUpdated: Date.now(),
1796
1809
  isLoading: false,
1797
1810
  error: null,
@@ -312,14 +312,16 @@ export class OpsViewCertificates extends DeesElement {
312
312
  return;
313
313
  }
314
314
 
315
- const doReprovision = async () => {
315
+ const doReprovision = async (forceRenew = false) => {
316
316
  await appstate.certificateStatePart.dispatchAction(
317
317
  appstate.reprovisionCertificateAction,
318
- cert.domain,
318
+ { domain: cert.domain, forceRenew },
319
319
  );
320
320
  const { DeesToast } = await import('@design.estate/dees-catalog');
321
321
  DeesToast.show({
322
- message: `Reprovisioning triggered for ${cert.domain}`,
322
+ message: forceRenew
323
+ ? `Force renewal triggered for ${cert.domain}`
324
+ : `Reprovisioning triggered for ${cert.domain}`,
323
325
  type: 'success',
324
326
  duration: 3000,
325
327
  });
@@ -336,7 +338,7 @@ export class OpsViewCertificates extends DeesElement {
336
338
  name: 'Force Renew',
337
339
  action: async (modalArg: any) => {
338
340
  await modalArg.destroy();
339
- await doReprovision();
341
+ await doReprovision(true);
340
342
  },
341
343
  },
342
344
  ],
@@ -21,6 +21,8 @@ export class OpsViewOverview extends DeesElement {
21
21
  emailStats: null,
22
22
  dnsStats: null,
23
23
  securityMetrics: null,
24
+ radiusStats: null,
25
+ vpnStats: null,
24
26
  lastUpdated: 0,
25
27
  isLoading: false,
26
28
  error: null,
@@ -117,6 +119,10 @@ export class OpsViewOverview extends DeesElement {
117
119
 
118
120
  ${this.renderDnsStats()}
119
121
 
122
+ ${this.renderRadiusStats()}
123
+
124
+ ${this.renderVpnStats()}
125
+
120
126
  <div class="chartGrid">
121
127
  <dees-chart-area
122
128
  .label=${'Email Traffic (24h)'}
@@ -378,6 +384,97 @@ export class OpsViewOverview extends DeesElement {
378
384
  `;
379
385
  }
380
386
 
387
+ private renderRadiusStats(): TemplateResult {
388
+ if (!this.statsState.radiusStats) return html``;
389
+
390
+ const stats = this.statsState.radiusStats;
391
+ const authTotal = stats.authRequests || 0;
392
+ const acceptRate = authTotal > 0 ? ((stats.authAccepts / authTotal) * 100).toFixed(1) : '0.0';
393
+
394
+ const tiles: IStatsTile[] = [
395
+ {
396
+ id: 'radiusStatus',
397
+ title: 'RADIUS Status',
398
+ value: stats.running ? 'Running' : 'Stopped',
399
+ type: 'text',
400
+ icon: 'lucide:ShieldCheck',
401
+ color: stats.running ? '#22c55e' : '#ef4444',
402
+ description: stats.running ? `Uptime: ${this.formatUptime(stats.uptime / 1000)}` : undefined,
403
+ },
404
+ {
405
+ id: 'authRequests',
406
+ title: 'Auth Requests',
407
+ value: stats.authRequests,
408
+ type: 'number',
409
+ icon: 'lucide:KeyRound',
410
+ color: '#3b82f6',
411
+ description: `Accept rate: ${acceptRate}% (${stats.authAccepts} / ${stats.authRejects} rejected)`,
412
+ },
413
+ {
414
+ id: 'activeSessions',
415
+ title: 'Active Sessions',
416
+ value: stats.activeSessions,
417
+ type: 'number',
418
+ icon: 'lucide:Users',
419
+ color: '#8b5cf6',
420
+ },
421
+ {
422
+ id: 'radiusTraffic',
423
+ title: 'Data Transfer',
424
+ value: this.formatBytes(stats.totalInputBytes + stats.totalOutputBytes),
425
+ type: 'text',
426
+ icon: 'lucide:ArrowLeftRight',
427
+ color: '#f59e0b',
428
+ description: `In: ${this.formatBytes(stats.totalInputBytes)} / Out: ${this.formatBytes(stats.totalOutputBytes)}`,
429
+ },
430
+ ];
431
+
432
+ return html`
433
+ <h2>RADIUS Statistics</h2>
434
+ <dees-statsgrid .tiles=${tiles}></dees-statsgrid>
435
+ `;
436
+ }
437
+
438
+ private renderVpnStats(): TemplateResult {
439
+ if (!this.statsState.vpnStats) return html``;
440
+
441
+ const stats = this.statsState.vpnStats;
442
+
443
+ const tiles: IStatsTile[] = [
444
+ {
445
+ id: 'vpnStatus',
446
+ title: 'VPN Status',
447
+ value: stats.running ? 'Running' : 'Stopped',
448
+ type: 'text',
449
+ icon: 'lucide:Shield',
450
+ color: stats.running ? '#22c55e' : '#ef4444',
451
+ description: `Subnet: ${stats.subnet}`,
452
+ },
453
+ {
454
+ id: 'connectedClients',
455
+ title: 'Connected Clients',
456
+ value: stats.connectedClients,
457
+ type: 'number',
458
+ icon: 'lucide:Wifi',
459
+ color: '#3b82f6',
460
+ description: `${stats.registeredClients} registered`,
461
+ },
462
+ {
463
+ id: 'wgPort',
464
+ title: 'WireGuard Port',
465
+ value: stats.wgListenPort,
466
+ type: 'number',
467
+ icon: 'lucide:Network',
468
+ color: '#8b5cf6',
469
+ },
470
+ ];
471
+
472
+ return html`
473
+ <h2>VPN Statistics</h2>
474
+ <dees-statsgrid .tiles=${tiles}></dees-statsgrid>
475
+ `;
476
+ }
477
+
381
478
  // --- Chart data helpers ---
382
479
 
383
480
  private getRecentEventEntries(): Array<{ timestamp: string; level: 'debug' | 'info' | 'warn' | 'error' | 'success'; message: string; source?: string }> {
@@ -20,6 +20,8 @@ export class OpsViewSecurity extends DeesElement {
20
20
  emailStats: null,
21
21
  dnsStats: null,
22
22
  securityMetrics: null,
23
+ radiusStats: null,
24
+ vpnStats: null,
23
25
  lastUpdated: 0,
24
26
  isLoading: false,
25
27
  error: null,