336 lines
15 KiB
TypeScript
336 lines
15 KiB
TypeScript
import {
|
|
DeesElement,
|
|
customElement,
|
|
html,
|
|
css,
|
|
cssManager,
|
|
state,
|
|
type TemplateResult,
|
|
} from '@design.estate/dees-element';
|
|
import type { DeesAppui } from '@design.estate/dees-catalog';
|
|
import type { IEmail, TEmailDirection } from './sz-mta-list-view.js';
|
|
import type { IEmailDetail } from './sz-mta-detail-view.js';
|
|
import './index.js';
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
'sz-demo-view-mta': SzDemoViewMta;
|
|
}
|
|
}
|
|
|
|
@customElement('sz-demo-view-mta')
|
|
export class SzDemoViewMta extends DeesElement {
|
|
private appui: DeesAppui | null = null;
|
|
|
|
@state()
|
|
private accessor currentView: 'list' | 'detail' = 'list';
|
|
|
|
@state()
|
|
private accessor selectedEmail: IEmailDetail | null = null;
|
|
|
|
@state()
|
|
private accessor currentDirectionFilter: TEmailDirection | 'all' = 'all';
|
|
|
|
private demoEmails: IEmail[] = [
|
|
{ id: '1', direction: 'outbound', status: 'delivered', from: 'noreply@serve.zone', to: 'user@example.com', subject: 'Welcome to serve.zone', timestamp: '2024-01-15 14:30:22', messageId: '<abc123@serve.zone>', size: '12.4 KB' },
|
|
{ id: '2', direction: 'outbound', status: 'bounced', from: 'alerts@serve.zone', to: 'invalid@nowhere.test', subject: 'Service Alert: CPU Usage High', timestamp: '2024-01-15 14:28:10', messageId: '<def456@serve.zone>', size: '8.2 KB' },
|
|
{ id: '3', direction: 'inbound', status: 'delivered', from: 'support@customer.com', to: 'admin@serve.zone', subject: 'Re: Infrastructure Review', timestamp: '2024-01-15 14:25:00', messageId: '<ghi789@customer.com>', size: '24.1 KB' },
|
|
{ id: '4', direction: 'outbound', status: 'rejected', from: 'billing@serve.zone', to: 'blocked@spam-domain.test', subject: 'Invoice #2024-001', timestamp: '2024-01-15 14:20:45', messageId: '<jkl012@serve.zone>', size: '45.6 KB' },
|
|
{ id: '5', direction: 'outbound', status: 'deferred', from: 'noreply@serve.zone', to: 'slow@remote-server.test', subject: 'Password Reset Request', timestamp: '2024-01-15 14:15:30', messageId: '<mno345@serve.zone>', size: '6.8 KB' },
|
|
{ id: '6', direction: 'inbound', status: 'delivered', from: 'ci@github.com', to: 'devops@serve.zone', subject: 'Build #4521 passed', timestamp: '2024-01-15 14:10:00', messageId: '<pqr678@github.com>', size: '15.3 KB' },
|
|
{ id: '7', direction: 'outbound', status: 'pending', from: 'reports@serve.zone', to: 'team@serve.zone', subject: 'Weekly Infrastructure Report', timestamp: '2024-01-15 14:05:00', messageId: '<stu901@serve.zone>', size: '102.7 KB' },
|
|
{ id: '8', direction: 'inbound', status: 'delivered', from: 'monitoring@uptime.io', to: 'ops@serve.zone', subject: 'Uptime Report: 99.98%', timestamp: '2024-01-15 13:55:00', messageId: '<vwx234@uptime.io>', size: '9.1 KB' },
|
|
];
|
|
|
|
private demoEmailDetails: Record<string, IEmailDetail> = {
|
|
'1': {
|
|
id: '1',
|
|
direction: 'outbound',
|
|
status: 'delivered',
|
|
from: 'noreply@serve.zone',
|
|
to: 'user@example.com',
|
|
toList: ['user@example.com'],
|
|
subject: 'Welcome to serve.zone',
|
|
timestamp: '2024-01-15 14:30:22',
|
|
messageId: '<abc123@serve.zone>',
|
|
size: '12.4 KB',
|
|
smtpLog: [
|
|
{ timestamp: '14:30:20', direction: 'client', command: 'EHLO mail.serve.zone' },
|
|
{ timestamp: '14:30:20', direction: 'server', command: '250-mail.example.com Hello', responseCode: 250 },
|
|
{ timestamp: '14:30:20', direction: 'server', command: '250-STARTTLS', responseCode: 250 },
|
|
{ timestamp: '14:30:20', direction: 'server', command: '250 SIZE 52428800', responseCode: 250 },
|
|
{ timestamp: '14:30:20', direction: 'client', command: 'STARTTLS' },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '220 Ready to start TLS', responseCode: 220 },
|
|
{ timestamp: '14:30:21', direction: 'client', command: 'EHLO mail.serve.zone' },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '250-mail.example.com Hello', responseCode: 250 },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '250-AUTH PLAIN LOGIN', responseCode: 250 },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '250 SIZE 52428800', responseCode: 250 },
|
|
{ timestamp: '14:30:21', direction: 'client', command: 'AUTH PLAIN AHVzZXIAcGFzc3dvcmQ=' },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '235 2.7.0 Authentication successful', responseCode: 235 },
|
|
{ timestamp: '14:30:21', direction: 'client', command: 'MAIL FROM:<noreply@serve.zone>' },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '250 OK', responseCode: 250 },
|
|
{ timestamp: '14:30:21', direction: 'client', command: 'RCPT TO:<user@example.com>' },
|
|
{ timestamp: '14:30:21', direction: 'server', command: '250 Accepted', responseCode: 250 },
|
|
{ timestamp: '14:30:22', direction: 'client', command: 'DATA' },
|
|
{ timestamp: '14:30:22', direction: 'server', command: '354 Enter message, ending with "." on a line by itself', responseCode: 354 },
|
|
{ timestamp: '14:30:22', direction: 'client', command: '.' },
|
|
{ timestamp: '14:30:22', direction: 'server', command: '250 OK id=1pQ2rS-0003Ab-C4', responseCode: 250 },
|
|
{ timestamp: '14:30:22', direction: 'client', command: 'QUIT' },
|
|
{ timestamp: '14:30:22', direction: 'server', command: '221 mail.example.com closing connection', responseCode: 221 },
|
|
],
|
|
connectionInfo: {
|
|
sourceIp: '10.0.1.50',
|
|
sourceHostname: 'mail.serve.zone',
|
|
destinationIp: '93.184.216.34',
|
|
destinationPort: 25,
|
|
tlsVersion: 'TLSv1.3',
|
|
tlsCipher: 'TLS_AES_256_GCM_SHA384',
|
|
authenticated: true,
|
|
authMethod: 'PLAIN',
|
|
authUser: 'noreply@serve.zone',
|
|
},
|
|
authenticationResults: {
|
|
spf: 'pass',
|
|
spfDomain: 'serve.zone',
|
|
dkim: 'pass',
|
|
dkimDomain: 'serve.zone',
|
|
dmarc: 'pass',
|
|
dmarcPolicy: 'reject',
|
|
},
|
|
headers: {
|
|
'From': 'noreply@serve.zone',
|
|
'To': 'user@example.com',
|
|
'Subject': 'Welcome to serve.zone',
|
|
'Date': 'Mon, 15 Jan 2024 14:30:22 +0000',
|
|
'MIME-Version': '1.0',
|
|
'Content-Type': 'text/html; charset=UTF-8',
|
|
},
|
|
body: '<html>\n<head><title>Welcome</title></head>\n<body>\n <h1>Welcome to serve.zone!</h1>\n <p>Your account has been created successfully.</p>\n <p>Get started by visiting your <a href="https://serve.zone/dashboard">dashboard</a>.</p>\n</body>\n</html>',
|
|
},
|
|
'2': {
|
|
id: '2',
|
|
direction: 'outbound',
|
|
status: 'bounced',
|
|
from: 'alerts@serve.zone',
|
|
to: 'invalid@nowhere.test',
|
|
toList: ['invalid@nowhere.test'],
|
|
subject: 'Service Alert: CPU Usage High',
|
|
timestamp: '2024-01-15 14:28:10',
|
|
messageId: '<def456@serve.zone>',
|
|
size: '8.2 KB',
|
|
rejectionReason: '550 5.1.1 The email account that you tried to reach does not exist.',
|
|
bounceMessage: 'Delivery to the following recipient failed permanently:\n\n invalid@nowhere.test\n\nTechnical details of permanent failure:\nGoogle tried to deliver your message, but it was rejected by the server for the recipient domain nowhere.test.',
|
|
smtpLog: [
|
|
{ timestamp: '14:28:08', direction: 'client', command: 'EHLO mail.serve.zone' },
|
|
{ timestamp: '14:28:08', direction: 'server', command: '250-mail.nowhere.test Hello', responseCode: 250 },
|
|
{ timestamp: '14:28:08', direction: 'client', command: 'MAIL FROM:<alerts@serve.zone>' },
|
|
{ timestamp: '14:28:09', direction: 'server', command: '250 OK', responseCode: 250 },
|
|
{ timestamp: '14:28:09', direction: 'client', command: 'RCPT TO:<invalid@nowhere.test>' },
|
|
{ timestamp: '14:28:10', direction: 'server', command: '550 5.1.1 The email account that you tried to reach does not exist.', responseCode: 550 },
|
|
{ timestamp: '14:28:10', direction: 'client', command: 'QUIT' },
|
|
{ timestamp: '14:28:10', direction: 'server', command: '221 Bye', responseCode: 221 },
|
|
],
|
|
connectionInfo: {
|
|
sourceIp: '10.0.1.50',
|
|
sourceHostname: 'mail.serve.zone',
|
|
destinationIp: '198.51.100.25',
|
|
destinationPort: 25,
|
|
tlsVersion: 'TLSv1.2',
|
|
tlsCipher: 'ECDHE-RSA-AES128-GCM-SHA256',
|
|
authenticated: true,
|
|
authMethod: 'PLAIN',
|
|
authUser: 'alerts@serve.zone',
|
|
},
|
|
authenticationResults: {
|
|
spf: 'pass',
|
|
spfDomain: 'serve.zone',
|
|
dkim: 'pass',
|
|
dkimDomain: 'serve.zone',
|
|
dmarc: 'pass',
|
|
dmarcPolicy: 'quarantine',
|
|
},
|
|
headers: {
|
|
'From': 'alerts@serve.zone',
|
|
'To': 'invalid@nowhere.test',
|
|
'Subject': 'Service Alert: CPU Usage High',
|
|
'Date': 'Mon, 15 Jan 2024 14:28:10 +0000',
|
|
'MIME-Version': '1.0',
|
|
'Content-Type': 'text/plain; charset=UTF-8',
|
|
},
|
|
body: 'ALERT: CPU Usage High\n\nService: api-gateway\nCurrent Usage: 94.2%\nThreshold: 90%\nTimestamp: 2024-01-15 14:28:00 UTC\n\nPlease investigate immediately.',
|
|
},
|
|
'3': {
|
|
id: '3',
|
|
direction: 'inbound',
|
|
status: 'delivered',
|
|
from: 'support@customer.com',
|
|
to: 'admin@serve.zone',
|
|
toList: ['admin@serve.zone'],
|
|
cc: ['ops@serve.zone'],
|
|
subject: 'Re: Infrastructure Review',
|
|
timestamp: '2024-01-15 14:25:00',
|
|
messageId: '<ghi789@customer.com>',
|
|
size: '24.1 KB',
|
|
smtpLog: [
|
|
{ timestamp: '14:24:58', direction: 'client', command: 'EHLO mail.customer.com' },
|
|
{ timestamp: '14:24:58', direction: 'server', command: '250-mail.serve.zone Hello', responseCode: 250 },
|
|
{ timestamp: '14:24:58', direction: 'server', command: '250-STARTTLS', responseCode: 250 },
|
|
{ timestamp: '14:24:58', direction: 'server', command: '250 SIZE 52428800', responseCode: 250 },
|
|
{ timestamp: '14:24:59', direction: 'client', command: 'STARTTLS' },
|
|
{ timestamp: '14:24:59', direction: 'server', command: '220 Ready to start TLS', responseCode: 220 },
|
|
{ timestamp: '14:24:59', direction: 'client', command: 'MAIL FROM:<support@customer.com>' },
|
|
{ timestamp: '14:24:59', direction: 'server', command: '250 OK', responseCode: 250 },
|
|
{ timestamp: '14:24:59', direction: 'client', command: 'RCPT TO:<admin@serve.zone>' },
|
|
{ timestamp: '14:25:00', direction: 'server', command: '250 Accepted', responseCode: 250 },
|
|
{ timestamp: '14:25:00', direction: 'client', command: 'DATA' },
|
|
{ timestamp: '14:25:00', direction: 'server', command: '354 Enter message', responseCode: 354 },
|
|
{ timestamp: '14:25:00', direction: 'client', command: '.' },
|
|
{ timestamp: '14:25:00', direction: 'server', command: '250 OK id=2bR3sT-0004Cd-E5', responseCode: 250 },
|
|
],
|
|
connectionInfo: {
|
|
sourceIp: '203.0.113.45',
|
|
sourceHostname: 'mail.customer.com',
|
|
destinationIp: '10.0.1.50',
|
|
destinationPort: 25,
|
|
tlsVersion: 'TLSv1.3',
|
|
tlsCipher: 'TLS_AES_128_GCM_SHA256',
|
|
authenticated: false,
|
|
authMethod: '',
|
|
authUser: '',
|
|
},
|
|
authenticationResults: {
|
|
spf: 'pass',
|
|
spfDomain: 'customer.com',
|
|
dkim: 'pass',
|
|
dkimDomain: 'customer.com',
|
|
dmarc: 'pass',
|
|
dmarcPolicy: 'none',
|
|
},
|
|
headers: {
|
|
'From': 'support@customer.com',
|
|
'To': 'admin@serve.zone',
|
|
'CC': 'ops@serve.zone',
|
|
'Subject': 'Re: Infrastructure Review',
|
|
'Date': 'Mon, 15 Jan 2024 14:25:00 +0000',
|
|
'MIME-Version': '1.0',
|
|
'Content-Type': 'text/plain; charset=UTF-8',
|
|
'In-Reply-To': '<prev123@serve.zone>',
|
|
},
|
|
body: 'Hi Admin,\n\nThank you for the detailed infrastructure review report.\n\nWe have reviewed the recommendations and would like to\nproceed with the following:\n\n1. Upgrade to the Pro tier\n2. Enable automatic backups\n3. Set up monitoring alerts\n\nPlease let us know the timeline for these changes.\n\nBest regards,\nCustomer Support Team',
|
|
},
|
|
};
|
|
|
|
async onActivate(context: { appui: DeesAppui; viewId: string }) {
|
|
this.appui = context.appui;
|
|
|
|
this.appui.setContentTabs([
|
|
{
|
|
key: 'All Emails',
|
|
action: () => {
|
|
this.currentDirectionFilter = 'all';
|
|
this.currentView = 'list';
|
|
this.updateSecondaryMenu();
|
|
},
|
|
},
|
|
{
|
|
key: 'Inbound',
|
|
action: () => {
|
|
this.currentDirectionFilter = 'inbound';
|
|
this.currentView = 'list';
|
|
this.updateSecondaryMenu();
|
|
},
|
|
},
|
|
{
|
|
key: 'Outbound',
|
|
action: () => {
|
|
this.currentDirectionFilter = 'outbound';
|
|
this.currentView = 'list';
|
|
this.updateSecondaryMenu();
|
|
},
|
|
},
|
|
]);
|
|
|
|
this.updateSecondaryMenu();
|
|
}
|
|
|
|
private updateSecondaryMenu() {
|
|
if (!this.appui) return;
|
|
|
|
this.appui.setSecondaryMenu({
|
|
heading: 'Email / MTA',
|
|
groups: [
|
|
{
|
|
name: 'Actions',
|
|
items: [
|
|
{ type: 'action', key: 'Refresh', iconName: 'lucide:RefreshCw', action: () => { console.log('Refresh emails'); } },
|
|
{ type: 'action', key: 'Export Logs', iconName: 'lucide:Download', action: () => { console.log('Export logs'); } },
|
|
],
|
|
},
|
|
{
|
|
name: 'Status Filters',
|
|
items: [
|
|
{ key: 'Delivered', iconName: 'lucide:CheckCircle', badge: '5', badgeVariant: 'success' as const, action: () => { console.log('Filter delivered'); } },
|
|
{ key: 'Bounced', iconName: 'lucide:XCircle', badge: '1', badgeVariant: 'error' as const, action: () => { console.log('Filter bounced'); } },
|
|
{ key: 'Deferred', iconName: 'lucide:Clock', badge: '1', badgeVariant: 'warning' as const, action: () => { console.log('Filter deferred'); } },
|
|
{ key: 'Pending', iconName: 'lucide:Loader', badge: '1', action: () => { console.log('Filter pending'); } },
|
|
],
|
|
},
|
|
{
|
|
name: 'Statistics',
|
|
items: [
|
|
{ type: 'header' as const, label: '8 Total Emails' },
|
|
{ type: 'header' as const, label: '62.5% Delivery Rate' },
|
|
],
|
|
},
|
|
],
|
|
});
|
|
}
|
|
|
|
onDeactivate() {
|
|
// Cleanup if needed
|
|
}
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
css`
|
|
:host {
|
|
display: block;
|
|
padding: 24px;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
box-sizing: border-box;
|
|
}
|
|
`,
|
|
];
|
|
|
|
public render(): TemplateResult {
|
|
if (this.currentView === 'detail' && this.selectedEmail) {
|
|
return html`
|
|
<sz-mta-detail-view
|
|
.email=${this.selectedEmail}
|
|
@back=${() => { this.currentView = 'list'; this.selectedEmail = null; }}
|
|
></sz-mta-detail-view>
|
|
`;
|
|
}
|
|
|
|
return html`
|
|
<sz-mta-list-view
|
|
.emails=${this.currentDirectionFilter === 'all'
|
|
? this.demoEmails
|
|
: this.demoEmails.filter(e => e.direction === this.currentDirectionFilter)}
|
|
@email-click=${(e: CustomEvent<IEmail>) => this.handleEmailClick(e.detail)}
|
|
></sz-mta-list-view>
|
|
`;
|
|
}
|
|
|
|
private handleEmailClick(email: IEmail) {
|
|
const detail = this.demoEmailDetails[email.id];
|
|
if (detail) {
|
|
this.selectedEmail = detail;
|
|
this.currentView = 'detail';
|
|
} else {
|
|
console.log('No detail data available for email:', email.id);
|
|
}
|
|
}
|
|
}
|