feat(security): cross cutting security features
exposed class interfaces for auth and token services
Showing
exposed class interfaces for auth and token services
import { TestBed } from '@angular/core/testing'; | |||
import { Router } from '@angular/router'; | |||
import { Mock } from 'ts-mocks'; | |||
import { AlreadyLoggedInGuard } from './already-logged-in.guard'; | |||
import { AuthService } from './auth.service'; | |||
describe('AlreadyLoggedInGuard', () => { | |||
let guard: AlreadyLoggedInGuard; | |||
let router: Mock<Router>; | |||
let authService: Mock<AuthService>; | |||
let isLoggedIn: boolean; | |||
let result: boolean; | |||
let complete: boolean; | |||
let loadResult: boolean; | |||
let loadComplete: boolean; | |||
const snapshot = { | |||
data: { | |||
targetRoute: ['test', 'route'], | |||
queryParams: { | |||
a: 'b' | |||
} | |||
} | |||
}; | |||
beforeEach(() => { | |||
result = complete = undefined; | |||
Please
register
or
sign in
to reply
|
|||
loadResult = loadComplete = undefined; | |||
|
|||
isLoggedIn = undefined; | |||
router = new Mock<Router>({ | |||
navigate: () => ({} as any) | |||
}); | |||
authService = new Mock<AuthService>({ | |||
isLoggedIn: () => isLoggedIn | |||
}); | |||
TestBed.configureTestingModule({ | |||
providers: [ | |||
{ provide: Router, useValue: router.Object }, | |||
{ provide: AuthService, useValue: authService.Object }, | |||
AlreadyLoggedInGuard | |||
] | |||
}); | |||
guard = TestBed.get(AlreadyLoggedInGuard); | |||
}); | |||
describe('when not logged in', () => { | |||
beforeEach(() => { | |||
isLoggedIn = false; | |||
}); | |||
it('should emit true and not redirect', () => { | |||
expect(guard.canActivate(snapshot as any)).toBe(true); | |||
expect(guard.canLoad({ data: { targetRoute: ['lazy'] } })).toBe(true); | |||
expect(router.Object.navigate).not.toHaveBeenCalled(); | |||
}); | |||
}); | |||
describe('when logged in', () => { | |||
beforeEach(() => { | |||
isLoggedIn = true; | |||
}); | |||
it('should emit false and redirect to dashboard', () => { | |||
expect(guard.canActivate(snapshot as any)).toBe(false); | |||
expect(guard.canLoad({ data: { targetRoute: ['lazy'] } })).toBe(false); | |||
expect(router.Object.navigate).toHaveBeenCalledWith(['test', 'route'], { | |||
queryParams: { a: 'b' } | |||
}); | |||
expect(router.Object.navigate).toHaveBeenCalledWith(['lazy'], { | |||
queryParams: {} | |||
}); | |||
}); | |||
}); | |||
}); |
import { Injectable } from '@angular/core'; | |||
import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router } from '@angular/router'; | |||
import { Observable, of } from 'rxjs'; | |||
|
|||
import { map, take, tap } from 'rxjs/operators'; | |||
|
|||
import { AuthService } from './auth.service'; | |||
@Injectable({ | |||
providedIn: 'root' | |||
}) | |||
export class AlreadyLoggedInGuard implements CanActivate, CanLoad { | |||
constructor(private authService: AuthService, private router: Router) {} | |||
public canActivate(route: ActivatedRouteSnapshot): boolean { | |||
return this.isLoggedIn(route.data); | |||
} | |||
public canLoad(route: Route): boolean { | |||
return this.isLoggedIn(route.data); | |||
} | |||
private isLoggedIn(routeData: any): boolean { | |||
const loggedIn = !!this.authService.isLoggedIn(); | |||
if (loggedIn && routeData && routeData.targetRoute) { | |||
this.router.navigate(routeData.targetRoute, { | |||
queryParams: routeData.queryParams || {} | |||
}); | |||
} | |||
return !loggedIn; | |||
} | |||
} |