import { Injectable } from "@angular/core"; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse, HTTP_INTERCEPTORS, } from "@angular/common/http"; import { Observable, throwError, BehaviorSubject } from "rxjs"; import { catchError, filter, take, switchMap } from "rxjs/operators"; import { SessionStore } from "src/app/store/session.service"; import { MiddlewareRepositoryService } from "src/app/repository/middleWare/middleware-repository.service" @Injectable({ providedIn: 'root' }) export class TokenInterceptorService { private isRefreshing = false; private refreshTokenSubject: BehaviorSubject = new BehaviorSubject( null ); constructor(private middlewareRepositoryService: MiddlewareRepositoryService) { this.middlewareRepositoryService = middlewareRepositoryService } intercept( request: HttpRequest, next: HttpHandler ): Observable> { if (SessionStore.user.Authorization) { request = this.addToken(request, SessionStore.user.Authorization); } return next.handle(request).pipe( catchError((error) => { if (error instanceof HttpErrorResponse && error.status === 401) { return this.handle401Error(request, next); } else { return throwError(error); } }) ) as any } private addToken(request: HttpRequest, token: string) { return request.clone({ setHeaders: { Authorization: `Bearer ${token}`, }, }); } private handle401Error(request: HttpRequest, next: HttpHandler) { if (!this.isRefreshing) { this.isRefreshing = true; this.refreshTokenSubject.next(null); return this.middlewareRepositoryService.refreshToken().pipe( switchMap((token: any) => { this.isRefreshing = false; this.refreshTokenSubject.next(token['result'].accessToken); return next.handle(this.addToken(request, token['result'].accessToken)); }) ); } else { return this.refreshTokenSubject.pipe( filter((token) => token != null), take(1), switchMap((jwt) => { return next.handle(this.addToken(request, jwt)); }) ); } } }