All files / src/app/core/identity-provider co-browse.identity-provider.ts

71.42% Statements 35/49
75% Branches 21/28
52.63% Functions 10/19
72.91% Lines 35/48

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116  2x 2x 2x 2x 2x   2x 2x 2x   2x 2x 2x     2x   6x 6x 6x 6x 6x 6x                       6x             6x   6x 3x           2x 1x 1x     1x   1x                       1x                                                 2x 2x 2x   2x     2x   2x 2x                    
import { HttpEvent, HttpHandler, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Router } from '@angular/router';
import { Store, select } from '@ngrx/store';
import { Observable, noop, of, race, throwError } from 'rxjs';
import { catchError, concatMap, delay, filter, first, map, switchMap, take } from 'rxjs/operators';
 
import { AccountFacade } from 'ish-core/facades/account.facade';
import { AppFacade } from 'ish-core/facades/app.facade';
import { CheckoutFacade } from 'ish-core/facades/checkout.facade';
import { IdentityProvider, TriggerReturnType } from 'ish-core/identity-provider/identity-provider.interface';
import { selectQueryParam } from 'ish-core/store/core/router';
import { ApiTokenService } from 'ish-core/utils/api-token/api-token.service';
import { whenTruthy } from 'ish-core/utils/operators';
 
@Injectable({ providedIn: 'root' })
export class CoBrowseIdentityProvider implements IdentityProvider {
  constructor(
    protected router: Router,
    protected store: Store,
    protected apiTokenService: ApiTokenService,
    private appFacade: AppFacade,
    private accountFacade: AccountFacade,
    private checkoutFacade: CheckoutFacade
  ) {}
 
  getCapabilities() {
    return {
      editPassword: false,
      editEmail: false,
      editProfile: false,
    };
  }
 
  init() {
    this.apiTokenService.getCookieVanishes$().subscribe(type => {
      Iif (type === 'user') {
        this.accountFacade.logoutUser({ revokeApiToken: false });
      }
    });
 
    // OAuth Service should be configured before apiToken information are restored and the refresh token mechanism is setup
    this.apiTokenService.restore$(['user', 'order']).subscribe(noop);
 
    this.checkoutFacade.basket$.pipe(whenTruthy(), first()).subscribe(basketView => {
      window.sessionStorage.setItem('basket-id', basketView.id);
    });
  }
 
  triggerLogin(route: ActivatedRouteSnapshot): TriggerReturnType {
    // check for required start parameters before doing anything with the co-browse route
    if (!route.queryParamMap.has('access-token')) {
      this.appFacade.setBusinessError('cobrowse.error.missing.parameter');
      return false;
    }
 
    this.accountFacade.loginUserWithToken(route.queryParamMap.get('access-token'));
 
    return race(
      // throw an error if a user login error occurs
      this.accountFacade.userError$.pipe(
        whenTruthy(),
        take(1),
        concatMap(userError => throwError(() => userError))
      ),
 
      // handle the punchout functions once the punchout user is logged in
      this.accountFacade.isLoggedIn$.pipe(
        whenTruthy(),
        take(1),
        map(() => this.router.parseUrl('/home')),
        // punchout error after successful authentication (needs to logout)
        catchError(error =>
          this.accountFacade.userLoading$.pipe(
            first(loading => !loading),
            delay(0),
            switchMap(() => {
              this.accountFacade.logoutUser();
              this.apiTokenService.removeApiToken();
              this.appFacade.setBusinessError(error);
              return of(this.router.parseUrl('/error'));
            })
          )
        )
      )
    ).pipe(
      // general punchout error handling (parameter missing, authentication error)
      catchError(error => {
        this.appFacade.setBusinessError(error);
        return of(this.router.parseUrl('/error'));
      })
    );
  }
 
  triggerLogout(): TriggerReturnType {
    window.sessionStorage.removeItem('basket-id');
    this.accountFacade.logoutUser(); // user will be logged out and related refresh token is revoked on server
    return this.accountFacade.isLoggedIn$.pipe(
      // wait until the user is logged out before you go to homepage to prevent unnecessary REST calls
      filter(loggedIn => !loggedIn),
      take(1),
      switchMap(() =>
        this.store.pipe(
          select(selectQueryParam('returnUrl')),
          map(returnUrl => returnUrl || '/home'),
          map(returnUrl => this.router.parseUrl(returnUrl))
        )
      )
    );
  }
 
  intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return this.apiTokenService.intercept(req, next);
  }
}