summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-07-27 13:18:47 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-07-27 13:18:47 -0300
commit0f0bd402988c91951d004a3c4ee802faf52d504f (patch)
tree366c63262868212b925fbae64613c27b9b19aca5
parentd120021305aeb01ce106e3c1e8a53a5295424ccb (diff)
parent8b55f0f1246b4a89f55e66e4ad92865364448794 (diff)
downloadmullvadvpn-0f0bd402988c91951d004a3c4ee802faf52d504f.tar.xz
mullvadvpn-0f0bd402988c91951d004a3c4ee802faf52d504f.zip
Merge branch 'linux-autostart'
-rw-r--r--app/components/Preferences.js1
-rw-r--r--app/lib/platform.js93
2 files changed, 79 insertions, 15 deletions
diff --git a/app/components/Preferences.js b/app/components/Preferences.js
index ceb76f4384..3fe803a156 100644
--- a/app/components/Preferences.js
+++ b/app/components/Preferences.js
@@ -99,6 +99,7 @@ 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/app/lib/platform.js b/app/lib/platform.js
index 0e46341149..2ba438274f 100644
--- a/app/lib/platform.js
+++ b/app/lib/platform.js
@@ -1,10 +1,18 @@
// @flow
+import fs from 'fs';
import { remote, shell } from 'electron';
import electronLog from 'electron-log';
import { execFile } from 'child_process';
+import path from 'path';
import { promisify } from 'util';
+const DESKTOP_FILE_NAME = 'mullvad-vpn.desktop';
+
const execFileAsync = promisify(execFile);
+const mkdirAsync = promisify(fs.mkdir);
+const statAsync = promisify(fs.stat);
+const symlinkAsync = promisify(fs.symlink);
+const unlinkAsync = promisify(fs.unlink);
const log = electronLog;
@@ -12,33 +20,88 @@ const getAppVersion = () => {
return remote.app.getVersion();
};
-const getOpenAtLogin = () => {
- return remote.app.getLoginItemSettings().openAtLogin;
+const getOpenAtLogin = (): boolean => {
+ if (process.platform === 'linux') {
+ try {
+ const autostartDir = path.join(remote.app.getPath('appData'), 'autostart');
+ const autostartFilePath = path.join(autostartDir, DESKTOP_FILE_NAME);
+
+ fs.accessSync(autostartFilePath);
+
+ return true;
+ } catch (error) {
+ log.debug(`Failed to check autostart file: ${error.message}`);
+ return false;
+ }
+ } else {
+ return remote.app.getLoginItemSettings().openAtLogin;
+ }
};
const setOpenAtLogin = async (openAtLogin: boolean) => {
// setLoginItemSettings is broken on macOS and cannot delete login items.
// Issue: https://github.com/electron/electron/issues/10880
- if (process.platform === 'darwin' && openAtLogin === false) {
- // process.execPath in renderer process points to the sub-bundle of Electron Helper.
- // This regular expression extracts the path to the app bundle, which is the first occurrence of
- // file with .app extension.
- const matches = process.execPath.match(/([a-z0-9 ]+)\.app/i);
- if (matches && matches.length > 1) {
- const bundleName = matches[1];
- const appleScript = `on run argv
- set itemName to item 1 of argv
- tell application "System Events" to delete login item itemName
- end run`;
- await execFileAsync('osascript', ['-e', appleScript, bundleName]);
+ if (process.platform === 'darwin') {
+ if (openAtLogin === false) {
+ // process.execPath in renderer process points to the sub-bundle of Electron Helper.
+ // This regular expression extracts the path to the app bundle, which is the first occurrence of
+ // file with .app extension.
+ const matches = process.execPath.match(/([a-z0-9 ]+)\.app/i);
+ if (matches && matches.length > 1) {
+ const bundleName = matches[1];
+ const appleScript = `on run argv
+ set itemName to item 1 of argv
+ tell application "System Events" to delete login item itemName
+ end run`;
+ await execFileAsync('osascript', ['-e', appleScript, bundleName]);
+ } else {
+ log.error(`Cannot extract the app bundle name from ${process.execPath}`);
+ }
} else {
- log.error(`Cannot extract the app bundle name from ${process.execPath}`);
+ remote.app.setLoginItemSettings({ openAtLogin });
+ }
+ } else 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 autostartFilePath = path.join(autostartDir, DESKTOP_FILE_NAME);
+
+ if (openAtLogin) {
+ await createDirIfNecessary(autostartDir);
+ await symlinkAsync(desktopFilePath, autostartFilePath);
+ } else {
+ await unlinkAsync(autostartFilePath);
+ }
+ } catch (error) {
+ log.error(`Failed to set auto-start: ${error.message}`);
}
} else {
remote.app.setLoginItemSettings({ openAtLogin });
}
};
+const createDirIfNecessary = async (directory: string) => {
+ let stat;
+ try {
+ stat = await statAsync(directory);
+ } catch (error) {
+ // Path doesn't exist, so it has to be created
+ return mkdirAsync(directory);
+ }
+
+ // Is there a file instead of a directory?
+ if (!stat.isDirectory()) {
+ // Try to remove existing file and replace it with a new directory
+ try {
+ await unlinkAsync(directory);
+ } catch (error) {
+ log.debug(`Failed to remove path before creating a directory for it: ${error.message}`);
+ }
+
+ return mkdirAsync(directory);
+ }
+};
+
const exit = () => {
remote.app.quit();
};