summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer/redux
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-03-14 13:59:05 +0100
committerOskar Nyberg <oskar@mullvad.net>2022-03-14 13:59:05 +0100
commit4ab205bd9add69264ccdfaaf8cf068515ceddb77 (patch)
tree302357507a7e51ece04f563c5f7018d64adaccac /gui/src/renderer/redux
parent6459ae7beefcc5f13eb54254dfe402dd807c62fe (diff)
parent55aa3418f8b7ec6f473fd22819f7e54cb432d097 (diff)
downloadmullvadvpn-4ab205bd9add69264ccdfaaf8cf068515ceddb77.tar.xz
mullvadvpn-4ab205bd9add69264ccdfaaf8cf068515ceddb77.zip
Merge branch 'device-api-electron'
Diffstat (limited to 'gui/src/renderer/redux')
-rw-r--r--gui/src/renderer/redux/account/actions.ts98
-rw-r--r--gui/src/renderer/redux/account/reducers.ts56
-rw-r--r--gui/src/renderer/redux/settings/actions.ts99
-rw-r--r--gui/src/renderer/redux/settings/reducers.ts163
4 files changed, 139 insertions, 277 deletions
diff --git a/gui/src/renderer/redux/account/actions.ts b/gui/src/renderer/redux/account/actions.ts
index b8fbe94d39..aa0a949533 100644
--- a/gui/src/renderer/redux/account/actions.ts
+++ b/gui/src/renderer/redux/account/actions.ts
@@ -1,4 +1,4 @@
-import { AccountToken } from '../../../shared/daemon-rpc-types';
+import { AccountToken, IDeviceConfig, IDevice } from '../../../shared/daemon-rpc-types';
interface IStartLoginAction {
type: 'START_LOGIN';
@@ -7,6 +7,8 @@ interface IStartLoginAction {
interface ILoggedInAction {
type: 'LOGGED_IN';
+ accountToken: AccountToken;
+ deviceName?: string;
}
interface ILoginFailedAction {
@@ -14,6 +16,19 @@ interface ILoginFailedAction {
error: Error;
}
+interface ILoginTooManyDevicesAction {
+ type: 'TOO_MANY_DEVICES';
+ error: Error;
+}
+
+interface IPrepareLogoutAction {
+ type: 'PREPARE_LOG_OUT';
+}
+
+interface ICancelLogoutAction {
+ type: 'CANCEL_LOGOUT';
+}
+
interface ILoggedOutAction {
type: 'LOGGED_OUT';
}
@@ -22,6 +37,10 @@ interface IResetLoginErrorAction {
type: 'RESET_LOGIN_ERROR';
}
+interface IDeviceRevokedAction {
+ type: 'DEVICE_REVOKED';
+}
+
interface IStartCreateAccount {
type: 'START_CREATE_ACCOUNT';
}
@@ -33,13 +52,18 @@ interface ICreateAccountFailed {
interface IAccountCreated {
type: 'ACCOUNT_CREATED';
- token: AccountToken;
+ accountToken: AccountToken;
+ deviceName?: string;
expiry: string;
}
+interface IAccountSetupFinished {
+ type: 'ACCOUNT_SETUP_FINISHED';
+}
+
interface IUpdateAccountTokenAction {
type: 'UPDATE_ACCOUNT_TOKEN';
- token: AccountToken;
+ accountToken: AccountToken;
}
interface IUpdateAccountHistoryAction {
@@ -52,18 +76,29 @@ interface IUpdateAccountExpiryAction {
expiry?: string;
}
+interface IUpdateDevicesAction {
+ type: 'UPDATE_DEVICES';
+ devices: Array<IDevice>;
+}
+
export type AccountAction =
| IStartLoginAction
| ILoggedInAction
| ILoginFailedAction
+ | ILoginTooManyDevicesAction
+ | IPrepareLogoutAction
+ | ICancelLogoutAction
| ILoggedOutAction
| IResetLoginErrorAction
+ | IDeviceRevokedAction
| IStartCreateAccount
| ICreateAccountFailed
| IAccountCreated
+ | IAccountSetupFinished
| IUpdateAccountTokenAction
| IUpdateAccountHistoryAction
- | IUpdateAccountExpiryAction;
+ | IUpdateAccountExpiryAction
+ | IUpdateDevicesAction;
function startLogin(accountToken: AccountToken): IStartLoginAction {
return {
@@ -72,9 +107,11 @@ function startLogin(accountToken: AccountToken): IStartLoginAction {
};
}
-function loggedIn(): ILoggedInAction {
+function loggedIn(deviceConfig: IDeviceConfig): ILoggedInAction {
return {
type: 'LOGGED_IN',
+ accountToken: deviceConfig.accountToken,
+ deviceName: deviceConfig.device?.name,
};
}
@@ -85,6 +122,25 @@ function loginFailed(error: Error): ILoginFailedAction {
};
}
+function loginTooManyDevices(error: Error): ILoginTooManyDevicesAction {
+ return {
+ type: 'TOO_MANY_DEVICES',
+ error,
+ };
+}
+
+function prepareLogout(): IPrepareLogoutAction {
+ return {
+ type: 'PREPARE_LOG_OUT',
+ };
+}
+
+function cancelLogout(): ICancelLogoutAction {
+ return {
+ type: 'CANCEL_LOGOUT',
+ };
+}
+
function loggedOut(): ILoggedOutAction {
return {
type: 'LOGGED_OUT',
@@ -97,6 +153,12 @@ function resetLoginError(): IResetLoginErrorAction {
};
}
+function deviceRevoked(): IDeviceRevokedAction {
+ return {
+ type: 'DEVICE_REVOKED',
+ };
+}
+
function startCreateAccount(): IStartCreateAccount {
return {
type: 'START_CREATE_ACCOUNT',
@@ -110,18 +172,23 @@ function createAccountFailed(error: Error): ICreateAccountFailed {
};
}
-function accountCreated(token: AccountToken, expiry: string): IAccountCreated {
+function accountCreated(deviceConfig: IDeviceConfig, expiry: string): IAccountCreated {
return {
type: 'ACCOUNT_CREATED',
- token,
+ accountToken: deviceConfig.accountToken,
+ deviceName: deviceConfig.device?.name,
expiry,
};
}
-function updateAccountToken(token: AccountToken): IUpdateAccountTokenAction {
+function accountSetupFinished(): IAccountSetupFinished {
+ return { type: 'ACCOUNT_SETUP_FINISHED' };
+}
+
+function updateAccountToken(accountToken: AccountToken): IUpdateAccountTokenAction {
return {
type: 'UPDATE_ACCOUNT_TOKEN',
- token,
+ accountToken,
};
}
@@ -139,16 +206,29 @@ function updateAccountExpiry(expiry?: string): IUpdateAccountExpiryAction {
};
}
+function updateDevices(devices: Array<IDevice>): IUpdateDevicesAction {
+ return {
+ type: 'UPDATE_DEVICES',
+ devices: devices.sort((a, b) => a.name.localeCompare(b.name)),
+ };
+}
+
export default {
startLogin,
loggedIn,
loginFailed,
+ loginTooManyDevices,
+ prepareLogout,
+ cancelLogout,
loggedOut,
resetLoginError,
+ deviceRevoked,
startCreateAccount,
createAccountFailed,
accountCreated,
+ accountSetupFinished,
updateAccountToken,
updateAccountHistory,
updateAccountExpiry,
+ updateDevices,
};
diff --git a/gui/src/renderer/redux/account/reducers.ts b/gui/src/renderer/redux/account/reducers.ts
index 53bc55db1b..00f2ef7bb5 100644
--- a/gui/src/renderer/redux/account/reducers.ts
+++ b/gui/src/renderer/redux/account/reducers.ts
@@ -1,23 +1,29 @@
-import { AccountToken } from '../../../shared/daemon-rpc-types';
+import { AccountToken, IDevice } from '../../../shared/daemon-rpc-types';
import { ReduxAction } from '../store';
type LoginMethod = 'existing_account' | 'new_account';
export type LoginState =
- | { type: 'none' }
+ | { type: 'none'; deviceRevoked: boolean }
| { type: 'logging in' | 'ok'; method: LoginMethod }
- | { type: 'failed'; method: LoginMethod; error: Error };
+ | { type: 'failed' | 'too many devices'; method: LoginMethod; error: Error };
export interface IAccountReduxState {
accountToken?: AccountToken;
+ deviceName?: string;
+ devices: Array<IDevice>;
accountHistory?: AccountToken;
expiry?: string; // ISO8601
status: LoginState;
+ loggingOut: boolean;
}
const initialState: IAccountReduxState = {
accountToken: undefined,
+ deviceName: undefined,
+ devices: [],
accountHistory: undefined,
expiry: undefined,
- status: { type: 'none' },
+ status: { type: 'none', deviceRevoked: false },
+ loggingOut: false,
};
export default function (
@@ -35,6 +41,8 @@ export default function (
return {
...state,
status: { type: 'ok', method: 'existing_account' },
+ accountToken: action.accountToken,
+ deviceName: action.deviceName,
};
case 'LOGIN_FAILED':
return {
@@ -42,17 +50,38 @@ export default function (
status: { type: 'failed', method: 'existing_account', error: action.error },
accountToken: undefined,
};
+ case 'TOO_MANY_DEVICES':
+ return {
+ ...state,
+ status: { type: 'too many devices', method: 'existing_account', error: action.error },
+ };
+ case 'PREPARE_LOG_OUT':
+ return {
+ ...state,
+ loggingOut: true,
+ };
+ case 'CANCEL_LOGOUT':
+ return {
+ ...state,
+ loggingOut: false,
+ };
case 'LOGGED_OUT':
return {
...state,
- status: { type: 'none' },
+ status: { type: 'none', deviceRevoked: false },
accountToken: undefined,
expiry: undefined,
+ loggingOut: false,
};
case 'RESET_LOGIN_ERROR':
return {
...state,
- status: { type: 'none' },
+ status: { type: 'none', deviceRevoked: false },
+ };
+ case 'DEVICE_REVOKED':
+ return {
+ ...state,
+ status: { type: 'none', deviceRevoked: true },
};
case 'START_CREATE_ACCOUNT':
return {
@@ -68,13 +97,19 @@ export default function (
return {
...state,
status: { type: 'ok', method: 'new_account' },
- accountToken: action.token,
+ accountToken: action.accountToken,
+ deviceName: action.deviceName,
expiry: action.expiry,
};
+ case 'ACCOUNT_SETUP_FINISHED':
+ return {
+ ...state,
+ status: { type: 'ok', method: 'existing_account' },
+ };
case 'UPDATE_ACCOUNT_TOKEN':
return {
...state,
- accountToken: action.token,
+ accountToken: action.accountToken,
};
case 'UPDATE_ACCOUNT_HISTORY':
return {
@@ -86,6 +121,11 @@ export default function (
...state,
expiry: action.expiry,
};
+ case 'UPDATE_DEVICES':
+ return {
+ ...state,
+ devices: action.devices,
+ };
}
return state;
diff --git a/gui/src/renderer/redux/settings/actions.ts b/gui/src/renderer/redux/settings/actions.ts
index 1b1e48265c..32cd157157 100644
--- a/gui/src/renderer/redux/settings/actions.ts
+++ b/gui/src/renderer/redux/settings/actions.ts
@@ -1,12 +1,7 @@
-import {
- BridgeState,
- IDnsOptions,
- IWireguardPublicKey,
- KeygenEvent,
-} from '../../../shared/daemon-rpc-types';
+import { BridgeState, IDnsOptions } from '../../../shared/daemon-rpc-types';
import { IGuiSettingsState } from '../../../shared/gui-settings-state';
import { IApplication } from '../../../shared/application-types';
-import { BridgeSettingsRedux, IRelayLocationRedux, IWgKey, RelaySettingsRedux } from './reducers';
+import { BridgeSettingsRedux, IRelayLocationRedux, RelaySettingsRedux } from './reducers';
export interface IUpdateGuiSettingsAction {
type: 'UPDATE_GUI_SETTINGS';
@@ -73,36 +68,6 @@ export interface IUpdateAutoStartAction {
autoStart: boolean;
}
-// Used to set wireguard key when accounts are changed.
-export interface IWireguardSetKey {
- type: 'SET_WIREGUARD_KEY';
- key?: IWgKey;
-}
-
-export interface IWireguardGenerateKey {
- type: 'GENERATE_WIREGUARD_KEY';
-}
-
-export interface IWireguardReplaceKey {
- type: 'REPLACE_WIREGUARD_KEY';
- oldKey: IWgKey;
-}
-
-export interface IWireguardVerifyKey {
- type: 'VERIFY_WIREGUARD_KEY';
- key: IWgKey;
-}
-
-export interface IWireguardKeygenEvent {
- type: 'WIREGUARD_KEYGEN_EVENT';
- event: KeygenEvent;
-}
-
-export interface IWireguardKeyVerifiedAction {
- type: 'WIREGUARD_KEY_VERIFICATION_COMPLETE';
- verified?: boolean;
-}
-
export interface IUpdateDnsOptionsAction {
type: 'UPDATE_DNS_OPTIONS';
dns: IDnsOptions;
@@ -132,12 +97,6 @@ export type SettingsAction =
| IUpdateOpenVpnMssfixAction
| IUpdateWireguardMtuAction
| IUpdateAutoStartAction
- | IWireguardSetKey
- | IWireguardVerifyKey
- | IWireguardGenerateKey
- | IWireguardReplaceKey
- | IWireguardKeygenEvent
- | IWireguardKeyVerifiedAction
| IUpdateDnsOptionsAction
| IUpdateSplitTunnelingStateAction
| ISetSplitTunnelingApplicationsAction;
@@ -237,54 +196,6 @@ function updateAutoStart(autoStart: boolean): IUpdateAutoStartAction {
};
}
-function setWireguardKey(publicKey?: IWireguardPublicKey): IWireguardSetKey {
- const key = publicKey
- ? {
- publicKey: publicKey.key,
- created: publicKey.created,
- valid: undefined,
- }
- : undefined;
- return {
- type: 'SET_WIREGUARD_KEY',
- key,
- };
-}
-
-function setWireguardKeygenEvent(event: KeygenEvent): IWireguardKeygenEvent {
- return {
- type: 'WIREGUARD_KEYGEN_EVENT',
- event,
- };
-}
-
-function generateWireguardKey(): IWireguardGenerateKey {
- return {
- type: 'GENERATE_WIREGUARD_KEY',
- };
-}
-
-function replaceWireguardKey(oldKey: IWgKey): IWireguardReplaceKey {
- return {
- type: 'REPLACE_WIREGUARD_KEY',
- oldKey,
- };
-}
-
-function verifyWireguardKey(key: IWgKey): IWireguardVerifyKey {
- return {
- type: 'VERIFY_WIREGUARD_KEY',
- key,
- };
-}
-
-function completeWireguardKeyVerification(verified?: boolean): IWireguardKeyVerifiedAction {
- return {
- type: 'WIREGUARD_KEY_VERIFICATION_COMPLETE',
- verified,
- };
-}
-
function updateDnsOptions(dns: IDnsOptions): IUpdateDnsOptionsAction {
return {
type: 'UPDATE_DNS_OPTIONS',
@@ -322,12 +233,6 @@ export default {
updateOpenVpnMssfix,
updateWireguardMtu,
updateAutoStart,
- setWireguardKey,
- setWireguardKeygenEvent,
- generateWireguardKey,
- replaceWireguardKey,
- verifyWireguardKey,
- completeWireguardKeyVerification,
updateDnsOptions,
updateSplitTunnelingState,
setSplitTunnelingApplications,
diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts
index 449ff2b563..9b55160a5e 100644
--- a/gui/src/renderer/redux/settings/reducers.ts
+++ b/gui/src/renderer/redux/settings/reducers.ts
@@ -1,7 +1,6 @@
import { IApplication } from '../../../shared/application-types';
import {
BridgeState,
- KeygenEvent,
LiftedConstraint,
ProxySettings,
RelayLocation,
@@ -11,7 +10,6 @@ import {
IpVersion,
} from '../../../shared/daemon-rpc-types';
import { IGuiSettingsState } from '../../../shared/gui-settings-state';
-import log from '../../../shared/logging';
import { ReduxAction } from '../store';
export type RelaySettingsRedux =
@@ -73,54 +71,6 @@ export interface IRelayLocationRedux {
cities: IRelayLocationCityRedux[];
}
-export interface IWgKey {
- publicKey: string;
- created: string;
- valid?: boolean;
- replacementFailure?: KeygenEvent;
- verificationFailed?: boolean;
-}
-
-interface IWgKeySet {
- type: 'key-set';
- key: IWgKey;
-}
-
-interface IWgKeyNotSet {
- type: 'key-not-set';
-}
-
-interface IWgTooManyKeys {
- type: 'too-many-keys';
-}
-
-interface IWgKeyGenerationFailure {
- type: 'generation-failure';
-}
-
-interface IWgKeyBeingGenerated {
- type: 'being-generated';
-}
-
-interface IWgKeyBeingReplaced {
- type: 'being-replaced';
- oldKey: IWgKey;
-}
-
-interface IWgKeyBeingVerified {
- type: 'being-verified';
- key: IWgKey;
-}
-
-export type WgKeyState =
- | IWgKeySet
- | IWgKeyNotSet
- | IWgKeyGenerationFailure
- | IWgTooManyKeys
- | IWgKeyBeingVerified
- | IWgKeyBeingReplaced
- | IWgKeyBeingGenerated;
-
export interface ISettingsReduxState {
autoStart: boolean;
guiSettings: IGuiSettingsState;
@@ -140,7 +90,6 @@ export interface ISettingsReduxState {
mtu?: number;
};
dns: IDnsOptions;
- wireguardKeyState: WgKeyState;
splitTunneling: boolean;
splitTunnelingApplications: IApplication[];
}
@@ -183,9 +132,6 @@ const initialState: ISettingsReduxState = {
showBetaReleases: false,
openVpn: {},
wireguard: {},
- wireguardKeyState: {
- type: 'key-not-set',
- },
dns: {
state: 'default',
defaultOptions: {
@@ -290,42 +236,6 @@ export default function (
bridgeState: action.bridgeState,
};
- case 'SET_WIREGUARD_KEY':
- return {
- ...state,
- wireguardKeyState: setWireguardKey(action.key),
- };
- case 'WIREGUARD_KEYGEN_EVENT':
- return {
- ...state,
- wireguardKeyState: setWireguardKeygenEvent(state, action.event),
- };
- case 'WIREGUARD_KEY_VERIFICATION_COMPLETE':
- return {
- ...state,
- wireguardKeyState: applyKeyVerification(state.wireguardKeyState, action.verified),
- };
- case 'VERIFY_WIREGUARD_KEY':
- return {
- ...state,
- wireguardKeyState: { type: 'being-verified', key: resetWireguardKeyErrors(action.key) },
- };
-
- case 'GENERATE_WIREGUARD_KEY':
- return {
- ...state,
- wireguardKeyState: { type: 'being-generated' },
- };
-
- case 'REPLACE_WIREGUARD_KEY':
- return {
- ...state,
- wireguardKeyState: {
- type: 'being-replaced',
- oldKey: resetWireguardKeyErrors(action.oldKey),
- },
- };
-
case 'UPDATE_DNS_OPTIONS':
return {
...state,
@@ -348,76 +258,3 @@ export default function (
return state;
}
}
-
-function setWireguardKey(key?: IWgKey): WgKeyState {
- if (key) {
- return {
- type: 'key-set',
- key,
- };
- } else {
- return {
- type: 'key-not-set',
- };
- }
-}
-
-function resetWireguardKeyErrors(key: IWgKey): IWgKey {
- return {
- publicKey: key.publicKey,
- created: key.created,
- };
-}
-
-function setWireguardKeygenEvent(state: ISettingsReduxState, keygenEvent: KeygenEvent): WgKeyState {
- const oldKeyState = state.wireguardKeyState;
- if (oldKeyState.type === 'being-replaced') {
- switch (keygenEvent) {
- case 'too_many_keys':
- case 'generation_failure':
- return {
- type: 'key-set',
- key: {
- ...oldKeyState.oldKey,
- replacementFailure: keygenEvent,
- },
- };
- default:
- break;
- }
- }
- switch (keygenEvent) {
- case 'too_many_keys':
- return { type: 'too-many-keys' };
- case 'generation_failure':
- return { type: 'generation-failure' };
- default:
- return {
- type: 'key-set',
- key: {
- publicKey: keygenEvent.newKey.key,
- created: keygenEvent.newKey.created,
- valid: undefined,
- },
- };
- }
-}
-
-function applyKeyVerification(state: WgKeyState, verified?: boolean): WgKeyState {
- const verificationFailed = verified === undefined ? true : undefined;
- switch (state.type) {
- case 'being-verified':
- return {
- type: 'key-set',
- key: {
- ...state.key,
- valid: verified,
- verificationFailed,
- },
- };
- // drop the verification event if the key wasn't being verified.
- default:
- log.error("Received key verification event when key wasn't being verified");
- return state;
- }
-}