summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gui/.eslintrc.js19
-rw-r--r--gui/package.json2
-rw-r--r--gui/src/main/account-data-cache.ts5
-rw-r--r--gui/src/main/daemon-rpc.ts4
-rw-r--r--gui/src/main/index.ts21
-rw-r--r--gui/src/main/notification-controller.ts3
-rw-r--r--gui/src/main/proc.ts2
-rw-r--r--gui/src/renderer/app.tsx9
-rw-r--r--gui/src/renderer/components/Accordion.tsx5
-rw-r--r--gui/src/renderer/components/AppButton.tsx9
-rw-r--r--gui/src/renderer/components/Login.tsx9
-rw-r--r--gui/src/renderer/components/Marquee.tsx2
-rw-r--r--gui/src/renderer/components/NotificationBanner.tsx5
-rw-r--r--gui/src/renderer/containers/AccountPage.tsx3
-rw-r--r--gui/src/renderer/containers/LoginPage.tsx3
-rw-r--r--gui/src/renderer/containers/PreferencesPage.tsx3
-rw-r--r--gui/src/shared/promise.ts6
-rw-r--r--gui/types/d3-geo-projection/index.d.ts1
18 files changed, 62 insertions, 49 deletions
diff --git a/gui/.eslintrc.js b/gui/.eslintrc.js
index 01b47ee0d5..4a8eac1f15 100644
--- a/gui/.eslintrc.js
+++ b/gui/.eslintrc.js
@@ -18,10 +18,6 @@ module.exports = {
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
- 'plugin:import/errors',
- 'plugin:import/warnings',
- 'plugin:import/typescript',
- 'plugin:promise/recommended',
],
settings: {
react: {
@@ -36,20 +32,19 @@ module.exports = {
'error',
{ argsIgnorePattern: '^_', ignoreRestSiblings: true },
],
- // TODO: Enable these
- // 'require-await': 'error',
- // '@typescript-eslint/no-floating-promises': 'error',
+ '@typescript-eslint/require-await': 'error',
+ '@typescript-eslint/no-floating-promises': 'error',
+ 'no-return-await': 'error',
+ 'no-unused-expressions': 'error',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
- // TODO: This should eventually be removed.
- '@typescript-eslint/ban-types': 'warn',
- '@typescript-eslint/no-non-null-assertion': 'warn',
- '@typescript-eslint/no-explicit-any': 'warn',
- 'react/no-find-dom-node': 'warn',
+ '@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
+
// TODO: The rules below should be enabled when move from ReactXP is completed.
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
+ 'react/no-find-dom-node': 'off',
},
};
diff --git a/gui/package.json b/gui/package.json
index 2d4282249e..2d33a6af81 100644
--- a/gui/package.json
+++ b/gui/package.json
@@ -74,9 +74,7 @@
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"eslint": "^6.8.0",
- "eslint-plugin-import": "^2.20.1",
"eslint-plugin-prettier": "^3.1.2",
- "eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.18.3",
"gettext-extractor": "^3.5.1",
"gulp": "^4.0.2",
diff --git a/gui/src/main/account-data-cache.ts b/gui/src/main/account-data-cache.ts
index 0c68f38729..58c6d41dbd 100644
--- a/gui/src/main/account-data-cache.ts
+++ b/gui/src/main/account-data-cache.ts
@@ -1,5 +1,6 @@
import log from 'electron-log';
import { AccountToken, IAccountData } from '../shared/daemon-rpc-types';
+import consumePromise from '../shared/promise';
export enum AccountFetchRetryAction {
stop,
@@ -37,7 +38,7 @@ export default class AccountDataCache {
this.watchers.push(watcher);
}
- this.performFetch(accountToken);
+ consumePromise(this.performFetch(accountToken));
} else if (watcher) {
watcher.onFinish();
}
@@ -107,7 +108,7 @@ export default class AccountDataCache {
this.fetchRetryTimeout = global.setTimeout(() => {
this.fetchRetryTimeout = undefined;
- this.performFetch(accountToken);
+ consumePromise(this.performFetch(accountToken));
}, delay);
}
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index 31ac80f7e7..00201f7505 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -392,8 +392,8 @@ const NETWORK_CALL_TIMEOUT = 10000;
export class DaemonRpc {
private transport = new JsonRpcClient(new SocketTransport());
- public connect(connectionParams: { path: string }) {
- this.transport.connect(connectionParams);
+ public connect(connectionParams: { path: string }): Promise<void> {
+ return this.transport.connect(connectionParams);
}
public disconnect() {
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index 6d146eb418..3b13231e69 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -34,6 +34,7 @@ import {
getRendererLogFile,
setupLogging,
} from '../shared/logging';
+import consumePromise from '../shared/promise';
import AccountDataCache, { AccountFetchRetryAction } from './account-data-cache';
import { getOpenAtLogin, setOpenAtLogin } from './autostart';
import {
@@ -379,7 +380,11 @@ class ApplicationMain {
windowController.show();
}
- window.loadFile(path.resolve(path.join(__dirname, '../renderer/index.html')));
+ try {
+ await window.loadFile(path.resolve(path.join(__dirname, '../renderer/index.html')));
+ } catch (error) {
+ log.error(`Failed to load index file: ${error.message}`);
+ }
};
private onDaemonConnected = async () => {
@@ -444,7 +449,7 @@ class ApplicationMain {
}
// fetch the latest version info in background
- this.fetchLatestVersion();
+ consumePromise(this.fetchLatestVersion());
// notify user about inconsistent version
if (
@@ -502,7 +507,7 @@ class ApplicationMain {
};
private connectToDaemon() {
- this.daemonRpc.connect({ path: DAEMON_RPC_PATH });
+ consumePromise(this.daemonRpc.connect({ path: DAEMON_RPC_PATH }));
}
private reconnectToDaemon() {
@@ -585,7 +590,7 @@ class ApplicationMain {
private setTunnelState(newState: TunnelState) {
this.tunnelState = newState;
this.updateTrayIcon(newState, this.settings.blockWhenDisconnected);
- this.updateLocation();
+ consumePromise(this.updateLocation());
if (!this.shouldSuppressNotifications(false)) {
this.notificationController.notifyTunnelState(newState);
@@ -610,8 +615,8 @@ class ApplicationMain {
this.updateAccountDataOnAccountChange(oldSettings.accountToken, newSettings.accountToken);
if (oldSettings.accountToken !== newSettings.accountToken) {
- this.updateAccountHistory();
- this.fetchWireguardKey();
+ consumePromise(this.updateAccountHistory());
+ consumePromise(this.fetchWireguardKey());
}
if (this.windowController) {
@@ -975,7 +980,7 @@ class ApplicationMain {
IpcMainEventChannel.accountHistory.handleRemoveItem(async (token: AccountToken) => {
await this.daemonRpc.removeAccountFromHistory(token);
- this.updateAccountHistory();
+ consumePromise(this.updateAccountHistory());
});
IpcMainEventChannel.wireguardKeys.handleGenerateKey(async () => {
@@ -1183,7 +1188,7 @@ class ApplicationMain {
private updateDaemonsAutoConnect() {
const daemonAutoConnect = this.guiSettings.autoConnect && getOpenAtLogin();
if (daemonAutoConnect !== this.settings.autoConnect) {
- this.daemonRpc.setAutoConnect(daemonAutoConnect);
+ consumePromise(this.daemonRpc.setAutoConnect(daemonAutoConnect));
}
}
diff --git a/gui/src/main/notification-controller.ts b/gui/src/main/notification-controller.ts
index 69c0f9ec30..4c542db3ea 100644
--- a/gui/src/main/notification-controller.ts
+++ b/gui/src/main/notification-controller.ts
@@ -6,6 +6,7 @@ import config from '../config.json';
import AccountExpiry from '../shared/account-expiry';
import { TunnelState } from '../shared/daemon-rpc-types';
import { messages } from '../shared/gettext';
+import consumePromise from '../shared/promise';
export default class NotificationController {
private lastTunnelStateAnnouncement?: { body: string; notification: Notification };
@@ -140,7 +141,7 @@ export default class NotificationController {
});
notification.on('click', () => {
- shell.openExternal(config.links.download);
+ consumePromise(shell.openExternal(config.links.download));
});
this.scheduleNotification(notification);
diff --git a/gui/src/main/proc.ts b/gui/src/main/proc.ts
index 238c08c172..1e8118268d 100644
--- a/gui/src/main/proc.ts
+++ b/gui/src/main/proc.ts
@@ -10,7 +10,7 @@ function getBasePath(): string {
process.env.MULLVAD_PATH || path.resolve(path.join(__dirname, '../../../../target/debug'))
);
} else {
- return process.resourcesPath!;
+ return process.resourcesPath;
}
}
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index 73de4302bf..9eabd147b5 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -27,6 +27,7 @@ import { loadTranslations, messages, relayLocations } from '../shared/gettext';
import { IGuiSettingsState, SYSTEM_PREFERRED_LOCALE_KEY } from '../shared/gui-settings-state';
import { IpcRendererEventChannel, IRelayListPair } from '../shared/ipc-event-channel';
import { getRendererLogFile, setupLogging } from '../shared/logging';
+import consumePromise from '../shared/promise';
import {
AccountToken,
@@ -121,7 +122,7 @@ export default class AppRenderer {
});
IpcRendererEventChannel.daemonConnected.listen(() => {
- this.onDaemonConnected();
+ consumePromise(this.onDaemonConnected());
});
IpcRendererEventChannel.daemonDisconnected.listen((errorMessage?: string) => {
@@ -206,7 +207,7 @@ export default class AppRenderer {
this.setWireguardPublicKey(initialState.wireguardPublicKey);
if (initialState.isConnected) {
- this.onDaemonConnected();
+ consumePromise(this.onDaemonConnected());
}
// disable pinch to zoom
@@ -290,7 +291,7 @@ export default class AppRenderer {
return IpcRendererEventChannel.settings.updateBridgeSettings(bridgeSettings);
}
- public async removeAccountFromHistory(accountToken: AccountToken): Promise<void> {
+ public removeAccountFromHistory(accountToken: AccountToken): Promise<void> {
return IpcRendererEventChannel.accountHistory.removeItem(accountToken);
}
@@ -301,7 +302,7 @@ export default class AppRenderer {
} catch (e) {
log.error(`Failed to get the WWW auth token: ${e.message}`);
}
- shell.openExternal(`${link}?token=${token}`);
+ consumePromise(shell.openExternal(`${link}?token=${token}`));
}
public async setAllowLan(allowLan: boolean) {
diff --git a/gui/src/renderer/components/Accordion.tsx b/gui/src/renderer/components/Accordion.tsx
index 19c9ddee56..cf6603774e 100644
--- a/gui/src/renderer/components/Accordion.tsx
+++ b/gui/src/renderer/components/Accordion.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import { Animated, Component, Styles, Types, UserInterface, View } from 'reactxp';
+import consumePromise from '../../shared/promise';
interface IProps {
expanded: boolean;
@@ -56,11 +57,11 @@ export default class Accordion extends Component<IProps, IState> {
if (this.props.expanded && !this.state.mountChildren) {
this.setState({ mountChildren: true });
} else {
- this.animate(this.props.expanded);
+ consumePromise(this.animate(this.props.expanded));
}
} else if (this.state.mountChildren && !oldState.mountChildren) {
// run animations once the children are mounted
- this.animate(this.props.expanded);
+ consumePromise(this.animate(this.props.expanded));
}
}
diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx
index d31194e072..e1c37c014b 100644
--- a/gui/src/renderer/components/AppButton.tsx
+++ b/gui/src/renderer/components/AppButton.tsx
@@ -2,6 +2,7 @@ import log from 'electron-log';
import * as React from 'react';
import { Button, Component, Styles, Text, Types, UserInterface, View } from 'reactxp';
import { colors } from '../../config.json';
+import consumePromise from '../../shared/promise';
import styles from './AppButtonStyles';
import ImageView from './ImageView';
@@ -94,7 +95,7 @@ class BaseButton extends Component<IProps, IState> {
private textViewRef = React.createRef<PrivateLabel>();
public componentDidMount() {
- this.forceUpdateTextAdjustment();
+ consumePromise(this.forceUpdateTextAdjustment());
}
public render() {
@@ -135,7 +136,7 @@ class BaseButton extends Component<IProps, IState> {
this,
);
- this.updateTextAdjustment(containerLayout);
+ await this.updateTextAdjustment(containerLayout);
}
}
@@ -160,8 +161,8 @@ class BaseButton extends Component<IProps, IState> {
}
}
- private onLayout = async (containerLayout: Types.ViewOnLayoutEvent) => {
- this.updateTextAdjustment(containerLayout);
+ private onLayout = (containerLayout: Types.ViewOnLayoutEvent) => {
+ consumePromise(this.updateTextAdjustment(containerLayout));
};
}
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index 9e2ff82433..f49054f076 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import { Animated, Component, Styles, Text, TextInput, Types, UserInterface, View } from 'reactxp';
import { colors, links } from '../../config.json';
+import consumePromise from '../../shared/promise';
import { messages } from '../../shared/gettext';
import Accordion from './Accordion';
import * as AppButton from './AppButton';
@@ -72,7 +73,7 @@ export default class Login extends Component<IProps, IState> {
}
public componentDidMount() {
- this.setFooterVisibility(this.shouldShowFooter());
+ consumePromise(this.setFooterVisibility(this.shouldShowFooter()));
}
public componentDidUpdate(prevProps: IProps, _prevState: IState) {
@@ -91,7 +92,7 @@ export default class Login extends Component<IProps, IState> {
}
this.setLoginButtonActive(this.shouldActivateLoginButton());
- this.setFooterVisibility(this.shouldShowFooter());
+ consumePromise(this.setFooterVisibility(this.shouldShowFooter()));
}
public render() {
@@ -142,7 +143,7 @@ export default class Login extends Component<IProps, IState> {
this.setState({ isActive: false });
};
- private async setLoginButtonActive(isActive: boolean) {
+ private setLoginButtonActive(isActive: boolean) {
if (this.isLoginButtonActive === isActive) {
return;
}
@@ -336,7 +337,7 @@ export default class Login extends Component<IProps, IState> {
};
private onRemoveAccountFromHistory = (accountToken: string) => {
- this.removeAccountFromHistory(accountToken);
+ consumePromise(this.removeAccountFromHistory(accountToken));
};
private async removeAccountFromHistory(accountToken: AccountToken) {
diff --git a/gui/src/renderer/components/Marquee.tsx b/gui/src/renderer/components/Marquee.tsx
index dc019d74ca..04b095711e 100644
--- a/gui/src/renderer/components/Marquee.tsx
+++ b/gui/src/renderer/components/Marquee.tsx
@@ -45,7 +45,7 @@ export default class Marquee extends Component<IMarqueeProps> {
);
}
- private async startAnimation() {
+ private startAnimation() {
this.stopAnimation();
this.animationTimeout = setTimeout(async () => {
diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx
index ba626c07f4..360c910403 100644
--- a/gui/src/renderer/components/NotificationBanner.tsx
+++ b/gui/src/renderer/components/NotificationBanner.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import { Animated, Button, Component, Styles, Text, Types, UserInterface, View } from 'reactxp';
import { colors } from '../../config.json';
+import consumePromise from '../../shared/promise';
import { BlockingButton } from './AppButton';
import ImageView from './ImageView';
@@ -213,7 +214,7 @@ export class NotificationBanner extends Component<
if (prevProps.visible !== this.props.visible) {
// enable drawer-like animation when changing banner's visibility
this.setState({ contentPinnedToBottom: true }, () => {
- this.animateHeightChanges();
+ consumePromise(this.animateHeightChanges());
});
}
}
@@ -249,7 +250,7 @@ export class NotificationBanner extends Component<
// notification banner to slide down each time the component is mounted.
if (this.didFinishFirstLayoutPass) {
if (oldHeight !== height) {
- this.animateHeightChanges();
+ consumePromise(this.animateHeightChanges());
}
} else {
this.didFinishFirstLayoutPass = true;
diff --git a/gui/src/renderer/containers/AccountPage.tsx b/gui/src/renderer/containers/AccountPage.tsx
index 945512a2f7..012427b94d 100644
--- a/gui/src/renderer/containers/AccountPage.tsx
+++ b/gui/src/renderer/containers/AccountPage.tsx
@@ -2,6 +2,7 @@ import { goBack } from 'connected-react-router';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { links } from '../../config.json';
+import consumePromise from '../../shared/promise';
import Account from '../components/Account';
import withAppContext, { IAppContext } from '../context';
@@ -17,7 +18,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
const history = bindActionCreators({ goBack }, dispatch);
return {
onLogout: () => {
- props.app.logout();
+ consumePromise(props.app.logout());
},
onClose: () => {
history.goBack();
diff --git a/gui/src/renderer/containers/LoginPage.tsx b/gui/src/renderer/containers/LoginPage.tsx
index 9b39520881..2f221ad875 100644
--- a/gui/src/renderer/containers/LoginPage.tsx
+++ b/gui/src/renderer/containers/LoginPage.tsx
@@ -2,6 +2,7 @@ import { push } from 'connected-react-router';
import { shell } from 'electron';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
+import consumePromise from '../../shared/promise';
import Login from '../components/Login';
import withAppContext, { IAppContext } from '../context';
import accountActions from '../redux/account/actions';
@@ -24,7 +25,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
history.push('/settings');
},
login: (account: string) => {
- props.app.login(account);
+ consumePromise(props.app.login(account));
},
resetLoginError: () => {
resetLoginError();
diff --git a/gui/src/renderer/containers/PreferencesPage.tsx b/gui/src/renderer/containers/PreferencesPage.tsx
index 068f6f8d1d..299d5799cb 100644
--- a/gui/src/renderer/containers/PreferencesPage.tsx
+++ b/gui/src/renderer/containers/PreferencesPage.tsx
@@ -2,6 +2,7 @@ import { goBack } from 'connected-react-router';
import log from 'electron-log';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
+import consumePromise from '../../shared/promise';
import Preferences from '../components/Preferences';
import withAppContext, { IAppContext } from '../context';
import { IReduxState, ReduxDispatch } from '../redux/store';
@@ -35,7 +36,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
props.app.setAutoConnect(autoConnect);
},
setAllowLan: (allowLan: boolean) => {
- props.app.setAllowLan(allowLan);
+ consumePromise(props.app.setAllowLan(allowLan));
},
setStartMinimized: (startMinimized: boolean) => {
props.app.setStartMinimized(startMinimized);
diff --git a/gui/src/shared/promise.ts b/gui/src/shared/promise.ts
new file mode 100644
index 0000000000..c0228e23e8
--- /dev/null
+++ b/gui/src/shared/promise.ts
@@ -0,0 +1,6 @@
+// eslint-disable-next-line @typescript-eslint/no-empty-function
+const noop = () => {};
+
+export default function consumePromise<T>(promise: Promise<T>): void {
+ promise.then(noop, noop);
+}
diff --git a/gui/types/d3-geo-projection/index.d.ts b/gui/types/d3-geo-projection/index.d.ts
index 0c70c39e6b..0f6de59ba2 100644
--- a/gui/types/d3-geo-projection/index.d.ts
+++ b/gui/types/d3-geo-projection/index.d.ts
@@ -1,5 +1,4 @@
declare module 'd3-geo-projection' {
- // eslint-disable-next-line import/no-extraneous-dependencies
import { GeoProjection } from 'd3-geo';
export function geoTimes(): GeoProjection;