Δημοσίευση πηγής
Κατεβάστε την πηγή ZIP
CH-J Tools
Περιηγηθείτε σε καταλόγους και αρχεία για μια συγκεκριμένη έκδοση εφαρμογών.
CH-J / Server Manager
406 αρχεία
core-20261024T135205Z-7c487d719de2
Προστέθηκε: · Χτισμένο:
1
"use strict";2
// Electron UI check of chj.key-generator with the real plugin runtime, preload and KeyGeneratorService inside3
// 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]5
const { app, BrowserWindow, clipboard, ipcMain, protocol } = require("electron");6
const assert = require("node:assert/strict");7
const fs = require("node:fs");8
const os = require("node:os");9
const path = require("node:path");10
const { hardenSession } = require("../src/main/bootstrap/createMainWindow");11
const { PluginRegistry } = require("../src/main/plugins/pluginRegistry");12
const { PluginRuntime } = require("../src/main/plugins/pluginRuntime");13
const { KeyGeneratorService } = require("../src/main/keys/keyGeneratorService");15
const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-keygen-ui-"));16
const shots = process.argv.find((arg, index) => index > 1 && !arg.startsWith("-") && !arg.endsWith(".js")) || null;17
app.setPath("userData", root);18
protocol.registerSchemesAsPrivileged([{ scheme: "chj-plugin", privileges: { standard: true, secure: true, supportFetchAPI: true } }]);19
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));20
const errors = [];21
let window;22
const js = (source) => window.webContents.executeJavaScript(source);23
async 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")}`);27
}28
async function shot(name) { if (shots) { fs.mkdirSync(shots, { recursive: true }); fs.writeFileSync(path.join(shots, `${name}.png`), (await window.webContents.capturePage()).toPNG()); } }30
async 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");77
}78
function finish(code) { for (const window of BrowserWindow.getAllWindows()) window.destroy(); try { fs.rmSync(root, { recursive: true, force: true }); } catch {} app.exit(code); }79
run().then(() => finish(0), (error) => { console.error(error); finish(1); });80
setTimeout(() => { console.error("Key generator UI smoke exceeded 90s"); finish(1); }, 90000).unref();SHA-256
992e46c1fe0f47843672506ddfbc03eeae22784b05c488eea48e20c2d31e05f0CH-J Proprietary Software License 1.14 · Η πηγή παρέχεται στο CH-J Proprietary Software License 1.14. Η διαθεσιμότητά του δεν αλλάζει τους όρους της άδειας χρήσης ούτε χορηγεί πρόσθετα δικαιώματα.
Archive SHA-256
476ed8aef0f1e96a5acdf223127b6692acdf4492eeaf5d0816b6e2a634fbbda6