# Interceptor
import { AuthService } from '../services/auth.service';
import { ApiService } from '../services/api.service';
import { Injectable, Injector } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { BehaviorSubject, Observable, throwError } from 'rxjs';
import { catchError, switchMap, finalize } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppState } from '../../reducers/app.reducers';
import {environment} from '../../../environments/environment';
declare var CryptoJSAesJson;
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
isRefreshingToken = false;
private publicKey = environment.publicKey;
tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
constructor(
private injector: Injector,
private readonly store: Store<AppState>,
private readonly authService: AuthService
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any | HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (typeof err === 'string' || err?.error.data) {
const encrypted = atob(err?.error.data).toString();
err = CryptoJSAesJson.decrypt(encrypted, this.publicKey);
}
if (err.status === 401) {
localStorage.removeItem('token');
if (!this.isRefreshingToken) {
this.isRefreshingToken = true;
// Reset here so that the following requests wait until the token
// comes back from the refreshToken call.
this.tokenSubject.next(null);
const authService = this.injector.get(ApiService);
return authService.refreshToken().pipe(
switchMap((newToken: any) => {
if (newToken) {
const oauth = JSON.parse(localStorage.getItem('oauth'));
oauth.refresh_token = newToken.refresh_token;
localStorage.setItem('token', newToken.access_token);
localStorage.setItem('oauth', JSON.stringify(oauth));
this.tokenSubject.next(newToken);
return next.handle(this.addToken(request, newToken.access_token));
}
return throwError(err);
}),
catchError(error => {
return throwError(error);
}),
finalize(() => {
this.isRefreshingToken = false;
}));
} else {
this.authService.logout();
}
}
const errorRsp = err?.message || err?.statusText || 'Error inesperado en el servidor.';
return throwError(errorRsp);
}));
}
addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
return req.clone({ setHeaders: { Authorization: 'Bearer ' + token } });
}
}
# Refresh Token
public refreshToken() {
const oauth = JSON.parse(localStorage.getItem('oauth'));
const httpHeaders = new HttpHeaders({
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
Accept: 'application/json',
});
const params = new URLSearchParams();
params.set('grant_type', 'refresh_token');
params.set('refresh_token', oauth?.refresh_token);
params.set('client_id', oauth?.client_id);
params.set('client_secret', oauth?.client_secret);
const dataSend = {
grant_type: 'refresh_token',
refresh_token: oauth?.refresh_token,
client_id: oauth?.client_id,
client_secret: oauth?.client_secret,
};
return this.http.post(this.url + 'oauth/token', dataSend, { headers: httpHeaders });
}