agent-mailbox-cli 0.1.0 → 0.1.2

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/cli/index.js CHANGED
@@ -1,16 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { createInterface } from 'readline';
5
+ import { loadConfig, saveConfig, clearSession } from './config.js';
3
6
  const program = new Command();
4
- const API_URL = process.env.AGENT_EMAIL_API_URL || 'https://agent-email-api-production.up.railway.app';
5
- const API_KEY = process.env.AGENT_EMAIL_API_KEY || '';
6
- async function api(method, path, body) {
7
+ function getApiUrl() {
8
+ return (process.env.AGENT_EMAIL_API_URL ||
9
+ loadConfig().api_url ||
10
+ 'https://agent-email-api-production.up.railway.app');
11
+ }
12
+ function getAuthHeader() {
13
+ const apiKey = process.env.AGENT_EMAIL_API_KEY;
14
+ if (apiKey)
15
+ return `Bearer ${apiKey}`;
16
+ const cfg = loadConfig();
17
+ if (cfg.session_token)
18
+ return `Bearer ${cfg.session_token}`;
19
+ return '';
20
+ }
21
+ async function api(method, path, body, authOverride) {
7
22
  const headers = {
8
23
  'Content-Type': 'application/json',
9
24
  };
10
- if (API_KEY) {
11
- headers['Authorization'] = `Bearer ${API_KEY}`;
12
- }
13
- const res = await fetch(`${API_URL}${path}`, {
25
+ const auth = authOverride || getAuthHeader();
26
+ if (auth)
27
+ headers['Authorization'] = auth;
28
+ const res = await fetch(`${getApiUrl()}${path}`, {
14
29
  method,
15
30
  headers,
16
31
  body: body ? JSON.stringify(body) : undefined,
@@ -19,29 +34,139 @@ async function api(method, path, body) {
19
34
  return null;
20
35
  const data = await res.json();
21
36
  if (!res.ok) {
22
- console.error(`Error ${res.status}:`, data.error || data);
37
+ console.error(chalk.red(`Error ${res.status}:`), data.error || data);
23
38
  process.exit(1);
24
39
  }
25
40
  return data;
26
41
  }
42
+ function prompt(question) {
43
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
44
+ return new Promise((resolve) => {
45
+ rl.question(question, (answer) => {
46
+ rl.close();
47
+ resolve(answer.trim());
48
+ });
49
+ });
50
+ }
27
51
  program
28
52
  .name('agentmailbox')
29
- .description('CLI for AgentEmail service')
30
- .version('0.1.0');
53
+ .description('Email addresses for AI agents')
54
+ .version('0.2.0');
55
+ // Auth commands
56
+ program
57
+ .command('signup')
58
+ .argument('<email>', 'Your email address')
59
+ .description('Create an admin account')
60
+ .action(async (email) => {
61
+ await api('POST', '/v1/auth/signup', { email }, '');
62
+ console.log(chalk.green('Verification code sent to'), chalk.bold(email));
63
+ const code = await prompt(chalk.cyan('Enter the 6-digit code: '));
64
+ const verify = await api('POST', '/v1/auth/verify', { token: code }, '');
65
+ const cfg = loadConfig();
66
+ cfg.session_token = verify.session_token;
67
+ cfg.email = verify.admin.email;
68
+ saveConfig(cfg);
69
+ console.log(chalk.green('Logged in as'), chalk.bold(verify.admin.email));
70
+ });
71
+ program
72
+ .command('login')
73
+ .argument('<email>', 'Your email address')
74
+ .description('Log in with magic link')
75
+ .action(async (email) => {
76
+ await api('POST', '/v1/auth/login', { email }, '');
77
+ console.log(chalk.green('Verification code sent to'), chalk.bold(email));
78
+ const code = await prompt(chalk.cyan('Enter the 6-digit code: '));
79
+ const verify = await api('POST', '/v1/auth/verify', { token: code }, '');
80
+ const cfg = loadConfig();
81
+ cfg.session_token = verify.session_token;
82
+ cfg.email = verify.admin.email;
83
+ saveConfig(cfg);
84
+ console.log(chalk.green('Logged in as'), chalk.bold(verify.admin.email));
85
+ });
86
+ program
87
+ .command('logout')
88
+ .description('Log out')
89
+ .action(async () => {
90
+ const cfg = loadConfig();
91
+ if (cfg.session_token) {
92
+ try {
93
+ await api('POST', '/v1/auth/logout', undefined, `Bearer ${cfg.session_token}`);
94
+ }
95
+ catch { }
96
+ }
97
+ clearSession();
98
+ console.log(chalk.gray('Logged out.'));
99
+ });
100
+ program
101
+ .command('whoami')
102
+ .description('Show current user')
103
+ .action(async () => {
104
+ const cfg = loadConfig();
105
+ if (!cfg.session_token) {
106
+ console.log(chalk.yellow('Not logged in.'), 'Run:', chalk.cyan('agentmailbox login <email>'));
107
+ return;
108
+ }
109
+ try {
110
+ const data = await api('GET', '/v1/auth/me', undefined, `Bearer ${cfg.session_token}`);
111
+ console.log(chalk.green('Logged in as'), chalk.bold(data.admin.email));
112
+ }
113
+ catch {
114
+ console.log(chalk.yellow('Session expired.'), 'Run:', chalk.cyan('agentmailbox login <email>'));
115
+ }
116
+ });
31
117
  // Org commands
32
118
  const org = program.command('org');
33
119
  org
34
120
  .command('create')
35
121
  .argument('<name>', 'Organization name')
122
+ .description('Create an org and get an API key')
36
123
  .action(async (name) => {
37
- const data = await api('POST', '/v1/orgs', { name });
38
- console.log('Organization created:');
39
- console.log(` ID: ${data.org.id}`);
40
- console.log(` Name: ${data.org.name}`);
41
- console.log(` API Key: ${data.api_key}`);
124
+ const cfg = loadConfig();
125
+ if (!cfg.session_token) {
126
+ console.error(chalk.red('Not logged in.'), 'Run:', chalk.cyan('agentmailbox login <email>'));
127
+ process.exit(1);
128
+ }
129
+ const data = await api('POST', '/v1/orgs', { name }, `Bearer ${cfg.session_token}`);
130
+ console.log(chalk.green('Organization created'));
131
+ console.log(` ${chalk.gray('ID:')} ${data.org.id}`);
132
+ console.log(` ${chalk.gray('Name:')} ${data.org.name}`);
133
+ console.log(` ${chalk.gray('API Key:')} ${chalk.yellow(data.api_key)}`);
42
134
  console.log('');
43
- console.log('Save this API key — it cannot be retrieved again.');
44
- console.log(`Export it: export AGENT_EMAIL_API_KEY=${data.api_key}`);
135
+ console.log(chalk.dim('Save this API key — it cannot be retrieved again.'));
136
+ console.log(chalk.dim(`export AGENT_EMAIL_API_KEY=${data.api_key}`));
137
+ });
138
+ org
139
+ .command('list')
140
+ .description('List your orgs')
141
+ .action(async () => {
142
+ const cfg = loadConfig();
143
+ if (!cfg.session_token) {
144
+ console.error(chalk.red('Not logged in.'), 'Run:', chalk.cyan('agentmailbox login <email>'));
145
+ process.exit(1);
146
+ }
147
+ const data = await api('GET', '/v1/orgs', undefined, `Bearer ${cfg.session_token}`);
148
+ if (data.orgs.length === 0) {
149
+ console.log(chalk.gray('No orgs.'), 'Create one:', chalk.cyan('agentmailbox org create <name>'));
150
+ return;
151
+ }
152
+ for (const o of data.orgs) {
153
+ console.log(` ${chalk.bold(o.name)} ${chalk.gray(o.id)} ${chalk.dim(o.created_at)}`);
154
+ }
155
+ });
156
+ org
157
+ .command('rotate-key')
158
+ .argument('<org-id>', 'Org ID')
159
+ .description('Rotate API key for an org')
160
+ .action(async (orgId) => {
161
+ const cfg = loadConfig();
162
+ if (!cfg.session_token) {
163
+ console.error(chalk.red('Not logged in.'), 'Run:', chalk.cyan('agentmailbox login <email>'));
164
+ process.exit(1);
165
+ }
166
+ const data = await api('POST', `/v1/orgs/${orgId}/rotate-key`, undefined, `Bearer ${cfg.session_token}`);
167
+ console.log(chalk.green('Key rotated for'), chalk.bold(data.org.name));
168
+ console.log(` ${chalk.gray('API Key:')} ${chalk.yellow(data.api_key)}`);
169
+ console.log(chalk.dim('Save this API key — the old one is now invalid.'));
45
170
  });
46
171
  // Account commands
47
172
  const account = program.command('account');
@@ -54,18 +179,18 @@ account
54
179
  local_part: localPart,
55
180
  display_name: opts.displayName,
56
181
  });
57
- console.log(`Account created: ${data.account.address}`);
182
+ console.log(chalk.green('Created'), chalk.bold(data.account.address));
58
183
  });
59
184
  account
60
185
  .command('list')
61
186
  .action(async () => {
62
187
  const data = await api('GET', '/v1/accounts');
63
188
  if (data.accounts.length === 0) {
64
- console.log('No accounts.');
189
+ console.log(chalk.gray('No accounts.'));
65
190
  return;
66
191
  }
67
192
  for (const a of data.accounts) {
68
- console.log(` ${a.address} (${a.display_name || 'no name'}) created ${a.created_at}`);
193
+ console.log(` ${chalk.bold(a.address)} ${chalk.gray(a.display_name || '')} ${chalk.dim(a.created_at)}`);
69
194
  }
70
195
  });
71
196
  account
@@ -73,7 +198,7 @@ account
73
198
  .argument('<address>', 'Full email address')
74
199
  .action(async (address) => {
75
200
  await api('DELETE', `/v1/accounts/${encodeURIComponent(address)}`);
76
- console.log(`Deleted ${address}`);
201
+ console.log(chalk.red('Deleted'), address);
77
202
  });
78
203
  // Message commands
79
204
  const msg = program.command('messages').alias('msg');
@@ -84,13 +209,14 @@ msg
84
209
  .action(async (address, opts) => {
85
210
  const data = await api('GET', `/v1/accounts/${encodeURIComponent(address)}/messages?limit=${opts.limit}`);
86
211
  if (data.messages.length === 0) {
87
- console.log('No messages.');
212
+ console.log(chalk.gray('No messages.'));
88
213
  return;
89
214
  }
90
215
  for (const m of data.messages) {
91
- const read = m.read_at ? ' ' : '*';
92
- const dir = m.direction === 'outbound' ? '>>>' : '<<<';
93
- console.log(`${read} ${m.id.slice(0, 8)} ${dir} ${m.from} → ${m.to} "${m.subject}" ${m.received_at}`);
216
+ const unread = m.read_at ? ' ' : chalk.cyan('*');
217
+ const dir = m.direction === 'outbound' ? chalk.blue('>>>') : chalk.green('<<<');
218
+ const subject = chalk.bold(`"${m.subject}"`);
219
+ console.log(`${unread} ${chalk.gray(m.id.slice(0, 8))} ${dir} ${m.from} ${chalk.gray('→')} ${m.to} ${subject} ${chalk.dim(m.received_at)}`);
94
220
  }
95
221
  });
96
222
  msg
@@ -100,12 +226,12 @@ msg
100
226
  .action(async (address, id) => {
101
227
  const data = await api('GET', `/v1/accounts/${encodeURIComponent(address)}/messages/${id}`);
102
228
  const m = data.message;
103
- console.log(`From: ${m.from}`);
104
- console.log(`To: ${m.to}`);
105
- console.log(`Subject: ${m.subject}`);
106
- console.log(`Date: ${m.received_at}`);
107
- console.log('---');
108
- console.log(m.text || m.html || '(empty body)');
229
+ console.log(`${chalk.gray('From:')} ${m.from}`);
230
+ console.log(`${chalk.gray('To:')} ${m.to}`);
231
+ console.log(`${chalk.gray('Subject:')} ${chalk.bold(m.subject)}`);
232
+ console.log(`${chalk.gray('Date:')} ${m.received_at}`);
233
+ console.log(chalk.gray('---'));
234
+ console.log(m.text || m.html || chalk.dim('(empty body)'));
109
235
  });
110
236
  msg
111
237
  .command('wait')
@@ -113,19 +239,19 @@ msg
113
239
  .option('-t, --timeout <seconds>', 'Timeout in seconds', '60')
114
240
  .option('-s, --since <timestamp>', 'Only messages after this timestamp')
115
241
  .action(async (address, opts) => {
116
- console.log(`Waiting for email to ${address}...`);
242
+ console.log(chalk.cyan('Waiting for email to'), chalk.bold(address), chalk.cyan('...'));
117
243
  const params = new URLSearchParams({ timeout: opts.timeout });
118
244
  if (opts.since)
119
245
  params.set('since', opts.since);
120
246
  const data = await api('GET', `/v1/accounts/${encodeURIComponent(address)}/messages/wait?${params}`);
121
247
  if (!data) {
122
- console.log('Timeout — no new messages.');
248
+ console.log(chalk.yellow('Timeout — no new messages.'));
123
249
  return;
124
250
  }
125
251
  const m = data.message;
126
- console.log(`New message from ${m.from}: "${m.subject}"`);
127
- console.log('---');
128
- console.log(m.text || m.html || '(empty body)');
252
+ console.log(chalk.green('New message from'), `${m.from}: ${chalk.bold(`"${m.subject}"`)}`);
253
+ console.log(chalk.gray('---'));
254
+ console.log(m.text || m.html || chalk.dim('(empty body)'));
129
255
  });
130
256
  msg
131
257
  .command('reply')
@@ -134,7 +260,7 @@ msg
134
260
  .argument('<body>', 'Reply text')
135
261
  .action(async (address, id, body) => {
136
262
  const data = await api('POST', `/v1/accounts/${encodeURIComponent(address)}/messages/${id}/reply`, { text: body });
137
- console.log(`Reply sent. Message-ID: ${data.message_id}`);
263
+ console.log(chalk.green('Reply sent.'), chalk.gray(`Message-ID: ${data.message_id}`));
138
264
  });
139
265
  msg
140
266
  .command('send')
@@ -144,7 +270,7 @@ msg
144
270
  .argument('<body>', 'Email body')
145
271
  .action(async (from, to, subject, body) => {
146
272
  const data = await api('POST', `/v1/accounts/${encodeURIComponent(from)}/send`, { to, subject, text: body });
147
- console.log(`Sent. Message-ID: ${data.message_id}`);
273
+ console.log(chalk.green('Sent.'), chalk.gray(`Message-ID: ${data.message_id}`));
148
274
  });
149
275
  program.parse();
150
276
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -7,11 +7,23 @@ export declare const config: {
7
7
  port: number;
8
8
  host: string;
9
9
  domain: string;
10
+ relaySecret: string;
10
11
  };
11
12
  api: {
12
13
  port: number;
13
14
  host: string;
14
15
  };
16
+ auth: {
17
+ magicLinkTtlMinutes: number;
18
+ sessionTtlDays: number;
19
+ fromAddress: string;
20
+ };
21
+ outboundSmtp: {
22
+ host: string;
23
+ port: number;
24
+ user: string;
25
+ pass: string;
26
+ };
15
27
  dkim: {
16
28
  selector: string;
17
29
  privateKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;CAiBlB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BlB,CAAC"}
package/dist/config.js CHANGED
@@ -7,11 +7,23 @@ export const config = {
7
7
  port: parseInt(process.env.SMTP_PORT || '2525', 10),
8
8
  host: process.env.SMTP_HOST || '0.0.0.0',
9
9
  domain: process.env.SMTP_DOMAIN || 'agentmailbox.io',
10
+ relaySecret: process.env.SMTP_RELAY_SECRET || '',
10
11
  },
11
12
  api: {
12
13
  port: parseInt(process.env.API_PORT || '3025', 10),
13
14
  host: process.env.API_HOST || '0.0.0.0',
14
15
  },
16
+ auth: {
17
+ magicLinkTtlMinutes: parseInt(process.env.AUTH_MAGIC_LINK_TTL || '15', 10),
18
+ sessionTtlDays: parseInt(process.env.AUTH_SESSION_TTL_DAYS || '30', 10),
19
+ fromAddress: process.env.AUTH_FROM_ADDRESS || 'auth@agentmailbox.io',
20
+ },
21
+ outboundSmtp: {
22
+ host: process.env.OUTBOUND_SMTP_HOST || 'mail.agentmailbox.io',
23
+ port: parseInt(process.env.OUTBOUND_SMTP_PORT || '25', 10),
24
+ user: process.env.OUTBOUND_SMTP_USER || '',
25
+ pass: process.env.OUTBOUND_SMTP_PASS || '',
26
+ },
15
27
  dkim: {
16
28
  selector: process.env.DKIM_SELECTOR || 'default',
17
29
  privateKey: process.env.DKIM_PRIVATE_KEY || '',
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,QAAQ,EAAE;QACR,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,sCAAsC;KACxE;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC;QACnD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;QACxC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,iBAAiB;KACrD;IACD,GAAG,EAAE;QACH,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;QAClD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS;KACxC;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,SAAS;QAChD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;KAC/C;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,QAAQ,EAAE;QACR,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,sCAAsC;KACxE;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC;QACnD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;QACxC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,iBAAiB;QACpD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE;KACjD;IACD,GAAG,EAAE;QACH,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;QAClD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS;KACxC;IACD,IAAI,EAAE;QACJ,mBAAmB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,EAAE,EAAE,CAAC;QAC1E,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,IAAI,EAAE,EAAE,CAAC;QACvE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,sBAAsB;KACrE;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,sBAAsB;QAC9D,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,CAAC;QAC1D,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE;QAC1C,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE;KAC3C;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,SAAS;QAChD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;KAC/C;CACF,CAAC"}
@@ -36,3 +36,38 @@ CREATE INDEX IF NOT EXISTS idx_messages_account_received ON messages(account_id,
36
36
  CREATE INDEX IF NOT EXISTS idx_accounts_org ON accounts(org_id);
37
37
  CREATE INDEX IF NOT EXISTS idx_accounts_address ON accounts(address);
38
38
  CREATE INDEX IF NOT EXISTS idx_orgs_api_key_hash ON orgs(api_key_hash);
39
+
40
+ -- Admin auth
41
+ CREATE TABLE IF NOT EXISTS admin_users (
42
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
43
+ email TEXT NOT NULL UNIQUE,
44
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
45
+ );
46
+
47
+ CREATE TABLE IF NOT EXISTS magic_link_tokens (
48
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
49
+ admin_user_id UUID NOT NULL REFERENCES admin_users(id) ON DELETE CASCADE,
50
+ token_hash TEXT NOT NULL UNIQUE,
51
+ expires_at TIMESTAMPTZ NOT NULL,
52
+ used_at TIMESTAMPTZ,
53
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
54
+ );
55
+
56
+ CREATE TABLE IF NOT EXISTS admin_sessions (
57
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
58
+ admin_user_id UUID NOT NULL REFERENCES admin_users(id) ON DELETE CASCADE,
59
+ token_hash TEXT NOT NULL UNIQUE,
60
+ expires_at TIMESTAMPTZ NOT NULL,
61
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
62
+ );
63
+
64
+ -- Add owner to orgs (nullable for backward compat)
65
+ DO $$ BEGIN
66
+ ALTER TABLE orgs ADD COLUMN admin_user_id UUID REFERENCES admin_users(id);
67
+ EXCEPTION WHEN duplicate_column THEN NULL;
68
+ END $$;
69
+
70
+ CREATE INDEX IF NOT EXISTS idx_admin_users_email ON admin_users(email);
71
+ CREATE INDEX IF NOT EXISTS idx_magic_link_tokens_hash ON magic_link_tokens(token_hash);
72
+ CREATE INDEX IF NOT EXISTS idx_admin_sessions_hash ON admin_sessions(token_hash);
73
+ CREATE INDEX IF NOT EXISTS idx_orgs_admin ON orgs(admin_user_id);
@@ -0,0 +1,2 @@
1
+ export declare function sendMagicLinkEmail(to: string, code: string): Promise<void>;
2
+ //# sourceMappingURL=send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/email/send.ts"],"names":[],"mappings":"AAOA,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAqBhE"}
@@ -0,0 +1,24 @@
1
+ import { config } from '../config.js';
2
+ const SEND_API_URL = process.env.SEND_API_URL || 'https://agent-email-smtp.fly.dev/internal/send';
3
+ const SEND_API_SECRET = process.env.OUTBOUND_SMTP_PASS || config.outboundSmtp.pass;
4
+ export async function sendMagicLinkEmail(to, code) {
5
+ const text = `Your AgentMailbox verification code is: ${code}\n\nEnter this code in your terminal to complete login.\nIt expires in ${config.auth.magicLinkTtlMinutes} minutes.`;
6
+ const res = await fetch(SEND_API_URL, {
7
+ method: 'POST',
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ Authorization: `Bearer ${SEND_API_SECRET}`,
11
+ },
12
+ body: JSON.stringify({
13
+ from: `AgentMailbox ${config.auth.fromAddress}`,
14
+ to,
15
+ subject: `${code} is your AgentMailbox verification code`,
16
+ text,
17
+ }),
18
+ });
19
+ if (!res.ok) {
20
+ const body = await res.text();
21
+ throw new Error(`Send API error ${res.status}: ${body}`);
22
+ }
23
+ }
24
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/email/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,YAAY,GAChB,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,gDAAgD,CAAC;AAC/E,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAU,EAAE,IAAY;IAC/D,MAAM,IAAI,GAAG,2CAA2C,IAAI,0EAA0E,MAAM,CAAC,IAAI,CAAC,mBAAmB,WAAW,CAAC;IAEjL,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;QACpC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,eAAe,EAAE;SAC3C;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,IAAI,EAAE,gBAAgB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;YAC/C,EAAE;YACF,OAAO,EAAE,GAAG,IAAI,yCAAyC;YACzD,IAAI;SACL,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"receiver.d.ts","sourceRoot":"","sources":["../../src/smtp/receiver.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB;;;EA2GjC"}
1
+ {"version":3,"file":"receiver.d.ts","sourceRoot":"","sources":["../../src/smtp/receiver.ts"],"names":[],"mappings":"AAOA,wBAAgB,kBAAkB;;;EAyFjC"}
@@ -1,18 +1,34 @@
1
1
  import { SMTPServer } from 'smtp-server';
2
2
  import { simpleParser } from 'mailparser';
3
+ import dns from 'dns/promises';
4
+ import nodemailer from 'nodemailer';
3
5
  import { pool } from '../db/index.js';
4
6
  import { config } from '../config.js';
5
7
  export function createSmtpReceiver() {
6
8
  const domain = config.smtp.domain;
9
+ const relaySecret = config.smtp.relaySecret;
7
10
  const server = new SMTPServer({
8
11
  authOptional: true,
9
- disabledCommands: ['AUTH'],
10
12
  banner: `AgentEmail SMTP`,
11
13
  size: 10 * 1024 * 1024, // 10MB max
12
- onRcptTo(address, _session, callback) {
14
+ onAuth(auth, _session, callback) {
15
+ if (relaySecret &&
16
+ auth.username === 'relay' &&
17
+ auth.password === relaySecret) {
18
+ callback(null, { user: 'relay' });
19
+ }
20
+ else {
21
+ callback(new Error('Invalid credentials'));
22
+ }
23
+ },
24
+ onRcptTo(address, session, callback) {
13
25
  const addr = address.address.toLowerCase();
26
+ const isRelay = session.user === 'relay';
14
27
  if (addr.endsWith(`@${domain}`)) {
15
- callback();
28
+ callback(); // Accept mail for our domain
29
+ }
30
+ else if (isRelay) {
31
+ callback(); // Authenticated relay to external
16
32
  }
17
33
  else {
18
34
  callback(new Error(`Not accepting mail for ${addr}`));
@@ -25,39 +41,21 @@ export function createSmtpReceiver() {
25
41
  try {
26
42
  const raw = Buffer.concat(chunks).toString('utf-8');
27
43
  const parsed = await simpleParser(raw);
44
+ const isRelay = session.user === 'relay';
28
45
  const fromAddress = session.envelope.mailFrom &&
29
46
  typeof session.envelope.mailFrom === 'object'
30
47
  ? session.envelope.mailFrom.address
31
48
  : '';
32
49
  const recipients = session.envelope.rcptTo.map((r) => r.address.toLowerCase());
33
50
  for (const toAddress of recipients) {
34
- const result = await pool.query('SELECT id FROM accounts WHERE address = $1', [toAddress]);
35
- if (result.rows.length === 0) {
36
- console.log(`No account for ${toAddress}, skipping`);
37
- continue;
51
+ if (toAddress.endsWith(`@${domain}`)) {
52
+ // Inbound: store in DB
53
+ await storeInbound(parsed, fromAddress, toAddress, raw);
54
+ }
55
+ else if (isRelay) {
56
+ // Relay: deliver to external MX
57
+ await relayOutbound(fromAddress, toAddress, raw);
38
58
  }
39
- const accountId = result.rows[0].id;
40
- await pool.query(`INSERT INTO messages
41
- (account_id, message_id, from_address, to_address, subject, text_body, html_body, raw, headers, direction)
42
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, 'inbound')`, [
43
- accountId,
44
- parsed.messageId || null,
45
- fromAddress,
46
- toAddress,
47
- parsed.subject || null,
48
- parsed.text || null,
49
- parsed.html || null,
50
- raw,
51
- JSON.stringify(parsed.headerLines?.map((h) => ({
52
- key: h.key,
53
- line: h.line,
54
- })) || []),
55
- ]);
56
- // Notify listeners waiting for new messages
57
- await pool.query(`SELECT pg_notify('new_message', $1)`, [
58
- accountId,
59
- ]);
60
- console.log(`Stored message for ${toAddress} from ${fromAddress}: ${parsed.subject}`);
61
59
  }
62
60
  callback();
63
61
  }
@@ -85,4 +83,59 @@ export function createSmtpReceiver() {
85
83
  },
86
84
  };
87
85
  }
86
+ async function storeInbound(parsed, fromAddress, toAddress, raw) {
87
+ const result = await pool.query('SELECT id FROM accounts WHERE address = $1', [toAddress]);
88
+ if (result.rows.length === 0) {
89
+ console.log(`No account for ${toAddress}, skipping`);
90
+ return;
91
+ }
92
+ const accountId = result.rows[0].id;
93
+ await pool.query(`INSERT INTO messages
94
+ (account_id, message_id, from_address, to_address, subject, text_body, html_body, raw, headers, direction)
95
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, 'inbound')`, [
96
+ accountId,
97
+ parsed.messageId || null,
98
+ fromAddress,
99
+ toAddress,
100
+ parsed.subject || null,
101
+ parsed.text || null,
102
+ parsed.html || null,
103
+ raw,
104
+ JSON.stringify(parsed.headerLines?.map((h) => ({
105
+ key: h.key,
106
+ line: h.line,
107
+ })) || []),
108
+ ]);
109
+ await pool.query(`SELECT pg_notify('new_message', $1)`, [accountId]);
110
+ console.log(`Stored message for ${toAddress} from ${fromAddress}: ${parsed.subject}`);
111
+ }
112
+ async function relayOutbound(from, to, raw) {
113
+ try {
114
+ const domain = to.split('@')[1];
115
+ const mxRecords = await dns.resolveMx(domain);
116
+ mxRecords.sort((a, b) => a.priority - b.priority);
117
+ for (const mx of mxRecords) {
118
+ try {
119
+ const transport = nodemailer.createTransport({
120
+ host: mx.exchange,
121
+ port: 25,
122
+ secure: false,
123
+ tls: { rejectUnauthorized: false },
124
+ name: 'mail.agentmailbox.io',
125
+ });
126
+ await transport.sendMail({ envelope: { from, to: [to] }, raw });
127
+ console.log(`Relayed email from ${from} to ${to} via ${mx.exchange}`);
128
+ return;
129
+ }
130
+ catch (err) {
131
+ console.error(`MX ${mx.exchange} failed:`, err.message);
132
+ continue;
133
+ }
134
+ }
135
+ console.error(`All MX servers for ${to} failed`);
136
+ }
137
+ catch (err) {
138
+ console.error(`Failed to relay to ${to}:`, err);
139
+ }
140
+ }
88
141
  //# sourceMappingURL=receiver.js.map