mirror of
https://github.com/dream-pep/koring-launcher.git
synced 2026-09-12 05:45:18 +08:00
feat(更新模块): 提升更新安装安全性并添加统一主进程日志
重构更新验证流程:下载包验证失败时保持为已下载状态并标记校验未通过,而非直接置为错误状态 添加安装校验未通过包时的确认弹窗,支持删除异常安装包 禁用应用退出时自动安装,防止静默安装未校验的包 新增统一主进程日志模块,支持渲染进程通过IPC桥接接入日志 更新已下载但校验失败的UI提示文案
This commit is contained in:
+54
-13
@@ -189,7 +189,9 @@ class UpdateService {
|
||||
}
|
||||
|
||||
autoUpdater.autoDownload = false;
|
||||
autoUpdater.autoInstallOnAppQuit = true;
|
||||
// 安装一律走我们受控的 quitAndInstall(含核验与确认弹窗),
|
||||
// 禁止 electron-updater 在退出时静默自动安装(否则未核验/核验失败的包可能被直接装上)
|
||||
autoUpdater.autoInstallOnAppQuit = false;
|
||||
this.applyChannel();
|
||||
autoUpdater.logger = console;
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
@@ -220,16 +222,18 @@ class UpdateService {
|
||||
this.progress = p;
|
||||
this.emit();
|
||||
});
|
||||
// 下载完成 → 本地核验安装包(sha512 + 大小)通过后才置为"已下载可安装";
|
||||
// 核验失败 → 进入 error,拒绝安装(防下载损坏 / 篡改)
|
||||
// 下载完成 → 本地核验安装包(sha512 + 大小)。
|
||||
// · 通过:进入"已下载可安装"(verified=true)
|
||||
// · 失败:仍进入"已下载",但 verified=false + 记录原因 —— 点"安装"会弹确认框
|
||||
// (继续安装 / 取消并删除安装包),绝不静默安装未核验包
|
||||
autoUpdater.on('update-downloaded', async (info) => {
|
||||
const errMsg = await this.verifyDownloadedPackage();
|
||||
if (errMsg) {
|
||||
console.error(`[updater] 安装包核验失败: ${errMsg}`);
|
||||
this.state = 'error';
|
||||
this.error = errMsg;
|
||||
this.version = undefined;
|
||||
this.state = 'downloaded';
|
||||
this.verified = false;
|
||||
this.version = info.version;
|
||||
this.error = errMsg;
|
||||
this.emit();
|
||||
return;
|
||||
}
|
||||
@@ -237,6 +241,7 @@ class UpdateService {
|
||||
this.state = 'downloaded';
|
||||
this.verified = true;
|
||||
this.version = info.version;
|
||||
this.error = undefined;
|
||||
this.emit();
|
||||
});
|
||||
autoUpdater.on('error', (err: Error) => {
|
||||
@@ -680,17 +685,42 @@ class UpdateService {
|
||||
/**
|
||||
* 退出并安装(NSIS 静默安装,安装完成自动重启)。
|
||||
* 安装状态先写入配置并立即落盘,避免退出时 debounce 未写盘。
|
||||
* 安装包未通过核验(verified=false)时先弹确认框:
|
||||
* 继续安装 / 取消并删除安装包 —— 绝不静默安装校验异常的文件。
|
||||
*/
|
||||
quitAndInstall(): void {
|
||||
async quitAndInstall(): Promise<void> {
|
||||
if (!this.ready || this.state !== 'downloaded') return;
|
||||
// 安装前必须已通过本地核验(sha512 + 大小),防损坏/篡改包被安装
|
||||
|
||||
if (!this.verified) {
|
||||
console.warn('[updater] 安装被拒:安装包未通过核验');
|
||||
this.state = 'error';
|
||||
this.error = '安装包未通过核验,已拒绝安装,请重新检查并下载更新';
|
||||
this.emit();
|
||||
return;
|
||||
const { dialog, BrowserWindow } = electron;
|
||||
const parent = BrowserWindow.getAllWindows().find((w) => w.isVisible()) ?? null;
|
||||
const opts: electron.MessageBoxOptions = {
|
||||
type: 'warning',
|
||||
title: '版本校验异常',
|
||||
message: '请注意,版本校验异常,可能是文件损坏或者被替换,因此您会看到此弹窗,您可以选择继续安装或取消并删除安装包',
|
||||
detail: this.error ? `核验详情:${this.error}` : '核验详情:sha512 校验和与发布记录不一致',
|
||||
buttons: ['继续安装', '取消并删除安装包'],
|
||||
defaultId: 1,
|
||||
cancelId: 1,
|
||||
noLink: true,
|
||||
};
|
||||
const { response } = parent
|
||||
? await dialog.showMessageBox(parent, opts)
|
||||
: await dialog.showMessageBox(opts);
|
||||
if (response !== 0) {
|
||||
// 取消并删除安装包
|
||||
console.warn('[updater] 用户取消安装并删除校验异常包');
|
||||
await this.removeDownloadedPackage().catch((e) => console.warn('[updater] 删除安装包失败:', e));
|
||||
this.state = 'idle';
|
||||
this.version = undefined;
|
||||
this.error = undefined;
|
||||
this.verified = false;
|
||||
this.emit();
|
||||
return;
|
||||
}
|
||||
console.warn('[updater] 用户确认继续安装(校验异常但已确认)');
|
||||
}
|
||||
|
||||
this.state = 'installing';
|
||||
this.emit();
|
||||
try {
|
||||
@@ -702,6 +732,17 @@ class UpdateService {
|
||||
autoUpdater.quitAndInstall(true, true);
|
||||
}
|
||||
|
||||
/** 删除已下载(校验失败)的安装包 */
|
||||
private async removeDownloadedPackage(): Promise<void> {
|
||||
const helper = (autoUpdater as unknown as { downloadedUpdateHelper?: { file?: string } }).downloadedUpdateHelper;
|
||||
const filePath = helper?.file;
|
||||
if (!filePath) return;
|
||||
if (fs.existsSync(filePath)) {
|
||||
await fs.promises.unlink(filePath);
|
||||
console.log(`[updater] 已删除安装包: ${filePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取系统下载临时目录(用于清理提示,暂未启用) */
|
||||
getCacheDir(): string {
|
||||
return os.tmpdir();
|
||||
|
||||
Reference in New Issue
Block a user