From e671ce437a4573bf1c30f09a44e2496b57213cff Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 19 Nov 2024 16:16:10 +0100 Subject: [PATCH] MOBILE-4028 links: Fix opening links to sites with token expired --- .../services/contentlinks-delegate.ts | 22 +++++++--- .../features/sitehome/tests/links.test.ts | 1 + src/core/services/navigator.ts | 40 +++++++++++++++---- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/core/features/contentlinks/services/contentlinks-delegate.ts b/src/core/features/contentlinks/services/contentlinks-delegate.ts index b83b4109e..d76bb7ca0 100644 --- a/src/core/features/contentlinks/services/contentlinks-delegate.ts +++ b/src/core/features/contentlinks/services/contentlinks-delegate.ts @@ -19,6 +19,7 @@ import { CoreUrl } from '@singletons/url'; import { makeSingleton } from '@singletons'; import { CoreText } from '@singletons/text'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreNavigator } from '@services/navigator'; /** * Interface that all handlers must implement. @@ -208,15 +209,24 @@ export class CoreContentLinksDelegateService { // Wrap the action function in our own function to treat logged out sites. const actionFunction = action.action; action.action = async (siteId) => { - const site = await CoreSites.getSite(siteId); + if (!CoreSites.isLoggedIn()) { + // Not logged in, load site first. + const loggedIn = await CoreSites.loadSite(siteId, { urlToOpen: url }); + if (loggedIn) { + await CoreNavigator.navigateToSiteHome({ params: { urlToOpen: url } }); + } - if (!site.isLoggedOut()) { - // Call the action now. - return actionFunction(siteId); + return; } - // Site is logged out, authenticate first before treating the URL. - await CoreSites.logout({ urlToOpen: url, siteId }); + if (siteId !== CoreSites.getCurrentSiteId()) { + // Different site, logout and login first before treating the URL because token could be expired. + await CoreSites.logout({ urlToOpen: url, siteId }); + + return; + } + + actionFunction(siteId); }; }); diff --git a/src/core/features/sitehome/tests/links.test.ts b/src/core/features/sitehome/tests/links.test.ts index cf4b21326..c0f58e06f 100644 --- a/src/core/features/sitehome/tests/links.test.ts +++ b/src/core/features/sitehome/tests/links.test.ts @@ -33,6 +33,7 @@ describe('Site Home link handlers', () => { getSite: () => Promise.resolve(new CoreSite(siteId, siteUrl, '')), getSiteIdsFromUrl: () => Promise.resolve([siteId]), getCurrentSiteId: () => siteId, + isLoggedIn: () => true, })); mockSingleton(CoreLoginHelper, { getAvailableSites: async () => [{ url: siteUrl, name: 'Example Campus' }] }); diff --git a/src/core/services/navigator.ts b/src/core/services/navigator.ts index 2d07de2d3..0c840b043 100644 --- a/src/core/services/navigator.ts +++ b/src/core/services/navigator.ts @@ -195,7 +195,7 @@ export class CoreNavigatorService { async navigateToSiteHome(options: Omit & { siteId?: string } = {}): Promise { const siteId = options.siteId ?? CoreSites.getCurrentSiteId(); const landingPagePath = CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() === siteId ? - this.getLandingTabPage() : 'main'; + this.getLandingTabPage() : ''; return this.navigateToSitePath(landingPagePath, { ...options, @@ -221,8 +221,7 @@ export class CoreNavigatorService { // If we are logged into a different site, log out first. if (CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() !== siteId) { await CoreSites.logout({ - redirectPath: path, - redirectOptions: options || {}, + ...this.getRedirectDataForSitePath(path, options), siteId, }); @@ -242,10 +241,7 @@ export class CoreNavigatorService { const modal = await CoreLoadings.show(); try { - const loggedIn = await CoreSites.loadSite(siteId, { - redirectPath: path, - redirectOptions: options, - }); + const loggedIn = await CoreSites.loadSite(siteId, this.getRedirectDataForSitePath(path, options)); if (!loggedIn) { // User has been redirected to the login page and will be redirected to the site path after login. @@ -263,6 +259,31 @@ export class CoreNavigatorService { return this.navigateToMainMenuPath(path, navigationOptions); } + /** + * Get the redirect data to use when navigating to a site path. + * + * @param path Site path. + * @param options Navigation options. + * @returns Redirect data. + */ + protected getRedirectDataForSitePath(path: string, options: CoreNavigationOptions = {}): CoreRedirectPayload { + if (!path || path.match(/^\/?main\/?$/)) { + // Navigating to main, obtain the redirect from the navigation parameters (if any). + // If there is no redirect path or url to open, use 'main' to open the site's main menu. + return { + redirectPath: !options.params?.redirectPath && !options.params?.urlToOpen ? 'main' : options.params?.redirectPath, + redirectOptions: options.params?.redirectOptions, + urlToOpen: options.params?.urlToOpen, + }; + } + + // Use the path to navigate as the redirect path. + return { + redirectPath: path, + redirectOptions: options || {}, + }; + } + /** * Get the active route path. * @@ -546,6 +567,11 @@ export class CoreNavigatorService { ...options, }; + if (!path || path.match(/^\/?main\/?$/)) { + // Navigating to main, nothing else to do. + return this.navigate('/main', options); + } + path = path.replace(/^(\.|\/main)?\//, ''); const pathRoot = /^[^/]+/.exec(path)?.[0] ?? '';