54 lines
1.4 KiB
TypeScript
54 lines
1.4 KiB
TypeScript
|
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||
|
|
import { dirname, join } from "node:path";
|
||
|
|
|
||
|
|
import { app, safeStorage } from "electron/main";
|
||
|
|
|
||
|
|
type VaultStore = Record<string, string>;
|
||
|
|
|
||
|
|
function vaultPath(): string {
|
||
|
|
return join(app.getPath("userData"), "desktop-vault.json");
|
||
|
|
}
|
||
|
|
|
||
|
|
function loadStore(): VaultStore {
|
||
|
|
try {
|
||
|
|
return JSON.parse(readFileSync(vaultPath(), "utf8")) as VaultStore;
|
||
|
|
} catch {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function persistStore(store: VaultStore): void {
|
||
|
|
const target = vaultPath();
|
||
|
|
mkdirSync(dirname(target), { recursive: true });
|
||
|
|
writeFileSync(target, JSON.stringify(store, null, 2), "utf8");
|
||
|
|
}
|
||
|
|
|
||
|
|
export function describeVaultBackend() {
|
||
|
|
return {
|
||
|
|
encryptionAvailable: safeStorage.isEncryptionAvailable(),
|
||
|
|
backend:
|
||
|
|
typeof safeStorage.getSelectedStorageBackend === "function"
|
||
|
|
? safeStorage.getSelectedStorageBackend()
|
||
|
|
: "unknown",
|
||
|
|
path: vaultPath(),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function writeEncrypted(key: string, value: string): void {
|
||
|
|
if (!safeStorage.isEncryptionAvailable()) {
|
||
|
|
throw new Error("safeStorage encryption is unavailable");
|
||
|
|
}
|
||
|
|
|
||
|
|
const store = loadStore();
|
||
|
|
store[key] = safeStorage.encryptString(value).toString("base64");
|
||
|
|
persistStore(store);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function readEncrypted(key: string): string | null {
|
||
|
|
const encoded = loadStore()[key];
|
||
|
|
if (!encoded) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return safeStorage.decryptString(Buffer.from(encoded, "base64"));
|
||
|
|
}
|