Upload via GUI (72 Dateien)

This commit is contained in:
2026-10-25 17:48:07 +00:00
parent e812dac9e4
commit 7b6403ceb0
7 changed files with 83 additions and 3 deletions
+43
View File
@@ -88,6 +88,49 @@ ipcMain.handle('api', async (_e, req) => {
} catch (e) { return { error: { status: e.status, code: e.code, message: e.message || String(e) } }; }
});
// ─── Programm-Update (Version und Setup kommen vom DeskHub-Server, Quelle ist die Plugin-Webseite) ──────────
const verParts = (v) => String(v).split(/[-+]/)[0].split('.').map((n) => parseInt(n, 10) || 0);
function isNewer(remote, local) {
const a = verParts(remote), b = verParts(local);
for (let i = 0; i < Math.max(a.length, b.length); i++) { if ((a[i] || 0) !== (b[i] || 0)) return (a[i] || 0) > (b[i] || 0); }
return false;
}
let pendingUpdate = null;
ipcMain.handle('update:check', async () => {
try {
const r = await callApi({ path: 'app_update.php', query: { platform: 'windows' } });
const d = r.data;
if (!d?.available || !d.version) return { data: { available: false, current: app.getVersion() } };
pendingUpdate = d;
return { data: { available: isNewer(d.version, app.getVersion()), version: d.version, notes: d.notes || '', size: d.size || 0, current: app.getVersion(), packaged: app.isPackaged } };
} catch (e) { return { error: { message: e.message || String(e) } }; }
});
ipcMain.handle('update:install', async () => {
if (!pendingUpdate || !session) return { error: { message: 'Keine Update-Information vorhanden.' } };
try {
const url = new URL(`${session.serverUrl}/api/staff/v1/app_update.php`);
url.searchParams.set('platform', 'windows'); url.searchParams.set('download', '1');
const res = await fetch(url, { headers: { Authorization: `Bearer ${session.token}`, 'X-DeskHub-Authorization': `Bearer ${session.token}` } });
if (!res.ok) return { error: { message: `Download fehlgeschlagen (${res.status}).` } };
const dir = fs.mkdtempSync(path.join(app.getPath('temp'), 'deskhub-update-'));
const file = path.join(dir, 'DeskHub-Setup.exe');
const out = fs.createWriteStream(file);
const hash = require('crypto').createHash('sha256');
const total = Number(res.headers.get('content-length')) || pendingUpdate.size || 0;
let got = 0;
for await (const chunk of res.body) {
hash.update(chunk); got += chunk.length;
if (!out.write(chunk)) await new Promise((ok) => out.once('drain', ok));
win?.webContents.send('update-progress', total ? Math.min(99, Math.round((got / total) * 100)) : 0);
}
await new Promise((ok, fail) => out.end((err) => (err ? fail(err) : ok())));
if (hash.digest('hex') !== String(pendingUpdate.sha256).toLowerCase()) { try { fs.rmSync(dir, { recursive: true, force: true }); } catch {} return { error: { message: 'Die heruntergeladene Datei ist beschädigt (Prüfsumme stimmt nicht). Bitte erneut versuchen.' } }; }
require('child_process').spawn(file, [], { detached: true, stdio: 'ignore' }).unref();
setTimeout(() => { quitting = true; app.quit(); }, 500);
return { data: true };
} catch (e) { return { error: { message: e.message || String(e) } }; }
});
// Seite der Weboberfläche im Standardbrowser öffnen: Der Server gibt eine einmalige Anmelde-Adresse (und prüft dabei die Rechte)
ipcMain.handle('web:open', async (_e, { path: p }) => {
if (typeof p !== 'string' || !p.startsWith('/staff/') || p.length > 200) return { error: { message: 'Ungültige Seite.' } };