/**
 * Copyright 2017 - 2018  The Hyve B.V.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */ import { tap , switchMap } from 'rxjs/operators' ; import { Injectable , Injector } from '@angular/core' ; import { HttpErrorResponse , HttpEvent , HttpHandler , HttpInterceptor , HttpRequest } from '@angular/common/http' ; import { Observable } from 'rxjs' ; import { AppConfig } from '../../config/app.config' ; import { AuthenticationService } from '../authentication/authentication.service' ; import { AuthorizationResult } from '../authentication/authorization-result' ; @ Injectable ( { providedIn : 'root' } ) export class ApiHttpInterceptor implements HttpInterceptor { private authenticationService : AuthenticationService ; private appConfig : AppConfig ; constructor ( private injector ) { } /**
     * Intercept HTTP request to embed headers (token and content-type)
     */ intercept ( req , next ) { if ( this . authenticationService === undefined ) { this . authenticationService = this . injector . get ( AuthenticationService ) ; } if ( this . appConfig === undefined ) { this . appConfig = this . injector . get ( AppConfig ) ; } if ( this . authorizationNotRequiredForUrl ( req . url ) ) { return next . handle ( req ) ; } return this . authenticationService . authorised . pipe ( switchMap ( ( isAuthorized ) => { if ( isAuthorized && this . authenticationService . validToken ) { return next . handle ( this . addAPIHeaders ( req ) ) ; } else { return this . authenticationService . authorise ( ) . pipe ( switchMap ( ( authResult ) => { if ( authResult !== AuthorizationResult . Authorized ) { throw new Error ( 'Not authorized' ) ; } return next . handle ( this . addAPIHeaders ( req ) ) . pipe ( tap ( ( ) => { } , ( err ) => { if ( err instanceof HttpErrorResponse ) { if ( err . status === 401 ) { this . authenticationService . logout ( ) ; } } } ) ) ; } ) ) ; } } ) ) ; } private authorizationNotRequiredForUrl ( url ) { return url . includes ( AppConfig . path ) || ( ! url . includes ( this . appConfig . getConfig ( 'gb-backend-url' ) ) && ! url . includes ( this . appConfig . getConfig ( 'api-url' ) ) && ! ( this . appConfig . getConfig ( 'export-mode' ) [ 'name' ] !== 'transmart' ? url . includes ( this . appConfig . getConfig ( 'export-mode' ) [ 'export-url' ] ) : false ) ) || url . endsWith ( '/oauth/token' ) ; } private addAPIHeaders ( req ) { let token = this . authenticationService . token ; if ( token !== '' ) { return req . clone ( { setHeaders : { 'Content-Type' : 'application/json' , 'Authorization' : 'Bearer ' + token } } ) ; } else { throw new Error ( 'Token is null' ) ; } } }