ef-keycloak-connect 1.7.8 → 1.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,6 @@ This adapter is extended from keycloak-connect and have functionalities of both
40
40
  - getRealmRoles
41
41
  - assignRoleToUser
42
42
  - authenticateFinesse
43
- - getUserDetailsById
44
43
 
45
44
  ```
46
45
  ### Example
@@ -457,53 +456,5 @@ Response:
457
456
  "status": 400,
458
457
  "message": "Refresh Token expired, please login again"
459
458
  }
460
-
461
- ### getUserDetailsById( userId )
462
-
463
- This function returns user object against given user id. The information contains the details of user except its team and roles. If userId is incorrect then it returns 404 error response.
464
-
465
- It takes 1 argument:
466
-
467
- - userId: The keycloak id of a given user.
468
-
469
- Response:
470
-
471
- - If the userId is valid then a user details object is returned in reponse along with status code 200.
472
-
473
- ```js
474
- {
475
- "id": "66498b60-d6d1-45c9-9a04-e8d43f1ce3ce",
476
- "createdTimestamp": 1748601962666,
477
- "username": "admin",
478
- "enabled": true,
479
- "totp": false,
480
- "emailVerified": false,
481
- "firstName": "",
482
- "lastName": "",
483
- "disableableCredentialTypes": [],
484
- "requiredActions": [],
485
- "notBefore": 0,
486
- "access": {
487
- "manageGroupMembership": true,
488
- "view": true,
489
- "mapRoles": true,
490
- "impersonate": true,
491
- "manage": true
492
- }
493
- }
494
-
495
- - If userId is incorrect then it returns 404 error response.
496
-
497
- ```js
498
- {
499
- "error": {
500
- "error_message": "User Details API Error: Error occurred while getting user against user id",
501
- "error_detail": {
502
- "status": 404,
503
- "reason": "No user exist in keycloak against given user id: 66498b60-d6d1-45c9-9a04-e8d43f1ce3cd"
504
- }
505
- }
506
- }
507
-
508
459
 
509
460
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ef-keycloak-connect",
3
- "version": "1.7.8",
3
+ "version": "1.7.9",
4
4
  "description": "Node JS keycloak adapter for authentication and authorization.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -47,7 +47,7 @@ class KeycloakService extends Keycloak {
47
47
  let attributesFromToken = token.keycloak_User.attributes
48
48
 
49
49
  if ( is2FAEnabled ) { // if 2FA is enabled then running the 2FA flow
50
- if ( !twoFAChannel || twoFAChannel == '' || ( twoFAChannel !== 'app' && twoFAChannel !== 'sms' ) ) {
50
+ if ( !twoFAChannel || twoFAChannel == '' || ( twoFAChannel !== 'app' && twoFAChannel !== 'sms' && twoFAChannel !== 'rsa' ) ) {
51
51
  return Promise.reject( { status: 400, error_message: 'twoFAChannel parameter is empty or invalid' } )
52
52
  }
53
53
 
@@ -59,25 +59,42 @@ class KeycloakService extends Keycloak {
59
59
  // checking if user attributes in keycloak exist or not to confirm 2FA registration
60
60
  if ( !attributesFromToken || !attributesFromToken.is2FARegistered || attributesFromToken.is2FARegistered == 'false' ) {
61
61
 
62
+ // getting admin access token to update the user attributes for RSA & Auht Apps
63
+ const adminData = await this.getAccessToken( keycloakConfig.USERNAME_ADMIN, keycloakConfig.PASSWORD_ADMIN );
64
+ const adminToken = adminData.access_token;
65
+
62
66
  // appending extra information regarding 2FA in response object
63
67
  tempToken.is2FARegistered = false
64
68
  tempToken.twoFAChannel = twoFAChannel
65
69
  tempToken.message = "2FA registration required"
66
70
 
71
+ // handling RSA authenticator scenario exclusively
72
+ if ( twoFAChannel === 'rsa' ) {
73
+
74
+ tempToken.is2FARegistered = true;
75
+ tempToken.message = "OTP required.";
76
+
77
+ //updating user attributes for RSA MFA
78
+ let newAttributes = {};
79
+ if ( attributesFromToken ) newAttributes = attributesFromToken;
80
+ newAttributes.twoFAChannel = "rsa";
81
+ newAttributes.is2FARegistered = true;
82
+
83
+ await this.updateUserAttributes( adminToken, token.keycloak_User.id, newAttributes );
84
+ }
85
+
67
86
  // if 2FA is required through authenticator app then performing necessary operation in keycloak user attributes
68
- if ( twoFAChannel == 'app' ) {
87
+ else if ( twoFAChannel == 'app' ) {
88
+
69
89
  // QR Code and Secret Code generation based on username
70
90
  const qrSetup = await this.getQRCode( user_name )
71
91
  if ( qrSetup ) {
92
+
72
93
  tempToken.otpSecret = qrSetup.secret
73
94
  tempToken.qrImage = qrSetup.image
74
95
  }
75
96
  else return Promise.reject( { error: 404, error_message: 'Error occurred while generating QR code.' } )
76
97
 
77
- // getting admin access token to update the user attributes
78
- const adminData = await this.getAccessToken( keycloakConfig.USERNAME_ADMIN, keycloakConfig.PASSWORD_ADMIN )
79
- const adminToken = adminData.access_token
80
-
81
98
  //updating user attributes for 2FA
82
99
  let newAttributes = {}
83
100
  if ( attributesFromToken ) newAttributes = attributesFromToken
@@ -88,11 +105,10 @@ class KeycloakService extends Keycloak {
88
105
  // saving the Secret Code into KeyCloak as user attribute to validate the OTP on each login
89
106
  await this.updateUserAttributes( adminToken, token.keycloak_User.id, newAttributes )
90
107
  }
91
- }
92
- else if ( attributesFromToken.is2FARegistered[ 0 ] == 'true' ) { // if user has already registered for 2FA
108
+ } else if ( attributesFromToken.is2FARegistered[ 0 ] == 'true' ) { // if user has already registered for 2FA
93
109
  tempToken.is2FARegistered = true
94
110
  tempToken.twoFAChannel = attributesFromToken.twoFAChannel[ 0 ]
95
- tempToken.message = "OTP required"
111
+ tempToken.message = "OTP required."
96
112
 
97
113
  if ( attributesFromToken.twoFAChannel[ 0 ] == 'sms' ) {
98
114
  if ( !attributesFromToken.phoneNumber ) {
@@ -257,7 +273,6 @@ class KeycloakService extends Keycloak {
257
273
  } );
258
274
  }
259
275
 
260
-
261
276
  // function for getting user details against user id (and extracting attributes)
262
277
  async getUserDetailsById( userId ) {
263
278
 
@@ -557,6 +572,47 @@ class KeycloakService extends Keycloak {
557
572
  }
558
573
  }
559
574
 
575
+ // running OTP validation flow for RSA Authenticator
576
+ else if ( userAttributes.twoFAChannel[ 0 ] === 'rsa' ) {
577
+ // setting up SecurID API for MFA
578
+ let URL = keycloakConfig.RSA_Server_URL + "mfa/v1_1/authn/initialize";
579
+
580
+ // configuring headers & payload
581
+ let config = {
582
+ method: "post",
583
+ url: URL,
584
+ headers: {
585
+ "Content-Type": "application/json",
586
+ "client-key": keycloakConfig.RSA_Client_Key,
587
+ },
588
+ data: {
589
+ clientId: keycloakConfig.RSA_Client_ID,
590
+ subjectName: username,
591
+ subjectCredentials: [
592
+ {
593
+ methodId: "SECURID",
594
+ collectedInputs: [ { name: "SECURID", value: otpToValidate } ],
595
+ },
596
+ ],
597
+ context: {
598
+ authnAttemptId: "",
599
+ messageId: username + "2faAttempt",
600
+ inResponseTo: "",
601
+ },
602
+ },
603
+ };
604
+
605
+ try {
606
+ let verificationStatus = await requestController.httpRequest( config, false );
607
+ if ( verificationStatus.status !== 200 || !verificationStatus.data || ( verificationStatus.data.attemptResponseCode !== 'SUCCESS' && verificationStatus.data.attemptReasonCode !== 'CREDENTIAL_VERIFIED' ) ) {
608
+ throw false
609
+ }
610
+ }
611
+ catch ( err ) {
612
+ return Promise.reject( { error: 400, error_message: "Error occured while verifying token from RSA SecurID. This may be due to invalid token, invalid configurations or some issue with SecurID." } )
613
+ }
614
+
615
+ }
560
616
  }
561
617
  else return Promise.reject( { error: 400, error_message: 'Error occurred while fetching user attributes.' } )
562
618
 
@@ -596,9 +652,9 @@ class KeycloakService extends Keycloak {
596
652
  data: {
597
653
  username: user_name,
598
654
  password: user_password,
599
- client_id: keycloakConfig.CLIENT_ID,
600
- client_secret: keycloakConfig.credentials.secret,
601
- grant_type: keycloakConfig.GRANT_TYPE,
655
+ client_id: keycloakConfig?.CLIENT_ID,
656
+ client_secret: keycloakConfig?.credentials?.secret,
657
+ grant_type: keycloakConfig?.GRANT_TYPE,
602
658
  },
603
659
 
604
660
  };
@@ -608,9 +664,10 @@ class KeycloakService extends Keycloak {
608
664
  // T.O.K.E.N R.E.Q.U.E.S.T # 1 ( P.E.R.M.I.S.S.I.O.N.S N.O.T I.N.C.L.U.D.E.D)
609
665
  let tokenResponse = await requestController.httpRequest( config, true );
610
666
 
611
- if ( tokenResponse.data.access_token ) {
667
+ if ( tokenResponse?.data?.access_token ) {
612
668
 
613
- token = tokenResponse.data.access_token;
669
+ token = tokenResponse?.data?.access_token;
670
+ refresh_token = tokenResponse?.data?.refresh_token;
614
671
 
615
672
  //To fetch introspect token to handle errors.
616
673
  let config_introspect = { ...config };
@@ -624,13 +681,13 @@ class KeycloakService extends Keycloak {
624
681
 
625
682
  let intro_token_response = await requestController.httpRequest( config_introspect, true );
626
683
 
627
- if ( Object.keys( intro_token_response.data ).length > 0 ) {
684
+ if ( Object.keys( intro_token_response?.data ).length > 0 ) {
628
685
 
629
686
  try {
630
687
 
631
688
  let config1 = { ...config };
632
- config1.data.username = keycloakConfig.USERNAME_ADMIN;
633
- config1.data.password = keycloakConfig.PASSWORD_ADMIN;
689
+ config1.data.username = keycloakConfig?.USERNAME_ADMIN;
690
+ config1.data.password = keycloakConfig?.PASSWORD_ADMIN;
634
691
  delete config1.data.token;
635
692
 
636
693
  config1.url = keycloakConfig[ "auth-server-url" ] + "realms/" + realm_name + "/protocol/openid-connect/token";
@@ -639,7 +696,7 @@ class KeycloakService extends Keycloak {
639
696
 
640
697
  if ( adminTokenResponse.data.access_token ) {
641
698
 
642
- let admin_token = adminTokenResponse.data.access_token;
699
+ let admin_token = adminTokenResponse?.data?.access_token;
643
700
 
644
701
  try {
645
702
 
@@ -655,18 +712,18 @@ class KeycloakService extends Keycloak {
655
712
  responseObject = {
656
713
 
657
714
  id: getuserDetails.data[ 0 ].id,
658
- firstName: getuserDetails.data[ 0 ].firstName ? getuserDetails.data[ 0 ].firstName : "",
659
- lastName: getuserDetails.data[ 0 ].lastName ? getuserDetails.data[ 0 ].lastName : "",
660
- username: getuserDetails.data[ 0 ].username,
661
- roles: ( 'realm_access' in intro_token_response.data && 'roles' in intro_token_response.data.realm_access ) ? intro_token_response.data.realm_access.roles : [],
715
+ firstName: getuserDetails?.data[ 0 ]?.firstName ? getuserDetails.data[ 0 ]?.firstName : "",
716
+ lastName: getuserDetails?.data[ 0 ]?.lastName ? getuserDetails.data[ 0 ]?.lastName : "",
717
+ username: getuserDetails?.data[ 0 ]?.username,
718
+ roles: ( 'realm_access' in intro_token_response.data && 'roles' in intro_token_response?.data?.realm_access ) ? intro_token_response?.data?.realm_access.roles : [],
662
719
  realm: realm_name,
663
720
 
664
721
  };
665
722
 
666
723
  //Adding user custom attribute to our token object data.
667
- if ( getuserDetails.data[ 0 ].attributes ) {
724
+ if ( getuserDetails?.data[ 0 ]?.attributes ) {
668
725
 
669
- responseObject.attributes = getuserDetails.data[ 0 ].attributes;
726
+ responseObject.attributes = getuserDetails?.data[ 0 ]?.attributes;
670
727
  } else {
671
728
 
672
729
  responseObject.attributes = {};
@@ -678,7 +735,7 @@ class KeycloakService extends Keycloak {
678
735
  //Fetching Groups data for each user.
679
736
  try {
680
737
 
681
- let teamData = await this.getUserSupervisedGroups( responseObject.id, admin_token, type );
738
+ let teamData = await this.getUserSupervisedGroups( responseObject?.id, responseObject?.username, admin_token, type, responseObject?.roles );
682
739
 
683
740
  //Check for Permission Groups assignment and roles assignment against them
684
741
  const checkUserRoleAndPermissions = this.checkUserRoleAndPermissions( teamData, responseObject );
@@ -696,8 +753,8 @@ class KeycloakService extends Keycloak {
696
753
 
697
754
  delete teamData.permissionGroups;
698
755
 
699
- responseObject.userTeam = teamData.userTeam;
700
- responseObject.supervisedTeams = teamData.supervisedTeams;
756
+ responseObject.userTeam = teamData?.userTeam;
757
+ responseObject.supervisedTeams = teamData?.supervisedTeams;
701
758
 
702
759
  } catch ( er ) {
703
760
 
@@ -752,15 +809,15 @@ class KeycloakService extends Keycloak {
752
809
  data: {
753
810
  username: user_name,
754
811
  password: user_password,
755
- client_id: keycloakConfig.CLIENT_ID,
756
- client_secret: keycloakConfig.credentials.secret,
757
- grant_type: keycloakConfig.GRANT_TYPE,
812
+ client_id: keycloakConfig?.CLIENT_ID,
813
+ client_secret: keycloakConfig.credentials?.secret,
814
+ grant_type: keycloakConfig?.GRANT_TYPE,
758
815
  },
759
816
 
760
817
  };
761
818
 
762
819
  config.data.grant_type = "urn:ietf:params:oauth:grant-type:uma-ticket";
763
- config.data.audience = keycloakConfig.CLIENT_ID;
820
+ config.data.audience = keycloakConfig?.CLIENT_ID;
764
821
  config.headers.Authorization = "Bearer " + token;
765
822
 
766
823
  // T.O.K.E.N R.E.Q.U.E.S.T # 2 (A.C.C.E.S.S T.O.K.E.N W.I.T.H P.E.R.M.I.S.S.I.O.N.S)
@@ -769,12 +826,11 @@ class KeycloakService extends Keycloak {
769
826
  let rptResponse = await requestController.httpRequest( config, true );
770
827
 
771
828
  if ( rptResponse.data.access_token ) {
772
- token = rptResponse.data.access_token;
773
- refresh_token = rptResponse.data.refresh_token;
829
+ let rpt_token = rptResponse?.data?.access_token;
774
830
 
775
831
  let userToken = token;
776
- config.data.grant_type = keycloakConfig.GRANT_TYPE;
777
- config.data.token = token;
832
+ config.data.grant_type = keycloakConfig?.GRANT_TYPE;
833
+ config.data.token = rpt_token;
778
834
  URL = URL + "/introspect";
779
835
  config.url = URL;
780
836
 
@@ -782,10 +838,10 @@ class KeycloakService extends Keycloak {
782
838
  try {
783
839
 
784
840
  let intrsopectionResponse = await requestController.httpRequest( config, true );
785
- intrsopectionResponse.data.access_token = token;
841
+ intrsopectionResponse.data.access_token = rpt_token;
786
842
 
787
843
  responseObject.permittedResources = {
788
- Resources: ( intrsopectionResponse.data.authorization.permissions.length > 0 ) ? intrsopectionResponse.data.authorization.permissions : []
844
+ Resources: ( intrsopectionResponse?.data?.authorization?.permissions?.length > 0 ) ? intrsopectionResponse?.data?.authorization?.permissions : []
789
845
  }
790
846
 
791
847
  // T.O.K.E.N R.E.Q.U.E.S.T # 4 ( A.D.M.I.N. T.O.K.E.N)
@@ -1709,7 +1765,7 @@ class KeycloakService extends Keycloak {
1709
1765
  } );
1710
1766
  }
1711
1767
 
1712
- async getUserSupervisedGroups( userId, adminToken, type ) {
1768
+ async getUserSupervisedGroups( userId, username, adminToken, type, roles ) {
1713
1769
 
1714
1770
  return new Promise( async ( resolve, reject ) => {
1715
1771
 
@@ -1734,7 +1790,7 @@ class KeycloakService extends Keycloak {
1734
1790
  try {
1735
1791
 
1736
1792
  let userTeams = await requestController.httpRequest( config, true );
1737
- const { userTeam, supervisedTeams } = userTeams.data;
1793
+ const { userTeam, supervisedTeams } = userTeams?.data;
1738
1794
 
1739
1795
  if ( Object.keys( userTeam ).length == 0 && type != 'CX' ) {
1740
1796
  reject( {
@@ -1746,15 +1802,27 @@ class KeycloakService extends Keycloak {
1746
1802
  } );
1747
1803
  }
1748
1804
 
1805
+ // Only add teams where user is actually supervisor
1806
+ const filteredSupervisedTeams = supervisedTeams.filter(
1807
+ team =>
1808
+ // Condition 1: Check if user is the primary supervisor
1809
+ team?.supervisor_Id === userId ||
1810
+ // Condition 2: Check if user is in the secondary supervisors array
1811
+ ( team?.secondarySupervisors || [] ).some( supervisor => supervisor?.username === username )
1812
+ );
1813
+
1749
1814
  team.userTeam = userTeam;
1750
- team.supervisedTeams = supervisedTeams;
1815
+ team.supervisedTeams = filteredSupervisedTeams;
1751
1816
 
1752
1817
  } catch ( er ) {
1753
1818
 
1754
- error = await errorService.handleError( er );
1819
+ if ( !roles.includes( "admin" ) ) {
1755
1820
 
1756
- // Log the error and proceed with default values
1757
- console.error( "User Team Fetch Error: An error occurred while fetching the user's team:", error );
1821
+ error = await errorService.handleError( er );
1822
+
1823
+ // Log the error and proceed with default values
1824
+ console.error( "User Team Fetch Error: An error occurred while fetching the user's team:", error );
1825
+ }
1758
1826
 
1759
1827
  }
1760
1828
 
@@ -1769,15 +1837,15 @@ class KeycloakService extends Keycloak {
1769
1837
 
1770
1838
  if ( userGroup.data.length != 0 ) {
1771
1839
 
1772
- let groups = userGroup.data;
1773
- let permissionGroups = groups.filter( group => group.name.includes( "_permission" ) );
1840
+ let groups = userGroup?.data;
1841
+ let permissionGroups = groups.filter( group => group?.name.includes( "_permission" ) );
1774
1842
 
1775
1843
  if ( permissionGroups.length > 0 ) {
1776
1844
 
1777
1845
  team.permissionGroups = [];
1778
1846
 
1779
1847
  permissionGroups.forEach( perGroup => {
1780
- team.permissionGroups.push( perGroup.name );
1848
+ team.permissionGroups.push( perGroup?.name );
1781
1849
  } );
1782
1850
  }
1783
1851
 
@@ -2759,13 +2827,12 @@ class KeycloakService extends Keycloak {
2759
2827
  } );
2760
2828
  }
2761
2829
 
2762
- //Create a Finesse user during login.
2763
2830
  async createUser( userObject, token ) {
2764
2831
 
2765
2832
  let assignRole = [];
2766
2833
  let assignGroups = [];
2767
2834
 
2768
- assignGroups = userObject.roles.includes( "supervisor" ) ? [ "agents_permission", "senior_agents_permission" ] : [ "agents_permission" ];
2835
+ assignGroups = userObject?.roles.includes( "supervisor" ) ? [ "agents_permission", "senior_agents_permission" ] : [ "agents_permission" ];
2769
2836
 
2770
2837
 
2771
2838
  return new Promise( async ( resolve, reject ) => {
@@ -2774,20 +2841,20 @@ class KeycloakService extends Keycloak {
2774
2841
 
2775
2842
  let data = {
2776
2843
 
2777
- username: userObject.username,
2778
- firstName: userObject.firstName,
2779
- lastName: userObject.lastName,
2844
+ username: userObject?.username,
2845
+ firstName: userObject?.firstName,
2846
+ lastName: userObject?.lastName,
2780
2847
  enabled: true,
2781
2848
  credentials: [
2782
2849
  {
2783
2850
  type: "password",
2784
- value: userObject.password,
2851
+ value: userObject?.password,
2785
2852
  temporary: false,
2786
2853
  },
2787
2854
  ],
2788
2855
  attributes: {
2789
- "user_name": `${userObject.loginName}`,
2790
- "extension": `${userObject.extension}`
2856
+ "user_name": `${userObject?.loginName}`,
2857
+ "extension": `${userObject?.extension}`
2791
2858
  },
2792
2859
  groups: assignGroups
2793
2860
  };
@@ -2809,18 +2876,18 @@ class KeycloakService extends Keycloak {
2809
2876
  let newUser = await requestController.httpRequest( config, false );
2810
2877
 
2811
2878
  //Get the user id at time of creation
2812
- let userLocation = newUser.headers.location;
2879
+ let userLocation = newUser?.headers?.location;
2813
2880
  let userLocationSplit = userLocation.split( "/" );
2814
- let userId = userLocationSplit[ userLocationSplit.length - 1 ];
2881
+ let userId = userLocationSplit[ userLocationSplit?.length - 1 ];
2815
2882
 
2816
2883
  //Get list of all the roles in keycloak realm
2817
2884
  /* Storing all the realm roles in Global realmRoles list.If some role come from finesse which doesn't
2818
2885
  exist in realmRoles list then we call keycloak roles api again to update realmRoles list. */
2819
- if ( userObject.roles != [] ) {
2886
+ if ( userObject?.roles != [] ) {
2820
2887
 
2821
2888
  if ( realmRoles.length > 0 ) {
2822
2889
 
2823
- let check = checkForMissingRole( realmRoles, userObject.roles );
2890
+ let check = checkForMissingRole( realmRoles, userObject?.roles );
2824
2891
 
2825
2892
  if ( !check ) {
2826
2893
 
@@ -2835,13 +2902,13 @@ class KeycloakService extends Keycloak {
2835
2902
  //checking whether role exist in realmRoles object array:
2836
2903
  for ( let role of realmRoles ) {
2837
2904
 
2838
- userObject.roles.forEach( ( userRole ) => {
2905
+ userObject?.roles?.forEach( ( userRole ) => {
2839
2906
 
2840
- if ( role.name == userRole.toLocaleLowerCase() ) {
2907
+ if ( role?.name == userRole.toLocaleLowerCase() ) {
2841
2908
 
2842
2909
  assignRole.push( {
2843
- id: role.id,
2844
- name: role.name,
2910
+ id: role?.id,
2911
+ name: role?.name,
2845
2912
  } );
2846
2913
  }
2847
2914
  } );
@@ -2865,7 +2932,7 @@ class KeycloakService extends Keycloak {
2865
2932
  }
2866
2933
 
2867
2934
 
2868
- let ciscoTeamId = userObject.group.id;
2935
+ let ciscoTeamId = userObject?.group?.id;
2869
2936
 
2870
2937
  //Check whether team of Agent already exists in CX Core or not
2871
2938
  let URL1 = `${keycloakConfig[ "ef-server-url" ]}team?ids=${ciscoTeamId}`;
@@ -2901,14 +2968,14 @@ class KeycloakService extends Keycloak {
2901
2968
  let createAgentCXTeam;
2902
2969
 
2903
2970
  //This means the team doesn't exist in CX Core. We need to create a team
2904
- if ( getAgentCXTeam.data.length == 0 ) {
2971
+ if ( getAgentCXTeam?.data.length == 0 ) {
2905
2972
 
2906
2973
  //Setting URL to Create CX team of Agent
2907
2974
  let URL2 = `${keycloakConfig[ "ef-server-url" ]}team`;
2908
2975
 
2909
2976
  let data = {
2910
- "team_Id": userObject.group.id,
2911
- "team_name": userObject.group.name,
2977
+ "team_Id": userObject?.group?.id,
2978
+ "team_name": userObject?.group?.name,
2912
2979
  "supervisor_Id": "",
2913
2980
  "source": "CISCO",
2914
2981
  "created_by": "1"
@@ -2940,10 +3007,10 @@ class KeycloakService extends Keycloak {
2940
3007
 
2941
3008
  let data = {
2942
3009
  "id": userId,
2943
- "username": userObject.username.toLocaleLowerCase(),
2944
- "firstName": userObject.firstName,
2945
- "lastName": userObject.lastName,
2946
- "roles": userObject.roles
3010
+ "username": userObject?.username.toLocaleLowerCase(),
3011
+ "firstName": userObject?.firstName,
3012
+ "lastName": userObject?.lastName,
3013
+ "roles": userObject?.roles
2947
3014
  }
2948
3015
 
2949
3016
  config2.url = URL3;
@@ -2965,11 +3032,11 @@ class KeycloakService extends Keycloak {
2965
3032
  }
2966
3033
 
2967
3034
  //Assign Agent to a team
2968
- let URL4 = `${keycloakConfig[ "ef-server-url" ]}team/${userObject.group.id}/member`;
3035
+ let URL4 = `${keycloakConfig[ "ef-server-url" ]}team/${userObject?.group?.id}/member`;
2969
3036
 
2970
3037
  data = {
2971
3038
  "type": "agent",
2972
- "usernames": [ userObject.username.toLocaleLowerCase() ]
3039
+ "usernames": [ userObject?.username.toLocaleLowerCase() ]
2973
3040
  }
2974
3041
 
2975
3042
  config2.url = URL4;
@@ -3004,11 +3071,11 @@ class KeycloakService extends Keycloak {
3004
3071
 
3005
3072
 
3006
3073
 
3007
- if ( userObject.roles.includes( "supervisor" ) && userObject.supervisedGroups.length > 0 ) {
3074
+ if ( userObject?.roles?.includes( "supervisor" ) && userObject?.supervisedGroups?.length > 0 ) {
3008
3075
 
3009
- for ( let supervisedGroup of userObject.supervisedGroups ) {
3076
+ for ( let supervisedGroup of userObject?.supervisedGroups ) {
3010
3077
 
3011
- let supervisorTeamId = supervisedGroup.id;
3078
+ let supervisorTeamId = supervisedGroup?.id;
3012
3079
 
3013
3080
  //Check whether team of Supervisor already exists in CX Core or not
3014
3081
  let URL5 = `${keycloakConfig[ "ef-server-url" ]}team?ids=${supervisorTeamId}`;
@@ -3020,14 +3087,14 @@ class KeycloakService extends Keycloak {
3020
3087
  let getSupervisorCXTeam = await requestController.httpRequest( config1, false );
3021
3088
 
3022
3089
  //This means the team doesn't exist in CX Core. We need to create a team
3023
- if ( getSupervisorCXTeam.data.length == 0 ) {
3090
+ if ( getSupervisorCXTeam?.data.length == 0 ) {
3024
3091
 
3025
3092
  //Creating or Updating Supervisor team in CX Core.
3026
3093
  let URL6 = `${keycloakConfig[ "ef-server-url" ]}team`;
3027
3094
 
3028
3095
  let data = {
3029
3096
  "team_Id": supervisorTeamId,
3030
- "team_name": supervisedGroup.name,
3097
+ "team_name": supervisedGroup?.name,
3031
3098
  "supervisor_Id": userId,
3032
3099
  "source": "CISCO",
3033
3100
  "created_by": "1"
@@ -3055,25 +3122,21 @@ class KeycloakService extends Keycloak {
3055
3122
 
3056
3123
  } else {
3057
3124
 
3058
- console.log( getSupervisorCXTeam.data[ 0 ].supervisor_Id );
3059
-
3060
3125
  //Adding this supervisor as Secondary Supervisor
3061
- if ( getSupervisorCXTeam.data[ 0 ].supervisor_Id != null ) {
3126
+ if ( getSupervisorCXTeam?.data[ 0 ]?.supervisor_Id != null ) {
3062
3127
 
3063
3128
  //Assign Secondary Supervisor to a team
3064
3129
  let URL7 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisorTeamId}/member`;
3065
3130
 
3066
3131
  data = {
3067
3132
  "type": "secondary-supervisor",
3068
- "usernames": [ userObject.username.toLocaleLowerCase() ]
3133
+ "usernames": [ userObject?.username.toLocaleLowerCase() ]
3069
3134
  }
3070
3135
 
3071
3136
  config2.method = 'post';
3072
3137
  config2.url = URL7;
3073
3138
  config2.data = data;
3074
3139
 
3075
- console.log( config2 );
3076
-
3077
3140
  try {
3078
3141
 
3079
3142
  //Assigning Secondary Supervisor to CX team
@@ -3096,7 +3159,7 @@ class KeycloakService extends Keycloak {
3096
3159
  let URL8 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisorTeamId}`;
3097
3160
 
3098
3161
  let data = {
3099
- "team_name": getSupervisorCXTeam.data[ 0 ].team_name,
3162
+ "team_name": getSupervisorCXTeam?.data[ 0 ]?.team_name,
3100
3163
  "supervisor_Id": userId
3101
3164
  }
3102
3165
 
@@ -3186,17 +3249,17 @@ class KeycloakService extends Keycloak {
3186
3249
 
3187
3250
  try {
3188
3251
 
3189
- let rptToken = await this.getTokenRPT( username, password, keycloakAuthToken.access_token );
3190
- let introspectToken = await this.getIntrospectToken( rptToken.access_token );
3252
+ let rptToken = await this.getTokenRPT( username, password, keycloakAuthToken?.access_token );
3253
+ let introspectToken = await this.getIntrospectToken( rptToken?.access_token );
3191
3254
 
3192
3255
  let keyObj = {
3193
- id: introspectToken.sub,
3194
- username: introspectToken.username,
3195
- firstName: introspectToken.given_name,
3196
- lastName: introspectToken.family_name,
3197
- roles: introspectToken.realm_access.roles,
3256
+ id: introspectToken?.sub,
3257
+ username: introspectToken?.username,
3258
+ firstName: introspectToken?.given_name,
3259
+ lastName: introspectToken?.family_name,
3260
+ roles: introspectToken?.realm_access?.roles,
3198
3261
  permittedResources: {
3199
- Resources: introspectToken.authorization.permissions,
3262
+ Resources: introspectToken?.authorization?.permissions,
3200
3263
  }
3201
3264
  }
3202
3265
 
@@ -3209,14 +3272,14 @@ class KeycloakService extends Keycloak {
3209
3272
  url: URL,
3210
3273
  headers: {
3211
3274
  "Content-Type": "application/json",
3212
- Authorization: `Bearer ${keycloakAdminToken.access_token}`,
3275
+ Authorization: `Bearer ${keycloakAdminToken?.access_token}`,
3213
3276
  }
3214
3277
  };
3215
3278
 
3216
3279
  try {
3217
3280
 
3218
3281
  let userDataResponse = await requestController.httpRequest( config, false );
3219
- userAttributes = userDataResponse.data.attributes;
3282
+ userAttributes = userDataResponse?.data?.attributes;
3220
3283
 
3221
3284
  } catch ( err ) {
3222
3285
 
@@ -3231,21 +3294,21 @@ class KeycloakService extends Keycloak {
3231
3294
  }
3232
3295
 
3233
3296
  //Comparing the basic info of Finesse User and Normal User.
3234
- if ( ( finObj.username ).toLowerCase() != keyObj.username
3235
- || finObj.firstName != keyObj.firstName
3236
- || finObj.lastName != keyObj.lastName
3237
- || ( userAttributes.user_name && finObj.loginName !== userAttributes.user_name[ 0 ] )
3238
- || ( userAttributes.extension && finObj.extension !== userAttributes.extension[ 0 ] )
3239
- || ( !userAttributes.user_name )
3297
+ if ( ( finObj?.username ).toLowerCase() != keyObj?.username
3298
+ || finObj?.firstName != keyObj?.firstName
3299
+ || finObj?.lastName != keyObj?.lastName
3300
+ || ( userAttributes?.user_name && finObj?.loginName !== userAttributes?.user_name[ 0 ] )
3301
+ || ( userAttributes?.extension && finObj?.extension !== userAttributes?.extension[ 0 ] )
3302
+ || ( !userAttributes?.user_name )
3240
3303
  ) {
3241
3304
 
3242
3305
  data = {
3243
- username: ( finObj.username ).toLowerCase(),
3244
- firstName: finObj.firstName,
3245
- lastName: finObj.lastName,
3306
+ username: ( finObj?.username ).toLowerCase(),
3307
+ firstName: finObj?.firstName,
3308
+ lastName: finObj?.lastName,
3246
3309
  attributes: {
3247
- "user_name": `${finObj.loginName}`,
3248
- "extension": `${finObj.extension}`
3310
+ "user_name": `${finObj?.loginName}`,
3311
+ "extension": `${finObj?.extension}`
3249
3312
  }
3250
3313
  };
3251
3314
  }
@@ -3281,40 +3344,40 @@ class KeycloakService extends Keycloak {
3281
3344
 
3282
3345
  //Role to Add to keycloak user during Update process.
3283
3346
  //rolesToAdd = finObj.roles.filter( role => !keyObj.roles.includes( role ) );
3284
- rolesToAdd = finObj.roles;
3347
+ rolesToAdd = finObj?.roles;
3285
3348
 
3286
3349
  //Role to Remove from keycloak user during Update process.
3287
3350
  let ignoreRoles = [ 'offline_access', 'uma_authorization' ];
3288
- rolesToRemove = keyObj.roles.filter( role => (
3289
- !finObj.roles.includes( role ) &&
3351
+ rolesToRemove = keyObj?.roles.filter( role => (
3352
+ !finObj?.roles.includes( role ) &&
3290
3353
  !ignoreRoles.includes( role ) &&
3291
3354
  role.indexOf( "default-roles" ) == -1 ) );
3292
3355
 
3293
3356
  //Updating group data in case it is not similar.
3294
- let finesseGroups = finObj.roles.includes( "supervisor" ) ? [ "agents_permission", "senior_agents_permission" ] : [ "agents_permission" ];
3357
+ let finesseGroups = finObj?.roles.includes( "supervisor" ) ? [ "agents_permission", "senior_agents_permission" ] : [ "agents_permission" ];
3295
3358
 
3296
3359
  try {
3297
3360
 
3298
- let token = keycloakAdminToken.access_token;
3361
+ let token = keycloakAdminToken?.access_token;
3299
3362
 
3300
3363
  let userGroups = await this.getKeycloakUserGroups( keyObj.id, token );
3301
3364
 
3302
3365
  keycloakGroups = userGroups.map( group => {
3303
3366
  return {
3304
- id: group.id,
3305
- name: group.name
3367
+ id: group?.id,
3368
+ name: group?.name
3306
3369
  }
3307
3370
  } );
3308
3371
 
3309
3372
  //find if senior_agents_permission group is assigned to user already against an agent role.
3310
- let isSeniorAgent = keycloakGroups.some( group => group.name == 'senior_agents_permission' );
3373
+ let isSeniorAgent = keycloakGroups.some( group => group?.name == 'senior_agents_permission' );
3311
3374
 
3312
- if ( isSeniorAgent && keyObj.roles.includes( 'agent' ) && !finesseGroups.includes( 'senior_agents_permission' ) ) {
3375
+ if ( isSeniorAgent && keyObj?.roles.includes( 'agent' ) && !finesseGroups.includes( 'senior_agents_permission' ) ) {
3313
3376
  finesseGroups.push( 'senior_agents_permission' );
3314
3377
  }
3315
3378
 
3316
- groupsToAdd = finesseGroups.filter( group => !keycloakGroups.find( keygroup => keygroup.name == group ) );
3317
- groupsToRemove = keycloakGroups.filter( group => !finesseGroups.includes( group.name ) );
3379
+ groupsToAdd = finesseGroups.filter( group => !keycloakGroups.find( keygroup => keygroup?.name == group ) );
3380
+ groupsToRemove = keycloakGroups.filter( group => !finesseGroups.includes( group?.name ) );
3318
3381
 
3319
3382
  //Adding and Removing Roles from Keycloak
3320
3383
  try {
@@ -3323,12 +3386,12 @@ class KeycloakService extends Keycloak {
3323
3386
  const rolesPromises = [];
3324
3387
 
3325
3388
  if ( rolesToAdd.length > 0 ) {
3326
- let addRolesPromise = this.addOrRemoveUserRole( keyObj.id, rolesToAdd, 'add', token );
3389
+ let addRolesPromise = this.addOrRemoveUserRole( keyObj?.id, rolesToAdd, 'add', token );
3327
3390
  rolesPromises.push( addRolesPromise );
3328
3391
  }
3329
3392
 
3330
3393
  if ( rolesToRemove.length > 0 ) {
3331
- let removeRolesPromise = this.addOrRemoveUserRole( keyObj.id, rolesToRemove, 'remove', token );
3394
+ let removeRolesPromise = this.addOrRemoveUserRole( keyObj?.id, rolesToRemove, 'remove', token );
3332
3395
  rolesPromises.push( removeRolesPromise );
3333
3396
  }
3334
3397
 
@@ -3343,16 +3406,16 @@ class KeycloakService extends Keycloak {
3343
3406
 
3344
3407
  //Fetching Ids of all the groups to add to current Keycloak User.
3345
3408
  groupsToAdd = await this.gettingGroupByGroupName( groupsToAdd, token );
3346
- await this.addOrRemoveUserGroup( keyObj.id, groupsToAdd, 'add', token );
3409
+ await this.addOrRemoveUserGroup( keyObj?.id, groupsToAdd, 'add', token );
3347
3410
  }
3348
3411
 
3349
3412
  if ( groupsToRemove.length > 0 ) {
3350
3413
 
3351
- await this.addOrRemoveUserGroup( keyObj.id, groupsToRemove, 'remove', token );
3414
+ await this.addOrRemoveUserGroup( keyObj?.id, groupsToRemove, 'remove', token );
3352
3415
  }
3353
3416
 
3354
3417
  //Checking Agent Case first, if agent team in CX is not same as agent team in finesse then update it
3355
- let userId = keyObj.id;
3418
+ let userId = keyObj?.id;
3356
3419
  let config1 = {
3357
3420
 
3358
3421
  method: "get",
@@ -3383,36 +3446,36 @@ class KeycloakService extends Keycloak {
3383
3446
 
3384
3447
  let userTeams = await requestController.httpRequest( config1, true );
3385
3448
 
3386
- const { userTeam, supervisedTeams } = userTeams.data;
3449
+ const { userTeam, supervisedTeams } = userTeams?.data;
3387
3450
 
3388
3451
  let supervisedTeamsFiltered = [];
3389
3452
 
3390
- if ( supervisedTeams.length > 0 ) {
3453
+ if ( supervisedTeams?.length > 0 ) {
3391
3454
 
3392
3455
  //Fetching list of all primary and seconday supervised teams of current user (Whether in CX or Cisco)
3393
3456
  supervisedTeamsFiltered = supervisedTeams.filter( team => {
3394
- const isPrimarySupervisor = team.supervisor.username.toLocaleLowerCase() === username.toLocaleLowerCase();
3395
- const isSecondarySupervisor = team.secondarySupervisors.some( secSupervisor => secSupervisor.username.toLocaleLowerCase() === username.toLocaleLowerCase() );
3457
+ const isPrimarySupervisor = team?.supervisor?.username?.toLocaleLowerCase() === username?.toLocaleLowerCase();
3458
+ const isSecondarySupervisor = team?.secondarySupervisors?.some( secSupervisor => secSupervisor?.username?.toLocaleLowerCase() === username?.toLocaleLowerCase() );
3396
3459
 
3397
3460
  return isPrimarySupervisor || isSecondarySupervisor;
3398
3461
  } ).map( team => {
3399
3462
  let type;
3400
- if ( team.supervisor.username.toLocaleLowerCase() === username.toLocaleLowerCase() ) {
3463
+ if ( team?.supervisor?.username?.toLocaleLowerCase() === username?.toLocaleLowerCase() ) {
3401
3464
  type = 'supervisor';
3402
- } else if ( team.secondarySupervisors.some( secSupervisor => secSupervisor.username.toLocaleLowerCase() === username.toLocaleLowerCase() ) ) {
3465
+ } else if ( team?.secondarySupervisors?.some( secSupervisor => secSupervisor?.username?.toLocaleLowerCase() === username?.toLocaleLowerCase() ) ) {
3403
3466
  type = 'secondary supervisor';
3404
3467
  }
3405
3468
 
3406
- return { teamId: team.teamId, teamName: team.teamName, type, source: team.source };
3469
+ return { teamId: team?.teamId, teamName: team?.teamName, type, source: team?.source };
3407
3470
  } );
3408
3471
  }
3409
3472
 
3410
3473
  //If Agent team in finesse is different from Agent Team in finesse
3411
- if ( finObj.group.id !== userTeam.teamId ) {
3474
+ if ( finObj?.group?.id !== userTeam?.teamId ) {
3412
3475
 
3413
3476
  //We have to both add agent to a team corresponding to Finesse and remove it from CX team.
3414
3477
  //Removing agent from CX team first
3415
- let URL3 = `${keycloakConfig[ "ef-server-url" ]}team/${userTeam.teamId}/member?type=agent&usernames=${finObj.username.toLowerCase()}`;
3478
+ let URL3 = `${keycloakConfig[ "ef-server-url" ]}team/${userTeam?.teamId}/member?type=agent&usernames=${finObj?.username?.toLowerCase()}`;
3416
3479
 
3417
3480
  config1.method = 'delete';
3418
3481
  config1.url = URL3;
@@ -3446,14 +3509,14 @@ class KeycloakService extends Keycloak {
3446
3509
  let createAgentCXTeam;
3447
3510
 
3448
3511
  //This means the team doesn't exist in CX Core. We need to create a team
3449
- if ( getAgentCXTeam.data.length == 0 ) {
3512
+ if ( getAgentCXTeam?.data?.length == 0 ) {
3450
3513
 
3451
3514
  //Setting URL to Create CX team of Agent
3452
3515
  let URL5 = `${keycloakConfig[ "ef-server-url" ]}team`;
3453
3516
 
3454
3517
  let data = {
3455
- "team_Id": finObj.group.id,
3456
- "team_name": finObj.group.name,
3518
+ "team_Id": finObj?.group?.id,
3519
+ "team_name": finObj?.group?.name,
3457
3520
  "supervisor_Id": "",
3458
3521
  "source": "CISCO",
3459
3522
  "created_by": "1"
@@ -3485,7 +3548,7 @@ class KeycloakService extends Keycloak {
3485
3548
 
3486
3549
  data = {
3487
3550
  "type": "agent",
3488
- "usernames": [ finObj.username.toLowerCase() ]
3551
+ "usernames": [ finObj?.username?.toLowerCase() ]
3489
3552
  }
3490
3553
 
3491
3554
  config2.url = URL6;
@@ -3520,16 +3583,16 @@ class KeycloakService extends Keycloak {
3520
3583
  }
3521
3584
 
3522
3585
  //If no team is assigned to supervise to current user in Cisco, remove its all supervised teams from CX
3523
- if ( !finObj.supervisedGroups && supervisedTeamsFiltered.length > 0 ) {
3586
+ if ( !finObj?.supervisedGroups && supervisedTeamsFiltered.length > 0 ) {
3524
3587
 
3525
3588
  for ( let supervisedTeam of supervisedTeamsFiltered ) {
3526
3589
 
3527
- if ( supervisedTeam.source === 'CISCO' ) {
3590
+ if ( supervisedTeam?.source === 'CISCO' ) {
3528
3591
 
3529
- if ( supervisedTeam.type === 'secondary supervisor' ) {
3592
+ if ( supervisedTeam?.type === 'secondary supervisor' ) {
3530
3593
 
3531
3594
  //Removing user from Secondary Supervisor in CX Core
3532
- let URL13 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam.teamId}/member?type=secondary-supervisor&usernames=${finObj.username.toLowerCase()}`;
3595
+ let URL13 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam.teamId}/member?type=secondary-supervisor&usernames=${finObj?.username?.toLowerCase()}`;
3533
3596
 
3534
3597
  config2.method = 'delete';
3535
3598
  config2.url = URL13;
@@ -3554,10 +3617,10 @@ class KeycloakService extends Keycloak {
3554
3617
  } else {
3555
3618
 
3556
3619
  //Removing user from Supervising team in CX Core or not
3557
- let URL7 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam.teamId}`;
3620
+ let URL7 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam?.teamId}`;
3558
3621
 
3559
3622
  let data = {
3560
- "team_name": supervisedTeam.teamName,
3623
+ "team_name": supervisedTeam?.teamName,
3561
3624
  "supervisor_Id": null
3562
3625
  }
3563
3626
 
@@ -3588,22 +3651,22 @@ class KeycloakService extends Keycloak {
3588
3651
 
3589
3652
  //Supervisor Case. Filtering out teams to add and teams to remove from Supervisor
3590
3653
  //First check that We have supervised Groups in finesse
3591
- if ( finObj.supervisedGroups ) {
3654
+ if ( finObj?.supervisedGroups ) {
3592
3655
 
3593
- let finesseSupervisedGroups = finObj.supervisedGroups;
3656
+ let finesseSupervisedGroups = finObj?.supervisedGroups;
3594
3657
 
3595
3658
  // Fetching All the ids of CX Supervised Teams of current Supervisor
3596
- const teamIdsInSupervisedTeams = new Set( supervisedTeamsFiltered.map( team => team.teamId ) );
3659
+ const teamIdsInSupervisedTeams = new Set( supervisedTeamsFiltered.map( team => team?.teamId ) );
3597
3660
 
3598
3661
  // Teams in which we need to add current user as Supervisor
3599
- const teamsToAddInCX = finesseSupervisedGroups.filter( item => !teamIdsInSupervisedTeams.has( item.id ) );
3662
+ const teamsToAddInCX = finesseSupervisedGroups.filter( item => !teamIdsInSupervisedTeams.has( item?.id ) );
3600
3663
 
3601
3664
  if ( teamsToAddInCX.length > 0 ) {
3602
3665
 
3603
3666
  //Adding current user as supervisor in all the given teamsToAddInCX teams.
3604
3667
  for ( let teamToAdd of teamsToAddInCX ) {
3605
3668
 
3606
- let supervisorTeamId = teamToAdd.id;
3669
+ let supervisorTeamId = teamToAdd?.id;
3607
3670
 
3608
3671
  //Check whether team of Supervisor already exists in CX Core or not
3609
3672
  let URL8 = `${keycloakConfig[ "ef-server-url" ]}team?ids=${supervisorTeamId}`;
@@ -3622,7 +3685,7 @@ class KeycloakService extends Keycloak {
3622
3685
 
3623
3686
  let data = {
3624
3687
  "team_Id": supervisorTeamId,
3625
- "team_name": teamToAdd.name,
3688
+ "team_name": teamToAdd?.name,
3626
3689
  "supervisor_Id": userId,
3627
3690
  "source": "CISCO",
3628
3691
  "created_by": "1"
@@ -3651,14 +3714,14 @@ class KeycloakService extends Keycloak {
3651
3714
  } else {
3652
3715
 
3653
3716
  //If the supervisor is already assigned to team, add current user as secondary supervisor.
3654
- if ( getSupervisorCXTeam.data[ 0 ].supervisor_Id != null ) {
3717
+ if ( getSupervisorCXTeam?.data[ 0 ]?.supervisor_Id != null ) {
3655
3718
 
3656
3719
  //Assign Agent to a team
3657
3720
  let URL10 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisorTeamId}/member`;
3658
3721
 
3659
3722
  data = {
3660
3723
  "type": "secondary-supervisor",
3661
- "usernames": [ finObj.username.toLowerCase() ]
3724
+ "usernames": [ finObj?.username?.toLowerCase() ]
3662
3725
  }
3663
3726
 
3664
3727
  config2.method = 'post';
@@ -3730,10 +3793,10 @@ class KeycloakService extends Keycloak {
3730
3793
 
3731
3794
 
3732
3795
  // Fetching All the ids of Finesse Supervised Teams of current Supervisor
3733
- const idsInFinesseSupervisedGroups = new Set( finesseSupervisedGroups.map( item => item.id ) );
3796
+ const idsInFinesseSupervisedGroups = new Set( finesseSupervisedGroups.map( item => item?.id ) );
3734
3797
 
3735
3798
  // Teams in which we need to remove current user as Supervisor
3736
- const teamsToRemoveFromCX = supervisedTeamsFiltered.filter( team => !idsInFinesseSupervisedGroups.has( team.teamId ) );
3799
+ const teamsToRemoveFromCX = supervisedTeamsFiltered.filter( team => !idsInFinesseSupervisedGroups.has( team?.teamId ) );
3737
3800
 
3738
3801
  //Removing teams that Supervisor is not supervising anymore in finesse.
3739
3802
  if ( teamsToRemoveFromCX.length > 0 ) {
@@ -3741,12 +3804,12 @@ class KeycloakService extends Keycloak {
3741
3804
  for ( let supervisedTeam of teamsToRemoveFromCX ) {
3742
3805
 
3743
3806
  //Only removing user from supervising teams that are from Cisco
3744
- if ( supervisedTeam.source === 'CISCO' ) {
3807
+ if ( supervisedTeam?.source === 'CISCO' ) {
3745
3808
 
3746
- if ( supervisedTeam.type === 'secondary supervisor' ) {
3809
+ if ( supervisedTeam?.type === 'secondary supervisor' ) {
3747
3810
 
3748
3811
  //Removing user from Secondary Supervisor in CX Core
3749
- let URL11 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam.teamId}/member?type=secondary-supervisor&usernames=${finObj.username.toLowerCase()}`;
3812
+ let URL11 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam?.teamId}/member?type=secondary-supervisor&usernames=${finObj?.username?.toLowerCase()}`;
3750
3813
 
3751
3814
  config2.method = 'delete';
3752
3815
  config2.url = URL11;
@@ -3771,10 +3834,9 @@ class KeycloakService extends Keycloak {
3771
3834
  } else {
3772
3835
 
3773
3836
  //Removing user from Supervising team in CX Core
3774
- let URL12 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam.teamId}`;
3775
-
3837
+ let URL12 = `${keycloakConfig[ "ef-server-url" ]}team/${supervisedTeam?.teamId}`;
3776
3838
  let data = {
3777
- "team_name": supervisedTeam.teamName,
3839
+ "team_name": supervisedTeam?.teamName,
3778
3840
  "supervisor_Id": null
3779
3841
  }
3780
3842