summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls Piņķis <emils@mullvad.net>2018-10-16 14:54:13 +0100
committerEmīls Piņķis <emils@mullvad.net>2018-10-23 10:44:12 +0100
commit5adfd92b767eb5df98608d5a28cde865228ee758 (patch)
tree347dc3a2ea8a1535afb051923cea286d0f70f990
parentc0632541d77a22e543d1549e5569a25c4d040d7e (diff)
downloadmullvadvpn-5adfd92b767eb5df98608d5a28cde865228ee758.tar.xz
mullvadvpn-5adfd92b767eb5df98608d5a28cde865228ee758.zip
Add proper auth_failed parsing to frontend
-rw-r--r--gui/packages/desktop/src/renderer/components/NotificationArea.js6
-rw-r--r--gui/packages/desktop/src/renderer/lib/auth-failure.js73
-rw-r--r--gui/packages/desktop/test/auth-failure.spec.js24
3 files changed, 99 insertions, 4 deletions
diff --git a/gui/packages/desktop/src/renderer/components/NotificationArea.js b/gui/packages/desktop/src/renderer/components/NotificationArea.js
index 8fff84f375..df8c63706c 100644
--- a/gui/packages/desktop/src/renderer/components/NotificationArea.js
+++ b/gui/packages/desktop/src/renderer/components/NotificationArea.js
@@ -11,6 +11,7 @@ import {
NotificationOpenLinkAction,
} from './NotificationBanner';
+import { AuthFailure } from '../lib/auth-failure';
import type { BlockReason, TunnelStateTransition } from '../lib/daemon-rpc';
import type { VersionReduxState } from '../redux/version/reducers';
@@ -34,10 +35,7 @@ type State = NotificationAreaPresentation & {
function getBlockReasonMessage(blockReason: BlockReason): string {
switch (blockReason.reason) {
case 'auth_failed': {
- const details =
- blockReason.details ||
- 'Check that the account is valid, has time left and not too many connections';
- return `Authentication failed: ${details}`;
+ return new AuthFailure(blockReason.details).show();
}
case 'ipv6_unavailable':
return 'Could not configure IPv6, please enable it on your system or disable it in the app';
diff --git a/gui/packages/desktop/src/renderer/lib/auth-failure.js b/gui/packages/desktop/src/renderer/lib/auth-failure.js
new file mode 100644
index 0000000000..d012e3f826
--- /dev/null
+++ b/gui/packages/desktop/src/renderer/lib/auth-failure.js
@@ -0,0 +1,73 @@
+// @flow
+
+import log from 'electron-log';
+
+export type AuthFailureKind =
+ | 'INVALID_ACCOUNT'
+ | 'EXPIRED_ACCOUNT'
+ | 'TOO_MANY_CONNECTIONS'
+ | 'UNKNOWN';
+
+// These strings should match up with mullvad-types/src/auth_failed.rs
+const GENERIC_FAILURE_MSG = 'Account authentication failed';
+const INVALID_ACCOUNT_MSG =
+ "You've logged in with an account number that is not valid. Please log out and try another one.";
+const EXPIRED_ACCOUNT_MSG =
+ 'You have no more VPN time left on this account. Please log in on our website to buy more credit.';
+const TOO_MANY_CONNECTIONS_MSG =
+ 'This account has too many simultaneous connections. Disconnect another device or try connecting again shortly.';
+
+export class AuthFailure {
+ _reasonId: AuthFailureKind;
+ _message: string;
+
+ constructor(reason: ?string) {
+ if (!reason) {
+ log.error('Received invalid auth_failed reason: ', reason);
+ this._reasonId = 'UNKNOWN';
+ this._message = GENERIC_FAILURE_MSG;
+ return;
+ }
+
+ const results = /^\[(\w+)\]\s*(.*)$/.exec(reason);
+
+ if (!results || results.length < 3) {
+ log.error(`Received invalid auth_failed message - "${reason}"`);
+ this._reasonId = 'UNKNOWN';
+ this._message = reason;
+ return;
+ }
+
+ const id_string = results[1];
+ this._reasonId = strToFailureKind(id_string);
+ this._message = results[2] || GENERIC_FAILURE_MSG;
+ }
+
+ show(): string {
+ switch (this._reasonId) {
+ case 'INVALID_ACCOUNT':
+ return INVALID_ACCOUNT_MSG;
+ case 'EXPIRED_ACCOUNT':
+ return EXPIRED_ACCOUNT_MSG;
+ case 'TOO_MANY_CONNECTIONS':
+ return TOO_MANY_CONNECTIONS_MSG;
+ case 'UNKNOWN':
+ return this._message;
+
+ default:
+ throw new Error(`Invalid reason ID: ${(this._reasonId: empty)}`);
+ }
+ }
+}
+
+export function strToFailureKind(id: string): AuthFailureKind {
+ switch (id) {
+ case 'INVALID_ACCOUNT':
+ case 'EXPIRED_ACCOUNT':
+ case 'TOO_MANY_CONNECTIONS':
+ return id;
+ default:
+ log.error(`Received unknown auth_failed message id - ${id}`);
+ return 'UNKNOWN';
+ }
+}
diff --git a/gui/packages/desktop/test/auth-failure.spec.js b/gui/packages/desktop/test/auth-failure.spec.js
new file mode 100644
index 0000000000..86bb97b13c
--- /dev/null
+++ b/gui/packages/desktop/test/auth-failure.spec.js
@@ -0,0 +1,24 @@
+import { AuthFailure } from '../src/renderer/lib/auth-failure';
+describe('auth_failed parsing', () => {
+ it('invalid line parsing works', () => {
+ const auth_msg = new AuthFailure('invalid auth_failed message');
+ expect(auth_msg._reasonId).to.be.eql('UNKNOWN');
+ expect(auth_msg.show()).to.be.eql('invalid auth_failed message');
+ });
+
+ it('valid unknown works', () => {
+ const auth_msg = new AuthFailure('[valid_unknown] Message');
+ expect(auth_msg._reasonId).to.be.eql('UNKNOWN');
+ expect(auth_msg.show()).to.be.eql('Message');
+ });
+
+ it('valid known works', () => {
+ const auth_msg = new AuthFailure('[INVALID_ACCOUNT] Invalid account');
+ expect(auth_msg._reasonId).to.be.eql('INVALID_ACCOUNT');
+ });
+
+ it('empty message works', () => {
+ const auth_msg = new AuthFailure('[INVALID_ACCOUNT]');
+ expect(auth_msg._reasonId).to.be.eql('INVALID_ACCOUNT');
+ });
+});