Merge pull request #3870 from dpalou/MOBILE-3947

MOBILE-3947 core: Stop using deprecated guard interfaces
main
Pau Ferrer Ocaña 2023-11-29 15:57:05 +01:00 committed by GitHub
commit bb2e08d0fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 119 additions and 196 deletions

View File

@ -12,39 +12,23 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivateFn } from '@angular/router';
import { ActivatedRouteSnapshot, CanActivate, UrlTree } from '@angular/router';
import { Router } from '@singletons'; import { Router } from '@singletons';
import { AddonMessagesMainMenuHandlerService } from '../services/handlers/mainmenu'; import { AddonMessagesMainMenuHandlerService } from '../services/handlers/mainmenu';
import { AddonMessages } from '../services/messages'; import { AddonMessages } from '../services/messages';
/** /**
* Guard to redirect to the right page based on the current Moodle site version. * Guard to redirect to the right page based on the current Moodle site version.
*
* @returns Route.
*/ */
@Injectable({ providedIn: 'root' }) export const messagesIndexGuard: CanActivateFn = async (route: ActivatedRouteSnapshot) => {
export class AddonMessagesIndexGuard implements CanActivate { const enabled = AddonMessages.isGroupMessagingEnabled();
const path = `/main/${AddonMessagesMainMenuHandlerService.PAGE_NAME}/` + ( enabled ? 'group-conversations' : 'index');
/** const newRoute = Router.parseUrl(path);
* @inheritdoc
*/
canActivate(route: ActivatedRouteSnapshot): UrlTree {
return this.guard(route);
}
/** newRoute.queryParams = route.queryParams;
* Check if there is a pending redirect and trigger it.
*
* @returns The redirection route.
*/
private guard(route: ActivatedRouteSnapshot): UrlTree {
const enabled = AddonMessages.isGroupMessagingEnabled();
const path = `/main/${AddonMessagesMainMenuHandlerService.PAGE_NAME}/` + ( enabled ? 'group-conversations' : 'index');
const newRoute = Router.parseUrl(path); return newRoute;
};
newRoute.queryParams = route.queryParams;
return newRoute;
}
}

View File

@ -28,7 +28,7 @@ import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/comp
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module'; import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
import { CoreSearchComponentsModule } from '@features/search/components/components.module'; import { CoreSearchComponentsModule } from '@features/search/components/components.module';
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { AddonMessagesIndexGuard } from './guards'; import { messagesIndexGuard } from './guards';
/** /**
* Build module routes. * Build module routes.
@ -120,7 +120,7 @@ function buildRoutes(injector: Injector): Routes {
loadChildren: () => import('./messages-settings-lazy.module').then(m => m.AddonMessagesSettingsLazyModule), loadChildren: () => import('./messages-settings-lazy.module').then(m => m.AddonMessagesSettingsLazyModule),
}, },
...buildTabMainRoutes(injector, { ...buildTabMainRoutes(injector, {
canActivate: [AddonMessagesIndexGuard], canActivate: [messagesIndexGuard],
}), }),
]; ];
} }

View File

@ -16,7 +16,7 @@ import { conditionalRoutes } from '@/app/app-routing.module';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { AddonModAssignComponentsModule } from './components/components.module'; import { AddonModAssignComponentsModule } from './components/components.module';
import { AddonModAssignEditPage } from './pages/edit/edit'; import { AddonModAssignEditPage } from './pages/edit/edit';
@ -32,7 +32,7 @@ const commonRoutes: Routes = [
{ {
path: ':courseId/:cmId/edit', path: ':courseId/:cmId/edit',
component: AddonModAssignEditPage, component: AddonModAssignEditPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];
@ -45,7 +45,7 @@ const mobileRoutes: Routes = [
{ {
path: ':courseId/:cmId/submission/:submitId', path: ':courseId/:cmId/submission/:submitId',
component: AddonModAssignSubmissionReviewPage, component: AddonModAssignSubmissionReviewPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];
@ -58,7 +58,7 @@ const tabletRoutes: Routes = [
{ {
path: ':submitId', path: ':submitId',
component: AddonModAssignSubmissionReviewPage, component: AddonModAssignSubmissionReviewPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
], ],
}, },

View File

@ -22,7 +22,7 @@ import { AddonModChatSessionMessagesPage } from './pages/session-messages/sessio
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { conditionalRoutes } from '@/app/app-routing.module'; import { conditionalRoutes } from '@/app/app-routing.module';
import { AddonModChatSessionsPage } from './pages/sessions/sessions'; import { AddonModChatSessionsPage } from './pages/sessions/sessions';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
const commonRoutes: Routes = [ const commonRoutes: Routes = [
{ {
@ -32,7 +32,7 @@ const commonRoutes: Routes = [
{ {
path: ':courseId/:cmId/chat', path: ':courseId/:cmId/chat',
component: AddonModChatChatPage, component: AddonModChatChatPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];

View File

@ -18,7 +18,7 @@ import { RouterModule, Routes } from '@angular/router';
import { CoreCommentsComponentsModule } from '@features/comments/components/components.module'; import { CoreCommentsComponentsModule } from '@features/comments/components/components.module';
import { CoreCompileHtmlComponentModule } from '@features/compile/components/compile-html/compile-html.module'; import { CoreCompileHtmlComponentModule } from '@features/compile/components/compile-html/compile-html.module';
import { CoreRatingComponentsModule } from '@features/rating/components/components.module'; import { CoreRatingComponentsModule } from '@features/rating/components/components.module';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModDataComponentsCompileModule } from './components/components-compile.module'; import { AddonModDataComponentsCompileModule } from './components/components-compile.module';
import { AddonModDataComponentsModule } from './components/components.module'; import { AddonModDataComponentsModule } from './components/components.module';
import { AddonModDataEditPage } from './pages/edit/edit'; import { AddonModDataEditPage } from './pages/edit/edit';
@ -33,12 +33,12 @@ const routes: Routes = [
{ {
path: ':courseId/:cmId/edit', path: ':courseId/:cmId/edit',
component: AddonModDataEditPage, component: AddonModDataEditPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/edit/:entryId', path: ':courseId/:cmId/edit/:entryId',
component: AddonModDataEditPage, component: AddonModDataEditPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/:entryId', path: ':courseId/:cmId/:entryId',

View File

@ -22,7 +22,7 @@ import { conditionalRoutes } from '@/app/app-routing.module';
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { AddonModFeedbackAttemptPage } from '@addons/mod/feedback/pages/attempt/attempt'; import { AddonModFeedbackAttemptPage } from '@addons/mod/feedback/pages/attempt/attempt';
import { AddonModFeedbackFormPage } from '@addons/mod/feedback/pages/form/form'; import { AddonModFeedbackFormPage } from '@addons/mod/feedback/pages/form/form';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModFeedbackNonRespondentsPage } from '@addons/mod/feedback/pages/nonrespondents/nonrespondents'; import { AddonModFeedbackNonRespondentsPage } from '@addons/mod/feedback/pages/nonrespondents/nonrespondents';
const commonRoutes: Routes = [ const commonRoutes: Routes = [
@ -33,7 +33,7 @@ const commonRoutes: Routes = [
{ {
path: ':courseId/:cmId/form', path: ':courseId/:cmId/form',
component: AddonModFeedbackFormPage, component: AddonModFeedbackFormPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/nonrespondents', path: ':courseId/:cmId/nonrespondents',

View File

@ -16,14 +16,14 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module'; import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { AddonModForumDiscussionPage } from '@addons/mod/forum/pages/discussion/discussion'; import { AddonModForumDiscussionPage } from '@addons/mod/forum/pages/discussion/discussion';
const routes: Routes = [{ const routes: Routes = [{
path: '', path: '',
component: AddonModForumDiscussionPage, component: AddonModForumDiscussionPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}]; }];
@NgModule({ @NgModule({

View File

@ -16,7 +16,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module'; import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { CoreEditorComponentsModule } from '@features/editor/components/components.module'; import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { AddonModForumNewDiscussionPage } from '@addons/mod/forum/pages/new-discussion/new-discussion'; import { AddonModForumNewDiscussionPage } from '@addons/mod/forum/pages/new-discussion/new-discussion';
@ -24,7 +24,7 @@ import { AddonModForumNewDiscussionPage } from '@addons/mod/forum/pages/new-disc
const routes: Routes = [{ const routes: Routes = [{
path: '', path: '',
component: AddonModForumNewDiscussionPage, component: AddonModForumNewDiscussionPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}]; }];
@NgModule({ @NgModule({

View File

@ -16,13 +16,13 @@ import { NgModule } from '@angular/core';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CoreEditorComponentsModule } from '@features/editor/components/components.module'; import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModGlossaryEditPage } from '@addons/mod/glossary/pages/edit/edit'; import { AddonModGlossaryEditPage } from '@addons/mod/glossary/pages/edit/edit';
const routes: Routes = [{ const routes: Routes = [{
path: '', path: '',
component: AddonModGlossaryEditPage, component: AddonModGlossaryEditPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}]; }];
@NgModule({ @NgModule({

View File

@ -16,7 +16,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModH5PActivityComponentsModule } from './components/components.module'; import { AddonModH5PActivityComponentsModule } from './components/components.module';
import { AddonModH5PActivityIndexPage } from './pages/index/index'; import { AddonModH5PActivityIndexPage } from './pages/index/index';
import { AddonModH5PActivityUserAttemptsPage } from '@addons/mod/h5pactivity/pages/user-attempts/user-attempts'; import { AddonModH5PActivityUserAttemptsPage } from '@addons/mod/h5pactivity/pages/user-attempts/user-attempts';
@ -27,7 +27,7 @@ const routes: Routes = [
{ {
path: ':courseId/:cmId', path: ':courseId/:cmId',
component: AddonModH5PActivityIndexPage, component: AddonModH5PActivityIndexPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/userattempts/:userId', path: ':courseId/:cmId/userattempts/:userId',

View File

@ -21,7 +21,7 @@ import { AddonModLessonComponentsModule } from './components/components.module';
import { AddonModLessonIndexPage } from './pages/index'; import { AddonModLessonIndexPage } from './pages/index';
import { CoreEditorComponentsModule } from '@features/editor/components/components.module'; import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
import { AddonModLessonPlayerPage } from '@addons/mod/lesson/pages/player/player'; import { AddonModLessonPlayerPage } from '@addons/mod/lesson/pages/player/player';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModLessonUserRetakePage } from '@addons/mod/lesson/pages/user-retake/user-retake'; import { AddonModLessonUserRetakePage } from '@addons/mod/lesson/pages/user-retake/user-retake';
const routes: Routes = [ const routes: Routes = [
@ -32,7 +32,7 @@ const routes: Routes = [
{ {
path: ':courseId/:cmId/player', path: ':courseId/:cmId/player',
component: AddonModLessonPlayerPage, component: AddonModLessonPlayerPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/user-retake/:userId', path: ':courseId/:cmId/user-retake/:userId',

View File

@ -22,7 +22,7 @@ import { AddonModQuizIndexPage } from './pages/index';
import { AddonModQuizAttemptPage } from '@addons/mod/quiz/pages/attempt/attempt'; import { AddonModQuizAttemptPage } from '@addons/mod/quiz/pages/attempt/attempt';
import { CoreQuestionComponentsModule } from '@features/question/components/components.module'; import { CoreQuestionComponentsModule } from '@features/question/components/components.module';
import { AddonModQuizPlayerPage } from '@addons/mod/quiz/pages/player/player'; import { AddonModQuizPlayerPage } from '@addons/mod/quiz/pages/player/player';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModQuizReviewPage } from '@addons/mod/quiz/pages/review/review'; import { AddonModQuizReviewPage } from '@addons/mod/quiz/pages/review/review';
const routes: Routes = [ const routes: Routes = [
@ -33,7 +33,7 @@ const routes: Routes = [
{ {
path: ':courseId/:cmId/player', path: ':courseId/:cmId/player',
component: AddonModQuizPlayerPage, component: AddonModQuizPlayerPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/attempt/:attemptId', path: ':courseId/:cmId/attempt/:attemptId',

View File

@ -18,7 +18,7 @@ import { CoreSharedModule } from '@/core/shared.module';
import { AddonModWikiComponentsModule } from './components/components.module'; import { AddonModWikiComponentsModule } from './components/components.module';
import { AddonModWikiIndexPage } from './pages/index/index'; import { AddonModWikiIndexPage } from './pages/index/index';
import { CoreEditorComponentsModule } from '@features/editor/components/components.module'; import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { AddonModWikiEditPage } from './pages/edit/edit'; import { AddonModWikiEditPage } from './pages/edit/edit';
const routes: Routes = [ const routes: Routes = [
@ -33,7 +33,7 @@ const routes: Routes = [
{ {
path: ':courseId/:cmId/edit', path: ':courseId/:cmId/edit',
component: AddonModWikiEditPage, component: AddonModWikiEditPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];

View File

@ -14,7 +14,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { AddonModWorkshopIndexPage } from './pages/index/index'; import { AddonModWorkshopIndexPage } from './pages/index/index';
@ -32,17 +32,17 @@ const routes: Routes = [
{ {
path: ':courseId/:cmId/:submissionId', path: ':courseId/:cmId/:submissionId',
component: AddonModWorkshopSubmissionPage, component: AddonModWorkshopSubmissionPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/:submissionId/edit', path: ':courseId/:cmId/:submissionId/edit',
component: AddonModWorkshopEditSubmissionPage, component: AddonModWorkshopEditSubmissionPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
{ {
path: ':courseId/:cmId/:submissionId/:assessmentId', path: ':courseId/:cmId/:submissionId/:assessmentId',
component: AddonModWorkshopAssessmentPage, component: AddonModWorkshopAssessmentPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];

View File

@ -12,50 +12,28 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { CanActivateFn } from '@angular/router';
import { CanActivate, CanLoad, UrlTree } from '@angular/router';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { Router } from '@singletons'; import { Router } from '@singletons';
import { CoreLoginHelper } from '../services/login-helper'; import { CoreLoginHelper } from '../services/login-helper';
@Injectable({ providedIn: 'root' }) /**
export class CoreLoginHasSitesGuard implements CanActivate, CanLoad { * Guard to check if the user has any sites stored.
*
* @returns True if user has sites, redirect route otherwise.
*/
export const hasSitesGuard: CanActivateFn = async () => {
const sites = await CoreUtils.ignoreErrors(CoreSites.getSites(), []);
/** if (sites.length > 0) {
* @inheritdoc return true;
*/
canActivate(): Promise<true | UrlTree> {
return this.guard();
} }
/** const [path, params] = await CoreLoginHelper.getAddSiteRouteInfo();
* @inheritdoc const route = Router.parseUrl(path);
*/
canLoad(): Promise<true | UrlTree> {
return this.guard();
}
/** route.queryParams = params;
* Check if the user has any sites stored.
*
* @returns Promise resolved with true if it's not redirected or the redirection route.
*/
private async guard(): Promise<true | UrlTree> {
const sites = await CoreUtils.ignoreErrors(CoreSites.getSites(), []);
if (sites.length > 0) { return route;
return true; };
}
const [path, params] = await CoreLoginHelper.getAddSiteRouteInfo();
const route = Router.parseUrl(path);
route.queryParams = params;
return route;
}
}

View File

@ -16,7 +16,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CoreLoginHasSitesGuard } from './guards/has-sites'; import { hasSitesGuard } from './guards/has-sites';
import { CoreLoginComponentsModule } from './components/components.module'; import { CoreLoginComponentsModule } from './components/components.module';
import { CoreLoginHelper } from './services/login-helper'; import { CoreLoginHelper } from './services/login-helper';
import { CoreLoginForgottenPasswordPage } from '@features/login/pages/forgotten-password/forgotten-password'; import { CoreLoginForgottenPasswordPage } from '@features/login/pages/forgotten-password/forgotten-password';
@ -44,8 +44,7 @@ const routes: Routes = [
{ {
path: 'sites', path: 'sites',
component: CoreLoginSitesPage, component: CoreLoginSitesPage,
canLoad: [CoreLoginHasSitesGuard], canActivate: [hasSitesGuard],
canActivate: [CoreLoginHasSitesGuard],
}, },
{ {
path: 'forgottenpassword', path: 'forgottenpassword',

View File

@ -17,7 +17,7 @@ import { Routes } from '@angular/router';
import { AppRoutingModule } from '@/app/app-routing.module'; import { AppRoutingModule } from '@/app/app-routing.module';
import { CoreLoginHelper, CoreLoginHelperProvider } from './services/login-helper'; import { CoreLoginHelper, CoreLoginHelperProvider } from './services/login-helper';
import { CoreRedirectGuard } from '@guards/redirect'; import { redirectGuard } from '@guards/redirect';
import { CoreLoginCronHandler } from './services/handlers/cron'; import { CoreLoginCronHandler } from './services/handlers/cron';
import { CoreCronDelegate } from '@services/cron'; import { CoreCronDelegate } from '@services/cron';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
@ -30,8 +30,7 @@ const appRoutes: Routes = [
{ {
path: 'login', path: 'login',
loadChildren: () => import('./login-lazy.module').then(m => m.CoreLoginLazyModule), loadChildren: () => import('./login-lazy.module').then(m => m.CoreLoginLazyModule),
canActivate: [CoreRedirectGuard], canActivate: [redirectGuard],
canLoad: [CoreRedirectGuard],
}, },
]; ];

View File

@ -12,61 +12,41 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { CanActivateFn } from '@angular/router';
import { CanLoad, CanActivate, UrlTree } from '@angular/router';
import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CoreLoginHelper } from '@features/login/services/login-helper';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { Router } from '@singletons'; import { Router } from '@singletons';
@Injectable({ providedIn: 'root' }) /**
export class CoreMainMenuAuthGuard implements CanLoad, CanActivate { * Guard to check if the user is authenticated.
*
/** * @returns True if user has sites, redirect route otherwise.
* @inheritdoc */
*/ export const authGuard: CanActivateFn = async () => {
canActivate(): Promise<true | UrlTree> { if (!CoreSites.isLoggedIn()) {
return this.guard(); return Router.parseUrl('/login');
} }
/** if (CoreLoginHelper.isSiteLoggedOut()) {
* @inheritdoc // Send the user to reconnect page.
*/ const newRoute = Router.parseUrl('/login/reconnect');
canLoad(): Promise<true | UrlTree> { const siteId = CoreSites.getCurrentSiteId();
return this.guard();
}
/** // Pass redirect data (if any and belongs to same site).
* Check if the current user should be redirected to the authentication page. let redirect = CoreApp.consumeMemoryRedirect();
* if (redirect?.siteId !== siteId) {
* @returns Promise resolved with true if it's not redirected or the redirection route. redirect = null;
*/
private async guard(): Promise<true | UrlTree> {
if (!CoreSites.isLoggedIn()) {
return Router.parseUrl('/login');
} }
if (CoreLoginHelper.isSiteLoggedOut()) { newRoute.queryParams = {
// Send the user to reconnect page. siteId,
const newRoute = Router.parseUrl('/login/reconnect'); ...redirect,
const siteId = CoreSites.getCurrentSiteId(); };
// Pass redirect data (if any and belongs to same site). return newRoute;
let redirect = CoreApp.consumeMemoryRedirect();
if (redirect?.siteId !== siteId) {
redirect = null;
}
newRoute.queryParams = {
siteId,
...redirect,
};
return newRoute;
}
return true;
} }
} return true;
};

View File

@ -14,7 +14,7 @@
import { APP_INITIALIZER, NgModule } from '@angular/core'; import { APP_INITIALIZER, NgModule } from '@angular/core';
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
import { CoreMainMenuAuthGuard } from '@features/mainmenu/guards/auth'; import { authGuard } from '@features/mainmenu/guards/auth';
import { AppRoutingModule } from '@/app/app-routing.module'; import { AppRoutingModule } from '@/app/app-routing.module';
@ -38,8 +38,7 @@ const appRoutes: Routes = [
{ {
path: 'main', path: 'main',
loadChildren: () => import('./mainmenu-lazy.module').then(m => m.CoreMainMenuLazyModule), loadChildren: () => import('./mainmenu-lazy.module').then(m => m.CoreMainMenuLazyModule),
canActivate: [CoreMainMenuAuthGuard], canActivate: [authGuard],
canLoad: [CoreMainMenuAuthGuard],
}, },
{ {
path: 'reload', path: 'reload',

View File

@ -23,7 +23,7 @@ import { CoreSitePluginsComponentsModule } from './components/components.module'
import { CoreSitePluginsHelper } from './services/siteplugins-helper'; import { CoreSitePluginsHelper } from './services/siteplugins-helper';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CoreSitePluginsPluginPage } from '@features/siteplugins/pages/plugin/plugin'; import { CoreSitePluginsPluginPage } from '@features/siteplugins/pages/plugin/plugin';
import { CanLeaveGuard } from '@guards/can-leave'; import { canLeaveGuard } from '@guards/can-leave';
import { CoreSitePluginsCourseOptionPage } from '@features/siteplugins/pages/course-option/course-option'; import { CoreSitePluginsCourseOptionPage } from '@features/siteplugins/pages/course-option/course-option';
import { CoreSitePluginsModuleIndexPage } from '@features/siteplugins/pages/module-index/module-index'; import { CoreSitePluginsModuleIndexPage } from '@features/siteplugins/pages/module-index/module-index';
@ -31,7 +31,7 @@ const routes: Routes = [
{ {
path: 'siteplugins/content/:component/:method/:hash', path: 'siteplugins/content/:component/:method/:hash',
component: CoreSitePluginsPluginPage, component: CoreSitePluginsPluginPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];
@ -39,7 +39,7 @@ const homeRoutes: Routes = [
{ {
path: 'siteplugins/homecontent/:component/:method', path: 'siteplugins/homecontent/:component/:method',
component: CoreSitePluginsPluginPage, component: CoreSitePluginsPluginPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];
@ -47,7 +47,7 @@ const courseIndexRoutes: Routes = [
{ {
path: 'siteplugins/:handlerUniqueName', path: 'siteplugins/:handlerUniqueName',
component: CoreSitePluginsCourseOptionPage, component: CoreSitePluginsCourseOptionPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];
@ -55,7 +55,7 @@ const moduleRoutes: Routes = [
{ {
path: 'siteplugins/module/:courseId/:cmId', path: 'siteplugins/module/:courseId/:cmId',
component: CoreSitePluginsModuleIndexPage, component: CoreSitePluginsModuleIndexPage,
canDeactivate: [CanLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
]; ];

View File

@ -12,26 +12,30 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { CanDeactivateFn } from '@angular/router';
import { CanDeactivate } from '@angular/router';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
@Injectable({ providedIn: 'root' }) /**
export class CanLeaveGuard implements CanDeactivate<unknown> { * Check if a component implements the canLeave interface.
*
* @param component Component instance to check.
* @returns Whether it implements CanLeave interface.
*/
const isCanLeave = (component: unknown | null): component is CanLeave =>
component !== null && 'canLeave' in <CanLeave> component;
async canDeactivate(component: unknown | null): Promise<boolean> { /**
if (!this.isCanLeave(component)) { * Guard to check if the user can leave a page.
return true; *
} * @returns True if user has sites, redirect route otherwise.
*/
return CoreUtils.ignoreErrors(component.canLeave(), false); export const canLeaveGuard: CanDeactivateFn<unknown> = async (component: unknown) => {
if (!isCanLeave(component)) {
return true;
} }
isCanLeave(component: unknown | null): component is CanLeave { return CoreUtils.ignoreErrors(component.canLeave(), false);
return component !== null && 'canLeave' in <CanLeave> component; };
}
}
export interface CanLeave { export interface CanLeave {
/** /**

View File

@ -12,38 +12,20 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { CanActivateFn } from '@angular/router';
import { CanActivate, CanLoad, UrlTree } from '@angular/router';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreRedirectPayload } from '@services/navigator'; import { CoreRedirectPayload } from '@services/navigator';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { Router } from '@singletons'; import { Router } from '@singletons';
import { CoreConstants } from '../constants'; import { CoreConstants } from '../constants';
@Injectable({ providedIn: 'root' }) /**
export class CoreRedirectGuard implements CanLoad, CanActivate { * Guard to check if there is a pending redirect and trigger it.
*
/** * @returns True if there's no redirect, redirection route otherwise.
* @inheritdoc */
*/ export const redirectGuard: CanActivateFn = async () => {
canLoad(): Promise<true | UrlTree> { const redirect = CoreApp.consumeMemoryRedirect();
return this.guard();
}
/**
* @inheritdoc
*/
canActivate(): Promise<true | UrlTree> {
return this.guard();
}
/**
* Check if there is a pending redirect and trigger it.
*
* @returns Promise resolved with true if it's not redirected or the redirection route.
*/
private async guard(): Promise<true | UrlTree> {
const redirect = CoreApp.consumeMemoryRedirect();
if (!redirect) { if (!redirect) {
return true; return true;
} }
@ -81,6 +63,4 @@ export class CoreRedirectGuard implements CanLoad, CanActivate {
route.queryParams = redirect.redirectOptions?.params || {}; route.queryParams = redirect.redirectOptions?.params || {};
return route; return route;
} };
}