mirror of https://github.com/vector-im/riot-web
Don't force-logout the user if reading localstorage fails
Give them a modal dialog to give them a chance to abort.pull/21833/head
parent
a5325ee14a
commit
bdb8f9d052
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -24,6 +25,8 @@ import Presence from './Presence';
|
||||||
import dis from './dispatcher';
|
import dis from './dispatcher';
|
||||||
import DMRoomMap from './utils/DMRoomMap';
|
import DMRoomMap from './utils/DMRoomMap';
|
||||||
import RtsClient from './RtsClient';
|
import RtsClient from './RtsClient';
|
||||||
|
import Modal from './Modal';
|
||||||
|
import sdk from './index';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at startup, to attempt to build a logged-in Matrix session. It tries
|
* Called at startup, to attempt to build a logged-in Matrix session. It tries
|
||||||
|
@ -109,16 +112,17 @@ export function loadSession(opts) {
|
||||||
return q();
|
return q();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_restoreFromLocalStorage()) {
|
return _restoreFromLocalStorage().then((success) => {
|
||||||
return q();
|
if (success) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (enableGuest) {
|
if (enableGuest) {
|
||||||
return _registerAsGuest(guestHsUrl, guestIsUrl, defaultDeviceDisplayName);
|
return _registerAsGuest(guestHsUrl, guestIsUrl, defaultDeviceDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fall back to login screen
|
// fall back to login screen
|
||||||
return q();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function _loginWithToken(queryParams, defaultDeviceDisplayName) {
|
function _loginWithToken(queryParams, defaultDeviceDisplayName) {
|
||||||
|
@ -178,10 +182,11 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if a session is found in localstorage
|
// returns a promise which resolves to true if a session is found in
|
||||||
|
// localstorage
|
||||||
function _restoreFromLocalStorage() {
|
function _restoreFromLocalStorage() {
|
||||||
if (!localStorage) {
|
if (!localStorage) {
|
||||||
return false;
|
return q(false);
|
||||||
}
|
}
|
||||||
const hs_url = localStorage.getItem("mx_hs_url");
|
const hs_url = localStorage.getItem("mx_hs_url");
|
||||||
const is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
const is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
||||||
|
@ -208,28 +213,55 @@ function _restoreFromLocalStorage() {
|
||||||
identityServerUrl: is_url,
|
identityServerUrl: is_url,
|
||||||
guest: is_guest,
|
guest: is_guest,
|
||||||
});
|
});
|
||||||
return true;
|
return q(true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Unable to restore session", e);
|
return _handleRestoreFailure(e);
|
||||||
|
|
||||||
var msg = e.message;
|
|
||||||
if (msg == "OLM.BAD_LEGACY_ACCOUNT_PICKLE") {
|
|
||||||
msg = "You need to log back in to generate end-to-end encryption keys "
|
|
||||||
+ "for this device and submit the public key to your homeserver. "
|
|
||||||
+ "This is a once off; sorry for the inconvenience.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't leak things into the new session
|
|
||||||
_clearLocalStorage();
|
|
||||||
|
|
||||||
throw new Error("Unable to restore previous session: " + msg);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("No previous session found.");
|
console.log("No previous session found.");
|
||||||
return false;
|
return q(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _handleRestoreFailure(e) {
|
||||||
|
console.log("Unable to restore session", e);
|
||||||
|
|
||||||
|
let msg = e.message;
|
||||||
|
if (msg == "OLM.BAD_LEGACY_ACCOUNT_PICKLE") {
|
||||||
|
msg = "You need to log back in to generate end-to-end encryption keys "
|
||||||
|
+ "for this device and submit the public key to your homeserver. "
|
||||||
|
+ "This is a once off; sorry for the inconvenience.";
|
||||||
|
|
||||||
|
_clearLocalStorage();
|
||||||
|
|
||||||
|
return q.reject(new Error(
|
||||||
|
"Unable to restore previous session: " + msg,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
const def = q.defer();
|
||||||
|
const SessionRestoreErrorDialog =
|
||||||
|
sdk.getComponent('views.dialogs.SessionRestoreErrorDialog');
|
||||||
|
|
||||||
|
Modal.createDialog(SessionRestoreErrorDialog, {
|
||||||
|
error: msg,
|
||||||
|
onFinished: (success) => {
|
||||||
|
def.resolve(success);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return def.promise.then((success) => {
|
||||||
|
if (success) {
|
||||||
|
// user clicked continue.
|
||||||
|
_clearLocalStorage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try, try again
|
||||||
|
return _restoreFromLocalStorage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let rtsClient = null;
|
let rtsClient = null;
|
||||||
export function initRtsClient(url) {
|
export function initRtsClient(url) {
|
||||||
rtsClient = new RtsClient(url);
|
rtsClient = new RtsClient(url);
|
||||||
|
|
|
@ -89,6 +89,8 @@ import views$dialogs$NeedToRegisterDialog from './components/views/dialogs/NeedT
|
||||||
views$dialogs$NeedToRegisterDialog && (module.exports.components['views.dialogs.NeedToRegisterDialog'] = views$dialogs$NeedToRegisterDialog);
|
views$dialogs$NeedToRegisterDialog && (module.exports.components['views.dialogs.NeedToRegisterDialog'] = views$dialogs$NeedToRegisterDialog);
|
||||||
import views$dialogs$QuestionDialog from './components/views/dialogs/QuestionDialog';
|
import views$dialogs$QuestionDialog from './components/views/dialogs/QuestionDialog';
|
||||||
views$dialogs$QuestionDialog && (module.exports.components['views.dialogs.QuestionDialog'] = views$dialogs$QuestionDialog);
|
views$dialogs$QuestionDialog && (module.exports.components['views.dialogs.QuestionDialog'] = views$dialogs$QuestionDialog);
|
||||||
|
import views$dialogs$SessionRestoreErrorDialog from './components/views/dialogs/SessionRestoreErrorDialog';
|
||||||
|
views$dialogs$SessionRestoreErrorDialog && (module.exports.components['views.dialogs.SessionRestoreErrorDialog'] = views$dialogs$SessionRestoreErrorDialog);
|
||||||
import views$dialogs$SetDisplayNameDialog from './components/views/dialogs/SetDisplayNameDialog';
|
import views$dialogs$SetDisplayNameDialog from './components/views/dialogs/SetDisplayNameDialog';
|
||||||
views$dialogs$SetDisplayNameDialog && (module.exports.components['views.dialogs.SetDisplayNameDialog'] = views$dialogs$SetDisplayNameDialog);
|
views$dialogs$SetDisplayNameDialog && (module.exports.components['views.dialogs.SetDisplayNameDialog'] = views$dialogs$SetDisplayNameDialog);
|
||||||
import views$dialogs$TextInputDialog from './components/views/dialogs/TextInputDialog';
|
import views$dialogs$TextInputDialog from './components/views/dialogs/TextInputDialog';
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import sdk from '../../../index';
|
||||||
|
import SdkConfig from '../../../SdkConfig';
|
||||||
|
import Modal from '../../../Modal';
|
||||||
|
|
||||||
|
|
||||||
|
export default React.createClass({
|
||||||
|
displayName: 'SessionRestoreErrorDialog',
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
error: React.PropTypes.string.isRequired,
|
||||||
|
onFinished: React.PropTypes.func.isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
_sendBugReport: function() {
|
||||||
|
const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog");
|
||||||
|
Modal.createDialog(BugReportDialog, {});
|
||||||
|
},
|
||||||
|
|
||||||
|
_continueClicked: function() {
|
||||||
|
this.props.onFinished(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
|
let bugreport;
|
||||||
|
|
||||||
|
if (SdkConfig.get().bug_report_endpoint_url) {
|
||||||
|
bugreport = (
|
||||||
|
<p>Otherwise, <a onClick={this._sendBugReport} href='#'>
|
||||||
|
click here</a> to send a bug report.
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||||
|
title='Unable to restore session'>
|
||||||
|
<div className="mx_Dialog_content">
|
||||||
|
<p>We encountered an error trying to restore your previous session. If
|
||||||
|
you continue, you will need to log in again, and encrypted chat
|
||||||
|
history will be unreadable.</p>
|
||||||
|
|
||||||
|
<p>If you have previously used a more recent version of Riot, your session
|
||||||
|
may be incompatible with this version. Close this window and return
|
||||||
|
to the more recent version.</p>
|
||||||
|
|
||||||
|
{bugreport}
|
||||||
|
</div>
|
||||||
|
<div className="mx_Dialog_buttons">
|
||||||
|
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
|
||||||
|
Continue anyway
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</BaseDialog>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue