doclyft
Version:
CLI for DocLyft - Interactive documentation generator with hosted documentation support
85 lines (84 loc) • 3.62 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.encrypt = encrypt;
exports.decrypt = decrypt;
exports.encryptSessionData = encryptSessionData;
exports.decryptSessionData = decryptSessionData;
exports.generateSecureDeviceId = generateSecureDeviceId;
const crypto_1 = __importDefault(require("crypto"));
const os_1 = __importDefault(require("os"));
// Generate a deterministic key from CLI metadata
// Must be deterministic across all machines for config decryption to work
function generateKey() {
const packageInfo = 'doclyft-cli-v1.6.2-security';
const salt = 'doclf-2025-secure';
const additionalEntropy = 'doclyft-security-2025';
const combined = packageInfo + salt + additionalEntropy;
// Increased iterations for better security (100k iterations)
return crypto_1.default.pbkdf2Sync(combined, salt, 100000, 32, 'sha256');
}
function encrypt(text) {
const key = generateKey();
const iv = crypto_1.default.randomBytes(16);
const cipher = crypto_1.default.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return iv.toString('hex') + ':' + encrypted;
}
function decrypt(encryptedText) {
try {
const key = generateKey();
const parts = encryptedText.split(':');
const iv = Buffer.from(parts[0], 'hex');
const encrypted = parts[1];
const decipher = crypto_1.default.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
catch (error) {
throw new Error('Failed to decrypt configuration. Please reinstall the CLI.');
}
}
// Session-specific encryption functions using the same key generation but different context
function generateSessionKey() {
const packageInfo = 'doclyft-cli-session-v1.6.2';
const salt = 'session-2025-secure';
// Add machine-specific entropy
const machineEntropy = crypto_1.default.createHash('sha256')
.update(os_1.default.platform() + os_1.default.arch() + os_1.default.type())
.digest('hex');
const additionalEntropy = 'doclyft-session-security-2025';
const combined = packageInfo + salt + additionalEntropy + machineEntropy;
return crypto_1.default.pbkdf2Sync(combined, salt, 100000, 32, 'sha256');
}
function encryptSessionData(text) {
const key = generateSessionKey();
const iv = crypto_1.default.randomBytes(16);
const cipher = crypto_1.default.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return iv.toString('hex') + ':' + encrypted;
}
function decryptSessionData(encryptedText) {
try {
const key = generateSessionKey();
const parts = encryptedText.split(':');
const iv = Buffer.from(parts[0], 'hex');
const encrypted = parts[1];
const decipher = crypto_1.default.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
catch (error) {
throw new Error('Failed to decrypt session data. Please login again.');
}
}
// Generate cryptographically secure random values
function generateSecureDeviceId() {
return crypto_1.default.randomBytes(16).toString('hex');
}