// @flow import electron from 'electron'; import { CHECK_FOR_UPDATES_INTERVAL, getAppVersion, isDevelopment, UPDATE_URL_MAC, UPDATE_URL_WINDOWS, } from '../common/constants'; import * as models from '../models/index'; import { buildQueryStringFromParams, joinUrlAndQueryString } from 'insomnia-url'; import { delay } from '../common/misc'; const { autoUpdater, BrowserWindow, ipcMain } = electron; async function getUpdateUrl(force: boolean): Promise { const platform = process.platform; const settings = await models.settings.getOrCreate(); let updateUrl = null; if (platform === 'win32') { updateUrl = UPDATE_URL_WINDOWS; } else if (platform === 'darwin') { updateUrl = UPDATE_URL_MAC; } else { return null; } const params = [ { name: 'v', value: getAppVersion() }, { name: 'channel', value: settings.updateChannel }, ]; const qs = buildQueryStringFromParams(params); const fullUrl = joinUrlAndQueryString(updateUrl, qs); console.log(`[updater] Using url ${fullUrl}`); if (process.env.INSOMNIA_DISABLE_AUTOMATIC_UPDATES) { console.log(`[updater] Disabled by INSOMNIA_DISABLE_AUTOMATIC_UPDATES environment variable`); return null; } if (isDevelopment()) { return null; } if (!force && !settings.updateAutomatically) { return null; } return fullUrl; } function _sendUpdateStatus(status) { const windows = BrowserWindow.getAllWindows(); for (const w of windows) { w.send('updater.check.status', status); } } function _sendUpdateComplete(success: boolean, msg: string) { const windows = BrowserWindow.getAllWindows(); for (const w of windows) { w.send('updater.check.complete', success, msg); } } let hasPromptedForUpdates = false; export async function init() { autoUpdater.on('error', e => { console.warn(`[updater] Error: ${e.message}`); }); autoUpdater.on('update-not-available', () => { console.log('[updater] Not Available'); _sendUpdateComplete(false, 'Up to Date'); }); autoUpdater.on('update-available', () => { console.log('[updater] Update Available'); _sendUpdateStatus('Downloading...'); }); autoUpdater.on('update-downloaded', (e, releaseNotes, releaseName, releaseDate, updateUrl) => { console.log(`[updater] Downloaded ${releaseName}`); _sendUpdateComplete(true, 'Updated (Restart Required)'); _showUpdateNotification(); }); ipcMain.on('updater.check', async e => { await _checkForUpdates(true); }); // Check for updates on an interval setInterval(async () => { await _checkForUpdates(false); }, CHECK_FOR_UPDATES_INTERVAL); // Check for updates immediately await _checkForUpdates(false); } function _showUpdateNotification() { if (hasPromptedForUpdates) { return; } const windows = BrowserWindow.getAllWindows(); if (windows.length && windows[0].webContents) { windows[0].webContents.send('update-available'); } hasPromptedForUpdates = true; } async function _checkForUpdates(force: boolean) { _sendUpdateStatus('Checking'); await delay(500); if (force) { hasPromptedForUpdates = false; } if (hasPromptedForUpdates) { // We've already prompted for updates. Don't bug the user anymore return; } const updateUrl = await getUpdateUrl(force); if (updateUrl === null) { console.log( `[updater] Updater not running platform=${process.platform} dev=${isDevelopment()}`, ); _sendUpdateComplete(false, 'Updates Not Supported'); return; } try { console.log(`[updater] Checking for updates url=${updateUrl}`); autoUpdater.setFeedURL(updateUrl); autoUpdater.checkForUpdates(); } catch (err) { console.warn('[updater] Failed to check for updates:', err.message); _sendUpdateComplete(false, 'Update Error'); } }