CH-J Server Managerserver management over SSH
Menu
Published source

CH-J Server Manager

Browse directories and files for a specific application release.

Download source ZIP
CH-J Proprietary Software License 1.14

Source is provided under the CH-J Proprietary Software License 1.14. Its availability does not change the license terms or grant additional rights.

3,4 KB · 73 linesDownload file
1"use strict";
3const test = require("node:test");
4const assert = require("node:assert/strict");
5const fs = require("node:fs");
6const os = require("node:os");
7const path = require("node:path");
8const { VaultStore, validatePassword } = require("../src/main/security/vaultStore");
10test("vault password accepts 4 to 64 characters", () => {
11 assert.equal(validatePassword("1234"), "1234");
12 assert.equal(validatePassword(" "), " ");
13 assert.equal(validatePassword("🔐".repeat(64)), "🔐".repeat(64));
14 assert.throws(() => validatePassword("123"), /4 to 64/);
15 assert.throws(() => validatePassword("x".repeat(65)), /4 to 64/);
16});
18test("vault preserves and unlocks a four-space password", async (t) => {
19 const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-vault-spaces-"));
20 t.after(() => fs.rmSync(root, { recursive: true, force: true }));
21 const vault = new VaultStore(root);
23 await vault.create(" ");
24 assert.equal(vault.lock().unlocked, false);
25 assert.equal((await vault.unlock(" ")).unlocked, true);
26});
28test("vault encrypts data and only unlocks with the correct password", async (t) => {
29 const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-vault-"));
30 t.after(() => fs.rmSync(root, { recursive: true, force: true }));
31 const vault = new VaultStore(root);
33 assert.equal(vault.status().needsSetup, true);
34 const created = await vault.create("correct horse battery staple");
35 assert.deepEqual({ initialized: created.initialized, needsSetup: created.needsSetup, unlocked: created.unlocked }, {
36 initialized: true, needsSetup: false, unlocked: true
37 });
38 vault.update((data) => data.profiles.push({ id: "secret-profile", label: "Hidden server" }));
40 const encrypted = fs.readFileSync(path.join(root, "vault", "core-v1.data.json"), "utf8");
41 assert.doesNotMatch(encrypted, /Hidden server|secret-profile/);
42 assert.equal(vault.lock().unlocked, false);
43 await assert.rejects(() => vault.unlock("wrong password"), { code: "VAULT_UNLOCK_FAILED" });
44 assert.equal(vault.status().unlocked, false);
45 await vault.unlock("correct horse battery staple");
46 assert.equal(vault.getData().profiles[0].label, "Hidden server");
47});
49test("vault refuses to overwrite an incomplete vault", async (t) => {
50 const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-vault-"));
51 t.after(() => fs.rmSync(root, { recursive: true, force: true }));
52 fs.mkdirSync(path.join(root, "vault"), { recursive: true });
53 fs.writeFileSync(path.join(root, "vault", "core-v1.meta.json"), "{}");
54 const vault = new VaultStore(root);
55 assert.equal(vault.status().damaged, true);
56 await assert.rejects(() => vault.create("correct horse battery staple"), /incomplete/);
57});
59test("vault reset requires confirmation, deletes protected data and returns to setup", async (t) => {
60 const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-vault-"));
61 t.after(() => fs.rmSync(root, { recursive: true, force: true }));
62 const vault = new VaultStore(root);
63 await vault.create("1234");
64 vault.update((data) => data.profiles.push({ id: "to-delete", label: "Deleted" }));
66 assert.throws(() => vault.reset("wrong"), { code: "VAULT_RESET_CONFIRMATION_REQUIRED" });
67 assert.equal(vault.status().initialized, true);
68 assert.deepEqual(vault.reset("SMAZAT"), { initialized: false, needsSetup: true, damaged: false, unlocked: false });
69 assert.equal(fs.existsSync(path.join(root, "vault")), false);
71 await vault.create("new-password");
72 assert.deepEqual(vault.getData().profiles, []);
73});

SHA-256: 66b46ab48bee66e70ff1119a22b5bd06c438584dcb7ca7488f6c5e6ecedbd655

Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0