diff --git a/src/app/auth/confirm-login/confirm-login.component.ts b/src/app/auth/confirm-login/confirm-login.component.ts index e292672a2..ad8f5d558 100644 --- a/src/app/auth/confirm-login/confirm-login.component.ts +++ b/src/app/auth/confirm-login/confirm-login.component.ts @@ -44,8 +44,8 @@ export class ConfirmLoginComponent implements OnInit { */ handleAuthSuccess() { this.authService.setTitleWithPhaseDetail(); - this.router.navigateByUrl(this.phaseService.currentPhase); this.authService.changeAuthState(AuthState.Authenticated); + this.authService.navigateToLandingPage(); } /** diff --git a/src/app/core/guards/auth.guard.ts b/src/app/core/guards/auth.guard.ts index def276425..2fadddd46 100644 --- a/src/app/core/guards/auth.guard.ts +++ b/src/app/core/guards/auth.guard.ts @@ -11,8 +11,10 @@ export class AuthGuard implements CanActivate, CanLoad { canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean { if (this.auth.isAuthenticated()) { + this.auth.clearNext(); return true; } else { + this.auth.storeNext(state); this.router.navigate(['']); return false; } diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts index cf8a9cb68..7dba57036 100644 --- a/src/app/core/services/auth.service.ts +++ b/src/app/core/services/auth.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { NgZone } from '@angular/core'; import { Title } from '@angular/platform-browser'; -import { Router } from '@angular/router'; +import { Router, RouterStateSnapshot } from '@angular/router'; import { BehaviorSubject } from 'rxjs'; import { AppConfig } from '../../../environments/environment'; import { generateSessionId } from '../../shared/lib/session'; @@ -30,6 +30,8 @@ export enum AuthState { * updating the application state with regards to authentication. */ export class AuthService { + private static readonly SESSION_NEXT_KEY = 'next'; + authStateSource = new BehaviorSubject(AuthState.NotAuthenticated); currentAuthState = this.authStateSource.asObservable(); accessToken = new BehaviorSubject(undefined); @@ -50,6 +52,27 @@ export class AuthService { private logger: LoggingService ) {} + /** + * Stores the data about the next route in the session storage. + */ + storeNext(next: RouterStateSnapshot) { + sessionStorage.setItem(AuthService.SESSION_NEXT_KEY, next.url); + } + + /** + * Returns the next route + */ + private getNext(): string { + return sessionStorage.getItem(AuthService.SESSION_NEXT_KEY); + } + + /** + * Clears the next route from the session storage. + */ + clearNext() { + sessionStorage.removeItem(AuthService.SESSION_NEXT_KEY); + } + /** * Will store the OAuth token. */ @@ -144,4 +167,16 @@ export class AuthService { } window.location.href = url; } + + /** + * Navigates to next if there is, or default landing page. + */ + navigateToLandingPage() { + const nextRoute = this.getNext(); + if (!nextRoute || !this.phaseService.isValidRoute(nextRoute)) { + this.router.navigateByUrl(this.phaseService.currentPhase); + } else { + this.router.navigateByUrl(nextRoute); + } + } } diff --git a/src/app/core/services/phase.service.ts b/src/app/core/services/phase.service.ts index ada3c9bb4..3e5d8b221 100644 --- a/src/app/core/services/phase.service.ts +++ b/src/app/core/services/phase.service.ts @@ -161,6 +161,13 @@ export class PhaseService { return this.orgName.concat('/').concat(this.repoName); } + /** + * Checks whether the given route is allowed in this phase. + */ + isValidRoute(route: string): boolean { + return route.startsWith('/' + this.currentPhase); + } + reset() { this.currentPhase = null; } diff --git a/src/app/shared/view-issue/view-issue.component.ts b/src/app/shared/view-issue/view-issue.component.ts index 34b24e93d..f36b67260 100644 --- a/src/app/shared/view-issue/view-issue.component.ts +++ b/src/app/shared/view-issue/view-issue.component.ts @@ -1,4 +1,5 @@ import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; +import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; import { Issue } from '../../core/models/issue.model'; import { UserRole } from '../../core/models/user.model'; @@ -53,7 +54,8 @@ export class ViewIssueComponent implements OnInit, OnDestroy, OnChanges { public permissions: PermissionService, public userService: UserService, public issueService: IssueService, - private phaseService: PhaseService + private phaseService: PhaseService, + private router: Router ) {} ngOnInit() { @@ -126,7 +128,11 @@ export class ViewIssueComponent implements OnInit, OnDestroy, OnChanges { this.issue = issue; this.pollIssue(id); }, - (err) => this.errorHandlingService.handleError(err) + (err) => { + this.router.navigateByUrl(this.phaseService.currentPhase).then(() => { + this.errorHandlingService.handleError(new Error('Invalid URL provided!')); + }); + } ); }