diff --git a/projects/ngx-security/src/lib/guards/ngx-security.guard.ts b/projects/ngx-security/src/lib/guards/ngx-security.guard.ts index 8fd6536..753167e 100644 --- a/projects/ngx-security/src/lib/guards/ngx-security.guard.ts +++ b/projects/ngx-security/src/lib/guards/ngx-security.guard.ts @@ -6,50 +6,56 @@ import { CanLoad, Route, Router, - RouterStateSnapshot + RouterStateSnapshot, UrlTree } from '@angular/router'; import {NgxSecurityService} from '../services/ngx-security.service'; -import {NgxSecurityGuardOptions} from '../models/ngx-security.model'; -import {merge, Observable, of} from 'rxjs'; -import {every, map, take, tap} from 'rxjs/operators'; +import {CurrentRoute, NgxSecurityGuardOptions, RouteUrl} from '../models/ngx-security.model'; +import {merge, Observable} from 'rxjs'; +import {every, map, take} from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) -export class NgxSecurityGuard implements CanLoad, CanActivate, CanActivateChild -{ +export class NgxSecurityGuard implements CanLoad, CanActivate, CanActivateChild { constructor( protected readonly security: NgxSecurityService, protected readonly router: Router ) {} + canLoad(route: Route): Observable { return this.canAccess(route); } + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return this.canAccess(route, state); } + canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return this.canAccess(route, state); } - canLoad(route: Route): Observable { return this.canAccess(route); } - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return this.canAccess(route, state); } - canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return this.canAccess(route, state); } - - - protected canAccess(route: Route | ActivatedRouteSnapshot, state?: RouterStateSnapshot): Observable { + canAccess(route: CurrentRoute, state?: RouteUrl): Observable { const guardOptions = !!route && route.data ? route.data['security'] as NgxSecurityGuardOptions : {}; + return this.handle(guardOptions, route, state); + } + + handle(guardOptions: NgxSecurityGuardOptions, route?: CurrentRoute, state?: RouteUrl): Observable { return this.checkAccess(guardOptions).pipe( - tap(access => { + map(access => { + let returnValue: boolean | UrlTree = access; + if (!access) { if (guardOptions.unauthorizedHandler) { guardOptions.unauthorizedHandler(route, state); } - if (guardOptions.redirectTo) - this.router.navigateByUrl(guardOptions.redirectTo); + if (guardOptions.redirectTo) { + returnValue = this.router.parseUrl(guardOptions.redirectTo); + } } else { if (guardOptions.authorizedHandler) { guardOptions.authorizedHandler(route, state); } } + + return returnValue; }) ); } - private checkAccess(guardOptions: NgxSecurityGuardOptions): Observable { + protected checkAccess(guardOptions: NgxSecurityGuardOptions): Observable { let allObs$: Observable[] = []; if (guardOptions.isAuthenticated === true) { diff --git a/projects/ngx-security/src/lib/models/ngx-security.model.ts b/projects/ngx-security/src/lib/models/ngx-security.model.ts index 202b413..dcfc096 100644 --- a/projects/ngx-security/src/lib/models/ngx-security.model.ts +++ b/projects/ngx-security/src/lib/models/ngx-security.model.ts @@ -1,6 +1,9 @@ -import { ActivatedRouteSnapshot, Route, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, Route, RouterStateSnapshot, UrlSegment } from '@angular/router'; import { Observable } from 'rxjs'; +export type CurrentRoute = Route | ActivatedRouteSnapshot; +export type RouteUrl = RouterStateSnapshot | UrlSegment[]; + export interface NgxSecurityState { authenticationChecker: () => Observable; rolesChecker: (name: string) => Observable; @@ -25,6 +28,6 @@ export interface NgxSecurityGuardOptions { hasNotPermissions?: string | string[]; redirectTo?: string; - authorizedHandler?: (route: Route | ActivatedRouteSnapshot, state?: RouterStateSnapshot) => void; - unauthorizedHandler?: (route: Route | ActivatedRouteSnapshot, state?: RouterStateSnapshot) => void; + authorizedHandler?: (route?: CurrentRoute, state?: RouteUrl) => void; + unauthorizedHandler?: (route?: CurrentRoute, state?: RouteUrl) => void; }