mxroute-cli 0.2.0 → 0.3.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.
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.notifySetup = notifySetup;
7
+ exports.notifyTest = notifyTest;
8
+ exports.sendNotification = sendNotification;
9
+ const node_fetch_1 = __importDefault(require("node-fetch"));
10
+ const inquirer_1 = __importDefault(require("inquirer"));
11
+ const theme_1 = require("../utils/theme");
12
+ const config_1 = require("../utils/config");
13
+ async function notifySetup() {
14
+ console.log(theme_1.theme.heading('Notification Setup'));
15
+ console.log(theme_1.theme.muted(' Configure where to send monitoring alerts.\n'));
16
+ const { channel } = await inquirer_1.default.prompt([
17
+ {
18
+ type: 'list',
19
+ name: 'channel',
20
+ message: 'Notification channel:',
21
+ choices: [
22
+ { name: 'Slack (webhook URL)', value: 'slack' },
23
+ { name: 'Discord (webhook URL)', value: 'discord' },
24
+ { name: 'Telegram (bot token + chat ID)', value: 'telegram' },
25
+ { name: 'Email (uses configured SMTP)', value: 'email' },
26
+ ],
27
+ },
28
+ ]);
29
+ const notifyConfig = { type: channel };
30
+ if (channel === 'slack' || channel === 'discord') {
31
+ const { webhook } = await inquirer_1.default.prompt([
32
+ {
33
+ type: 'input',
34
+ name: 'webhook',
35
+ message: theme_1.theme.secondary(`${channel === 'slack' ? 'Slack' : 'Discord'} webhook URL:`),
36
+ validate: (input) => (input.startsWith('http') ? true : 'Enter a valid URL'),
37
+ },
38
+ ]);
39
+ notifyConfig.webhook = webhook;
40
+ }
41
+ else if (channel === 'telegram') {
42
+ const answers = await inquirer_1.default.prompt([
43
+ {
44
+ type: 'input',
45
+ name: 'botToken',
46
+ message: theme_1.theme.secondary('Telegram Bot Token:'),
47
+ validate: (i) => (i.trim() ? true : 'Required'),
48
+ },
49
+ {
50
+ type: 'input',
51
+ name: 'chatId',
52
+ message: theme_1.theme.secondary('Chat ID:'),
53
+ validate: (i) => (i.trim() ? true : 'Required'),
54
+ },
55
+ ]);
56
+ notifyConfig.botToken = answers.botToken;
57
+ notifyConfig.chatId = answers.chatId;
58
+ }
59
+ // Test notification
60
+ const { test } = await inquirer_1.default.prompt([
61
+ { type: 'confirm', name: 'test', message: 'Send a test notification?', default: true },
62
+ ]);
63
+ if (test) {
64
+ const success = await sendNotification(notifyConfig, 'MXroute CLI', 'Test notification — monitoring alerts are configured!');
65
+ if (success) {
66
+ console.log(theme_1.theme.success(`\n ${theme_1.theme.statusIcon('pass')} Test notification sent!`));
67
+ }
68
+ else {
69
+ console.log(theme_1.theme.error(`\n ${theme_1.theme.statusIcon('fail')} Failed to send test notification.`));
70
+ }
71
+ }
72
+ (0, config_1.setConfig)('notify', notifyConfig);
73
+ console.log(theme_1.theme.success(`\n ${theme_1.theme.statusIcon('pass')} Notification channel saved.\n`));
74
+ console.log(theme_1.theme.muted(` Alerts will be sent when running: mxroute monitor --alert\n`));
75
+ }
76
+ async function notifyTest() {
77
+ const config = (0, config_1.getConfig)();
78
+ const notifyConfig = config.notify;
79
+ if (!notifyConfig) {
80
+ console.log(theme_1.theme.error(`\n ${theme_1.theme.statusIcon('fail')} No notification channel configured. Run ${theme_1.theme.bold('mxroute notify setup')}\n`));
81
+ return;
82
+ }
83
+ console.log(theme_1.theme.muted(`\n Sending test to ${notifyConfig.type}...`));
84
+ const success = await sendNotification(notifyConfig, 'MXroute CLI', 'Test notification from mxroute-cli');
85
+ if (success) {
86
+ console.log(theme_1.theme.success(` ${theme_1.theme.statusIcon('pass')} Sent!\n`));
87
+ }
88
+ else {
89
+ console.log(theme_1.theme.error(` ${theme_1.theme.statusIcon('fail')} Failed.\n`));
90
+ }
91
+ }
92
+ async function sendNotification(channel, title, message) {
93
+ try {
94
+ switch (channel.type) {
95
+ case 'slack':
96
+ return await sendSlack(channel.webhook, title, message);
97
+ case 'discord':
98
+ return await sendDiscord(channel.webhook, title, message);
99
+ case 'telegram':
100
+ return await sendTelegram(channel.botToken, channel.chatId, title, message);
101
+ case 'email':
102
+ return true; // Handled by monitor command directly
103
+ default:
104
+ return false;
105
+ }
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ async function sendSlack(webhook, title, message) {
112
+ const res = await (0, node_fetch_1.default)(webhook, {
113
+ method: 'POST',
114
+ headers: { 'Content-Type': 'application/json' },
115
+ body: JSON.stringify({
116
+ text: `*${title}*\n${message}`,
117
+ blocks: [
118
+ { type: 'header', text: { type: 'plain_text', text: title } },
119
+ { type: 'section', text: { type: 'mrkdwn', text: message } },
120
+ ],
121
+ }),
122
+ });
123
+ return res.ok;
124
+ }
125
+ async function sendDiscord(webhook, title, message) {
126
+ const res = await (0, node_fetch_1.default)(webhook, {
127
+ method: 'POST',
128
+ headers: { 'Content-Type': 'application/json' },
129
+ body: JSON.stringify({
130
+ embeds: [
131
+ {
132
+ title,
133
+ description: message,
134
+ color: 0xff5252,
135
+ footer: { text: 'mxroute-cli monitor' },
136
+ timestamp: new Date().toISOString(),
137
+ },
138
+ ],
139
+ }),
140
+ });
141
+ return res.ok;
142
+ }
143
+ async function sendTelegram(botToken, chatId, title, message) {
144
+ const text = `*${title}*\n${message}`;
145
+ const res = await (0, node_fetch_1.default)(`https://api.telegram.org/bot${botToken}/sendMessage`, {
146
+ method: 'POST',
147
+ headers: { 'Content-Type': 'application/json' },
148
+ body: JSON.stringify({ chat_id: chatId, text, parse_mode: 'Markdown' }),
149
+ });
150
+ const data = (await res.json());
151
+ return data.ok === true;
152
+ }
153
+ //# sourceMappingURL=notify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/commands/notify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function onboardCommand(domain?: string): Promise<void>;
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.onboardCommand = onboardCommand;
7
+ const ora_1 = __importDefault(require("ora"));
8
+ const inquirer_1 = __importDefault(require("inquirer"));
9
+ const theme_1 = require("../utils/theme");
10
+ const config_1 = require("../utils/config");
11
+ const shared_1 = require("../utils/shared");
12
+ const directadmin_1 = require("../utils/directadmin");
13
+ const registrars_1 = require("../utils/registrars");
14
+ const dns_1 = require("../utils/dns");
15
+ async function onboardCommand(domain) {
16
+ const config = (0, config_1.getConfig)();
17
+ const creds = (0, shared_1.getCreds)();
18
+ console.log(theme_1.theme.heading('Domain Onboarding'));
19
+ console.log(theme_1.theme.muted(' Complete domain setup in one command.\n'));
20
+ // Step 1: Domain
21
+ if (!domain) {
22
+ const { d } = await inquirer_1.default.prompt([
23
+ {
24
+ type: 'input',
25
+ name: 'd',
26
+ message: theme_1.theme.secondary('Domain to onboard:'),
27
+ validate: (input) => (input.includes('.') ? true : 'Enter a valid domain'),
28
+ },
29
+ ]);
30
+ domain = d;
31
+ }
32
+ // Check if domain already exists
33
+ const existingDomains = await (0, directadmin_1.listDomains)(creds);
34
+ const alreadyExists = existingDomains.includes(domain);
35
+ console.log(theme_1.theme.subheading(`Domain: ${domain}`));
36
+ console.log(alreadyExists
37
+ ? theme_1.theme.success(` ${theme_1.theme.statusIcon('pass')} Already on your MXroute account`)
38
+ : theme_1.theme.muted(` ${theme_1.theme.statusIcon('info')} Will need to be added via Control Panel`));
39
+ console.log('');
40
+ // Step 2: Standard accounts
41
+ const { createAccounts } = await inquirer_1.default.prompt([
42
+ {
43
+ type: 'confirm',
44
+ name: 'createAccounts',
45
+ message: 'Create standard email accounts? (admin@, postmaster@, abuse@)',
46
+ default: true,
47
+ },
48
+ ]);
49
+ let customAccounts = [];
50
+ const { addCustom } = await inquirer_1.default.prompt([
51
+ {
52
+ type: 'confirm',
53
+ name: 'addCustom',
54
+ message: 'Add custom email accounts?',
55
+ default: false,
56
+ },
57
+ ]);
58
+ if (addCustom) {
59
+ const { accounts } = await inquirer_1.default.prompt([
60
+ {
61
+ type: 'input',
62
+ name: 'accounts',
63
+ message: theme_1.theme.secondary('Account names (comma-separated, e.g., info,hello,support):'),
64
+ },
65
+ ]);
66
+ customAccounts = accounts
67
+ .split(',')
68
+ .map((a) => a.trim())
69
+ .filter((a) => a);
70
+ }
71
+ // Step 3: DNS setup
72
+ const registrarConfig = config.registrar
73
+ ? {
74
+ provider: config.registrar.provider,
75
+ apiKey: config.registrar.apiKey,
76
+ apiSecret: config.registrar.apiSecret,
77
+ }
78
+ : null;
79
+ const provider = registrarConfig ? (0, registrars_1.getProvider)(registrarConfig.provider) : null;
80
+ const hasDns = !!provider && !!registrarConfig;
81
+ // Step 4: Confirm plan
82
+ console.log(theme_1.theme.heading('Onboarding Plan'));
83
+ const steps = [];
84
+ if (createAccounts) {
85
+ steps.push('Create admin@, postmaster@, abuse@ accounts');
86
+ }
87
+ if (customAccounts.length > 0) {
88
+ steps.push(`Create ${customAccounts.join(', ')}@ accounts`);
89
+ }
90
+ if (hasDns) {
91
+ steps.push(`Configure DNS via ${provider.name} (MX, SPF, DKIM, DMARC)`);
92
+ }
93
+ else {
94
+ steps.push('Generate DNS records (manual setup — no registrar configured)');
95
+ }
96
+ steps.push('Verify DNS configuration');
97
+ for (let i = 0; i < steps.length; i++) {
98
+ console.log(` ${theme_1.theme.secondary(`${i + 1}.`)} ${steps[i]}`);
99
+ }
100
+ console.log('');
101
+ const { proceed } = await inquirer_1.default.prompt([
102
+ {
103
+ type: 'confirm',
104
+ name: 'proceed',
105
+ message: `Proceed with onboarding ${domain}?`,
106
+ default: true,
107
+ },
108
+ ]);
109
+ if (!proceed) {
110
+ console.log(theme_1.theme.muted('\n Cancelled.\n'));
111
+ return;
112
+ }
113
+ // Execute
114
+ console.log(theme_1.theme.heading('Executing'));
115
+ // Create accounts
116
+ const allAccounts = [];
117
+ if (createAccounts)
118
+ allAccounts.push('admin', 'postmaster', 'abuse');
119
+ allAccounts.push(...customAccounts);
120
+ if (allAccounts.length > 0 && alreadyExists) {
121
+ for (const account of allAccounts) {
122
+ const spinner = (0, ora_1.default)({ text: `Creating ${account}@${domain}...`, spinner: 'dots12', color: 'cyan' }).start();
123
+ try {
124
+ // Generate a random password
125
+ const password = generatePassword();
126
+ const result = await (0, directadmin_1.createEmailAccount)(creds, domain, account, password);
127
+ if (result.error && result.error !== '0') {
128
+ spinner.warn(`${account}@${domain}: ${result.text || 'may already exist'}`);
129
+ }
130
+ else {
131
+ spinner.succeed(`${account}@${domain} (password: ${password})`);
132
+ }
133
+ }
134
+ catch (err) {
135
+ spinner.warn(`${account}@${domain}: ${err.message}`);
136
+ }
137
+ }
138
+ console.log('');
139
+ console.log(theme_1.theme.warning(` ${theme_1.theme.statusIcon('warn')} Save the passwords above — they won't be shown again!`));
140
+ console.log('');
141
+ }
142
+ else if (allAccounts.length > 0 && !alreadyExists) {
143
+ console.log(theme_1.theme.warning(`\n ${theme_1.theme.statusIcon('warn')} Domain not yet on MXroute — add it via Control Panel first, then re-run onboard.\n`));
144
+ }
145
+ // DNS setup
146
+ if (hasDns) {
147
+ console.log(theme_1.theme.subheading('Configuring DNS'));
148
+ // Get DKIM key
149
+ let dkimKey = null;
150
+ if (alreadyExists) {
151
+ const dkimSpinner = (0, ora_1.default)({ text: 'Fetching DKIM key...', spinner: 'dots12', color: 'cyan' }).start();
152
+ dkimKey = await (0, directadmin_1.getDkimKey)(creds, domain);
153
+ dkimSpinner.stop();
154
+ }
155
+ const records = (0, registrars_1.generateMxrouteRecords)(config.server, domain, dkimKey || undefined);
156
+ for (const record of records) {
157
+ const spinner = (0, ora_1.default)({ text: `${record.type} ${record.name}...`, spinner: 'dots12', color: 'cyan' }).start();
158
+ try {
159
+ const result = await provider.createRecord(registrarConfig, domain, record);
160
+ if (result.success) {
161
+ spinner.succeed(`${record.type} ${record.name}`);
162
+ }
163
+ else {
164
+ spinner.warn(`${record.type} ${record.name}: ${result.message}`);
165
+ }
166
+ }
167
+ catch (err) {
168
+ spinner.warn(`${record.type} ${record.name}: ${err.message}`);
169
+ }
170
+ }
171
+ }
172
+ else {
173
+ console.log(theme_1.theme.subheading('DNS Records (manual setup)'));
174
+ console.log(theme_1.theme.muted(` Run: ${theme_1.theme.bold(`mxroute dns records ${domain}`)} to see required records`));
175
+ console.log(theme_1.theme.muted(` Or: ${theme_1.theme.bold(`mxroute dns setup ${domain}`)} to configure via registrar API`));
176
+ }
177
+ // Verify
178
+ console.log('');
179
+ console.log(theme_1.theme.subheading('Verification'));
180
+ const verifySpinner = (0, ora_1.default)({ text: 'Checking DNS...', spinner: 'dots12', color: 'cyan' }).start();
181
+ try {
182
+ const results = await (0, dns_1.runFullDnsCheck)(domain, config.server);
183
+ verifySpinner.stop();
184
+ const passed = results.filter((r) => r.status === 'pass').length;
185
+ const total = results.length;
186
+ for (const r of results) {
187
+ console.log(` ${theme_1.theme.statusIcon(r.status)} ${r.type.padEnd(6)} ${theme_1.theme.muted(r.message)}`);
188
+ }
189
+ console.log('');
190
+ if (passed === total) {
191
+ console.log(theme_1.theme.success(` ${theme_1.theme.statusIcon('pass')} ${domain} is fully configured!`));
192
+ }
193
+ else {
194
+ console.log(theme_1.theme.info(` ${theme_1.theme.statusIcon('info')} ${passed}/${total} checks passing. DNS may need time to propagate.`));
195
+ console.log(theme_1.theme.muted(` Run ${theme_1.theme.bold(`mxroute dns watch ${domain}`)} to monitor propagation.`));
196
+ }
197
+ }
198
+ catch {
199
+ verifySpinner.stop();
200
+ console.log(theme_1.theme.muted(' DNS verification will work after propagation.'));
201
+ }
202
+ // Generate share page
203
+ console.log('');
204
+ console.log(theme_1.theme.subheading('Next steps'));
205
+ console.log(theme_1.theme.muted(` mxroute share Generate setup instructions for users`));
206
+ console.log(theme_1.theme.muted(` mxroute accounts list ${domain} View created accounts`));
207
+ console.log(theme_1.theme.muted(` mxroute dns watch ${domain} Monitor DNS propagation`));
208
+ console.log('');
209
+ }
210
+ function generatePassword(length = 16) {
211
+ const chars = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%';
212
+ let password = '';
213
+ const array = new Uint8Array(length);
214
+ require('crypto').randomFillSync(array);
215
+ for (let i = 0; i < length; i++) {
216
+ password += chars[array[i] % chars.length];
217
+ }
218
+ return password;
219
+ }
220
+ //# sourceMappingURL=onboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function reportCommand(): Promise<void>;
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.reportCommand = reportCommand;
40
+ const fs = __importStar(require("fs"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const inquirer_1 = __importDefault(require("inquirer"));
43
+ const theme_1 = require("../utils/theme");
44
+ const config_1 = require("../utils/config");
45
+ const shared_1 = require("../utils/shared");
46
+ const directadmin_1 = require("../utils/directadmin");
47
+ const dns_1 = require("../utils/dns");
48
+ const blacklist_1 = require("../utils/blacklist");
49
+ async function reportCommand() {
50
+ const config = (0, config_1.getConfig)();
51
+ const creds = (0, shared_1.getCreds)();
52
+ console.log(theme_1.theme.heading('Infrastructure Report'));
53
+ const spinner = (0, ora_1.default)({ text: 'Generating report...', spinner: 'dots12', color: 'cyan' }).start();
54
+ try {
55
+ // Gather all data
56
+ const domains = await (0, directadmin_1.listDomains)(creds);
57
+ const [usage, userConfig] = await Promise.all([(0, directadmin_1.getQuotaUsage)(creds), (0, directadmin_1.getUserConfig)(creds)]);
58
+ const domainData = [];
59
+ for (const domain of domains) {
60
+ const [accounts, forwarders, autoresponders, catchAll, spamConfig, dnsResults] = await Promise.all([
61
+ (0, directadmin_1.listEmailAccounts)(creds, domain).catch(() => []),
62
+ (0, directadmin_1.listForwarders)(creds, domain).catch(() => []),
63
+ (0, directadmin_1.listAutoresponders)(creds, domain).catch(() => []),
64
+ (0, directadmin_1.getCatchAll)(creds, domain).catch(() => ''),
65
+ (0, directadmin_1.getSpamConfig)(creds, domain).catch(() => ({})),
66
+ (0, dns_1.runFullDnsCheck)(domain, config.server).catch(() => []),
67
+ ]);
68
+ domainData.push({ domain, accounts, forwarders, autoresponders, catchAll, spamConfig, dnsResults });
69
+ }
70
+ // Blacklist check
71
+ let blacklistResults = [];
72
+ try {
73
+ const ip = await (0, blacklist_1.resolveServerIp)(`${config.server}.mxrouting.net`);
74
+ blacklistResults = await (0, blacklist_1.checkAllBlacklists)(ip);
75
+ }
76
+ catch {
77
+ /* skip */
78
+ }
79
+ spinner.succeed('Data collected');
80
+ // Generate HTML
81
+ const html = generateReportHtml({
82
+ server: config.server,
83
+ daUsername: config.daUsername,
84
+ domains: domainData,
85
+ usage,
86
+ userConfig,
87
+ blacklistResults,
88
+ generatedAt: new Date().toISOString(),
89
+ });
90
+ const filename = `mxroute-report-${new Date().toISOString().split('T')[0]}.html`;
91
+ const { outputFile } = await inquirer_1.default.prompt([
92
+ {
93
+ type: 'input',
94
+ name: 'outputFile',
95
+ message: theme_1.theme.secondary('Output file:'),
96
+ default: filename,
97
+ },
98
+ ]);
99
+ fs.writeFileSync(outputFile, html);
100
+ console.log(theme_1.theme.success(`\n ${theme_1.theme.statusIcon('pass')} Report saved to ${outputFile}`));
101
+ console.log(theme_1.theme.muted(` Open in a browser to view.\n`));
102
+ }
103
+ catch (err) {
104
+ spinner.fail('Report generation failed');
105
+ console.log(theme_1.theme.error(` ${err.message}\n`));
106
+ }
107
+ }
108
+ function generateReportHtml(data) {
109
+ const { server, domains, usage, blacklistResults, generatedAt } = data;
110
+ const totalAccounts = domains.reduce((s, d) => s + d.accounts.length, 0);
111
+ const totalForwarders = domains.reduce((s, d) => s + d.forwarders.length, 0);
112
+ const blacklisted = blacklistResults.filter((r) => r.listed).length;
113
+ let domainSections = '';
114
+ for (const d of domains) {
115
+ const dnsChecks = d.dnsResults || [];
116
+ const dnsPassed = dnsChecks.filter((r) => r.status === 'pass').length;
117
+ const dnsTotal = dnsChecks.length;
118
+ const dnsColor = dnsPassed === dnsTotal ? '#00E676' : dnsPassed >= dnsTotal - 2 ? '#FFD600' : '#FF5252';
119
+ const catchAllLabel = d.catchAll === ':fail:' ? 'Reject' : d.catchAll === ':blackhole:' ? 'Disabled' : d.catchAll || 'Not set';
120
+ domainSections += `
121
+ <div class="card">
122
+ <h3>${d.domain} <span class="dns-score" style="color:${dnsColor}">${dnsPassed}/${dnsTotal} DNS</span></h3>
123
+ <div class="grid">
124
+ <div class="stat"><span class="num">${d.accounts.length}</span><span class="label">Accounts</span></div>
125
+ <div class="stat"><span class="num">${d.forwarders.length}</span><span class="label">Forwarders</span></div>
126
+ <div class="stat"><span class="num">${d.autoresponders.length}</span><span class="label">Autoresponders</span></div>
127
+ </div>
128
+ <div class="detail"><strong>Catch-all:</strong> ${catchAllLabel}</div>
129
+ ${d.accounts.length > 0 ? `<div class="detail"><strong>Accounts:</strong> ${d.accounts.map((a) => `${a}@${d.domain}`).join(', ')}</div>` : ''}
130
+ <div class="dns-list">
131
+ ${dnsChecks.map((r) => `<span class="dns-item ${r.status}">${r.type}: ${r.status}</span>`).join(' ')}
132
+ </div>
133
+ </div>`;
134
+ }
135
+ return `<!DOCTYPE html>
136
+ <html lang="en">
137
+ <head>
138
+ <meta charset="UTF-8">
139
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
140
+ <title>MXroute Infrastructure Report</title>
141
+ <style>
142
+ * { margin: 0; padding: 0; box-sizing: border-box; }
143
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; background: #0a0a1a; color: #e0e0e0; padding: 2rem; }
144
+ .container { max-width: 900px; margin: 0 auto; }
145
+ h1 { color: #00D9FF; font-size: 2rem; margin-bottom: 0.25rem; }
146
+ h2 { color: #6C63FF; font-size: 1.3rem; margin: 2rem 0 1rem; padding-bottom: 0.5rem; border-bottom: 1px solid #1a1a2e; }
147
+ h3 { color: #fff; font-size: 1.1rem; margin-bottom: 0.75rem; display: flex; justify-content: space-between; align-items: center; }
148
+ .subtitle { color: #7C8DB0; margin-bottom: 2rem; }
149
+ .overview { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
150
+ .overview-card { background: #1a1a2e; border: 1px solid #222; border-radius: 8px; padding: 1.25rem; text-align: center; }
151
+ .overview-card .num { font-size: 2rem; font-weight: bold; color: #00D9FF; display: block; }
152
+ .overview-card .label { color: #7C8DB0; font-size: 0.85rem; }
153
+ .card { background: #1a1a2e; border: 1px solid #222; border-radius: 8px; padding: 1.25rem; margin-bottom: 1rem; }
154
+ .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin: 0.75rem 0; }
155
+ .stat { text-align: center; }
156
+ .stat .num { font-size: 1.5rem; font-weight: bold; color: #00D9FF; display: block; }
157
+ .stat .label { color: #7C8DB0; font-size: 0.8rem; }
158
+ .detail { color: #aaa; font-size: 0.9rem; margin: 0.4rem 0; }
159
+ .dns-score { font-size: 0.85rem; font-weight: normal; }
160
+ .dns-list { margin-top: 0.75rem; display: flex; gap: 0.5rem; flex-wrap: wrap; }
161
+ .dns-item { font-size: 0.75rem; padding: 2px 8px; border-radius: 4px; }
162
+ .dns-item.pass { background: #00E67622; color: #00E676; }
163
+ .dns-item.fail { background: #FF525222; color: #FF5252; }
164
+ .dns-item.warn { background: #FFD60022; color: #FFD600; }
165
+ .dns-item.info { background: #448AFF22; color: #448AFF; }
166
+ .bl-clean { color: #00E676; }
167
+ .bl-listed { color: #FF5252; }
168
+ .footer { color: #555; font-size: 0.8rem; margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #1a1a2e; }
169
+ @media (prefers-color-scheme: light) {
170
+ body { background: #f5f5f5; color: #333; }
171
+ .card, .overview-card { background: #fff; border-color: #ddd; }
172
+ .detail { color: #666; }
173
+ }
174
+ </style>
175
+ </head>
176
+ <body>
177
+ <div class="container">
178
+ <h1>MXroute Infrastructure Report</h1>
179
+ <p class="subtitle">Server: ${server}.mxrouting.net — Generated: ${new Date(generatedAt).toLocaleString()}</p>
180
+
181
+ <div class="overview">
182
+ <div class="overview-card"><span class="num">${domains.length}</span><span class="label">Domains</span></div>
183
+ <div class="overview-card"><span class="num">${totalAccounts}</span><span class="label">Email Accounts</span></div>
184
+ <div class="overview-card"><span class="num">${totalForwarders}</span><span class="label">Forwarders</span></div>
185
+ <div class="overview-card"><span class="num">${usage.quota || usage.disk || '?'} MB</span><span class="label">Disk Used</span></div>
186
+ <div class="overview-card"><span class="num ${blacklisted > 0 ? 'bl-listed' : 'bl-clean'}">${blacklisted > 0 ? blacklisted + ' listed' : 'Clean'}</span><span class="label">Blacklists (${blacklistResults.length})</span></div>
187
+ </div>
188
+
189
+ <h2>Domains</h2>
190
+ ${domainSections}
191
+
192
+ ${blacklistResults.length > 0
193
+ ? `
194
+ <h2>IP Reputation</h2>
195
+ <div class="card">
196
+ ${blacklistResults.map((r) => `<span class="dns-item ${r.listed ? 'fail' : 'pass'}">${r.list}: ${r.listed ? 'LISTED' : 'Clean'}</span>`).join(' ')}
197
+ </div>
198
+ `
199
+ : ''}
200
+
201
+ <p class="footer">Generated by mxroute-cli — https://github.com/t-rhex/mxroute-cli</p>
202
+ </div>
203
+ </body>
204
+ </html>`;
205
+ }
206
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"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"}