diff --git a/package.json b/package.json index fcdb34a596..888fd9e32a 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.11.1", "text-encoding-utf-8": "^1.0.1", + "url": "^0.11.0", "velocity-vector": "vector-im/velocity#059e3b2", "whatwg-fetch": "^1.0.0" }, diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 6f4c931ab7..bf21d15587 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -18,8 +18,12 @@ limitations under the License. import React from 'react'; import MatrixClientPeg from '../../../MatrixClientPeg'; +import ScalarAuthClient from '../../../ScalarAuthClient'; +import SdkConfig from '../../../SdkConfig'; import { _t } from '../../../languageHandler'; +import url from 'url'; + export default React.createClass({ displayName: 'AppTile', @@ -36,6 +40,52 @@ export default React.createClass({ }; }, + getInitialState: function() { + return { + loading: false, + widgetUrl: this.props.url, + error: null, + }; + }, + + // Returns true if props.url is a scalar URL, typically https://scalar.vector.im/api + isScalarUrl: function() { + const scalarUrl = SdkConfig.get().integrations_rest_url; + return scalarUrl && this.props.url.startsWith(scalarUrl); + }, + + componentWillMount: function() { + if (!this.isScalarUrl()) { + return; + } + // Fetch the token before loading the iframe as we need to mangle the URL + this.setState({ + loading: true, + }); + this._scalarClient = new ScalarAuthClient(); + this._scalarClient.getScalarToken().done((token) => { + // Append scalar_token as a query param + let u = url.parse(this.props.url); + if (!u.search) { + u.search = "?scalar_token=" + encodeURIComponent(token); + } + else { + u.search += "&scalar_token=" + encodeURIComponent(token); + } + + this.setState({ + error: null, + widgetUrl: u.format(), + loading: false, + }); + }, (err) => { + this.setState({ + error: err.message, + loading: false, + }); + }); + }, + _onEditClick: function() { console.log("Edit widget %s", this.props.id); }, @@ -72,6 +122,19 @@ export default React.createClass({ }, render: function() { + let appTileBody; + if (this.state.loading) { + appTileBody = ( +