summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2018-11-15 13:34:50 +0100
committerAndrej Mihajlov <and@mullvad.net>2018-11-16 11:12:41 +0100
commit113d529db2d769aa327a366b73bb9520f4e0c18c (patch)
treefba4a1c2f91f8c984f9002435d3ed1c870a286c3 /gui
parent5c44ad01b85928c1bbee6054daa053540c1c1970 (diff)
downloadmullvadvpn-113d529db2d769aa327a366b73bb9520f4e0c18c.tar.xz
mullvadvpn-113d529db2d769aa327a366b73bb9520f4e0c18c.zip
Move tunnel and settings management from renderer to main
Diffstat (limited to 'gui')
-rw-r--r--gui/packages/desktop/src/main/daemon-rpc.js25
-rw-r--r--gui/packages/desktop/src/main/index.js168
-rw-r--r--gui/packages/desktop/src/renderer/app.js147
-rw-r--r--gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js42
-rw-r--r--gui/packages/desktop/src/renderer/lib/subscription-proxy/base-proxy.js118
-rw-r--r--gui/packages/desktop/src/renderer/lib/subscription-proxy/settings-proxy.js15
-rw-r--r--gui/packages/desktop/src/renderer/lib/subscription-proxy/tunnel-state-proxy.js18
7 files changed, 216 insertions, 317 deletions
diff --git a/gui/packages/desktop/src/main/daemon-rpc.js b/gui/packages/desktop/src/main/daemon-rpc.js
index 1811fa1e36..ef904560f0 100644
--- a/gui/packages/desktop/src/main/daemon-rpc.js
+++ b/gui/packages/desktop/src/main/daemon-rpc.js
@@ -638,3 +638,28 @@ function transformObjectKeys(object: Object, keyTransformer: (string) => string)
}
return object;
}
+
+export function defaultSettings(): Settings {
+ return {
+ accountToken: null,
+ allowLan: false,
+ autoConnect: false,
+ relaySettings: {
+ normal: {
+ location: 'any',
+ tunnel: 'any',
+ },
+ },
+ tunnelOptions: {
+ enableIpv6: false,
+ openvpn: {
+ mssfix: null,
+ },
+ proxy: null,
+ },
+ };
+}
+
+export function defaultTunnelStateTransition(): TunnelStateTransition {
+ return { state: 'disconnected' };
+}
diff --git a/gui/packages/desktop/src/main/index.js b/gui/packages/desktop/src/main/index.js
index 4ba94831e7..365cf3e613 100644
--- a/gui/packages/desktop/src/main/index.js
+++ b/gui/packages/desktop/src/main/index.js
@@ -8,15 +8,23 @@ import mkdirp from 'mkdirp';
import uuid from 'uuid';
import { app, screen, BrowserWindow, ipcMain, Tray, Menu, nativeImage } from 'electron';
-import TrayIconController from './tray-icon-controller';
import WindowController from './window-controller';
-import { DaemonRpc, ConnectionObserver, SubscriptionListener } from './daemon-rpc';
-import type { TunnelStateTransition, Settings } from './daemon-rpc';
-import ReconnectionBackoff from './reconnection-backoff';
-import { resolveBin } from './proc';
+import TrayIconController from './tray-icon-controller';
import type { TrayIconType } from './tray-icon-controller';
+import {
+ DaemonRpc,
+ ConnectionObserver,
+ SubscriptionListener,
+ defaultSettings,
+ defaultTunnelStateTransition,
+} from './daemon-rpc';
+import type { TunnelState, TunnelStateTransition, Settings } from './daemon-rpc';
+
+import ReconnectionBackoff from './reconnection-backoff';
+import { resolveBin } from './proc';
+
const DAEMON_RPC_PATH =
process.platform === 'win32' ? '//./pipe/Mullvad VPN' : '/var/run/mullvad-vpn';
@@ -34,6 +42,9 @@ const ApplicationMain = {
_oldLogFilePath: (null: ?string),
_quitStage: ('unready': AppQuitStage),
+ _tunnelState: defaultTunnelStateTransition(),
+ _settings: defaultSettings(),
+
run() {
// Since electron's GPU blacklists are broken, GPU acceleration won't work on older distros
if (process.platform === 'linux') {
@@ -237,38 +248,39 @@ const ApplicationMain = {
async _onDaemonConnected() {
this._connectedToDaemon = true;
- // reset the reconnect backoff when connection established.
- this._reconnectBackoff.reset();
+ // subscribe to events
+ try {
+ await this._subscribeEvents();
+ } catch (error) {
+ log.error(`Failed to subscribe: ${error.message}`);
- if (this._windowController) {
- this._windowController.send('daemon-connected');
+ return this._recoverFromBootstrapError(error);
}
- const stateListener = new SubscriptionListener(
- (newState: TunnelStateTransition) => {
- this._onStateChange(newState);
- },
- (error: Error) => {
- log.error(`Cannot deserialize the new state: ${error.message}`);
- },
- );
+ // fetch the tunnel state
+ try {
+ this._setTunnelState(await this._daemonRpc.getState());
+ } catch (error) {
+ log.error(`Failed to fetch the tunnel state: ${error.message}`);
- const settingsListener = new SubscriptionListener(
- (newSettings: Settings) => {
- this._onSettingsChange(newSettings);
- },
- (error: Error) => {
- log.error(`Cannot deserialize the new settings: ${error.message}`);
- },
- );
+ return this._recoverFromBootstrapError(error);
+ }
+ // fetch settings
try {
- await Promise.all([
- this._daemonRpc.subscribeStateListener(stateListener),
- this._daemonRpc.subscribeSettingsListener(settingsListener),
- ]);
+ this._setSettings(await this._daemonRpc.getSettings());
} catch (error) {
- log.error(`Failed to subscribe: ${error.message}`);
+ log.error(`Failed to fetch settings: ${error.message}`);
+
+ return this._recoverFromBootstrapError(error);
+ }
+
+ // reset the reconnect backoff when connection established.
+ this._reconnectBackoff.reset();
+
+ // notify renderer
+ if (this._windowController) {
+ this._windowController.send('daemon-connected');
}
},
@@ -277,9 +289,7 @@ const ApplicationMain = {
if (error) {
log.debug(`Lost connection to daemon: ${error.message}`);
- this._reconnectBackoff.attempt(() => {
- this._connectToDaemon();
- });
+ this._reconnectToDaemon();
} else {
log.info(`Disconnected from the daemon`);
}
@@ -295,18 +305,75 @@ const ApplicationMain = {
this._daemonRpc.connect({ path: DAEMON_RPC_PATH });
},
- _onStateChange(newState: TunnelStateTransition) {
+ _reconnectToDaemon() {
+ this._reconnectBackoff.attempt(() => {
+ this._connectToDaemon();
+ });
+ },
+
+ _recoverFromBootstrapError(_error: ?Error) {
+ // Attempt to reconnect to daemon if the program fails to fetch settings, tunnel state or
+ // subscribe for RPC events.
+ this._daemonRpc.disconnect();
+
+ this._reconnectToDaemon();
+ },
+
+ async _subscribeEvents(): Promise<void> {
+ const stateListener = new SubscriptionListener(
+ (newState: TunnelStateTransition) => {
+ this._setTunnelState(newState);
+ },
+ (error: Error) => {
+ log.error(`Cannot deserialize the new state: ${error.message}`);
+ },
+ );
+
+ const settingsListener = new SubscriptionListener(
+ (newSettings: Settings) => {
+ this._setSettings(newSettings);
+ },
+ (error: Error) => {
+ log.error(`Cannot deserialize the new settings: ${error.message}`);
+ },
+ );
+
+ await Promise.all([
+ this._daemonRpc.subscribeStateListener(stateListener),
+ this._daemonRpc.subscribeSettingsListener(settingsListener),
+ ]);
+ },
+
+ _setTunnelState(newState: TunnelStateTransition) {
+ this._tunnelState = newState;
+ this._updateTrayIcon(newState.state);
+
if (this._windowController) {
- this._windowController.send('state-changed', newState);
+ this._windowController.send('tunnel-state-changed', newState);
}
},
- _onSettingsChange(newSettings: Settings) {
+ _setSettings(newSettings: Settings) {
+ this._settings = newSettings;
+
if (this._windowController) {
this._windowController.send('settings-changed', newSettings);
}
},
+ _updateTrayIcon(tunnelState: TunnelState) {
+ const iconTypes: { [TunnelState]: TrayIconType } = {
+ connected: 'secured',
+ connecting: 'securing',
+ blocked: 'securing',
+ };
+ const type = iconTypes[tunnelState] || 'unsecured';
+
+ if (this._trayIconController) {
+ this._trayIconController.animateToIcon(type);
+ }
+ },
+
_registerWindowListener(windowController: WindowController) {
const window = windowController.window;
@@ -315,16 +382,16 @@ const ApplicationMain = {
_registerIpcListeners() {
ipcMain.on('daemon-rpc-call', async (event, id: string, method: string, payload: any) => {
- log.debug(`Got daemon-rpc-call: ${id} ${method} ${payload}`);
+ log.debug(`Got daemon-rpc-call: ${id} ${method}`);
try {
// $FlowFixMe: flow does not like index accessors.
const result = await this._daemonRpc[method](payload);
- log.debug(`Reply to ${id} ${method} with success: ${JSON.stringify(result)}`);
+ log.debug(`Send daemon-rpc-reply-${id} ${method} with success`);
event.sender.send(`daemon-rpc-reply-${id}`, result);
} catch (error) {
- log.debug(`Reply to ${id} ${method} with error: ${error.message}`);
+ log.debug(`Send daemon-rpc-reply-${id} ${method} with error: ${error.message}`);
event.sender.send(`daemon-rpc-reply-${id}`, undefined, {
className: error.constructor.name || '',
data: {
@@ -335,8 +402,13 @@ const ApplicationMain = {
}
});
- ipcMain.on('daemon-connection-status', (event) => {
- event.sender.send('daemon-connection-status-reply', this._connectedToDaemon);
+ ipcMain.on('get-state', (event) => {
+ event.sender.send(
+ 'get-state-reply',
+ this._connectedToDaemon,
+ this._tunnelState,
+ this._settings,
+ );
});
ipcMain.on('show-window', () => {
@@ -346,20 +418,6 @@ const ApplicationMain = {
}
});
- ipcMain.on('hide-window', () => {
- const windowController = this._windowController;
- if (windowController) {
- windowController.hide();
- }
- });
-
- ipcMain.on('change-tray-icon', (_event: any, type: TrayIconType) => {
- const trayIconController = this._trayIconController;
- if (trayIconController) {
- trayIconController.animateToIcon(type);
- }
- });
-
ipcMain.on('collect-logs', (event, requestId, toRedact) => {
const reportPath = path.join(app.getPath('temp'), uuid.v4() + '.log');
const executable = resolveBin('problem-report');
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js
index cd9d003659..e21a64aafb 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.js
@@ -23,9 +23,6 @@ import settingsActions from './redux/settings/actions';
import versionActions from './redux/version/actions';
import userInterfaceActions from './redux/userinterface/actions';
-import SettingsProxy from './lib/subscription-proxy/settings-proxy';
-import TunnelStateProxy from './lib/subscription-proxy/tunnel-state-proxy';
-
import type { WindowShapeParameters } from '../main/window-controller';
import type {
AccountToken,
@@ -38,10 +35,12 @@ import type {
AccountData,
} from './lib/daemon-rpc-proxy';
-import DaemonRpcProxy from './lib/daemon-rpc-proxy';
+import DaemonRpcProxy, {
+ defaultSettings,
+ defaultTunnelStateTransition,
+} from './lib/daemon-rpc-proxy';
import type { ReduxStore } from './redux/store';
-import type { TrayIconType } from '../main/tray-icon-controller';
const RELAY_LIST_UPDATE_INTERVAL = 60 * 60 * 1000;
@@ -68,12 +67,10 @@ export default class AppRenderer {
this._updateRelayLocations(relayList);
},
);
- _tunnelStateProxy = new TunnelStateProxy(this._daemonRpc, (tunnelState) => {
- this._setTunnelState(tunnelState);
- });
- _settingsProxy = new SettingsProxy(this._daemonRpc, (settings) => {
- this._setSettings(settings);
- });
+
+ _tunnelState = defaultTunnelStateTransition();
+ _settings = defaultSettings();
+
_connectedToDaemon = false;
constructor() {
@@ -118,14 +115,33 @@ export default class AppRenderer {
this._onDaemonDisconnected(errorMessage ? new Error(errorMessage) : null);
});
- // Request the initial daemon connection status
- ipcRenderer.once('daemon-connection-status-reply', (isConnected: boolean) => {
- if (isConnected) {
- this._onDaemonConnected();
- }
+ ipcRenderer.on('tunnel-state-changed', (_event: Event, newState: TunnelStateTransition) => {
+ this._setTunnelState(newState);
});
- ipcRenderer.send('daemon-connection-status');
+ ipcRenderer.on('settings-changed', (_event: Event, newSettings: Settings) => {
+ this._setSettings(newSettings);
+ });
+
+ // Request the initial state from main process
+ ipcRenderer.on(
+ 'get-state-reply',
+ (
+ _event: Event,
+ isConnected: boolean,
+ tunnelState: TunnelStateTransition,
+ settings: Settings,
+ ) => {
+ this._setTunnelState(tunnelState);
+ this._setSettings(settings);
+
+ if (isConnected) {
+ this._onDaemonConnected();
+ }
+ },
+ );
+
+ ipcRenderer.send('get-state');
// disable pinch to zoom
webFrame.setVisualZoomLevelLimits(1, 1);
@@ -216,10 +232,8 @@ export default class AppRenderer {
async connectTunnel() {
const actions = this._reduxActions;
- const tunnelState = await this._tunnelStateProxy.fetch();
-
// connect only if tunnel is disconnected or blocked.
- if (tunnelState.state === 'disconnected' || tunnelState.state === 'blocked') {
+ if (this._tunnelState.state === 'disconnected' || this._tunnelState.state === 'blocked') {
// switch to connecting state immediately to prevent a lag that may be caused by RPC
// communication delay
actions.connection.connecting(null);
@@ -283,10 +297,8 @@ export default class AppRenderer {
}
async updateAccountExpiry() {
- const settings = await this._settingsProxy.fetch();
-
- if (settings && settings.accountToken) {
- this._accountDataCache.fetch(settings.accountToken);
+ if (this._settings.accountToken) {
+ this._accountDataCache.fetch(this._settings.accountToken);
}
}
@@ -428,45 +440,6 @@ export default class AppRenderer {
this._connectedToDaemon = true;
try {
- await this._runPrimaryApplicationFlow();
- } catch (error) {
- log.error(`An error was raised when running the primary application flow: ${error.message}`);
- }
- }
-
- _onDaemonDisconnected(error: ?Error) {
- const actions = this._reduxActions;
-
- this._relayListCache.stopUpdating();
-
- // recover connection on error
- if (error) {
- // only send to the connecting to daemon view if the daemon was
- // connnected previously
- if (this._connectedToDaemon) {
- actions.history.replace('/');
- }
- }
-
- this._connectedToDaemon = false;
- }
-
- async _runPrimaryApplicationFlow() {
- // fetch initial state and subscribe for changes
- try {
- await this._settingsProxy.fetch();
- } catch (error) {
- log.error(`Cannot fetch the initial settings: ${error.message}`);
- }
-
- try {
- await this._tunnelStateProxy.fetch();
- } catch (error) {
- log.error(`Cannot fetch the initial tunnel state: ${error.message}`);
- }
-
- // fetch the rest of data
- try {
await this._fetchCurrentVersion();
} catch (error) {
log.error(`Cannot fetch the current version: ${error.message}`);
@@ -488,33 +461,29 @@ export default class AppRenderer {
} catch (error) {
log.error(`Cannot fetch the latest version information: ${error.message}`);
}
+ }
- // auto connect the tunnel on startup
- // note: disabled when developing
- if (process.env.NODE_ENV !== 'development') {
- const settings = await this._settingsProxy.fetch();
+ _onDaemonDisconnected(error: ?Error) {
+ const actions = this._reduxActions;
- // only connect if account is set in the daemon
- if (settings.accountToken) {
- try {
- log.debug('Autoconnect the tunnel');
- await this.connectTunnel();
- } catch (error) {
- log.error(`Failed to autoconnect the tunnel: ${error.message}`);
- }
- } else {
- log.debug('Skip autoconnect because account token is not set');
+ this._relayListCache.stopUpdating();
+
+ // recover connection on error
+ if (error) {
+ // only send to the connecting to daemon view if the daemon was
+ // connnected previously
+ if (this._connectedToDaemon) {
+ actions.history.replace('/');
}
- } else {
- log.debug('Skip autoconnect in development');
}
+
+ this._connectedToDaemon = false;
}
async _setStartView() {
const actions = this._reduxActions;
const history = this._memoryHistory;
- const settings = await this._settingsProxy.fetch();
- const accountToken = settings.accountToken;
+ const accountToken = this._settings.accountToken;
if (accountToken) {
log.debug(`Account token is set. Showing the tunnel view.`);
@@ -560,13 +529,16 @@ export default class AppRenderer {
_setTunnelState(tunnelState: TunnelStateTransition) {
log.debug(`Tunnel state: ${tunnelState.state}`);
+ this._tunnelState = tunnelState;
+
this._updateConnectionStatus(tunnelState);
this._updateUserLocation(tunnelState.state);
- this._updateTrayIcon(tunnelState.state);
this._notificationController.notifyTunnelState(tunnelState);
}
_setSettings(newSettings: Settings) {
+ this._settings = newSettings;
+
const reduxSettings = this._reduxActions.settings;
reduxSettings.updateAllowLan(newSettings.allowLan);
@@ -616,17 +588,6 @@ export default class AppRenderer {
break;
}
}
-
- _updateTrayIcon(tunnelState: TunnelState) {
- const iconTypes: { [TunnelState]: TrayIconType } = {
- connected: 'secured',
- connecting: 'securing',
- blocked: 'securing',
- };
- const type = iconTypes[tunnelState] || 'unsecured';
-
- ipcRenderer.send('change-tray-icon', type);
- }
}
type AccountVerification = { status: 'verified' } | { status: 'deferred', error: Error };
diff --git a/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js b/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
index df2c5b72b6..b3d326a5a6 100644
--- a/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
+++ b/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
@@ -4,6 +4,7 @@ import { ipcRenderer } from 'electron';
import log from 'electron-log';
import uuid from 'uuid';
+// Re-export types
export type {
AccountToken,
AccountData,
@@ -27,17 +28,12 @@ export type {
DaemonRpcProtocol,
} from '../../main/daemon-rpc';
-export { ConnectionObserver, SubscriptionListener } from '../../main/daemon-rpc';
-
-import {
- NoCreditError,
- NoInternetError,
- NoDaemonError,
- InvalidAccountError,
- CommunicationError,
-} from '../../main/errors';
-
-import { TimeOutError, RemoteError } from '../../main/jsonrpc-client';
+export {
+ ConnectionObserver,
+ SubscriptionListener,
+ defaultSettings,
+ defaultTunnelStateTransition,
+} from '../../main/daemon-rpc';
import type {
AccountToken,
@@ -50,8 +46,19 @@ import type {
Settings,
Location,
} from '../../main/daemon-rpc';
+
import { ConnectionObserver, SubscriptionListener } from '../../main/daemon-rpc';
+import {
+ NoCreditError,
+ NoInternetError,
+ NoDaemonError,
+ InvalidAccountError,
+ CommunicationError,
+} from '../../main/errors';
+
+import { TimeOutError, RemoteError } from '../../main/jsonrpc-client';
+
type ErrorInfo = {
className: string,
data: Object,
@@ -192,17 +199,16 @@ export default class DaemonRpcProxy implements DaemonRpcProtocol {
ipcRenderer.once(
`daemon-rpc-reply-${id}`,
(_event: Event, result: R, errorInfo: ?ErrorInfo) => {
- log.debug(
- `Got daemon-rpc-reply: ${id} ${method} ${JSON.stringify(result)} ${JSON.stringify(
- errorInfo,
- )}`,
- );
-
if (errorInfo) {
const error = this._deserializeError(errorInfo.className, errorInfo.data);
- log.debug(`Deserialized an error to instance of ${error.constructor.name}`);
+
+ log.debug(
+ `Got daemon-rpc-reply-${id} ${method} with error: ${JSON.stringify(errorInfo)}`,
+ );
+
reject(error);
} else {
+ log.debug(`Got daemon-rpc-reply-${id} ${method} with success`);
resolve(result);
}
},
diff --git a/gui/packages/desktop/src/renderer/lib/subscription-proxy/base-proxy.js b/gui/packages/desktop/src/renderer/lib/subscription-proxy/base-proxy.js
deleted file mode 100644
index 5d34ff8839..0000000000
--- a/gui/packages/desktop/src/renderer/lib/subscription-proxy/base-proxy.js
+++ /dev/null
@@ -1,118 +0,0 @@
-// @flow
-
-import log from 'electron-log';
-import { ConnectionObserver, SubscriptionListener, ResponseParseError } from '../daemon-rpc-proxy';
-import type { DaemonRpcProtocol } from '../daemon-rpc-proxy';
-
-export default class BaseSubscriptionProxy<T> {
- _rpc: DaemonRpcProtocol;
- _connectionObserver = new ConnectionObserver(
- () => {},
- () => {
- this._didDisconnectFromDaemon();
- },
- );
-
- _isSubscribed = false;
- _executingPromise: ?Promise<T>;
-
- _value: ?T;
- _onUpdate: (T) => void;
-
- constructor(rpc: DaemonRpcProtocol, onUpdate: (T) => void) {
- this._rpc = rpc;
- this._onUpdate = onUpdate;
-
- rpc.addConnectionObserver(this._connectionObserver);
- }
-
- async fetch(): Promise<T> {
- // return the cached promise if there is an ongoing fetch
- if (this._executingPromise) {
- return this._executingPromise;
- }
-
- // return the value if it's available
- if (this._value) {
- return this._value;
- }
-
- // subscribe if needed and fetch the initial state.
- const fetchPromise = this._subscribeAndFetchValue();
-
- // cache the fetch promise
- this._executingPromise = fetchPromise;
-
- try {
- const value = await fetchPromise;
-
- // cache the initial value
- this._value = value;
-
- // notify the delegate upon initial fetch
- this._onUpdate(value);
-
- return value;
- } catch (error) {
- throw error;
- } finally {
- // unset the cached fetch promise
- this._executingPromise = null;
- }
- }
-
- async _subscribeAndFetchValue(): Promise<T> {
- if (!this._isSubscribed) {
- await this._subscribeValueListener();
- this._isSubscribed = true;
- }
-
- // request the initial value
- return await this.constructor.requestValue(this._rpc);
- }
-
- static subscribeValueListener(
- _rpc: DaemonRpcProtocol,
- _listener: SubscriptionListener<T>,
- ): Promise<void> {
- throw new Error(
- `Override static ${this.constructor.name}.subscribeValueListener() in subclasses`,
- );
- }
-
- static requestValue(_rpc: DaemonRpcProtocol): Promise<T> {
- throw new Error(`Override static ${this.constructor.name}.requestValue() in subclasses`);
- }
-
- _subscribeValueListener(): Promise<void> {
- const listener = new SubscriptionListener(
- (value: T) => {
- this._didReceiveUpdate(value);
- },
- (error: Error) => {
- let reason = '';
-
- if (error instanceof ResponseParseError) {
- const validationError = error.validationError;
- if (validationError) {
- reason = ` Reason: ${validationError.message}`;
- }
- }
-
- log.error(`Failed to deserialize the payload: ${error.message}.${reason}`);
- },
- );
- return this.constructor.subscribeValueListener(this._rpc, listener);
- }
-
- _didReceiveUpdate(updatedValue: T) {
- this._value = updatedValue;
- this._onUpdate(updatedValue);
- }
-
- _didDisconnectFromDaemon() {
- this._isSubscribed = false;
- this._executingPromise = null;
- this._value = null;
- }
-}
diff --git a/gui/packages/desktop/src/renderer/lib/subscription-proxy/settings-proxy.js b/gui/packages/desktop/src/renderer/lib/subscription-proxy/settings-proxy.js
deleted file mode 100644
index c7fb9b3b3b..0000000000
--- a/gui/packages/desktop/src/renderer/lib/subscription-proxy/settings-proxy.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// @flow
-
-import BaseSubscriptionProxy from './base-proxy';
-import { SubscriptionListener } from '../daemon-rpc-proxy';
-import type { DaemonRpcProtocol, Settings } from '../daemon-rpc-proxy';
-
-export default class SettingsProxy extends BaseSubscriptionProxy<Settings> {
- static subscribeValueListener(rpc: DaemonRpcProtocol, listener: SubscriptionListener<Settings>) {
- return rpc.subscribeSettingsListener(listener);
- }
-
- static requestValue(rpc: DaemonRpcProtocol): Promise<Settings> {
- return rpc.getSettings();
- }
-}
diff --git a/gui/packages/desktop/src/renderer/lib/subscription-proxy/tunnel-state-proxy.js b/gui/packages/desktop/src/renderer/lib/subscription-proxy/tunnel-state-proxy.js
deleted file mode 100644
index 4c1afa66d6..0000000000
--- a/gui/packages/desktop/src/renderer/lib/subscription-proxy/tunnel-state-proxy.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// @flow
-
-import BaseSubscriptionProxy from './base-proxy';
-import { SubscriptionListener } from '../daemon-rpc-proxy';
-import type { DaemonRpcProtocol, TunnelStateTransition } from '../daemon-rpc-proxy';
-
-export default class TunnelStateProxy extends BaseSubscriptionProxy<TunnelStateTransition> {
- static subscribeValueListener(
- rpc: DaemonRpcProtocol,
- listener: SubscriptionListener<TunnelStateTransition>,
- ) {
- return rpc.subscribeStateListener(listener);
- }
-
- static requestValue(rpc: DaemonRpcProtocol): Promise<TunnelStateTransition> {
- return rpc.getState();
- }
-}