mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-01-28 22:59:03 -06:00
Chore: Http interceptors refactor (#11923)
--------- Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
@@ -1,30 +1,41 @@
|
|||||||
import { HttpEvent, HttpRequest } from '@angular/common/http'
|
import {
|
||||||
|
HttpClient,
|
||||||
|
provideHttpClient,
|
||||||
|
withInterceptors,
|
||||||
|
} from '@angular/common/http'
|
||||||
|
import {
|
||||||
|
HttpTestingController,
|
||||||
|
provideHttpClientTesting,
|
||||||
|
} from '@angular/common/http/testing'
|
||||||
import { TestBed } from '@angular/core/testing'
|
import { TestBed } from '@angular/core/testing'
|
||||||
import { of } from 'rxjs'
|
|
||||||
import { environment } from 'src/environments/environment'
|
import { environment } from 'src/environments/environment'
|
||||||
import { ApiVersionInterceptor } from './api-version.interceptor'
|
import { withApiVersionInterceptor } from './api-version.interceptor'
|
||||||
|
|
||||||
describe('ApiVersionInterceptor', () => {
|
describe('ApiVersionInterceptor', () => {
|
||||||
let interceptor: ApiVersionInterceptor
|
let httpClient: HttpClient
|
||||||
|
let httpMock: HttpTestingController
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [ApiVersionInterceptor],
|
providers: [
|
||||||
|
provideHttpClient(withInterceptors([withApiVersionInterceptor])),
|
||||||
|
provideHttpClientTesting(),
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
interceptor = TestBed.inject(ApiVersionInterceptor)
|
httpClient = TestBed.inject(HttpClient)
|
||||||
|
httpMock = TestBed.inject(HttpTestingController)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should add api version to headers', () => {
|
it('should add api version to headers', () => {
|
||||||
interceptor.intercept(new HttpRequest('GET', 'https://example.com'), {
|
httpClient.get('https://example.com').subscribe()
|
||||||
handle: (request) => {
|
const request = httpMock.expectOne('https://example.com')
|
||||||
const header = request.headers['lazyUpdate'][0]
|
const header = request.request.headers['lazyUpdate'][0]
|
||||||
expect(header.name).toEqual('Accept')
|
|
||||||
expect(header.value).toEqual(
|
expect(header.name).toEqual('Accept')
|
||||||
`application/json; version=${environment.apiVersion}`
|
expect(header.value).toEqual(
|
||||||
)
|
`application/json; version=${environment.apiVersion}`
|
||||||
return of({} as HttpEvent<any>)
|
)
|
||||||
},
|
request.flush({})
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,27 +1,20 @@
|
|||||||
import {
|
import {
|
||||||
HttpEvent,
|
HttpEvent,
|
||||||
HttpHandler,
|
HttpHandlerFn,
|
||||||
HttpInterceptor,
|
HttpInterceptorFn,
|
||||||
HttpRequest,
|
HttpRequest,
|
||||||
} from '@angular/common/http'
|
} from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
|
||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
import { environment } from 'src/environments/environment'
|
import { environment } from 'src/environments/environment'
|
||||||
|
|
||||||
@Injectable()
|
export const withApiVersionInterceptor: HttpInterceptorFn = (
|
||||||
export class ApiVersionInterceptor implements HttpInterceptor {
|
request: HttpRequest<unknown>,
|
||||||
constructor() {}
|
next: HttpHandlerFn
|
||||||
|
): Observable<HttpEvent<unknown>> => {
|
||||||
intercept(
|
request = request.clone({
|
||||||
request: HttpRequest<unknown>,
|
setHeaders: {
|
||||||
next: HttpHandler
|
Accept: `application/json; version=${environment.apiVersion}`,
|
||||||
): Observable<HttpEvent<unknown>> {
|
},
|
||||||
request = request.clone({
|
})
|
||||||
setHeaders: {
|
return next(request)
|
||||||
Accept: `application/json; version=${environment.apiVersion}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return next.handle(request)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,52 @@
|
|||||||
import { HttpEvent, HttpRequest } from '@angular/common/http'
|
import {
|
||||||
|
HttpClient,
|
||||||
|
provideHttpClient,
|
||||||
|
withInterceptors,
|
||||||
|
} from '@angular/common/http'
|
||||||
|
import {
|
||||||
|
HttpTestingController,
|
||||||
|
provideHttpClientTesting,
|
||||||
|
} from '@angular/common/http/testing'
|
||||||
import { TestBed } from '@angular/core/testing'
|
import { TestBed } from '@angular/core/testing'
|
||||||
import { Meta } from '@angular/platform-browser'
|
import { Meta } from '@angular/platform-browser'
|
||||||
import { CookieService } from 'ngx-cookie-service'
|
import { CookieService } from 'ngx-cookie-service'
|
||||||
import { of } from 'rxjs'
|
import { withCsrfInterceptor } from './csrf.interceptor'
|
||||||
import { CsrfInterceptor } from './csrf.interceptor'
|
|
||||||
|
|
||||||
describe('CsrfInterceptor', () => {
|
describe('CsrfInterceptor', () => {
|
||||||
let interceptor: CsrfInterceptor
|
|
||||||
let meta: Meta
|
let meta: Meta
|
||||||
let cookieService: CookieService
|
let cookieService: CookieService
|
||||||
|
let httpClient: HttpClient
|
||||||
|
let httpMock: HttpTestingController
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [CsrfInterceptor, Meta, CookieService],
|
providers: [
|
||||||
|
Meta,
|
||||||
|
CookieService,
|
||||||
|
provideHttpClient(withInterceptors([withCsrfInterceptor])),
|
||||||
|
provideHttpClientTesting(),
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
meta = TestBed.inject(Meta)
|
meta = TestBed.inject(Meta)
|
||||||
cookieService = TestBed.inject(CookieService)
|
cookieService = TestBed.inject(CookieService)
|
||||||
interceptor = TestBed.inject(CsrfInterceptor)
|
httpClient = TestBed.inject(HttpClient)
|
||||||
|
httpMock = TestBed.inject(HttpTestingController)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get csrf token', () => {
|
it('should get csrf token', () => {
|
||||||
meta.addTag({ name: 'cookie_prefix', content: 'ngx-' }, true)
|
meta.addTag({ name: 'cookie_prefix', content: 'ngx-' }, true)
|
||||||
|
|
||||||
const cookieServiceSpy = jest.spyOn(cookieService, 'get')
|
const cookieServiceSpy = jest.spyOn(cookieService, 'get')
|
||||||
cookieServiceSpy.mockReturnValue('csrftoken')
|
cookieServiceSpy.mockReturnValue('csrftoken')
|
||||||
interceptor.intercept(new HttpRequest('GET', 'https://example.com'), {
|
|
||||||
handle: (request) => {
|
httpClient.get('https://example.com').subscribe()
|
||||||
expect(request.headers['lazyUpdate'][0]['name']).toEqual('X-CSRFToken')
|
const request = httpMock.expectOne('https://example.com')
|
||||||
return of({} as HttpEvent<any>)
|
|
||||||
},
|
expect(request.request.headers['lazyUpdate'][0]['name']).toEqual(
|
||||||
})
|
'X-CSRFToken'
|
||||||
|
)
|
||||||
expect(cookieServiceSpy).toHaveBeenCalled()
|
expect(cookieServiceSpy).toHaveBeenCalled()
|
||||||
|
request.flush({})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,36 +1,32 @@
|
|||||||
import {
|
import {
|
||||||
HttpEvent,
|
HttpEvent,
|
||||||
HttpHandler,
|
HttpHandlerFn,
|
||||||
HttpInterceptor,
|
HttpInterceptorFn,
|
||||||
HttpRequest,
|
HttpRequest,
|
||||||
} from '@angular/common/http'
|
} from '@angular/common/http'
|
||||||
import { inject, Injectable } from '@angular/core'
|
import { inject } from '@angular/core'
|
||||||
import { Meta } from '@angular/platform-browser'
|
import { Meta } from '@angular/platform-browser'
|
||||||
import { CookieService } from 'ngx-cookie-service'
|
import { CookieService } from 'ngx-cookie-service'
|
||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
|
|
||||||
@Injectable()
|
export const withCsrfInterceptor: HttpInterceptorFn = (
|
||||||
export class CsrfInterceptor implements HttpInterceptor {
|
request: HttpRequest<unknown>,
|
||||||
private cookieService: CookieService = inject(CookieService)
|
next: HttpHandlerFn
|
||||||
private meta: Meta = inject(Meta)
|
): Observable<HttpEvent<unknown>> => {
|
||||||
|
const cookieService: CookieService = inject(CookieService)
|
||||||
|
const meta: Meta = inject(Meta)
|
||||||
|
|
||||||
intercept(
|
let prefix = ''
|
||||||
request: HttpRequest<unknown>,
|
if (meta.getTag('name=cookie_prefix')) {
|
||||||
next: HttpHandler
|
prefix = meta.getTag('name=cookie_prefix').content
|
||||||
): Observable<HttpEvent<unknown>> {
|
|
||||||
let prefix = ''
|
|
||||||
if (this.meta.getTag('name=cookie_prefix')) {
|
|
||||||
prefix = this.meta.getTag('name=cookie_prefix').content
|
|
||||||
}
|
|
||||||
let csrfToken = this.cookieService.get(`${prefix}csrftoken`)
|
|
||||||
if (csrfToken) {
|
|
||||||
request = request.clone({
|
|
||||||
setHeaders: {
|
|
||||||
'X-CSRFToken': csrfToken,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return next.handle(request)
|
|
||||||
}
|
}
|
||||||
|
let csrfToken = cookieService.get(`${prefix}csrftoken`)
|
||||||
|
if (csrfToken) {
|
||||||
|
request = request.clone({
|
||||||
|
setHeaders: {
|
||||||
|
'X-CSRFToken': csrfToken,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return next(request)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import {
|
|||||||
import { DragDropModule } from '@angular/cdk/drag-drop'
|
import { DragDropModule } from '@angular/cdk/drag-drop'
|
||||||
import { DatePipe, registerLocaleData } from '@angular/common'
|
import { DatePipe, registerLocaleData } from '@angular/common'
|
||||||
import {
|
import {
|
||||||
HTTP_INTERCEPTORS,
|
|
||||||
provideHttpClient,
|
provideHttpClient,
|
||||||
withFetch,
|
withFetch,
|
||||||
|
withInterceptors,
|
||||||
withInterceptorsFromDi,
|
withInterceptorsFromDi,
|
||||||
} from '@angular/common/http'
|
} from '@angular/common/http'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
@@ -151,8 +151,8 @@ import { AppComponent } from './app/app.component'
|
|||||||
import { DirtyDocGuard } from './app/guards/dirty-doc.guard'
|
import { DirtyDocGuard } from './app/guards/dirty-doc.guard'
|
||||||
import { DirtySavedViewGuard } from './app/guards/dirty-saved-view.guard'
|
import { DirtySavedViewGuard } from './app/guards/dirty-saved-view.guard'
|
||||||
import { PermissionsGuard } from './app/guards/permissions.guard'
|
import { PermissionsGuard } from './app/guards/permissions.guard'
|
||||||
import { ApiVersionInterceptor } from './app/interceptors/api-version.interceptor'
|
import { withApiVersionInterceptor } from './app/interceptors/api-version.interceptor'
|
||||||
import { CsrfInterceptor } from './app/interceptors/csrf.interceptor'
|
import { withCsrfInterceptor } from './app/interceptors/csrf.interceptor'
|
||||||
import { DocumentTitlePipe } from './app/pipes/document-title.pipe'
|
import { DocumentTitlePipe } from './app/pipes/document-title.pipe'
|
||||||
import { FilterPipe } from './app/pipes/filter.pipe'
|
import { FilterPipe } from './app/pipes/filter.pipe'
|
||||||
import { UsernamePipe } from './app/pipes/username.pipe'
|
import { UsernamePipe } from './app/pipes/username.pipe'
|
||||||
@@ -381,16 +381,6 @@ bootstrapApplication(AppComponent, {
|
|||||||
provideAppInitializer(initializeApp),
|
provideAppInitializer(initializeApp),
|
||||||
DatePipe,
|
DatePipe,
|
||||||
CookieService,
|
CookieService,
|
||||||
{
|
|
||||||
provide: HTTP_INTERCEPTORS,
|
|
||||||
useClass: CsrfInterceptor,
|
|
||||||
multi: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: HTTP_INTERCEPTORS,
|
|
||||||
useClass: ApiVersionInterceptor,
|
|
||||||
multi: true,
|
|
||||||
},
|
|
||||||
FilterPipe,
|
FilterPipe,
|
||||||
DocumentTitlePipe,
|
DocumentTitlePipe,
|
||||||
{ provide: NgbDateAdapter, useClass: ISODateAdapter },
|
{ provide: NgbDateAdapter, useClass: ISODateAdapter },
|
||||||
@@ -402,6 +392,10 @@ bootstrapApplication(AppComponent, {
|
|||||||
CorrespondentNamePipe,
|
CorrespondentNamePipe,
|
||||||
DocumentTypeNamePipe,
|
DocumentTypeNamePipe,
|
||||||
StoragePathNamePipe,
|
StoragePathNamePipe,
|
||||||
provideHttpClient(withInterceptorsFromDi(), withFetch()),
|
provideHttpClient(
|
||||||
|
withInterceptorsFromDi(),
|
||||||
|
withInterceptors([withCsrfInterceptor, withApiVersionInterceptor]),
|
||||||
|
withFetch()
|
||||||
|
),
|
||||||
],
|
],
|
||||||
}).catch((err) => console.error(err))
|
}).catch((err) => console.error(err))
|
||||||
|
|||||||
Reference in New Issue
Block a user