feat: Windows download link + self-served update feed + install tracking
Downloads/updates: - config: DOWNLOADS_DIR (override to a mounted volume in prod). - static.js: serves /downloads/* (installer, latest.yml, .blockmap) with range support for resumable + differential auto-updates; /download/windows redirects to the current .exe (stable link). Landing page gets a "Download the Windows desktop app" button (hidden in-app). Install tracking (who installed the app): - db app_installs + repos.appInstalls (upsert by install_id, fills in the user on sign-in). - POST /api/v1/telemetry/install (records install + user once authenticated); GET /api/v1/admin/installs (admin: list installs with user/version/os/last-seen). - desktop main.js: stable per-install id in userData, exposed via preload (bizConnectNative.installId/version/os); home.html reportInstall() posts it after login. - e2e: +2 checks (telemetry recorded, admin sees it). 119/119. build batch20. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,25 @@
|
||||
// Server origin is configurable so the same build works against prod or a dev server.
|
||||
const { app, BrowserWindow, session, desktopCapturer, shell, Menu, ipcMain, nativeImage } = require('electron');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const crypto = require('crypto');
|
||||
|
||||
// A stable per-install id (persisted in userData), so the server can count installs and
|
||||
// associate them with the user who signs in. Created once, then reused across launches.
|
||||
function getInstallId() {
|
||||
try {
|
||||
const p = path.join(app.getPath('userData'), 'install-id');
|
||||
if (fs.existsSync(p)) { const v = fs.readFileSync(p, 'utf8').trim(); if (v) return v; }
|
||||
const id = crypto.randomUUID();
|
||||
fs.writeFileSync(p, id);
|
||||
return id;
|
||||
} catch (_) { return 'unknown'; }
|
||||
}
|
||||
// The renderer (web app) reads this synchronously to report telemetry after login.
|
||||
ipcMain.on('get-install-info', (e) => {
|
||||
e.returnValue = { installId: getInstallId(), appVersion: app.getVersion(), os: process.platform + ' ' + os.release() };
|
||||
});
|
||||
// Auto-update: only NATIVE shell changes (this .exe) need this — all web/UI changes arrive
|
||||
// live from the server. Checks the self-hosted feed (publish config in package.json →
|
||||
// https://remote.bizgaze.com/downloads/latest.yml), downloads in the background, and installs
|
||||
|
||||
Reference in New Issue
Block a user