summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2020-06-15 20:17:27 +0200
committerOskar Nyberg <oskar@mullvad.net>2020-06-24 11:23:12 +0200
commit0db07414743e8dbd5c00f810a138ff276fbf92f6 (patch)
tree9957b5fdde83938bb1b2b3ff0ba0810a6c90812d /gui
parente66685fc8024d9ce8b6448199b2109e9123bd3b6 (diff)
downloadmullvadvpn-0db07414743e8dbd5c00f810a138ff276fbf92f6.tar.xz
mullvadvpn-0db07414743e8dbd5c00f810a138ff276fbf92f6.zip
Add account expiry case to error notification
Diffstat (limited to 'gui')
-rw-r--r--gui/src/main/index.ts6
-rw-r--r--gui/src/main/notification-controller.ts8
-rw-r--r--gui/src/renderer/components/NotificationArea.tsx2
-rw-r--r--gui/src/shared/notifications/error.ts46
4 files changed, 48 insertions, 14 deletions
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index 407a348ca9..a0e17fd9be 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -623,7 +623,11 @@ class ApplicationMain {
this.updateTrayIcon(newState, this.settings.blockWhenDisconnected);
consumePromise(this.updateLocation());
- this.notificationController.notifyTunnelState(newState, this.settings.blockWhenDisconnected);
+ this.notificationController.notifyTunnelState(
+ newState,
+ this.settings.blockWhenDisconnected,
+ this.accountData?.expiry,
+ );
if (this.windowController) {
IpcMainEventChannel.tunnel.notify(this.windowController.webContents, newState);
diff --git a/gui/src/main/notification-controller.ts b/gui/src/main/notification-controller.ts
index 548c20e122..20c29d0a41 100644
--- a/gui/src/main/notification-controller.ts
+++ b/gui/src/main/notification-controller.ts
@@ -47,14 +47,18 @@ export default class NotificationController {
}
}
- public notifyTunnelState(tunnelState: TunnelState, blockWhenDisconnected: boolean) {
+ public notifyTunnelState(
+ tunnelState: TunnelState,
+ blockWhenDisconnected: boolean,
+ accountExpiry?: string,
+ ) {
const notificationProviders: SystemNotificationProvider[] = [
new ConnectingNotificationProvider({ tunnelState, reconnecting: this.reconnecting }),
new ConnectedNotificationProvider(tunnelState),
new ReconnectingNotificationProvider(tunnelState),
new BlockWhenDisconnectedNotificationProvider({ tunnelState, blockWhenDisconnected }),
new DisconnectedNotificationProvider(tunnelState),
- new ErrorNotificationProvider(tunnelState),
+ new ErrorNotificationProvider({ tunnelState, accountExpiry }),
];
const notificationProvider = notificationProviders.find((notification) =>
diff --git a/gui/src/renderer/components/NotificationArea.tsx b/gui/src/renderer/components/NotificationArea.tsx
index 89d742df0a..b5153a54aa 100644
--- a/gui/src/renderer/components/NotificationArea.tsx
+++ b/gui/src/renderer/components/NotificationArea.tsx
@@ -44,7 +44,7 @@ export default function NotificationArea(props: IProps) {
new ConnectingNotificationProvider({ tunnelState }),
new ReconnectingNotificationProvider(tunnelState),
new BlockWhenDisconnectedNotificationProvider({ tunnelState, blockWhenDisconnected }),
- new ErrorNotificationProvider(tunnelState),
+ new ErrorNotificationProvider({ tunnelState, accountExpiry }),
new InconsistentVersionNotificationProvider({ consistent: version.consistent }),
new UnsupportedVersionNotificationProvider(version),
new UpdateAvailableNotificationProvider(version),
diff --git a/gui/src/shared/notifications/error.ts b/gui/src/shared/notifications/error.ts
index a4ba97c81d..1a8499739e 100644
--- a/gui/src/shared/notifications/error.ts
+++ b/gui/src/shared/notifications/error.ts
@@ -1,4 +1,6 @@
-import { parseAuthFailure } from '../auth-failure';
+import { sprintf } from 'sprintf-js';
+import { hasExpired } from '../account-expiry';
+import { AuthFailureKind, parseAuthFailure } from '../auth-failure';
import { IErrorState, TunnelState, TunnelParameterError } from '../daemon-rpc-types';
import { messages } from '../gettext';
import {
@@ -7,38 +9,62 @@ import {
SystemNotificationProvider,
} from './notification';
+interface ErrorNotificationContext {
+ tunnelState: TunnelState;
+ accountExpiry?: string;
+}
+
export class ErrorNotificationProvider
implements SystemNotificationProvider, InAppNotificationProvider {
- public constructor(private context: TunnelState) {}
+ public constructor(private context: ErrorNotificationContext) {}
- public mayDisplay = () => this.context.state === 'error';
+ public mayDisplay = () => this.context.tunnelState.state === 'error';
public getSystemNotification() {
- return this.context.state === 'error'
+ return this.context.tunnelState.state === 'error'
? {
- message: getSystemNotificationMessage(this.context),
- critical: !this.context.details.isBlocking,
+ message: getSystemNotificationMessage(
+ this.context.tunnelState,
+ this.context.accountExpiry,
+ ),
+ critical: !this.context.tunnelState.details.isBlocking,
}
: undefined;
}
public getInAppNotification(): InAppNotification | undefined {
- return this.context.state === 'error'
+ return this.context.tunnelState.state === 'error'
? {
indicator: 'error',
- title: this.context.details.isBlocking
+ title: this.context.tunnelState.details.isBlocking
? messages.pgettext('in-app-notifications', 'BLOCKING INTERNET')
: messages.pgettext('in-app-notifications', 'YOU MIGHT BE LEAKING NETWORK TRAFFIC'),
- subtitle: getInAppNotificationSubtitle(this.context),
+ subtitle: getInAppNotificationSubtitle(this.context.tunnelState),
}
: undefined;
}
}
-function getSystemNotificationMessage(tunnelState: { state: 'error'; details: IErrorState }) {
+function getSystemNotificationMessage(
+ tunnelState: { state: 'error'; details: IErrorState },
+ accountExpiry?: string,
+) {
if (!tunnelState.details.isBlocking) {
return messages.pgettext('notifications', 'Critical error (your attention is required)');
} else if (
+ (tunnelState.details.cause.reason === 'auth_failed' &&
+ parseAuthFailure(tunnelState.details.cause.details).kind ===
+ AuthFailureKind.expiredAccount) ||
+ (accountExpiry && hasExpired(accountExpiry))
+ ) {
+ return sprintf('%(blocking)s %(message)s', {
+ blocking: messages.pgettext('notifications', 'Blocking internet:'),
+ message: messages.pgettext(
+ 'notifications',
+ 'You have no more VPN time left on this account.',
+ ),
+ });
+ } else if (
tunnelState.details.cause.reason === 'tunnel_parameter_error' &&
tunnelState.details.cause.details === 'no_wireguard_key'
) {