OIDC: extract success/failure handlers from token login function (#11154)
* extract success/failure handlers from token login function * typo * use for no homeserver error dialog too * i18n * tidy * Update src/Lifecycle.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * move try again responsibility --------- Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
parent
f62fe2626c
commit
3930f1a10b
3 changed files with 53 additions and 31 deletions
|
@ -17,6 +17,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ReactNode } from "react";
|
||||||
import { createClient } from "matrix-js-sdk/src/matrix";
|
import { createClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
|
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
|
@ -204,14 +205,12 @@ export function attemptTokenLogin(
|
||||||
const identityServer = localStorage.getItem(SSO_ID_SERVER_URL_KEY) ?? undefined;
|
const identityServer = localStorage.getItem(SSO_ID_SERVER_URL_KEY) ?? undefined;
|
||||||
if (!homeserver) {
|
if (!homeserver) {
|
||||||
logger.warn("Cannot log in with token: can't determine HS URL to use");
|
logger.warn("Cannot log in with token: can't determine HS URL to use");
|
||||||
Modal.createDialog(ErrorDialog, {
|
onFailedDelegatedAuthLogin(
|
||||||
title: _t("We couldn't log you in"),
|
_t(
|
||||||
description: _t(
|
|
||||||
"We asked the browser to remember which homeserver you use to let you sign in, " +
|
"We asked the browser to remember which homeserver you use to let you sign in, " +
|
||||||
"but unfortunately your browser has forgotten it. Go to the sign in page and try again.",
|
"but unfortunately your browser has forgotten it. Go to the sign in page and try again.",
|
||||||
),
|
),
|
||||||
button: _t("Try again"),
|
);
|
||||||
});
|
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,40 +218,61 @@ export function attemptTokenLogin(
|
||||||
token: queryParams.loginToken as string,
|
token: queryParams.loginToken as string,
|
||||||
initial_device_display_name: defaultDeviceDisplayName,
|
initial_device_display_name: defaultDeviceDisplayName,
|
||||||
})
|
})
|
||||||
.then(function (creds) {
|
.then(async function (creds) {
|
||||||
logger.log("Logged in with token");
|
logger.log("Logged in with token");
|
||||||
return clearStorage().then(async (): Promise<boolean> => {
|
await onSuccessfulDelegatedAuthLogin(creds);
|
||||||
await persistCredentials(creds);
|
return true;
|
||||||
// remember that we just logged in
|
|
||||||
sessionStorage.setItem("mx_fresh_login", String(true));
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((error) => {
|
||||||
Modal.createDialog(ErrorDialog, {
|
const tryAgainCallback: TryAgainFunction = () => {
|
||||||
title: _t("We couldn't log you in"),
|
const cli = createClient({
|
||||||
description: messageForLoginError(err, {
|
baseUrl: homeserver,
|
||||||
|
idBaseUrl: identityServer,
|
||||||
|
});
|
||||||
|
const idpId = localStorage.getItem(SSO_IDP_ID_KEY) || undefined;
|
||||||
|
PlatformPeg.get()?.startSingleSignOn(cli, "sso", fragmentAfterLogin, idpId, SSOAction.LOGIN);
|
||||||
|
};
|
||||||
|
onFailedDelegatedAuthLogin(
|
||||||
|
messageForLoginError(error, {
|
||||||
hsUrl: homeserver,
|
hsUrl: homeserver,
|
||||||
hsName: homeserver,
|
hsName: homeserver,
|
||||||
}),
|
}),
|
||||||
button: _t("Try again"),
|
tryAgainCallback,
|
||||||
onFinished: (tryAgain) => {
|
);
|
||||||
if (tryAgain) {
|
logger.error("Failed to log in with login token:", error);
|
||||||
const cli = createClient({
|
|
||||||
baseUrl: homeserver,
|
|
||||||
idBaseUrl: identityServer,
|
|
||||||
});
|
|
||||||
const idpId = localStorage.getItem(SSO_IDP_ID_KEY) || undefined;
|
|
||||||
PlatformPeg.get()?.startSingleSignOn(cli, "sso", fragmentAfterLogin, idpId, SSOAction.LOGIN);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
logger.error("Failed to log in with login token:");
|
|
||||||
logger.error(err);
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after a successful token login or OIDC authorization.
|
||||||
|
* Clear storage then save new credentials in storage
|
||||||
|
* @param credentials as returned from login
|
||||||
|
*/
|
||||||
|
async function onSuccessfulDelegatedAuthLogin(credentials: IMatrixClientCreds): Promise<void> {
|
||||||
|
await clearStorage();
|
||||||
|
await persistCredentials(credentials);
|
||||||
|
|
||||||
|
// remember that we just logged in
|
||||||
|
sessionStorage.setItem("mx_fresh_login", String(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
type TryAgainFunction = () => void;
|
||||||
|
/**
|
||||||
|
* Display a friendly error to the user when token login or OIDC authorization fails
|
||||||
|
* @param description error description
|
||||||
|
* @param tryAgain OPTIONAL function to call on try again button from error dialog
|
||||||
|
*/
|
||||||
|
async function onFailedDelegatedAuthLogin(description: string | ReactNode, tryAgain?: TryAgainFunction): Promise<void> {
|
||||||
|
Modal.createDialog(ErrorDialog, {
|
||||||
|
title: _t("We couldn't log you in"),
|
||||||
|
description,
|
||||||
|
button: _t("Try again"),
|
||||||
|
// if we have a tryAgain callback, call it the primary 'try again' button was clicked in the dialog
|
||||||
|
onFinished: tryAgain ? (shouldTryAgain?: boolean) => shouldTryAgain && tryAgain() : undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> | void {
|
export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> | void {
|
||||||
if (e.reason === InvalidStoreError.TOGGLED_LAZY_LOADING) {
|
if (e.reason === InvalidStoreError.TOGGLED_LAZY_LOADING) {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
|
|
|
@ -330,6 +330,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
this.tokenLogin = true;
|
this.tokenLogin = true;
|
||||||
|
|
||||||
// Create and start the client
|
// Create and start the client
|
||||||
|
// accesses the new credentials just set in storage during attemptTokenLogin
|
||||||
|
// and sets logged in state
|
||||||
await Lifecycle.restoreFromLocalStorage({
|
await Lifecycle.restoreFromLocalStorage({
|
||||||
ignoreGuest: true,
|
ignoreGuest: true,
|
||||||
});
|
});
|
||||||
|
|
|
@ -101,8 +101,8 @@
|
||||||
"Failed to transfer call": "Failed to transfer call",
|
"Failed to transfer call": "Failed to transfer call",
|
||||||
"Permission Required": "Permission Required",
|
"Permission Required": "Permission Required",
|
||||||
"You do not have permission to start a conference call in this room": "You do not have permission to start a conference call in this room",
|
"You do not have permission to start a conference call in this room": "You do not have permission to start a conference call in this room",
|
||||||
"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, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.",
|
"We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.",
|
||||||
|
"We couldn't log you in": "We couldn't log you in",
|
||||||
"Try again": "Try again",
|
"Try again": "Try again",
|
||||||
"User is not logged in": "User is not logged in",
|
"User is not logged in": "User is not logged in",
|
||||||
"Database unexpectedly closed": "Database unexpectedly closed",
|
"Database unexpectedly closed": "Database unexpectedly closed",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue