(core) Use the new "CanMatch" rather than "CanLoad" and "CanActivate" for routes

This commit is contained in:
Sercan Yemen 2022-12-02 14:17:05 +03:00
parent 41a1692e01
commit ba8689ed0c
3 changed files with 41 additions and 105 deletions

View File

@ -12,9 +12,9 @@ export const appRoutes: Route[] = [
// Redirect empty path to '/dashboards/project' // Redirect empty path to '/dashboards/project'
{path: '', pathMatch : 'full', redirectTo: 'dashboards/project'}, {path: '', pathMatch : 'full', redirectTo: 'dashboards/project'},
// Redirect signed in user to the '/dashboards/project' // Redirect signed-in user to the '/dashboards/project'
// //
// After the user signs in, the sign in page will redirect the user to the 'signed-in-redirect' // After the user signs in, the sign-in page will redirect the user to the 'signed-in-redirect'
// path. Below is another redirection for that path to redirect the user to the desired // path. Below is another redirection for that path to redirect the user to the desired
// location. This is a small convenience to keep all main routes together here on this file. // location. This is a small convenience to keep all main routes together here on this file.
{path: 'signed-in-redirect', pathMatch : 'full', redirectTo: 'dashboards/project'}, {path: 'signed-in-redirect', pathMatch : 'full', redirectTo: 'dashboards/project'},
@ -22,8 +22,7 @@ export const appRoutes: Route[] = [
// Auth routes for guests // Auth routes for guests
{ {
path: '', path: '',
canActivate: [NoAuthGuard], canMatch: [NoAuthGuard],
canActivateChild: [NoAuthGuard],
component: LayoutComponent, component: LayoutComponent,
data: { data: {
layout: 'empty' layout: 'empty'
@ -40,8 +39,7 @@ export const appRoutes: Route[] = [
// Auth routes for authenticated users // Auth routes for authenticated users
{ {
path: '', path: '',
canActivate: [AuthGuard], canMatch: [AuthGuard],
canActivateChild: [AuthGuard],
component: LayoutComponent, component: LayoutComponent,
data: { data: {
layout: 'empty' layout: 'empty'
@ -55,25 +53,24 @@ export const appRoutes: Route[] = [
// Landing routes // Landing routes
{ {
path: '', path: '',
component : LayoutComponent, component: LayoutComponent,
data: { data: {
layout: 'empty' layout: 'empty'
}, },
children : [ children: [
{path: 'home', loadChildren: () => import('app/modules/landing/home/home.module').then(m => m.LandingHomeModule)}, {path: 'home', loadChildren: () => import('app/modules/landing/home/home.module').then(m => m.LandingHomeModule)},
] ]
}, },
// Admin routes // Admin routes
{ {
path : '', path: '',
canActivate: [AuthGuard], canMatch: [AuthGuard],
canActivateChild: [AuthGuard], component: LayoutComponent,
component : LayoutComponent, resolve: {
resolve : {
initialData: InitialDataResolver, initialData: InitialDataResolver,
}, },
children : [ children: [
// Dashboards // Dashboards
{path: 'dashboards', children: [ {path: 'dashboards', children: [

View File

@ -1,12 +1,12 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router'; import { CanMatch, Route, Router, UrlSegment, UrlTree } from '@angular/router';
import { Observable, of, switchMap } from 'rxjs'; import { Observable, of, switchMap } from 'rxjs';
import { AuthService } from 'app/core/auth/auth.service'; import { AuthService } from 'app/core/auth/auth.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad export class AuthGuard implements CanMatch
{ {
/** /**
* Constructor * Constructor
@ -23,38 +23,14 @@ export class AuthGuard implements CanActivate, CanActivateChild, CanLoad
// ----------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------
/** /**
* Can activate * Can match
*
* @param route
* @param state
*/
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
const redirectUrl = state.url === '/sign-out' ? '/' : state.url;
return this._check(redirectUrl);
}
/**
* Can activate child
*
* @param childRoute
* @param state
*/
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
{
const redirectUrl = state.url === '/sign-out' ? '/' : state.url;
return this._check(redirectUrl);
}
/**
* Can load
* *
* @param route * @param route
* @param segments * @param segments
*/ */
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean canMatch(route: Route, segments: UrlSegment[]): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
{ {
return this._check('/'); return this._check(segments);
} }
// ----------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------
@ -64,29 +40,28 @@ export class AuthGuard implements CanActivate, CanActivateChild, CanLoad
/** /**
* Check the authenticated status * Check the authenticated status
* *
* @param redirectURL * @param segments
* @private * @private
*/ */
private _check(redirectURL: string): Observable<boolean> private _check(segments: UrlSegment[]): Observable<boolean | UrlTree>
{ {
// Check the authentication status // Check the authentication status
return this._authService.check() return this._authService.check().pipe(
.pipe( switchMap((authenticated) => {
switchMap((authenticated) => {
// If the user is not authenticated... // If the user is not authenticated...
if ( !authenticated ) if ( !authenticated )
{ {
// Redirect to the sign-in page // Redirect to the sign-in page with a redirectUrl param
this._router.navigate(['sign-in'], {queryParams: {redirectURL}}); const redirectURL = `/${segments.join('/')}`;
const urlTree = this._router.parseUrl(`sign-in?redirectURL=${redirectURL}`);
// Prevent the access return of(urlTree);
return of(false); }
}
// Allow the access // Allow the access
return of(true); return of(true);
}) })
); );
} }
} }

View File

@ -1,12 +1,12 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router'; import { CanMatch, Route, Router, UrlSegment, UrlTree } from '@angular/router';
import { Observable, of, switchMap } from 'rxjs'; import { Observable, of, switchMap } from 'rxjs';
import { AuthService } from 'app/core/auth/auth.service'; import { AuthService } from 'app/core/auth/auth.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class NoAuthGuard implements CanActivate, CanActivateChild, CanLoad export class NoAuthGuard implements CanMatch
{ {
/** /**
* Constructor * Constructor
@ -23,34 +23,12 @@ export class NoAuthGuard implements CanActivate, CanActivateChild, CanLoad
// ----------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------
/** /**
* Can activate * Can match
*
* @param route
* @param state
*/
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
return this._check();
}
/**
* Can activate child
*
* @param childRoute
* @param state
*/
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
{
return this._check();
}
/**
* Can load
* *
* @param route * @param route
* @param segments * @param segments
*/ */
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean canMatch(route: Route, segments: UrlSegment[]): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
{ {
return this._check(); return this._check();
} }
@ -66,24 +44,10 @@ export class NoAuthGuard implements CanActivate, CanActivateChild, CanLoad
*/ */
private _check(): Observable<boolean> private _check(): Observable<boolean>
{ {
// Check the authentication status // Check the authentication status and return an observable of
return this._authService.check() // "true" or "false" to allow or prevent the access
.pipe( return this._authService.check().pipe(
switchMap((authenticated) => { switchMap((authenticated) => of(!authenticated))
);
// If the user is authenticated...
if ( authenticated )
{
// Redirect to the root
this._router.navigate(['']);
// Prevent the access
return of(false);
}
// Allow the access
return of(true);
})
);
} }
} }