/test

Created with StackBlitz ⚡️

Primary LanguageTypeScript

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AdminLoginEventsService, EDAPAdminConfigurationsService, EDAPExtendSessionPopup, EDAPLocaleConvertorService, EDAPLocalizationConfigurationService, EDAPLocalizationService, EdapServerConfigManager, EdapServerURI, EDAPSessionManagementService, SeedLoginEventsService,EDAP_APP_FLOW_TYPE } from 'EdapWebComponents';
import * as WebFont from 'webfontloader';
import { ApplicationConfigurationService } from '../configuration/application.configuration';
import { ContextManagerService } from './context-manager/context-manager.service';
import { AppLocationService } from './service/app.state.service';
import { LoginStatusService } from './service/login-status.service';
+import { take } from 'rxjs/operators';
declare var $;
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'EDAP Login';
  extentSession
  constructor(private _router: Router, private acRoute: ActivatedRoute, private appLocation: AppLocationService, private edapAdminConfig: EDAPAdminConfigurationsService, public translate: EDAPLocalizationService, public localization: EDAPLocalizationConfigurationService, private sessionManage: EDAPSessionManagementService, private edapLocaleConvertor: EDAPLocaleConvertorService, private edapServerConfigManager: EdapServerConfigManager, private loginStatus: LoginStatusService, private contextManager: ContextManagerService, private adminLoginEvents: AdminLoginEventsService, private seedLoginEvent: SeedLoginEventsService) {
    //App Service to access last location entered in the browser
    this.appLocation.setLastLocation(window.location.pathname);
    //Set WebComponent Library Parameters for Application context to access the images and setting the context
    this.edapServerConfigManager.setEdapServerURI(<EdapServerURI>{
      url: ApplicationConfigurationService.configSettings.apiServerConfig.uri,
      version: ApplicationConfigurationService.configSettings.apiServerConfig.version,
      deployUrl: this.contextManager.getContext()
    });

    this.loginStatus.getLoggedInNotifier().subscribe(() => {
      this.setSessionExpiredPopupDetails();
    });
    
+    /**
+     * Event/Subscriptions to notify the application need to load the required locale resources
+     * To Notify Locale is changed and application can load the required 
+    */
+    this.localization.getTranslationLoadRequired().subscribe((userLocale)=>{
+      this.localization.setLocaleTranslationConfiguration(userLocale, ...this.contextManager.getLocaleFiles(userLocale));
+    });
    /**
     * For TMO Users Only
     * Subscribe the event to get the User successfully logged into the application
     * As soon User Login process is completed and user is verified the event is triggered
     * with parameters @loginEvent which contains the session information for the user
     */
    this.adminLoginEvents.onLoginSuccess.subscribe((loginEvent) => {
      //Initialize the Localization Service
-      this.localization.setLocaleConfiguration({ ...loginEvent.userLocale }, ...this.contextManager.getLocaleFiles(loginEvent.userLocale)).pipe(take(1)).subscribe(() => {
+      this.localization.setLocaleConfiguration({ ...loginEvent.userLocale }, ...this.contextManager.getLocaleFiles(loginEvent.userLocale)).pipe(take(1)).subscribe(() => {
        //for application flow only to refresh the session object
        //cached the session information object
        this.loginStatus.setSessionInfo(loginEvent);
        //Triggered the logged in event to notify
        this.loginStatus.userLoggedIn();
        //Admin logged in event to notify admin is logged in
        this.appLocation.onAdminLoggedIn.emit(loginEvent);
      });
    });
    /**
     * For Seed Admin Users Only
     * Subscribe the event to get the User successfully logged into the application
     * As soon User Login process is completed and user is verified the event is triggered
     * with parameters @loginEvent which contains the session information for the user
     */
    this.seedLoginEvent.onLoginSuccess.subscribe((loginEvent) => {
      let sessionInfo = loginEvent;
+      if(this.isSeedAdminBasic() && !sessionInfo.needToLoadLocale){
+         //for application flow only to refresh the session object
+         this.loginStatus.setSessionInfo(sessionInfo);
+         //Triggered the logged in event to notify
+         this.loginStatus.userLoggedIn();
+         //Seed Admin logged in event to notify seed admin is logged in
+         this.appLocation.onSeedAdminLoggedIn.emit(loginEvent);
+         this.localization.setLocaleConfigurationMetrics(sessionInfo.userLocale);
+      }
+      else{
        //Initialize the Localization Service
-        this.localization.setLocaleConfiguration(sessionInfo.userLocale, ...this.contextManager.getLocaleFiles(loginEvent.userLocale)).subscribe(() =>
+        this.localization.setLocaleConfiguration(sessionInfo.userLocale, ...this.contextManager.getLocaleFiles(loginEvent.userLocale)).pipe(take(1)).subscribe(() => {
          //for application flow only to refresh the session object
          this.loginStatus.setSessionInfo(sessionInfo);
          //Triggered the logged in event to notify
          this.loginStatus.userLoggedIn();
          //Seed Admin logged in event to notify seed admin is logged in
          this.appLocation.onSeedAdminLoggedIn.emit(loginEvent);
+        });
      }
    });
+    this.seedLoginEvent.onLoginRefreshFailure.subscribe((error) => {
+      this.seedLoginEvent.triggerSessionTerminated(error.error);
+      sessionStorage.clear();
+    });
+    /**
+     * Seed Locale changes
+     */
+    this.seedLoginEvent.getLocaleChangeEvent().subscribe((localeEvent)=>{
+      this.localization.setLocaleTranslationConfiguration(localeEvent, ...this.contextManager.getLocaleFiles(localeEvent)).pipe(take(1)).subscribe((e) => {
+        console.log(e); //@todo
+      });
+    })
    /**
     * For Admin Users Only
     * Subscribe the event to get when the admin is logged out from the Session and 
     * Application can Take the Required Action if needed
     */
    this.adminLoginEvents.onLogout.subscribe(() => {
+    this.loginStatus.clearSessionInformation();
      /**
       * Clear the session management schedular
       */
      this.sessionManage.clear();
    });
+    /**
+     * Event to capture session refresh failure for Admin User
+     * In the case of if edap token changed on server and not matched with the browser one.
+     * This event is triggered when user presses F5 or refresh the browser
+     **/
+    this.adminLoginEvents.onLoginRefreshFailure.subscribe((error) => {
+      this.adminLoginEvents.triggerSessionTerminated(error.error);
+      sessionStorage.clear();
+    });
    /**
    * For Seed Admin Users Only
    * Subscribe the event to get when the seed admin is logged out from the Session and 
    * Application can Take the Required Action if needed
    */
    this.seedLoginEvent.onLogout.subscribe(() => {
+    this.loginStatus.clearSessionInformation();
      /**
       * Clear the session management schedular
       */
      this.sessionManage.clear();
    });
    if (WebFont && WebFont.load) {
      WebFont.load({
        google: {
          families: ['falcon', 'Roboto', 'Roboto-Light', 'Roboto-Medium', 'Roboto-Bold', 'Roboto-Black']
        }
      });
    }
  }
  /**
   * Set the following things for the Session popup
   * 1.Verbiage for the session timeout popup
   * 2.Set Parameters for the popup window e.g.(grace period,idle time)
   */
  setSessionExpiredPopupDetails() {
    // Setting keys after locale loaded successfully
    let sessionInfo = this.loginStatus.getSessionInfo();
    this.extentSession = <EDAPExtendSessionPopup>{
      title: 'sessionExtend.title',//key presents inside assets/i18n/<localize-file>.json
      yesText: 'sessionExtend.yesText',
      noText: 'sessionExtend.noText',
      expired: 'sessionExtend.expired',
      expiring: 'sessionExtend.expiring'
    };
    //Initialize the session management timeout period
    this.sessionManage.init({
      //Grace period
      gracePeriod: sessionInfo.sessionGracePeriod || 0,
      //Max idle time
      maxIdleTime: sessionInfo.sessionMaxIdleTime || 0,
      //Need to be set false only (Reserved for Future use)
      suppressTimeout: false,
      //Auth token
      accessToken: sessionInfo.accessToken,
      //Extends Session call frequency
      pingtime: sessionInfo.schedluerFrequency,
      //Session Type TMO,USER etc.
      sessionType: sessionInfo.sessionType
    });
  }
  /**
   * Convert query parameters into the JSON Object
   * @param url URL provided
   */
  queryStringToJSON(url) {
    var pairs = url.slice(1).split('&');
    var result = {};
    pairs.forEach(function (pair) {
      pair = pair.split('=');
      result[pair[0]] = decodeURIComponent(pair[1] || '');
    });
    return JSON.parse(JSON.stringify(result));
  }
  /**
   * Triggered when the session is expired
   * Either from the Terminate button is clicked or Default terminated session is initiated
   * @param res Expired information object
   * for User :if res.errorMessage is non empty and res.suppressLogout is true then the user must lands to the Error Page otherwise Lands to the login page
   * for TMO : needs to call triggerSessionExpired of AdminLoginEventsService  to notify admin flow
   * for Seed admin: Needs to call the triggerSessionExpired of SeedLoginEventsService to notify seed admin flow
   */
  onSessionExpired(res) {
+    this.loginStatus.clearSessionInformation();
    /**
     * for Admin users needs to trigger the triggerSessionExpired of AdminLoginEventsService  to notify admin flow
     */
    if (window.location.pathname.toLowerCase().includes("/edapsample/admin")) {
      this.adminLoginEvents.triggerSessionExpired(res);
    }
    /**
    * for Seed admin needs to trigger the triggerSessionExpired of SeedLoginEventsService  to notify seed admin flow
    */
    else if (window.location.pathname.toLowerCase().includes("edapsample/seedadminsso")||window.location.pathname.toLowerCase().includes("edapsample/seedadmin")) {
      this.seedLoginEvent.triggerSessionExpired(res);
    }
    /**
     * for User :if res.errorMessage is non empty and res.suppressLogout is true then the user must lands to the Error Page otherwise Lands to the login page
     */
    else {
      /**
       * If Error Message contains error and Needs to go to the error page in the case of the SSO Flow
       */
      if (res && res.suppressLogout === true && res.errorMessage) {
        this._router.navigate(['/edapsample/error'], { queryParams: { error: res.errorMessage } });
      }
      /**
       * If no error message and no suppress means go to the login page flow
       */
      else {
        this._router.navigate(['/edapsample/login']);
      }
    }
    sessionStorage.clear();
  }
  ngOnInit() {
    //Redirect to the admin login Page in the case of the Admin Flow
    if (window.location.pathname.toLowerCase().endsWith("/edapsample/admin")) {
      this._router.navigate(['/edapsample/admin/tenantadmin/adminlogin']);
    }
    /**
     * Redirect to the seed admin flow in the case of the seed admin flow
     */
    if (window.location.pathname.toLowerCase().endsWith("/edapsample/seedadmin") || window.location.pathname.toLowerCase().endsWith("/edapsample/seedadminsso")) {
      if (window.location.pathname.toLowerCase().endsWith("/edapsample/seedadminsso")) {
        let params = (window.location.search && this.queryStringToJSON(window.location.search)) || {};
        if(!$.isEmptyObject(params)){
          let queryParams = { queryParams: params };
          this._router.navigate(['/edapsample/seedadminsso/seed/seedlogin'],queryParams);
        }
        else{
          this._router.navigate(['/edapsample/seedadminsso/seed/seedlogin']);
        }
      }
      else {
        this._router.navigate(['/edapsample/seedadmin/seed/seedlogin']);
      }
    }
    /**
     * For the User flow if the user is not admin and not seed
     */
    else if (!(window.location.pathname.toLowerCase().includes("/edapsample/admin") || window.location.pathname.toLowerCase().includes("/edapsample/seedadmin"))) {
      /**
       * Persist the Query parameters of the URL
       */
      let params = (window.location.search && this.queryStringToJSON(window.location.search)) || {};
      if ($.isEmptyObject(params)) {
        /**
         * Without query params if no query params presents
         */
        this._router.navigate(['/edapsample/login']);
      }
      else {
        let queryParams = { queryParams: params }
        /**
         * With the query params if found
         */
        this._router.navigate(['/edapsample/login'], queryParams);
      }
    }
    /**
     * Subscribe the Session terminate notifier in the case of the Session terminated from the Server itself
     */
    this.sessionManage.getSessionTerminatedNotifier().subscribe((err) => {
      this.onSessionTerminated(err);
    });
  }
  /**
   * Called when Session is terminated from the server
   * @param err Error Description object
   * for User :User must lands to the Error Page
   * for TMO : Needs to call triggerSessionTerminated of AdminLoginEventsService  to notify admin flow
   * for Seed Admin: Needs to call the triggerSessionTerminated of SeedLoginEventsService to notify seed admin flow
   */
  onSessionTerminated(err) {
+     this.loginStatus.clearSessionInformation();
    /**
     * for TMO : Needs to call triggerSessionTerminated of AdminLoginEventsService  to notify admin flow
     */
    if (window.location.pathname.toLowerCase().includes("/edapsample/admin")) {
      this.adminLoginEvents.triggerSessionTerminated(err);
    }
    /**
     * for Seed Admin: Needs to call the triggerSessionTerminated of SeedLoginEventsService to notify seed admin flow
     */
    else if (window.location.pathname.toLowerCase().includes("edapsample/seedadminsso")){
      this.seedLoginEvent.triggerSessionTerminated(err);
    }
    /**
     * for User :User must lands to the Error Page
     */
    else {
      //Clear the session storage
      sessionStorage.clear();
-      this._router.navigate(['/edapsample/error'], { queryParams: { error: err.errorMessage } });
+      if(sessionInfo && sessionInfo.userLoginMode === EDAP_APP_FLOW_TYPE.BASIC){
+        this._router.navigate(['/edapsample/login']);
+      }
+      else{
+        this._router.navigate(['/edapsample/error'], { queryParams: { error: err.errorMessage } });
+      }
  }

+  isSeedAdminBasic(){
+    return window.location.pathname.toLowerCase().includes("edapsample/seedadmin") && (!window.location.pathname.toLowerCase().includes("edapsample/seedadminsso"));
+  }
}

Interceptor changes for error handing and Session Event Notification

import { Injectable } from '@angular/core';
import {
    HttpInterceptor,
    HttpRequest,
    HttpResponse,
    HttpHandler,
    HttpEvent,
    HttpErrorResponse
} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { ApplicationConfigurationService } from 'src/configuration/application.configuration';
+import { LoginStatusService } from '../service/login-status.service';
-import { EDAPSessionManagementService } from 'EdapWebComponents'
+import { EDAPSessionManagementService,EDAP_COMMON_SESSION_ERRORS, EDAP_ADMIN_SESSION_AUTH_TOKEN, EDAP_SEED_ADMIN_SESSION_AUTH_TOKEN, AdminLoginEventsService, SeedLoginEventsService,EDAP_APP_FLOW_TYPE } from 'EdapWebComponents'
import { Router } from '@angular/router';

@Injectable()
export class HttpConfigInterceptor implements HttpInterceptor {
    apiContext;
    loggedIn = false;
    constructor(private loginStatus: LoginStatusService, public _router: Router, private sessionManage: EDAPSessionManagementService,private adminLoginEvents: AdminLoginEventsService, private seedLoginEvent: SeedLoginEventsService) {
        this.loginStatus.getLoggedInNotifier().subscribe(() => {
            this.loggedIn = true;
        });
    }
    isNotAdminAndSeed() {
        return (!window.location.href.includes("edapsample/seedadmin") && !window.location.href.includes("edapsample/admin"));
    }
    isAdmin() {
        return window.location.href.includes("edapsample/admin");
    }
    isSeedUser() {
        return window.location.href.includes("edapsample/seedadmin");
    }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        if (ApplicationConfigurationService && ApplicationConfigurationService.configSettings && ApplicationConfigurationService.configSettings.apiServerConfig && ApplicationConfigurationService.configSettings.apiServerConfig.uri) {
            this.apiContext = ApplicationConfigurationService.configSettings.apiServerConfig.uri.substring(ApplicationConfigurationService.configSettings.apiServerConfig.uri.lastIndexOf("/") + 1);
        }
        let isApiCall = request.url.indexOf(this.apiContext) >= 0;
        if (isApiCall && this.isNotAdminAndSeed()) {
            let token: string = sessionStorage.getItem('accessToken');
            if (token) {
                request = request.clone({ headers: request.headers.set('Authorization', token) });
            }
        }
        if (isApiCall && !this.isNotAdminAndSeed()) {
            if (window.location.href.includes("edapsample/seedadmin")) {
                let token: string = sessionStorage.getItem(EDAP_SEED_ADMIN_SESSION_AUTH_TOKEN.AUTH_TOKEN_STORAGE_KEY);
                if (token) {
                    request = request.clone({ headers: request.headers.set(EDAP_SEED_ADMIN_SESSION_AUTH_TOKEN.AUTH_TOKEN_HTTP_HEADER_KEY, token) });
                }
            }
            else {
                let token: string = sessionStorage.getItem(EDAP_ADMIN_SESSION_AUTH_TOKEN.AUTH_TOKEN_STORAGE_KEY);
                if (token) {
                    request = request.clone({ headers: request.headers.set(EDAP_ADMIN_SESSION_AUTH_TOKEN.AUTH_TOKEN_HTTP_HEADER_KEY, token) });
                }
            }
        }
        return next.handle(request).pipe(
            catchError((error: HttpErrorResponse) => {
                let notAdminAndNotSeed = this.isNotAdminAndSeed();
-                if (error && error.error && error.error.errorCode) {
+                if (error && error.error && error.error.errorCode && this.loginStatus.getLoggedInStatus()) {
                    //Error for the User needs to be handled
+                    let hasUserError = (EDAP_COMMON_SESSION_ERRORS.USER.indexOf(error.error.errorCode) >= 0);
+                    //Error for the Seed Admin needs to be handled
+                    let hasSeedAdminError = (EDAP_COMMON_SESSION_ERRORS.SEEDADMIN.indexOf(error.error.errorCode) >= 0);
+                    //Error for the Admin
+                    let hasAdminError = (EDAP_COMMON_SESSION_ERRORS.TMO.indexOf(error.error.errorCode) >= 0);
+                    //Catch exception for the User
+                     if (notAdminAndNotSeed && hasUserError) {
+                        this.loginStatus.clearSessionInformation();
+                        sessionStorage.clear();
+                        this.sessionManage.clear();
+                        let sessionInfo = this.loginStatus.getSessionInfo();
+                        if(sessionInfo && sessionInfo.userLoginMode === EDAP_APP_FLOW_TYPE.BASIC){
+                            this._router.navigate(['/edapsample/login']);
+                        }
+                        else{
                            this._router.navigate(['/edapsample/error'], { queryParams: { error: error.error.errorMessage } });
+                        }                      
+                    }
+                    //Catch exception for the Admin
                    else if (this.isAdmin() && hasAdminError) {
+                         this.loginStatus.clearSessionInformation();
                          this.adminLoginEvents.triggerSessionTerminated(error.error);
+                    }
+                    //catch Exception for the Seed Admin
+                    else if (this.isSeedUser() && hasSeedAdminError) {
+                        this.loginStatus.clearSessionInformation();
                         this.seedLoginEvent.triggerSessionTerminated(error.error);
+                    }
                }
                return throwError(error);
            })
        );
    }
}