From fa8b88e8a0ba7c839ce48eb0b82c037d096017c0 Mon Sep 17 00:00:00 2001 From: Rene Enriquez Date: Mon, 20 Apr 2020 17:37:35 -0500 Subject: [PATCH] fix: #148 adding interceptor to inject Authorization headers --- src/app/app.module.ts | 9 +++- .../inject.token.interceptor.spec.ts | 46 +++++++++++++++++++ .../interceptors/inject.token.interceptor.ts | 31 +++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/app/modules/shared/interceptors/inject.token.interceptor.spec.ts create mode 100644 src/app/modules/shared/interceptors/inject.token.interceptor.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 52561e721..a82fd3e09 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,7 +2,7 @@ import { CommonModule } from '@angular/common'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; @@ -50,6 +50,7 @@ import { ProjectTypeListComponent } from './modules/customer-management/componen // tslint:disable-next-line: max-line-length import { CreateProjectTypeComponent } from './modules/customer-management/components/projects-type/components/create-project-type/create-project-type.component'; import { CustomerEffects } from './modules/customer-management/store/customer-management.effects'; +import { InjectTokenInterceptor } from './modules/shared/interceptors/inject.token.interceptor'; @NgModule({ declarations: [ @@ -103,7 +104,11 @@ import { CustomerEffects } from './modules/customer-management/store/customer-ma : [], EffectsModule.forRoot([ProjectEffects, ActivityEffects, CustomerEffects, TechnologyEffects]), ], - providers: [], + providers: [{ + provide: HTTP_INTERCEPTORS, + useClass: InjectTokenInterceptor, + multi: true, + }], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/src/app/modules/shared/interceptors/inject.token.interceptor.spec.ts b/src/app/modules/shared/interceptors/inject.token.interceptor.spec.ts new file mode 100644 index 000000000..79a702c28 --- /dev/null +++ b/src/app/modules/shared/interceptors/inject.token.interceptor.spec.ts @@ -0,0 +1,46 @@ +import { HttpHandler, HttpRequest, HttpResponse, HttpEvent } from '@angular/common/http'; +import { Observable, of } from 'rxjs'; + +import { AzureAdB2CService } from 'src/app/modules/login/services/azure.ad.b2c.service'; +import { environment } from '../../../../environments/environment'; +import { InjectTokenInterceptor } from './inject.token.interceptor'; + +describe('InjectTokenInterceptor test', () => { + + class MockHttpHandler extends HttpHandler { + handle(req: HttpRequest): Observable> { + return of(new HttpResponse()); + } + } + + const azureAdB2CService: AzureAdB2CService = new AzureAdB2CService(); + azureAdB2CService.getBearerToken = () => { + return 'XYZ'; + }; + const handler: HttpHandler = new MockHttpHandler(); + + it('if request.url is not part of time-tracker-api, then next.handle', () => { + const interceptor = new InjectTokenInterceptor(azureAdB2CService); + const request = new HttpRequest('GET', '/foo'); + spyOn(handler, 'handle'); + + interceptor.intercept(request, handler); + + expect(handler.handle).toHaveBeenCalledWith(request); + }); + + it('if request.url is part of time-tracker-api, then Authorization header is injected', () => { + const interceptor = new InjectTokenInterceptor(azureAdB2CService); + const request = new HttpRequest('GET', environment.timeTrackerApiUrl); + spyOn(handler, 'handle'); + const requestWithHeaders = request.clone( + { + headers: request.headers.set('Authorization', 'Bearer XYZ') + }); + + interceptor.intercept(request, handler); + + expect(handler.handle).toHaveBeenCalledWith(requestWithHeaders); + }); + +}); diff --git a/src/app/modules/shared/interceptors/inject.token.interceptor.ts b/src/app/modules/shared/interceptors/inject.token.interceptor.ts new file mode 100644 index 000000000..6cb943d87 --- /dev/null +++ b/src/app/modules/shared/interceptors/inject.token.interceptor.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { + HttpEvent, + HttpInterceptor, + HttpHandler, + HttpRequest, +} from '@angular/common/http'; +import { Observable } from 'rxjs'; + +import { AzureAdB2CService } from 'src/app/modules/login/services/azure.ad.b2c.service'; +import { environment } from './../../../../environments/environment'; + +@Injectable() +export class InjectTokenInterceptor implements HttpInterceptor { + + constructor(private azureAdB2CService: AzureAdB2CService) { } + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + if (request.url.startsWith(environment.timeTrackerApiUrl)) { + const requestWithHeaders = request.clone( + { + headers: request.headers.set('Authorization', + 'Bearer ' + this.azureAdB2CService.getBearerToken()) + }); + return next.handle(requestWithHeaders); + } else { + return next.handle(request); + } + } + +}