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.
@@ -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,2 @@
1
+ export declare function headerAnalyzeCommand(): Promise<void>;
2
+ export declare function analyzeHeaders(raw: string): void;
@@ -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":"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"}
@@ -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 {};