summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gui/src/renderer/components/Connect.tsx2
-rw-r--r--gui/src/renderer/components/NotificationArea.tsx4
-rw-r--r--gui/src/renderer/lib/auth-failure.ts110
-rw-r--r--gui/test/auth-failure.spec.ts22
4 files changed, 64 insertions, 74 deletions
diff --git a/gui/src/renderer/components/Connect.tsx b/gui/src/renderer/components/Connect.tsx
index a0ebe53820..657d030c6b 100644
--- a/gui/src/renderer/components/Connect.tsx
+++ b/gui/src/renderer/components/Connect.tsx
@@ -3,7 +3,7 @@ import { Component, Styles, View } from 'reactxp';
import { links } from '../../config.json';
import { ITunnelEndpoint, parseSocketAddress } from '../../shared/daemon-rpc-types';
import AccountExpiry from '../lib/account-expiry';
-import { AuthFailureError, AuthFailureKind } from '../lib/auth-failure';
+import { AuthFailureKind, parseAuthFailure } from '../lib/auth-failure';
import { IConnectionReduxState } from '../redux/connection/reducers';
import { IVersionReduxState } from '../redux/version/reducers';
import ExpiredAccountErrorView, { RecoveryAction } from './ExpiredAccountErrorView';
diff --git a/gui/src/renderer/components/NotificationArea.tsx b/gui/src/renderer/components/NotificationArea.tsx
index 8d831bf3c3..033067df8a 100644
--- a/gui/src/renderer/components/NotificationArea.tsx
+++ b/gui/src/renderer/components/NotificationArea.tsx
@@ -16,7 +16,7 @@ import {
import { BlockReason, TunnelStateTransition } from '../../shared/daemon-rpc-types';
import AccountExpiry from '../lib/account-expiry';
-import { AuthFailureError } from '../lib/auth-failure';
+import { parseAuthFailure } from '../lib/auth-failure';
import { IVersionReduxState } from '../redux/version/reducers';
interface IProps {
@@ -43,7 +43,7 @@ type State = NotificationAreaPresentation & {
function getBlockReasonMessage(blockReason: BlockReason): string {
switch (blockReason.reason) {
case 'auth_failed':
- return new AuthFailureError(blockReason.details).message;
+ return parseAuthFailure(blockReason.details).message;
case 'ipv6_unavailable':
return pgettext(
'in-app-notifications',
diff --git a/gui/src/renderer/lib/auth-failure.ts b/gui/src/renderer/lib/auth-failure.ts
index 7ac9b4b527..ae381d5677 100644
--- a/gui/src/renderer/lib/auth-failure.ts
+++ b/gui/src/renderer/lib/auth-failure.ts
@@ -1,4 +1,3 @@
-import log from 'electron-log';
import { pgettext } from '../../shared/gettext';
export enum AuthFailureKind {
@@ -8,75 +7,41 @@ export enum AuthFailureKind {
unknown,
}
-export class AuthFailureError extends Error {
- private kindValue: AuthFailureKind;
- private unknownErrorMessage?: string;
-
- get kind(): AuthFailureKind {
- return this.kindValue;
- }
-
- get message(): string {
- switch (this.kindValue) {
- case AuthFailureKind.invalidAccount:
- return pgettext(
- 'auth-failure',
- "You've logged in with an account number that is not valid. Please log out and try another one.",
- );
-
- case AuthFailureKind.expiredAccount:
- return pgettext(
- 'auth-failure',
- 'You have no more VPN time left on this account. Please log in on our website to buy more credit.',
- );
-
- case AuthFailureKind.tooManyConnections:
- return pgettext(
- 'auth-failure',
- 'This account has too many simultaneous connections. Disconnect another device or try connecting again shortly.',
- );
-
- case AuthFailureKind.unknown:
- return (
- this.unknownErrorMessage || pgettext('auth-failure', 'Account authentication failed.')
- );
- }
- }
-
- constructor(reason?: string) {
- super();
-
- if (!reason) {
- log.error('Received invalid auth_failed reason: ', reason);
-
- this.kindValue = AuthFailureKind.unknown;
- return;
- }
+interface IAuthFailure {
+ kind: AuthFailureKind;
+ message: string;
+}
- const results = /^\[(\w+)\]\s*(.*)$/.exec(reason);
+export function parseAuthFailure(rawFailureMessage?: string): IAuthFailure {
+ if (rawFailureMessage) {
+ const results = /^\[(\w+)\]\s*(.*)$/.exec(rawFailureMessage);
if (results && results.length === 3) {
- const rawReasonId = results[1];
- const kindValue = rawReasonIdToFailureKind(rawReasonId);
-
- if (kindValue === AuthFailureKind.unknown) {
- log.error(`Received unknown auth_failed message id - ${rawReasonId}`);
- }
+ const kind = parseRawFailureKind(results[1]);
+ const message =
+ kind === AuthFailureKind.unknown ? rawFailureMessage : messageForFailureKind(kind);
- this.kindValue = kindValue;
- this.unknownErrorMessage = results[2];
+ return {
+ kind,
+ message,
+ };
} else {
- log.error(`Received invalid auth_failed message - "${reason}"`);
-
- this.kindValue = AuthFailureKind.unknown;
- this.unknownErrorMessage = reason;
+ return {
+ kind: AuthFailureKind.unknown,
+ message: rawFailureMessage,
+ };
}
+ } else {
+ return {
+ kind: AuthFailureKind.unknown,
+ message: messageForFailureKind(AuthFailureKind.unknown),
+ };
}
}
-function rawReasonIdToFailureKind(id: string): AuthFailureKind {
+function parseRawFailureKind(failureId: string): AuthFailureKind {
// These strings should match up with mullvad-types/src/auth_failed.rs
- switch (id) {
+ switch (failureId) {
case 'INVALID_ACCOUNT':
return AuthFailureKind.invalidAccount;
@@ -90,3 +55,28 @@ function rawReasonIdToFailureKind(id: string): AuthFailureKind {
return AuthFailureKind.unknown;
}
}
+
+function messageForFailureKind(kind: AuthFailureKind): string {
+ switch (kind) {
+ case AuthFailureKind.invalidAccount:
+ return pgettext(
+ 'auth-failure',
+ "You've logged in with an account number that is not valid. Please log out and try another one.",
+ );
+
+ case AuthFailureKind.expiredAccount:
+ return pgettext(
+ 'auth-failure',
+ 'You have no more VPN time left on this account. Please log in on our website to buy more credit.',
+ );
+
+ case AuthFailureKind.tooManyConnections:
+ return pgettext(
+ 'auth-failure',
+ 'This account has too many simultaneous connections. Disconnect another device or try connecting again shortly.',
+ );
+
+ case AuthFailureKind.unknown:
+ return pgettext('auth-failure', 'Account authentication failed.');
+ }
+}
diff --git a/gui/test/auth-failure.spec.ts b/gui/test/auth-failure.spec.ts
index 6bb643c345..eaa08c4a1e 100644
--- a/gui/test/auth-failure.spec.ts
+++ b/gui/test/auth-failure.spec.ts
@@ -1,27 +1,27 @@
import { expect } from 'chai';
import { it, describe } from 'mocha';
-import { AuthFailureError, AuthFailureKind } from '../src/renderer/lib/auth-failure';
+import { parseAuthFailure, AuthFailureKind } from '../src/renderer/lib/auth-failure';
describe('auth_failed parsing', () => {
it('invalid line parsing works', () => {
- const auth_msg = new AuthFailureError('invalid auth_failed message');
- expect(auth_msg.kind).to.be.equal(AuthFailureKind.unknown);
- expect(auth_msg.message).to.be.equal('invalid auth_failed message');
+ const authFailure = parseAuthFailure('invalid auth_failed message');
+ expect(authFailure.kind).to.be.equal(AuthFailureKind.unknown);
+ expect(authFailure.message).to.be.equal('invalid auth_failed message');
});
it('valid unknown works', () => {
- const auth_msg = new AuthFailureError('[valid_unknown] Message');
- expect(auth_msg.kind).to.be.equal(AuthFailureKind.unknown);
- expect(auth_msg.message).to.be.equal('Message');
+ const authFailure = parseAuthFailure('[valid_unknown] Message');
+ expect(authFailure.kind).to.be.equal(AuthFailureKind.unknown);
+ expect(authFailure.message).to.be.equal('Message');
});
it('valid known works', () => {
- const auth_msg = new AuthFailureError('[INVALID_ACCOUNT] Invalid account');
- expect(auth_msg.kind).to.be.equal(AuthFailureKind.invalidAccount);
+ const authFailure = parseAuthFailure('[INVALID_ACCOUNT] Invalid account');
+ expect(authFailure.kind).to.be.equal(AuthFailureKind.invalidAccount);
});
it('empty message works', () => {
- const auth_msg = new AuthFailureError('[INVALID_ACCOUNT]');
- expect(auth_msg.kind).to.be.equal(AuthFailureKind.invalidAccount);
+ const authFailure = parseAuthFailure('[INVALID_ACCOUNT]');
+ expect(authFailure.kind).to.be.equal(AuthFailureKind.invalidAccount);
});
});