--- /dev/null
+/*
+ Copyright 2020 TATA ELXSI
+
+ Licensed under the Apache License, Version 2.0 (the 'License');
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
+ */
+
+/**
+ * @file HttpInterceptor file
+ */
+import {
+ HttpErrorResponse, HttpHandler, HttpHeaderResponse, HttpInterceptor, HttpProgressEvent,
+ HttpRequest, HttpResponse, HttpSentEvent, HttpUserEvent
+} from '@angular/common/http';
+import { Injectable, Injector } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
+import { NotifierService } from 'angular-notifier';
+import { AuthenticationService } from 'AuthenticationService';
+import * as HttpStatus from 'http-status-codes';
+import { Observable, throwError } from 'rxjs';
+import { catchError, retry } from 'rxjs/operators';
+
+/**
+ * An Injectable is a class adorned with the @Injectable decorator function.
+ * @Injectable takes a metadata object that tells Angular how to compile and run module code
+ */
+@Injectable()
+export class AuthInterceptorService implements HttpInterceptor {
+ /** Holds header options @private */
+ private clonedReq: HttpRequest<{}>;
+
+ /** To inject services @private */
+ private injector: Injector;
+
+ /** Notifier service to popup notification @private */
+ private notifierService: NotifierService;
+
+ /** Contains tranlsate instance @private */
+ private translateService: TranslateService;
+
+ /** Utilizes auth service for any auth operations @private */
+ private authService: AuthenticationService;
+
+ /** create the instance of the component */
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.notifierService = this.injector.get(NotifierService);
+ this.authService = this.injector.get(AuthenticationService);
+ this.translateService = this.injector.get(TranslateService);
+ }
+
+ /**
+ * intercept logic
+ * @param req
+ * @param next
+ */
+ public intercept(req: HttpRequest<{}>, next: HttpHandler): Observable<HttpSentEvent |
+ // tslint:disable-next-line:no-any
+ HttpHeaderResponse | HttpProgressEvent | HttpResponse<{}> | HttpUserEvent<any> | any> {
+ const idToken: string = localStorage.getItem('id_token');
+ const excludedUrl: string[] = ['osm/admin/v1/tokens', 'assets/i18n/', 'osm/version'];
+ if (excludedUrl.some((x: string): boolean => { return req.url.includes(x); })) { return next.handle(req); }
+ if (idToken.length > 0) {
+ this.setHeader(req, idToken);
+ return next.handle(this.clonedReq).pipe(
+ catchError((err: HttpErrorResponse) => {
+ this.errorRes(err, req, next);
+ return throwError(err);
+ })
+ );
+ } else {
+ //TODO: Handle error via notification service
+ }
+ }
+
+ /** Set header options @public */
+ // tslint:disable-next-line:no-any
+ public setHeader(req: HttpRequest<any>, idToken: string): void {
+ if (req.body !== null && req.body.byteLength !== null) {
+ this.clonedReq = req.clone({
+ setHeaders: { Authorization: 'Bearer ' + idToken, 'Cache-Control': 'no-cache', Pragma: 'no-cache' }
+ });
+ } else {
+ this.clonedReq = req.clone({
+ setHeaders: { Authorization: 'Bearer ' + idToken, 'Content-Type': 'charset=UTF-8',
+ 'Cache-Control': 'no-cache', Pragma: 'no-cache' }
+ });
+ }
+ }
+
+ /** Handles error response @public */
+ public errorRes(err: HttpErrorResponse, req: HttpRequest<{}>, next: HttpHandler): Observable<{}> {
+ if (err instanceof HttpErrorResponse) {
+ switch (err.status) {
+ case HttpStatus.UNAUTHORIZED || HttpStatus.FORBIDDEN:
+ this.handleError(err);
+ break;
+ default: return throwError(err);
+ }
+ } else { return throwError(err); }
+ }
+
+ /** Method to handle 401 & 403 error */
+ private handleError(err: HttpErrorResponse): void {
+ if (err.error.detail === 'Expired Token or Authorization HTTP header' ||
+ err.error.detail === 'Invalid Token or Authorization HTTP header') {
+ this.notifierService.hideAll();
+ this.authService.logoutResponse();
+ if (this.authService.handle401) {
+ this.notifierService.notify('error', this.translateService.instant('SESSIONEXPIRY'));
+ this.authService.handle401 = false;
+ }
+ }
+ }
+}