From ed835752bc9f632e91c747565a88e07c9b2d6179 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 May 2016 13:51:51 +0100 Subject: [PATCH 1/5] Hopefully fix memory leak with velocity --- src/Velociraptor.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Velociraptor.js b/src/Velociraptor.js index ad12d1323b..bad921c8c4 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -25,6 +25,10 @@ module.exports = React.createClass({ this._updateChildren(this.props.children); }, + componentWillUnmount: function() { + this._updateChildren([]); + }, + componentWillReceiveProps: function(nextProps) { this._updateChildren(nextProps.children); }, @@ -106,6 +110,9 @@ module.exports = React.createClass({ }); //console.log("enter: "+JSON.stringify(node.props._restingStyle)); + } else if (node === null) { + // https://github.com/julianshapiro/velocity/issues/300 + Velocity.Utilities.removeData(this.nodes[k]); } this.nodes[k] = node; }, From 3a5e37aa84cf16df1db1d2b0be917a6745ed0584 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 May 2016 16:22:40 +0100 Subject: [PATCH 2/5] This actually shouldn't be necessary. --- src/Velociraptor.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Velociraptor.js b/src/Velociraptor.js index bad921c8c4..9132f7b7b9 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -25,10 +25,6 @@ module.exports = React.createClass({ this._updateChildren(this.props.children); }, - componentWillUnmount: function() { - this._updateChildren([]); - }, - componentWillReceiveProps: function(nextProps) { this._updateChildren(nextProps.children); }, From 1664f461805c7b8ac772a7b67c1f9f5faa52dd4d Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 May 2016 16:30:04 +0100 Subject: [PATCH 3/5] Add comment --- src/Velociraptor.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Velociraptor.js b/src/Velociraptor.js index 9132f7b7b9..0abf34b230 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -107,7 +107,16 @@ module.exports = React.createClass({ //console.log("enter: "+JSON.stringify(node.props._restingStyle)); } else if (node === null) { + // Velocity stores data on elements using the jQuery .data() + // method, and assumes you'll be using jQuery's .remove() to + // remove the element, but we don't use jQuery, so we need to + // blow away the element's data explicitly otherwise it will leak. + // This uses Velocity's internal jQuery compatible wrapper. + // See the bug at // https://github.com/julianshapiro/velocity/issues/300 + // and the FAQ entry, "Preventing memory leaks when + // creating/destroying large numbers of elements" + // (https://github.com/julianshapiro/velocity/issues/47) Velocity.Utilities.removeData(this.nodes[k]); } this.nodes[k] = node; From d5e6e961fd9e66a1bc7b008014ebdd18eec12eac Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 27 May 2016 10:09:07 +0100 Subject: [PATCH 4/5] fix url previews firing incorrectly on Matrix.org --- src/components/views/messages/TextualBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 223eabdc36..a72608d329 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -117,7 +117,7 @@ module.exports = React.createClass({ else { var url = node.getAttribute("href"); var host = url.match(/^https?:\/\/(.*?)(\/|$)/)[1]; - if (node.textContent.trim().startsWith(host)) { + if (node.textContent.toLowerCase().trim().startsWith(host.toLowerCase())) { // it's a "foo.pl" style link return; } From 118eec8cc06e5f38fa0450be0a693e27531dd29d Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 May 2016 14:57:43 +0100 Subject: [PATCH 5/5] Add a fallback home server to log into If login fail with a credential error on the default HS, try logging in on the fallback one. --- src/Signup.js | 27 +++++++++++++++++++++++- src/components/structures/MatrixChat.js | 5 +++++ src/components/structures/login/Login.js | 8 ++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/Signup.js b/src/Signup.js index 5b368b4811..4518955d95 100644 --- a/src/Signup.js +++ b/src/Signup.js @@ -293,8 +293,9 @@ class Register extends Signup { class Login extends Signup { - constructor(hsUrl, isUrl) { + constructor(hsUrl, isUrl, fallbackHsUrl) { super(hsUrl, isUrl); + this._fallbackHsUrl = fallbackHsUrl; this._currentFlowIndex = 0; this._flows = []; } @@ -359,6 +360,30 @@ class Login extends Signup { error.friendlyText = ( 'Incorrect username and/or password.' ); + if (self._fallbackHsUrl) { + // as per elsewhere, it would be much nicer to not replace the global + // client just to try an alternate HS + MatrixClientPeg.replaceUsingUrls( + self._fallbackHsUrl, + self._isUrl + ); + return MatrixClientPeg.get().login('m.login.password', loginParams).then(function(data) { + return q({ + homeserverUrl: self._fallbackHsUrl, + identityServerUrl: self._isUrl, + userId: data.user_id, + accessToken: data.access_token + }); + }, function(fallback_error) { + // We also have to put the default back again if it fails... + MatrixClientPeg.replaceUsingUrls( + this._hsUrl, + this._isUrl + ); + // throw the original error + throw error; + }); + } } else { error.friendlyText = ( diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 255f7c9b92..2f7a6ed8ec 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -103,6 +103,10 @@ module.exports = React.createClass({ return "https://matrix.org"; }, + getFallbackHsUrl: function() { + return this.props.config.fallback_hs_url; + }, + getCurrentIsUrl: function() { if (this.state.register_is_url) { return this.state.register_is_url; @@ -1183,6 +1187,7 @@ module.exports = React.createClass({ defaultIsUrl={this.props.config.default_is_url} customHsUrl={this.getCurrentHsUrl()} customIsUrl={this.getCurrentIsUrl()} + fallbackHsUrl={this.getFallbackHsUrl()} onForgotPasswordClick={this.onForgotPasswordClick} onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest.bind(this, true) : undefined} onCancelClick={ this.state.guestCreds ? this.onReturnToGuestClick : null } diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index d127c7ed78..aa0c42dc98 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -35,6 +35,10 @@ module.exports = React.createClass({displayName: 'Login', customIsUrl: React.PropTypes.string, defaultHsUrl: React.PropTypes.string, defaultIsUrl: React.PropTypes.string, + // Secondary HS which we try to log into if the user is using + // the default HS but login fails. Useful for migrating to a + // different home server without confusing users. + fallbackHsUrl: React.PropTypes.string, // login shouldn't know or care how registration is done. onRegisterClick: React.PropTypes.func.isRequired, @@ -105,7 +109,9 @@ module.exports = React.createClass({displayName: 'Login', hsUrl = hsUrl || this.state.enteredHomeserverUrl; isUrl = isUrl || this.state.enteredIdentityServerUrl; - var loginLogic = new Signup.Login(hsUrl, isUrl); + var fallbackHsUrl = hsUrl == this.props.defaultHsUrl ? this.props.fallbackHsUrl : null; + + var loginLogic = new Signup.Login(hsUrl, isUrl, fallbackHsUrl); this._loginLogic = loginLogic; loginLogic.getFlows().then(function(flows) {