aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/shared-main/auth/auth-interceptor.service.ts')
-rw-r--r--client/src/app/shared/shared-main/auth/auth-interceptor.service.ts60
1 files changed, 60 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts b/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts
new file mode 100644
index 000000000..68a4acdb5
--- /dev/null
+++ b/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts
@@ -0,0 +1,60 @@
1import { Observable, throwError as observableThrowError } from 'rxjs'
2import { catchError, switchMap } from 'rxjs/operators'
3import { HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'
4import { Injectable, Injector } from '@angular/core'
5import { AuthService } from '@app/core/auth/auth.service'
6
7@Injectable()
8export class AuthInterceptor implements HttpInterceptor {
9 private authService: AuthService
10
11 // https://github.com/angular/angular/issues/18224#issuecomment-316957213
12 constructor (private injector: Injector) {}
13
14 intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
15 if (this.authService === undefined) {
16 this.authService = this.injector.get(AuthService)
17 }
18
19 const authReq = this.cloneRequestWithAuth(req)
20
21 // Pass on the cloned request instead of the original request
22 // Catch 401 errors (refresh token expired)
23 return next.handle(authReq)
24 .pipe(
25 catchError(err => {
26 if (err.status === 401 && err.error && err.error.code === 'invalid_token') {
27 return this.handleTokenExpired(req, next)
28 }
29
30 return observableThrowError(err)
31 })
32 )
33 }
34
35 private handleTokenExpired (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
36 return this.authService.refreshAccessToken()
37 .pipe(
38 switchMap(() => {
39 const authReq = this.cloneRequestWithAuth(req)
40
41 return next.handle(authReq)
42 })
43 )
44 }
45
46 private cloneRequestWithAuth (req: HttpRequest<any>) {
47 const authHeaderValue = this.authService.getRequestHeaderValue()
48
49 if (authHeaderValue === null) return req
50
51 // Clone the request to add the new header
52 return req.clone({ headers: req.headers.set('Authorization', authHeaderValue) })
53 }
54}
55
56export const AUTH_INTERCEPTOR_PROVIDER = {
57 provide: HTTP_INTERCEPTORS,
58 useClass: AuthInterceptor,
59 multi: true
60}