summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-01-23 13:33:14 +0100
committerAndrej Mihajlov <and@mullvad.net>2019-01-23 15:37:57 +0100
commitb1b35e5b902b7e66b3c86160137be7fbf1d88f92 (patch)
tree2d15e2c26e747f8337e2350c90085e1639d9fe0c
parent181bbf34c63efdbac6f09b5a1e39944b8acf4196 (diff)
downloadmullvadvpn-b1b35e5b902b7e66b3c86160137be7fbf1d88f92.tar.xz
mullvadvpn-b1b35e5b902b7e66b3c86160137be7fbf1d88f92.zip
Migrate autostart logic to the main process
-rw-r--r--gui/packages/desktop/src/main/autostart.js (renamed from gui/packages/desktop/src/renderer/lib/autostart.js)10
-rw-r--r--gui/packages/desktop/src/main/index.js34
-rw-r--r--gui/packages/desktop/src/renderer/app.js36
-rw-r--r--gui/packages/desktop/src/renderer/components/Preferences.js21
-rw-r--r--gui/packages/desktop/src/renderer/containers/PreferencesPage.js5
-rw-r--r--gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js4
-rw-r--r--gui/packages/desktop/src/renderer/redux/settings/actions.js16
-rw-r--r--gui/packages/desktop/src/renderer/redux/settings/reducers.js8
-rw-r--r--gui/packages/desktop/src/shared/ipc-event-channel.js28
9 files changed, 112 insertions, 50 deletions
diff --git a/gui/packages/desktop/src/renderer/lib/autostart.js b/gui/packages/desktop/src/main/autostart.js
index 7617b9b13a..614df69350 100644
--- a/gui/packages/desktop/src/renderer/lib/autostart.js
+++ b/gui/packages/desktop/src/main/autostart.js
@@ -3,7 +3,7 @@
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
-import { remote } from 'electron';
+import { app } from 'electron';
import log from 'electron-log';
const DESKTOP_FILE_NAME = 'mullvad-vpn.desktop';
@@ -16,7 +16,7 @@ const unlinkAsync = promisify(fs.unlink);
export function getOpenAtLogin() {
if (process.platform === 'linux') {
try {
- const autostartDir = path.join(remote.app.getPath('appData'), 'autostart');
+ const autostartDir = path.join(app.getPath('appData'), 'autostart');
const autostartFilePath = path.join(autostartDir, DESKTOP_FILE_NAME);
fs.accessSync(autostartFilePath);
@@ -27,7 +27,7 @@ export function getOpenAtLogin() {
return false;
}
} else {
- return remote.app.getLoginItemSettings().openAtLogin;
+ return app.getLoginItemSettings().openAtLogin;
}
}
@@ -35,7 +35,7 @@ export async function setOpenAtLogin(openAtLogin: boolean) {
if (process.platform === 'linux') {
try {
const desktopFilePath = path.join('/usr/share/applications', DESKTOP_FILE_NAME);
- const autostartDir = path.join(remote.app.getPath('appData'), 'autostart');
+ const autostartDir = path.join(app.getPath('appData'), 'autostart');
const autostartFilePath = path.join(autostartDir, DESKTOP_FILE_NAME);
if (openAtLogin) {
@@ -48,7 +48,7 @@ export async function setOpenAtLogin(openAtLogin: boolean) {
log.error(`Failed to set auto-start: ${error.message}`);
}
} else {
- remote.app.setLoginItemSettings({ openAtLogin });
+ app.setLoginItemSettings({ openAtLogin });
}
}
diff --git a/gui/packages/desktop/src/main/index.js b/gui/packages/desktop/src/main/index.js
index d63a65a944..d1598c3210 100644
--- a/gui/packages/desktop/src/main/index.js
+++ b/gui/packages/desktop/src/main/index.js
@@ -8,6 +8,7 @@ import mkdirp from 'mkdirp';
import uuid from 'uuid';
import { app, screen, BrowserWindow, ipcMain, Tray, Menu, nativeImage } from 'electron';
+import { getOpenAtLogin, setOpenAtLogin } from './autostart';
import NotificationController from './notification-controller';
import WindowController from './window-controller';
@@ -298,6 +299,10 @@ const ApplicationMain = {
}
}
+ if (newState.autoConnect !== oldState.autoConnect) {
+ this._updateDaemonsAutoConnect();
+ }
+
if (this._windowController) {
IpcMainEventChannel.guiSettings.notify(this._windowController.webContents, newState);
}
@@ -751,6 +756,7 @@ const ApplicationMain = {
IpcMainEventChannel.state.handleGet(() => ({
isConnected: this._connectedToDaemon,
+ autoStart: getOpenAtLogin(),
tunnelState: this._tunnelState,
settings: this._settings,
location: this._location,
@@ -760,6 +766,10 @@ const ApplicationMain = {
guiSettings: this._guiSettings.state,
}));
+ IpcMainEventChannel.autoStart.handleSet((autoStart: boolean) => {
+ return this._setAutoStart(autoStart);
+ });
+
IpcMainEventChannel.guiSettings.handleAutoConnect((autoConnect: boolean) => {
this._guiSettings.autoConnect = autoConnect;
});
@@ -854,6 +864,30 @@ const ApplicationMain = {
);
},
+ _updateDaemonsAutoConnect() {
+ const daemonAutoConnect = this._guiSettings.autoConnect && getOpenAtLogin();
+ if (daemonAutoConnect !== this._settings.autoConnect) {
+ this._daemonRpc.setAutoConnect(daemonAutoConnect);
+ }
+ },
+
+ async _setAutoStart(autoStart: boolean): Promise<void> {
+ try {
+ await setOpenAtLogin(autoStart);
+
+ if (this._windowController) {
+ IpcMainEventChannel.autoStart.notify(this._windowController.webContents, autoStart);
+ }
+
+ this._updateDaemonsAutoConnect();
+ } catch (error) {
+ log.error(
+ `Failed to update the autostart to ${autoStart.toString()}. ${error.message.toString()}`,
+ );
+ }
+ return Promise.resolve();
+ },
+
async _installDevTools() {
const installer = require('electron-devtools-installer');
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js
index f433688a98..1506b5fa9b 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.js
@@ -14,7 +14,6 @@ import { createMemoryHistory } from 'history';
import { InvalidAccountError } from '../main/errors';
import makeRoutes from './routes';
-import { getOpenAtLogin, setOpenAtLogin } from './lib/autostart';
import configureStore from './redux/store';
import accountActions from './redux/account/actions';
@@ -58,6 +57,7 @@ export default class AppRenderer {
_tunnelState: TunnelStateTransition;
_settings: Settings;
+ _guiSettings: GuiSettingsState;
_connectedToDaemon = false;
_autoConnected = false;
_doingLogin = false;
@@ -131,6 +131,10 @@ export default class AppRenderer {
this._setGuiSettings(guiSettings);
});
+ IpcRendererEventChannel.autoStart.listen((autoStart: boolean) => {
+ this._setAutoStart(autoStart);
+ });
+
// Request the initial state from the main process
const initialState = IpcRendererEventChannel.state.get();
@@ -145,6 +149,7 @@ export default class AppRenderer {
this._setCurrentVersion(initialState.currentVersion);
this._setUpgradeVersion(initialState.upgradeVersion);
this._setGuiSettings(initialState.guiSettings);
+ this._setAutoStart(initialState.autoStart);
if (initialState.isConnected) {
this._onDaemonConnected();
@@ -331,27 +336,15 @@ export default class AppRenderer {
}
async setAutoConnect(autoConnect: boolean) {
- const actions = this._reduxActions;
- await IpcRendererEventChannel.guiSettings.setAutoConnect(autoConnect);
- await this._setDaemonAutoConnect(autoConnect, getOpenAtLogin());
- actions.settings.updateAutoConnect(autoConnect);
- }
+ this._reduxActions.settings.updateAutoConnect(autoConnect);
- _getAutoConnect(): boolean {
- return this._reduxStore.getState().settings.guiSettings.autoConnect;
+ return IpcRendererEventChannel.guiSettings.setAutoConnect(autoConnect);
}
- async setAutoStart(autoStart: boolean) {
- await setOpenAtLogin(autoStart);
- await this._setDaemonAutoConnect(this._getAutoConnect(), autoStart);
- }
+ async setAutoStart(autoStart: boolean): Promise<void> {
+ this._setAutoStart(autoStart);
- async _setDaemonAutoConnect(guiAutoConnect: boolean, autoStart: boolean) {
- const daemonAutoConnect = guiAutoConnect && autoStart;
-
- if (daemonAutoConnect !== this._settings.autoConnect) {
- await this._daemonRpc.setAutoConnect(daemonAutoConnect);
- }
+ return IpcRendererEventChannel.autoStart.set(autoStart);
}
setStartMinimized(startMinimized: boolean) {
@@ -400,7 +393,7 @@ export default class AppRenderer {
} else if (this._autoConnected) {
log.debug('Skip autoconnect because it was done before');
} else if (this._settings.accountToken) {
- if (this._getAutoConnect()) {
+ if (this._guiSettings.autoConnect) {
try {
log.debug('Autoconnect the tunnel');
@@ -526,8 +519,13 @@ export default class AppRenderer {
}
_setGuiSettings(guiSettings: GuiSettingsState) {
+ this._guiSettings = guiSettings;
this._reduxActions.settings.updateGuiSettings(guiSettings);
}
+
+ _setAutoStart(autoStart: boolean) {
+ this._reduxActions.settings.updateAutoStart(autoStart);
+ }
}
type AccountVerification = { status: 'verified' } | { status: 'deferred', error: Error };
diff --git a/gui/packages/desktop/src/renderer/components/Preferences.js b/gui/packages/desktop/src/renderer/components/Preferences.js
index b7191804ed..b5b8405b75 100644
--- a/gui/packages/desktop/src/renderer/components/Preferences.js
+++ b/gui/packages/desktop/src/renderer/components/Preferences.js
@@ -16,13 +16,13 @@ import Switch from './Switch';
import styles from './PreferencesStyles';
export type PreferencesProps = {
+ autoStart: boolean,
autoConnect: boolean,
allowLan: boolean,
monochromaticIcon: boolean,
startMinimized: boolean,
enableMonochromaticIconToggle: boolean,
enableStartMinimizedToggle: boolean,
- getAutoStart: () => boolean,
setAutoStart: (boolean) => void,
setAutoConnect: (boolean) => void,
setAllowLan: (boolean) => void,
@@ -31,20 +31,7 @@ export type PreferencesProps = {
onClose: () => void,
};
-type State = {
- autoStart: boolean,
-};
-
-export default class Preferences extends Component<PreferencesProps, State> {
- state = {
- autoStart: false,
- };
-
- constructor(props: PreferencesProps) {
- super();
- this.state.autoStart = props.getAutoStart();
- }
-
+export default class Preferences extends Component<PreferencesProps> {
render() {
return (
<Layout>
@@ -65,7 +52,7 @@ export default class Preferences extends Component<PreferencesProps, State> {
<View style={styles.preferences__content}>
<Cell.Container>
<Cell.Label>Launch app on start-up</Cell.Label>
- <Switch isOn={this.state.autoStart} onChange={this._onChangeAutoStart} />
+ <Switch isOn={this.props.autoStart} onChange={this._onChangeAutoStart} />
</Cell.Container>
<View style={styles.preferences__separator} />
@@ -108,8 +95,6 @@ export default class Preferences extends Component<PreferencesProps, State> {
_onChangeAutoStart = (autoStart: boolean) => {
this.props.setAutoStart(autoStart);
- // TODO: Handle failure to set auto-start
- this.setState({ autoStart });
};
}
diff --git a/gui/packages/desktop/src/renderer/containers/PreferencesPage.js b/gui/packages/desktop/src/renderer/containers/PreferencesPage.js
index 565160c528..0d18e50bee 100644
--- a/gui/packages/desktop/src/renderer/containers/PreferencesPage.js
+++ b/gui/packages/desktop/src/renderer/containers/PreferencesPage.js
@@ -5,12 +5,12 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { goBack } from 'connected-react-router';
import Preferences from '../components/Preferences';
-import { getOpenAtLogin } from '../lib/autostart';
import type { ReduxState, ReduxDispatch } from '../redux/store';
import type { SharedRouteProps } from '../routes';
const mapStateToProps = (state: ReduxState) => ({
+ autoStart: state.settings.autoStart,
autoConnect: state.settings.guiSettings.autoConnect,
allowLan: state.settings.allowLan,
monochromaticIcon: state.settings.guiSettings.monochromaticIcon,
@@ -23,9 +23,6 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
onClose: () => {
history.goBack();
},
- getAutoStart: () => {
- return getOpenAtLogin();
- },
setAutoStart: async (autoStart) => {
try {
await props.app.setAutoStart(autoStart);
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 182fb0fbb2..45a4abe89c 100644
--- a/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
+++ b/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
@@ -130,8 +130,8 @@ export default class DaemonRpcProxy implements DaemonRpcProtocol {
return this._sendMessage('setOpenVpnMssfix', mssfix);
}
- setAutoConnect(autoConnect: boolean): Promise<void> {
- return this._sendMessage('setAutoConnect', autoConnect);
+ setAutoConnect(_autoConnect: boolean): Promise<void> {
+ throw new Error('Do not call this method.');
}
connectTunnel(): Promise<void> {
diff --git a/gui/packages/desktop/src/renderer/redux/settings/actions.js b/gui/packages/desktop/src/renderer/redux/settings/actions.js
index ff6e8a0e3d..20b185c8b3 100644
--- a/gui/packages/desktop/src/renderer/redux/settings/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/settings/actions.js
@@ -43,6 +43,11 @@ export type UpdateOpenVpnMssfixAction = {
mssfix: ?number,
};
+export type UpdateAutoStartAction = {
+ type: 'UPDATE_AUTO_START',
+ autoStart: boolean,
+};
+
export type SettingsAction =
| UpdateGuiSettingsAction
| UpdateRelayAction
@@ -51,7 +56,8 @@ export type SettingsAction =
| UpdateAllowLanAction
| UpdateEnableIpv6Action
| UpdateBlockWhenDisconnectedAction
- | UpdateOpenVpnMssfixAction;
+ | UpdateOpenVpnMssfixAction
+ | UpdateAutoStartAction;
function updateGuiSettings(guiSettings: GuiSettingsState): UpdateGuiSettingsAction {
return {
@@ -113,6 +119,13 @@ function updateOpenVpnMssfix(mssfix: ?number): UpdateOpenVpnMssfixAction {
};
}
+function updateAutoStart(autoStart: boolean): UpdateAutoStartAction {
+ return {
+ type: 'UPDATE_AUTO_START',
+ autoStart,
+ };
+}
+
export default {
updateGuiSettings,
updateRelay,
@@ -122,4 +135,5 @@ export default {
updateEnableIpv6,
updateBlockWhenDisconnected,
updateOpenVpnMssfix,
+ updateAutoStart,
};
diff --git a/gui/packages/desktop/src/renderer/redux/settings/reducers.js b/gui/packages/desktop/src/renderer/redux/settings/reducers.js
index 7f5d1c42ef..b92a72d7d0 100644
--- a/gui/packages/desktop/src/renderer/redux/settings/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/settings/reducers.js
@@ -45,6 +45,7 @@ export type RelayLocationRedux = {
};
export type SettingsReduxState = {
+ autoStart: boolean,
guiSettings: GuiSettingsState,
relaySettings: RelaySettingsRedux,
relayLocations: Array<RelayLocationRedux>,
@@ -57,6 +58,7 @@ export type SettingsReduxState = {
};
const initialState: SettingsReduxState = {
+ autoStart: false,
guiSettings: {
autoConnect: true,
monochromaticIcon: false,
@@ -134,6 +136,12 @@ export default function(
},
};
+ case 'UPDATE_AUTO_START':
+ return {
+ ...state,
+ autoStart: action.autoStart,
+ };
+
default:
return state;
}
diff --git a/gui/packages/desktop/src/shared/ipc-event-channel.js b/gui/packages/desktop/src/shared/ipc-event-channel.js
index 029ff7dd26..273a543790 100644
--- a/gui/packages/desktop/src/shared/ipc-event-channel.js
+++ b/gui/packages/desktop/src/shared/ipc-event-channel.js
@@ -17,6 +17,7 @@ import type {
export type AppStateSnapshot = {
isConnected: boolean,
+ autoStart: boolean,
tunnelState: TunnelStateTransition,
settings: Settings,
location: ?Location,
@@ -66,6 +67,15 @@ interface AccountHistoryMethods {
removeItem(token: AccountToken): Promise<void>;
}
+interface AutoStartMethods {
+ listen(fn: (boolean) => void): void;
+ set(autoStart: boolean): Promise<void>;
+}
+
+interface AutoStartHandlers {
+ handleSet: ((boolean) => Promise<void>) => void;
+}
+
/// Events names
const DAEMON_CONNECTED = 'daemon-connected';
@@ -76,17 +86,23 @@ const LOCATION_CHANGED = 'location-changed';
const RELAYS_CHANGED = 'relays-changed';
const CURRENT_VERSION_CHANGED = 'current-version-changed';
const UPGRADE_VERSION_CHANGED = 'upgrade-version-changed';
-const GUI_SETTINGS_CHANGED = 'gui-settings-changed';
+const GUI_SETTINGS_CHANGED = 'gui-settings-changed';
const SET_AUTO_CONNECT = 'set-auto-connect';
const SET_MONOCHROMATIC_ICON = 'set-monochromatic-icon';
const SET_START_MINIMIZED = 'set-start-minimized';
+
const GET_APP_STATE = 'get-app-state';
+
const GET_ACCOUNT_HISTORY = 'get-account-history';
const REMOVE_ACCOUNT_HISTORY_ITEM = 'remove-account-history-item';
+
const SET_ACCOUNT = 'set-account';
const UNSET_ACCOUNT = 'unset-account';
+const AUTO_START_CHANGED = 'auto-start-changed';
+const SET_AUTO_START = 'set-auto-start';
+
/// Typed IPC event channel
///
/// Static methods are meant to be provide the way to send the events from a renderer process, while
@@ -139,6 +155,11 @@ export class IpcRendererEventChannel {
setStartMinimized: set(SET_START_MINIMIZED),
};
+ static autoStart: Receiver<boolean> & AutoStartMethods = {
+ listen: listen(AUTO_START_CHANGED),
+ set: requestSender(SET_AUTO_START),
+ };
+
static account: AccountMethods = {
set: requestSender(SET_ACCOUNT),
unset: requestSender(UNSET_ACCOUNT),
@@ -198,6 +219,11 @@ export class IpcMainEventChannel {
handleStartMinimized: handler(SET_START_MINIMIZED),
};
+ static autoStart: Sender<boolean> & AutoStartHandlers = {
+ notify: sender(AUTO_START_CHANGED),
+ handleSet: requestHandler(SET_AUTO_START),
+ };
+
static account: AccountHandlers = {
handleSet: requestHandler(SET_ACCOUNT),
handleUnset: requestHandler(UNSET_ACCOUNT),