From c3d37c1ff9f3cb30834bb6e97c49845be9363b2f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 31 May 2017 17:28:46 +0100 Subject: [PATCH 1/2] Call MatrixClient.clearStores on logout ... to make sure that we don't have any sensitive data sitting around in the stores. --- src/Lifecycle.js | 38 +++++++++++++++++++------ src/components/structures/MatrixChat.js | 4 +-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index bf7b25fd2b..a3bec14492 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -237,7 +237,7 @@ function _handleRestoreFailure(e) { + ' This is a once off; sorry for the inconvenience.', ); - _clearLocalStorage(); + _clearStorage(); return q.reject(new Error( _t('Unable to restore previous session') + ': ' + msg, @@ -258,7 +258,7 @@ function _handleRestoreFailure(e) { return def.promise.then((success) => { if (success) { // user clicked continue. - _clearLocalStorage(); + _clearStorage(); return false; } @@ -332,6 +332,10 @@ export function setLoggedIn(credentials) { } // stop any running clients before we create a new one with these new credentials + // + // XXX: why do we have any running clients here? Maybe on sign-in after + // initial use as a guest? but what about our persistent storage? we need to + // be careful not to leak e2e data created as one user into another session. stopMatrixClient(); MatrixClientPeg.replaceUsingCreds(credentials); @@ -402,13 +406,19 @@ export function startMatrixClient() { * a session has been logged out / ended. */ export function onLoggedOut() { - _clearLocalStorage(); - stopMatrixClient(); + stopMatrixClient(true); dis.dispatch({action: 'on_logged_out'}); } -function _clearLocalStorage() { +function _clearStorage() { Analytics.logout(); + + const cli = MatrixClientPeg.get(); + if (cli) { + // TODO: *really* ought to wait for the promise to complete + cli.clearStores().done(); + } + if (!window.localStorage) { return; } @@ -425,9 +435,13 @@ function _clearLocalStorage() { } /** - * Stop all the background processes related to the current client + * Stop all the background processes related to the current client. + * + * Optionally clears persistent stores. + * + * @param {boolean} clearStores true to clear the persistent stores. */ -export function stopMatrixClient() { +export function stopMatrixClient(clearStores) { Notifier.stop(); UserActivity.stop(); Presence.stop(); @@ -436,7 +450,13 @@ export function stopMatrixClient() { if (cli) { cli.stopClient(); cli.removeAllListeners(); - cli.store.deleteAllData(); - MatrixClientPeg.unset(); } + + if (clearStores) { + // note that we have to do this *after* stopping the client, but + // *before* clearing the MatrixClientPeg. + _clearStorage(); + } + + MatrixClientPeg.unset(); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 64b5354eda..f53128fba9 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -292,7 +292,7 @@ module.exports = React.createClass({ }, componentWillUnmount: function() { - Lifecycle.stopMatrixClient(); + Lifecycle.stopMatrixClient(false); dis.unregister(this.dispatcherRef); UDEHandler.stopListening(); window.removeEventListener("focus", this.onFocus); @@ -364,7 +364,7 @@ module.exports = React.createClass({ // is completed in another browser, we'll be 401ed for using // a guest access token for a non-guest account. // It will be restarted in onReturnToGuestClick - Lifecycle.stopMatrixClient(); + Lifecycle.stopMatrixClient(false); this.notifyNewScreen('register'); break; From b3e97161268c3e5a2bf6a41748e289564fb29db7 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 1 Jun 2017 17:52:25 +0100 Subject: [PATCH 2/2] Revert "add labels to language picker" --- .../views/elements/LanguageDropdown.js | 9 ++++++++- src/languageHandler.js | 19 +++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index 49f89aa469..25a920d2e0 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -40,7 +40,14 @@ export default class LanguageDropdown extends React.Component { } componentWillMount() { - languageHandler.getAllLanguagesFromJson().then((langs) => { + languageHandler.getAllLanguageKeysFromJson().then((langKeys) => { + const langs = []; + langKeys.forEach((languageKey) => { + langs.push({ + value: languageKey, + label: _t(languageKey) + }); + }); langs.sort(function(a, b){ if(a.label < b.label) return -1; if(a.label > b.label) return 1; diff --git a/src/languageHandler.js b/src/languageHandler.js index ab29dd926e..1c3acab082 100644 --- a/src/languageHandler.js +++ b/src/languageHandler.js @@ -133,7 +133,7 @@ export function setLanguage(preferredLangs) { throw new Error("Unable to find an appropriate language"); } - return getLanguage(i18nFolder + availLangs[langToUse].fileName); + return getLanguage(i18nFolder + availLangs[langToUse]); }).then((langData) => { counterpart.registerTranslations(langToUse, langData); counterpart.setLocale(langToUse); @@ -142,25 +142,16 @@ export function setLanguage(preferredLangs) { // Set 'en' as fallback language: if (langToUse != "en") { - return getLanguage(i18nFolder + availLangs['en'].fileName); + return getLanguage(i18nFolder + availLangs['en']); } }).then((langData) => { if (langData) counterpart.registerTranslations('en', langData); }); }; -export function getAllLanguagesFromJson() { - return getLangsJson().then((langsObject) => { - var langs = []; - for (var langKey in langsObject) { - if (langsObject.hasOwnProperty(langKey)) { - langs.push({ - 'value': langKey, - 'label': langsObject[langKey].label - }); - } - } - return langs; +export function getAllLanguageKeysFromJson() { + return getLangsJson().then((langs) => { + return Object.keys(langs); }); }