66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { execa } from 'execa';
|
|
import inquirer from 'inquirer';
|
|
export async function generateKey(tmpDir, keysDir, pubkey) {
|
|
const { algorithm } = await inquirer.prompt([
|
|
{
|
|
type: 'list',
|
|
name: 'algorithm',
|
|
message: 'Select algorithm:',
|
|
choices: ['ed25519', 'rsa'],
|
|
default: 'ed25519',
|
|
},
|
|
]);
|
|
const { keyName } = await inquirer.prompt([
|
|
{
|
|
type: 'input',
|
|
name: 'keyName',
|
|
message: 'Enter key name:',
|
|
validate: (input) => (input.trim() !== '' ? true : 'Key name cannot be empty'),
|
|
},
|
|
]);
|
|
const { password } = await inquirer.prompt([
|
|
{
|
|
type: 'password',
|
|
name: 'password',
|
|
message: 'Enter passphrase (leave empty for no passphrase):',
|
|
mask: '*',
|
|
},
|
|
]);
|
|
const { identity } = await inquirer.prompt([
|
|
{
|
|
type: 'input',
|
|
name: 'identity',
|
|
message: 'Enter key identity (comment):',
|
|
},
|
|
]);
|
|
const fileName = keyName.startsWith('id_') ? keyName : `id_${keyName}`;
|
|
const keyPath = path.join(tmpDir, fileName);
|
|
if (fs.existsSync(keyPath)) {
|
|
console.error(`❌ Error: Key file ${fileName} already exists in ${tmpDir}`);
|
|
return;
|
|
}
|
|
try {
|
|
console.log(`Generating ${algorithm} key pair...`);
|
|
const args = ['-t', algorithm, '-f', keyPath, '-N', password, '-C', identity];
|
|
if (algorithm === 'rsa') {
|
|
args.push('-b', '4096');
|
|
}
|
|
await execa('ssh-keygen', args);
|
|
console.log(`✅ Key generated: ${keyPath}`);
|
|
// Encrypt the key
|
|
const folderName = fileName.replace('id_', '');
|
|
const vaultPath = path.join(keysDir, folderName);
|
|
fs.mkdirSync(vaultPath, { recursive: true });
|
|
// Encrypt key using `age`
|
|
await execa('age', ['-r', pubkey, '-o', path.join(vaultPath, `${fileName}.age`), keyPath]);
|
|
// Copy public key
|
|
fs.copyFileSync(`${keyPath}.pub`, path.join(vaultPath, `${fileName}.pub`));
|
|
console.log(`🔒 Encrypted and stored: ${vaultPath}`);
|
|
}
|
|
catch (error) {
|
|
console.error(`❌ Error generating/encrypting key: ${error}`);
|
|
}
|
|
}
|