mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
* feat: AI translations at release, 7 new languages and regional fallback * fix: proper plural forms for count strings and full translations * fix: plural forms for selected, hidden and active counts * fix: synced plugin updates failing on desktop and server-only plugins shown as stopped * fix: restore rounded corners on app icons and favicon * feat: desktop app auto updates with automatic, ask first or never modes * feat: community and custom plugin registries * feat: plugin guide for AI tools in the SDK with a lint check * fix: keep the terminal WebSocket open past nginx's 60s default (#1588) * chore: update changelog * feat: show plugin download counts only and stop CI builds inflating them * feat: hide installed plugins in the browse tab by default * chore: pin bundled plugins to latest releases * chore: update translations * fix: focusing a saved password field and saving no longer erases it * fix: tell desktop users when their 2.8 data needs 2.9 first * fix: point windows update info at the x64 installer * fix: keep desktop client tunnel sockets alive behind proxies * chore: pin bundled plugins to latest releases * fix: cover client tunnel keepalive in the c2s runtime tests * fix: typing after opening a host no longer goes to the host search * fix: accept tab and = separators in SSH config import (#1598) * chore: update changelog * chore: drop plugin versions from core changelog * chore: update translations * chore: lint, format, and bump version to 26.10.1 --------- Co-authored-by: Darnel Hunter <68697450+innotelinc@users.noreply.github.com> Co-authored-by: Iain <Iain1970@protonmail.com>
81 lines
2.1 KiB
JavaScript
81 lines
2.1 KiB
JavaScript
// Desktop-only settings kept next to the app's data, and the server address
|
|
// older versions saved, so linking can offer it again.
|
|
|
|
const { app } = require("electron");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
function dataPath(filename) {
|
|
return path.join(app.getPath("userData"), filename);
|
|
}
|
|
|
|
function readJson(filePath, fallback) {
|
|
try {
|
|
if (!fs.existsSync(filePath)) return fallback;
|
|
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
function writeJson(filePath, value) {
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
const temporaryPath = `${filePath}.${process.pid}-${Date.now()}.tmp`;
|
|
try {
|
|
fs.writeFileSync(temporaryPath, JSON.stringify(value, null, 2), {
|
|
mode: 0o600,
|
|
});
|
|
fs.renameSync(temporaryPath, filePath);
|
|
} catch (error) {
|
|
fs.rmSync(temporaryPath, { force: true });
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
const DEFAULTS = { defaultConnectionOrigin: "local", updateMode: "prompt" };
|
|
|
|
function getDesktopSettings() {
|
|
return { ...DEFAULTS, ...readJson(dataPath("desktop-settings.json"), {}) };
|
|
}
|
|
|
|
function saveDesktopSettings(settings) {
|
|
writeJson(dataPath("desktop-settings.json"), {
|
|
...getDesktopSettings(),
|
|
...settings,
|
|
});
|
|
return { success: true };
|
|
}
|
|
|
|
// The server a 2.8 or older desktop was pointed at, if any.
|
|
function getPreviousServerUrl() {
|
|
for (const file of ["remote-sync-config.json", "server-config.json"]) {
|
|
const config = readJson(dataPath(file), null);
|
|
if (config && typeof config.serverUrl === "string" && config.serverUrl) {
|
|
return config.serverUrl;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// The old sync engine's session and cursors are useless to the new one,
|
|
// and the session is a credential, so they go.
|
|
function removeOldSyncFiles() {
|
|
for (const file of [
|
|
"remote-sync-credential.json",
|
|
"remote-sync-state.json",
|
|
]) {
|
|
try {
|
|
fs.rmSync(dataPath(file), { force: true });
|
|
} catch {
|
|
// Best effort.
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
getDesktopSettings,
|
|
saveDesktopSettings,
|
|
getPreviousServerUrl,
|
|
removeOldSyncFiles,
|
|
};
|