summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-01-22 13:10:19 +0100
committerAndrej Mihajlov <and@mullvad.net>2019-01-22 13:57:51 +0100
commit5a45cb950ebd1e1957f3b1cca9722af8dbafd33d (patch)
tree21f36cb437e28a55c6b07375be3a0863ebc7aa92
parenta3d4437dc2405f4d473b68429cf62c921fee2b42 (diff)
downloadmullvadvpn-5a45cb950ebd1e1957f3b1cca9722af8dbafd33d.tar.xz
mullvadvpn-5a45cb950ebd1e1957f3b1cca9722af8dbafd33d.zip
Handle changes to account token
-rw-r--r--gui/packages/desktop/src/renderer/app.js140
-rw-r--r--gui/packages/desktop/src/renderer/components/Login.js4
-rw-r--r--gui/packages/desktop/src/renderer/redux/account/actions.js12
-rw-r--r--gui/packages/desktop/src/renderer/redux/account/reducers.js2
4 files changed, 67 insertions, 91 deletions
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js
index ec2edd2571..28fc33f949 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.js
@@ -41,11 +41,9 @@ import type {
import DaemonRpcProxy from './lib/daemon-rpc-proxy';
-import type { ReduxStore } from './redux/store';
-
export default class AppRenderer {
_memoryHistory = createMemoryHistory();
- _reduxStore: ReduxStore;
+ _reduxStore = configureStore(null, this._memoryHistory);
_reduxActions: *;
_daemonRpc = new DaemonRpcProxy();
_accountDataCache = new AccountDataCache(
@@ -62,12 +60,11 @@ export default class AppRenderer {
_settings: Settings;
_connectedToDaemon = false;
_autoConnected = false;
+ _doingLogin = false;
+ _loginTimer: ?TimeoutID;
constructor() {
- const store = configureStore(null, this._memoryHistory);
- const dispatch = store.dispatch;
-
- this._reduxStore = store;
+ const dispatch = this._reduxStore.dispatch;
this._reduxActions = {
account: bindActionCreators(accountActions, dispatch),
connection: bindActionCreators(connectionActions, dispatch),
@@ -108,7 +105,10 @@ export default class AppRenderer {
});
IpcRendererEventChannel.settings.listen((newSettings: Settings) => {
+ const oldSettings = this._settings;
+
this._setSettings(newSettings);
+ this._handleAccountChange(oldSettings.accountToken, newSettings.accountToken);
});
IpcRendererEventChannel.location.listen((newLocation: Location) => {
@@ -164,11 +164,12 @@ export default class AppRenderer {
async login(accountToken: AccountToken) {
const actions = this._reduxActions;
- const history = this._memoryHistory;
actions.account.startLogin(accountToken);
log.debug('Logging in');
+ this._doingLogin = true;
+
try {
const verification = await this.verifyAccount(accountToken);
@@ -177,14 +178,10 @@ export default class AppRenderer {
}
await this._daemonRpc.setAccount(accountToken);
- actions.account.loginSuccessful();
- // Redirect the user after some time to allow for
- // the 'Login Successful' screen to be visible
- setTimeout(async () => {
- if (history.location.pathname === '/login') {
- actions.history.replace('/connect');
- }
+ // Redirect the user after some time to allow for the 'Logged in' screen to be visible
+ this._loginTimer = setTimeout(async () => {
+ this._memoryHistory.replace('/connect');
try {
log.debug('Auto-connecting the tunnel');
@@ -219,18 +216,8 @@ export default class AppRenderer {
}
async logout() {
- const actions = this._reduxActions;
-
try {
await this._daemonRpc.setAccount(null);
-
- await this._fetchAccountHistory();
-
- actions.account.loggedOut();
- actions.history.replace('/login');
-
- // invalidate account data cache on log out
- this._accountDataCache.invalidate();
} catch (e) {
log.info('Failed to logout: ', e.message);
}
@@ -302,7 +289,7 @@ export default class AppRenderer {
}
}
- async updateAccountExpiry() {
+ updateAccountExpiry() {
if (this._settings.accountToken) {
this._accountDataCache.fetch(this._settings.accountToken);
}
@@ -384,71 +371,26 @@ export default class AppRenderer {
log.error(`Cannot fetch the account history: ${error.message}`);
}
- // set the appropriate start view
- await this._setStartView();
-
- // try to autoconnect the tunnel
- await this._autoConnect();
- }
+ if (this._settings.accountToken) {
+ this._memoryHistory.replace('/connect');
- _onDaemonDisconnected(error: ?Error) {
- const actions = this._reduxActions;
+ // try to autoconnect the tunnel
+ await this._autoConnect();
+ } else {
+ this._memoryHistory.replace('/login');
- // recover connection on error
- if (error) {
- // only send to the connecting to daemon view if the daemon was
- // connnected previously
- if (this._connectedToDaemon) {
- actions.history.replace('/');
- }
+ // show window when account is not set
+ ipcRenderer.send('show-window');
}
-
- this._connectedToDaemon = false;
}
- async _setStartView() {
- const actions = this._reduxActions;
- const history = this._memoryHistory;
- const accountToken = this._settings.accountToken;
-
- if (accountToken) {
- log.debug(`Account token is set. Showing the tunnel view.`);
-
- this._accountDataCache.fetch(accountToken);
-
- actions.account.updateAccountToken(accountToken);
- actions.account.loginSuccessful();
-
- // take user to main view if user is still at launch screen `/`
- if (history.location.pathname === '/') {
- actions.history.replace('/connect');
- } else {
- // TODO: Reinvent the navigation back in history to make sure that user does not end up on
- // the restricted screen due to changes in daemon's state.
- for (const entry of history.entries) {
- if (entry.pathname === '/') {
- entry.pathname = '/connect';
- }
- }
- }
- } else {
- log.debug('No account set, showing login view.');
+ _onDaemonDisconnected(error: ?Error) {
+ const wasConnected = this._connectedToDaemon;
- // show window when account is not set
- ipcRenderer.send('show-window');
+ this._connectedToDaemon = false;
- // take user to `/login` screen if user is at launch screen `/`
- if (history.location.pathname === '/') {
- actions.history.replace('/login');
- } else {
- // TODO: Reinvent the navigation back in history to make sure that user does not end up on
- // the restricted screen due to changes in daemon's state.
- for (const entry of history.entries) {
- if (!entry.pathname.startsWith('/settings')) {
- entry.pathname = '/login';
- }
- }
- }
+ if (error && wasConnected) {
+ this._memoryHistory.replace('/');
}
}
@@ -514,6 +456,7 @@ export default class AppRenderer {
this._settings = newSettings;
const reduxSettings = this._reduxActions.settings;
+ const reduxAccount = this._reduxActions.account;
reduxSettings.updateAllowLan(newSettings.allowLan);
reduxSettings.updateEnableIpv6(newSettings.tunnelOptions.enableIpv6);
@@ -521,6 +464,35 @@ export default class AppRenderer {
reduxSettings.updateOpenVpnMssfix(newSettings.tunnelOptions.openvpn.mssfix);
this._setRelaySettings(newSettings.relaySettings);
+
+ if (newSettings.accountToken) {
+ reduxAccount.updateAccountToken(newSettings.accountToken);
+ reduxAccount.loggedIn();
+ } else {
+ reduxAccount.loggedOut();
+ }
+ }
+
+ _handleAccountChange(oldAccount: ?string, newAccount: ?string) {
+ if (oldAccount && !newAccount) {
+ this._accountDataCache.invalidate();
+
+ if (this._loginTimer) {
+ clearTimeout(this._loginTimer);
+ }
+
+ this._memoryHistory.replace('/login');
+ } else if (!oldAccount && newAccount) {
+ this._accountDataCache.fetch(newAccount);
+
+ if (!this._doingLogin) {
+ this._memoryHistory.replace('/connect');
+ }
+ } else if (oldAccount && newAccount && oldAccount !== newAccount) {
+ this._accountDataCache.fetch(newAccount);
+ }
+
+ this._doingLogin = false;
}
_setLocation(location: Location) {
diff --git a/gui/packages/desktop/src/renderer/components/Login.js b/gui/packages/desktop/src/renderer/components/Login.js
index f1ce7542c7..fe7f23cc8f 100644
--- a/gui/packages/desktop/src/renderer/components/Login.js
+++ b/gui/packages/desktop/src/renderer/components/Login.js
@@ -70,6 +70,10 @@ export default class Login extends Component<Props, State> {
});
}
+ componentDidMount() {
+ this._setFooterVisibility(this._shouldShowFooter());
+ }
+
componentDidUpdate(prevProps: Props, _prevState: State) {
if (
this.props.loginState !== prevProps.loginState &&
diff --git a/gui/packages/desktop/src/renderer/redux/account/actions.js b/gui/packages/desktop/src/renderer/redux/account/actions.js
index a5dfd13412..a089cb3705 100644
--- a/gui/packages/desktop/src/renderer/redux/account/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/account/actions.js
@@ -7,8 +7,8 @@ type StartLoginAction = {
accountToken: AccountToken,
};
-type LoginSuccessfulAction = {
- type: 'LOGIN_SUCCESSFUL',
+type LoggedInAction = {
+ type: 'LOGGED_IN',
};
type LoginFailedAction = {
@@ -41,7 +41,7 @@ type UpdateAccountExpiryAction = {
export type AccountAction =
| StartLoginAction
- | LoginSuccessfulAction
+ | LoggedInAction
| LoginFailedAction
| LoggedOutAction
| ResetLoginErrorAction
@@ -56,9 +56,9 @@ function startLogin(accountToken: AccountToken): StartLoginAction {
};
}
-function loginSuccessful(): LoginSuccessfulAction {
+function loggedIn(): LoggedInAction {
return {
- type: 'LOGIN_SUCCESSFUL',
+ type: 'LOGGED_IN',
};
}
@@ -104,7 +104,7 @@ function updateAccountExpiry(expiry: string): UpdateAccountExpiryAction {
export default {
startLogin,
- loginSuccessful,
+ loggedIn,
loginFailed,
loggedOut,
resetLoginError,
diff --git a/gui/packages/desktop/src/renderer/redux/account/reducers.js b/gui/packages/desktop/src/renderer/redux/account/reducers.js
index 01405d0fef..cac021128f 100644
--- a/gui/packages/desktop/src/renderer/redux/account/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/account/reducers.js
@@ -34,7 +34,7 @@ export default function(
error: null,
},
};
- case 'LOGIN_SUCCESSFUL':
+ case 'LOGGED_IN':
return {
...state,
...{