Prevent multiple concurrent update installers

* Exit early if we are already installing on Windows

* Setup a single handler for updating

* Guard against undefined updateFilePath
This commit is contained in:
Josh Perez 2020-07-20 14:42:26 -04:00 committed by Scott Nonnenberg
parent 36a0d1efcf
commit 5119193093
3 changed files with 62 additions and 29 deletions

View file

@ -170,8 +170,6 @@ export function showUpdateDialog(
): void {
let ack = false;
ipcMain.once('start-update', performUpdateCallback);
ipcMain.once('show-update-dialog-ack', () => {
ack = true;
});
@ -380,3 +378,7 @@ export function getCliOptions<T>(options: any): T {
return cliOptions;
}
export function setUpdateListener(performUpdateCallback: () => void): void {
ipcMain.once('start-update', performUpdateCallback);
}

View file

@ -15,6 +15,7 @@ import {
deleteTempDir,
downloadUpdate,
getPrintableError,
setUpdateListener,
showCannotUpdateDialog,
showUpdateDialog,
} from './common';
@ -46,6 +47,8 @@ export async function start(
}
}, INTERVAL);
setUpdateListener(createUpdater(logger));
await checkDownloadAndInstall(getMainWindow, locale, logger);
}
@ -74,6 +77,11 @@ async function checkDownloadAndInstall(
updateFilePath = await downloadUpdate(fileName, logger);
}
if (!updateFilePath) {
logger.info('checkDownloadAndInstall: no update file path. Skipping!');
return;
}
const publicKey = hexToBinary(getFromConfig('updatesPublicKey'));
const verified = await verifySignature(updateFilePath, version, publicKey);
if (!verified) {
@ -107,11 +115,7 @@ async function checkDownloadAndInstall(
logger.info('checkDownloadAndInstall: showing update dialog...');
showUpdateDialog(getMainWindow(), locale, () => {
logger.info('checkDownloadAndInstall: calling quitAndInstall...');
markShouldQuit();
autoUpdater.quitAndInstall();
});
showUpdateDialog(getMainWindow(), locale, createUpdater(logger));
} catch (error) {
logger.error('checkDownloadAndInstall: error', getPrintableError(error));
}
@ -372,3 +376,11 @@ async function showFallbackReadOnlyDialog(
showingReadOnlyDialog = false;
}
function createUpdater(logger: LoggerType) {
return () => {
logger.info('performUpdate: calling quitAndInstall...');
markShouldQuit();
autoUpdater.quitAndInstall();
};
}

View file

@ -12,6 +12,7 @@ import {
deleteTempDir,
downloadUpdate,
getPrintableError,
setUpdateListener,
showCannotUpdateDialog,
showUpdateDialog,
} from './common';
@ -27,6 +28,12 @@ const SECOND = 1000;
const MINUTE = SECOND * 60;
const INTERVAL = MINUTE * 30;
let fileName: string;
let version: string;
let updateFilePath: string;
let installing: boolean;
let loggerForQuitHandler: LoggerType;
export async function start(
getMainWindow: () => BrowserWindow,
locale: LocaleType,
@ -37,6 +44,8 @@ export async function start(
loggerForQuitHandler = logger;
app.once('quit', quitHandler);
setUpdateListener(createUpdater(getMainWindow, locale, logger));
setInterval(async () => {
try {
await checkDownloadAndInstall(getMainWindow, locale, logger);
@ -49,12 +58,6 @@ export async function start(
await checkDownloadAndInstall(getMainWindow, locale, logger);
}
let fileName: string;
let version: string;
let updateFilePath: string;
let installing: boolean;
let loggerForQuitHandler: LoggerType;
async function checkDownloadAndInstall(
getMainWindow: () => BrowserWindow,
locale: LocaleType,
@ -86,22 +89,11 @@ async function checkDownloadAndInstall(
}
logger.info('checkDownloadAndInstall: showing dialog...');
showUpdateDialog(getMainWindow(), locale, async () => {
try {
await verifyAndInstall(updateFilePath, version, logger);
installing = true;
} catch (error) {
logger.info(
'checkDownloadAndInstall: showing general update failure dialog...'
);
showCannotUpdateDialog(getMainWindow(), locale);
throw error;
}
markShouldQuit();
app.quit();
});
showUpdateDialog(
getMainWindow(),
locale,
createUpdater(getMainWindow, locale, logger)
);
} catch (error) {
logger.error('checkDownloadAndInstall: error', getPrintableError(error));
}
@ -151,6 +143,10 @@ async function verifyAndInstall(
newVersion: string,
logger: LoggerType
) {
if (installing) {
return;
}
const publicKey = hexToBinary(getFromConfig('updatesPublicKey'));
const verified = await verifySignature(updateFilePath, newVersion, publicKey);
if (!verified) {
@ -217,3 +213,26 @@ async function spawn(
setTimeout(resolve, 200);
});
}
function createUpdater(
getMainWindow: () => BrowserWindow,
locale: LocaleType,
logger: LoggerType
) {
return async () => {
try {
await verifyAndInstall(updateFilePath, version, logger);
installing = true;
} catch (error) {
logger.info(
'checkDownloadAndInstall: showing general update failure dialog...'
);
showCannotUpdateDialog(getMainWindow(), locale);
throw error;
}
markShouldQuit();
app.quit();
};
}