import { Injectable, Injector } from '@angular/core'; import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor,HttpErrorResponse} from '@angular/common/http'; import { BehaviorSubject, Observable, throwError } from 'rxjs'; import { catchError, filter, switchMap, take } from 'rxjs/operators'; import { ErrorMessages } from '../../utils/enums'; import { environment } from '../../../environments/environment'; import { CredentialService } from '../../services/credential.service'; import { EncryptionService } from '../../services/encryption.service'; import { NotificationService } from '../services/notification.service'; import { I18NService } from '../../services/i18n.service'; import { AuthenticationService } from '../../services/authenticate.service'; @Injectable() export class AuthInterceptor implements HttpInterceptor { private isRefreshing = false; private refreshTokenSubject: BehaviorSubject = new BehaviorSubject(null); private enableEncryption = environment.enableEncryption; constructor(private injector: Injector, private credentialService: CredentialService, private encryptionService: EncryptionService, private notificationService: NotificationService, private i18nService: I18NService) {} intercept(request: HttpRequest, handler: HttpHandler): Observable> { if (this.credentialService.getPorOrgacode()!= undefined){ request = this.setDefaultHeaders(request); } // FOR BIOMETRIC SECUGEN WE BYPASS THESE URIS AS SECUGEN DRIVERS IS USING LOCAL ENDPOINTS. if (this.credentialService.getToken()&& !request.url.endsWith("/SGIFPCapture")&& !request.url.endsWith("/CreateTemplate")&& !request.url.endsWith("/verifyUserBiometric")) { request = this.addToken(request, this.credentialService.getToken()); } if(this.enableEncryption && (request.method === "POST" || request.method === "PATCH" ) && !request.url.endsWith("/SGIFPCapture")&& !request.url.endsWith("/createTemplate")&& !request.url.endsWith("/verifyUserBiometric")) { request = this.setEncryptionHeader(request); request = this.encryptRequestBody(request); } return handler.handle(request).pipe(catchError(error => { if (error instanceof HttpErrorResponse && error.status === 401) { return this.handleAuthError(request, handler); } else { this.handleServerError(error); return throwError(error); } })); } private encryptRequestBody(request: HttpRequest): HttpRequest { if (Object.keys(request.body).length > 0) { const encryptedData: object = this.encryptionService.encryptData(request.body); const encryptedRequest: any = request.clone({ body: encryptedData }); return encryptedRequest; } return request; } private handleAuthError(request: HttpRequest, handler: HttpHandler) { if (!this.isRefreshing) { this.isRefreshing = true; this.refreshTokenSubject.next(null); let authService: AuthenticationService = this.injector.get(AuthenticationService); return authService.refreshToken().pipe( switchMap((response: any) => { this.isRefreshing = false; this.refreshTokenSubject.next(response.token); return handler.handle(this.addToken(request, response.token)).pipe(catchError(error => { this.handleServerError(error); return throwError(error); })); })); } else { return this.refreshTokenSubject.pipe( filter(token => token != null), take(1), switchMap(token => { return handler.handle(this.addToken(request, token)); })); } } private handleServerError(error: HttpErrorResponse) { let url: string = error.url as string; let moduleName: string = ""; if (url != null && url != undefined) { moduleName = url.split(':').length>2 ? url.split(':')[2].split('/')[1]: url.split('/')[3]; } let authService: AuthenticationService = this.injector.get(AuthenticationService); switch (error.status) { case 400: let errorResponse:any = error ; if (errorResponse.error && errorResponse.error.errorCode != null) { this.i18nService.error(errorResponse.error.errorCode, errorResponse.error.arguments); } else { this.i18nService.error(ErrorMessages.BAD_REQUEST,[moduleName.toUpperCase()]); } break; case 401: this.i18nService.error(ErrorMessages.UNAUTHORIZED_REQUEST,[]); authService.logout(); break; case 403: this.i18nService.error(ErrorMessages.FORBIDDEN_REQUEST,[]); authService.logout(); break; case 500: this.i18nService.error(ErrorMessages.INTERNAL_SERVER_ERROR,[moduleName.toUpperCase()]); break; case 0: this.i18nService.error(ErrorMessages.CONNECTION_ERROR,[moduleName.toUpperCase()]); break; } } private addToken(request: HttpRequest, token: string) { return request.clone({ setHeaders: { 'Authorization': `Bearer ${token}` } }); } private setDefaultHeaders(request: HttpRequest): HttpRequest { const modifiedHeaders = request.headers.set('userId', this.credentialService.getUserId()) .append('porOrgacode', this.credentialService.getPorOrgacode()) return request.clone({ headers: modifiedHeaders }); } private setEncryptionHeader(request: HttpRequest): HttpRequest { const modifiedHeaders = request.headers.set('X-Encrypted', this.enableEncryption.toString()); return request.clone({ headers: modifiedHeaders }); } }