diff --git a/projects/angular-jwt/src/lib/angular-jwt.module.ts b/projects/angular-jwt/src/lib/angular-jwt.module.ts index a898b6da..d1476b6e 100644 --- a/projects/angular-jwt/src/lib/angular-jwt.module.ts +++ b/projects/angular-jwt/src/lib/angular-jwt.module.ts @@ -1,14 +1,21 @@ -import { NgModule, ModuleWithProviders, Optional, SkipSelf, Provider } from '@angular/core'; -import { HTTP_INTERCEPTORS } from '@angular/common/http'; -import {JwtInterceptor} from './jwt.interceptor'; -import {JWT_OPTIONS} from './jwtoptions.token'; -import {JwtHelperService} from './jwthelper.service'; - +import { + NgModule, + ModuleWithProviders, + Optional, + SkipSelf, + Provider, +} from "@angular/core"; +import { HttpRequest, HTTP_INTERCEPTORS } from "@angular/common/http"; +import { JwtInterceptor } from "./jwt.interceptor"; +import { JWT_OPTIONS } from "./jwtoptions.token"; +import { JwtHelperService } from "./jwthelper.service"; export interface JwtModuleOptions { jwtOptionsProvider?: Provider; config?: { - tokenGetter?: () => string | null | Promise; + tokenGetter?: ( + request?: HttpRequest + ) => string | null | Promise; headerName?: string; authScheme?: string; whitelistedDomains?: Array; @@ -20,10 +27,11 @@ export interface JwtModuleOptions { @NgModule() export class JwtModule { - constructor(@Optional() @SkipSelf() parentModule: JwtModule) { if (parentModule) { - throw new Error('JwtModule is already loaded. It should only be imported in your application\'s main module.'); + throw new Error( + "JwtModule is already loaded. It should only be imported in your application's main module." + ); } } static forRoot(options: JwtModuleOptions): ModuleWithProviders { @@ -33,15 +41,14 @@ export class JwtModule { { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, - multi: true + multi: true, }, - options.jwtOptionsProvider || - { + options.jwtOptionsProvider || { provide: JWT_OPTIONS, - useValue: options.config + useValue: options.config, }, - JwtHelperService - ] + JwtHelperService, + ], }; } } diff --git a/projects/angular-jwt/src/lib/jwt.interceptor.ts b/projects/angular-jwt/src/lib/jwt.interceptor.ts index 75ef38c3..15a7f6c1 100644 --- a/projects/angular-jwt/src/lib/jwt.interceptor.ts +++ b/projects/angular-jwt/src/lib/jwt.interceptor.ts @@ -14,7 +14,9 @@ import { from, Observable } from "rxjs"; @Injectable() export class JwtInterceptor implements HttpInterceptor { - tokenGetter: () => string | null | Promise; + tokenGetter: ( + request?: HttpRequest + ) => string | null | Promise; headerName: string; authScheme: string; whitelistedDomains: Array; @@ -112,7 +114,7 @@ export class JwtInterceptor implements HttpInterceptor { ) { return next.handle(request); } - const token = this.tokenGetter(); + const token = this.tokenGetter(request); if (token instanceof Promise) { return from(token).pipe( diff --git a/src/app/services/example-http.service.spec.ts b/src/app/services/example-http.service.spec.ts index fc43a049..c6a34331 100644 --- a/src/app/services/example-http.service.spec.ts +++ b/src/app/services/example-http.service.spec.ts @@ -7,10 +7,22 @@ import { import { JwtModule } from "angular-jwt"; export function tokenGetter() { - return "SOME_TEST_TOKEN"; + return "TEST_TOKEN"; } -describe("ExampleHttpService", () => { +export function tokenGetterWithRequest(request) { + if (request.url.includes("1")) { + return "TEST_TOKEN_1"; + } + + if (request.url.includes("2")) { + return "TEST_TOKEN_2"; + } + + return "TEST_TOKEN"; +} + +describe("Example HttpService: with simple tokken getter", () => { let service: ExampleHttpService; let httpMock: HttpTestingController; @@ -82,3 +94,52 @@ describe("ExampleHttpService", () => { }) ); }); + +describe("Example HttpService: with request based tokken getter", () => { + let service: ExampleHttpService; + let httpMock: HttpTestingController; + + const routes = [ + `http://example-1.com/api/`, + `http://example-2.com/api/`, + `http://example-3.com/api/`, + ]; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientTestingModule, + JwtModule.forRoot({ + config: { + tokenGetter: tokenGetterWithRequest, + whitelistedDomains: [ + "example-1.com", + "example-2.com", + "example-3.com", + ], + }, + }), + ], + }); + service = TestBed.get(ExampleHttpService); + httpMock = TestBed.get(HttpTestingController); + }); + + it("should add Authorisation header", () => { + expect(service).toBeTruthy(); + }); + + routes.forEach((route) => + it(`should set the correct auth token for a domain: ${route}`, () => { + service.testRequest(route).subscribe((response) => { + expect(response).toBeTruthy(); + }); + + const httpRequest = httpMock.expectOne(route); + expect(httpRequest.request.headers.has("Authorization")).toEqual(true); + expect(httpRequest.request.headers.get("Authorization")).toEqual( + `Bearer ${tokenGetterWithRequest({ url: route })}` + ); + }) + ); +});