CH-J Toolsġestjoni tas-server fuq SSH
Menu
Sors ippubblikat

CH-J Tools

direttorji browse u fajls għal rilaxx applikazzjoni speċifika.

Sors ta' tniżżil ZIP
CH-J / Server Manager 406 fajls
core-20261024T135205Z-7c487d719de2 Miżjud: · Buillt:
smokeKeyGeneratorUi.js Miżjud: Data mhux irreġistrata 6.7 KB · 80 linji
Kodiċi Fajl tat-tniżżil
1"use strict";
2// Electron UI check of chj.key-generator with the real plugin runtime, preload and KeyGeneratorService inside
3// Electron (BoringSSL): DSA (legacy) in all formats and the password generator incl. copy to the clipboard.
4// Run (VS Code terminal): env -u ELECTRON_RUN_AS_NODE npx electron scripts/smokeKeyGeneratorUi.js [screenshot-dir]
5const { app, BrowserWindow, clipboard, ipcMain, protocol } = require("electron");
6const assert = require("node:assert/strict");
7const fs = require("node:fs");
8const os = require("node:os");
9const path = require("node:path");
10const { hardenSession } = require("../src/main/bootstrap/createMainWindow");
11const { PluginRegistry } = require("../src/main/plugins/pluginRegistry");
12const { PluginRuntime } = require("../src/main/plugins/pluginRuntime");
13const { KeyGeneratorService } = require("../src/main/keys/keyGeneratorService");
15const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-keygen-ui-"));
16const shots = process.argv.find((arg, index) => index > 1 && !arg.startsWith("-") && !arg.endsWith(".js")) || null;
17app.setPath("userData", root);
18protocol.registerSchemesAsPrivileged([{ scheme: "chj-plugin", privileges: { standard: true, secure: true, supportFetchAPI: true } }]);
19const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
20const errors = [];
21let window;
22const js = (source) => window.webContents.executeJavaScript(source);
23async function until(source, timeout = 30000) {
24 const started = Date.now();
25 while (Date.now() - started < timeout) { if (await js(`(() => { try { return (${source}); } catch { return false; } })()`)) return; await delay(50); }
26 throw new Error(`UI condition timed out: ${source}\nstatus: ${await js("document.querySelector('#status').textContent")}`);
28async function shot(name) { if (shots) { fs.mkdirSync(shots, { recursive: true }); fs.writeFileSync(path.join(shots, `${name}.png`), (await window.webContents.capturePage()).toPNG()); } }
30async function run() {
31 await app.whenReady(); hardenSession();
32 const registry = new PluginRegistry(root, null, { bundledRoot: path.join(__dirname, "../src/main/firstPartyPlugins") });
33 const runtime = new PluginRuntime({ BrowserWindow, registry, keyGeneratorService: new KeyGeneratorService({ writeClipboard: (text) => clipboard.writeText(text) }), preload: path.join(__dirname, "../src/preload/pluginPreload.js"), getMainWindow: () => null, isVaultUnlocked: () => true });
34 runtime.registerIpc(ipcMain);
35 runtime.open("chj.key-generator");
36 window = runtime.windows.get("chj.key-generator");
37 window.webContents.on("console-message", (event) => { if (event.level === "error") errors.push(event.message); });
38 window.setSize(1100, 1250);
39 await until("document.querySelector('#pluginVersion').textContent.includes('Key Generator')");
40 // DSA (legacy) inside Electron, all private key formats.
41 await js("document.querySelector('#keyType').value = 'dsa'; document.querySelector('#keyType').dispatchEvent(new Event('change'))");
42 await js("document.querySelector('#generatorForm').requestSubmit()");
43 await until("document.querySelector('#status').classList.contains('error')");
44 assert.match(await js("document.querySelector('#status').textContent"), /confirmation/, "legacy needs explicit confirmation");
45 await js("document.querySelector('#legacyConfirmed').checked = true");
46 for (const [format, pattern] of [["openssh", "BEGIN OPENSSH PRIVATE KEY"], ["pem", "BEGIN PRIVATE KEY"], ["ppk", "PuTTY-User-Key-File-2: ssh-dss"]]) {
47 await js(`document.querySelector('#privateKey').value = ''; document.querySelector('#keyFormat').value = '${format}'; document.querySelector('#generatorForm').requestSubmit()`);
48 await until(`document.querySelector('#privateKey').value.includes(${JSON.stringify(pattern)})`);
49 assert.equal(await js("document.querySelector('#status').classList.contains('error')"), false);
50 assert.match(await js("document.querySelector('#publicKey').value"), /^ssh-dss AAAAB3NzaC1kc3M/);
51 }
52 await shot("k01-dsa");
53 // Password generator: grouped xxxx-yyyy-cccc-vvvv- with special characters, then copy.
54 await js("document.querySelector('#passwordLength').value = '20'; document.querySelector('#passwordLength').dispatchEvent(new Event('input')); document.querySelector('#pwSpecial').checked = true; document.querySelector('#pwGrouped').checked = true; document.querySelector('#passwordForm').requestSubmit()");
55 await until("document.querySelector('#passwordOutput').value.length === 20");
56 const grouped = await js("document.querySelector('#passwordOutput').value");
57 assert.match(grouped, /^[^-]{4}-[^-]{4}-[^-]{4}-[^-]{4}-$/u, grouped);
58 assert.equal(await js("document.querySelector('#passwordLengthRange').value"), "20", "slider follows the number field");
59 clipboard.writeText("before");
60 await js("document.querySelector('#copyPasswordButton').click()");
61 // The runtime reports English (default without a configured language): the plugin follows the app language.
62 await until("document.querySelector('#status').textContent.includes('copied to the clipboard')");
63 assert.equal(clipboard.readText(), grouped, "copied to the system clipboard");
64 clipboard.writeText("");
65 await js("document.querySelector('#pwGrouped').checked = false; document.querySelector('#passwordLength').value = '70'; document.querySelector('#passwordForm').requestSubmit()");
66 await until("document.querySelector('#passwordOutput').value.length === 70");
67 // 71: the form refuses it (max=70) and Core refuses it independently.
68 await js("document.querySelector('#passwordLength').value = '71'");
69 assert.equal(await js("document.querySelector('#passwordForm').checkValidity()"), false);
70 assert.match(await js("window.chjPlugin.keys.password({ length: 71, upper: true }).then(() => 'accepted', (error) => error.message)"), /4-70/);
71 assert.match(await js("window.chjPlugin.keys.copyPassword('00000000-0000-0000-0000-000000000000').then(() => 'copied', (error) => error.message)"), /expired/, "only generated passwords can be copied");
72 await js("document.querySelector('#passwordLength').value = '24'; document.querySelector('#pwGrouped').checked = true; document.querySelector('#passwordForm').requestSubmit()");
73 await until("document.querySelector('#passwordOutput').value.length === 24");
74 await shot("k02-password");
75 assert.deepEqual(errors, []);
76 console.log("CHJ_KEYGEN_UI_OK: DSA openssh/pem/ppk in Electron, legacy confirmation, password 20 grouped (every 5th char a dash)/70/invalid 71, copy to clipboard");
78function finish(code) { for (const window of BrowserWindow.getAllWindows()) window.destroy(); try { fs.rmSync(root, { recursive: true, force: true }); } catch {} app.exit(code); }
79run().then(() => finish(0), (error) => { console.error(error); finish(1); });
80setTimeout(() => { console.error("Key generator UI smoke exceeded 90s"); finish(1); }, 90000).unref();
SHA-256992e46c1fe0f47843672506ddfbc03eeae22784b05c488eea48e20c2d31e05f0

CH-J Proprietary Software License 1.14 · Sors huwa pprovdut taħt iż-CH-J Proprietary Software License 1.14. Id-disponibbiltà tagħha ma tibdilx it-termini tal-liċenzja jew tagħti drittijiet addizzjonali.

Archive SHA-256476ed8aef0f1e96a5acdf223127b6692acdf4492eeaf5d0816b6e2a634fbbda6
Fajls