Skip to content

Commit

Permalink
[DNCR-107] Improve homepage guarding and redirection
Browse files Browse the repository at this point in the history
This commit also contains some minor changes to how being logged in is checked.
  • Loading branch information
megawebmaster committed Oct 26, 2016
1 parent c868381 commit ed396c7
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 41 deletions.
8 changes: 5 additions & 3 deletions frontend/src/app/_commons/auth/auth-guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {
constructor(private router: Router) {
}

canActivate(): Observable<boolean> {
let isLoggedIn = this.authService.isLoggedIn();
let isLoggedIn = AuthService.isLoggedIn();

if (!isLoggedIn){
// TODO: Add "login required" message ;)
this.router.navigate(['/']);
if (this.router.url !== '/') {
this.router.navigate(['/']);
}
}

return Observable.of(isLoggedIn);
Expand Down
46 changes: 21 additions & 25 deletions frontend/src/app/_commons/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { CookieService } from 'angular2-cookie/core';
import { Response } from '@angular/http';
import { Router } from '@angular/router';
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';
import { Observable } from 'rxjs/Observable';
import * as moment from 'moment';
Expand All @@ -12,16 +11,16 @@ import { AuthHttp } from './http';
@Injectable()
export class AuthService {
private static TOKEN = 'id_token';
private static refreshTimeout: any;
public KNOWN_USER = 'known_user';
private static KNOWN_USER = 'known_user';
private static refreshTimeoutId: any;

public static clear() {
clearTimeout(AuthService.refreshTimeout);
localStorage.removeItem(AuthService.TOKEN);
constructor(private cookies: CookieService, private http: AuthHttp) {
this.scheduleTokenRefreshing();
}

constructor(private cookies: CookieService, private http: AuthHttp, private router: Router) {
this.scheduleTokenRefreshing();
public static clear() {
clearTimeout(AuthService.refreshTimeoutId);
localStorage.removeItem(AuthService.TOKEN);
}

public login(model: LoginModel): Observable<Response> {
Expand All @@ -34,45 +33,42 @@ export class AuthService {
.do(() => AuthService.clear());
}

public isLoggedIn(): boolean {
public static isLoggedIn(): boolean {
try {
if (!tokenNotExpired()){
if (this.router.url !== '/') {
this.router.navigate(['/']);
}
return false;
}

return true;
return tokenNotExpired();
} catch (e) {
return false;
}
}

public isKnownUser(): boolean {
return this.cookies.get(this.KNOWN_USER) === 'true';
return this.cookies.get(AuthService.KNOWN_USER) === 'true';
}

private saveToken(response: Response) {
localStorage.setItem(AuthService.TOKEN, response.json().token);
this.cookies.put(this.KNOWN_USER, 'true');
this.cookies.put(AuthService.KNOWN_USER, 'true');
this.scheduleTokenRefreshing();
}

private scheduleTokenRefreshing() {
if (!this.isLoggedIn()) {
if (!AuthService.isLoggedIn()) {
AuthService.clear();
return;
}

let helper = new JwtHelper();
let token = localStorage.getItem(AuthService.TOKEN);
let expiry = helper.decodeToken(token).exp * 1000;
let now = moment().valueOf();
let timeout = expiry - now - 60000; // Subtract 1 minute to be sure token is still valid
let timeout = AuthService.getTokenTimeout(token);

AuthService.refreshTimeout = setTimeout(
AuthService.refreshTimeoutId = setTimeout(
() => this.http.post('/api/refresh-token', {}).subscribe((response) => this.saveToken(response)), timeout
);
}

private static getTokenTimeout(token: string): number {
let expiry = moment(new JwtHelper().getTokenExpirationDate(token));
let now = moment();
// Subtract 1 minute to be sure token is still valid
return moment.duration(expiry.diff(now)).subtract(1, 'minute').asMilliseconds();
}
}
6 changes: 3 additions & 3 deletions frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export class App {
constructor(private router: Router, private authService: AuthService) {
}

logout() {
public logout() {
this.authService.logout().subscribe(() => {
this.router.navigate(['/']);
});
}

isLoggedIn() {
return this.authService.isLoggedIn();
public isLoggedIn() {
return AuthService.isLoggedIn();
}
}
4 changes: 2 additions & 2 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { CommonsModule } from './_commons/commons.module';
import { App } from './app.component';
import { APP_RESOLVER_PROVIDERS } from './app.resolver';
import { NoContent } from './no-content';
import { Homepage } from './homepage/homepage.component';
import { Homepage, HomepageGuard } from './homepage';

// Application wide providers
const APP_PROVIDERS = [
...APP_RESOLVER_PROVIDERS, CookieService, ...AUTH_PROVIDERS, {
...APP_RESOLVER_PROVIDERS, CookieService, HomepageGuard, ...AUTH_PROVIDERS, {
provide: XSRFStrategy,
useValue: new CookieXSRFStrategy('XSRF-TOKEN', 'X-XSRF-TOKEN')
}
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Routes } from '@angular/router';
import { NoContent } from './no-content';
import { Homepage } from './homepage/homepage.component';
import { AuthGuard } from 'app/_commons/auth';
import { NoContent } from './no-content';
import { Homepage, HomepageGuard } from './homepage';

export const ROUTES: Routes = [
{
path: '',
component: Homepage
pathMatch: 'full',
component: Homepage,
canActivate: [HomepageGuard]
},
{
path: 'reception',
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/app/homepage/homepage-guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from 'app/_commons/auth';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class HomepageGuard implements CanActivate {
constructor(private router: Router) {
}

canActivate(): Observable<boolean> {
let isLoggedIn = AuthService.isLoggedIn();

if (isLoggedIn){
this.router.navigate(['/reception']);
}

return Observable.of(!isLoggedIn);
}
}
3 changes: 0 additions & 3 deletions frontend/src/app/homepage/homepage.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,5 @@ export class Homepage {

ngOnInit() {
this.isLoginVisible = this.service.isKnownUser();
if (this.service.isLoggedIn()) {
this.router.navigate(['reception']);
}
}
}
1 change: 1 addition & 0 deletions frontend/src/app/homepage/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './homepage.component';
export * from './homepage-guard';
2 changes: 1 addition & 1 deletion frontend/src/app/homepage/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class LoginComponent {
if (response.hasOwnProperty('error')) {
this.error = response.error;
} else {
this.error = 'Nieprawidłowy login lub hasło.';
this.error = 'Nieoczekiwany błąd serwera.';
}
}
);
Expand Down
1 change: 0 additions & 1 deletion frontend/tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
Expand Down

0 comments on commit ed396c7

Please sign in to comment.