File size: 1,485 Bytes
d76f93d
 
 
 
0a536c9
2200342
d76f93d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { promises as fs } from "fs";
import path from "path";
import { encryptWithAlphabet, decryptWithAlphabet } from "./caesar-cipher";

// Use path relative to project root, works in both dev and production
const dataDir = path.join(__dirname, "../../src/data/encrypted/");
const keyFile = path.join(dataDir, ".encryption_key");

const MASTER_KEY = process.env.MASTER_KEY || "RSIOT_SECRET_LAB7";

export async function ensureDataDir(): Promise<void> {
   try {
      await fs.access(dataDir);
   } catch {
      await fs.mkdir(dataDir, { recursive: true });
   }
}

export async function getOrCreateKey(): Promise<string> {
   await ensureDataDir();

   try {
      const encryptedKey = await fs.readFile(keyFile, "utf-8");
      return decryptWithAlphabet(encryptedKey, MASTER_KEY);
   } catch (err: any) {
      if (err.code === "ENOENT") {
         const newKey = generateRandomKey(16);
         await saveKey(newKey);
         return newKey;
      }
      throw err;
   }
}

export async function saveKey(key: string): Promise<void> {
   await ensureDataDir();
   const encryptedKey = encryptWithAlphabet(key, MASTER_KEY);
   await fs.writeFile(keyFile, encryptedKey, "utf-8");
}

export function generateRandomKey(length: number): string {
   const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
   let key = "";
   for (let i = 0; i < length; i++) {
      key += chars.charAt(Math.floor(Math.random() * chars.length));
   }
   return key;
}