Better errors for SSO failures
parent
d06f61393d
commit
bad71cf52f
|
@ -30,6 +30,7 @@ import {idbLoad, idbSave, idbDelete} from "./utils/StorageManager";
|
|||
|
||||
export const SSO_HOMESERVER_URL_KEY = "mx_sso_hs_url";
|
||||
export const SSO_ID_SERVER_URL_KEY = "mx_sso_is_url";
|
||||
export const SSO_IDP_ID_KEY = "mx_sso_idp_id";
|
||||
|
||||
export enum UpdateCheckStatus {
|
||||
Checking = "CHECKING",
|
||||
|
@ -258,6 +259,9 @@ export default abstract class BasePlatform {
|
|||
if (mxClient.getIdentityServerUrl()) {
|
||||
localStorage.setItem(SSO_ID_SERVER_URL_KEY, mxClient.getIdentityServerUrl());
|
||||
}
|
||||
if (idpId) {
|
||||
localStorage.setItem(SSO_IDP_ID_KEY, idpId);
|
||||
}
|
||||
const callbackUrl = this.getSSOCallbackUrl(fragmentAfterLogin);
|
||||
window.location.href = mxClient.getSsoLoginUrl(callbackUrl.toString(), loginType, idpId); // redirect to SSO
|
||||
}
|
||||
|
|
|
@ -46,11 +46,13 @@ import {IntegrationManagers} from "./integrations/IntegrationManagers";
|
|||
import {Mjolnir} from "./mjolnir/Mjolnir";
|
||||
import DeviceListener from "./DeviceListener";
|
||||
import {Jitsi} from "./widgets/Jitsi";
|
||||
import {SSO_HOMESERVER_URL_KEY, SSO_ID_SERVER_URL_KEY} from "./BasePlatform";
|
||||
import {SSO_HOMESERVER_URL_KEY, SSO_ID_SERVER_URL_KEY, SSO_IDP_ID_KEY} from "./BasePlatform";
|
||||
import ThreepidInviteStore from "./stores/ThreepidInviteStore";
|
||||
import CountlyAnalytics from "./CountlyAnalytics";
|
||||
import CallHandler from './CallHandler';
|
||||
import LifecycleCustomisations from "./customisations/Lifecycle";
|
||||
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
|
||||
import {_t} from "./languageHandler";
|
||||
|
||||
const HOMESERVER_URL_KEY = "mx_hs_url";
|
||||
const ID_SERVER_URL_KEY = "mx_is_url";
|
||||
|
@ -162,7 +164,8 @@ export async function getStoredSessionOwner(): Promise<[string, boolean]> {
|
|||
* query-parameters extracted from the real query-string of the starting
|
||||
* URI.
|
||||
*
|
||||
* @param {String} defaultDeviceDisplayName
|
||||
* @param {string} defaultDeviceDisplayName
|
||||
* @param {string} fragmentAfterLogin path to go to after a successful login, only used for "Try again"
|
||||
*
|
||||
* @returns {Promise} promise which resolves to true if we completed the token
|
||||
* login, else false
|
||||
|
@ -170,6 +173,7 @@ export async function getStoredSessionOwner(): Promise<[string, boolean]> {
|
|||
export function attemptTokenLogin(
|
||||
queryParams: Record<string, string>,
|
||||
defaultDeviceDisplayName?: string,
|
||||
fragmentAfterLogin?: string,
|
||||
): Promise<boolean> {
|
||||
if (!queryParams.loginToken) {
|
||||
return Promise.resolve(false);
|
||||
|
@ -179,6 +183,12 @@ export function attemptTokenLogin(
|
|||
const identityServer = localStorage.getItem(SSO_ID_SERVER_URL_KEY);
|
||||
if (!homeserver) {
|
||||
console.warn("Cannot log in with token: can't determine HS URL to use");
|
||||
Modal.createTrackedDialog("SSO", "Unknown HS", ErrorDialog, {
|
||||
title: _t("We couldn't log you in"),
|
||||
description: _t("We asked the browser to remember which homeserver you use, to let you sign in. " +
|
||||
"Unfortunately your browser has forgotten in. Go to the sign in page and try again."),
|
||||
button: _t("Try again"),
|
||||
});
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
|
@ -198,8 +208,28 @@ export function attemptTokenLogin(
|
|||
return true;
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.error("Failed to log in with login token: " + err + " " +
|
||||
err.data);
|
||||
Modal.createTrackedDialog("SSO", "Token Rejected", ErrorDialog, {
|
||||
title: _t("We couldn't log you in"),
|
||||
description: err.name === "ConnectionError"
|
||||
? _t("Your homeserver was unreachable and was not able to log you in. Please try again. " +
|
||||
"If this continues, please contact your homeserver administrator.")
|
||||
: _t("Your homeserver rejected your log in attempt. " +
|
||||
"This could be due to things just taking too long. Please try again. " +
|
||||
"If this continues, please contact your homeserver administrator."),
|
||||
button: _t("Try again"),
|
||||
onFinished: tryAgain => {
|
||||
if (tryAgain) {
|
||||
const cli = Matrix.createClient({
|
||||
baseUrl: homeserver,
|
||||
idBaseUrl: identityServer,
|
||||
});
|
||||
const idpId = localStorage.getItem(SSO_IDP_ID_KEY) || undefined;
|
||||
PlatformPeg.get().startSingleSignOn(cli, "sso", fragmentAfterLogin, idpId);
|
||||
}
|
||||
},
|
||||
});
|
||||
console.error("Failed to log in with login token:");
|
||||
console.error(err);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -325,6 +325,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
Lifecycle.attemptTokenLogin(
|
||||
this.props.realQueryParams,
|
||||
this.props.defaultDeviceDisplayName,
|
||||
this.getFragmentAfterLogin(),
|
||||
).then(async (loggedIn) => {
|
||||
if (this.props.realQueryParams?.loginToken) {
|
||||
// remove the loginToken from the URL regardless
|
||||
|
|
|
@ -50,6 +50,10 @@ export default class ErrorDialog extends React.Component {
|
|||
button: null,
|
||||
};
|
||||
|
||||
onClick = () => {
|
||||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
render() {
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return (
|
||||
|
@ -64,7 +68,7 @@ export default class ErrorDialog extends React.Component {
|
|||
{ this.props.description || _t('An error has occurred.') }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={this.props.onFinished} autoFocus={this.props.focus}>
|
||||
<button className="mx_Dialog_primary" onClick={this.onClick} autoFocus={this.props.focus}>
|
||||
{ this.props.button || _t('OK') }
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -118,6 +118,11 @@
|
|||
"This action requires accessing the default identity server <server /> to validate an email address or phone number, but the server does not have any terms of service.": "This action requires accessing the default identity server <server /> to validate an email address or phone number, but the server does not have any terms of service.",
|
||||
"Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.",
|
||||
"Trust": "Trust",
|
||||
"We couldn't log you in": "We couldn't log you in",
|
||||
"We asked the browser to remember which homeserver you use, to let you sign in. Unfortunately your browser has forgotten in. Go to the sign in page and try again.": "We asked the browser to remember which homeserver you use, to let you sign in. Unfortunately your browser has forgotten in. Go to the sign in page and try again.",
|
||||
"Try again": "Try again",
|
||||
"Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.",
|
||||
"Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.",
|
||||
"%(name)s is requesting verification": "%(name)s is requesting verification",
|
||||
"%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s does not have permission to send you notifications - please check your browser settings",
|
||||
"%(brand)s was not given permission to send notifications - please try again": "%(brand)s was not given permission to send notifications - please try again",
|
||||
|
|
Loading…
Reference in New Issue