diff --git a/src/common/ipc/index.ts b/src/common/ipc/index.ts index 60ae46438e..bb60ce4f6c 100644 --- a/src/common/ipc/index.ts +++ b/src/common/ipc/index.ts @@ -5,5 +5,4 @@ export * from "./ipc"; export * from "./invalid-kubeconfig"; -export * from "./update-available"; export * from "./type-enforced-ipc"; diff --git a/src/common/ipc/update-available.ts b/src/common/ipc/update-available.ts deleted file mode 100644 index ed5b18b13d..0000000000 --- a/src/common/ipc/update-available.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import type { UpdateInfo } from "electron-updater"; - -export const UpdateAvailableChannel = "update-available"; -export const AutoUpdateChecking = "auto-update:checking"; -export const AutoUpdateNoUpdateAvailable = "auto-update:no-update"; -export const AutoUpdateLogPrefix = "[UPDATE-CHECKER]"; - -export type UpdateAvailableFromMain = [backChannel: string, updateInfo: UpdateInfo]; - -export function areArgsUpdateAvailableFromMain(args: unknown[]): args is UpdateAvailableFromMain { - if (args.length !== 2) { - return false; - } - - if (typeof args[0] !== "string") { - return false; - } - - if (typeof args[1] !== "object" || args[1] === null) { - // TODO: improve this checking - return false; - } - - return true; -} - -export type BackchannelArg = { - doUpdate: false; -} | { - doUpdate: true; - now: boolean; -}; - -export type UpdateAvailableToBackchannel = [updateDecision: BackchannelArg]; - -export function areArgsUpdateAvailableToBackchannel(args: unknown[]): args is UpdateAvailableToBackchannel { - if (args.length !== 1) { - return false; - } - - if (typeof args[0] !== "object" || args[0] === null) { - // TODO: improve this checking - return false; - } - - return true; -} diff --git a/src/common/user-store/user-store.ts b/src/common/user-store/user-store.ts index 3cfd551fd7..35982b9183 100644 --- a/src/common/user-store/user-store.ts +++ b/src/common/user-store/user-store.ts @@ -4,7 +4,7 @@ */ import { app } from "electron"; -import semver, { SemVer } from "semver"; +import semver from "semver"; import { action, computed, observable, reaction, makeObservable, isObservableArray, isObservableSet, isObservableMap } from "mobx"; import { BaseStore } from "../base-store"; import migrations from "../../migrations/user-store"; @@ -100,10 +100,6 @@ export class UserStore extends BaseStore /* implements UserStore return this.shell || process.env.SHELL || process.env.PTYSHELL; } - @computed get isAllowedToDowngrade() { - return new SemVer(getAppVersion()).prerelease[0] !== this.updateChannel; - } - startMainReactions() { // open at system start-up reaction(() => this.openAtLogin, openAtLogin => { diff --git a/src/main/app-updater.ts b/src/main/app-updater.ts deleted file mode 100644 index 47d651cd79..0000000000 --- a/src/main/app-updater.ts +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import type { UpdateInfo } from "electron-updater"; -import { autoUpdater } from "electron-updater"; -import logger from "./logger"; -import { isTestEnv } from "../common/vars"; -import { delay } from "../common/utils"; -import type { UpdateAvailableToBackchannel } from "../common/ipc"; -import { areArgsUpdateAvailableToBackchannel, AutoUpdateChecking, AutoUpdateLogPrefix, AutoUpdateNoUpdateAvailable, broadcastMessage, onceCorrect, UpdateAvailableChannel } from "../common/ipc"; -import { once } from "lodash"; -import { ipcMain } from "electron"; -import { nextUpdateChannel } from "./utils/update-channel"; -import { UserStore } from "../common/user-store"; - -let installVersion: undefined | string; - -function handleAutoUpdateBackChannel(event: Electron.IpcMainEvent, ...[arg]: UpdateAvailableToBackchannel) { - if (arg.doUpdate) { - if (arg.now) { - logger.info(`${AutoUpdateLogPrefix}: User chose to update now`); - autoUpdater.quitAndInstall(true, true); - } else { - logger.info(`${AutoUpdateLogPrefix}: User chose to update on quit`); - } - } else { - logger.info(`${AutoUpdateLogPrefix}: User chose not to update, will update on quit anyway`); - } -} - -autoUpdater.logger = { - info: message => logger.info(`[AUTO-UPDATE]: electron-updater: %s`, message), - warn: message => logger.warn(`[AUTO-UPDATE]: electron-updater: %s`, message), - error: message => logger.error(`[AUTO-UPDATE]: electron-updater: %s`, message), - debug: message => logger.debug(`[AUTO-UPDATE]: electron-updater: %s`, message), -}; - -interface Dependencies { - updatingIsEnabled: boolean; -} - -/** - * starts the automatic update checking - * @param interval milliseconds between interval to check on, defaults to 2h - */ -export const startUpdateChecking = ({ updatingIsEnabled } : Dependencies) => once(function (interval = 1000 * 60 * 60 * 2): void { - if (!updatingIsEnabled || isTestEnv) { - return; - } - - const userStore = UserStore.getInstance(); - - autoUpdater.autoDownload = false; - autoUpdater.autoInstallOnAppQuit = true; - autoUpdater.channel = userStore.updateChannel; - autoUpdater.allowDowngrade = userStore.isAllowedToDowngrade; - - autoUpdater - .on("update-available", (info: UpdateInfo) => { - if (installVersion === info.version) { - // same version, don't broadcast - return; - } - - installVersion = info.version; - - autoUpdater.downloadUpdate() - .catch(error => logger.error(`${AutoUpdateLogPrefix}: failed to download update`, { error: String(error) })); - }) - .on("update-downloaded", (info: UpdateInfo) => { - try { - const backchannel = `auto-update:${info.version}`; - - ipcMain.removeAllListeners(backchannel); // only one handler should be present - - // make sure that the handler is in place before broadcasting (prevent race-condition) - onceCorrect({ - source: ipcMain, - channel: backchannel, - listener: handleAutoUpdateBackChannel, - verifier: areArgsUpdateAvailableToBackchannel, - }); - logger.info(`${AutoUpdateLogPrefix}: broadcasting update available`, { backchannel, version: info.version }); - broadcastMessage(UpdateAvailableChannel, backchannel, info); - } catch (error) { - logger.error(`${AutoUpdateLogPrefix}: broadcasting failed`, { error }); - installVersion = undefined; - } - }) - .on("update-not-available", () => { - const nextChannel = nextUpdateChannel(userStore.updateChannel, autoUpdater.channel); - - logger.info(`${AutoUpdateLogPrefix}: update not available from ${autoUpdater.channel}, will check ${nextChannel} channel next`); - - if (nextChannel !== autoUpdater.channel) { - autoUpdater.channel = nextChannel; - autoUpdater.checkForUpdates() - .catch(error => logger.error(`${AutoUpdateLogPrefix}: failed with an error`, error)); - } else { - broadcastMessage(AutoUpdateNoUpdateAvailable); - } - }); - - async function helper() { - while (true) { - await checkForUpdates(); - await delay(interval); - } - } - - helper(); -}); - -export async function checkForUpdates(): Promise { - const userStore = UserStore.getInstance(); - - try { - logger.info(`📡 Checking for app updates`); - - autoUpdater.channel = userStore.updateChannel; - autoUpdater.allowDowngrade = userStore.isAllowedToDowngrade; - broadcastMessage(AutoUpdateChecking); - await autoUpdater.checkForUpdates(); - } catch (error) { - logger.error(`${AutoUpdateLogPrefix}: failed with an error`, error); - } -} diff --git a/src/main/start-update-checking.injectable.ts b/src/main/start-update-checking.injectable.ts deleted file mode 100644 index 813c9329ed..0000000000 --- a/src/main/start-update-checking.injectable.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import { startUpdateChecking } from "./app-updater"; -import updatingIsEnabledInjectable from "./update-app/updating-is-enabled.injectable"; - -const startUpdateCheckingInjectable = getInjectable({ - id: "start-update-checking", - - instantiate: (di) => startUpdateChecking({ - updatingIsEnabled: di.inject(updatingIsEnabledInjectable), - }), - - causesSideEffects: true, -}); - -export default startUpdateCheckingInjectable; diff --git a/src/renderer/ipc/register-listeners.tsx b/src/renderer/ipc/register-listeners.tsx index f69feb6d6b..4d2ed9f5c8 100644 --- a/src/renderer/ipc/register-listeners.tsx +++ b/src/renderer/ipc/register-listeners.tsx @@ -3,88 +3,14 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import React from "react"; import type { IpcRendererEvent } from "electron"; import { ipcRenderer } from "electron"; -import type { UpdateAvailableFromMain, BackchannelArg } from "../../common/ipc"; -import { areArgsUpdateAvailableFromMain, UpdateAvailableChannel, onCorrect, ipcRendererOn, AutoUpdateChecking, AutoUpdateNoUpdateAvailable } from "../../common/ipc"; +import { onCorrect } from "../../common/ipc"; import { Notifications } from "../components/notifications"; -import { Button } from "../components/button"; -import { isMac } from "../../common/vars"; import { defaultHotbarCells } from "../../common/hotbars/types"; import { type ListNamespaceForbiddenArgs, clusterListNamespaceForbiddenChannel, isListNamespaceForbiddenArgs } from "../../common/ipc/cluster"; import { hotbarTooManyItemsChannel } from "../../common/ipc/hotbar"; -function sendToBackchannel(backchannel: string, notificationId: string, data: BackchannelArg): void { - ipcRenderer.send(backchannel, data); -} - -function RenderYesButtons(props: { backchannel: string; notificationId: string }) { - if (isMac) { - /** - * auto-updater's "installOnQuit" is not applicable for macOS as per their docs. - * - * See: https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/src/AppUpdater.ts#L27-L32 - */ - return ( -