diff --git a/src/BasePlatform.js b/src/BasePlatform.js index 7214031586..8a950dc2e3 100644 --- a/src/BasePlatform.js +++ b/src/BasePlatform.js @@ -167,13 +167,9 @@ export default class BasePlatform { setLanguage(preferredLangs: string[]) {} - getSSOCallbackUrl(hsUrl: string, isUrl: string): URL { + getSSOCallbackUrl(hsUrl: string, isUrl: string, fragmentAfterLogin: string): URL { const url = new URL(window.location.href); - // XXX: at this point, the fragment will always be #/login, which is no - // use to anyone. Ideally, we would get the intended fragment from - // MatrixChat.screenAfterLogin so that you could follow #/room links etc - // through an SSO login. - url.hash = ""; + url.hash = fragmentAfterLogin || ""; url.searchParams.set("homeserver", hsUrl); url.searchParams.set("identityServer", isUrl); return url; @@ -183,9 +179,11 @@ export default class BasePlatform { * Begin Single Sign On flows. * @param {MatrixClient} mxClient the matrix client using which we should start the flow * @param {"sso"|"cas"} loginType the type of SSO it is, CAS/SSO. + * @param {string} fragmentAfterLogin the hash to pass to the app during sso callback. */ - startSingleSignOn(mxClient: MatrixClient, loginType: "sso"|"cas") { - const callbackUrl = this.getSSOCallbackUrl(mxClient.getHomeserverUrl(), mxClient.getIdentityServerUrl()); + startSingleSignOn(mxClient: MatrixClient, loginType: "sso" | "cas", fragmentAfterLogin: string) { + const callbackUrl = this.getSSOCallbackUrl(mxClient.getHomeserverUrl(), mxClient.getIdentityServerUrl(), + fragmentAfterLogin); window.location.href = mxClient.getSsoLoginUrl(callbackUrl.toString(), loginType); // redirect to SSO } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 3929711406..8ff8abb190 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1973,6 +1973,11 @@ export default class MatrixChat extends React.PureComponent { render() { // console.log(`Rendering MatrixChat with view ${this.state.view}`); + let fragmentAfterLogin = ""; + if (this.props.initialScreenAfterLogin) { + fragmentAfterLogin = `/${this.props.initialScreenAfterLogin.screen}`; + } + let view; if (this.state.view === Views.LOADING) { @@ -2052,7 +2057,7 @@ export default class MatrixChat extends React.PureComponent { } } else if (this.state.view === Views.WELCOME) { const Welcome = sdk.getComponent('auth.Welcome'); - view = ; + view = ; } else if (this.state.view === Views.REGISTER) { const Registration = sdk.getComponent('structures.auth.Registration'); view = ( @@ -2091,6 +2096,7 @@ export default class MatrixChat extends React.PureComponent { defaultDeviceDisplayName={this.props.defaultDeviceDisplayName} onForgotPasswordClick={this.onForgotPasswordClick} onServerConfigChange={this.onServerConfigChange} + fragmentAfterLogin={fragmentAfterLogin} {...this.getServerProperties()} /> ); @@ -2100,6 +2106,7 @@ export default class MatrixChat extends React.PureComponent { ); } else { diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index 5d3cb69417..e65a223bd6 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -355,7 +355,8 @@ export default createReactClass({ ev.preventDefault(); ev.stopPropagation(); const ssoKind = step === 'm.login.sso' ? 'sso' : 'cas'; - PlatformPeg.get().startSingleSignOn(this._loginLogic.createTemporaryClient(), ssoKind); + PlatformPeg.get().startSingleSignOn(this._loginLogic.createTemporaryClient(), ssoKind, + this.props.fragmentAfterLogin); } else { // Don't intercept - just go through to the register page this.onRegisterClick(ev); @@ -628,7 +629,9 @@ export default createReactClass({ + loginType={loginType} + fragmentAfterLogin={this.props.fragmentAfterLogin} + /> ); }, diff --git a/src/components/structures/auth/SoftLogout.js b/src/components/structures/auth/SoftLogout.js index 08ab7e8a61..ede1041f8a 100644 --- a/src/components/structures/auth/SoftLogout.js +++ b/src/components/structures/auth/SoftLogout.js @@ -244,7 +244,9 @@ export default class SoftLogout extends React.Component {

{introText}

+ loginType={this.state.loginView === LOGIN_VIEW.CAS ? "cas" : "sso"} + fragmentAfterLogin={this.props.fragmentAfterLogin} + /> ); } diff --git a/src/components/views/auth/Welcome.js b/src/components/views/auth/Welcome.js index 7cbcf65d3c..91ba368f70 100644 --- a/src/components/views/auth/Welcome.js +++ b/src/components/views/auth/Welcome.js @@ -45,7 +45,8 @@ export default class Welcome extends React.PureComponent { idBaseUrl: isUrl, }); const plaf = PlatformPeg.get(); - const callbackUrl = plaf.getSSOCallbackUrl(tmpClient.getHomeserverUrl(), tmpClient.getIdentityServerUrl()); + const callbackUrl = plaf.getSSOCallbackUrl(tmpClient.getHomeserverUrl(), tmpClient.getIdentityServerUrl(), + this.props.fragmentAfterLogin); return ( diff --git a/src/components/views/elements/SSOButton.js b/src/components/views/elements/SSOButton.js index 3e0757924b..1126ae3cd7 100644 --- a/src/components/views/elements/SSOButton.js +++ b/src/components/views/elements/SSOButton.js @@ -21,9 +21,9 @@ import PlatformPeg from "../../../PlatformPeg"; import AccessibleButton from "./AccessibleButton"; import {_t} from "../../../languageHandler"; -const SSOButton = ({matrixClient, loginType, ...props}) => { +const SSOButton = ({matrixClient, loginType, fragmentAfterLogin, ...props}) => { const onClick = () => { - PlatformPeg.get().startSingleSignOn(matrixClient, loginType); + PlatformPeg.get().startSingleSignOn(matrixClient, loginType, fragmentAfterLogin); }; return ( @@ -36,6 +36,7 @@ const SSOButton = ({matrixClient, loginType, ...props}) => { SSOButton.propTypes = { matrixClient: PropTypes.object.isRequired, // does not use context as may use a temporary client loginType: PropTypes.oneOf(["sso", "cas"]), // defaults to "sso" in base-apis + fragmentAfterLogin: PropTypes.string, }; export default SSOButton;