diff --git a/package.json b/package.json index c1c7f5fbe5..7ea508fd8a 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "matrix-js-sdk": "https://github.com/matrix-org/matrix-js-sdk.git#develop", "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/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/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 = { </div> ); - React.render(dialog, this.getOrCreateContainer()); + ReactDOM.render(dialog, this.getOrCreateContainer()); return {close: closeDialog}; }, @@ -77,7 +78,7 @@ module.exports = { </div> ); - React.render(dialog, this.getOrCreateContainer()); + ReactDOM.render(dialog, this.getOrCreateContainer()); return {close: closeDialog}; }, 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/CasLogin.js b/src/controllers/organisms/CasLogin.js index b01c3781b0..d84306e587 100644 --- a/src/controllers/organisms/CasLogin.js +++ b/src/controllers/organisms/CasLogin.js @@ -17,20 +17,17 @@ 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(); + var casUrl = MatrixClientPeg.get().getCasLoginUrl(url.format(parsedUrl)); + window.location.href = casUrl; }, }; 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) } diff --git a/src/controllers/organisms/MemberList.js b/src/controllers/organisms/MemberList.js index 4dfe5330e1..8b6733fbeb 100644 --- a/src/controllers/organisms/MemberList.js +++ b/src/controllers/organisms/MemberList.js @@ -115,9 +115,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", @@ -125,12 +127,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 diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index 7ab59b497a..3a5d432ebd 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -50,7 +50,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); @@ -85,7 +85,7 @@ module.exports = { // scroll to bottom var messageWrapper = this.refs.messageWrapper; if (messageWrapper) { - messageWrapper = messageWrapper.getDOMNode(); + messageWrapper = messageWrapper; messageWrapper.scrollTop = messageWrapper.scrollHeight; } break; @@ -116,7 +116,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) @@ -166,7 +166,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); @@ -184,7 +184,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; @@ -203,7 +203,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}); @@ -254,7 +254,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/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js index e54f800e63..2fdb9eb8ef 100644 --- a/src/controllers/pages/MatrixChat.js +++ b/src/controllers/pages/MatrixChat.js @@ -24,7 +24,7 @@ var sdk = require('../../index'); var MatrixTools = require('../../MatrixTools'); var linkifyMatrix = require("../../linkify-matrix"); -var Cas = require("../../CasLogic"); +var url = require('url'); module.exports = { PageTypes: { @@ -142,14 +142,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 @@ -158,8 +161,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.'}); @@ -391,9 +399,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) { 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); } },