X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=src%2Fservices%2FAuthInterceptorService.ts;fp=src%2Fservices%2FAuthInterceptorService.ts;h=ede10a8b2ab4d010d87b8f2a2d4bdb90391261ab;hb=3b4814aa2d3dec621dadb52f058ba95a3dc3a86a;hp=0000000000000000000000000000000000000000;hpb=1434673f8f8dc53bce5c350f04ac8df67b2ff84f;p=osm%2FNG-UI.git diff --git a/src/services/AuthInterceptorService.ts b/src/services/AuthInterceptorService.ts new file mode 100644 index 0000000..ede10a8 --- /dev/null +++ b/src/services/AuthInterceptorService.ts @@ -0,0 +1,126 @@ +/* + 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 | HttpUserEvent | 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, 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; + } + } + } +}