import { Injectable } from "@angular/core"; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse, HTTP_INTERCEPTORS, HttpClient, } from "@angular/common/http"; import { AuthService } from '../services/auth.service'; import { Observable, throwError, BehaviorSubject, of } from "rxjs"; import { catchError, filter, take, switchMap, tap } from "rxjs/operators"; import { SessionStore } from '../store/session.service'; import { environment } from "src/environments/environment"; import { Router } from "@angular/router"; import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'; @Injectable() export class TokenInterceptor implements HttpInterceptor { private isRefreshing = false; private refreshTokenSubject: BehaviorSubject = new BehaviorSubject( null ); private excludedDomains = [ 'Login', environment.apiChatUrl, 'http://localhost:8019']; // Add the domains you want to exclude constructor(private http: HttpClient, private router: Router,private httpErrorHandle: HttpErrorHandle,) { } intercept( request: HttpRequest, next: HttpHandler ): Observable> { if (this.shouldExcludeDomain(request)) { return next.handle(request); } if (SessionStore.user.Authorization) { request = this.addToken(request, SessionStore.user.Authorization); } return next.handle(request).pipe( catchError((error) => { console.log('interceptor ',error) if (error instanceof HttpErrorResponse && error.status === 401) { return this.handle401Error(request, next); } else if (error.url.includes('https://gdapi-dev.dyndns.info/stage/api/v2') && error.status === 0){ return this.handle401Error(request, next); } else { return throwError(error); } }) ); } private shouldExcludeDomain(request: HttpRequest): boolean { const url = request.url.toLowerCase(); return this.excludedDomains.some((domain) => url.includes(domain.toLowerCase())); } private addToken(request: HttpRequest, token: string) { return request.clone({ setHeaders: { //'Access-Control-Allow-Origin': '*', Authorization: `Bearer ${token}`, }, }); } private handle401Error(request: HttpRequest, next: HttpHandler) { // if not getting the new token yet if (!this.isRefreshing) { this.isRefreshing = true; this.refreshTokenSubject.next(null); return this.refreshToken().pipe( switchMap((token: any) => { this.isRefreshing = false; this.refreshTokenSubject.next(token.Authorization); return next.handle(this.addToken(request, token.Authorization)); }) ); } else { // get new token return this.refreshTokenSubject.pipe( filter((token) => token != null), take(1), switchMap((jwt) => { return next.handle(this.addToken(request, jwt)); }) ); } } //this method refresh token is declared here temporary beacouse a circular error refreshToken() { return this.http .put(environment.apiURL + "UserAuthentication/RefreshToken", { refreshToken: SessionStore.user.RefreshToken, },) .pipe( tap((tokens) => { console.log(tokens) SessionStore.user.Authorization = tokens.Authorization; SessionStore.user.RefreshToken = tokens.refreshToken; SessionStore.save(); }), catchError((error) => { console.log(error) SessionStore.user.Authorization = SessionStore.user.Authorization; SessionStore.user.RefreshToken = SessionStore.user.RefreshToken; SessionStore.setInativity(false) /* SessionStore.setUrlBeforeInactivity(this.router.url); */ if (environment.production) { window.location.pathname = '/auth' } else { const pathBeforeGoOut = window.location.pathname console.log('Before auth',window.location.pathname) this.router.navigateByUrl('/auth', { replaceUrl: true }).then(() =>{ if(pathBeforeGoOut != "/auth") { this.httpErrorHandle.httpsSucessMessagge('sessonExpired') } }) } return of(false); }) ); } } export const tokenInterceptor = { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true };