diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 1069d2a..7e65103 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -8,7 +8,7 @@ import { SmesComponent } from './components/smes/smes.component'; import { UserModule } from './components/user/user.module'; import { SignInComponent } from './components/sign-in/sign-in.component'; import { SmesDashboardComponent } from './components/smes-dashboard/smes-dashboard.component'; - +import { AuthGuardService as AuthGuard } from './services/auth-guard.service'; const routes: Routes = [ { @@ -17,7 +17,8 @@ const routes: Routes = [ }, { path: 'smes-dashboard', - component: SmesDashboardComponent + component: SmesDashboardComponent, + canActivate: [AuthGuard] }, { path: 'user', loadChildren: () => UserModule }, { @@ -29,7 +30,8 @@ const routes: Routes = [ { path: 'Smes', component: SmesComponent}, ] }, - { path: 'sign-in', component: SignInComponent} + { path: 'sign-in', component: SignInComponent}, + { path: '**', redirectTo: '/' } ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 21ee63b..ec994a6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,3 +1,4 @@ +import { TokenInterceptor, ErrorInterceptor } from './services/token.interceptor'; import { SideNavService } from './shared/services/side-nav.service'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; @@ -23,7 +24,7 @@ import { AuthService } from './services/auth.service'; import { authReducers } from './store/state/user.state'; import { EffectsModule } from '@ngrx/effects'; import { AuthEffects } from './store/effects/auth.effects'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { environment } from '../environments/environment'; import { SideNavTogglerComponent } from './shared/components/side-nav-toggler/side-nav-toggler.component'; @@ -64,7 +65,19 @@ import { SideNavComponent } from './shared/components/side-nav/side-nav.componen StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: environment.production }), ], - providers: [AuthService, SideNavService], + providers: [ + AuthService, SideNavService, + { + provide: HTTP_INTERCEPTORS, + useClass: TokenInterceptor, + multi: true + }, + { + provide: HTTP_INTERCEPTORS, + useClass: ErrorInterceptor, + multi: true + } + ], bootstrap: [AppComponent] }) diff --git a/src/app/components/home-page/home-page.component.html b/src/app/components/home-page/home-page.component.html index cb188f0..6a74a6b 100644 --- a/src/app/components/home-page/home-page.component.html +++ b/src/app/components/home-page/home-page.component.html @@ -1,35 +1,35 @@
- +
+
+ U Business + Connecting Businesses to Opportunity
+ +
diff --git a/src/app/components/smes-dashboard/smes-dashboard.component.ts b/src/app/components/smes-dashboard/smes-dashboard.component.ts index bc85e0b..f420b1d 100644 --- a/src/app/components/smes-dashboard/smes-dashboard.component.ts +++ b/src/app/components/smes-dashboard/smes-dashboard.component.ts @@ -1,3 +1,4 @@ +import { Router } from '@angular/router'; import { selectAuthState } from './../../store/state/user.state'; import { Observable } from 'rxjs'; import { Component, OnInit } from '@angular/core'; @@ -17,7 +18,7 @@ export class SmesDashboardComponent implements OnInit { user = null; errorMessage = null; - constructor(private store: Store) { + constructor(private store: Store, public router: Router) { this.getState = this.store.select(selectAuthState); } @@ -31,6 +32,7 @@ export class SmesDashboardComponent implements OnInit { logout(): void { this.store.dispatch(new Logout()); + this.router.navigateByUrl('/'); } } diff --git a/src/app/services/auth-guard.service.spec.ts b/src/app/services/auth-guard.service.spec.ts new file mode 100644 index 0000000..35afd37 --- /dev/null +++ b/src/app/services/auth-guard.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthGuardService } from './auth-guard.service'; + +describe('AuthGuardService', () => { + let service: AuthGuardService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthGuardService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/auth-guard.service.ts b/src/app/services/auth-guard.service.ts new file mode 100644 index 0000000..45d2138 --- /dev/null +++ b/src/app/services/auth-guard.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import { Router, CanActivate } from '@angular/router'; +import { AuthService } from './auth.service'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthGuardService implements CanActivate{ + + constructor( + public auth: AuthService, + public router: Router + ) { } + + canActivate(): boolean { + if (!this.auth.getToken()) { + this.router.navigateByUrl('/sign-in'); + return false; + } + return true; + } +} diff --git a/src/app/services/token.interceptor.ts b/src/app/services/token.interceptor.ts new file mode 100644 index 0000000..a3094f3 --- /dev/null +++ b/src/app/services/token.interceptor.ts @@ -0,0 +1,39 @@ +import { catchError } from 'rxjs/operators'; +import { Injectable, Injector } from '@angular/core'; +import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { Observable, throwError } from 'rxjs'; +import { AuthService } from './auth.service'; + +@Injectable() +export class TokenInterceptor implements HttpInterceptor { + private authService: AuthService; + + constructor(private injector: Injector) { } + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + this.authService = this.injector.get(AuthService); + const token = this.authService.getToken(); + request = request.clone({ + setHeaders: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + } + }); + return next.handle(request); + } +} + +@Injectable() +export class ErrorInterceptor implements HttpInterceptor { + constructor(private router: Router) {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + return next.handle(request).pipe( + catchError(response => { + if (response instanceof HttpErrorResponse && response.status === 401) {} + return throwError(response); + }) + ); + } +} diff --git a/src/app/shared/components/navbar/navbar.component.ts b/src/app/shared/components/navbar/navbar.component.ts index 9d4a88b..58f4a90 100644 --- a/src/app/shared/components/navbar/navbar.component.ts +++ b/src/app/shared/components/navbar/navbar.component.ts @@ -1,3 +1,4 @@ +import { Router } from '@angular/router'; import { Component, OnInit } from '@angular/core'; import { Logout } from './../../../store/actions/auth.actions'; import { selectAuthState, UserState } from './../../../store/state/user.state'; @@ -17,7 +18,7 @@ export class NavbarComponent implements OnInit { user = null; errorMessage = null; - constructor(private store: Store) { + constructor(private store: Store, public router: Router) { this.getState = this.store.select(selectAuthState); } @@ -31,6 +32,7 @@ export class NavbarComponent implements OnInit { logout(): void { this.store.dispatch(new Logout()); + this.router.navigateByUrl('/'); } }