@serve.zone/dcrouter 7.0.1 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -249,7 +249,14 @@ export class OpsViewSecurity extends DeesElement {
249
249
  private renderOverview(metrics: any) {
250
250
  const threatLevel = this.calculateThreatLevel(metrics);
251
251
  const threatScore = this.getThreatScore(metrics);
252
-
252
+
253
+ // Derive active sessions from recent successful auth events (last hour)
254
+ const allEvents: any[] = metrics.recentEvents || [];
255
+ const oneHourAgo = Date.now() - 3600000;
256
+ const recentAuthSuccesses = allEvents.filter(
257
+ (evt: any) => evt.type === 'authentication' && evt.success === true && evt.timestamp >= oneHourAgo
258
+ ).length;
259
+
253
260
  const tiles: IStatsTile[] = [
254
261
  {
255
262
  id: 'threatLevel',
@@ -271,7 +278,7 @@ export class OpsViewSecurity extends DeesElement {
271
278
  {
272
279
  id: 'blockedThreats',
273
280
  title: 'Blocked Threats',
274
- value: metrics.blockedIPs.length + metrics.spamDetected,
281
+ value: (metrics.blockedIPs?.length || 0) + metrics.spamDetected,
275
282
  type: 'number',
276
283
  icon: 'lucide:ShieldCheck',
277
284
  color: '#ef4444',
@@ -280,11 +287,11 @@ export class OpsViewSecurity extends DeesElement {
280
287
  {
281
288
  id: 'activeSessions',
282
289
  title: 'Active Sessions',
283
- value: 0,
290
+ value: recentAuthSuccesses,
284
291
  type: 'number',
285
292
  icon: 'lucide:Users',
286
293
  color: '#22c55e',
287
- description: 'Current authenticated sessions',
294
+ description: 'Authenticated in last hour',
288
295
  },
289
296
  {
290
297
  id: 'authFailures',
@@ -349,6 +356,11 @@ export class OpsViewSecurity extends DeesElement {
349
356
  }
350
357
 
351
358
  private renderAuthentication(metrics: any) {
359
+ // Derive auth events from recentEvents
360
+ const allEvents: any[] = metrics.recentEvents || [];
361
+ const authEvents = allEvents.filter((evt: any) => evt.type === 'authentication');
362
+ const successfulLogins = authEvents.filter((evt: any) => evt.success === true).length;
363
+
352
364
  const tiles: IStatsTile[] = [
353
365
  {
354
366
  id: 'authFailures',
@@ -362,7 +374,7 @@ export class OpsViewSecurity extends DeesElement {
362
374
  {
363
375
  id: 'successfulLogins',
364
376
  title: 'Successful Logins',
365
- value: 0,
377
+ value: successfulLogins,
366
378
  type: 'number',
367
379
  icon: 'lucide:Lock',
368
380
  color: '#22c55e',
@@ -370,6 +382,15 @@ export class OpsViewSecurity extends DeesElement {
370
382
  },
371
383
  ];
372
384
 
385
+ // Map auth events to login history table data
386
+ const loginHistory = authEvents.map((evt: any) => ({
387
+ timestamp: evt.timestamp,
388
+ username: evt.details?.username || 'unknown',
389
+ ipAddress: evt.ipAddress || 'unknown',
390
+ success: evt.success ?? false,
391
+ reason: evt.success ? '' : evt.message || 'Authentication failed',
392
+ }));
393
+
373
394
  return html`
374
395
  <dees-statsgrid
375
396
  .tiles=${tiles}
@@ -380,7 +401,7 @@ export class OpsViewSecurity extends DeesElement {
380
401
  <dees-table
381
402
  .heading1=${'Login History'}
382
403
  .heading2=${'Recent authentication attempts'}
383
- .data=${[]}
404
+ .data=${loginHistory}
384
405
  .displayFunction=${(item) => ({
385
406
  'Time': new Date(item.timestamp).toLocaleString(),
386
407
  'Username': item.username,
@@ -483,48 +504,38 @@ export class OpsViewSecurity extends DeesElement {
483
504
  private getThreatScore(metrics: any): number {
484
505
  // Simple scoring algorithm
485
506
  let score = 100;
486
- score -= metrics.blockedIPs.length * 2;
487
- score -= metrics.authenticationFailures * 1;
488
- score -= metrics.spamDetected * 0.5;
489
- score -= metrics.malwareDetected * 3;
490
- score -= metrics.phishingDetected * 3;
491
- score -= metrics.suspiciousActivities * 2;
507
+ const blockedCount = Array.isArray(metrics.blockedIPs) ? metrics.blockedIPs.length : (metrics.blockedIPs || 0);
508
+ score -= blockedCount * 2;
509
+ score -= (metrics.authenticationFailures || 0) * 1;
510
+ score -= (metrics.spamDetected || 0) * 0.5;
511
+ score -= (metrics.malwareDetected || 0) * 3;
512
+ score -= (metrics.phishingDetected || 0) * 3;
513
+ score -= (metrics.suspiciousActivities || 0) * 2;
492
514
  return Math.max(0, Math.min(100, Math.round(score)));
493
515
  }
494
516
 
495
517
  private getSecurityEvents(metrics: any): any[] {
496
- // Mock data - in real implementation, this would come from the server
497
- return [
498
- {
499
- timestamp: Date.now() - 1000 * 60 * 5,
500
- event: 'Multiple failed login attempts',
501
- severity: 'warning',
502
- details: 'IP: 192.168.1.100',
503
- },
504
- {
505
- timestamp: Date.now() - 1000 * 60 * 15,
506
- event: 'SPF check failed',
507
- severity: 'medium',
508
- details: 'Domain: example.com',
509
- },
510
- {
511
- timestamp: Date.now() - 1000 * 60 * 30,
512
- event: 'IP blocked due to spam',
513
- severity: 'high',
514
- details: 'IP: 10.0.0.1',
515
- },
516
- ];
518
+ const events: any[] = metrics.recentEvents || [];
519
+ return events.map((evt: any) => ({
520
+ timestamp: evt.timestamp,
521
+ event: evt.message,
522
+ severity: evt.level === 'critical' ? 'critical' : evt.level === 'error' ? 'high' : evt.level === 'warn' ? 'warning' : 'info',
523
+ details: evt.ipAddress ? `IP: ${evt.ipAddress}` : evt.domain ? `Domain: ${evt.domain}` : evt.type,
524
+ }));
517
525
  }
518
526
 
519
527
  private async clearBlockedIPs() {
520
- console.log('Clear blocked IPs');
528
+ // SmartProxy manages IP blocking — not yet exposed via API
529
+ alert('Clearing blocked IPs is not yet supported from the UI.');
521
530
  }
522
531
 
523
532
  private async unblockIP(ip: string) {
524
- console.log('Unblock IP:', ip);
533
+ // SmartProxy manages IP blocking — not yet exposed via API
534
+ alert(`Unblocking IP ${ip} is not yet supported from the UI.`);
525
535
  }
526
536
 
527
537
  private async saveEmailSecuritySettings() {
528
- console.log('Save email security settings');
538
+ // Config is read-only from the UI for now
539
+ alert('Email security settings are read-only. Update the dcrouter configuration file to change these settings.');
529
540
  }
530
541
  }