Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backup second pass #6388

Merged
merged 10 commits into from Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions packages/insomnia/src/main.development.ts
@@ -1,3 +1,4 @@

import electron, { app, ipcMain, session } from 'electron';
import { BrowserWindow } from 'electron';
import contextMenu from 'electron-context-menu';
Expand All @@ -8,6 +9,7 @@ import { userDataFolder } from '../config/config.json';
import { changelogUrl, getAppVersion, isDevelopment, isMac } from './common/constants';
import { database } from './common/database';
import log, { initializeLogging } from './common/log';
import { backupIfNewerVersionAvailable } from './main/backup';
import { registerElectronHandlers } from './main/ipc/electron';
import { registergRPCHandlers } from './main/ipc/grpc';
import { registerMainHandlers } from './main/ipc/main';
Expand Down Expand Up @@ -228,7 +230,8 @@ async function _trackStats() {
launches: oldStats.launches + 1,
});

ipcMain.once('halfSecondAfterAppStart', () => {
ipcMain.once('halfSecondAfterAppStart', async () => {
backupIfNewerVersionAvailable();
const { currentVersion, launches, lastVersion } = stats;

const firstLaunch = launches === 1;
Expand All @@ -244,7 +247,7 @@ async function _trackStats() {
message: `Updated to ${currentVersion}`,
};
// Wait a bit before showing the user because the app just launched.
setTimeout(() => {
setTimeout(async () => {
for (const window of BrowserWindow.getAllWindows()) {
// @ts-expect-error -- TSCONVERSION likely needs to be window.webContents.send instead
window.send('show-notification', notification);
Expand Down
75 changes: 75 additions & 0 deletions packages/insomnia/src/main/backup.ts
@@ -0,0 +1,75 @@
import { copyFile, mkdir, readdir } from 'node:fs/promises';
import path from 'node:path';

import electron from 'electron';

import appConfig from '../../config/config.json';
import { version } from '../../package.json';
import * as models from '../models';
import { insomniaFetch } from './insomniaFetch';

export async function backupIfNewerVersionAvailable() {
try {
const settings = await models.settings.getOrCreate();
console.log('[main] Checking for newer version than ', version);
const response = await insomniaFetch<{ url: string }>({
method: 'GET',
origin: 'https://updates.insomnia.rest',
path: `/builds/check/mac?v=${version}&app=${appConfig.appId}&channel=${settings.updateChannel}`,
sessionId: null,
});
if (response) {
console.log('[main] Found newer version', response);
backup();
return;
}
console.log('[main] No newer version');
} catch (err) {
console.log('[main] Error checking for newer version', err);
}
}

export async function backup() {
try {
const dataPath = process.env['INSOMNIA_DATA_PATH'] || electron.app.getPath('userData');
const versionPath = path.join(dataPath, 'backups', version);
await mkdir(versionPath, { recursive: true });
// skip if backup already exists at version path
const backupFiles = await readdir(versionPath);
if (backupFiles.length) {
console.log('Backup found at:', versionPath);
return;
}
const files = await readdir(dataPath);
files.forEach(async (file: string) => {
if (file.endsWith('.db')) {
await copyFile(path.join(dataPath, file), path.join(versionPath, file));
}
});
console.log('Exported backup to:', versionPath);
} catch (err) {
console.log('Error exporting backup:', err);
}
}

export async function restoreBackup(version: string) {
try {
const dataPath = process.env['INSOMNIA_DATA_PATH'] || electron.app.getPath('userData');
const versionPath = path.join(dataPath, 'backups', version);
const files = await readdir(versionPath);
if (!files.length) {
console.log('No backup found at:', versionPath);
return;
}
files.forEach(async (file: string) => {
if (file.endsWith('.db')) {
await copyFile(path.join(versionPath, file), path.join(dataPath, file));
}
});
console.log('Restored backup from:', versionPath);
} catch (err) {
console.log('Error restoring backup:', err);
}
electron.app.relaunch();
electron.app.exit();
}
32 changes: 0 additions & 32 deletions packages/insomnia/src/main/export.ts

This file was deleted.

12 changes: 8 additions & 4 deletions packages/insomnia/src/main/ipc/main.ts
Expand Up @@ -9,7 +9,7 @@ import fs from 'fs';

import { SegmentEvent, trackPageView, trackSegmentEvent } from '../analytics';
import { authorizeUserInWindow } from '../authorizeUserInWindow';
import { exportAllWorkspaces } from '../export';
import { backup, restoreBackup } from '../backup';
import { insomniaFetch } from '../insomniaFetch';
import installPlugin from '../install-plugin';
import { axiosRequest } from '../network/axios-request';
Expand All @@ -24,7 +24,8 @@ export interface MainBridgeAPI {
restart: () => void;
halfSecondAfterAppStart: () => void;
manualUpdateCheck: () => void;
exportAllWorkspaces: () => Promise<void>;
backup: () => Promise<void>;
restoreBackup: (version: string) => Promise<void>;
spectralRun: (options: { contents: string; rulesetPath: string }) => Promise<ISpectralDiagnostic[]>;
authorizeUserInWindow: typeof authorizeUserInWindow;
setMenuBarVisibility: (visible: boolean) => void;
Expand Down Expand Up @@ -54,8 +55,11 @@ export function registerMainHandlers() {
w.webContents.send('loggedIn');
});
});
ipcMain.handle('exportAllWorkspaces', async () => {
return exportAllWorkspaces();
ipcMain.handle('backup', async () => {
return backup();
});
ipcMain.handle('restoreBackup', async (_, options: string) => {
return restoreBackup(options);
});
ipcMain.handle('authorizeUserInWindow', (_, options: Parameters<typeof authorizeUserInWindow>[0]) => {
const { url, urlSuccessRegex, urlFailureRegex, sessionId } = options;
Expand Down
3 changes: 1 addition & 2 deletions packages/insomnia/src/main/updates.ts
Expand Up @@ -10,7 +10,6 @@ import {
import { delay } from '../common/misc';
import * as models from '../models/index';
import { invariant } from '../utils/invariant';
import { exportAllWorkspaces } from './export';
const isUpdateSupported = () => {
if (process.platform === 'linux') {
console.log('[updater] Not supported on this platform', process.platform);
Expand Down Expand Up @@ -62,7 +61,6 @@ export const init = async () => {
autoUpdater.on('update-downloaded', async (_error, releaseNotes, releaseName) => {
console.log(`[updater] Downloaded ${releaseName}`);
_sendUpdateStatus('Performing backup...');
await exportAllWorkspaces();
_sendUpdateStatus('Updated (Restart Required)');

dialog.showMessageBox({
Expand All @@ -79,6 +77,7 @@ export const init = async () => {
});

if (isUpdateSupported()) {
// perhaps disable this method of upgrading just incase it trigger before backup is complete
// on app start
const settings = await models.settings.getOrCreate();
const updateUrl = getUpdateUrl(settings.updateChannel);
Expand Down
3 changes: 2 additions & 1 deletion packages/insomnia/src/preload.ts
Expand Up @@ -43,7 +43,8 @@ const main: Window['main'] = {
openInBrowser: options => ipcRenderer.send('openInBrowser', options),
halfSecondAfterAppStart: () => ipcRenderer.send('halfSecondAfterAppStart'),
manualUpdateCheck: () => ipcRenderer.send('manualUpdateCheck'),
exportAllWorkspaces: () => ipcRenderer.invoke('exportAllWorkspaces'),
backup: () => ipcRenderer.invoke('backup'),
restoreBackup: options => ipcRenderer.invoke('restoreBackup', options),
authorizeUserInWindow: options => ipcRenderer.invoke('authorizeUserInWindow', options),
spectralRun: options => ipcRenderer.invoke('spectralRun', options),
setMenuBarVisibility: options => ipcRenderer.send('setMenuBarVisibility', options),
Expand Down
Expand Up @@ -45,7 +45,9 @@ export const ImportExport: FC<Props> = ({ hideSettingsModal }) => {
exportAllToFile(projectName, workspacesForActiveProject);
hideSettingsModal();
};

// here we should list all the folders which contain insomnia.*.db files
// and have some big red button to overwrite the current data with the backup
// and once complete trigger an app restart?
return (
<Fragment>
<div data-testid="import-export-tab">
Expand Down