@vultisig/cli 0.1.0-alpha.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/README.md +391 -0
- package/dist/adapters/cli-context.js +25 -0
- package/dist/adapters/cli-context.js.map +1 -0
- package/dist/adapters/cli-runner.js +47 -0
- package/dist/adapters/cli-runner.js.map +1 -0
- package/dist/adapters/index.js +6 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/commands/balance.js +65 -0
- package/dist/commands/balance.js.map +1 -0
- package/dist/commands/chains.js +46 -0
- package/dist/commands/chains.js.map +1 -0
- package/dist/commands/index.js +12 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/settings.js +151 -0
- package/dist/commands/settings.js.map +1 -0
- package/dist/commands/swap.js +180 -0
- package/dist/commands/swap.js.map +1 -0
- package/dist/commands/tokens.js +116 -0
- package/dist/commands/tokens.js.map +1 -0
- package/dist/commands/transaction.js +99 -0
- package/dist/commands/transaction.js.map +1 -0
- package/dist/commands/vault-management.js +360 -0
- package/dist/commands/vault-management.js.map +1 -0
- package/dist/core/command-context.js +81 -0
- package/dist/core/command-context.js.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/password-manager.js +92 -0
- package/dist/core/password-manager.js.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.js +440 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive/completer.js +170 -0
- package/dist/interactive/completer.js.map +1 -0
- package/dist/interactive/event-buffer.js +186 -0
- package/dist/interactive/event-buffer.js.map +1 -0
- package/dist/interactive/index.js +9 -0
- package/dist/interactive/index.js.map +1 -0
- package/dist/interactive/session.js +525 -0
- package/dist/interactive/session.js.map +1 -0
- package/dist/interactive/shell-commands.js +167 -0
- package/dist/interactive/shell-commands.js.map +1 -0
- package/dist/interactive/shell-context.js +112 -0
- package/dist/interactive/shell-context.js.map +1 -0
- package/dist/lib/completion.js +375 -0
- package/dist/lib/completion.js.map +1 -0
- package/dist/lib/config.js +172 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.js +163 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/output.js +155 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/version.js +210 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/ui.js +286 -0
- package/dist/ui.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import { createSpinner, error, info, isJsonOutput, outputJson, printResult, success, warn } from '../lib/output';
|
|
5
|
+
import { displayVaultInfo, displayVaultsList, setupVaultEvents } from '../ui';
|
|
6
|
+
/**
|
|
7
|
+
* Execute create vault command
|
|
8
|
+
*/
|
|
9
|
+
export async function executeCreate(ctx, options = { type: 'fast' }) {
|
|
10
|
+
const vaultType = options.type.toLowerCase();
|
|
11
|
+
if (vaultType !== 'fast' && vaultType !== 'secure') {
|
|
12
|
+
throw new Error('Invalid vault type. Must be "fast" or "secure"');
|
|
13
|
+
}
|
|
14
|
+
// Use provided options or prompt for missing values
|
|
15
|
+
let name = options.name;
|
|
16
|
+
let password = options.password;
|
|
17
|
+
const prompts = [];
|
|
18
|
+
if (!name) {
|
|
19
|
+
prompts.push({
|
|
20
|
+
type: 'input',
|
|
21
|
+
name: 'name',
|
|
22
|
+
message: 'Enter vault name:',
|
|
23
|
+
validate: (input) => input.trim() !== '' || 'Name is required',
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (!password) {
|
|
27
|
+
prompts.push({
|
|
28
|
+
type: 'password',
|
|
29
|
+
name: 'password',
|
|
30
|
+
message: 'Enter password:',
|
|
31
|
+
mask: '*',
|
|
32
|
+
validate: (input) => input.length >= 8 || 'Password must be at least 8 characters',
|
|
33
|
+
});
|
|
34
|
+
prompts.push({
|
|
35
|
+
type: 'password',
|
|
36
|
+
name: 'confirmPassword',
|
|
37
|
+
message: 'Confirm password:',
|
|
38
|
+
mask: '*',
|
|
39
|
+
validate: (input, ans) => input === ans.password || 'Passwords do not match',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (prompts.length > 0) {
|
|
43
|
+
const answers = (await inquirer.prompt(prompts));
|
|
44
|
+
name = name || answers.name;
|
|
45
|
+
password = password || answers.password;
|
|
46
|
+
}
|
|
47
|
+
if (vaultType === 'fast') {
|
|
48
|
+
let email = options.email;
|
|
49
|
+
if (!email) {
|
|
50
|
+
const emailAnswer = await inquirer.prompt([
|
|
51
|
+
{
|
|
52
|
+
type: 'input',
|
|
53
|
+
name: 'email',
|
|
54
|
+
message: 'Enter email for verification:',
|
|
55
|
+
validate: (input) => /\S+@\S+\.\S+/.test(input) || 'Invalid email format',
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
email = emailAnswer.email;
|
|
59
|
+
}
|
|
60
|
+
const spinner = createSpinner('Creating vault...');
|
|
61
|
+
const result = await ctx.sdk.createFastVault({
|
|
62
|
+
name: name,
|
|
63
|
+
password: password,
|
|
64
|
+
email: email,
|
|
65
|
+
onProgress: step => {
|
|
66
|
+
spinner.text = `${step.message} (${step.progress}%)`;
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
setupVaultEvents(result.vault);
|
|
70
|
+
await ctx.setActiveVault(result.vault);
|
|
71
|
+
spinner.succeed(`Vault created: ${name}`);
|
|
72
|
+
if (result.verificationRequired) {
|
|
73
|
+
let code = options.code;
|
|
74
|
+
if (!code) {
|
|
75
|
+
warn('\nA verification code has been sent to your email.');
|
|
76
|
+
info('Please check your inbox and enter the code.');
|
|
77
|
+
const codeAnswer = await inquirer.prompt([
|
|
78
|
+
{
|
|
79
|
+
type: 'input',
|
|
80
|
+
name: 'code',
|
|
81
|
+
message: `Verification code sent to ${email}. Enter code:`,
|
|
82
|
+
validate: (input) => /^\d{4,6}$/.test(input) || 'Code must be 4-6 digits',
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
code = codeAnswer.code;
|
|
86
|
+
}
|
|
87
|
+
const verifySpinner = createSpinner('Verifying email code...');
|
|
88
|
+
const verified = await ctx.sdk.verifyVault(result.vaultId, code);
|
|
89
|
+
if (verified) {
|
|
90
|
+
verifySpinner.succeed('Email verified successfully!');
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
verifySpinner.fail('Invalid verification code');
|
|
94
|
+
error('\nx Verification failed. Please check the code and try again.');
|
|
95
|
+
warn('\nTo retry verification, use:');
|
|
96
|
+
info(` npm run wallet verify ${result.vaultId}`);
|
|
97
|
+
warn('\nTo resend the verification email:');
|
|
98
|
+
info(` npm run wallet verify ${result.vaultId} --resend`);
|
|
99
|
+
const err = new Error('Verification failed');
|
|
100
|
+
err.exitCode = 1;
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
success('\n+ Vault created!');
|
|
105
|
+
info('\nYour vault is ready. Run the following commands:');
|
|
106
|
+
printResult(chalk.cyan(' npm run wallet balance ') + '- View balances');
|
|
107
|
+
printResult(chalk.cyan(' npm run wallet addresses ') + '- View addresses');
|
|
108
|
+
printResult(chalk.cyan(' npm run wallet portfolio ') + '- View portfolio value');
|
|
109
|
+
return result.vault;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Secure vault
|
|
113
|
+
let threshold = options.threshold;
|
|
114
|
+
let totalShares = options.shares;
|
|
115
|
+
const securePrompts = [];
|
|
116
|
+
if (threshold === undefined) {
|
|
117
|
+
securePrompts.push({
|
|
118
|
+
type: 'number',
|
|
119
|
+
name: 'threshold',
|
|
120
|
+
message: 'Signing threshold (m):',
|
|
121
|
+
default: 2,
|
|
122
|
+
validate: (input) => input > 0 || 'Threshold must be greater than 0',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if (totalShares === undefined) {
|
|
126
|
+
securePrompts.push({
|
|
127
|
+
type: 'number',
|
|
128
|
+
name: 'totalShares',
|
|
129
|
+
message: 'Total shares (n):',
|
|
130
|
+
default: 3,
|
|
131
|
+
validate: (input, ans) => {
|
|
132
|
+
const t = threshold ?? ans.threshold;
|
|
133
|
+
return input >= t || `Total shares must be >= threshold (${t})`;
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (securePrompts.length > 0) {
|
|
138
|
+
const secureAnswers = (await inquirer.prompt(securePrompts));
|
|
139
|
+
threshold = threshold ?? secureAnswers.threshold;
|
|
140
|
+
totalShares = totalShares ?? secureAnswers.totalShares;
|
|
141
|
+
}
|
|
142
|
+
const spinner = createSpinner('Creating secure vault...');
|
|
143
|
+
try {
|
|
144
|
+
const result = await ctx.sdk.createSecureVault({
|
|
145
|
+
name: name,
|
|
146
|
+
password: password,
|
|
147
|
+
devices: totalShares,
|
|
148
|
+
threshold: threshold,
|
|
149
|
+
onProgress: step => {
|
|
150
|
+
spinner.text = `${step.message} (${step.progress}%)`;
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
setupVaultEvents(result.vault);
|
|
154
|
+
await ctx.setActiveVault(result.vault);
|
|
155
|
+
spinner.succeed(`Secure vault created: ${name} (${threshold}-of-${totalShares})`);
|
|
156
|
+
warn(`\nImportant: Save your vault backup file (.vult) in a secure location.`);
|
|
157
|
+
warn(`This is a ${threshold}-of-${totalShares} vault. You'll need ${threshold} devices to sign transactions.`);
|
|
158
|
+
success('\n+ Vault created!');
|
|
159
|
+
return result.vault;
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
spinner.fail('Secure vault creation failed');
|
|
163
|
+
if (err.message?.includes('not implemented')) {
|
|
164
|
+
warn('\nSecure vault creation is not yet implemented in the SDK');
|
|
165
|
+
}
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Execute import vault command
|
|
172
|
+
*/
|
|
173
|
+
export async function executeImport(ctx, file) {
|
|
174
|
+
const { password } = await inquirer.prompt([
|
|
175
|
+
{
|
|
176
|
+
type: 'password',
|
|
177
|
+
name: 'password',
|
|
178
|
+
message: 'Enter vault password (if encrypted):',
|
|
179
|
+
mask: '*',
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
182
|
+
const spinner = createSpinner('Importing vault...');
|
|
183
|
+
const vultContent = await fs.readFile(file, 'utf-8');
|
|
184
|
+
const vault = await ctx.sdk.importVault(vultContent, password || undefined);
|
|
185
|
+
setupVaultEvents(vault);
|
|
186
|
+
await ctx.setActiveVault(vault);
|
|
187
|
+
spinner.succeed(`Vault imported: ${vault.name}`);
|
|
188
|
+
success('\n+ Vault imported successfully!');
|
|
189
|
+
info('\nRun "npm run wallet balance" to view balances');
|
|
190
|
+
return vault;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Execute verify vault command
|
|
194
|
+
*/
|
|
195
|
+
export async function executeVerify(ctx, vaultId, options = {}) {
|
|
196
|
+
if (options.resend) {
|
|
197
|
+
const spinner = createSpinner('Resending verification email...');
|
|
198
|
+
await ctx.sdk.resendVaultVerification(vaultId);
|
|
199
|
+
spinner.succeed('Verification email sent!');
|
|
200
|
+
info('Check your inbox for the new verification code.');
|
|
201
|
+
}
|
|
202
|
+
let code = options.code;
|
|
203
|
+
if (!code) {
|
|
204
|
+
const codeAnswer = await inquirer.prompt([
|
|
205
|
+
{
|
|
206
|
+
type: 'input',
|
|
207
|
+
name: 'code',
|
|
208
|
+
message: 'Enter verification code:',
|
|
209
|
+
validate: (input) => /^\d{4,6}$/.test(input) || 'Code must be 4-6 digits',
|
|
210
|
+
},
|
|
211
|
+
]);
|
|
212
|
+
code = codeAnswer.code;
|
|
213
|
+
}
|
|
214
|
+
const spinner = createSpinner('Verifying email code...');
|
|
215
|
+
const verified = await ctx.sdk.verifyVault(vaultId, code);
|
|
216
|
+
if (verified) {
|
|
217
|
+
spinner.succeed('Vault verified successfully!');
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
spinner.fail('Invalid verification code');
|
|
222
|
+
error('\nx Verification failed. Please check the code and try again.');
|
|
223
|
+
warn('\nTip: Use --resend to get a new verification code:');
|
|
224
|
+
info(` npm run wallet verify ${vaultId} --resend`);
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Execute export vault command
|
|
230
|
+
*/
|
|
231
|
+
export async function executeExport(ctx, options = {}) {
|
|
232
|
+
const vault = await ctx.ensureActiveVault();
|
|
233
|
+
let encrypt = options.encrypt;
|
|
234
|
+
let password = options.password;
|
|
235
|
+
// Only prompt if --encrypt/--no-encrypt not specified
|
|
236
|
+
if (encrypt === undefined) {
|
|
237
|
+
const encryptAnswer = await inquirer.prompt([
|
|
238
|
+
{
|
|
239
|
+
type: 'confirm',
|
|
240
|
+
name: 'encrypt',
|
|
241
|
+
message: 'Encrypt export with password?',
|
|
242
|
+
default: true,
|
|
243
|
+
},
|
|
244
|
+
]);
|
|
245
|
+
encrypt = encryptAnswer.encrypt;
|
|
246
|
+
}
|
|
247
|
+
if (encrypt && !password) {
|
|
248
|
+
const passwordAnswer = await inquirer.prompt([
|
|
249
|
+
{
|
|
250
|
+
type: 'password',
|
|
251
|
+
name: 'password',
|
|
252
|
+
message: 'Enter password:',
|
|
253
|
+
mask: '*',
|
|
254
|
+
},
|
|
255
|
+
]);
|
|
256
|
+
password = passwordAnswer.password;
|
|
257
|
+
}
|
|
258
|
+
const spinner = createSpinner('Exporting vault...');
|
|
259
|
+
// Pass password to export if encrypting
|
|
260
|
+
const { data: vultContent } = await vault.export(encrypt ? password : undefined);
|
|
261
|
+
const fileName = options.outputPath || `${vault.name}-${vault.localPartyId}-vault.vult`;
|
|
262
|
+
await fs.writeFile(fileName, vultContent, 'utf-8');
|
|
263
|
+
spinner.succeed(`Vault exported: ${fileName}`);
|
|
264
|
+
success('\n+ Vault exported successfully!');
|
|
265
|
+
info(`File: ${fileName}`);
|
|
266
|
+
return fileName;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Execute list vaults command
|
|
270
|
+
*/
|
|
271
|
+
export async function executeVaults(ctx) {
|
|
272
|
+
const spinner = createSpinner('Loading vaults...');
|
|
273
|
+
const vaults = await ctx.sdk.listVaults();
|
|
274
|
+
spinner.succeed('Vaults loaded');
|
|
275
|
+
if (isJsonOutput()) {
|
|
276
|
+
const activeVault = ctx.getActiveVault();
|
|
277
|
+
outputJson({
|
|
278
|
+
vaults: vaults.map(v => ({
|
|
279
|
+
id: v.id,
|
|
280
|
+
name: v.name,
|
|
281
|
+
type: v.type,
|
|
282
|
+
chains: v.chains.length,
|
|
283
|
+
createdAt: v.createdAt,
|
|
284
|
+
isActive: activeVault?.id === v.id,
|
|
285
|
+
})),
|
|
286
|
+
});
|
|
287
|
+
return vaults;
|
|
288
|
+
}
|
|
289
|
+
if (vaults.length === 0) {
|
|
290
|
+
warn('\nNo vaults found. Create or import a vault first.');
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
const activeVault = ctx.getActiveVault();
|
|
294
|
+
displayVaultsList(vaults, activeVault);
|
|
295
|
+
info(chalk.gray('\nUse "npm run wallet switch <id>" to switch active vault'));
|
|
296
|
+
return vaults;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Execute switch vault command
|
|
300
|
+
*/
|
|
301
|
+
export async function executeSwitch(ctx, vaultId) {
|
|
302
|
+
const spinner = createSpinner('Loading vault...');
|
|
303
|
+
const vault = await ctx.sdk.getVaultById(vaultId);
|
|
304
|
+
if (!vault) {
|
|
305
|
+
spinner.fail('Vault not found');
|
|
306
|
+
throw new Error(`No vault found with ID: ${vaultId}`);
|
|
307
|
+
}
|
|
308
|
+
await ctx.setActiveVault(vault);
|
|
309
|
+
setupVaultEvents(vault);
|
|
310
|
+
spinner.succeed('Vault switched');
|
|
311
|
+
success(`\n+ Switched to vault: ${vault.name}`);
|
|
312
|
+
info(` Type: ${vault.type}`);
|
|
313
|
+
info(` Chains: ${vault.chains.length}`);
|
|
314
|
+
return vault;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Execute rename vault command
|
|
318
|
+
*/
|
|
319
|
+
export async function executeRename(ctx, newName) {
|
|
320
|
+
const vault = await ctx.ensureActiveVault();
|
|
321
|
+
const oldName = vault.name;
|
|
322
|
+
const spinner = createSpinner('Renaming vault...');
|
|
323
|
+
await vault.rename(newName);
|
|
324
|
+
spinner.succeed('Vault renamed');
|
|
325
|
+
success(`\n+ Vault renamed from "${oldName}" to "${newName}"`);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Execute vault info command
|
|
329
|
+
*/
|
|
330
|
+
export async function executeInfo(ctx) {
|
|
331
|
+
const vault = await ctx.ensureActiveVault();
|
|
332
|
+
if (isJsonOutput()) {
|
|
333
|
+
outputJson({
|
|
334
|
+
vault: {
|
|
335
|
+
id: vault.id,
|
|
336
|
+
name: vault.name,
|
|
337
|
+
type: vault.type,
|
|
338
|
+
createdAt: vault.createdAt,
|
|
339
|
+
lastModified: vault.lastModified,
|
|
340
|
+
isEncrypted: vault.isEncrypted,
|
|
341
|
+
isBackedUp: vault.isBackedUp,
|
|
342
|
+
libType: vault.libType,
|
|
343
|
+
threshold: vault.threshold,
|
|
344
|
+
totalSigners: vault.totalSigners,
|
|
345
|
+
localPartyId: vault.localPartyId,
|
|
346
|
+
availableSigningModes: [...vault.availableSigningModes],
|
|
347
|
+
chains: [...vault.chains],
|
|
348
|
+
currency: vault.currency,
|
|
349
|
+
publicKeys: {
|
|
350
|
+
ecdsa: vault.publicKeys.ecdsa,
|
|
351
|
+
eddsa: vault.publicKeys.eddsa,
|
|
352
|
+
chainCode: vault.hexChainCode,
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
displayVaultInfo(vault);
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=vault-management.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-management.js","sourceRoot":"","sources":["../../src/commands/vault-management.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default password cache TTL (5 minutes)
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_PASSWORD_CACHE_TTL = 5 * 60 * 1000;
|
|
5
|
+
/**
|
|
6
|
+
* Base implementation of CommandContext that can be extended
|
|
7
|
+
* by CLI and Shell-specific implementations
|
|
8
|
+
*/
|
|
9
|
+
export class BaseCommandContext {
|
|
10
|
+
_sdk;
|
|
11
|
+
_activeVault = null;
|
|
12
|
+
passwordCache = new Map();
|
|
13
|
+
defaultPasswordTtl;
|
|
14
|
+
constructor(sdk, options) {
|
|
15
|
+
this._sdk = sdk;
|
|
16
|
+
this.defaultPasswordTtl = options?.passwordTtlMs ?? DEFAULT_PASSWORD_CACHE_TTL;
|
|
17
|
+
}
|
|
18
|
+
get sdk() {
|
|
19
|
+
return this._sdk;
|
|
20
|
+
}
|
|
21
|
+
getActiveVault() {
|
|
22
|
+
return this._activeVault;
|
|
23
|
+
}
|
|
24
|
+
async setActiveVault(vault) {
|
|
25
|
+
this._activeVault = vault;
|
|
26
|
+
await this._sdk.setActiveVault(vault);
|
|
27
|
+
}
|
|
28
|
+
async ensureActiveVault() {
|
|
29
|
+
if (!this._activeVault) {
|
|
30
|
+
// Try to load from SDK
|
|
31
|
+
const vault = await this._sdk.getActiveVault();
|
|
32
|
+
if (vault) {
|
|
33
|
+
this._activeVault = vault;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!this._activeVault) {
|
|
37
|
+
throw new Error('No active vault. Create or import a vault first.');
|
|
38
|
+
}
|
|
39
|
+
return this._activeVault;
|
|
40
|
+
}
|
|
41
|
+
cachePassword(vaultId, password, ttlMs) {
|
|
42
|
+
const ttl = ttlMs ?? this.defaultPasswordTtl;
|
|
43
|
+
this.passwordCache.set(vaultId, {
|
|
44
|
+
password,
|
|
45
|
+
expiresAt: Date.now() + ttl,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
clearPasswordCache(vaultId) {
|
|
49
|
+
if (vaultId) {
|
|
50
|
+
this.passwordCache.delete(vaultId);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.passwordCache.clear();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
isPasswordCached(vaultId) {
|
|
57
|
+
const entry = this.passwordCache.get(vaultId);
|
|
58
|
+
if (!entry)
|
|
59
|
+
return false;
|
|
60
|
+
if (Date.now() > entry.expiresAt) {
|
|
61
|
+
this.passwordCache.delete(vaultId);
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
getCachedPassword(vaultId) {
|
|
67
|
+
const entry = this.passwordCache.get(vaultId);
|
|
68
|
+
if (!entry)
|
|
69
|
+
return null;
|
|
70
|
+
if (Date.now() > entry.expiresAt) {
|
|
71
|
+
this.passwordCache.delete(vaultId);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return entry.password;
|
|
75
|
+
}
|
|
76
|
+
dispose() {
|
|
77
|
+
this.passwordCache.clear();
|
|
78
|
+
this._sdk.dispose();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=command-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-context.js","sourceRoot":"","sources":["../../src/core/command-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,SAAS,CAAA"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password Manager - Handles password resolution from various sources
|
|
3
|
+
*
|
|
4
|
+
* Priority order:
|
|
5
|
+
* 1. VAULT_PASSWORDS env var (format: "VaultName:password VaultId:password")
|
|
6
|
+
* 2. VAULT_PASSWORD env var (single fallback password)
|
|
7
|
+
* 3. Interactive prompt (if no env password found and not in silent/JSON mode)
|
|
8
|
+
*/
|
|
9
|
+
import inquirer from 'inquirer';
|
|
10
|
+
import { isJsonOutput, isSilent } from '../lib/output';
|
|
11
|
+
/**
|
|
12
|
+
* Parse VAULT_PASSWORDS env var into a Map
|
|
13
|
+
* Format: "VaultName:password VaultId:password"
|
|
14
|
+
*/
|
|
15
|
+
export function parseVaultPasswords() {
|
|
16
|
+
const passwordMap = new Map();
|
|
17
|
+
const passwordsEnv = process.env.VAULT_PASSWORDS;
|
|
18
|
+
if (passwordsEnv) {
|
|
19
|
+
const pairs = passwordsEnv.trim().split(/\s+/);
|
|
20
|
+
for (const pair of pairs) {
|
|
21
|
+
const colonIndex = pair.indexOf(':');
|
|
22
|
+
if (colonIndex > 0) {
|
|
23
|
+
const vaultKey = pair.substring(0, colonIndex);
|
|
24
|
+
const password = pair.substring(colonIndex + 1);
|
|
25
|
+
passwordMap.set(vaultKey, password);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return passwordMap;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get password from environment variables
|
|
33
|
+
* Returns null if not found in env
|
|
34
|
+
*/
|
|
35
|
+
export function getPasswordFromEnv(vaultId, vaultName) {
|
|
36
|
+
const vaultPasswords = parseVaultPasswords();
|
|
37
|
+
// Check by vault name first
|
|
38
|
+
if (vaultName && vaultPasswords.has(vaultName)) {
|
|
39
|
+
return vaultPasswords.get(vaultName);
|
|
40
|
+
}
|
|
41
|
+
// Check by vault ID
|
|
42
|
+
if (vaultPasswords.has(vaultId)) {
|
|
43
|
+
return vaultPasswords.get(vaultId);
|
|
44
|
+
}
|
|
45
|
+
// Check single fallback password
|
|
46
|
+
if (process.env.VAULT_PASSWORD) {
|
|
47
|
+
return process.env.VAULT_PASSWORD;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Prompt user for password interactively
|
|
53
|
+
*/
|
|
54
|
+
export async function promptForPassword(vaultName, vaultId) {
|
|
55
|
+
const displayName = vaultName || vaultId || 'vault';
|
|
56
|
+
const { password } = await inquirer.prompt([
|
|
57
|
+
{
|
|
58
|
+
type: 'password',
|
|
59
|
+
name: 'password',
|
|
60
|
+
message: `Enter password for vault "${displayName}":`,
|
|
61
|
+
mask: '*',
|
|
62
|
+
},
|
|
63
|
+
]);
|
|
64
|
+
return password;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get password using the standard resolution order:
|
|
68
|
+
* 1. Environment variables
|
|
69
|
+
* 2. Interactive prompt (only if not in silent/JSON mode)
|
|
70
|
+
*/
|
|
71
|
+
export async function getPassword(vaultId, vaultName) {
|
|
72
|
+
// Try environment first
|
|
73
|
+
const envPassword = getPasswordFromEnv(vaultId, vaultName);
|
|
74
|
+
if (envPassword) {
|
|
75
|
+
return envPassword;
|
|
76
|
+
}
|
|
77
|
+
// In silent/JSON mode, we can't prompt - throw an error
|
|
78
|
+
if (isSilent() || isJsonOutput()) {
|
|
79
|
+
throw new Error('Password required but not provided. Set VAULT_PASSWORD or VAULT_PASSWORDS environment variable.');
|
|
80
|
+
}
|
|
81
|
+
// Fall back to interactive prompt
|
|
82
|
+
return promptForPassword(vaultName, vaultId);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create an onPasswordRequired callback for SDK initialization
|
|
86
|
+
*/
|
|
87
|
+
export function createPasswordCallback() {
|
|
88
|
+
return async (vaultId, vaultName) => {
|
|
89
|
+
return getPassword(vaultId, vaultName);
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=password-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-manager.js","sourceRoot":"","sources":["../../src/core/password-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
|