From b0e71c9872fa2311992bfc9feffa546de481e6cc Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Fri, 6 Nov 2015 09:57:22 +0000 Subject: [PATCH 1/7] Fix bugs from typos from hackathon --- src/controllers/organisms/CreateRoom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/organisms/CreateRoom.js b/src/controllers/organisms/CreateRoom.js index f6404eb231..3c48e43f74 100644 --- a/src/controllers/organisms/CreateRoom.js +++ b/src/controllers/organisms/CreateRoom.js @@ -72,7 +72,7 @@ module.exports = { { type: "m.room.join_rules", content: { - "join_rules": this.state.is_private ? "invite" : "public" + "join_rule": this.state.is_private ? "invite" : "public" } }, { @@ -107,7 +107,7 @@ module.exports = { deferred = deferred.then(function(res) { response = res; return encryption.enableEncryption( - cli, response.roomId, options.invite + cli, response.room_id, options.invite ); }).then(function() { return q(response) } From de165ea6ad6ee92f3f9db8a5f685db3394cbd9ee Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Fri, 6 Nov 2015 11:21:13 +0000 Subject: [PATCH 2/7] Update CAS login to allow HS to do interaction with CAS and client receives and redeems login token --- src/CasLogic.js | 28 --------------------------- src/controllers/organisms/CasLogin.js | 16 ++++++--------- src/controllers/pages/MatrixChat.js | 17 ++++++++-------- 3 files changed, 15 insertions(+), 46 deletions(-) delete mode 100644 src/CasLogic.js diff --git a/src/CasLogic.js b/src/CasLogic.js deleted file mode 100644 index 1bcc6d5c78..0000000000 --- a/src/CasLogic.js +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2015 OpenMarket 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. -*/ - -'use strict'; - -var url = require ('url'); - -function getServiceUrl() { - var parsedUrl = url.parse(window.location.href); - return parsedUrl.protocol + "//" + parsedUrl.host + parsedUrl.pathname; -} - -module.exports = { - getServiceUrl: getServiceUrl -}; diff --git a/src/controllers/organisms/CasLogin.js b/src/controllers/organisms/CasLogin.js index b01c3781b0..95791a1a9a 100644 --- a/src/controllers/organisms/CasLogin.js +++ b/src/controllers/organisms/CasLogin.js @@ -17,20 +17,16 @@ limitations under the License. 'use strict'; var MatrixClientPeg = require("../../MatrixClientPeg"); -var Cas = require("../../CasLogic"); +var url = require("url"); module.exports = { onCasClicked: function(ev) { - var serviceRedirectUrl = Cas.getServiceUrl() + "#/login/cas"; - var self = this; - MatrixClientPeg.get().getCasServer().done(function(data) { - var serverUrl = data.serverUrl + "/login?service=" + encodeURIComponent(serviceRedirectUrl); - window.location.href = serverUrl; - }, function(error) { - self.setStep("stage_m.login.cas"); - self.setState({errorText: 'Login failed.'}); - }); + var cli = MatrixClientPeg.get(); + var parsedUrl = url.parse(window.location.href, true); + parsedUrl.query["homeserver"] = cli.getHomeserverUrl(); + parsedUrl.query["identityServer"] = cli.getIdentityServerUrl(); + MatrixClientPeg.get().loginWithCas(url.format(parsedUrl)); }, }; diff --git a/src/controllers/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js index a38ba8e4e7..796a3e858e 100644 --- a/src/controllers/pages/MatrixChat.js +++ b/src/controllers/pages/MatrixChat.js @@ -23,8 +23,6 @@ var sdk = require('../../index'); var MatrixTools = require('../../MatrixTools'); var linkifyMatrix = require("../../linkify-matrix"); -var Cas = require("../../CasLogic"); - module.exports = { PageTypes: { RoomView: "room_view", @@ -140,14 +138,17 @@ module.exports = { }); this.notifyNewScreen('login'); break; - case 'cas_login': + case 'token_login': if (this.state.logged_in) return; var self = this; - var client = MatrixClientPeg.get(); - var serviceUrl = Cas.getServiceUrl(); + MatrixClientPeg.replaceUsingUrls( + payload.params.homeserver, + payload.params.identityServer + ); - client.loginWithCas(payload.params.ticket, serviceUrl).done(function(data) { + var client = MatrixClientPeg.get(); + client.loginWithToken(payload.params.loginToken).done(function(data) { MatrixClientPeg.replaceUsingAccessToken( client.getHomeserverUrl(), client.getIdentityServerUrl(), data.user_id, data.access_token @@ -387,9 +388,9 @@ module.exports = { action: 'start_login', params: params }); - } else if (screen == 'cas_login') { + } else if (screen == 'token_login') { dis.dispatch({ - action: 'cas_login', + action: 'token_login', params: params }); } else if (screen.indexOf('room/') == 0) { From a7c53e99d9675f6cbceba5ea206c769235c50410 Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Fri, 6 Nov 2015 11:42:13 +0000 Subject: [PATCH 3/7] Clear query params from url with a nasty location update --- src/controllers/pages/MatrixChat.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/controllers/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js index 796a3e858e..e258866317 100644 --- a/src/controllers/pages/MatrixChat.js +++ b/src/controllers/pages/MatrixChat.js @@ -23,6 +23,8 @@ var sdk = require('../../index'); var MatrixTools = require('../../MatrixTools'); var linkifyMatrix = require("../../linkify-matrix"); +var url = require('url'); + module.exports = { PageTypes: { RoomView: "room_view", @@ -157,8 +159,13 @@ module.exports = { screen: undefined, logged_in: true }); - self.startMatrixClient(); - self.notifyNewScreen(''); + + // We're left with the login token, hs and is url as query params + // in the url, a little nasty but let's redirect to clear them + var parsedUrl = url.parse(window.location.href); + parsedUrl.search = ""; + window.location.href = url.format(parsedUrl); + }, function(error) { self.notifyNewScreen('login'); self.setState({errorText: 'Login failed.'}); From fec362c4df9111a5759e62363bf8e0b4b306c289 Mon Sep 17 00:00:00 2001 From: Steven Hammerton Date: Fri, 6 Nov 2015 12:12:51 +0000 Subject: [PATCH 4/7] JS SDK no longer does redirect for us, get the URL and update browser window location --- src/controllers/organisms/CasLogin.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controllers/organisms/CasLogin.js b/src/controllers/organisms/CasLogin.js index 95791a1a9a..d84306e587 100644 --- a/src/controllers/organisms/CasLogin.js +++ b/src/controllers/organisms/CasLogin.js @@ -26,7 +26,8 @@ module.exports = { var parsedUrl = url.parse(window.location.href, true); parsedUrl.query["homeserver"] = cli.getHomeserverUrl(); parsedUrl.query["identityServer"] = cli.getIdentityServerUrl(); - MatrixClientPeg.get().loginWithCas(url.format(parsedUrl)); + var casUrl = MatrixClientPeg.get().getCasLoginUrl(url.format(parsedUrl)); + window.location.href = casUrl; }, }; From 143483ec126468726eea395d059bea52fd5b0355 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Mon, 9 Nov 2015 17:36:14 +0000 Subject: [PATCH 5/7] Support inviting by email address and hit the right API. --- src/controllers/organisms/MemberList.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/controllers/organisms/MemberList.js b/src/controllers/organisms/MemberList.js index 48fef531bb..7d4326ef69 100644 --- a/src/controllers/organisms/MemberList.js +++ b/src/controllers/organisms/MemberList.js @@ -109,9 +109,11 @@ module.exports = { onInvite: function(inputText) { var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var self = this; - // sanity check the input inputText = inputText.trim(); // react requires es5-shim so we know trim() exists - if (inputText[0] !== '@' || inputText.indexOf(":") === -1) { + var isEmailAddress = /^\S+@\S+\.\S+$/.test(inputText); + + // sanity check the input for user IDs + if (!isEmailAddress && (inputText[0] !== '@' || inputText.indexOf(":") === -1)) { console.error("Bad user ID to invite: %s", inputText); Modal.createDialog(ErrorDialog, { title: "Invite Error", @@ -119,12 +121,22 @@ module.exports = { }); return; } + + var promise; + if (isEmailAddress) { + promise = MatrixClientPeg.get().inviteByEmail(this.props.roomId, inputText); + } + else { + promise = MatrixClientPeg.get().invite(this.props.roomId, inputText); + } + self.setState({ inviting: true }); - console.log("Invite %s to %s", inputText, this.props.roomId); - MatrixClientPeg.get().invite(this.props.roomId, inputText).done( - function(res) { + console.log( + "Invite %s to %s - isEmail=%s", inputText, this.props.roomId, isEmailAddress + ); + promise.done(function(res) { console.log("Invited"); self.setState({ inviting: false From efd88b9a8307a4148387ab3420935cead6ea0ccd Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 9 Nov 2015 23:13:43 +0000 Subject: [PATCH 6/7] upgrade to react 0.14 --- package.json | 3 ++- src/Modal.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ff7d75e712..4eef79a98f 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "matrix-js-sdk": "^0.3.0", "optimist": "^0.6.1", "q": "^1.4.1", - "react": "^0.13.3", + "react": "^0.14.2", + "react-dom": "^0.14.2", "react-loader": "^1.4.0" }, "//deps": "The loader packages are here because webpack in a project that depends on us needs them in this package's node_modules folder", diff --git a/src/Modal.js b/src/Modal.js index bf7758a1a8..a7dd4ca82d 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; var React = require('react'); +var ReactDOM = require('react-dom'); module.exports = { DialogContainerId: "mx_Dialog_Container", @@ -52,7 +53,7 @@ module.exports = { ); - React.render(dialog, this.getOrCreateContainer()); + ReactDOM.render(dialog, this.getOrCreateContainer()); return {close: closeDialog}; }, @@ -77,7 +78,7 @@ module.exports = { ); - React.render(dialog, this.getOrCreateContainer()); + ReactDOM.render(dialog, this.getOrCreateContainer()); return {close: closeDialog}; }, From b5402d0fa04b508e779dc80aaf88a4b5cc1f6cc3 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 9 Nov 2015 23:59:28 +0000 Subject: [PATCH 7/7] port to react 0.14, removing getDOMNode()s for DOM components and turning them into ReactDOM.findDOMNode()s for React components --- src/controllers/molecules/MEmoteTile.js | 2 +- src/controllers/molecules/MNoticeTile.js | 2 +- src/controllers/molecules/MTextTile.js | 2 +- src/controllers/molecules/MessageComposer.js | 16 ++++++++-------- src/controllers/organisms/RoomView.js | 14 +++++++------- src/controllers/templates/Register.js | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/controllers/molecules/MEmoteTile.js b/src/controllers/molecules/MEmoteTile.js index 1fb117ceef..d32d8ae911 100644 --- a/src/controllers/molecules/MEmoteTile.js +++ b/src/controllers/molecules/MEmoteTile.js @@ -24,7 +24,7 @@ linkifyMatrix(linkify); module.exports = { componentDidMount: function() { - linkifyElement(this.refs.content.getDOMNode(), linkifyMatrix.options); + linkifyElement(this.refs.content, linkifyMatrix.options); } }; diff --git a/src/controllers/molecules/MNoticeTile.js b/src/controllers/molecules/MNoticeTile.js index aceb029495..597ce3cd10 100644 --- a/src/controllers/molecules/MNoticeTile.js +++ b/src/controllers/molecules/MNoticeTile.js @@ -23,6 +23,6 @@ linkifyMatrix(linkify); module.exports = { componentDidMount: function() { - linkifyElement(this.refs.content.getDOMNode(), linkifyMatrix.options); + linkifyElement(this.refs.content, linkifyMatrix.options); } }; diff --git a/src/controllers/molecules/MTextTile.js b/src/controllers/molecules/MTextTile.js index 1fb117ceef..d32d8ae911 100644 --- a/src/controllers/molecules/MTextTile.js +++ b/src/controllers/molecules/MTextTile.js @@ -24,7 +24,7 @@ linkifyMatrix(linkify); module.exports = { componentDidMount: function() { - linkifyElement(this.refs.content.getDOMNode(), linkifyMatrix.options); + linkifyElement(this.refs.content, linkifyMatrix.options); } }; diff --git a/src/controllers/molecules/MessageComposer.js b/src/controllers/molecules/MessageComposer.js index c2b67c7898..7bb2ef9c18 100644 --- a/src/controllers/molecules/MessageComposer.js +++ b/src/controllers/molecules/MessageComposer.js @@ -130,7 +130,7 @@ module.exports = { componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); this.sentHistory.init( - this.refs.textarea.getDOMNode(), + this.refs.textarea, this.props.room.roomId ); }, @@ -143,14 +143,14 @@ module.exports = { onAction: function(payload) { switch (payload.action) { case 'focus_composer': - this.refs.textarea.getDOMNode().focus(); + this.refs.textarea.focus(); break; } }, onKeyDown: function (ev) { if (ev.keyCode === KeyCode.ENTER) { - var input = this.refs.textarea.getDOMNode().value; + var input = this.refs.textarea.value; if (input.length === 0) { ev.preventDefault(); return; @@ -179,7 +179,7 @@ module.exports = { var self = this; setTimeout(function() { - if (self.refs.textarea && self.refs.textarea.getDOMNode().value != '') { + if (self.refs.textarea && self.refs.textarea.value != '') { self.onTypingActivity(); } else { self.onFinishedTyping(); @@ -188,13 +188,13 @@ module.exports = { }, onEnter: function(ev) { - var contentText = this.refs.textarea.getDOMNode().value; + var contentText = this.refs.textarea.value; var cmd = SlashCommands.processInput(this.props.room.roomId, contentText); if (cmd) { ev.preventDefault(); if (!cmd.error) { - this.refs.textarea.getDOMNode().value = ''; + this.refs.textarea.value = ''; } if (cmd.promise) { cmd.promise.done(function() { @@ -241,12 +241,12 @@ module.exports = { action: 'message_send_failed' }); }); - this.refs.textarea.getDOMNode().value = ''; + this.refs.textarea.value = ''; ev.preventDefault(); }, onTab: function(ev, sortedMembers) { - var textArea = this.refs.textarea.getDOMNode(); + var textArea = this.refs.textarea; if (!this.tabStruct.completing) { this.tabStruct.completing = true; this.tabStruct.index = 0; diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index 931dbb5bcb..105392de0b 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -49,7 +49,7 @@ module.exports = { componentWillUnmount: function() { if (this.refs.messageWrapper) { - var messageWrapper = this.refs.messageWrapper.getDOMNode(); + var messageWrapper = this.refs.messageWrapper; messageWrapper.removeEventListener('drop', this.onDrop); messageWrapper.removeEventListener('dragover', this.onDragOver); messageWrapper.removeEventListener('dragleave', this.onDragLeaveOrEnd); @@ -83,7 +83,7 @@ module.exports = { // scroll to bottom var messageWrapper = this.refs.messageWrapper; if (messageWrapper) { - messageWrapper = messageWrapper.getDOMNode(); + messageWrapper = messageWrapper; messageWrapper.scrollTop = messageWrapper.scrollHeight; } break; @@ -111,7 +111,7 @@ module.exports = { if (room.roomId != this.props.roomId) return; if (this.refs.messageWrapper) { - var messageWrapper = this.refs.messageWrapper.getDOMNode(); + var messageWrapper = this.refs.messageWrapper; this.atBottom = ( messageWrapper.scrollHeight - messageWrapper.scrollTop <= (messageWrapper.clientHeight + 150) @@ -155,7 +155,7 @@ module.exports = { componentDidMount: function() { if (this.refs.messageWrapper) { - var messageWrapper = this.refs.messageWrapper.getDOMNode(); + var messageWrapper = this.refs.messageWrapper; messageWrapper.addEventListener('drop', this.onDrop); messageWrapper.addEventListener('dragover', this.onDragOver); @@ -171,7 +171,7 @@ module.exports = { componentDidUpdate: function() { if (!this.refs.messageWrapper) return; - var messageWrapper = this.refs.messageWrapper.getDOMNode(); + var messageWrapper = this.refs.messageWrapper; if (this.state.paginating && !this.waiting_for_paginate) { var heightGained = messageWrapper.scrollHeight - this.oldScrollHeight; @@ -190,7 +190,7 @@ module.exports = { fillSpace: function() { if (!this.refs.messageWrapper) return; - var messageWrapper = this.refs.messageWrapper.getDOMNode(); + var messageWrapper = this.refs.messageWrapper; if (messageWrapper.scrollTop < messageWrapper.clientHeight && this.state.room.oldState.paginationToken) { this.setState({paginating: true}); @@ -241,7 +241,7 @@ module.exports = { onMessageListScroll: function(ev) { if (this.refs.messageWrapper) { - var messageWrapper = this.refs.messageWrapper.getDOMNode(); + var messageWrapper = this.refs.messageWrapper; var wasAtBottom = this.atBottom; this.atBottom = messageWrapper.scrollHeight - messageWrapper.scrollTop <= messageWrapper.clientHeight; if (this.atBottom && !wasAtBottom) { diff --git a/src/controllers/templates/Register.js b/src/controllers/templates/Register.js index 53d1ad1219..59377b55f8 100644 --- a/src/controllers/templates/Register.js +++ b/src/controllers/templates/Register.js @@ -87,7 +87,7 @@ module.exports = { var scriptTag = document.createElement('script'); window.mx_on_recaptcha_loaded = this.onCaptchaLoaded; scriptTag.setAttribute('src', global.location.protocol+"//www.google.com/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit"); - this.refs.recaptchaContainer.getDOMNode().appendChild(scriptTag); + this.refs.recaptchaContainer.appendChild(scriptTag); } },