diff --git a/goofy-client/libs/ui/src/lib/interceptor/xhr.interceptor.spec.ts b/goofy-client/libs/tech-shared/src/lib/interceptor/xhr.interceptor.spec.ts similarity index 72% rename from goofy-client/libs/ui/src/lib/interceptor/xhr.interceptor.spec.ts rename to goofy-client/libs/tech-shared/src/lib/interceptor/xhr.interceptor.spec.ts index cddd23a3eb91f4c76d090c7d8a7e6481789c74d6..5637353ee5d69cfabb2ebe05eec0b6f46d08fe47 100644 --- a/goofy-client/libs/ui/src/lib/interceptor/xhr.interceptor.spec.ts +++ b/goofy-client/libs/tech-shared/src/lib/interceptor/xhr.interceptor.spec.ts @@ -29,10 +29,11 @@ import { XhrInterceptor } from './xhr.interceptor'; describe('XhrInterceptor', () => { let interceptor: XhrInterceptor; - const apiHost = 'http://kop/api' + const apiHost: string = 'http://kop/api' + const apiUrl: string = apiHost + '/vorgaenge'; + const nonApiUrl: string = 'http://kop/vorgang/123'; beforeEach(() => TestBed.configureTestingModule({ - imports: [], providers: [ XhrInterceptor, { @@ -62,7 +63,7 @@ describe('XhrInterceptor', () => { const httpHandler: HttpHandler = { handle }; it('should add header for api requests', () => { - const req: HttpRequest<any> = new HttpRequest('GET', apiHost + '/vorgaenge'); + const req: HttpRequest<any> = new HttpRequest('GET', apiUrl); interceptor.intercept(req, httpHandler); @@ -70,7 +71,7 @@ describe('XhrInterceptor', () => { }) it('should not add header for no api requests', () => { - const req: HttpRequest<any> = new HttpRequest('GET', 'http://someserver/resource'); + const req: HttpRequest<any> = new HttpRequest('GET', nonApiUrl); interceptor.intercept(req, httpHandler); @@ -78,4 +79,23 @@ describe('XhrInterceptor', () => { }) }) + describe('isApiRequest', () => { + it('should return true for API URL', () => { + expect(interceptor.isApiRequest(apiUrl)).toBeTruthy() + }) + + it('should return false for non-API URL', () => { + expect(interceptor.isApiRequest(nonApiUrl)).toBeFalsy() + }) + }) + + describe('addHeader', () => { + it('should add X-Requested-With header', () => { + const request: HttpRequest<unknown> = new HttpRequest('GET', apiUrl); + + const result: HttpRequest<unknown> = interceptor.addHeader(request); + + expect(result.headers.get('X-Requested-With')).toEqual('XMLHttpRequest'); + }) + }) }); \ No newline at end of file diff --git a/goofy-client/libs/ui/src/lib/interceptor/xhr.interceptor.ts b/goofy-client/libs/tech-shared/src/lib/interceptor/xhr.interceptor.ts similarity index 69% rename from goofy-client/libs/ui/src/lib/interceptor/xhr.interceptor.ts rename to goofy-client/libs/tech-shared/src/lib/interceptor/xhr.interceptor.ts index 35a26216efca4707d6eecbbb9bb788522837b916..a667ebcd5fb8e29fe332d45e37773f6cddab67cf 100644 --- a/goofy-client/libs/ui/src/lib/interceptor/xhr.interceptor.ts +++ b/goofy-client/libs/tech-shared/src/lib/interceptor/xhr.interceptor.ts @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; +import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { Environment, ENVIRONMENT_CONFIG } from '@goofy-client/environment-shared'; +import { Observable } from 'rxjs'; @Injectable() export class XhrInterceptor implements HttpInterceptor { @@ -31,13 +32,20 @@ export class XhrInterceptor implements HttpInterceptor { constructor(@Inject(ENVIRONMENT_CONFIG) private envConfig: Environment) { } - intercept(req: HttpRequest<any>, next: HttpHandler) { - if (req.url.startsWith(this.envConfig.remoteHost)) { - const xhr: HttpRequest<any> = req.clone({ - headers: req.headers.set('X-Requested-With', 'XMLHttpRequest') - }); - return next.handle(xhr); + intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { + if (this.isApiRequest(req.url)) { + return next.handle(this.addHeader(req)); } return next.handle(req); } + + isApiRequest(url: string): boolean { + return url.startsWith(this.envConfig.remoteHost); + } + + addHeader(req: HttpRequest<unknown>): HttpRequest<unknown> { + return req.clone({ + headers: req.headers.set('X-Requested-With', 'XMLHttpRequest') + }); + } } \ No newline at end of file diff --git a/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts b/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts index 155e6385f0d3e90db061b2684927ef1de77d0483..50efc0642f52bb3f1c92c2465e8de05525615ca1 100644 --- a/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts +++ b/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts @@ -26,6 +26,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { Injector, NgModule } from '@angular/core'; import { HttpBinaryFileInterceptor } from './interceptor/http-binary-file.interceptor'; import { HttpXsrfInterceptor } from './interceptor/http-xsrf.interceptor'; +import { XhrInterceptor } from './interceptor/xhr.interceptor'; import { ConvertForDataTestPipe } from './pipe/convert-for-data-test.pipe'; import { EnumToLabelPipe } from './pipe/enum-to-label.pipe'; import { FileSizePipe } from './pipe/file-size.pipe'; @@ -67,6 +68,11 @@ import { ToTrafficLightPipe } from './pipe/to-traffic-light.pipe'; FileSizePipe, ], providers: [ + { + provide: HTTP_INTERCEPTORS, + useClass: XhrInterceptor, + multi: true, + }, { provide: HTTP_INTERCEPTORS, useClass: HttpXsrfInterceptor, diff --git a/goofy-client/libs/ui/src/lib/ui/ui.module.ts b/goofy-client/libs/ui/src/lib/ui/ui.module.ts index 71e75fe205e6a099c4d66edac26c9658cffcbf5f..9a37578f0a282c7909fd73fefb9bddbf7e5d1bb9 100644 --- a/goofy-client/libs/ui/src/lib/ui/ui.module.ts +++ b/goofy-client/libs/ui/src/lib/ui/ui.module.ts @@ -58,7 +58,6 @@ import { AppIconComponent } from '../icon/app-icon/app-icon.component'; import { PostfachIconComponent } from '../icon/postfach-icon/postfach-icon.component'; import { HttpConnectionTimeoutInterceptor } from '../interceptor/http-connection-timeout.interceptor'; import { HttpErrorInterceptor } from '../interceptor/http-error.interceptor'; -import { XhrInterceptor } from '../interceptor/xhr.interceptor'; import { SnackbarCloseButtonComponent } from '../snackbar/snackbar-close-button/snackbar-close-button.component'; import { SnackbarErrorComponent } from '../snackbar/snackbar-error/snackbar-error.component'; import { SnackbarInfoComponent } from '../snackbar/snackbar-info/snackbar-info.component'; @@ -154,11 +153,6 @@ const modules = [ imports: [...modules], exports: [...modules, ...components], providers: [ - { - provide: HTTP_INTERCEPTORS, - useClass: XhrInterceptor, - multi: true, - }, { provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor,