mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge pull request #1255 from 4Science/#1248
Improve logging Angular implementation
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { APP_BASE_HREF, CommonModule } from '@angular/common';
|
import { APP_BASE_HREF, CommonModule } from '@angular/common';
|
||||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
|
||||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||||
|
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
@@ -38,6 +38,7 @@ import { ForbiddenComponent } from './forbidden/forbidden.component';
|
|||||||
import { AuthInterceptor } from './core/auth/auth.interceptor';
|
import { AuthInterceptor } from './core/auth/auth.interceptor';
|
||||||
import { LocaleInterceptor } from './core/locale/locale.interceptor';
|
import { LocaleInterceptor } from './core/locale/locale.interceptor';
|
||||||
import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor';
|
import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor';
|
||||||
|
import { LogInterceptor } from './core/log/log.interceptor';
|
||||||
import { RootComponent } from './root/root.component';
|
import { RootComponent } from './root/root.component';
|
||||||
import { ThemedRootComponent } from './root/themed-root.component';
|
import { ThemedRootComponent } from './root/themed-root.component';
|
||||||
import { ThemedEntryComponentModule } from '../themes/themed-entry-component.module';
|
import { ThemedEntryComponentModule } from '../themes/themed-entry-component.module';
|
||||||
@@ -49,6 +50,9 @@ import { ThemedBreadcrumbsComponent } from './breadcrumbs/themed-breadcrumbs.com
|
|||||||
import { ThemedHeaderNavbarWrapperComponent } from './header-nav-wrapper/themed-header-navbar-wrapper.component';
|
import { ThemedHeaderNavbarWrapperComponent } from './header-nav-wrapper/themed-header-navbar-wrapper.component';
|
||||||
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||||
|
|
||||||
|
import { UUIDService } from './core/shared/uuid.service';
|
||||||
|
import { CookieService } from './core/services/cookie.service';
|
||||||
|
|
||||||
export function getBase() {
|
export function getBase() {
|
||||||
return environment.ui.nameSpace;
|
return environment.ui.nameSpace;
|
||||||
}
|
}
|
||||||
@@ -121,6 +125,27 @@ const PROVIDERS = [
|
|||||||
useClass: XsrfInterceptor,
|
useClass: XsrfInterceptor,
|
||||||
multi: true
|
multi: true
|
||||||
},
|
},
|
||||||
|
// register LogInterceptor as HttpInterceptor
|
||||||
|
{
|
||||||
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
useClass: LogInterceptor,
|
||||||
|
multi: true
|
||||||
|
},
|
||||||
|
// insert the unique id of the user that is using the application utilizing cookies
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
useFactory: (cookieService: CookieService, uuidService: UUIDService) => {
|
||||||
|
const correlationId = cookieService.get('CORRELATION-ID');
|
||||||
|
|
||||||
|
// Check if cookie exists, if don't, set it with unique id
|
||||||
|
if (!correlationId) {
|
||||||
|
cookieService.set('CORRELATION-ID', uuidService.generate());
|
||||||
|
}
|
||||||
|
return () => true;
|
||||||
|
},
|
||||||
|
multi: true,
|
||||||
|
deps: [ CookieService, UUIDService ]
|
||||||
|
},
|
||||||
...DYNAMIC_MATCHER_PROVIDERS,
|
...DYNAMIC_MATCHER_PROVIDERS,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
76
src/app/core/log/log.interceptor.spec.ts
Normal file
76
src/app/core/log/log.interceptor.spec.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||||
|
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { LogInterceptor } from './log.interceptor';
|
||||||
|
import { DspaceRestService } from '../dspace-rest/dspace-rest.service';
|
||||||
|
import { RestRequestMethod } from '../data/rest-request-method';
|
||||||
|
import { CookieService } from '../services/cookie.service';
|
||||||
|
import { CookieServiceMock } from '../../shared/mocks/cookie.service.mock';
|
||||||
|
import { RouterStub } from '../../shared/testing/router.stub';
|
||||||
|
|
||||||
|
|
||||||
|
describe('LogInterceptor', () => {
|
||||||
|
let service: DspaceRestService;
|
||||||
|
let httpMock: HttpTestingController;
|
||||||
|
let cookieService: CookieService;
|
||||||
|
const router = Object.assign(new RouterStub(),{url : '/statistics'});
|
||||||
|
|
||||||
|
// Mock payload/statuses are dummy content as we are not testing the results
|
||||||
|
// of any below requests. We are only testing for X-XSRF-TOKEN header.
|
||||||
|
const mockPayload = {
|
||||||
|
id: 1
|
||||||
|
};
|
||||||
|
const mockStatusCode = 200;
|
||||||
|
const mockStatusText = 'SUCCESS';
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [HttpClientTestingModule],
|
||||||
|
providers: [
|
||||||
|
DspaceRestService,
|
||||||
|
// LogInterceptor,
|
||||||
|
{
|
||||||
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
useClass: LogInterceptor,
|
||||||
|
multi: true,
|
||||||
|
},
|
||||||
|
{ provide: CookieService, useValue: new CookieServiceMock() },
|
||||||
|
{ provide: Router, useValue: router },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
service = TestBed.get(DspaceRestService);
|
||||||
|
httpMock = TestBed.get(HttpTestingController);
|
||||||
|
cookieService = TestBed.get(CookieService);
|
||||||
|
|
||||||
|
cookieService.set('CORRELATION-ID','123455');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('headers should be set', (done) => {
|
||||||
|
service.request(RestRequestMethod.POST, 'server/api/core/items', 'test', { withCredentials: false }).subscribe((response) => {
|
||||||
|
expect(response).toBeTruthy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
const httpRequest = httpMock.expectOne('server/api/core/items');
|
||||||
|
httpRequest.flush(mockPayload, { status: mockStatusCode, statusText: mockStatusText });
|
||||||
|
expect(httpRequest.request.headers.has('X-CORRELATION-ID')).toBeTrue();
|
||||||
|
expect(httpRequest.request.headers.has('X-REFERRER')).toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('headers should have the right values', (done) => {
|
||||||
|
service.request(RestRequestMethod.POST, 'server/api/core/items', 'test', { withCredentials: false }).subscribe((response) => {
|
||||||
|
expect(response).toBeTruthy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
const httpRequest = httpMock.expectOne('server/api/core/items');
|
||||||
|
httpRequest.flush(mockPayload, { status: mockStatusCode, statusText: mockStatusText });
|
||||||
|
expect(httpRequest.request.headers.get('X-CORRELATION-ID')).toEqual('123455');
|
||||||
|
expect(httpRequest.request.headers.get('X-REFERRER')).toEqual('/statistics');
|
||||||
|
});
|
||||||
|
});
|
33
src/app/core/log/log.interceptor.ts
Normal file
33
src/app/core/log/log.interceptor.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
import { CookieService } from '../services/cookie.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log Interceptor intercepting Http Requests & Responses to
|
||||||
|
* exchange add headers of the user using the application utilizing unique id in cookies.
|
||||||
|
* Add header for users current page path.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class LogInterceptor implements HttpInterceptor {
|
||||||
|
|
||||||
|
constructor(private cookieService: CookieService, private router: Router) {}
|
||||||
|
|
||||||
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
|
||||||
|
// Get Unique id of the user from the cookies
|
||||||
|
const correlationId = this.cookieService.get('CORRELATION-ID');
|
||||||
|
|
||||||
|
// Add headers from the intercepted request
|
||||||
|
let headers = request.headers;
|
||||||
|
headers = headers.append('X-CORRELATION-ID', correlationId);
|
||||||
|
headers = headers.append('X-REFERRER', this.router.url);
|
||||||
|
|
||||||
|
// Add new headers to the intercepted request
|
||||||
|
request = request.clone({ withCredentials: true, headers: headers });
|
||||||
|
return next.handle(request);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user