devcrypt
Version:
A easy way to encrypt and decrypt your environment variables
150 lines (134 loc) • 4.13 kB
JavaScript
import inquirer from "inquirer";
import figlet from "figlet";
import crypto from "crypto";
import chalk from "chalk";
import { copyFileSync, readFileSync, write, writeFileSync } from "fs";
const algorithm = "aes256";
const wait = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
const encrypt = (text, password) => {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, password, iv);
const encryptedMessage =
cipher.update(text, "utf8", "hex") + cipher.final("hex");
return iv.toString("hex") + ":" + encryptedMessage;
};
const decrypt = (text, password) => {
const textParts = text.split(":");
const iv = Buffer.from(textParts.shift(), "hex");
const encryptedText = Buffer.from(textParts.join(":"), "hex");
const decipher = crypto.createDecipheriv(algorithm, password, iv);
try {
var decrypted =
decipher.update(encryptedText, "hex", "utf8") + decipher.final("utf8");
} catch (err) {
console.log(chalk.bgRed("Incorrect password."));
process.exit(1);
}
return decrypted.toString();
};
const hash = (password) => {
return (password = crypto
.createHash("sha256")
.update(String(password))
.digest("base64")
.substring(0, 32));
};
const setPassword = async (envFile) => {
let { password } = await inquirer.prompt([
{
type: "password",
name: "password",
message:
"Please enter a password to encrypt/decrypt your environment variables",
},
]);
// open env file and add password to it
let envLine = readFileSync(envFile, "utf8");
envLine += `
# npx devcrypt
ENV_PASSWORD=${password} # Created by devcrypt
`;
writeFileSync(envFile, envLine);
return password;
};
async function main() {
logSpecial("devcrypt");
console.log(
"Welcome to devcrypt, a tool to encrypt and decrypt environment variables."
);
console.log("Please select an option below:");
const { option } = await inquirer.prompt([
{
type: "list",
name: "option",
message: "Select an option",
choices: ["Encrypt", "Decrypt"],
},
]);
const { envFile } = await inquirer.prompt([
{
type: "input",
name: "envFile",
message: "Please enter the path and filename of your .env file",
default: ".env",
},
]);
// check if env file exists
try {
const env = readFileSync(envFile, "utf8");
} catch (err) {
const confirm = await inquirer.prompt([
{
type: "confirm",
name: "createFile",
message:
"The file you specified does not exist. would you like to create it?",
},
]);
if (confirm) {
writeFileSync(envFile, "");
} else {
console.log(chalk.bgRed("Exiting program."));
// exit program as failure
process.exit(1);
}
}
// check if there is a ENV_PASSWORD in the .env file
let env = readFileSync(envFile, "utf8");
let password;
if (!env.includes("ENV_PASSWORD")) {
// make chalk display "No password found in .env file." in red
console.log(chalk.bgRed(`No password found in ${envFile} file.`));
// set password
password = await setPassword(envFile);
} else {
// get password from .env file
password = env.split("ENV_PASSWORD=")[1].split(" #")[0];
}
password = hash(password);
if (option === "Encrypt") {
const env = readFileSync(envFile, "utf8");
let encrypted = encrypt(env, password);
// add a new line to the end of the file
encrypted += `\nnpx devcrypt`;
writeFileSync(envFile + ".encrypted", encrypted);
console.clear();
console.log("Your environment variables have been encrypted.");
process.exit(0);
} else if (option === "Decrypt") {
let env = readFileSync(envFile + ".encrypted", "utf8");
env = env.split(`\nnpx devcrypt`)[0];
const decrypted = decrypt(env, password);
writeFileSync(envFile, decrypted);
console.clear();
console.log("Your environment variables have been decrypted.");
process.exit(0);
}
}
const logSpecial = (text) => {
console.log(figlet.textSync(text));
};
main();