diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-03-30 09:23:28 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-03-31 15:59:47 +0200 |
| commit | a7d0e178604e740c695003ab2c99ef0216a516d2 (patch) | |
| tree | 48ad63e293336314bc7777e1ad15c7ad52592079 /gui/src/main | |
| parent | 296277eb75a58eff48addf31a7e8f4cf4d7ab4fd (diff) | |
| download | mullvadvpn-a7d0e178604e740c695003ab2c99ef0216a516d2.tar.xz mullvadvpn-a7d0e178604e740c695003ab2c99ef0216a516d2.zip | |
Add button to delete browsed for split tunneling apps
Diffstat (limited to 'gui/src/main')
| -rw-r--r-- | gui/src/main/gui-settings.ts | 9 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 70 | ||||
| -rw-r--r-- | gui/src/main/windows-split-tunneling.ts | 26 |
3 files changed, 51 insertions, 54 deletions
diff --git a/gui/src/main/gui-settings.ts b/gui/src/main/gui-settings.ts index 73c546a24b..a4e7a31d22 100644 --- a/gui/src/main/gui-settings.ts +++ b/gui/src/main/gui-settings.ts @@ -90,6 +90,15 @@ export default class GuiSettings { }); } + public deleteBrowsedForSplitTunnelingApplications(path: string) { + this.changeStateAndNotify({ + ...this.stateValue, + browsedForSplitTunnelingApplications: this.browsedForSplitTunnelingApplications.filter( + (application) => application !== path, + ), + }); + } + get browsedForSplitTunnelingApplications(): Array<string> { return this.stateValue.browsedForSplitTunnelingApplications; } diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index a6fcfa7be7..4ab0cbdd93 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -18,7 +18,7 @@ import * as path from 'path'; import util from 'util'; import config from '../config.json'; import { closeToExpiry, hasExpired } from '../shared/account-expiry'; -import { IApplication } from '../shared/application-types'; +import { IWindowsApplication } from '../shared/application-types'; import BridgeSettingsBuilder from '../shared/bridge-settings-builder'; import { AccountToken, @@ -241,7 +241,7 @@ class ApplicationMain { private rendererLog?: Logger; private translations: ITranslations = { locale: this.locale }; - private windowsSplitTunnelingApplications?: IApplication[]; + private windowsSplitTunnelingApplications?: IWindowsApplication[]; private macOsScrollbarVisibility?: MacOsScrollbarVisibility; @@ -1331,66 +1331,40 @@ class ApplicationMain { }); IpcMainEventChannel.linuxSplitTunneling.handleGetApplications(() => { - if (linuxSplitTunneling) { - return linuxSplitTunneling.getApplications(this.locale); - } else { - throw Error('linuxSplitTunneling.getApplications function called without being imported'); - } + return linuxSplitTunneling.getApplications(this.locale); }); IpcMainEventChannel.windowsSplitTunneling.handleGetApplications((updateCaches: boolean) => { - if (windowsSplitTunneling) { - return windowsSplitTunneling.getApplications({ - updateCaches, - }); - } else { - throw Error('windowsSplitTunneling.getApplications function called without being imported'); - } + return windowsSplitTunneling.getApplications({ updateCaches }); }); IpcMainEventChannel.linuxSplitTunneling.handleLaunchApplication((application) => { - if (linuxSplitTunneling) { - return linuxSplitTunneling.launchApplication(application); - } else { - throw Error('linuxSplitTunneling.launchApplication function called without being imported'); - } + return linuxSplitTunneling.launchApplication(application); }); IpcMainEventChannel.windowsSplitTunneling.handleSetState((enabled) => { - if (windowsSplitTunneling) { - return this.daemonRpc.setSplitTunnelingState(enabled); - } else { - throw Error('windowsSplitTunneling.setState function called without being imported'); - } + return this.daemonRpc.setSplitTunnelingState(enabled); }); IpcMainEventChannel.windowsSplitTunneling.handleAddApplication(async (application) => { - if (windowsSplitTunneling) { - // If the applications is a string (path) it's an application picked with the file picker - // that we want to add to the list of additional applications. - if (typeof application === 'string') { - this.guiSettings.addBrowsedForSplitTunnelingApplications(application); - const applicationPath = await windowsSplitTunneling.addApplicationPathToCache( - application, - ); - await this.daemonRpc.addSplitTunnelingApplication(applicationPath); - } else { - await this.daemonRpc.addSplitTunnelingApplication(application.absolutepath); - } + // If the applications is a string (path) it's an application picked with the file picker + // that we want to add to the list of additional applications. + if (typeof application === 'string') { + this.guiSettings.addBrowsedForSplitTunnelingApplications(application); + const applicationPath = await windowsSplitTunneling.addApplicationPathToCache(application); + await this.daemonRpc.addSplitTunnelingApplication(applicationPath); } else { - throw Error( - 'windowsSplitTunneling.handleAddApplication function called without being imported', - ); + await this.daemonRpc.addSplitTunnelingApplication(application.absolutepath); } }); IpcMainEventChannel.windowsSplitTunneling.handleRemoveApplication((application) => { - if (windowsSplitTunneling) { - return this.daemonRpc.removeSplitTunnelingApplication( - typeof application === 'string' ? application : application.absolutepath, - ); - } else { - throw Error( - 'windowsSplitTunneling.handleRemoveApplication function called without being imported', - ); - } + return this.daemonRpc.removeSplitTunnelingApplication( + typeof application === 'string' ? application : application.absolutepath, + ); }); + IpcMainEventChannel.windowsSplitTunneling.handleForgetManuallyAddedApplication( + (application) => { + this.guiSettings.deleteBrowsedForSplitTunnelingApplications(application.absolutepath); + return windowsSplitTunneling.removeApplicationFromCache(application); + }, + ); IpcMainEventChannel.problemReport.handleCollectLogs((toRedact) => { const id = randomUUID(); diff --git a/gui/src/main/windows-split-tunneling.ts b/gui/src/main/windows-split-tunneling.ts index a8915595e5..2ae118db4a 100644 --- a/gui/src/main/windows-split-tunneling.ts +++ b/gui/src/main/windows-split-tunneling.ts @@ -1,7 +1,7 @@ import { app, shell } from 'electron'; import fs from 'fs'; import path from 'path'; -import { IApplication } from '../shared/application-types'; +import { IWindowsApplication } from '../shared/application-types'; import log from '../shared/logging'; import { ArrayValue, @@ -35,6 +35,7 @@ interface ShortcutDetails { target: string; name: string; args?: string; + deletable: boolean; } type RvaToOffset = (rva: number) => Promise<number>; @@ -58,9 +59,9 @@ const APPLICATION_ALLOW_LIST = [ // Cache of all previously scanned shortcuts. const shortcutCache: Record<string, ShortcutDetails> = {}; // Cache of all previously scanned applications. -const applicationCache: Record<string, IApplication> = {}; +const applicationCache: Record<string, IWindowsApplication> = {}; // List of shortcuts that have been added manually by the user. -const additionalShortcuts: ShortcutDetails[] = []; +let additionalShortcuts: ShortcutDetails[] = []; // Finds applications by searching through the startmenu for shortcuts with and exe-file as target. // If applicationPaths has a value, the returned applications are only the ones corresponding to @@ -68,7 +69,7 @@ const additionalShortcuts: ShortcutDetails[] = []; export async function getApplications(options: { applicationPaths?: string[]; updateCaches?: boolean; -}): Promise<{ fromCache: boolean; applications: IApplication[] }> { +}): Promise<{ fromCache: boolean; applications: IWindowsApplication[] }> { const cacheIsEmpty = Object.keys(shortcutCache).length === 0; if (options.updateCaches || cacheIsEmpty) { @@ -105,7 +106,11 @@ export async function addApplicationPathToCache(applicationPath: string): Promis const parsedPath = path.parse(applicationPath); if (parsedPath.ext === '.lnk') { const shortcutDetiails = shell.readShortcutLink(path.resolve(applicationPath)); - additionalShortcuts.push({ ...shortcutDetiails, name: path.parse(applicationPath).name }); + additionalShortcuts.push({ + ...shortcutDetiails, + name: path.parse(applicationPath).name, + deletable: true, + }); return shortcutDetiails.target; } else { await addApplicationToAdditionalShortcuts(applicationPath); @@ -113,6 +118,13 @@ export async function addApplicationPathToCache(applicationPath: string): Promis } } +export function removeApplicationFromCache(application: IWindowsApplication): void { + additionalShortcuts = additionalShortcuts.filter( + (shortcut) => shortcut.target !== application.absolutepath, + ); + delete applicationCache[application.absolutepath.toLowerCase()]; +} + // Reads the start-menu directories and adds all shortcuts, targeting applications using networking, // to the shortcuts cache. Wheter or not an application use networking is determined by checking for // "WS2_32.dll" in it's imports. @@ -158,6 +170,7 @@ async function addApplicationToAdditionalShortcuts(applicationPath: string): Pro additionalShortcuts.push({ target: applicationPath, name: (await getProgramName(applicationPath)) ?? path.parse(applicationPath).name, + deletable: true, }); } } @@ -231,11 +244,12 @@ function removeDuplicates(shortcuts: ShortcutDetails[]): ShortcutDetails[] { async function convertToSplitTunnelingApplication( shortcut: ShortcutDetails, -): Promise<IApplication> { +): Promise<IWindowsApplication> { return { absolutepath: shortcut.target, name: shortcut.name, icon: await retrieveIcon(shortcut.target), + deletable: shortcut.deletable, }; } |
