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; | ||
} | ||
} |