diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b76e0978634303877a4385b093083ef3ac650593..65a8b8ed332afaf11163b9d605d78298421eb768 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -64,6 +64,7 @@ import { CreatorHomeScreenComponent } from './creator-home-screen/creator-home-s import { CreateCommentComponent } from './create-comment/create-comment.component'; import { CommentService } from './comment.service'; import { ParticipantHomeScreenComponent } from './participant-home-screen/participant-home-screen.component'; +import { DataStoreService } from './data-store.service'; @NgModule({ declarations: [ @@ -138,6 +139,7 @@ import { ParticipantHomeScreenComponent } from './participant-home-screen/partic NotificationService, AuthenticationService, AuthenticationGuard, + DataStoreService, RoomService, CommentService ], diff --git a/src/app/authentication.guard.ts b/src/app/authentication.guard.ts index 3883037a46bfe57fd992fdba30d81389f61c636e..cec297d1bb377e163c193e08af9f23227feccee4 100644 --- a/src/app/authentication.guard.ts +++ b/src/app/authentication.guard.ts @@ -7,6 +7,7 @@ import 'rxjs/add/observable/of'; import 'rxjs/add/operator/catch'; import { NotificationService } from './notification.service'; import { UserRole } from './user-roles.enum'; +import { User } from './user'; @Injectable() export class AuthenticationGuard implements CanActivate { @@ -16,21 +17,22 @@ export class AuthenticationGuard implements CanActivate { } canActivate(next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> { - return this.authenticationService.getUser().map(user => { - // Get roles having access to this route - // undefined if every logged in user should have access regardless of its role - const requiredRoles = next.data['roles'] as Array<UserRole>; - // Allow access when user is logged in AND - // the route doesn't require a specific role OR - // the user's role is one of the required roles - if (user && (!requiredRoles || requiredRoles.includes(user.role))) { - return true; - } - this.notificationService.show(`You're not authorized to view this page.`); - // TODO: redirect to error page - this.router.navigate(['/']); - return false; - }); + state: RouterStateSnapshot): boolean { + // Get active user + const user: User = this.authenticationService.getUser(); + // Get roles having access to this route + // undefined if every logged in user should have access regardless of its role + const requiredRoles = next.data['roles'] as Array<UserRole>; + // Allow access when user is logged in AND + // the route doesn't require a specific role OR + // the user's role is one of the required roles + if (user && (!requiredRoles || requiredRoles.includes(user.role))) { + return true; + } + + this.notificationService.show(`You're not authorized to view this page.`); + // TODO: redirect to error page + this.router.navigate(['/']); + return false; } } diff --git a/src/app/authentication.service.ts b/src/app/authentication.service.ts index 7f5349c3d8550d1b5f9cf516763c1af02eafc0ff..b04d62359d9a76595424c7b1f42da931d741b6df 100644 --- a/src/app/authentication.service.ts +++ b/src/app/authentication.service.ts @@ -3,17 +3,27 @@ import { User } from './user'; import { Observable } from 'rxjs/Observable'; import { of } from 'rxjs/observable/of'; import { UserRole } from './user-roles.enum'; +import { DataStoreService } from './data-store.service'; // TODO: connect to API // TODO: persist user data (shouldn't get lost on page refresh) @Injectable() export class AuthenticationService { - private mockUser: User; - - constructor() { } + private readonly STORAGE_KEY: string = 'USER'; + private user: User; + + constructor(private dataStoreService: DataStoreService) { + if (dataStoreService.has(this.STORAGE_KEY)) { + // Load user data from local data store if available + this.user = JSON.parse(dataStoreService.get(this.STORAGE_KEY)); + } + } login(email: string, password: string, role: UserRole): Observable<boolean> { - this.mockUser = new User(1, '', email, role); + this.user = new User(1, '', email, role, 'TOKEN'); + // Store user data in local storage to retain the data when the user reloads the page + this.dataStoreService.set(this.STORAGE_KEY, JSON.stringify(this.user)); + return of(true); } @@ -26,19 +36,21 @@ export class AuthenticationService { } logout() { - this.mockUser = null; + // Destroy the persisted user data + this.dataStoreService.remove(this.STORAGE_KEY); + this.user = undefined; } - getUser(): Observable<User> { - return of(this.mockUser); + getUser(): User { + return this.user; } - isLoggedIn(): Observable<boolean> { - return of(this.mockUser !== undefined); + isLoggedIn(): boolean { + return this.user !== undefined; } - getRole(): Observable<UserRole> { - return of(this.mockUser.role); + getRole(): UserRole { + return this.isLoggedIn() ? this.user.role : undefined; } } diff --git a/src/app/data-store.service.spec.ts b/src/app/data-store.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ae81c319f688bdb0f4d62e026bf846feb5dd4f7 --- /dev/null +++ b/src/app/data-store.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { DataStoreService } from './data-store.service'; + +describe('DataStoreService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DataStoreService] + }); + }); + + it('should be created', inject([DataStoreService], (service: DataStoreService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/data-store.service.ts b/src/app/data-store.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..d35260090818bbe94ce993a81a18e9f774c49afd --- /dev/null +++ b/src/app/data-store.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; + +/** + * Service for storing local user data. + * Use this service to allow switching between localStorage, cookies, .. easily. + */ +@Injectable() +export class DataStoreService { + has(key: string): boolean { + return key in localStorage; + } + + get(key: string): string { + return localStorage.getItem(key); + } + + set(key: string, data: string) { + localStorage.setItem(key, data); + } + + remove(key: string) { + localStorage.removeItem(key); + } +} diff --git a/src/app/user.ts b/src/app/user.ts index e9d2a88612425cdf57eb5b6b0c43f42b40a7adc1..99ed66b0aa3147d13824cb0862574d23d58168f6 100644 --- a/src/app/user.ts +++ b/src/app/user.ts @@ -5,11 +5,13 @@ export class User { name: string; email: string; role: UserRole; + token: string; - constructor(id: number, name: string, email: string, role: UserRole) { + constructor(id: number, name: string, email: string, role: UserRole, token: string) { this.id = id; this.name = name; this.email = email; this.role = role; + this.token = token; } }