mirror of https://github.com/vector-im/riot-web
				
				
				
			Merge pull request #437 from matrix-org/kegan/starter-links
Implement starter link supportpull/21833/head
						commit
						6e2fd85760
					
				|  | @ -18,9 +18,41 @@ var q = require("q"); | |||
| var request = require('browser-request'); | ||||
| 
 | ||||
| var SdkConfig = require('./SdkConfig'); | ||||
| var MatrixClientPeg = require('./MatrixClientPeg'); | ||||
| 
 | ||||
| class ScalarAuthClient { | ||||
|     getScalarToken(openid_token_object) { | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.scalarToken = null; | ||||
|     } | ||||
| 
 | ||||
|     connect() { | ||||
|         return this.getScalarToken().then((tok) => { | ||||
|             this.scalarToken = tok; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     hasCredentials() { | ||||
|         return this.scalarToken != null; // undef or null
 | ||||
|     } | ||||
| 
 | ||||
|     // Returns a scalar_token string
 | ||||
|     getScalarToken() { | ||||
|         var tok = window.localStorage.getItem("mx_scalar_token"); | ||||
|         if (tok) return q(tok); | ||||
| 
 | ||||
|         // No saved token, so do the dance to get one. First, we
 | ||||
|         // need an openid bearer token from the HS.
 | ||||
|         return MatrixClientPeg.get().getOpenIdToken().then((token_object) => { | ||||
|             // Now we can send that to scalar and exchange it for a scalar token
 | ||||
|             return this.exchangeForScalarToken(token_object); | ||||
|         }).then((token_object) => { | ||||
|             window.localStorage.setItem("mx_scalar_token", token_object); | ||||
|             return token_object; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     exchangeForScalarToken(openid_token_object) { | ||||
|         var defer = q.defer(); | ||||
| 
 | ||||
|         var scalar_rest_url = SdkConfig.get().integrations_rest_url; | ||||
|  | @ -43,6 +75,17 @@ class ScalarAuthClient { | |||
| 
 | ||||
|         return defer.promise; | ||||
|     } | ||||
| 
 | ||||
|     getScalarInterfaceUrlForRoom(roomId) { | ||||
|         var url = SdkConfig.get().integrations_ui_url; | ||||
|         url += "?scalar_token=" + encodeURIComponent(this.scalarToken); | ||||
|         url += "&room_id=" + encodeURIComponent(roomId); | ||||
|         return url; | ||||
|     } | ||||
| 
 | ||||
|     getStarterLink(starterLinkUrl) { | ||||
|         return starterLinkUrl + "?scalar_token=" + encodeURIComponent(this.scalarToken); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = ScalarAuthClient; | ||||
|  |  | |||
|  | @ -23,6 +23,10 @@ var linkify = require('linkifyjs'); | |||
| var linkifyElement = require('linkifyjs/element'); | ||||
| var linkifyMatrix = require('../../../linkify-matrix'); | ||||
| var sdk = require('../../../index'); | ||||
| var ScalarAuthClient = require("../../../ScalarAuthClient"); | ||||
| var Modal = require("../../../Modal"); | ||||
| var SdkConfig = require('../../../SdkConfig'); | ||||
| var UserSettingsStore = require('../../../UserSettingsStore'); | ||||
| 
 | ||||
| linkifyMatrix(linkify); | ||||
| 
 | ||||
|  | @ -176,15 +180,66 @@ module.exports = React.createClass({ | |||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     onStarterLinkClick: function(starterLink, ev) { | ||||
|         ev.preventDefault(); | ||||
|         // We need to add on our scalar token to the starter link, but we may not have one!
 | ||||
|         // In addition, we can't fetch one on click and then go to it immediately as that
 | ||||
|         // is then treated as a popup!
 | ||||
|         // We can get around this by fetching one now and showing a "confirmation dialog" (hurr hurr)
 | ||||
|         // which requires the user to click through and THEN we can open the link in a new tab because
 | ||||
|         // the window.open command occurs in the same stack frame as the onClick callback.
 | ||||
| 
 | ||||
|         let integrationsEnabled = UserSettingsStore.isFeatureEnabled("integration_management"); | ||||
|         if (!integrationsEnabled) { | ||||
|             var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); | ||||
|             Modal.createDialog(ErrorDialog, { | ||||
|                 title: "Integrations disabled", | ||||
|                 description: "You need to enable the Labs option 'Integrations Management' in your Vector user settings first.", | ||||
|             }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Go fetch a scalar token
 | ||||
|         let scalarClient = new ScalarAuthClient(); | ||||
|         scalarClient.connect().then(() => { | ||||
|             let completeUrl = scalarClient.getStarterLink(starterLink); | ||||
|             let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); | ||||
|             let integrationsUrl = SdkConfig.get().integrations_ui_url; | ||||
|             Modal.createDialog(QuestionDialog, { | ||||
|                 title: "Add an Integration", | ||||
|                 description: | ||||
|                     <div> | ||||
|                         You are about to taken to a third-party site so you can authenticate your account for use with {integrationsUrl}.<br/> | ||||
|                         Do you wish to continue? | ||||
|                     </div>, | ||||
|                 button: "Continue", | ||||
|                 onFinished: function(confirmed) { | ||||
|                     if (!confirmed) { | ||||
|                         return; | ||||
|                     } | ||||
|                     let width  = window.screen.width  > 1024 ? 1024 : window.screen.width; | ||||
|                     let height = window.screen.height > 800  ? 800 : window.screen.height; | ||||
|                     let left = (window.screen.width - width) / 2; | ||||
|                     let top = (window.screen.height - height) / 2; | ||||
|                     window.open(completeUrl, '_blank', `height=${height}, width=${width}, top=${top}, left=${left},`); | ||||
|                 }, | ||||
|             }); | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         const EmojiText = sdk.getComponent('elements.EmojiText'); | ||||
|         var mxEvent = this.props.mxEvent; | ||||
|         var content = mxEvent.getContent(); | ||||
| 
 | ||||
|         var body = HtmlUtils.bodyToHtml(content, this.props.highlights, {}); | ||||
| 
 | ||||
|         if (this.props.highlightLink) { | ||||
|             body = <a href={ this.props.highlightLink }>{ body }</a>; | ||||
|         } | ||||
|         else if (content.data && typeof content.data["org.matrix.neb.starter_link"] === "string") { | ||||
|             body = <a href="#" onClick={ this.onStarterLinkClick.bind(this, content.data["org.matrix.neb.starter_link"]) }>{ body }</a>; | ||||
|         } | ||||
| 
 | ||||
|         var widgets; | ||||
|         if (this.state.links.length && !this.state.widgetHidden && this.props.showUrlPreview) { | ||||
|  |  | |||
|  | @ -65,7 +65,6 @@ module.exports = React.createClass({ | |||
|             // Default to false if it's undefined, otherwise react complains about changing
 | ||||
|             // components from uncontrolled to controlled
 | ||||
|             isRoomPublished: this._originalIsRoomPublished || false, | ||||
|             scalar_token: null, | ||||
|             scalar_error: null, | ||||
|         }; | ||||
|     }, | ||||
|  | @ -81,11 +80,16 @@ module.exports = React.createClass({ | |||
|             console.error("Failed to get room visibility: " + err); | ||||
|         }); | ||||
| 
 | ||||
|         this.getScalarToken().done((token) => { | ||||
|             this.setState({scalar_token: token}); | ||||
|         }, (err) => { | ||||
|             this.setState({scalar_error: err}); | ||||
|         }); | ||||
|         if (UserSettingsStore.isFeatureEnabled("integration_management")) { | ||||
|             this.scalarClient = new ScalarAuthClient(); | ||||
|             this.scalarClient.connect().done(() => { | ||||
|                 this.forceUpdate(); | ||||
|             }, (err) => { | ||||
|                 this.setState({ | ||||
|                     scalar_error: err | ||||
|                 }); | ||||
|             }) | ||||
|         } | ||||
| 
 | ||||
|         dis.dispatch({ | ||||
|             action: 'ui_opacity', | ||||
|  | @ -395,34 +399,13 @@ module.exports = React.createClass({ | |||
|                 roomState.mayClientSendStateEvent("m.room.guest_access", cli)) | ||||
|     }, | ||||
| 
 | ||||
|     getScalarInterfaceUrl: function() { | ||||
|         var url = SdkConfig.get().integrations_ui_url; | ||||
|         url += "?scalar_token=" + encodeURIComponent(this.state.scalar_token); | ||||
|         url += "&room_id=" + encodeURIComponent(this.props.room.roomId); | ||||
|         return url; | ||||
|     }, | ||||
| 
 | ||||
|     getScalarToken() { | ||||
|         var tok = window.localStorage.getItem("mx_scalar_token"); | ||||
|         if (tok) return q(tok); | ||||
| 
 | ||||
|         // No saved token, so do the dance to get one. First, we
 | ||||
|         // need an openid bearer token from the HS.
 | ||||
|         return MatrixClientPeg.get().getOpenIdToken().then((token_object) => { | ||||
|             // Now we can send that to scalar and exchange it for a scalar token
 | ||||
|             var scalar_auth_client = new ScalarAuthClient(); | ||||
|             return scalar_auth_client.getScalarToken(token_object); | ||||
|         }).then((token_object) => { | ||||
|             window.localStorage.setItem("mx_scalar_token", token_object); | ||||
|             return token_object; | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
|     onManageIntegrations(ev) { | ||||
|         ev.preventDefault(); | ||||
|         var IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); | ||||
|         Modal.createDialog(IntegrationsManager, { | ||||
|             src: this.state.scalar_token ? this.getScalarInterfaceUrl() : null | ||||
|             src: this.scalarClient.hasCredentials() ? | ||||
|                     this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId) : | ||||
|                     null | ||||
|         }, ""); | ||||
|     }, | ||||
| 
 | ||||
|  | @ -649,7 +632,7 @@ module.exports = React.createClass({ | |||
|         if (UserSettingsStore.isFeatureEnabled("integration_management")) { | ||||
|             let integrations_body; | ||||
| 
 | ||||
|             if (this.state.scalar_token) { | ||||
|             if (this.scalarClient.hasCredentials()) { | ||||
|                 integrations_body = ( | ||||
|                     <div className="mx_RoomSettings_settings"> | ||||
|                         <a href="#" onClick={ this.onManageIntegrations }>Manage integrations</a> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Kegsay
						Kegsay