ef-keycloak-connect 1.3.0 → 1.3.2
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 +26 -0
- package/package.json +1 -1
- package/services/keycloakService.js +128 -3
- package/services/teamsService.js +2 -1
package/README.md
CHANGED
|
@@ -332,5 +332,31 @@ It takes 5 arguments:
|
|
|
332
332
|
##### Example of non SSO Finesse Auth:
|
|
333
333
|
|
|
334
334
|
authenticateFinesse('johndoe', '12345', `https://${finesse_server_url}:${port}`, ['agent','supervisor'], '')
|
|
335
|
+
|
|
336
|
+
### generateAccessTokenFromRefreshToken(refreshToken)
|
|
337
|
+
|
|
338
|
+
This function generates a new access_token by using the refreshToken received in parameter.
|
|
339
|
+
|
|
340
|
+
It takes a signle argument:
|
|
341
|
+
|
|
342
|
+
- refreshToken: Refresh Token is used to generate the new access token.
|
|
343
|
+
|
|
344
|
+
Response:
|
|
345
|
+
|
|
346
|
+
- If the refresh token is valid then a new access token is returned in reponse along with status code 200.
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
{
|
|
350
|
+
"status": 200,
|
|
351
|
+
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqeEMzZDV5VVZRS1ktY3MwSmhQd29DVzllNjB0VkFPQXBIUDlWUlhsejdBIn0.eyJleHAiOjE2NzgyNzIzNDEsImlhdCI6MTY3ODI3MjEwNSwianRpIjoiNWVkMDBiYzgtNDM1MC00MjQ2LTllOTEtYjE4ZGIyMzc5YTI2IiwiaXNzIjoiaHR0cDovLzE5Mi4xNjguMS4yMDQ6ODA4MC9hdXRoL3JlYWxtcy9EZW1vLUtleWNsb2FrLVJlYWxtIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjY5OGRkYWFkLTZkZTYtNDY1YS04Mjg1LTQ4MWI5NjZjMmYxNiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImRlbW8ta2V5Y2xvYWstY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6ImM2NTNmNDk5LWJlNzMtNDIyNS05MGU4LThkYjBjNDkwYTc5MCIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1kZW1vLWtleWNsb2FrLXJlYWxtIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImFnZW50LXJvbGUiXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJhdXRob3JpemF0aW9uIjp7InBlcm1pc3Npb25zIjpbeyJyc2lkIjoiNDBhNzg1MjYtNjNiNy00NDcwLThkZWEtZjRlZDViNTUwOTUzIiwicnNuYW1lIjoiRGVmYXVsdCBSZXNvdXJjZSJ9XX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6ImM2NTNmNDk5LWJlNzMtNDIyNS05MGU4LThkYjBjNDkwYTc5MCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6InphcnlhYiByYXphIiwiYWdlbnRFeHRlbnNpb24iOiI4MDgxLDYwMDEiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ6YXJ5YWIgcmF6YSIsImdpdmVuX25hbWUiOiJ6YXJ5YWIiLCJmYW1pbHlfbmFtZSI6InJhemEiLCJlbWFpbCI6InphcnlhYkBlbWFpbC5jb20ifQ.Y8NVa0OzAPBwtb6cGyhZxMEyv-o_nTA9ZcvXNcmcEMivqTT0dTE95yNKXYxUQuhTAWE6mPJDwuZ0GuEco7hhxQ6IjjH2j0QwjvqEFFi7KNNdIi-yS4q0elNCjxar8zkHY3Gy8a2d7C_9CQuBN-ernV-JYcmGHENlpmJJpyHfZ5aNkzrcHN5b9qDx2-YZm8pkgFuUv8bwogFFeECzclOlrSGHmaiOI1gp2jkUIw8q23LB8YvzdVg5aHgSDcTKD4gXRrG7C_OQRbCmycOtW4iECLlURnlbbF5Rq4vxzrHjRtBAQmVZ86ITP7yDqEPOWfIxHjODDWWHNL2r7dK8OhNK_g"
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
- If the refresh token is invalid then an error message is returned in reponse along with status code 400.
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
{
|
|
358
|
+
"status": 400,
|
|
359
|
+
"message": "Refresh Token expired, please login again"
|
|
360
|
+
}
|
|
335
361
|
|
|
336
362
|
|
package/package.json
CHANGED
|
@@ -81,6 +81,7 @@ class KeycloakService extends Keycloak {
|
|
|
81
81
|
|
|
82
82
|
return new Promise(async (resolve, reject) => {
|
|
83
83
|
let token;
|
|
84
|
+
let refresh_token;
|
|
84
85
|
var URL = keycloakConfig["auth-server-url"] + 'realms/' + realm_name + '/protocol/openid-connect/token'
|
|
85
86
|
//keycloakConfig["auth-server-url"] +'realms
|
|
86
87
|
let config = {
|
|
@@ -114,6 +115,8 @@ class KeycloakService extends Keycloak {
|
|
|
114
115
|
var rptResponse = await requestController.httpRequest(config, true);
|
|
115
116
|
if (rptResponse.data.access_token) {
|
|
116
117
|
token = rptResponse.data.access_token;
|
|
118
|
+
refresh_token = rptResponse.data.refresh_token;
|
|
119
|
+
|
|
117
120
|
var userToken = token;
|
|
118
121
|
config.data.grant_type = keycloakConfig.GRANT_TYPE;
|
|
119
122
|
config.data.token = token;
|
|
@@ -158,6 +161,8 @@ class KeycloakService extends Keycloak {
|
|
|
158
161
|
//Adding user custom attribute to our token object data.
|
|
159
162
|
if (getuserDetails.data[0].attributes) {
|
|
160
163
|
responseObject.attributes = getuserDetails.data[0].attributes;
|
|
164
|
+
} else {
|
|
165
|
+
responseObject.attributes = {};
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
delete config.headers.Authorization;
|
|
@@ -172,6 +177,7 @@ class KeycloakService extends Keycloak {
|
|
|
172
177
|
|
|
173
178
|
let finalObject = {
|
|
174
179
|
'token': userToken,
|
|
180
|
+
'refresh_token': refresh_token,
|
|
175
181
|
'keycloak_User': responseObject
|
|
176
182
|
}
|
|
177
183
|
resolve(finalObject);
|
|
@@ -1061,9 +1067,42 @@ class KeycloakService extends Keycloak {
|
|
|
1061
1067
|
async createUser(username, password, token, userRoles) {
|
|
1062
1068
|
|
|
1063
1069
|
let assignRole = [];
|
|
1070
|
+
let assignGroups = ['agents', 'default'];
|
|
1064
1071
|
|
|
1065
1072
|
return new Promise(async (resolve, reject) => {
|
|
1066
1073
|
|
|
1074
|
+
|
|
1075
|
+
for (let group of assignGroups) {
|
|
1076
|
+
|
|
1077
|
+
let URL2 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups?search=' + group;
|
|
1078
|
+
|
|
1079
|
+
let config1 = {
|
|
1080
|
+
method: 'get',
|
|
1081
|
+
url: URL2,
|
|
1082
|
+
headers: {
|
|
1083
|
+
'Content-Type': 'application/json',
|
|
1084
|
+
'Authorization': `Bearer ${token}`
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
try {
|
|
1089
|
+
let groupData = await requestController.httpRequest(config1, true);
|
|
1090
|
+
|
|
1091
|
+
if (groupData.data.length == 0) {
|
|
1092
|
+
|
|
1093
|
+
let createdGroup = await this.createGroup(token, group);
|
|
1094
|
+
|
|
1095
|
+
}
|
|
1096
|
+
} catch (err) {
|
|
1097
|
+
reject({
|
|
1098
|
+
"status": err.response.status,
|
|
1099
|
+
"message": err.response.data.error_description
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
|
|
1067
1106
|
let URL = `${keycloakConfig["auth-server-url"]}${keycloakConfig["USERNAME_ADMIN"]}/realms/${keycloakConfig["realm"]}/users`;
|
|
1068
1107
|
|
|
1069
1108
|
let data = {
|
|
@@ -1075,11 +1114,10 @@ class KeycloakService extends Keycloak {
|
|
|
1075
1114
|
value: password,
|
|
1076
1115
|
temporary: false
|
|
1077
1116
|
}
|
|
1078
|
-
]
|
|
1117
|
+
],
|
|
1118
|
+
groups: ["agents", "default"]
|
|
1079
1119
|
}
|
|
1080
1120
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
1121
|
let config = {
|
|
1084
1122
|
method: 'post',
|
|
1085
1123
|
url: URL,
|
|
@@ -1145,6 +1183,43 @@ class KeycloakService extends Keycloak {
|
|
|
1145
1183
|
});
|
|
1146
1184
|
}
|
|
1147
1185
|
|
|
1186
|
+
async createGroup(adminToken, groupName) {
|
|
1187
|
+
|
|
1188
|
+
return new Promise(async (resolve, reject) => {
|
|
1189
|
+
|
|
1190
|
+
let URL = `${keycloakConfig["auth-server-url"]}${keycloakConfig["USERNAME_ADMIN"]}/realms/${keycloakConfig["realm"]}/groups`;
|
|
1191
|
+
|
|
1192
|
+
let data = {
|
|
1193
|
+
name: groupName
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
let config = {
|
|
1198
|
+
method: 'post',
|
|
1199
|
+
url: URL,
|
|
1200
|
+
headers: {
|
|
1201
|
+
'Authorization': `Bearer ${adminToken}`
|
|
1202
|
+
},
|
|
1203
|
+
data: data
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1206
|
+
try {
|
|
1207
|
+
|
|
1208
|
+
let createdGroup = await requestController.httpRequest(config, false);
|
|
1209
|
+
resolve(createdGroup.data);
|
|
1210
|
+
|
|
1211
|
+
}
|
|
1212
|
+
catch (err) {
|
|
1213
|
+
reject({
|
|
1214
|
+
"status": err.response.status,
|
|
1215
|
+
"message": err.response.data.error_description
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1148
1223
|
//Authenticating Finesse User
|
|
1149
1224
|
async authenticateFinesse(username, password, finesseUrl, userRoles, finesseToken) {
|
|
1150
1225
|
|
|
@@ -1272,6 +1347,56 @@ class KeycloakService extends Keycloak {
|
|
|
1272
1347
|
}
|
|
1273
1348
|
}
|
|
1274
1349
|
|
|
1350
|
+
async generateAccessTokenFromRefreshToken(refreshToken) {
|
|
1351
|
+
|
|
1352
|
+
return new Promise(async (resolve, reject) => {
|
|
1353
|
+
let accessToken;
|
|
1354
|
+
var URL = keycloakConfig["auth-server-url"] + 'realms/' + keycloakConfig.realm + '/protocol/openid-connect/token'
|
|
1355
|
+
|
|
1356
|
+
var config = {
|
|
1357
|
+
method: 'post',
|
|
1358
|
+
url: URL,
|
|
1359
|
+
headers: {
|
|
1360
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
1361
|
+
},
|
|
1362
|
+
data: {
|
|
1363
|
+
client_id: keycloakConfig.CLIENT_ID,
|
|
1364
|
+
client_secret: keycloakConfig.credentials.secret,
|
|
1365
|
+
grant_type: 'refresh_token',
|
|
1366
|
+
refresh_token: refreshToken
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
|
|
1370
|
+
try {
|
|
1371
|
+
let refreshTokenResponse = await requestController.httpRequest(config, true);
|
|
1372
|
+
|
|
1373
|
+
let accessToken = refreshTokenResponse.data.access_token;
|
|
1374
|
+
resolve({
|
|
1375
|
+
'status': 200,
|
|
1376
|
+
'access_token': accessToken
|
|
1377
|
+
});
|
|
1378
|
+
|
|
1379
|
+
} catch (error) {
|
|
1380
|
+
|
|
1381
|
+
if (error.response) {
|
|
1382
|
+
|
|
1383
|
+
if (error.response.data.error_description == 'Token is not active') {
|
|
1384
|
+
error.response.data.error_description = 'Refresh Token expired, please login again';
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
reject({
|
|
1388
|
+
'status': error.response.status,
|
|
1389
|
+
'message': `${error.response.data.error_description}`
|
|
1390
|
+
});
|
|
1391
|
+
|
|
1392
|
+
} else {
|
|
1393
|
+
reject({ 'message': error.message });
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1275
1400
|
async checkErrorType(err) {
|
|
1276
1401
|
|
|
1277
1402
|
if (err.code == "ETIMEDOUT") {
|