feat: new encrypt

This commit is contained in:
2024-09-30 10:18:23 +05:30
parent 79810d7e03
commit 009f16796c
3 changed files with 96 additions and 21 deletions

View File

@@ -1,15 +1,15 @@
#!/bin/env bun #!/bin/env bun
import { checkbox, input, password, select } from "@inquirer/prompts"; import { input, password } from "@inquirer/prompts";
import { $ } from "bun"; import { $ } from "bun";
import chalk from "chalk-template"; import chalk from "chalk-template";
import { Command } from "commander"; import { Command } from "commander";
import { decrypt_diary, encrypt_diary, initialize, recovery } from "./src/main"; import { decrypt_vault, encrypt_vault, initialize, recovery } from "./src/main";
import { existsSync } from "fs"; import { existsSync } from "fs";
import checkForFiles, { import checkForFiles, {
getDecryptedName,
getDirectoryNames, getDirectoryNames,
getVaultName, getVaultName,
log,
panic, panic,
} from "./src/utils"; } from "./src/utils";
@@ -47,7 +47,6 @@ program
.option("-l, --live", "decrypt in live mode") .option("-l, --live", "decrypt in live mode")
.option("-v, --vault <name>", "name of the vault to decrypt") .option("-v, --vault <name>", "name of the vault to decrypt")
.action(async (args) => { .action(async (args) => {
let files: string[];
if (!args.vault) { if (!args.vault) {
args.vault = await getVaultName(); args.vault = await getVaultName();
} }
@@ -56,12 +55,12 @@ program
message: chalk`{reset {yellow Enter the password:}}`, message: chalk`{reset {yellow Enter the password:}}`,
mask: "•", mask: "•",
}); });
await decrypt_diary(pass, args.vault); await decrypt_vault(pass, args.vault);
if (args.live) { if (args.live) {
await input({ await input({
message: chalk`{yellow Live mode started. Press ENTER to encrypt}`, message: chalk`{yellow Live mode started. Press ENTER to encrypt}`,
}); });
await encrypt_diary(); await encrypt_vault(args.vault);
console.log(chalk`{green Successfully encrypted!}`); console.log(chalk`{green Successfully encrypted!}`);
} else { } else {
console.log(chalk`{green Decrypted sucessfully!}`); console.log(chalk`{green Decrypted sucessfully!}`);
@@ -71,14 +70,13 @@ program
program program
.command("encrypt") .command("encrypt")
.description("encrypt the vault") .description("encrypt the vault")
.action(async () => { .option("-v, --vault <name>", "name of the vault to decrypt")
checkForFiles(); .action(async (args) => {
if (!args.vault) {
if (!existsSync(".confidant")) { args.vault = await getDecryptedName();
panic`The vault was not decrypted yet!`;
} }
await encrypt_diary(); await encrypt_vault(args.vault);
console.log(chalk`{green Successfully encrypted!}`); console.log(chalk`{green Successfully encrypted!}`);
}); });

View File

@@ -94,7 +94,7 @@ confidant.zip
writeFileSync(`.gitignore`, gitignore); writeFileSync(`.gitignore`, gitignore);
} }
export async function decrypt_diary(password: string, dirname: string) { export async function decrypt_vault(password: string, dirname: string) {
// Read and split the vault file // Read and split the vault file
const combined = readFileSync(`${dirname}.vault`); const combined = readFileSync(`${dirname}.vault`);
const index = combined.indexOf(separator); const index = combined.indexOf(separator);
@@ -130,17 +130,27 @@ export async function decrypt_diary(password: string, dirname: string) {
await $`unzip confidant.zip > /dev/null && rm confidant.zip`; await $`unzip confidant.zip > /dev/null && rm confidant.zip`;
} }
export async function encrypt_diary() { export async function encrypt_vault(dirname: string) {
const { dirname, key }: { dirname: string; key: string } = JSON.parse( const D = decrypt(
decrypt(readFileSync(".confidant"), buffer(env.AUTH_KEY)).toString("utf8"), readFileSync(`.${dirname}.confidant`),
buffer(env.AUTH_KEY),
); );
const D = buffer(key); // create zip file and encrypt it
await $`zip -r9 confidant.zip ${dirname} > /dev/null`; await $`zip -r9 confidant.zip ${dirname} > /dev/null`;
await $`rm -rf ${dirname}`; await $`rm -rf ${dirname}`;
const Z = readFileSync("confidant.zip"); const Z = readFileSync("confidant.zip");
const E_Z = encrypt_file(Z, D); const E_Z = encrypt_file(Z, D);
writeFileSync(`vault.ant`, E_Z);
await $`rm confidant.zip .confidant`; // read original vault file to get header data
const vaultfile = readFileSync(`${dirname}.vault`);
const index = vaultfile.indexOf(separator);
// write new data to vault
writeFileSync(
`${dirname}.vault`,
Buffer.concat([vaultfile.subarray(0, index), separator, E_Z]),
);
await $`rm confidant.zip .${dirname}.confidant`;
} }
export async function recovery(recoverystring: string) { export async function recovery(recoverystring: string) {

View File

@@ -4,7 +4,7 @@ import { generatePrivate, getPublic } from "eccrypto";
import { generate } from "random-words"; import { generate } from "random-words";
import chalk from "chalk-template"; import chalk from "chalk-template";
import { $ } from "bun"; import { $ } from "bun";
import { existsSync } from "fs"; import { existsSync, readdirSync } from "fs";
import { select } from "@inquirer/prompts"; import { select } from "@inquirer/prompts";
export function buffer(input: string): Buffer; export function buffer(input: string): Buffer;
@@ -106,6 +106,32 @@ export function print(key: string, value: string) {
console.log(chalk`{green ${key}:} {blue ${value}}`); console.log(chalk`{green ${key}:} {blue ${value}}`);
} }
export class Files {
data: string[] | null = null;
constructor(regex: RegExp | string) {
try {
const data = readdirSync(".").filter((x) => x.match(regex));
this.data = data ? data.map((x) => x.replace(regex, "$1")) : null;
} catch (error) {
console.error("Error executing command:", error);
this.data = null;
}
}
toString(): string {
return `[ ${this.data ? this.data.join(", ") : "empty"} ]`;
}
intersection(a: Files) {
return Array.from(new Set(this.data).intersection(new Set(a.data)));
}
difference(a: Files) {
return Array.from(new Set(this.data).difference(new Set(a.data)));
}
}
export async function getDirectoryNames() { export async function getDirectoryNames() {
const dirlist = (await $`ls -d */`.text()).trim(); const dirlist = (await $`ls -d */`.text()).trim();
@@ -147,12 +173,25 @@ export async function getVaultName() {
return; return;
} }
const keyList = (await $`ls *.key`.text())
.trim()
.match(/.*\.key/g) as string[];
if (!keyList) {
panic`No vaults with keys found in the current directory.`;
return;
}
const vaults = Array.from(
new Set(vaultList.map((x) => x.replace(".vault", ""))).intersection(
new Set(keyList.map((x) => x.replace(".key", ""))),
),
);
let files: string[]; let files: string[];
const decryptedList = (await $`bash -c "ls .*.confidant"`.text()) const decryptedList = (await $`bash -c "ls .*.confidant"`.text())
.trim() .trim()
.match(/\.(.*)\.confidant/g); .match(/\.(.*)\.confidant/g);
if (decryptedList) { if (decryptedList) {
const vaults = vaultList.map((x) => x.replace(".vault", ""));
const decs = decryptedList.map((x) => x.replace(/\.(.*)\.confidant/, "$1")); const decs = decryptedList.map((x) => x.replace(/\.(.*)\.confidant/, "$1"));
files = Array.from(new Set(vaults).difference(new Set(decs))); files = Array.from(new Set(vaults).difference(new Set(decs)));
} else { } else {
@@ -171,3 +210,31 @@ export async function getVaultName() {
}); });
return vault; return vault;
} }
export async function getDecryptedName() {
const dec = new Files(/\.(.*)\.confidant/g);
if (dec.data === null || dec.data.length === 0) {
panic`No decrypted vaults found.`;
}
const vaults = new Files(/(.*).vault/g);
if (vaults.data === null) {
panic`No vaults found.`;
}
const decrypted = dec.intersection(vaults);
if (decrypted.length === 1) {
return decrypted[0];
}
const vault = await select({
message: "Select vault to encrypt:",
choices: decrypted.map((x) => ({
name: x.replace(".vault", ""),
value: x.replace(".vault", ""),
})),
});
return vault;
}