summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-04-07 15:29:43 +0200
committerOskar Nyberg <oskar@mullvad.net>2022-04-07 15:29:43 +0200
commit74ec2b59d1fa20604973f1bd4e5cd503631c2365 (patch)
tree3fa5771c1ad09e055086dab16c273c2b44d756bf /gui
parent3640e7731c8855de871c7d1af97a8d07414a4913 (diff)
parenta64c38052e9cf316d2819adcee89802f747dd630 (diff)
downloadmullvadvpn-74ec2b59d1fa20604973f1bd4e5cd503631c2365.tar.xz
mullvadvpn-74ec2b59d1fa20604973f1bd4e5cd503631c2365.zip
Merge branch 'handle-post-upgrade-flag'
Diffstat (limited to 'gui')
-rw-r--r--gui/locales/messages.pot8
-rw-r--r--gui/src/main/daemon-rpc.ts5
-rw-r--r--gui/src/main/index.ts29
-rw-r--r--gui/src/renderer/app.tsx9
-rw-r--r--gui/src/renderer/components/Login.tsx18
-rw-r--r--gui/src/renderer/containers/LoginPage.tsx3
-rw-r--r--gui/src/renderer/redux/userinterface/actions.ts16
-rw-r--r--gui/src/renderer/redux/userinterface/reducers.ts8
-rw-r--r--gui/src/shared/ipc-schema.ts2
9 files changed, 96 insertions, 2 deletions
diff --git a/gui/locales/messages.pot b/gui/locales/messages.pot
index 40810a8e8a..a7ba20c520 100644
--- a/gui/locales/messages.pot
+++ b/gui/locales/messages.pot
@@ -676,6 +676,10 @@ msgid "Failed to create account"
msgstr ""
msgctxt "login-view"
+msgid "Finishing upgrade."
+msgstr ""
+
+msgctxt "login-view"
msgid "Logged in"
msgstr ""
@@ -710,6 +714,10 @@ msgid "Unknown error"
msgstr ""
msgctxt "login-view"
+msgid "Upgrading..."
+msgstr ""
+
+msgctxt "login-view"
msgid "Valid account number"
msgstr ""
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index b3add4ec1d..52c43441a6 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -499,6 +499,11 @@ export class DaemonRpc {
await this.callEmpty(this.client.checkVolumes);
}
+ public async isPerformingPostUpgrade(): Promise<boolean> {
+ const response = await this.callEmpty<BoolValue>(this.client.isPerformingPostUpgrade);
+ return response.getValue();
+ }
+
public async getDevice(): Promise<IDeviceConfig | undefined> {
try {
const response = await this.callEmpty<grpcTypes.DeviceConfig>(this.client.getDevice);
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index e36c8d1b70..1dfde6537d 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -128,6 +128,7 @@ class ApplicationMain {
private reconnectBackoff = new ReconnectionBackoff();
private beforeFirstDaemonConnection = true;
private connectedToDaemon = false;
+ private isPerformingPostUpgrade = false;
private quitStage = AppQuitStage.unready;
private accountData?: IAccountData = undefined;
@@ -626,6 +627,18 @@ class ApplicationMain {
return this.handleBootstrapError(error);
}
+ if (firstDaemonConnection) {
+ // check if daemon is performing post upgrade tasks the first time it's connected to
+ try {
+ await this.performPostUpgradeCheck();
+ } catch (e) {
+ const error = e as Error;
+ log.error(`Failed to check if daemon is performing post upgrade tasks: ${error.message}`);
+
+ return this.handleBootstrapError(error);
+ }
+ }
+
// fetch account history
try {
this.setAccountHistory(await this.daemonRpc.getAccountHistory());
@@ -808,6 +821,17 @@ class ApplicationMain {
return daemonEventListener;
}
+ private async performPostUpgradeCheck(): Promise<void> {
+ const oldValue = this.isPerformingPostUpgrade;
+ this.isPerformingPostUpgrade = await this.daemonRpc.isPerformingPostUpgrade();
+ if (this.windowController && this.isPerformingPostUpgrade !== oldValue) {
+ IpcMainEventChannel.daemon.notifyIsPerformingPostUpgrade(
+ this.windowController.webContents,
+ this.isPerformingPostUpgrade,
+ );
+ }
+ }
+
private connectTunnel = async (): Promise<void> => {
if (
connectEnabled(
@@ -1125,6 +1149,10 @@ class ApplicationMain {
this.deviceConfig = deviceEvent.deviceConfig;
this.hasReceivedDeviceConfig = true;
+ if (this.isPerformingPostUpgrade) {
+ void this.performPostUpgradeCheck();
+ }
+
// make sure to invalidate the account data cache when account tokens change
this.updateAccountDataOnAccountChange(
oldDeviceConfig?.accountToken,
@@ -1219,6 +1247,7 @@ class ApplicationMain {
accountHistory: this.accountHistory,
tunnelState: this.tunnelState,
settings: this.settings,
+ isPerformingPostUpgrade: this.isPerformingPostUpgrade,
deviceConfig: this.deviceConfig,
hasReceivedDeviceConfig: this.hasReceivedDeviceConfig,
relayListPair: {
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index b221f0a0e1..ebb7f0e18b 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -122,6 +122,10 @@ export default class AppRenderer {
this.onDaemonDisconnected();
});
+ IpcRendererEventChannel.daemon.listenIsPerformingPostUpgrade((isPerformingPostUpgrade) => {
+ this.setIsPerformingPostUpgrade(isPerformingPostUpgrade);
+ });
+
IpcRendererEventChannel.account.listen((newAccountData?: IAccountData) => {
this.setAccountExpiry(newAccountData?.expiry);
});
@@ -203,6 +207,7 @@ export default class AppRenderer {
this.setAccountExpiry(initialState.accountData?.expiry);
this.setSettings(initialState.settings);
+ this.setIsPerformingPostUpgrade(initialState.isPerformingPostUpgrade);
this.handleAccountChange({ deviceConfig: initialState.deviceConfig }, undefined);
this.hasReceivedDeviceConfig = initialState.hasReceivedDeviceConfig;
this.setAccountHistory(initialState.accountHistory);
@@ -770,6 +775,10 @@ export default class AppRenderer {
this.setBridgeSettings(newSettings.bridgeSettings);
}
+ private setIsPerformingPostUpgrade(isPerformingPostUpgrade: boolean) {
+ this.reduxActions.userInterface.setIsPerformingPostUpgrade(isPerformingPostUpgrade);
+ }
+
private updateBlockedState(tunnelState: TunnelState, blockWhenDisconnected: boolean) {
const actions = this.reduxActions.connection;
switch (tunnelState.state) {
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index d9ae7f105f..282f49d01c 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -51,6 +51,7 @@ interface IProps {
updateAccountToken: (accountToken: AccountToken) => void;
clearAccountHistory: () => Promise<void>;
createNewAccount: () => void;
+ isPerformingPostUpgrade?: boolean;
}
interface IState {
@@ -149,6 +150,10 @@ export default class Login extends React.Component<IProps, IState> {
};
private formTitle() {
+ if (this.props.isPerformingPostUpgrade) {
+ return messages.pgettext('login-view', 'Upgrading...');
+ }
+
switch (this.props.loginState.type) {
case 'logging in':
case 'too many devices':
@@ -169,6 +174,10 @@ export default class Login extends React.Component<IProps, IState> {
}
private formSubtitle() {
+ if (this.props.isPerformingPostUpgrade) {
+ return messages.pgettext('login-view', 'Finishing upgrade.');
+ }
+
switch (this.props.loginState.type) {
case 'failed':
return this.props.loginState.method === 'existing_account'
@@ -199,6 +208,10 @@ export default class Login extends React.Component<IProps, IState> {
}
private getStatusIconPath(): string | undefined {
+ if (this.props.isPerformingPostUpgrade) {
+ return 'icon-spinner';
+ }
+
switch (this.props.loginState.type) {
case 'logging in':
return 'icon-spinner';
@@ -213,6 +226,7 @@ export default class Login extends React.Component<IProps, IState> {
private allowInteraction() {
return (
+ !this.props.isPerformingPostUpgrade &&
this.props.loginState.type !== 'logging in' &&
this.props.loginState.type !== 'ok' &&
this.props.loginState.type !== 'too many devices'
@@ -291,7 +305,9 @@ export default class Login extends React.Component<IProps, IState> {
messages.pgettext('accessibility', 'Login')
}>
<StyledInputSubmitIcon
- visible={this.props.loginState.type !== 'logging in'}
+ visible={
+ this.props.loginState.type !== 'logging in' && !this.props.isPerformingPostUpgrade
+ }
source="icon-arrow"
height={16}
width={24}
diff --git a/gui/src/renderer/containers/LoginPage.tsx b/gui/src/renderer/containers/LoginPage.tsx
index 1abfa863a2..fd5aa5cbcd 100644
--- a/gui/src/renderer/containers/LoginPage.tsx
+++ b/gui/src/renderer/containers/LoginPage.tsx
@@ -13,11 +13,14 @@ const mapStateToProps = (state: IReduxState) => {
const showBlockMessage = tunnelState.state === 'error' || blockWhenDisconnected;
+ const isPerformingPostUpgrade = state.userInterface.isPerformingPostUpgrade;
+
return {
accountToken,
accountHistory,
loginState: status,
showBlockMessage,
+ isPerformingPostUpgrade,
};
};
const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
diff --git a/gui/src/renderer/redux/userinterface/actions.ts b/gui/src/renderer/redux/userinterface/actions.ts
index 78b5bae756..ce0cd5401b 100644
--- a/gui/src/renderer/redux/userinterface/actions.ts
+++ b/gui/src/renderer/redux/userinterface/actions.ts
@@ -46,6 +46,11 @@ export interface ISetChangelog {
changelog: IChangelog;
}
+export interface ISetIsPerformingPostUpgrade {
+ type: 'SET_IS_PERFORMING_POST_UPGRADE';
+ isPerformingPostUpgrade: boolean;
+}
+
export type UserInterfaceAction =
| IUpdateLocaleAction
| IUpdateWindowArrowPositionAction
@@ -55,7 +60,8 @@ export type UserInterfaceAction =
| IRemoveScrollPosition
| ISetMacOsScrollbarVisibility
| ISetConnectedToDaemon
- | ISetChangelog;
+ | ISetChangelog
+ | ISetIsPerformingPostUpgrade;
function updateLocale(locale: string): IUpdateLocaleAction {
return {
@@ -122,6 +128,13 @@ function setChangelog(changelog: IChangelog): ISetChangelog {
};
}
+function setIsPerformingPostUpgrade(isPerformingPostUpgrade: boolean): ISetIsPerformingPostUpgrade {
+ return {
+ type: 'SET_IS_PERFORMING_POST_UPGRADE',
+ isPerformingPostUpgrade,
+ };
+}
+
export default {
updateLocale,
updateWindowArrowPosition,
@@ -132,4 +145,5 @@ export default {
setMacOsScrollbarVisibility,
setConnectedToDaemon,
setChangelog,
+ setIsPerformingPostUpgrade,
};
diff --git a/gui/src/renderer/redux/userinterface/reducers.ts b/gui/src/renderer/redux/userinterface/reducers.ts
index 58107b455e..ca470a8cba 100644
--- a/gui/src/renderer/redux/userinterface/reducers.ts
+++ b/gui/src/renderer/redux/userinterface/reducers.ts
@@ -11,6 +11,7 @@ export interface IUserInterfaceReduxState {
macOsScrollbarVisibility?: MacOsScrollbarVisibility;
connectedToDaemon: boolean;
changelog: IChangelog;
+ isPerformingPostUpgrade: boolean;
}
const initialState: IUserInterfaceReduxState = {
@@ -21,6 +22,7 @@ const initialState: IUserInterfaceReduxState = {
macOsScrollbarVisibility: undefined,
connectedToDaemon: false,
changelog: [],
+ isPerformingPostUpgrade: false,
};
export default function (
@@ -64,6 +66,12 @@ export default function (
changelog: action.changelog,
};
+ case 'SET_IS_PERFORMING_POST_UPGRADE':
+ return {
+ ...state,
+ isPerformingPostUpgrade: action.isPerformingPostUpgrade,
+ };
+
default:
return state;
}
diff --git a/gui/src/shared/ipc-schema.ts b/gui/src/shared/ipc-schema.ts
index 1700ddc606..ce517c8f21 100644
--- a/gui/src/shared/ipc-schema.ts
+++ b/gui/src/shared/ipc-schema.ts
@@ -55,6 +55,7 @@ export interface IAppStateSnapshot {
accountHistory?: AccountToken;
tunnelState: TunnelState;
settings: ISettings;
+ isPerformingPostUpgrade: boolean;
deviceConfig?: IDeviceConfig;
hasReceivedDeviceConfig: boolean;
relayListPair: IRelayListPair;
@@ -119,6 +120,7 @@ export const ipcSchema = {
reset: notifyRenderer<void>(),
},
daemon: {
+ isPerformingPostUpgrade: notifyRenderer<boolean>(),
connected: notifyRenderer<void>(),
disconnected: notifyRenderer<void>(),
},