mxroute-cli 0.2.0 → 0.3.1
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.
- package/dist/commands/fix.d.ts +1 -0
- package/dist/commands/fix.js +226 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/header-analyze.d.ts +2 -0
- package/dist/commands/header-analyze.js +177 -0
- package/dist/commands/header-analyze.js.map +1 -0
- package/dist/commands/migrate.d.ts +1 -0
- package/dist/commands/migrate.js +161 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/notify.d.ts +10 -0
- package/dist/commands/notify.js +153 -0
- package/dist/commands/notify.js.map +1 -0
- package/dist/commands/onboard.d.ts +1 -0
- package/dist/commands/onboard.js +220 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/report.d.ts +1 -0
- package/dist/commands/report.js +206 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/setup.js +18 -3
- package/dist/commands/setup.js.map +1 -1
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fixCommand(): Promise<void>;
|
|
@@ -0,0 +1,226 @@
|
|
|
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.fixCommand = fixCommand;
|
|
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 dns_1 = require("../utils/dns");
|
|
14
|
+
const registrars_1 = require("../utils/registrars");
|
|
15
|
+
async function fixCommand() {
|
|
16
|
+
const config = (0, config_1.getConfig)();
|
|
17
|
+
const creds = (0, shared_1.getCreds)();
|
|
18
|
+
console.log(theme_1.theme.heading('Auto-Fix'));
|
|
19
|
+
console.log(theme_1.theme.muted(' Scanning for issues and preparing fixes...\n'));
|
|
20
|
+
// Get registrar config if available
|
|
21
|
+
const registrarConfig = config.registrar
|
|
22
|
+
? {
|
|
23
|
+
provider: config.registrar.provider,
|
|
24
|
+
apiKey: config.registrar.apiKey,
|
|
25
|
+
apiSecret: config.registrar.apiSecret,
|
|
26
|
+
}
|
|
27
|
+
: null;
|
|
28
|
+
const provider = registrarConfig ? (0, registrars_1.getProvider)(registrarConfig.provider) : null;
|
|
29
|
+
// Fetch domains
|
|
30
|
+
const domSpinner = (0, ora_1.default)({ text: 'Fetching domains...', spinner: 'dots12', color: 'cyan' }).start();
|
|
31
|
+
let domains;
|
|
32
|
+
try {
|
|
33
|
+
domains = await (0, directadmin_1.listDomains)(creds);
|
|
34
|
+
domSpinner.succeed(`Found ${domains.length} domain${domains.length !== 1 ? 's' : ''}`);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
domSpinner.fail('Could not fetch domains');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const actions = [];
|
|
41
|
+
// Scan each domain
|
|
42
|
+
for (const domain of domains) {
|
|
43
|
+
const scanSpinner = (0, ora_1.default)({ text: `Scanning ${domain}...`, spinner: 'dots12', color: 'cyan' }).start();
|
|
44
|
+
// Check MX
|
|
45
|
+
const mx = await (0, dns_1.checkMxRecords)(domain, config.server);
|
|
46
|
+
if (mx.status === 'fail' && provider && registrarConfig) {
|
|
47
|
+
const records = (0, registrars_1.generateMxrouteRecords)(config.server, domain);
|
|
48
|
+
const mxRecords = records.filter((r) => r.type === 'MX');
|
|
49
|
+
actions.push({
|
|
50
|
+
domain,
|
|
51
|
+
issue: 'MX records missing or incorrect',
|
|
52
|
+
fix: 'Create MX records via ' + provider.name,
|
|
53
|
+
execute: async () => {
|
|
54
|
+
for (const r of mxRecords) {
|
|
55
|
+
const res = await provider.createRecord(registrarConfig, domain, r);
|
|
56
|
+
if (!res.success)
|
|
57
|
+
return res;
|
|
58
|
+
}
|
|
59
|
+
return { success: true, message: 'MX records created' };
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Check SPF
|
|
64
|
+
const spf = await (0, dns_1.checkSpfRecord)(domain);
|
|
65
|
+
if (spf.status === 'fail' && provider && registrarConfig) {
|
|
66
|
+
actions.push({
|
|
67
|
+
domain,
|
|
68
|
+
issue: 'SPF record missing',
|
|
69
|
+
fix: 'Create SPF TXT record',
|
|
70
|
+
execute: async () => provider.createRecord(registrarConfig, domain, {
|
|
71
|
+
type: 'TXT',
|
|
72
|
+
name: '@',
|
|
73
|
+
value: 'v=spf1 include:mxroute.com -all',
|
|
74
|
+
ttl: 3600,
|
|
75
|
+
}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else if (spf.status === 'warn' && spf.actual && spf.actual.includes('~all')) {
|
|
79
|
+
// Can't auto-fix soft fail without registrar — just note it
|
|
80
|
+
if (provider && registrarConfig) {
|
|
81
|
+
actions.push({
|
|
82
|
+
domain,
|
|
83
|
+
issue: 'SPF using ~all (soft fail)',
|
|
84
|
+
fix: 'Replace with -all (hard fail)',
|
|
85
|
+
execute: async () => {
|
|
86
|
+
// Delete old, create new
|
|
87
|
+
await provider.deleteRecord(registrarConfig, domain, { type: 'TXT', name: '@', value: spf.actual });
|
|
88
|
+
return provider.createRecord(registrarConfig, domain, {
|
|
89
|
+
type: 'TXT',
|
|
90
|
+
name: '@',
|
|
91
|
+
value: spf.actual.replace('~all', '-all'),
|
|
92
|
+
ttl: 3600,
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Check DKIM
|
|
99
|
+
const dkim = await (0, dns_1.checkDkimRecord)(domain);
|
|
100
|
+
if (dkim.status === 'fail' && provider && registrarConfig) {
|
|
101
|
+
// Try to get DKIM from DirectAdmin
|
|
102
|
+
const dkimKey = await (0, directadmin_1.getDkimKey)(creds, domain);
|
|
103
|
+
if (dkimKey) {
|
|
104
|
+
actions.push({
|
|
105
|
+
domain,
|
|
106
|
+
issue: 'DKIM record missing in DNS',
|
|
107
|
+
fix: 'Create DKIM TXT record from DirectAdmin key',
|
|
108
|
+
execute: async () => provider.createRecord(registrarConfig, domain, {
|
|
109
|
+
type: 'TXT',
|
|
110
|
+
name: 'x._domainkey',
|
|
111
|
+
value: dkimKey,
|
|
112
|
+
ttl: 3600,
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Check DMARC
|
|
118
|
+
const dmarc = await (0, dns_1.checkDmarcRecord)(domain);
|
|
119
|
+
if (dmarc.status === 'fail' || (dmarc.status === 'warn' && dmarc.actual && dmarc.actual.includes('p=none'))) {
|
|
120
|
+
if (provider && registrarConfig) {
|
|
121
|
+
const isNone = dmarc.actual && dmarc.actual.includes('p=none');
|
|
122
|
+
actions.push({
|
|
123
|
+
domain,
|
|
124
|
+
issue: isNone ? 'DMARC policy is "none" (no protection)' : 'DMARC record missing',
|
|
125
|
+
fix: isNone ? 'Upgrade to p=quarantine' : 'Create DMARC record with p=quarantine',
|
|
126
|
+
execute: async () => {
|
|
127
|
+
if (isNone) {
|
|
128
|
+
await provider.deleteRecord(registrarConfig, domain, {
|
|
129
|
+
type: 'TXT',
|
|
130
|
+
name: '_dmarc',
|
|
131
|
+
value: dmarc.actual,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return provider.createRecord(registrarConfig, domain, {
|
|
135
|
+
type: 'TXT',
|
|
136
|
+
name: '_dmarc',
|
|
137
|
+
value: `v=DMARC1; p=quarantine; rua=mailto:postmaster@${domain}`,
|
|
138
|
+
ttl: 3600,
|
|
139
|
+
});
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Check catch-all
|
|
145
|
+
try {
|
|
146
|
+
const catchAll = await (0, directadmin_1.getCatchAll)(creds, domain);
|
|
147
|
+
if (catchAll && catchAll !== ':fail:' && catchAll !== ':blackhole:') {
|
|
148
|
+
actions.push({
|
|
149
|
+
domain,
|
|
150
|
+
issue: `Catch-all is open (forwarding to ${catchAll})`,
|
|
151
|
+
fix: 'Set catch-all to reject',
|
|
152
|
+
execute: async () => {
|
|
153
|
+
await (0, directadmin_1.setCatchAll)(creds, domain, ':fail:');
|
|
154
|
+
return { success: true, message: 'Catch-all set to reject' };
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
/* skip */
|
|
161
|
+
}
|
|
162
|
+
scanSpinner.stop();
|
|
163
|
+
}
|
|
164
|
+
// Show results
|
|
165
|
+
if (actions.length === 0) {
|
|
166
|
+
console.log(theme_1.theme.success(`\n ${theme_1.theme.statusIcon('pass')} No issues found — everything looks healthy!\n`));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
console.log(theme_1.theme.heading(`Found ${actions.length} fixable issue${actions.length !== 1 ? 's' : ''}`));
|
|
170
|
+
for (let i = 0; i < actions.length; i++) {
|
|
171
|
+
console.log(` ${theme_1.theme.warning(`${i + 1}.`)} ${theme_1.theme.bold(actions[i].domain)} — ${actions[i].issue}`);
|
|
172
|
+
console.log(theme_1.theme.muted(` Fix: ${actions[i].fix}`));
|
|
173
|
+
}
|
|
174
|
+
console.log('');
|
|
175
|
+
if (!provider) {
|
|
176
|
+
console.log(theme_1.theme.warning(` ${theme_1.theme.statusIcon('warn')} DNS fixes require a registrar. Run ${theme_1.theme.bold('mxroute dns setup')} first.\n`));
|
|
177
|
+
// Filter to non-DNS fixes only
|
|
178
|
+
const nonDnsActions = actions.filter((a) => !a.issue.includes('MX') && !a.issue.includes('SPF') && !a.issue.includes('DKIM') && !a.issue.includes('DMARC'));
|
|
179
|
+
if (nonDnsActions.length === 0)
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const { proceed } = await inquirer_1.default.prompt([
|
|
183
|
+
{
|
|
184
|
+
type: 'confirm',
|
|
185
|
+
name: 'proceed',
|
|
186
|
+
message: `Apply all ${actions.length} fixes?`,
|
|
187
|
+
default: true,
|
|
188
|
+
},
|
|
189
|
+
]);
|
|
190
|
+
if (!proceed) {
|
|
191
|
+
console.log(theme_1.theme.muted('\n Cancelled.\n'));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Execute fixes
|
|
195
|
+
console.log(theme_1.theme.heading('Applying fixes'));
|
|
196
|
+
let fixed = 0;
|
|
197
|
+
let failed = 0;
|
|
198
|
+
for (const action of actions) {
|
|
199
|
+
const spinner = (0, ora_1.default)({ text: `${action.domain}: ${action.fix}...`, spinner: 'dots12', color: 'cyan' }).start();
|
|
200
|
+
try {
|
|
201
|
+
const result = await action.execute();
|
|
202
|
+
if (result.success) {
|
|
203
|
+
spinner.succeed(`${action.domain}: ${action.fix}`);
|
|
204
|
+
fixed++;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
spinner.fail(`${action.domain}: ${result.message}`);
|
|
208
|
+
failed++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
spinner.fail(`${action.domain}: ${err.message}`);
|
|
213
|
+
failed++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
console.log('');
|
|
217
|
+
console.log(theme_1.theme.separator());
|
|
218
|
+
if (failed === 0) {
|
|
219
|
+
console.log(theme_1.theme.success(`\n ${theme_1.theme.statusIcon('pass')} All ${fixed} fixes applied successfully!\n`));
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
console.log(theme_1.theme.warning(`\n ${fixed} fixed, ${failed} failed\n`));
|
|
223
|
+
}
|
|
224
|
+
console.log(theme_1.theme.info(` ${theme_1.theme.statusIcon('info')} Run ${theme_1.theme.bold('mxroute audit')} to verify, or ${theme_1.theme.bold('mxroute dns watch')} to monitor propagation.\n`));
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
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.headerAnalyzeCommand = headerAnalyzeCommand;
|
|
7
|
+
exports.analyzeHeaders = analyzeHeaders;
|
|
8
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
+
const theme_1 = require("../utils/theme");
|
|
10
|
+
async function headerAnalyzeCommand() {
|
|
11
|
+
console.log(theme_1.theme.heading('Email Header Analyzer'));
|
|
12
|
+
console.log(theme_1.theme.muted(' Paste raw email headers below.\n'));
|
|
13
|
+
const { headers } = await inquirer_1.default.prompt([
|
|
14
|
+
{
|
|
15
|
+
type: 'editor',
|
|
16
|
+
name: 'headers',
|
|
17
|
+
message: 'Paste email headers (opens editor):',
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
if (!headers || !headers.trim()) {
|
|
21
|
+
console.log(theme_1.theme.muted('\n No headers provided.\n'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
analyzeHeaders(headers);
|
|
25
|
+
}
|
|
26
|
+
function analyzeHeaders(raw) {
|
|
27
|
+
const lines = unfoldHeaders(raw);
|
|
28
|
+
// Parse routing (Received headers)
|
|
29
|
+
const hops = parseReceivedHeaders(lines);
|
|
30
|
+
if (hops.length > 0) {
|
|
31
|
+
console.log(theme_1.theme.heading('Message Route'));
|
|
32
|
+
for (let i = 0; i < hops.length; i++) {
|
|
33
|
+
const hop = hops[i];
|
|
34
|
+
const num = `${i + 1}.`.padEnd(4);
|
|
35
|
+
console.log(` ${theme_1.theme.secondary(num)} ${theme_1.theme.bold(hop.by)}`);
|
|
36
|
+
if (hop.from)
|
|
37
|
+
console.log(theme_1.theme.muted(` from: ${hop.from}`));
|
|
38
|
+
if (hop.protocol)
|
|
39
|
+
console.log(theme_1.theme.muted(` via: ${hop.protocol}`));
|
|
40
|
+
if (hop.timestamp)
|
|
41
|
+
console.log(theme_1.theme.muted(` at: ${hop.timestamp}`));
|
|
42
|
+
if (hop.delay && hop.delay !== '0s')
|
|
43
|
+
console.log(theme_1.theme.warning(` delay: ${hop.delay}`));
|
|
44
|
+
}
|
|
45
|
+
console.log('');
|
|
46
|
+
}
|
|
47
|
+
// Parse authentication results
|
|
48
|
+
const authResults = parseAuthResults(lines);
|
|
49
|
+
if (authResults.length > 0) {
|
|
50
|
+
console.log(theme_1.theme.heading('Authentication Results'));
|
|
51
|
+
for (const auth of authResults) {
|
|
52
|
+
const icon = auth.result === 'pass'
|
|
53
|
+
? theme_1.theme.statusIcon('pass')
|
|
54
|
+
: auth.result === 'fail'
|
|
55
|
+
? theme_1.theme.statusIcon('fail')
|
|
56
|
+
: theme_1.theme.statusIcon('warn');
|
|
57
|
+
const color = auth.result === 'pass' ? theme_1.theme.success : auth.result === 'fail' ? theme_1.theme.error : theme_1.theme.warning;
|
|
58
|
+
console.log(` ${icon} ${theme_1.theme.bold(auth.method.toUpperCase().padEnd(10))} ${color(auth.result)} ${theme_1.theme.muted(auth.details)}`);
|
|
59
|
+
}
|
|
60
|
+
console.log('');
|
|
61
|
+
}
|
|
62
|
+
// Parse key headers
|
|
63
|
+
console.log(theme_1.theme.heading('Message Details'));
|
|
64
|
+
const keyHeaders = ['from', 'to', 'subject', 'date', 'message-id', 'return-path', 'reply-to'];
|
|
65
|
+
for (const key of keyHeaders) {
|
|
66
|
+
const value = findHeader(lines, key);
|
|
67
|
+
if (value) {
|
|
68
|
+
console.log(theme_1.theme.keyValue(key.charAt(0).toUpperCase() + key.slice(1), value));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Spam headers
|
|
72
|
+
const spamScore = findHeader(lines, 'x-spam-score') || findHeader(lines, 'x-spam-status');
|
|
73
|
+
if (spamScore) {
|
|
74
|
+
console.log('');
|
|
75
|
+
console.log(theme_1.theme.heading('Spam Analysis'));
|
|
76
|
+
console.log(theme_1.theme.keyValue('Spam Score', spamScore));
|
|
77
|
+
const spamFlag = findHeader(lines, 'x-spam-flag');
|
|
78
|
+
if (spamFlag)
|
|
79
|
+
console.log(theme_1.theme.keyValue('Spam Flag', spamFlag));
|
|
80
|
+
}
|
|
81
|
+
// Total transit time
|
|
82
|
+
if (hops.length >= 2) {
|
|
83
|
+
console.log('');
|
|
84
|
+
const firstTime = parseDate(hops[0].timestamp);
|
|
85
|
+
const lastTime = parseDate(hops[hops.length - 1].timestamp);
|
|
86
|
+
if (firstTime && lastTime) {
|
|
87
|
+
const totalMs = Math.abs(lastTime.getTime() - firstTime.getTime());
|
|
88
|
+
const totalSec = Math.round(totalMs / 1000);
|
|
89
|
+
console.log(theme_1.theme.keyValue('Total Transit', `${totalSec}s (${hops.length} hops)`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
console.log('');
|
|
93
|
+
}
|
|
94
|
+
function unfoldHeaders(raw) {
|
|
95
|
+
// Unfold continuation lines (lines starting with whitespace)
|
|
96
|
+
const unfolded = raw.replace(/\r\n/g, '\n').replace(/\n[ \t]+/g, ' ');
|
|
97
|
+
return unfolded.split('\n').filter((l) => l.trim());
|
|
98
|
+
}
|
|
99
|
+
function findHeader(lines, name) {
|
|
100
|
+
const prefix = name.toLowerCase() + ':';
|
|
101
|
+
for (const line of lines) {
|
|
102
|
+
if (line.toLowerCase().startsWith(prefix)) {
|
|
103
|
+
return line.slice(prefix.length).trim();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
function parseReceivedHeaders(lines) {
|
|
109
|
+
const hops = [];
|
|
110
|
+
const receivedLines = lines.filter((l) => l.toLowerCase().startsWith('received:'));
|
|
111
|
+
for (const line of receivedLines) {
|
|
112
|
+
const content = line.slice('received:'.length).trim();
|
|
113
|
+
const fromMatch = content.match(/from\s+(\S+)/i);
|
|
114
|
+
const byMatch = content.match(/by\s+(\S+)/i);
|
|
115
|
+
const withMatch = content.match(/with\s+(\S+)/i);
|
|
116
|
+
const dateMatch = content.match(/;\s*(.+)$/);
|
|
117
|
+
hops.push({
|
|
118
|
+
from: fromMatch ? fromMatch[1] : '',
|
|
119
|
+
by: byMatch ? byMatch[1] : 'unknown',
|
|
120
|
+
protocol: withMatch ? withMatch[1] : '',
|
|
121
|
+
timestamp: dateMatch ? dateMatch[1].trim() : '',
|
|
122
|
+
delay: '',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// Calculate delays between hops
|
|
126
|
+
for (let i = 1; i < hops.length; i++) {
|
|
127
|
+
const prev = parseDate(hops[i - 1].timestamp);
|
|
128
|
+
const curr = parseDate(hops[i].timestamp);
|
|
129
|
+
if (prev && curr) {
|
|
130
|
+
const diffMs = Math.abs(curr.getTime() - prev.getTime());
|
|
131
|
+
const diffSec = Math.round(diffMs / 1000);
|
|
132
|
+
if (diffSec < 60)
|
|
133
|
+
hops[i].delay = `${diffSec}s`;
|
|
134
|
+
else if (diffSec < 3600)
|
|
135
|
+
hops[i].delay = `${Math.round(diffSec / 60)}m`;
|
|
136
|
+
else
|
|
137
|
+
hops[i].delay = `${Math.round(diffSec / 3600)}h`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Reverse so first hop is first
|
|
141
|
+
return hops.reverse();
|
|
142
|
+
}
|
|
143
|
+
function parseAuthResults(lines) {
|
|
144
|
+
const results = [];
|
|
145
|
+
for (const line of lines) {
|
|
146
|
+
if (!line.toLowerCase().startsWith('authentication-results:'))
|
|
147
|
+
continue;
|
|
148
|
+
const content = line.slice('authentication-results:'.length).trim();
|
|
149
|
+
// Parse individual results
|
|
150
|
+
const parts = content.split(';').slice(1); // skip the server identifier
|
|
151
|
+
for (const part of parts) {
|
|
152
|
+
const trimmed = part.trim();
|
|
153
|
+
const match = trimmed.match(/^(\w+)=(\w+)\s*(.*)/);
|
|
154
|
+
if (match) {
|
|
155
|
+
results.push({ method: match[1], result: match[2], details: match[3] || '' });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Also check for individual auth headers
|
|
160
|
+
const dkimResult = findHeader(lines, 'dkim-signature');
|
|
161
|
+
if (dkimResult && !results.find((r) => r.method === 'dkim')) {
|
|
162
|
+
results.push({ method: 'dkim', result: 'present', details: 'DKIM-Signature header found' });
|
|
163
|
+
}
|
|
164
|
+
return results;
|
|
165
|
+
}
|
|
166
|
+
function parseDate(str) {
|
|
167
|
+
if (!str)
|
|
168
|
+
return null;
|
|
169
|
+
try {
|
|
170
|
+
const d = new Date(str);
|
|
171
|
+
return isNaN(d.getTime()) ? null : d;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=header-analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header-analyze.js","sourceRoot":"","sources":["../../src/commands/header-analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateCommand(): Promise<void>;
|
|
@@ -0,0 +1,161 @@
|
|
|
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.migrateCommand = migrateCommand;
|
|
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
|
+
async function migrateCommand() {
|
|
14
|
+
console.log(theme_1.theme.heading('Email Migration Wizard'));
|
|
15
|
+
console.log(theme_1.theme.muted(' Migrate email from another provider to MXroute.\n'));
|
|
16
|
+
const config = (0, config_1.getConfig)();
|
|
17
|
+
const creds = (0, shared_1.getCreds)();
|
|
18
|
+
// Step 1: Source server
|
|
19
|
+
const source = await inquirer_1.default.prompt([
|
|
20
|
+
{
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'host',
|
|
23
|
+
message: theme_1.theme.secondary('Source IMAP server:'),
|
|
24
|
+
validate: (input) => (input.trim() ? true : 'Required'),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'number',
|
|
28
|
+
name: 'port',
|
|
29
|
+
message: theme_1.theme.secondary('Source IMAP port:'),
|
|
30
|
+
default: 993,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'confirm',
|
|
34
|
+
name: 'ssl',
|
|
35
|
+
message: 'Use SSL?',
|
|
36
|
+
default: true,
|
|
37
|
+
},
|
|
38
|
+
]);
|
|
39
|
+
// Step 2: Accounts to migrate
|
|
40
|
+
const { mode } = await inquirer_1.default.prompt([
|
|
41
|
+
{
|
|
42
|
+
type: 'list',
|
|
43
|
+
name: 'mode',
|
|
44
|
+
message: 'Migration mode:',
|
|
45
|
+
choices: [
|
|
46
|
+
{ name: 'Single account', value: 'single' },
|
|
47
|
+
{ name: 'Multiple accounts (one at a time)', value: 'multiple' },
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
const accounts = [];
|
|
52
|
+
if (mode === 'single') {
|
|
53
|
+
const acc = await inquirer_1.default.prompt([
|
|
54
|
+
{
|
|
55
|
+
type: 'input',
|
|
56
|
+
name: 'sourceUser',
|
|
57
|
+
message: theme_1.theme.secondary('Source email address:'),
|
|
58
|
+
validate: (i) => (i.includes('@') ? true : 'Enter full email'),
|
|
59
|
+
},
|
|
60
|
+
{ type: 'password', name: 'sourcePass', message: theme_1.theme.secondary('Source password:'), mask: '•' },
|
|
61
|
+
{
|
|
62
|
+
type: 'input',
|
|
63
|
+
name: 'destEmail',
|
|
64
|
+
message: theme_1.theme.secondary('Destination email on MXroute:'),
|
|
65
|
+
validate: (i) => (i.includes('@') ? true : 'Enter full email'),
|
|
66
|
+
},
|
|
67
|
+
]);
|
|
68
|
+
const [destUser, destDomain] = acc.destEmail.split('@');
|
|
69
|
+
accounts.push({ sourceUser: acc.sourceUser, sourcePass: acc.sourcePass, destUser, destDomain });
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
let addMore = true;
|
|
73
|
+
while (addMore) {
|
|
74
|
+
const acc = await inquirer_1.default.prompt([
|
|
75
|
+
{
|
|
76
|
+
type: 'input',
|
|
77
|
+
name: 'sourceUser',
|
|
78
|
+
message: theme_1.theme.secondary('Source email:'),
|
|
79
|
+
validate: (i) => (i.includes('@') ? true : 'Enter full email'),
|
|
80
|
+
},
|
|
81
|
+
{ type: 'password', name: 'sourcePass', message: theme_1.theme.secondary('Source password:'), mask: '•' },
|
|
82
|
+
{
|
|
83
|
+
type: 'input',
|
|
84
|
+
name: 'destEmail',
|
|
85
|
+
message: theme_1.theme.secondary('Destination email on MXroute:'),
|
|
86
|
+
validate: (i) => (i.includes('@') ? true : 'Enter full email'),
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
const [destUser, destDomain] = acc.destEmail.split('@');
|
|
90
|
+
accounts.push({ sourceUser: acc.sourceUser, sourcePass: acc.sourcePass, destUser, destDomain });
|
|
91
|
+
const { more } = await inquirer_1.default.prompt([
|
|
92
|
+
{ type: 'confirm', name: 'more', message: 'Add another account?', default: false },
|
|
93
|
+
]);
|
|
94
|
+
addMore = more;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Step 3: Show plan
|
|
98
|
+
console.log(theme_1.theme.heading('Migration Plan'));
|
|
99
|
+
console.log(theme_1.theme.keyValue('Source Server', `${source.host}:${source.port} (${source.ssl ? 'SSL' : 'plain'})`));
|
|
100
|
+
console.log(theme_1.theme.keyValue('Destination', `${config.server}.mxrouting.net:993 (SSL)`));
|
|
101
|
+
console.log(theme_1.theme.keyValue('Accounts', `${accounts.length}`));
|
|
102
|
+
console.log('');
|
|
103
|
+
for (const acc of accounts) {
|
|
104
|
+
console.log(theme_1.theme.muted(` ${acc.sourceUser} → ${acc.destUser}@${acc.destDomain}`));
|
|
105
|
+
}
|
|
106
|
+
console.log('');
|
|
107
|
+
// Step 4: Pre-flight checks
|
|
108
|
+
console.log(theme_1.theme.subheading('Pre-flight checks'));
|
|
109
|
+
for (const acc of accounts) {
|
|
110
|
+
const spinner = (0, ora_1.default)({
|
|
111
|
+
text: `Checking ${acc.destUser}@${acc.destDomain}...`,
|
|
112
|
+
spinner: 'dots12',
|
|
113
|
+
color: 'cyan',
|
|
114
|
+
}).start();
|
|
115
|
+
try {
|
|
116
|
+
const existing = await (0, directadmin_1.listEmailAccounts)(creds, acc.destDomain);
|
|
117
|
+
if (existing.includes(acc.destUser)) {
|
|
118
|
+
spinner.succeed(`${acc.destUser}@${acc.destDomain} exists on MXroute`);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
spinner.warn(`${acc.destUser}@${acc.destDomain} does not exist — will need to create it`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
spinner.warn(`Could not verify ${acc.destDomain}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Step 5: Generate imapsync commands
|
|
129
|
+
console.log(theme_1.theme.heading('Migration Commands'));
|
|
130
|
+
console.log(theme_1.theme.muted(' Run these commands to migrate emails:\n'));
|
|
131
|
+
for (const acc of accounts) {
|
|
132
|
+
const destHost = `${config.server}.mxrouting.net`;
|
|
133
|
+
const sslFlag = source.ssl ? '--ssl1' : '';
|
|
134
|
+
console.log(theme_1.theme.secondary(` # ${acc.sourceUser} → ${acc.destUser}@${acc.destDomain}`));
|
|
135
|
+
console.log(theme_1.theme.muted(` imapsync \\`));
|
|
136
|
+
console.log(theme_1.theme.muted(` --host1 ${source.host} --port1 ${source.port} ${sslFlag} \\`));
|
|
137
|
+
console.log(theme_1.theme.muted(` --user1 "${acc.sourceUser}" --password1 "${acc.sourcePass}" \\`));
|
|
138
|
+
console.log(theme_1.theme.muted(` --host2 ${destHost} --port2 993 --ssl2 \\`));
|
|
139
|
+
console.log(theme_1.theme.muted(` --user2 "${acc.destUser}@${acc.destDomain}" --password2 "DEST_PASSWORD"`));
|
|
140
|
+
console.log('');
|
|
141
|
+
}
|
|
142
|
+
// Step 6: Post-migration checklist
|
|
143
|
+
console.log(theme_1.theme.heading('Post-Migration Checklist'));
|
|
144
|
+
console.log(theme_1.theme.muted(' 1. Run the imapsync commands above'));
|
|
145
|
+
console.log(theme_1.theme.muted(' 2. Verify emails transferred on MXroute webmail'));
|
|
146
|
+
console.log(theme_1.theme.muted(' 3. Update DNS MX records to MXroute'));
|
|
147
|
+
console.log(theme_1.theme.muted(` Run: mxroute dns setup ${accounts[0]?.destDomain || 'yourdomain.com'}`));
|
|
148
|
+
console.log(theme_1.theme.muted(' 4. Configure SPF, DKIM, DMARC'));
|
|
149
|
+
console.log(theme_1.theme.muted(' 5. Reconfigure all email clients'));
|
|
150
|
+
console.log(theme_1.theme.muted(` Run: mxroute share ${accounts[0]?.destUser || 'user'}@${accounts[0]?.destDomain || 'domain.com'}`));
|
|
151
|
+
console.log(theme_1.theme.muted(' 6. Keep old service running during transition'));
|
|
152
|
+
console.log(theme_1.theme.muted(' 7. Monitor with: mxroute dns watch'));
|
|
153
|
+
console.log('');
|
|
154
|
+
// Offer to install imapsync
|
|
155
|
+
console.log(theme_1.theme.info(` ${theme_1.theme.statusIcon('info')} Install imapsync: https://imapsync.lamiral.info/`));
|
|
156
|
+
console.log(theme_1.theme.muted(' macOS: brew install imapsync'));
|
|
157
|
+
console.log(theme_1.theme.muted(' Ubuntu: sudo apt install imapsync'));
|
|
158
|
+
console.log(theme_1.theme.muted(' Or use the web version: https://i005.lamiral.info/'));
|
|
159
|
+
console.log('');
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":";;;;;AAOA,wCA0KC;AAjLD,8CAAsB;AACtB,wDAAgC;AAChC,0CAAuC;AACvC,4CAA4C;AAC5C,4CAA2C;AAC3C,sDAA6E;AAEtE,KAAK,UAAU,cAAc;IAClC,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAEhF,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAA,iBAAQ,GAAE,CAAC;IAEzB,wBAAwB;IACxB,MAAM,MAAM,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;QACnC;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,qBAAqB,CAAC;YAC/C,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;SAChE;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC;YAC7C,OAAO,EAAE,GAAG;SACb;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,UAAU;YACnB,OAAO,EAAE,IAAI;SACd;KACF,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;QACrC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAC3C,EAAE,IAAI,EAAE,mCAAmC,EAAE,KAAK,EAAE,UAAU,EAAE;aACjE;SACF;KACF,CAAC,CAAC;IASH,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;YAChC;gBACE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,uBAAuB,CAAC;gBACjD,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;aACvE;YACD,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE;YACjG;gBACE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,+BAA+B,CAAC;gBACzD,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;aACvE;SACF,CAAC,CAAC;QACH,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IAClG,CAAC;SAAM,CAAC;QACN,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,OAAO,OAAO,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;gBAChC;oBACE,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,YAAY;oBAClB,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,eAAe,CAAC;oBACzC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;iBACvE;gBACD,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE;gBACjG;oBACE,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,aAAK,CAAC,SAAS,CAAC,+BAA+B,CAAC;oBACzD,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;iBACvE;aACF,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;YAEhG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;gBACrC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,KAAK,EAAE;aACnF,CAAC,CAAC;YACH,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,QAAQ,CAAC,eAAe,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAChH,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,GAAG,MAAM,CAAC,MAAM,0BAA0B,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,UAAU,MAAM,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,4BAA4B;IAC5B,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAEnD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC;YAClB,IAAI,EAAE,YAAY,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK;YACrD,OAAO,EAAE,QAAQ;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAiB,EAAC,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;YAChE,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpC,OAAO,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,oBAAoB,CAAC,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,0CAA0C,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IAEtE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,MAAM,gBAAgB,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAE3C,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,UAAU,MAAM,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,IAAI,YAAY,MAAM,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,UAAU,kBAAkB,GAAG,CAAC,UAAU,MAAM,CAAC,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,eAAe,QAAQ,wBAAwB,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,+BAA+B,CAAC,CAAC,CAAC;QACxG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,mCAAmC;IACnC,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,iCAAiC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACzG,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CACT,aAAK,CAAC,KAAK,CACT,6BAA6B,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,YAAY,EAAE,CAC1G,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,4BAA4B;IAC5B,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,IAAI,CAAC,KAAK,aAAK,CAAC,UAAU,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC1G,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,aAAK,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface NotifyChannel {
|
|
2
|
+
type: 'slack' | 'discord' | 'telegram' | 'email';
|
|
3
|
+
webhook?: string;
|
|
4
|
+
chatId?: string;
|
|
5
|
+
botToken?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function notifySetup(): Promise<void>;
|
|
8
|
+
export declare function notifyTest(): Promise<void>;
|
|
9
|
+
export declare function sendNotification(channel: NotifyChannel, title: string, message: string): Promise<boolean>;
|
|
10
|
+
export {};
|