import * as plugins from '../plugins.js'; import * as shared from './shared/index.js'; import * as appstate from '../appstate.js'; import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element'; import { type IStatsTile } from '@design.estate/dees-catalog'; @customElement('ops-view-security') export class OpsViewSecurity extends DeesElement { @state() private statsState: appstate.IStatsState = { serverStats: null, emailStats: null, dnsStats: null, securityMetrics: null, lastUpdated: 0, isLoading: false, error: null, }; @state() private selectedTab: 'overview' | 'blocked' | 'authentication' | 'email-security' = 'overview'; constructor() { super(); const subscription = appstate.statsStatePart .select((stateArg) => stateArg) .subscribe((statsState) => { this.statsState = statsState; }); this.rxSubscriptions.push(subscription); } public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css` .tabs { display: flex; gap: 8px; margin-bottom: 24px; border-bottom: 2px solid ${cssManager.bdTheme('#e9ecef', '#333')}; } .tab { padding: 12px 24px; background: none; border: none; border-bottom: 2px solid transparent; cursor: pointer; font-size: 16px; color: ${cssManager.bdTheme('#666', '#999')}; transition: all 0.2s ease; } .tab:hover { color: ${cssManager.bdTheme('#333', '#ccc')}; } .tab.active { color: ${cssManager.bdTheme('#2196F3', '#4a90e2')}; border-bottom-color: ${cssManager.bdTheme('#2196F3', '#4a90e2')}; } h2 { margin: 32px 0 16px 0; font-size: 24px; font-weight: 600; color: ${cssManager.bdTheme('#333', '#ccc')}; } dees-statsgrid { margin-bottom: 32px; } .securityCard { background: ${cssManager.bdTheme('#fff', '#222')}; border: 1px solid ${cssManager.bdTheme('#e9ecef', '#333')}; border-radius: 8px; padding: 24px; position: relative; overflow: hidden; } .securityCard.alert { border-color: ${cssManager.bdTheme('#f44336', '#ff6666')}; background: ${cssManager.bdTheme('#ffebee', '#4a1f1f')}; } .securityCard.warning { border-color: ${cssManager.bdTheme('#ff9800', '#ffaa33')}; background: ${cssManager.bdTheme('#fff3e0', '#4a3a1f')}; } .securityCard.success { border-color: ${cssManager.bdTheme('#4caf50', '#66cc66')}; background: ${cssManager.bdTheme('#e8f5e9', '#1f3f1f')}; } .cardHeader { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .cardTitle { font-size: 18px; font-weight: 600; color: ${cssManager.bdTheme('#333', '#ccc')}; } .cardStatus { font-size: 14px; padding: 4px 12px; border-radius: 16px; font-weight: 500; } .status-critical { background: ${cssManager.bdTheme('#f44336', '#ff6666')}; color: ${cssManager.bdTheme('#fff', '#fff')}; } .status-warning { background: ${cssManager.bdTheme('#ff9800', '#ffaa33')}; color: ${cssManager.bdTheme('#fff', '#fff')}; } .status-good { background: ${cssManager.bdTheme('#4caf50', '#66cc66')}; color: ${cssManager.bdTheme('#fff', '#fff')}; } .metricValue { font-size: 32px; font-weight: 700; margin-bottom: 8px; } .metricLabel { font-size: 14px; color: ${cssManager.bdTheme('#666', '#999')}; } .actionButton { margin-top: 16px; } .blockedIpList { max-height: 400px; overflow-y: auto; } .blockedIpItem { display: flex; justify-content: space-between; align-items: center; padding: 12px; border-bottom: 1px solid ${cssManager.bdTheme('#e9ecef', '#333')}; } .blockedIpItem:last-child { border-bottom: none; } .ipAddress { font-family: 'Consolas', 'Monaco', monospace; font-weight: 600; } .blockReason { font-size: 14px; color: ${cssManager.bdTheme('#666', '#999')}; } .blockTime { font-size: 12px; color: ${cssManager.bdTheme('#999', '#666')}; } `, ]; public render() { return html` Security
${this.renderTabContent()} `; } private renderTabContent() { const metrics = this.statsState.securityMetrics; if (!metrics) { return html`

Loading security metrics...

`; } switch(this.selectedTab) { case 'overview': return this.renderOverview(metrics); case 'blocked': return this.renderBlockedIPs(metrics); case 'authentication': return this.renderAuthentication(metrics); case 'email-security': return this.renderEmailSecurity(metrics); } } private renderOverview(metrics: any) { const threatLevel = this.calculateThreatLevel(metrics); const threatScore = this.getThreatScore(metrics); const tiles: IStatsTile[] = [ { id: 'threatLevel', title: 'Threat Level', value: threatScore, type: 'gauge', icon: 'shield', gaugeOptions: { min: 0, max: 100, thresholds: [ { value: 0, color: '#ef4444' }, { value: 30, color: '#f59e0b' }, { value: 70, color: '#22c55e' }, ], }, description: `Status: ${threatLevel.toUpperCase()}`, }, { id: 'blockedThreats', title: 'Blocked Threats', value: metrics.blockedIPs.length + metrics.spamDetected, type: 'number', icon: 'userShield', color: '#ef4444', description: 'Total threats blocked today', }, { id: 'activeSessions', title: 'Active Sessions', value: 0, type: 'number', icon: 'users', color: '#22c55e', description: 'Current authenticated sessions', }, { id: 'authFailures', title: 'Auth Failures', value: metrics.authenticationFailures, type: 'number', icon: 'lockOpen', color: metrics.authenticationFailures > 10 ? '#ef4444' : '#f59e0b', description: 'Failed login attempts today', }, ]; return html`

Recent Security Events

({ 'Time': new Date(item.timestamp).toLocaleTimeString(), 'Event': item.event, 'Severity': item.severity, 'Details': item.details, })} > `; } private renderBlockedIPs(metrics: any) { return html`

Blocked IP Addresses

this.clearBlockedIPs()}> Clear All
${metrics.blockedIPs && metrics.blockedIPs.length > 0 ? metrics.blockedIPs.map((ipAddress, index) => html`
${ipAddress}
Suspicious activity
Blocked
this.unblockIP(ipAddress)}> Unblock
`) : html`

No blocked IPs

`}
`; } private renderAuthentication(metrics: any) { const tiles: IStatsTile[] = [ { id: 'authFailures', title: 'Authentication Failures', value: metrics.authenticationFailures, type: 'number', icon: 'lockOpen', color: metrics.authenticationFailures > 10 ? '#ef4444' : '#f59e0b', description: 'Failed authentication attempts today', }, { id: 'successfulLogins', title: 'Successful Logins', value: 0, type: 'number', icon: 'lock', color: '#22c55e', description: 'Successful logins today', }, ]; return html`

Recent Login Attempts

({ 'Time': new Date(item.timestamp).toLocaleString(), 'Username': item.username, 'IP Address': item.ipAddress, 'Status': item.success ? 'Success' : 'Failed', 'Reason': item.reason || '-', })} > `; } private renderEmailSecurity(metrics: any) { const tiles: IStatsTile[] = [ { id: 'malware', title: 'Malware Detection', value: metrics.malwareDetected, type: 'number', icon: 'virusSlash', color: metrics.malwareDetected > 0 ? '#ef4444' : '#22c55e', description: 'Malware detected', }, { id: 'phishing', title: 'Phishing Detection', value: metrics.phishingDetected, type: 'number', icon: 'fishFins', color: metrics.phishingDetected > 0 ? '#ef4444' : '#22c55e', description: 'Phishing attempts detected', }, { id: 'suspicious', title: 'Suspicious Activities', value: metrics.suspiciousActivities, type: 'number', icon: 'triangleExclamation', color: metrics.suspiciousActivities > 5 ? '#ef4444' : '#f59e0b', description: 'Suspicious activities detected', }, { id: 'spam', title: 'Spam Detection', value: metrics.spamDetected, type: 'number', icon: 'ban', color: '#f59e0b', description: 'Spam emails blocked', }, ]; return html`

Email Security Configuration

this.saveEmailSecuritySettings()} > Save Settings
`; } private calculateThreatLevel(metrics: any): string { const score = this.getThreatScore(metrics); if (score < 30) return 'alert'; if (score < 70) return 'warning'; return 'success'; } private getThreatScore(metrics: any): number { // Simple scoring algorithm let score = 100; score -= metrics.blockedIPs.length * 2; score -= metrics.authenticationFailures * 1; score -= metrics.spamDetected * 0.5; score -= metrics.malwareDetected * 3; score -= metrics.phishingDetected * 3; score -= metrics.suspiciousActivities * 2; return Math.max(0, Math.min(100, Math.round(score))); } private getSecurityEvents(metrics: any): any[] { // Mock data - in real implementation, this would come from the server return [ { timestamp: Date.now() - 1000 * 60 * 5, event: 'Multiple failed login attempts', severity: 'warning', details: 'IP: 192.168.1.100', }, { timestamp: Date.now() - 1000 * 60 * 15, event: 'SPF check failed', severity: 'medium', details: 'Domain: example.com', }, { timestamp: Date.now() - 1000 * 60 * 30, event: 'IP blocked due to spam', severity: 'high', details: 'IP: 10.0.0.1', }, ]; } private async clearBlockedIPs() { console.log('Clear blocked IPs'); } private async unblockIP(ip: string) { console.log('Unblock IP:', ip); } private async saveEmailSecuritySettings() { console.log('Save email security settings'); } }