Converted updating into a 2 step process.

First it will ask the user about downloading the new update.
Then it will download the update and ask the user to restart the application.

This was done so that if the company was forced to put out comprimised binaries, all our users won't be automatically updated to them.
pull/949/head
Mikunj 5 years ago
parent 8c071b2f11
commit 4eef73c0a2

@ -1965,7 +1965,7 @@
"message": "There is a new version of Session available."
},
"autoUpdateNewVersionInstructions": {
"message": "Press Restart Session to apply the updates."
"message": "Would you like to download the update?"
},
"autoUpdateRestartButtonLabel": {
"message": "Restart Session"
@ -1973,6 +1973,15 @@
"autoUpdateLaterButtonLabel": {
"message": "Later"
},
"autoUpdateDownloadButtonLabel": {
"message": "Download"
},
"autoUpdateDownloadedMessage": {
"message": "The new update has been downloaded."
},
"autoUpdateRestartInstructions": {
"message": "Press Restart Session to apply the updates."
},
"leftTheGroup": {
"message": "$name$ left the group",
"description":

@ -18,37 +18,57 @@ export type LoggerType = {
trace: LogFunction;
};
export async function showUpdateDialog(
export async function showDownloadUpdateDialog(
mainWindow: BrowserWindow,
messages: MessagesType
): Promise<boolean> {
const RESTART_BUTTON = 0;
const DOWNLOAD_BUTTON = 0;
const LATER_BUTTON = 1;
const options = {
type: 'info',
buttons: [
messages.autoUpdateRestartButtonLabel.message,
messages.autoUpdateDownloadButtonLabel.message,
messages.autoUpdateLaterButtonLabel.message,
],
title: messages.autoUpdateNewVersionTitle.message,
message: messages.autoUpdateNewVersionMessage.message,
detail: messages.autoUpdateNewVersionInstructions.message,
defaultId: LATER_BUTTON,
cancelId: RESTART_BUTTON,
cancelId: DOWNLOAD_BUTTON,
};
return new Promise(resolve => {
dialog.showMessageBox(mainWindow, options, response => {
if (response === RESTART_BUTTON) {
// It's key to delay any install calls here because they don't seem to work inside this
// callback - but only if the message box has a parent window.
// Fixes this: https://github.com/signalapp/Signal-Desktop/issues/1864
resolve(true);
resolve(response === DOWNLOAD_BUTTON);
});
});
}
return;
}
export async function showUpdateDialog(
mainWindow: BrowserWindow,
messages: MessagesType
): Promise<boolean> {
const RESTART_BUTTON = 0;
const LATER_BUTTON = 1;
const options = {
type: 'info',
buttons: [
messages.autoUpdateRestartButtonLabel.message,
messages.autoUpdateLaterButtonLabel.message,
],
title: messages.autoUpdateNewVersionTitle.message,
message: messages.autoUpdateDownloadedMessage.message,
detail: messages.autoUpdateRestartInstructions.message,
defaultId: LATER_BUTTON,
cancelId: RESTART_BUTTON,
};
resolve(false);
return new Promise(resolve => {
dialog.showMessageBox(mainWindow, options, response => {
// It's key to delay any install calls here because they don't seem to work inside this
// callback - but only if the message box has a parent window.
// Fixes this: https://github.com/signalapp/Signal-Desktop/issues/1864
resolve(response === RESTART_BUTTON);
});
});
}

@ -1,6 +1,6 @@
import * as path from 'path';
import * as fs from 'fs-extra';
import { autoUpdater } from 'electron-updater';
import { autoUpdater, UpdateInfo } from 'electron-updater';
import { app, BrowserWindow } from 'electron';
import { markShouldQuit } from '../../app/window_state';
import {
@ -8,10 +8,13 @@ import {
LoggerType,
MessagesType,
showCannotUpdateDialog,
showDownloadUpdateDialog,
showUpdateDialog,
} from './common';
import { gt as isVersionGreaterThan, parse as parseVersion } from 'semver';
let isUpdating = false;
let downloadIgnored = false;
const SECOND = 1000;
const MINUTE = SECOND * 60;
@ -25,6 +28,7 @@ export async function start(
logger.info('auto-update: starting checks...');
autoUpdater.logger = logger;
autoUpdater.autoDownload = false;
setInterval(async () => {
try {
@ -42,7 +46,7 @@ async function checkForUpdates(
messages: MessagesType,
logger: LoggerType
) {
if (isUpdating) {
if (isUpdating || downloadIgnored) {
return;
}
@ -51,20 +55,39 @@ async function checkForUpdates(
return;
}
isUpdating = true;
logger.info('auto-update: checking for update...');
isUpdating = true;
try {
// Get the update using electron-updater
const result = await autoUpdater.checkForUpdates();
if (!result.updateInfo) {
logger.info('auto-update: no update info received');
return;
}
try {
const info = await autoUpdater.checkForUpdates();
if (!info.downloadPromise) {
logger.info('auto-update: no update to download');
const hasUpdate = isUpdateAvailable(result.updateInfo);
if (!hasUpdate) {
logger.info('auto-update: no update available');
return;
}
await info.downloadPromise;
logger.info('auto-update: showing download dialog...');
const shouldDownload = await showDownloadUpdateDialog(
getMainWindow(),
messages
);
if (!shouldDownload) {
downloadIgnored = true;
return;
}
await autoUpdater.downloadUpdate();
} catch (error) {
await showCannotUpdateDialog(getMainWindow(), messages);
throw error;
@ -85,6 +108,18 @@ async function checkForUpdates(
}
}
function isUpdateAvailable(updateInfo: UpdateInfo): boolean {
const latestVersion = parseVersion(updateInfo.version);
if (!latestVersion) {
return false;
}
// We need to convert this to string because typescript won't let us use types across submodules ....
const currentVersion = autoUpdater.currentVersion.toString();
return isVersionGreaterThan(latestVersion, currentVersion);
}
/*
Check if we have the required files to auto update.
These files won't exist inside certain formats such as a linux deb file.

Loading…
Cancel
Save