ef-keycloak-connect 1.4.1 → 1.5.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ef-keycloak-connect",
3
- "version": "1.4.1",
3
+ "version": "1.5.1",
4
4
  "description": "Node JS keycloak adapter for authentication and authorization.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -148,8 +148,8 @@ class KeycloakService extends Keycloak {
148
148
  let getuserDetails = await requestController.httpRequest(config, true);
149
149
  let responseObject = {
150
150
  'id': getuserDetails.data[0].id,
151
- 'firstName': getuserDetails.data[0].firstName,
152
- 'lastName': getuserDetails.data[0].lastName,
151
+ 'firstName': getuserDetails.data[0].firstName ? getuserDetails.data[0].firstName : '',
152
+ 'lastName': getuserDetails.data[0].lastName ? getuserDetails.data[0].lastName : '',
153
153
  'username': getuserDetails.data[0].username,
154
154
  'permittedResources': {
155
155
  'Resources': intrsopectionResponse.data.authorization.permissions
@@ -184,11 +184,21 @@ class KeycloakService extends Keycloak {
184
184
  resolve(finalObject);
185
185
 
186
186
  } catch (error) {
187
- reject("Error while fetching Groups of User in Auth Process" + error);
187
+ console.log("Error while fetching Groups of User in Auth Process ");
188
+ reject(error);
188
189
  }
189
190
  }
190
191
  catch (error) {
191
- reject("Get all users request not sent" + error);
192
+
193
+ if (error.response) {
194
+ reject({
195
+ error: 'Error while fetching the User Details during Login Process',
196
+ status: error.response.status,
197
+ errorMessage: error.response.data
198
+ });
199
+ }
200
+
201
+ reject("Error while fetching the User Details during Login Process " + error);
192
202
  }
193
203
  }
194
204
  else {
@@ -197,25 +207,61 @@ class KeycloakService extends Keycloak {
197
207
  }
198
208
  }
199
209
  catch (error) {
200
- reject("Admin Request not sent" + error);
210
+
211
+ if (error.response) {
212
+ reject({
213
+ error: 'Error while generating Admin Access Token',
214
+ status: error.response.status,
215
+ errorMessage: error.response.data
216
+ });
217
+ }
218
+
219
+ reject("Error while generating Admin Access Token " + error);
201
220
  }
202
221
  }
203
222
  catch (error) {
204
- reject(error);
223
+ if (error.response) {
224
+ reject({
225
+ error: 'Error while fetching Introspect token',
226
+ status: error.response.status,
227
+ errorMessage: error.response.data
228
+ });
229
+ }
230
+
231
+ reject("Error while fetching Introspect token " + error);
205
232
  }
206
233
  } else {
207
234
  reject("RPT Request Failed");
208
235
  }
209
236
  } catch (error) {
210
- reject(error);
237
+
238
+ if (error.response) {
239
+ reject({
240
+ error: 'Error while fetching RPT token, Please make sure all required Permissions & ' +
241
+ 'Groups are assigned to User. For example, user with role agent must be assigned agents_permission group & all required permissions are created',
242
+ status: error.response.status,
243
+ errorMessage: error.response.data
244
+ });
245
+ }
246
+
247
+ reject("Error while fetching RPT token " + error);
211
248
  }
212
249
  }
213
250
  else {
214
251
  reject("Access Token Request Failed");
215
252
  }
216
253
  }
217
- catch (er) {
218
- reject(er);
254
+ catch (error) {
255
+
256
+ if (error.response) {
257
+ reject({
258
+ error: 'Error while generating Access Token',
259
+ status: error.response.status,
260
+ errorMessage: error.response.data
261
+ });
262
+ }
263
+
264
+ reject("Error while generating Access Token " + error);
219
265
  }
220
266
  });
221
267
  }
@@ -679,42 +725,49 @@ class KeycloakService extends Keycloak {
679
725
 
680
726
  let filteredTeams = groups.filter(group => !group.name.includes('_permission'));
681
727
 
728
+ if (filteredTeams.length > 0) {
682
729
 
683
- userTeam = {
684
- 'teamId': filteredTeams[0].id,
685
- 'teamName': filteredTeams[0].name
686
- }
730
+ userTeam = {
731
+ 'teamId': filteredTeams[0].id,
732
+ 'teamName': filteredTeams[0].name
733
+ }
687
734
 
688
- team.userTeam = userTeam;
735
+ team.userTeam = userTeam;
689
736
 
690
- config.method = 'get';
691
- delete config.data;
692
- delete config.url;
737
+ config.method = 'get';
738
+ delete config.data;
739
+ delete config.url;
693
740
 
694
- let URL3 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups';
695
- config.url = URL3;
696
- config.headers.Authorization = 'Bearer ' + token;
741
+ let URL3 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups';
742
+ config.url = URL3;
743
+ config.headers.Authorization = 'Bearer ' + token;
697
744
 
698
- try {
745
+ try {
699
746
 
700
- let allGroups = await requestController.httpRequest(config, true);
747
+ let allGroups = await requestController.httpRequest(config, true);
701
748
 
702
- for (let group of allGroups.data) {
749
+ for (let group of allGroups.data) {
703
750
 
704
- let result = await teamsService.getGroupByGroupID(group.id, username, token, keycloakConfig);
751
+ let result = await teamsService.getGroupByGroupID(group.id, username, token, keycloakConfig);
705
752
 
706
- if (result && !result.teamName.includes('_permission')) {
707
- supervisedTeams.push(result);
708
- }
709
- };
753
+ if (result && !result.teamName.includes('_permission')) {
754
+ supervisedTeams.push(result);
755
+ }
756
+ };
710
757
 
711
- team.supervisedTeams = supervisedTeams;
712
- resolve(team);
758
+ team.supervisedTeams = supervisedTeams;
759
+ resolve(team);
713
760
 
714
- } catch (er) {
761
+ } catch (er) {
715
762
 
716
- error = await this.checkErrorType(er);
717
- reject(error);
763
+ error = await this.checkErrorType(er);
764
+ reject(error);
765
+ }
766
+ } else {
767
+ reject({
768
+ status: 403,
769
+ errorMessage: 'No Teams group assigned to User, please assign one Team to user. If user has no team then assign it default group.'
770
+ });
718
771
  }
719
772
  } else {
720
773
 
@@ -913,6 +966,166 @@ class KeycloakService extends Keycloak {
913
966
 
914
967
  }
915
968
 
969
+ //function to be used only in teams implementation. We give the list of ids of groups and it returns all its members and supervisors
970
+ async getGroupMembers(groupIds) {
971
+
972
+ return new Promise(async (resolve, reject) => {
973
+
974
+ let token;
975
+ let groupsData = [];
976
+ var URL = keycloakConfig["auth-server-url"] + 'realms/' + keycloakConfig.realm + '/protocol/openid-connect/token';
977
+
978
+ var config = {
979
+ method: 'post',
980
+ url: URL,
981
+ headers: {
982
+ 'Accept': 'application/json',
983
+ 'cache-control': 'no-cache',
984
+ 'Content-Type': 'application/x-www-form-urlencoded'
985
+ },
986
+ data: {
987
+ client_id: keycloakConfig.CLIENT_ID,
988
+ username: keycloakConfig.USERNAME_ADMIN,
989
+ password: keycloakConfig.PASSWORD_ADMIN,
990
+ grant_type: keycloakConfig.GRANT_TYPE,
991
+ client_secret: keycloakConfig.credentials.secret
992
+ }
993
+ };
994
+
995
+ try {
996
+
997
+ let adminTokenResponse = await requestController.httpRequest(config, true);
998
+ token = adminTokenResponse.data.access_token;
999
+
1000
+ if (groupIds.length > 0) {
1001
+
1002
+ config.method = 'get';
1003
+ delete config.data;
1004
+ delete config.url;
1005
+ config.headers.Authorization = 'Bearer ' + token;
1006
+
1007
+
1008
+ for (let i = 0; i < groupIds.length; i++) {
1009
+
1010
+ try {
1011
+
1012
+ let groupData = {};
1013
+
1014
+ let URL2 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups/' + groupIds[i] + '/';
1015
+ config.url = URL2;
1016
+ let groupInfo = await requestController.httpRequest(config, true);
1017
+
1018
+ groupData.teamId = groupInfo.data.id;
1019
+ groupData.teamName = groupInfo.data.name;
1020
+
1021
+ if (Object.keys(groupInfo.data.attributes).length == 0) {
1022
+
1023
+ groupData.supervisors = [];
1024
+ } else {
1025
+
1026
+ let attributes = groupInfo.data.attributes;
1027
+
1028
+ if ('supervisor' in attributes) {
1029
+
1030
+ let supervisorList = attributes['supervisor'][0].split(",");
1031
+ let supervisors = [];
1032
+
1033
+ for (let j = 0; j < supervisorList.length; j++) {
1034
+
1035
+ let URL3 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/users?username=' + supervisorList[j] + '&exact=true';
1036
+ config.url = URL3;
1037
+
1038
+
1039
+ try {
1040
+
1041
+ let supervisorUser = await requestController.httpRequest(config, true);
1042
+
1043
+ if (supervisorUser.data.length > 0) {
1044
+ supervisors.push({
1045
+ supervisorId: supervisorUser.data[0].id,
1046
+ supervisorName: supervisorUser.data[0].username
1047
+ })
1048
+ }
1049
+ } catch (err) {
1050
+ if (err.response) {
1051
+ reject({
1052
+ status: err.response.status,
1053
+ errorMessage: err.response.data
1054
+ });
1055
+ }
1056
+
1057
+ reject(err);
1058
+
1059
+ }
1060
+ }
1061
+
1062
+ groupData.supervisors = supervisors;
1063
+
1064
+ }
1065
+
1066
+ }
1067
+
1068
+ let URL4 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups/' + groupIds[i] + '/members';
1069
+ config.url = URL4;
1070
+ let users = await requestController.httpRequest(config, true);
1071
+
1072
+
1073
+ if (users.data.length > 0) {
1074
+
1075
+ let agents = users.data;
1076
+ agents = agents.map(agent => {
1077
+ return {
1078
+ agentId: agent.id,
1079
+ agentName: agent.username
1080
+ }
1081
+ });
1082
+
1083
+ groupData.agents = agents;
1084
+
1085
+ } else {
1086
+ groupData.agents = [];
1087
+ }
1088
+
1089
+ groupsData.push(groupData);
1090
+
1091
+ } catch (err) {
1092
+
1093
+ if (err.response) {
1094
+ reject({
1095
+ status: err.response.status,
1096
+ errorMessage: err.response.data
1097
+ });
1098
+ }
1099
+
1100
+ reject(err);
1101
+
1102
+ }
1103
+
1104
+ }
1105
+
1106
+ resolve(groupsData);
1107
+ }
1108
+
1109
+ resolve([]);
1110
+
1111
+ } catch (err) {
1112
+
1113
+ if (err.response) {
1114
+ reject({
1115
+ status: err.response.status,
1116
+ errorMessage: err.response.data
1117
+ });
1118
+ }
1119
+
1120
+ reject(err);
1121
+
1122
+ }
1123
+
1124
+ });
1125
+
1126
+ }
1127
+
1128
+
916
1129
  // this function requires comma separated list of roles in parameter e.g ["robot","human","customer"];
917
1130
  getUsersByRole(keycloak_roles) {
918
1131
  return new Promise(async (resolve, reject) => {
@@ -1060,10 +1273,16 @@ class KeycloakService extends Keycloak {
1060
1273
 
1061
1274
  }
1062
1275
  catch (err) {
1063
- reject({
1064
- "status": err.response.status,
1065
- "message": err.response.data.error_description
1066
- });
1276
+
1277
+ if (err.response) {
1278
+ reject({
1279
+ "status": err.response.status,
1280
+ "message": err.response.data
1281
+ });
1282
+ }
1283
+
1284
+ reject('Error while assignment of roles to User: ' + err);
1285
+
1067
1286
  }
1068
1287
 
1069
1288
  });
@@ -1073,14 +1292,14 @@ class KeycloakService extends Keycloak {
1073
1292
  async createUser(username, password, token, userRoles) {
1074
1293
 
1075
1294
  let assignRole = [];
1076
- let assignGroups = ['agents_permission', 'default'];
1295
+ let assignGroups = userRoles.includes('supervisor') ? ["agents_permission", "default", "senior_agents_permission"] : ["agents_permission", "default"];
1077
1296
 
1078
1297
  return new Promise(async (resolve, reject) => {
1079
1298
 
1080
1299
 
1081
1300
  for (let group of assignGroups) {
1082
1301
 
1083
- let URL2 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups?search=' + group;
1302
+ let URL2 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups?search=' + group + '&exact=true';
1084
1303
 
1085
1304
  let config1 = {
1086
1305
  method: 'get',
@@ -1100,10 +1319,16 @@ class KeycloakService extends Keycloak {
1100
1319
 
1101
1320
  }
1102
1321
  } catch (err) {
1103
- reject({
1104
- "status": err.response.status,
1105
- "message": err.response.data.error_description
1106
- });
1322
+
1323
+ if (err.response) {
1324
+ reject({
1325
+ "status": err.response.status,
1326
+ "message": err.response.data
1327
+ });
1328
+ }
1329
+
1330
+ reject('Error while fetching group against group-name: ' + err);
1331
+
1107
1332
  }
1108
1333
 
1109
1334
  }
@@ -1121,7 +1346,7 @@ class KeycloakService extends Keycloak {
1121
1346
  temporary: false
1122
1347
  }
1123
1348
  ],
1124
- groups: ["agents_permission", "default"]
1349
+ groups: assignGroups
1125
1350
  }
1126
1351
 
1127
1352
  let config = {
@@ -1163,12 +1388,24 @@ class KeycloakService extends Keycloak {
1163
1388
  });
1164
1389
  }
1165
1390
 
1166
- //assigning role to user
1167
- let roleAssigned = await this.assignRoleToUser(userId, assignRole, token);
1391
+ try {
1392
+ //assigning role to user
1393
+ let roleAssigned = await this.assignRoleToUser(userId, assignRole, token);
1394
+
1395
+ //Role assigned with status
1396
+ //Role assigned with status
1397
+ //Role assigned with status
1398
+ if (roleAssigned.status == 204) {
1399
+ resolve(tokenResponse);
1400
+ }
1401
+ } catch (err) {
1402
+
1403
+ if (err.status) {
1404
+ reject(err);
1405
+ }
1406
+
1407
+ reject('Error while Assignment of role to user: ' + err);
1168
1408
 
1169
- //Role assigned with status
1170
- if (roleAssigned.status == 204) {
1171
- resolve(tokenResponse);
1172
1409
  }
1173
1410
 
1174
1411
  } else {
@@ -1180,10 +1417,15 @@ class KeycloakService extends Keycloak {
1180
1417
 
1181
1418
  }
1182
1419
  catch (err) {
1183
- reject({
1184
- "status": err.response.status,
1185
- "message": err.response.data.error_description
1186
- });
1420
+
1421
+ if (err.response) {
1422
+ reject({
1423
+ "status": err.response.status,
1424
+ "message": err.response.data
1425
+ });
1426
+ }
1427
+
1428
+ reject('Error while Creation of User: ' + err);
1187
1429
  }
1188
1430
 
1189
1431
  });
@@ -1508,17 +1750,17 @@ class KeycloakService extends Keycloak {
1508
1750
 
1509
1751
  } catch (err) {
1510
1752
 
1511
- if (err.response.status == 401) {
1512
-
1513
- console.log("User doesn't exist in Keycloak, syncing finesse user in keycloak...");
1753
+ if (err.status) {
1514
1754
 
1515
- } else {
1755
+ if (err.status == 401) {
1516
1756
 
1517
- throw ({
1518
- "status": err.response.status,
1519
- "message": err.response.data.error_description
1520
- });
1757
+ console.log("User doesn't exist in Keycloak, syncing finesse user in keycloak...");
1758
+ } else {
1759
+ throw (err);
1760
+ }
1521
1761
 
1762
+ } else {
1763
+ throw ("Error while fetching keycloak User token: " + err);
1522
1764
  }
1523
1765
 
1524
1766
  } finally {
@@ -1540,10 +1782,12 @@ class KeycloakService extends Keycloak {
1540
1782
  });
1541
1783
 
1542
1784
  } else {
1543
- throw ({
1544
- "status": err.response.status,
1545
- "message": "Error While getting Keycloak admin token: " + err.response.data.error_description
1546
- });
1785
+
1786
+ if (err.status) {
1787
+ throw (err);
1788
+ }
1789
+
1790
+ throw ("Error While getting Keycloak admin token: " + err);
1547
1791
  }
1548
1792
 
1549
1793
  }
@@ -1586,12 +1830,11 @@ class KeycloakService extends Keycloak {
1586
1830
 
1587
1831
  } else {
1588
1832
 
1589
- console.log(err);
1833
+ if (err.status) {
1834
+ throw (err);
1835
+ }
1590
1836
 
1591
- throw ({
1592
- "status": err.response.status,
1593
- "message": "Error While creating Keycloak user: " + err.response.data.error_description
1594
- });
1837
+ throw ("Error While creating Keycloak user: " + err);
1595
1838
  }
1596
1839
  }
1597
1840
  }
@@ -1667,10 +1910,14 @@ class KeycloakService extends Keycloak {
1667
1910
 
1668
1911
  } else {
1669
1912
 
1670
- return ({
1671
- "status": err.response.status,
1672
- "message": "Error: " + err.response.data.error_description
1673
- });
1913
+ if (err.response) {
1914
+ return ({
1915
+ status: error.response.status,
1916
+ errorMessage: error.response.data
1917
+ });
1918
+ }
1919
+
1920
+ return (err);
1674
1921
  }
1675
1922
  }
1676
1923