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,5 KB · 68 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 { utils: sshUtils } = require("ssh2");
9const { KeyGeneratorService } = require("../src/main/keys/keyGeneratorService");
11test("key generator creates modern and explicitly confirmed legacy key pairs", () => {
12 const service = new KeyGeneratorService();
13 for (const input of [
14 { type: "ed25519" }, { type: "rsa", bits: 2048 }, { type: "ecdsa", bits: 256 },
15 { type: "dsa", bits: 1024, legacyConfirmed: true }, { type: "rsa1", bits: 1024, legacyConfirmed: true }
16 ]) {
17 const generated = service.generate({ ...input, comment: "test@core" });
18 if (input.type === "rsa1") assert.match(generated.privateKey, /^PuTTY-User-Key-File-2: ssh1-rsa/);
19 else assert.match(generated.privateKey, /BEGIN PRIVATE KEY/);
20 assert.ok(generated.publicKey.length > 40);
21 assert.equal(Object.prototype.hasOwnProperty.call(generated, "passphrase"), false);
22 }
23 assert.throws(() => service.generate({ type: "dsa" }), /explicit confirmation/);
24 assert.throws(() => service.generate({ type: "rsa1" }), /explicit confirmation/);
25});
27test("key generator exports OpenSSH, PEM and PPK formats and reports safe passphrase fallback", () => {
28 const service = new KeyGeneratorService();
29 for (const input of [
30 { type: "ed25519", privateKeyFormat: "openssh" },
31 { type: "rsa", bits: 2048, privateKeyFormat: "openssh" },
32 { type: "ecdsa", bits: 256, privateKeyFormat: "openssh" },
33 { type: "dsa", bits: 1024, privateKeyFormat: "openssh", legacyConfirmed: true }
34 ]) {
35 const generated = service.generate(input);
36 assert.equal(generated.privateKeyFormat, "openssh");
37 assert.match(generated.privateKey, /^-----BEGIN OPENSSH PRIVATE KEY-----/);
38 assert.match(generated.publicKeyOpenSsh, /^(ssh-|ecdsa-)/);
39 const parsed = sshUtils.parseKey(generated.privateKey);
40 assert.equal(parsed instanceof Error, false, parsed?.message);
41 }
42 for (const input of [
43 { type: "ed25519" }, { type: "rsa", bits: 2048 }, { type: "ecdsa", bits: 256 },
44 { type: "dsa", legacyConfirmed: true }, { type: "rsa1", legacyConfirmed: true }
45 ]) {
46 const generated = service.generate({ ...input, privateKeyFormat: "ppk" });
47 assert.equal(generated.privateKeyFormat, "ppk");
48 assert.match(generated.privateKey, /^PuTTY-User-Key-File-2: /);
49 assert.match(generated.privateKey, /\nPrivate-MAC: [a-f0-9]{40}\n$/);
50 }
51 const fallback = service.generate({ type: "ed25519", privateKeyFormat: "openssh", passphrase: "secret" });
52 assert.equal(fallback.privateKeyFormat, "pem");
53 assert.match(fallback.privateKey, /BEGIN ENCRYPTED PRIVATE KEY/);
54 assert.match(fallback.notice, /šifrovaný PEM/);
55});
57test("key generator saves only a selected generated pair with restrictive private mode", async (t) => {
58 const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-keys-"));
59 t.after(() => fs.rmSync(root, { recursive: true, force: true }));
60 const target = path.join(root, "id_ed25519");
61 const service = new KeyGeneratorService({ selectSavePath: async () => ({ canceled: false, path: target }) });
62 const generated = service.generate({ type: "ed25519" });
63 const saved = await service.save(generated.generationId);
64 assert.equal(saved.privatePath, target);
65 assert.match(fs.readFileSync(target, "utf8"), /BEGIN PRIVATE KEY/);
66 assert.match(fs.readFileSync(`${target}.pub`, "utf8"), /^ssh-ed25519 /);
67 if (process.platform !== "win32") assert.equal(fs.statSync(target).mode & 0o777, 0o600);
68});

SHA-256: 6d25cd1cb38a63de307b530195a88ad52c7f337391401429fe12935ca81b0f34

Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0