From 9378882ecbb91170dcf992b2df987e46f8df59a9 Mon Sep 17 00:00:00 2001 From: Mathis Hofer Date: Mon, 29 Apr 2024 11:31:39 +0200 Subject: [PATCH] Fix unintentional redirect to dashboard when switching language #167 --- src/components/Portal.ts | 39 +++++++++++++++++++++++---------------- src/state/portal-state.ts | 24 +++++++++++++++++++----- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/components/Portal.ts b/src/components/Portal.ts index 43cb3d66..932d7239 100644 --- a/src/components/Portal.ts +++ b/src/components/Portal.ts @@ -79,22 +79,29 @@ export class Portal extends LitElement { connectedCallback(): void { super.connectedCallback(); - portalState.initialized.then(() => { - // When all roles/permissions have been loaded and the current - // app does not match the scope of the current token, activate a - // token for the app's scope. This can be the case when - // previously authenticated as another user and the current user - // has no access to the navigation item from the redirect URL, - // hence is redirected to home (see - // https://github.com/bkd-mba-fbi/evento-portal/issues/106). - if (tokenState.scope !== portalState.app.scope) { - activateTokenForScope( - oAuthClient, - portalState.app.scope, - portalState.locale, - ); - } - }); + portalState.initialized.then(() => + setTimeout(() => { + // When all roles/permissions have been loaded and the current app does + // not match the scope of the current token, activate a token for the + // app's scope. This can be the case when previously authenticated as + // another user and the current user has no access to the navigation + // item from the redirect URL, hence is redirected to home (see + // https://github.com/bkd-mba-fbi/evento-portal/issues/106). + // + // Also, escape the callstack with the `setTimeout`, to make sure we are + // checking the scope after the `navigate` call in `handleLoginResult` + // (which is also executed when the `initialized` promise is resolved). + // Without the `setTimeout`, we would check the scope before it is set + // correctly. + if (tokenState.scope !== portalState.app.scope) { + activateTokenForScope( + oAuthClient, + portalState.app.scope, + portalState.locale, + ); + } + }), + ); this.subscriptions.push( portalState.subscribeScopeAndLocale( diff --git a/src/state/portal-state.ts b/src/state/portal-state.ts index 691b2b76..182a9c03 100644 --- a/src/state/portal-state.ts +++ b/src/state/portal-state.ts @@ -181,7 +181,14 @@ class PortalState extends State { private async updateLocale(locale: PortalState["locale"]): Promise { updateQueryParam(LOCALE_QUERY_PARAM, locale); - await updateLocale(locale); + try { + await updateLocale(locale); + } catch (error) { + console.warn( + "Unable to fetch/update locale (this may happen when interrupted by a redirect):", + error, + ); + } } private updateNavigation(): void { @@ -253,10 +260,17 @@ class PortalState extends State { private async loadInstanceName(): Promise { if (!tokenState.authenticated) return; - const instanceName = await fetchInstanceName(); - this.instanceName = [msg("Evento"), instanceName] - .filter(Boolean) - .join(" | "); + try { + const instanceName = await fetchInstanceName(); + this.instanceName = [msg("Evento"), instanceName] + .filter(Boolean) + .join(" | "); + } catch (error) { + console.warn( + "Unable to fetch/update instance name (this may happen when interrupted by a redirect):", + error, + ); + } } }