Update legacy Electron configuration and build tasks

- Add legacy package.json
- Update Taskfile
This commit is contained in:
Sudo-Ivan
2026-01-14 18:00:02 -06:00
parent 1788aea0c2
commit d167d7c32e
3 changed files with 210 additions and 14 deletions
+32 -8
View File
@@ -289,27 +289,51 @@ tasks:
- task: build-appimage
electron-legacy:
desc: Install legacy Electron version
desc: Ensure legacy Electron version is available (will be downloaded by electron-builder if needed)
cmds:
- "{{.NPM}} install --no-save electron@{{.LEGACY_ELECTRON_VERSION}}"
- 'echo "Building with legacy Electron version: {{.LEGACY_ELECTRON_VERSION}}"'
build-appimage-legacy:
desc: Build Linux AppImage with legacy Electron version
deps: [build-frontend, electron-legacy]
cmds:
- "{{.NPM}} run electron-postinstall"
- "npx electron-builder install-app-deps --config package-legacy.json"
- "PLATFORM=linux {{.NPM}} run build-backend"
- "{{.NPM}} run dist -- --linux AppImage -c.extraMetadata.main=electron/main-legacy.js"
- "./scripts/rename_legacy_artifacts.sh"
- "npx electron-builder --config package-legacy.json --linux AppImage --publish=never"
build-exe-legacy:
desc: Build Windows portable executable with legacy Electron version
deps: [build-frontend, electron-legacy]
cmds:
- "{{.NPM}} run electron-postinstall"
- "npx electron-builder install-app-deps --config package-legacy.json"
- "PLATFORM=win32 {{.NPM}} run build-backend"
- "{{.NPM}} run dist -- --win portable -c.extraMetadata.main=electron/main-legacy.js"
- "./scripts/rename_legacy_artifacts.sh"
- "npx electron-builder --config package-legacy.json --win portable --publish=never"
build-exe-legacy-wine:
desc: Build Windows portable executable and NSIS installer using Wine (Legacy)
deps: [build-frontend, electron-legacy]
cmds:
- "npx electron-builder install-app-deps --config package-legacy.json"
- "PLATFORM=win32 PYTHON_CMD='{{.WINE_PYTHON}}' {{.NPM}} run build-backend"
- "npx electron-builder --config package-legacy.json --win portable nsis --publish=never"
build-legacy-all:
desc: Build all legacy Electron apps (Linux and Windows)
deps: [build-frontend, electron-legacy]
cmds:
- "npx electron-builder install-app-deps --config package-legacy.json"
- "PLATFORM=linux {{.NPM}} run build-backend"
- "PLATFORM=win32 {{.NPM}} run build-backend"
- "npx electron-builder --config package-legacy.json --linux AppImage deb --win portable nsis --publish=never"
build-legacy-all-wine:
desc: Build all legacy Electron apps (Linux + Windows via Wine)
deps: [build-frontend, electron-legacy]
cmds:
- "npx electron-builder install-app-deps --config package-legacy.json"
- "PLATFORM=linux {{.NPM}} run build-backend"
- "PLATFORM=win32 PYTHON_CMD='{{.WINE_PYTHON}}' {{.NPM}} run build-backend"
- "npx electron-builder --config package-legacy.json --linux AppImage deb --win portable nsis --publish=never"
forge-start:
desc: Run the application with Electron Forge
+118 -6
View File
@@ -1,15 +1,76 @@
const { app, BrowserWindow, dialog, ipcMain, shell, systemPreferences } = require("electron");
const {
app,
BrowserWindow,
dialog,
ipcMain,
shell,
systemPreferences,
Notification,
powerSaveBlocker,
} = require("electron");
const electronPrompt = require("electron-prompt");
const { spawn } = require("child_process");
const fs = require("fs");
const path = require("node:path");
const crypto = require("crypto");
// remember main window
var mainWindow = null;
// power save blocker id
var activePowerSaveBlockerId = null;
// remember child process for exe so we can kill it when app exits
var exeChildProcess = null;
// store integrity status
var integrityStatus = {
backend: { ok: true, issues: [] },
data: { ok: true, issues: [] },
};
function verifyBackendIntegrity(exeDir) {
const manifestPath = path.join(exeDir, "backend-manifest.json");
if (!fs.existsSync(manifestPath)) {
log("Backend integrity manifest missing, skipping check.");
return { ok: true, issues: ["Manifest missing"] };
}
try {
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
const issues = [];
const filesToVerify = manifest.files || manifest;
const metadata = manifest._metadata || {};
for (const [relPath, expectedHash] of Object.entries(filesToVerify)) {
const fullPath = path.join(exeDir, relPath);
if (!fs.existsSync(fullPath)) {
issues.push(`Missing: ${relPath}`);
continue;
}
const fileBuffer = fs.readFileSync(fullPath);
const actualHash = crypto.createHash("sha256").update(fileBuffer).digest("hex");
if (actualHash !== expectedHash) {
issues.push(`Modified: ${relPath}`);
}
}
if (issues.length > 0 && metadata.date && metadata.time) {
issues.unshift(`Backend build timestamp: ${metadata.date} ${metadata.time}`);
}
return {
ok: issues.length === 0,
issues: issues,
};
} catch (error) {
log(`Backend integrity check failed: ${error.message}`);
return { ok: false, issues: [error.message] };
}
}
// allow fetching app version via ipc
ipcMain.handle("app-version", () => {
return app.getVersion();
@@ -24,12 +85,43 @@ ipcMain.handle("is-hardware-acceleration-enabled", () => {
return true; // Assume true for older versions
});
// allow fetching integrity status (Stub for legacy)
// allow fetching integrity status
ipcMain.handle("get-integrity-status", () => {
return {
backend: { ok: true, issues: ["Not supported in legacy mode"] },
data: { ok: true, issues: ["Not supported in legacy mode"] },
};
return integrityStatus;
});
// Native Notification IPC
ipcMain.handle("show-notification", (event, { title, body, silent }) => {
const notification = new Notification({
title: title,
body: body,
silent: silent,
});
notification.show();
notification.on("click", () => {
if (mainWindow) {
mainWindow.show();
mainWindow.focus();
}
});
});
// Power Management IPC
ipcMain.handle("set-power-save-blocker", (event, enabled) => {
if (enabled) {
if (activePowerSaveBlockerId === null) {
activePowerSaveBlockerId = powerSaveBlocker.start("prevent-app-suspension");
log("Power save blocker started.");
}
} else {
if (activePowerSaveBlockerId !== null) {
powerSaveBlocker.stop(activePowerSaveBlockerId);
activePowerSaveBlockerId = null;
log("Power save blocker stopped.");
}
}
return activePowerSaveBlockerId !== null;
});
// ignore ssl errors
@@ -80,6 +172,19 @@ ipcMain.handle("relaunch", () => {
app.exit();
});
ipcMain.handle("relaunch-emergency", () => {
app.relaunch({ args: process.argv.slice(1).concat(["--emergency"]) });
app.exit();
});
ipcMain.handle("shutdown", () => {
quit();
});
ipcMain.handle("get-memory-usage", async () => {
return process.getProcessMemoryInfo();
});
// allow showing a file path in os file manager
ipcMain.handle("showPathInFolder", (event, path) => {
shell.showItemInFolder(path);
@@ -245,6 +350,13 @@ app.whenReady().then(async () => {
log(`Found executable at: ${exe}`);
// Verify backend integrity before spawning
const exeDir = path.dirname(exe);
integrityStatus.backend = verifyBackendIntegrity(exeDir);
if (!integrityStatus.backend.ok) {
log(`INTEGRITY WARNING: Backend tampering detected! Issues: ${integrityStatus.backend.issues.join(", ")}`);
}
try {
// arguments we always want to pass in
const requiredArguments = [
+60
View File
@@ -0,0 +1,60 @@
{
"appId": "com.sudoivan.reticulummeshchat-legacy",
"productName": "Reticulum MeshChatX Legacy",
"electronVersion": "30.0.8",
"extraMetadata": {
"main": "electron/main-legacy.js"
},
"asar": true,
"electronFuses": {
"runAsNode": false,
"enableCookieEncryption": true,
"enableNodeOptionsEnvironmentVariable": false,
"enableNodeCliInspectArguments": false,
"enableEmbeddedAsarIntegrityValidation": true,
"onlyLoadAppFromAsar": true
},
"files": ["electron/**/*"],
"directories": {
"buildResources": "electron/build"
},
"win": {
"artifactName": "ReticulumMeshChat-v${version}-legacy-${os}.${ext}",
"target": [
{
"target": "portable"
},
{
"target": "nsis"
}
],
"extraResources": [
{
"from": "build/exe/win32",
"to": "backend",
"filter": ["**/*"]
}
]
},
"linux": {
"artifactName": "ReticulumMeshChatX-v${version}-legacy-${os}.${ext}",
"target": ["AppImage", "deb"],
"maintainer": "Sudo-Ivan",
"category": "Network",
"extraResources": [
{
"from": "build/exe/linux",
"to": "backend",
"filter": ["**/*"]
}
]
},
"portable": {
"artifactName": "ReticulumMeshChatX-v${version}-legacy-${os}-portable.${ext}"
},
"nsis": {
"artifactName": "ReticulumMeshChatX-v${version}-legacy-${os}-installer.${ext}",
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
}