diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2020-02-26 16:06:59 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2020-04-06 17:44:45 +0200 |
| commit | dab4202bea4b5cfe9121cee513b61a3fb45bbb19 (patch) | |
| tree | 567b38a65a41a48c0f0262e4605502a9446d5de1 /gui/src | |
| parent | 6157a809ad6eb5cdb06b7fcaea9549b3f100f07a (diff) | |
| download | mullvadvpn-dab4202bea4b5cfe9121cee513b61a3fb45bbb19.tar.xz mullvadvpn-dab4202bea4b5cfe9121cee513b61a3fb45bbb19.zip | |
Add submitVoucher call
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 25 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 3 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 4 | ||||
| -rw-r--r-- | gui/src/shared/daemon-rpc-types.ts | 9 | ||||
| -rw-r--r-- | gui/src/shared/ipc-event-channel.ts | 6 |
5 files changed, 47 insertions, 0 deletions
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index 02b9deceec..5db6f621c2 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -12,6 +12,8 @@ import { KeygenEvent, RelaySettingsUpdate, TunnelState, + VoucherErrorCode, + VoucherResponse, } from '../shared/daemon-rpc-types'; import { CommunicationError, InvalidAccountError, NoDaemonError } from './errors'; import JsonRpcClient, { @@ -227,6 +229,10 @@ const accountDataSchema = partialObject({ expiry: string, }); +const voucherResponseSchema = partialObject({ + new_expiry: string, +}); + const tunnelStateSchema = oneOf( object({ state: enumeration('disconnecting'), @@ -443,6 +449,25 @@ export class DaemonRpc { } } + public async submitVoucher(voucherCode: string): Promise<VoucherResponse> { + try { + const response = await this.transport.send('submit_voucher', voucherCode); + const new_expiry = validate(voucherResponseSchema, response).new_expiry; + return { type: 'success', new_expiry }; + } catch (error) { + if (error instanceof JsonRpcRemoteError) { + switch (error.code) { + case VoucherErrorCode.Invalid: + return { type: 'invalid' }; + case VoucherErrorCode.AlreadyUsed: + return { type: 'already_used' }; + } + } + } + + return { type: 'error' }; + } + public async getRelayLocations(): Promise<IRelayList> { const response = await this.transport.send('get_relay_locations'); try { diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index 28956d8c88..2c3d71e628 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -995,6 +995,9 @@ class ApplicationMain { IpcMainEventChannel.account.handleLogin((token: AccountToken) => this.login(token)); IpcMainEventChannel.account.handleLogout(() => this.logout()); IpcMainEventChannel.account.handleWwwAuthToken(() => this.daemonRpc.getWwwAuthToken()); + IpcMainEventChannel.account.handleSubmitVoucher((voucherCode: string) => + this.daemonRpc.submitVoucher(voucherCode), + ); IpcMainEventChannel.accountHistory.handleRemoveItem(async (token: AccountToken) => { await this.daemonRpc.removeAccountFromHistory(token); diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index f47e4c58bf..6d6c2ecccb 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -272,6 +272,10 @@ export default class AppRenderer { } } + public async submitVoucher(voucherCode: string) { + return IpcRendererEventChannel.account.submitVoucher(voucherCode); + } + public async connectTunnel(): Promise<void> { const state = this.tunnelState.state; diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts index ac1e7584f6..661250c5f5 100644 --- a/gui/src/shared/daemon-rpc-types.ts +++ b/gui/src/shared/daemon-rpc-types.ts @@ -320,6 +320,15 @@ export interface ISocketAddress { port: number; } +export type VoucherResponse = + | { type: 'success'; new_expiry: string } + | { type: 'invalid' | 'already_used' | 'error' }; + +export enum VoucherErrorCode { + Invalid = -400, + AlreadyUsed = -401, +} + export function parseSocketAddress(socketAddrStr: string): ISocketAddress { const re = new RegExp(/(.+):(\d+)$/); const matches = socketAddrStr.match(re); diff --git a/gui/src/shared/ipc-event-channel.ts b/gui/src/shared/ipc-event-channel.ts index 48f7b71bdc..b6e788e72e 100644 --- a/gui/src/shared/ipc-event-channel.ts +++ b/gui/src/shared/ipc-event-channel.ts @@ -18,6 +18,7 @@ import { KeygenEvent, RelaySettingsUpdate, TunnelState, + VoucherResponse, } from './daemon-rpc-types'; export interface IAppStateSnapshot { @@ -110,6 +111,7 @@ interface IAccountHandlers extends ISender<IAccountData | undefined> { handleLogin(fn: (token: AccountToken) => Promise<void>): void; handleLogout(fn: () => Promise<void>): void; handleWwwAuthToken(fn: () => Promise<string>): void; + handleSubmitVoucher(fn: (voucherCode: string) => Promise<VoucherResponse>): void; } interface IAccountMethods extends IReceiver<IAccountData | undefined> { @@ -117,6 +119,7 @@ interface IAccountMethods extends IReceiver<IAccountData | undefined> { login(token: AccountToken): Promise<void>; logout(): Promise<void>; getWwwAuthToken(): Promise<string>; + submitVoucher(voucherCode: string): Promise<VoucherResponse>; } interface IAccountHistoryHandlers extends ISender<AccountToken[]> { @@ -193,6 +196,7 @@ const DO_LOGIN = 'do-login'; const DO_LOGOUT = 'do-logout'; const DO_GET_WWW_AUTH_TOKEN = 'do-get-www-auth-token'; const ACCOUNT_DATA_CHANGED = 'account-data-changed'; +const REDEEM_VOUCHER = 'redeem-voucher'; const AUTO_START_CHANGED = 'auto-start-changed'; const SET_AUTO_START = 'set-auto-start'; @@ -287,6 +291,7 @@ export class IpcRendererEventChannel { login: requestSender(DO_LOGIN), logout: requestSender(DO_LOGOUT), getWwwAuthToken: requestSender(DO_GET_WWW_AUTH_TOKEN), + submitVoucher: requestSender(REDEEM_VOUCHER), }; public static accountHistory: IAccountHistoryMethods = { @@ -383,6 +388,7 @@ export class IpcMainEventChannel { handleLogin: requestHandler(DO_LOGIN), handleLogout: requestHandler(DO_LOGOUT), handleWwwAuthToken: requestHandler(DO_GET_WWW_AUTH_TOKEN), + handleSubmitVoucher: requestHandler<VoucherResponse>(REDEEM_VOUCHER), }; public static accountHistory: IAccountHistoryHandlers = { |
