@agenticmail/enterprise 0.5.289 → 0.5.290
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/agent-heartbeat-DPIKXNL2.js +510 -0
- package/dist/agent-tools-TZVJESQ3.js +13881 -0
- package/dist/chunk-2YOTK5B7.js +4739 -0
- package/dist/chunk-HE5H6NHI.js +1460 -0
- package/dist/chunk-PG5CNF22.js +3780 -0
- package/dist/cli-agent-QADP7UDK.js +1778 -0
- package/dist/cli-recover-RPXOAQAI.js +478 -0
- package/dist/cli-reset-password-SO5Y6MW7.js +115 -0
- package/dist/cli-serve-VIRN7UCN.js +143 -0
- package/dist/cli.js +9 -5
- package/dist/index.js +3 -3
- package/dist/meetings-RR72OBSV.js +1 -1
- package/dist/routes-3PWOKM6G.js +13695 -0
- package/dist/runtime-VBLQQ7B3.js +45 -0
- package/dist/server-CLPV5R4E.js +15 -0
- package/dist/setup-CGSB4P4S.js +20 -0
- package/package.json +1 -1
- package/src/cli-reset-password.ts +138 -0
- package/src/cli.ts +6 -1
- package/src/domain-lock/cli-recover.ts +63 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentRuntime,
|
|
3
|
+
EmailChannel,
|
|
4
|
+
FollowUpScheduler,
|
|
5
|
+
SessionManager,
|
|
6
|
+
SubAgentManager,
|
|
7
|
+
ToolRegistry,
|
|
8
|
+
callLLM,
|
|
9
|
+
createAgentRuntime,
|
|
10
|
+
createNoopHooks,
|
|
11
|
+
createRuntimeHooks,
|
|
12
|
+
estimateMessageTokens,
|
|
13
|
+
estimateTokens,
|
|
14
|
+
executeTool,
|
|
15
|
+
runAgentLoop,
|
|
16
|
+
toolsToDefinitions
|
|
17
|
+
} from "./chunk-2YOTK5B7.js";
|
|
18
|
+
import {
|
|
19
|
+
PROVIDER_REGISTRY,
|
|
20
|
+
listAllProviders,
|
|
21
|
+
resolveApiKeyForProvider,
|
|
22
|
+
resolveProvider
|
|
23
|
+
} from "./chunk-UF3ZJMJO.js";
|
|
24
|
+
import "./chunk-KFQGP6VL.js";
|
|
25
|
+
export {
|
|
26
|
+
AgentRuntime,
|
|
27
|
+
EmailChannel,
|
|
28
|
+
FollowUpScheduler,
|
|
29
|
+
PROVIDER_REGISTRY,
|
|
30
|
+
SessionManager,
|
|
31
|
+
SubAgentManager,
|
|
32
|
+
ToolRegistry,
|
|
33
|
+
callLLM,
|
|
34
|
+
createAgentRuntime,
|
|
35
|
+
createNoopHooks,
|
|
36
|
+
createRuntimeHooks,
|
|
37
|
+
estimateMessageTokens,
|
|
38
|
+
estimateTokens,
|
|
39
|
+
executeTool,
|
|
40
|
+
listAllProviders,
|
|
41
|
+
resolveApiKeyForProvider,
|
|
42
|
+
resolveProvider,
|
|
43
|
+
runAgentLoop,
|
|
44
|
+
toolsToDefinitions
|
|
45
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createServer
|
|
3
|
+
} from "./chunk-PG5CNF22.js";
|
|
4
|
+
import "./chunk-OF4MUWWS.js";
|
|
5
|
+
import "./chunk-UF3ZJMJO.js";
|
|
6
|
+
import "./chunk-3OC6RH7W.js";
|
|
7
|
+
import "./chunk-2DDKGTD6.js";
|
|
8
|
+
import "./chunk-YVK6F5OD.js";
|
|
9
|
+
import "./chunk-MKRNEM5A.js";
|
|
10
|
+
import "./chunk-DRXMYYKN.js";
|
|
11
|
+
import "./chunk-6WSX7QXF.js";
|
|
12
|
+
import "./chunk-KFQGP6VL.js";
|
|
13
|
+
export {
|
|
14
|
+
createServer
|
|
15
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
promptCompanyInfo,
|
|
3
|
+
promptDatabase,
|
|
4
|
+
promptDeployment,
|
|
5
|
+
promptDomain,
|
|
6
|
+
promptRegistration,
|
|
7
|
+
provision,
|
|
8
|
+
runSetupWizard
|
|
9
|
+
} from "./chunk-HE5H6NHI.js";
|
|
10
|
+
import "./chunk-ULRBF2T7.js";
|
|
11
|
+
import "./chunk-KFQGP6VL.js";
|
|
12
|
+
export {
|
|
13
|
+
promptCompanyInfo,
|
|
14
|
+
promptDatabase,
|
|
15
|
+
promptDeployment,
|
|
16
|
+
promptDomain,
|
|
17
|
+
promptRegistration,
|
|
18
|
+
provision,
|
|
19
|
+
runSetupWizard
|
|
20
|
+
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Command: reset-password
|
|
3
|
+
*
|
|
4
|
+
* Reset the admin password directly in the database.
|
|
5
|
+
* Useful for recovery or when locked out.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx @agenticmail/enterprise reset-password
|
|
9
|
+
* DATABASE_URL=postgres://... npx @agenticmail/enterprise reset-password
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { existsSync, readFileSync } from 'fs';
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
import { homedir } from 'os';
|
|
15
|
+
|
|
16
|
+
export async function runResetPassword(_args: string[]): Promise<void> {
|
|
17
|
+
const { default: inquirer } = await import('inquirer');
|
|
18
|
+
const { default: chalk } = await import('chalk');
|
|
19
|
+
const { default: ora } = await import('ora');
|
|
20
|
+
|
|
21
|
+
console.log('');
|
|
22
|
+
console.log(chalk.bold(' AgenticMail Enterprise — Password Reset'));
|
|
23
|
+
console.log(chalk.dim(' Reset your admin login password.\n'));
|
|
24
|
+
|
|
25
|
+
// Find DATABASE_URL
|
|
26
|
+
let dbUrl = process.env.DATABASE_URL;
|
|
27
|
+
if (!dbUrl) {
|
|
28
|
+
// Try loading from .env
|
|
29
|
+
const envPaths = [
|
|
30
|
+
join(process.cwd(), '.env'),
|
|
31
|
+
join(homedir(), '.agenticmail', '.env'),
|
|
32
|
+
];
|
|
33
|
+
for (const p of envPaths) {
|
|
34
|
+
if (!existsSync(p)) continue;
|
|
35
|
+
try {
|
|
36
|
+
for (const line of readFileSync(p, 'utf8').split('\n')) {
|
|
37
|
+
const t = line.trim();
|
|
38
|
+
if (t.startsWith('DATABASE_URL=')) {
|
|
39
|
+
dbUrl = t.slice('DATABASE_URL='.length).replace(/^["']|["']$/g, '');
|
|
40
|
+
console.log(chalk.dim(` Found DATABASE_URL in ${p}`));
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (dbUrl) break;
|
|
45
|
+
} catch {}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!dbUrl) {
|
|
50
|
+
const answer = await inquirer.prompt([{
|
|
51
|
+
type: 'input',
|
|
52
|
+
name: 'dbUrl',
|
|
53
|
+
message: 'DATABASE_URL:',
|
|
54
|
+
validate: (v: string) => v.trim().length > 5 ? true : 'Enter your database connection string',
|
|
55
|
+
}]);
|
|
56
|
+
dbUrl = answer.dbUrl.trim();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Get new password
|
|
60
|
+
const { newPassword } = await inquirer.prompt([{
|
|
61
|
+
type: 'password',
|
|
62
|
+
name: 'newPassword',
|
|
63
|
+
message: 'New admin password:',
|
|
64
|
+
mask: '*',
|
|
65
|
+
validate: (v: string) => v.length >= 8 ? true : 'Password must be at least 8 characters',
|
|
66
|
+
}]);
|
|
67
|
+
|
|
68
|
+
const { confirmPassword } = await inquirer.prompt([{
|
|
69
|
+
type: 'password',
|
|
70
|
+
name: 'confirmPassword',
|
|
71
|
+
message: 'Confirm password:',
|
|
72
|
+
mask: '*',
|
|
73
|
+
validate: (v: string) => v === newPassword ? true : 'Passwords do not match',
|
|
74
|
+
}]);
|
|
75
|
+
|
|
76
|
+
if (newPassword !== confirmPassword) {
|
|
77
|
+
console.log(chalk.red(' Passwords do not match.'));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const spinner = ora('Resetting admin password...').start();
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const bcryptMod = await import('bcryptjs');
|
|
85
|
+
const bcrypt = bcryptMod.default || bcryptMod;
|
|
86
|
+
const hash = await bcrypt.hash(newPassword, 12);
|
|
87
|
+
|
|
88
|
+
if (dbUrl!.startsWith('postgres')) {
|
|
89
|
+
const pgMod = await import('postgres' as string);
|
|
90
|
+
const sql = (pgMod.default || pgMod)(dbUrl!);
|
|
91
|
+
// Update the first admin/owner user
|
|
92
|
+
const result = await sql`
|
|
93
|
+
UPDATE users SET password_hash = ${hash}, updated_at = NOW()
|
|
94
|
+
WHERE id = (
|
|
95
|
+
SELECT id FROM users
|
|
96
|
+
WHERE role IN ('admin', 'owner')
|
|
97
|
+
ORDER BY created_at ASC
|
|
98
|
+
LIMIT 1
|
|
99
|
+
)
|
|
100
|
+
RETURNING email, role
|
|
101
|
+
`;
|
|
102
|
+
await sql.end();
|
|
103
|
+
|
|
104
|
+
if (result.length > 0) {
|
|
105
|
+
spinner.succeed(`Password reset for ${result[0].email} (${result[0].role})`);
|
|
106
|
+
} else {
|
|
107
|
+
spinner.warn('No admin user found in database. Run setup first.');
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
// SQLite
|
|
111
|
+
const sqliteMod = await import('better-sqlite3' as string);
|
|
112
|
+
const Database = sqliteMod.default || sqliteMod;
|
|
113
|
+
const dbPath = dbUrl!.replace('file:', '').replace('sqlite:', '');
|
|
114
|
+
const db = new Database(dbPath);
|
|
115
|
+
|
|
116
|
+
const user = db.prepare(
|
|
117
|
+
"SELECT id, email, role FROM users WHERE role IN ('admin', 'owner') ORDER BY created_at ASC LIMIT 1"
|
|
118
|
+
).get() as any;
|
|
119
|
+
|
|
120
|
+
if (user) {
|
|
121
|
+
db.prepare('UPDATE users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(hash, user.id);
|
|
122
|
+
db.close();
|
|
123
|
+
spinner.succeed(`Password reset for ${user.email} (${user.role})`);
|
|
124
|
+
} else {
|
|
125
|
+
db.close();
|
|
126
|
+
spinner.warn('No admin user found in database. Run setup first.');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log('');
|
|
131
|
+
console.log(chalk.green(' You can now log in with your new password.'));
|
|
132
|
+
console.log('');
|
|
133
|
+
} catch (e: any) {
|
|
134
|
+
spinner.fail('Failed: ' + e.message);
|
|
135
|
+
console.log(chalk.dim(' Make sure DATABASE_URL is correct and the database is accessible.'));
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -44,6 +44,10 @@ switch (command) {
|
|
|
44
44
|
import('./domain-lock/cli-verify.js').then(m => m.runVerifyDomain(args.slice(1))).catch(fatal);
|
|
45
45
|
break;
|
|
46
46
|
|
|
47
|
+
case 'reset-password':
|
|
48
|
+
import('./cli-reset-password.js').then(m => m.runResetPassword(args.slice(1))).catch(fatal);
|
|
49
|
+
break;
|
|
50
|
+
|
|
47
51
|
case '--help':
|
|
48
52
|
case '-h':
|
|
49
53
|
console.log(`
|
|
@@ -57,7 +61,8 @@ Commands:
|
|
|
57
61
|
--json Machine-readable output
|
|
58
62
|
build-skill AI-assisted skill scaffolding
|
|
59
63
|
submit-skill <path> Submit a skill as a PR
|
|
60
|
-
recover Recover a domain
|
|
64
|
+
recover Recover a domain/subdomain on a new machine
|
|
65
|
+
reset-password Reset admin password directly in the database
|
|
61
66
|
verify-domain Check DNS verification for your domain
|
|
62
67
|
|
|
63
68
|
Domain Recovery & Verification:
|
|
@@ -443,6 +443,69 @@ async function runCloudRecover(args: string[], inquirer: any, chalk: any, ora: a
|
|
|
443
443
|
console.log(chalk.dim(' Users will need to log in again. This is normal for recovery.'));
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
+
// Offer to reset admin password
|
|
447
|
+
const { wantsReset } = await inquirer.prompt([{
|
|
448
|
+
type: 'confirm',
|
|
449
|
+
name: 'wantsReset',
|
|
450
|
+
message: 'Reset your admin password?',
|
|
451
|
+
default: false,
|
|
452
|
+
}]);
|
|
453
|
+
|
|
454
|
+
if (wantsReset) {
|
|
455
|
+
// Read DATABASE_URL from current env
|
|
456
|
+
let dbUrl = '';
|
|
457
|
+
for (const line of currentEnv.split('\n')) {
|
|
458
|
+
const t = line.trim();
|
|
459
|
+
if (t.startsWith('DATABASE_URL=')) dbUrl = t.slice('DATABASE_URL='.length);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (!dbUrl) {
|
|
463
|
+
console.log(chalk.yellow(' Cannot reset password without DATABASE_URL.'));
|
|
464
|
+
} else {
|
|
465
|
+
const { newPassword } = await inquirer.prompt([{
|
|
466
|
+
type: 'password',
|
|
467
|
+
name: 'newPassword',
|
|
468
|
+
message: 'New admin password:',
|
|
469
|
+
mask: '*',
|
|
470
|
+
validate: (v: string) => v.length >= 8 ? true : 'Password must be at least 8 characters',
|
|
471
|
+
}]);
|
|
472
|
+
const { confirmPassword } = await inquirer.prompt([{
|
|
473
|
+
type: 'password',
|
|
474
|
+
name: 'confirmPassword',
|
|
475
|
+
message: 'Confirm password:',
|
|
476
|
+
mask: '*',
|
|
477
|
+
validate: (v: string) => v === newPassword ? true : 'Passwords do not match',
|
|
478
|
+
}]);
|
|
479
|
+
|
|
480
|
+
if (newPassword === confirmPassword) {
|
|
481
|
+
const resetSpinner = ora('Resetting admin password...').start();
|
|
482
|
+
try {
|
|
483
|
+
const bcryptMod = await import('bcryptjs');
|
|
484
|
+
const bcrypt = bcryptMod.default || bcryptMod;
|
|
485
|
+
const hash = await bcrypt.hash(newPassword, 12);
|
|
486
|
+
|
|
487
|
+
if (dbUrl.startsWith('postgres')) {
|
|
488
|
+
const pgMod = await import('postgres' as string);
|
|
489
|
+
const sql = (pgMod.default || pgMod)(dbUrl);
|
|
490
|
+
await sql`UPDATE users SET password_hash = ${hash} WHERE role = 'admin' OR role = 'owner' ORDER BY created_at ASC LIMIT 1`;
|
|
491
|
+
await sql.end();
|
|
492
|
+
} else {
|
|
493
|
+
// SQLite
|
|
494
|
+
const sqliteMod = await import('better-sqlite3' as string);
|
|
495
|
+
const Database = sqliteMod.default || sqliteMod;
|
|
496
|
+
const db = new Database(dbUrl.replace('file:', '').replace('sqlite:', ''));
|
|
497
|
+
db.prepare('UPDATE users SET password_hash = ? WHERE rowid = (SELECT rowid FROM users WHERE role IN (?, ?) ORDER BY created_at ASC LIMIT 1)').run(hash, 'admin', 'owner');
|
|
498
|
+
db.close();
|
|
499
|
+
}
|
|
500
|
+
resetSpinner.succeed('Admin password reset successfully');
|
|
501
|
+
} catch (e: any) {
|
|
502
|
+
resetSpinner.fail('Could not reset password: ' + e.message);
|
|
503
|
+
console.log(chalk.dim(' You can reset it later from the dashboard or by re-running recovery.'));
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
446
509
|
console.log('');
|
|
447
510
|
console.log(` Start your instance:`);
|
|
448
511
|
console.log(` ${chalk.cyan('npx @agenticmail/enterprise start')}`);
|