]>
Commit | Line | Data |
---|---|---|
db400f44 C |
1 | import { Observable, throwError as observableThrowError } from 'rxjs' |
2 | import { catchError, switchMap } from 'rxjs/operators' | |
d592e0a9 | 3 | import { Injectable, Injector } from '@angular/core' |
db400f44 | 4 | import { HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http' |
d592e0a9 | 5 | import { AuthService } from '../../core' |
d592e0a9 C |
6 | |
7 | @Injectable() | |
8 | export 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) | |
db400f44 C |
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 | ) | |
d592e0a9 C |
33 | } |
34 | ||
35 | private handleTokenExpired (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | |
36 | return this.authService.refreshAccessToken() | |
db400f44 C |
37 | .pipe( |
38 | switchMap(() => { | |
39 | const authReq = this.cloneRequestWithAuth(req) | |
d592e0a9 | 40 | |
db400f44 C |
41 | return next.handle(authReq) |
42 | }) | |
43 | ) | |
d592e0a9 C |
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 | ||
56 | export const AUTH_INTERCEPTOR_PROVIDER = { | |
57 | provide: HTTP_INTERCEPTORS, | |
58 | useClass: AuthInterceptor, | |
59 | multi: true | |
60 | } |