diff --git a/.github/workflows/build-app-beta.yaml b/.github/workflows/build-app-beta.yaml index f04798524..c516c9475 100644 --- a/.github/workflows/build-app-beta.yaml +++ b/.github/workflows/build-app-beta.yaml @@ -102,6 +102,7 @@ jobs: mv app/dist/*.deb artifacts/ || true mv app/dist/*.snap artifacts/ || true mv app/dist/*.dmg artifacts/ || true + mv app/dist/*.blockmap artifacts/ || true mv app/dist/*.yml artifacts/ || true rm artifacts/builder-debug.yml diff --git a/.github/workflows/build-app-pro-beta.yaml b/.github/workflows/build-app-pro-beta.yaml index b1d9ec240..184a44d8c 100644 --- a/.github/workflows/build-app-pro-beta.yaml +++ b/.github/workflows/build-app-pro-beta.yaml @@ -132,6 +132,7 @@ jobs: mv ../dbgate-merged/app/dist/*.deb artifacts/ || true mv ../dbgate-merged/app/dist/*.snap artifacts/ || true mv ../dbgate-merged/app/dist/*.dmg artifacts/ || true + mv ../dbgate-merged/app/dist/*.blockmap artifacts/ || true mv ../dbgate-merged/app/dist/*.yml artifacts/ || true rm artifacts/builder-debug.yml diff --git a/.github/workflows/build-app-pro.yaml b/.github/workflows/build-app-pro.yaml index d893bc401..fc2e15532 100644 --- a/.github/workflows/build-app-pro.yaml +++ b/.github/workflows/build-app-pro.yaml @@ -135,6 +135,7 @@ jobs: mv ../dbgate-merged/app/dist/*.AppImage artifacts/ || true mv ../dbgate-merged/app/dist/*.deb artifacts/ || true mv ../dbgate-merged/app/dist/*.dmg artifacts/ || true + mv ../dbgate-merged/app/dist/*.blockmap artifacts/ || true mv ../dbgate-merged/app/dist/*.yml artifacts/ || true rm artifacts/builder-debug.yml diff --git a/.github/workflows/build-app.yaml b/.github/workflows/build-app.yaml index 87f6734c8..ed5ada489 100644 --- a/.github/workflows/build-app.yaml +++ b/.github/workflows/build-app.yaml @@ -109,6 +109,7 @@ jobs: mv app/dist/*.deb artifacts/ || true mv app/dist/*.dmg artifacts/ || true mv app/dist/*.snap artifacts/dbgate-latest.snap || true + mv app/dist/*.blockmap artifacts/ || true mv app/dist/*.yml artifacts/ || true rm artifacts/builder-debug.yml diff --git a/app/src/electron.js b/app/src/electron.js index 31b2fe062..cdaee3d47 100644 --- a/app/src/electron.js +++ b/app/src/electron.js @@ -18,7 +18,6 @@ const url = require('url'); const mainMenuDefinition = require('./mainMenuDefinition'); const { isProApp } = require('./proTools'); const updaterChannel = require('./updaterChannel'); -let disableAutoUpgrade = false; // require('@electron/remote/main').initialize(); @@ -29,6 +28,8 @@ let apiLoaded = false; let mainModule; // let getLogger; // let loadLogsContent; +let appUpdateStatus = ''; +let settingsJson = {}; process.on('uncaughtException', function (error) { console.error('uncaughtException', error); @@ -52,21 +53,11 @@ const isMac = () => os.platform() == 'darwin'; try { initialConfig = JSON.parse(fs.readFileSync(configRootPath, { encoding: 'utf-8' })); - disableAutoUpgrade = initialConfig['disableAutoUpgrade'] || false; } catch (err) { console.log('Error loading config-root:', err.message); initialConfig = {}; } -if (process.argv.includes('--disable-auto-upgrade')) { - console.log('Disabling auto-upgrade'); - disableAutoUpgrade = true; -} -if (process.argv.includes('--enable-auto-upgrade')) { - console.log('Enabling auto-upgrade'); - disableAutoUpgrade = false; -} - // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow; @@ -212,6 +203,15 @@ ipcMain.on('app-started', async (event, arg) => { if (initialConfig['winIsMaximized']) { mainWindow.webContents.send('setIsMaximized', true); } + if (autoUpdater.isUpdaterActive()) { + mainWindow.webContents.send('setAppUpdaterActive'); + } + if (!process.env.DEVMODE) { + if (settingsJson['app.autoUpdateMode'] != 'skip') { + autoUpdater.autoDownload = settingsJson['app.autoUpdateMode'] == 'download'; + autoUpdater.checkForUpdates(); + } + } }); ipcMain.on('window-action', async (event, arg) => { if (!mainWindow) { @@ -285,6 +285,20 @@ ipcMain.handle('showItemInFolder', async (event, path) => { ipcMain.handle('openExternal', async (event, url) => { electron.shell.openExternal(url); }); +ipcMain.handle('downloadUpdate', async (event, url) => { + autoUpdater.downloadUpdate(); + changeAppUpdateStatus({ + icon: 'icon loading', + message: `Downloading update...`, + }); +}); +ipcMain.on('applyUpdate', async (event, url) => { + autoUpdater.quitAndInstall(false, true); +}); +ipcMain.on('check-for-updates', async (event, url) => { + autoUpdater.autoDownload = false; + autoUpdater.checkForUpdates(); +}); function fillMissingSettings(value) { const res = { @@ -322,8 +336,6 @@ function ensureBoundsVisible(bounds) { function createWindow() { const datadir = path.join(os.homedir(), '.dbgate'); - let settingsJson = {}; - let licenseKey = null; try { settingsJson = fillMissingSettings( JSON.parse(fs.readFileSync(path.join(datadir, 'settings.json'), { encoding: 'utf-8' })) @@ -332,14 +344,6 @@ function createWindow() { console.log('Error loading settings.json:', err.message); settingsJson = fillMissingSettings({}); } - if (isProApp()) { - try { - licenseKey = fs.readFileSync(path.join(datadir, 'license.key'), { encoding: 'utf-8' }); - } catch (err) { - console.log('Error loading license.key:', err.message); - licenseKey = null; - } - } let bounds = initialConfig['winBounds']; if (bounds) { @@ -355,7 +359,7 @@ function createWindow() { titleBarStyle: useNativeMenu ? undefined : 'hidden', ...bounds, icon: os.platform() == 'win32' ? 'icon.ico' : path.resolve(__dirname, '../icon.png'), - partition: 'persist:dbgate', + partition: isProApp() ? 'persist:dbgate-premium' : 'persist:dbgate', webPreferences: { nodeIntegration: true, contextIsolation: false, @@ -389,7 +393,6 @@ function createWindow() { JSON.stringify({ winBounds: mainWindow.getBounds(), winIsMaximized: mainWindow.isMaximized(), - disableAutoUpgrade, }), 'utf-8' ); @@ -459,13 +462,61 @@ function createWindow() { }); } +function changeAppUpdateStatus(status) { + appUpdateStatus = status; + mainWindow.webContents.send('app-update-status', appUpdateStatus); +} + +autoUpdater.on('checking-for-update', () => { + console.log('Checking for updates'); + changeAppUpdateStatus({ + icon: 'icon loading', + message: 'Checking for updates...', + }); +}); + +autoUpdater.on('update-available', info => { + console.log('Update available', info); + if (autoUpdater.autoDownload) { + changeAppUpdateStatus({ + icon: 'icon loading', + message: `Downloading update...`, + }); + } else { + mainWindow.webContents.send('update-available', info.version); + changeAppUpdateStatus({ + icon: 'icon download', + message: `New version ${info.version} available`, + }); + } +}); + +autoUpdater.on('update-not-available', info => { + console.log('Update not available', info); + changeAppUpdateStatus({ + icon: 'icon check', + message: `No new updates`, + }); +}); + +autoUpdater.on('update-downloaded', info => { + console.log('Update downloaded from', info); + changeAppUpdateStatus({ + icon: 'icon download', + message: `Downloaded new version ${info.version}`, + }); + mainWindow.webContents.send('downloaded-new-version', info.version); +}); + +autoUpdater.on('error', error => { + changeAppUpdateStatus({ + icon: 'icon error', + message: `Autoupdate error`, + }); + console.error('Update error', error); +}); + function onAppReady() { - if (disableAutoUpgrade) { - console.log('Auto-upgrade is disabled, run dbgate --enable-auto-upgrade to enable'); - } - if (!process.env.DEVMODE && !disableAutoUpgrade) { - autoUpdater.checkForUpdatesAndNotify(); - } createWindow(); } diff --git a/app/src/mainMenuDefinition.js b/app/src/mainMenuDefinition.js index 5d5cd1188..40cc485dc 100644 --- a/app/src/mainMenuDefinition.js +++ b/app/src/mainMenuDefinition.js @@ -105,6 +105,8 @@ module.exports = ({ editMenu }) => [ { command: 'settings.commands', hideDisabled: true }, { command: 'tabs.changelog', hideDisabled: true }, { command: 'about.show', hideDisabled: true }, + { divider: true }, + { command: 'file.checkForUpdates', hideDisabled: true }, ], }, ]; diff --git a/package.json b/package.json index 3baf284ba..7da3e2940 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "5.4.4-premium-beta.5", + "version": "5.4.4-beta.10", "name": "dbgate-all", "workspaces": [ "packages/*", diff --git a/packages/api/src/utility/checkLicense.js b/packages/api/src/utility/checkLicense.js index b43b3c1f7..a21a66c40 100644 --- a/packages/api/src/utility/checkLicense.js +++ b/packages/api/src/utility/checkLicense.js @@ -5,6 +5,14 @@ function checkLicense() { }; } +function checkLicenseKey(key) { + return { + status: 'ok', + type: 'community', + }; +} + module.exports = { checkLicense, + checkLicenseKey, }; diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index 0c0c8c08b..4669f628a 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -21,6 +21,7 @@ import AppStartInfo from './widgets/AppStartInfo.svelte'; import SettingsListener from './utility/SettingsListener.svelte'; import { handleAuthOnStartup } from './clientAuth'; + import { initializeAppUpdates } from './utility/appUpdate'; export let isAdminPage = false; @@ -49,6 +50,7 @@ subscribeConnectionPingers(); subscribePermissionCompiler(); installNewVolatileConnectionListener(); + initializeAppUpdates(); } loadedApi = loadedApiValue; diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index d1b23a4dd..34f2f7bef 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -3,6 +3,7 @@ import { currentTheme, emptyConnectionGroupNames, extensions, + getAppUpdaterActive, getExtensions, getVisibleToolbar, visibleToolbar, @@ -585,6 +586,17 @@ registerCommand({ onClick: () => disconnectServerConnection(getCurrentConfig()?.singleConnection?._id), }); +registerCommand({ + id: 'file.checkForUpdates', + category: 'App', + name: 'Check for updates', + // testEnabled: () => true, + testEnabled: () => getAppUpdaterActive(), + onClick: () => getElectron().send('check-for-updates'), +}); + + + export function registerFileCommands({ idPrefix, category, diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index 4296d82f4..143235dde 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -140,6 +140,7 @@ 'icon custom-join': 'mdi mdi-arrow-left-right-bold', 'icon parent-filter': 'mdi mdi-home-alert', 'icon parent-filter-outline': 'mdi mdi-home-alert-outline', + 'icon download': 'mdi mdi-download', 'icon run': 'mdi mdi-play', 'icon chevron-down': 'mdi mdi-chevron-down', diff --git a/packages/web/src/settings/SettingsModal.svelte b/packages/web/src/settings/SettingsModal.svelte index 5f384e00e..6b36c9421 100644 --- a/packages/web/src/settings/SettingsModal.svelte +++ b/packages/web/src/settings/SettingsModal.svelte @@ -342,6 +342,18 @@ ORDER BY