MOBILE-4028 links: Fix opening links to sites with token expired

main
Dani Palou 2024-11-19 16:16:10 +01:00
parent feff5a87f8
commit e671ce437a
3 changed files with 50 additions and 13 deletions

View File

@ -19,6 +19,7 @@ import { CoreUrl } from '@singletons/url';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CorePromiseUtils } from '@singletons/promise-utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreNavigator } from '@services/navigator';
/** /**
* Interface that all handlers must implement. * 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. // Wrap the action function in our own function to treat logged out sites.
const actionFunction = action.action; const actionFunction = action.action;
action.action = async (siteId) => { 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()) { return;
// Call the action now.
return actionFunction(siteId);
} }
// Site is logged out, authenticate first before treating the URL. if (siteId !== CoreSites.getCurrentSiteId()) {
await CoreSites.logout({ urlToOpen: url, siteId }); // Different site, logout and login first before treating the URL because token could be expired.
await CoreSites.logout({ urlToOpen: url, siteId });
return;
}
actionFunction(siteId);
}; };
}); });

View File

@ -33,6 +33,7 @@ describe('Site Home link handlers', () => {
getSite: () => Promise.resolve(new CoreSite(siteId, siteUrl, '')), getSite: () => Promise.resolve(new CoreSite(siteId, siteUrl, '')),
getSiteIdsFromUrl: () => Promise.resolve([siteId]), getSiteIdsFromUrl: () => Promise.resolve([siteId]),
getCurrentSiteId: () => siteId, getCurrentSiteId: () => siteId,
isLoggedIn: () => true,
})); }));
mockSingleton(CoreLoginHelper, { getAvailableSites: async () => [{ url: siteUrl, name: 'Example Campus' }] }); mockSingleton(CoreLoginHelper, { getAvailableSites: async () => [{ url: siteUrl, name: 'Example Campus' }] });

View File

@ -195,7 +195,7 @@ export class CoreNavigatorService {
async navigateToSiteHome(options: Omit<CoreNavigationOptions, 'reset'> & { siteId?: string } = {}): Promise<boolean> { async navigateToSiteHome(options: Omit<CoreNavigationOptions, 'reset'> & { siteId?: string } = {}): Promise<boolean> {
const siteId = options.siteId ?? CoreSites.getCurrentSiteId(); const siteId = options.siteId ?? CoreSites.getCurrentSiteId();
const landingPagePath = CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() === siteId ? const landingPagePath = CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() === siteId ?
this.getLandingTabPage() : 'main'; this.getLandingTabPage() : '';
return this.navigateToSitePath(landingPagePath, { return this.navigateToSitePath(landingPagePath, {
...options, ...options,
@ -221,8 +221,7 @@ export class CoreNavigatorService {
// If we are logged into a different site, log out first. // If we are logged into a different site, log out first.
if (CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() !== siteId) { if (CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() !== siteId) {
await CoreSites.logout({ await CoreSites.logout({
redirectPath: path, ...this.getRedirectDataForSitePath(path, options),
redirectOptions: options || {},
siteId, siteId,
}); });
@ -242,10 +241,7 @@ export class CoreNavigatorService {
const modal = await CoreLoadings.show(); const modal = await CoreLoadings.show();
try { try {
const loggedIn = await CoreSites.loadSite(siteId, { const loggedIn = await CoreSites.loadSite(siteId, this.getRedirectDataForSitePath(path, options));
redirectPath: path,
redirectOptions: options,
});
if (!loggedIn) { if (!loggedIn) {
// User has been redirected to the login page and will be redirected to the site path after login. // 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); 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. * Get the active route path.
* *
@ -546,6 +567,11 @@ export class CoreNavigatorService {
...options, ...options,
}; };
if (!path || path.match(/^\/?main\/?$/)) {
// Navigating to main, nothing else to do.
return this.navigate('/main', options);
}
path = path.replace(/^(\.|\/main)?\//, ''); path = path.replace(/^(\.|\/main)?\//, '');
const pathRoot = /^[^/]+/.exec(path)?.[0] ?? ''; const pathRoot = /^[^/]+/.exec(path)?.[0] ?? '';