@itentialopensource/adapter-utils 5.9.0 → 5.9.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/CHANGELOG.md +16 -0
- package/error.json +6 -0
- package/lib/connectorRest.js +91 -44
- package/package.json +2 -2
- package/refs?service=git-upload-pack +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
|
|
2
|
+
## 5.9.2 [10-07-2024]
|
|
3
|
+
|
|
4
|
+
* add token logs
|
|
5
|
+
|
|
6
|
+
See merge request itentialopensource/adapter-utils!306
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 5.9.1 [09-26-2024]
|
|
11
|
+
|
|
12
|
+
* Update refresh token logic
|
|
13
|
+
|
|
14
|
+
See merge request itentialopensource/adapter-utils!304
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
2
18
|
## 5.9.0 [09-23-2024]
|
|
3
19
|
|
|
4
20
|
* Cache ssl file contents in memory
|
package/error.json
CHANGED
|
@@ -144,6 +144,12 @@
|
|
|
144
144
|
"displayString": "The Adapter has run out of time for the request",
|
|
145
145
|
"recommendation": "Increase your adapter request.attempt_timeout property"
|
|
146
146
|
},
|
|
147
|
+
{
|
|
148
|
+
"key": "Disconnect",
|
|
149
|
+
"icode": "AD.502",
|
|
150
|
+
"displayString": "The connection was terminated by the network or external system",
|
|
151
|
+
"recommendation": "Check connectivity to the external system and that the system is up"
|
|
152
|
+
},
|
|
147
153
|
{
|
|
148
154
|
"key": "Caught Exception",
|
|
149
155
|
"icode": "AD.900",
|
package/lib/connectorRest.js
CHANGED
|
@@ -1309,7 +1309,7 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1309
1309
|
|
|
1310
1310
|
// process primary token from header
|
|
1311
1311
|
if (tokenSchema.responseSchema && tokenSchema.responseSchema.properties && tokenSchema.responseSchema.properties.token
|
|
1312
|
-
|
|
1312
|
+
&& tokenSchema.responseSchema.properties.token.placement && tokenSchema.responseSchema.properties.token.placement.toUpperCase() === 'HEADER') {
|
|
1313
1313
|
if (!tokenSchema.responseSchema.properties.token.external_name) {
|
|
1314
1314
|
const errorObj = transUtilInst.formatErrorObject(origin, 'Unable To Get Primary Token', ['Primary Token', result.code], null, null, null);
|
|
1315
1315
|
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
|
@@ -1317,6 +1317,7 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1317
1317
|
}
|
|
1318
1318
|
|
|
1319
1319
|
const exName = tokenSchema.responseSchema.properties.token.external_name.toLowerCase();
|
|
1320
|
+
log.debug(`Attempting to get primary token from Header ${exName}`);
|
|
1320
1321
|
const headKeys = Object.keys(result.headers);
|
|
1321
1322
|
let fullToken = null;
|
|
1322
1323
|
let setCookie = null;
|
|
@@ -1397,6 +1398,7 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1397
1398
|
}
|
|
1398
1399
|
|
|
1399
1400
|
const exName = tokenSchema.responseSchema.properties.tokenp2.external_name.toLowerCase();
|
|
1401
|
+
log.debug(`Attempting to get second token from Header ${exName}`);
|
|
1400
1402
|
const headKeys = Object.keys(result.headers);
|
|
1401
1403
|
let fullToken = null;
|
|
1402
1404
|
let setCookie = null;
|
|
@@ -1470,6 +1472,8 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1470
1472
|
// process the body
|
|
1471
1473
|
// if response is just a string
|
|
1472
1474
|
if (Object.hasOwnProperty.call(tokenSchema, 'responseDatatype') && tokenSchema.responseDatatype.toUpperCase() === 'PLAIN') {
|
|
1475
|
+
log.debug('Attempting to get tokens from text body repsonse');
|
|
1476
|
+
|
|
1473
1477
|
if (tokenSchema.responseSchema && tokenSchema.responseSchema.properties && tokenSchema.responseSchema.properties.token
|
|
1474
1478
|
&& tokenSchema.responseSchema.properties.token.placement && tokenSchema.responseSchema.properties.token.placement.toUpperCase() === 'BODY') {
|
|
1475
1479
|
currResult.token = result.response;
|
|
@@ -1493,6 +1497,8 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1493
1497
|
return resolve(currResult);
|
|
1494
1498
|
}
|
|
1495
1499
|
if (Object.hasOwnProperty.call(tokenSchema, 'responseDatatype') && tokenSchema.responseDatatype.toUpperCase() === 'XML') {
|
|
1500
|
+
log.debug('Attempting to get tokens from XML body repsonse');
|
|
1501
|
+
|
|
1496
1502
|
if (tokenSchema.responseSchema && tokenSchema.responseSchema.properties && tokenSchema.responseSchema.properties.token
|
|
1497
1503
|
&& tokenSchema.responseSchema.properties.token.placement && tokenSchema.responseSchema.properties.token.placement.toUpperCase() === 'BODY') {
|
|
1498
1504
|
currResult.token = result.response;
|
|
@@ -1510,6 +1516,8 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1510
1516
|
let tempResult = null;
|
|
1511
1517
|
if (result.response) {
|
|
1512
1518
|
if (Object.hasOwnProperty.call(tokenSchema, 'responseDatatype') && tokenSchema.responseDatatype.toUpperCase() === 'XML2JSON') {
|
|
1519
|
+
log.debug('Attempting to get tokens from XML2JSON repsonse');
|
|
1520
|
+
|
|
1513
1521
|
try {
|
|
1514
1522
|
const parser = new xml2js.Parser({ explicitArray: false, attrkey: '_attr' });
|
|
1515
1523
|
parser.parseString(result.response, (error, presult) => {
|
|
@@ -1532,9 +1540,11 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1532
1540
|
}
|
|
1533
1541
|
}
|
|
1534
1542
|
if (Object.hasOwnProperty.call(tokenSchema, 'responseDatatype') && tokenSchema.responseDatatype.toUpperCase() === 'URLENCODE') {
|
|
1543
|
+
log.debug('Attempting to get tokens from URLENCODE repsonse');
|
|
1535
1544
|
tempResult = querystring.parse(result.response.trim());
|
|
1536
1545
|
} else {
|
|
1537
1546
|
try {
|
|
1547
|
+
log.debug('Parsing JSON response');
|
|
1538
1548
|
tempResult = JSON.parse(result.response.trim());
|
|
1539
1549
|
} catch (exc) {
|
|
1540
1550
|
log.warn(exc);
|
|
@@ -1572,7 +1582,9 @@ async function getToken(reqPath, options, tokenSchema, bodyString, callPropertie
|
|
|
1572
1582
|
}
|
|
1573
1583
|
|
|
1574
1584
|
// return the token from the token schema
|
|
1585
|
+
log.debug(`About to Translate Token Response: ${JSON.stringify(propUtilInst.scrubSensitiveInfo(tempResult))}`);
|
|
1575
1586
|
let translated = transUtilInst.mapFromOutboundEntity(tempResult, tokenSchema.responseSchema);
|
|
1587
|
+
log.debug(`Translated response ${JSON.stringify(propUtilInst.scrubSensitiveInfo(translated))}`);
|
|
1576
1588
|
|
|
1577
1589
|
// if what we got back is an array, just return the first element
|
|
1578
1590
|
// should only have one token!!!
|
|
@@ -2131,7 +2143,7 @@ async function buildTokenRequest(reqPath, reqBody, callProperties, callback) {
|
|
|
2131
2143
|
|
|
2132
2144
|
// if this is not a get, need to add the info to the request
|
|
2133
2145
|
if (options.method !== 'GET') {
|
|
2134
|
-
if (authMethod !== 'multi_step_authentication') {
|
|
2146
|
+
if (authMethod !== 'multi_step_authentication' && !runRefreshToken) {
|
|
2135
2147
|
creds = {
|
|
2136
2148
|
username: useUser,
|
|
2137
2149
|
password: usePass
|
|
@@ -2203,16 +2215,17 @@ async function buildTokenRequest(reqPath, reqBody, callProperties, callback) {
|
|
|
2203
2215
|
Object.assign(creds, body);
|
|
2204
2216
|
// If there are query variables, add them to the path
|
|
2205
2217
|
if (Object.keys(query).length > 0) {
|
|
2218
|
+
const systemQuery = transUtilInst.mapToOutboundEntity(query, tokenSchema.requestSchema);
|
|
2206
2219
|
let refTokenQueryString = '';
|
|
2207
2220
|
if (encodeUri === true) {
|
|
2208
|
-
refTokenQueryString += querystring.stringify(
|
|
2221
|
+
refTokenQueryString += querystring.stringify(systemQuery);
|
|
2209
2222
|
} else {
|
|
2210
|
-
const refTokenQueryKeys = Object.keys(
|
|
2223
|
+
const refTokenQueryKeys = Object.keys(systemQuery);
|
|
2211
2224
|
for (let k = 0; k < refTokenQueryKeys.length; k += 1) {
|
|
2212
2225
|
if (k > 0) {
|
|
2213
2226
|
refTokenQueryString += '&';
|
|
2214
2227
|
}
|
|
2215
|
-
refTokenQueryString += `${refTokenQueryKeys[k]}=${
|
|
2228
|
+
refTokenQueryString += `${refTokenQueryKeys[k]}=${systemQuery[refTokenQueryKeys[k]]}`;
|
|
2216
2229
|
}
|
|
2217
2230
|
}
|
|
2218
2231
|
// append to the path
|
|
@@ -2525,6 +2538,36 @@ function getCachedRefToken(cachedTokenIdentifier, invalidToken) {
|
|
|
2525
2538
|
});
|
|
2526
2539
|
}
|
|
2527
2540
|
|
|
2541
|
+
function handleToken(dyntoken, user, reqBody, done) {
|
|
2542
|
+
let timeout = tokenTimeout;
|
|
2543
|
+
// if we should use the timeout from the token request
|
|
2544
|
+
if (timeout === 0) {
|
|
2545
|
+
timeout = findExpireInResult(dyntoken);
|
|
2546
|
+
} else {
|
|
2547
|
+
// otherwise add the timeout to the current time
|
|
2548
|
+
timeout += new Date().getTime();
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
const tokenObj = {
|
|
2552
|
+
token: findPrimaryTokenInResult(dyntoken, dyntoken.front, dyntoken.end),
|
|
2553
|
+
tokenp2: findSecondaryTokenInResult(dyntoken, dyntoken.front, dyntoken.end),
|
|
2554
|
+
refreshToken: dyntoken.refreshToken
|
|
2555
|
+
};
|
|
2556
|
+
|
|
2557
|
+
// if this is worth caching
|
|
2558
|
+
if (timeout && timeout > 0) {
|
|
2559
|
+
// since this is adding the token for future use, do not care when it comes back
|
|
2560
|
+
addTokenItem(user, reqBody, tokenObj, timeout, (addedtoken, aerror) => {
|
|
2561
|
+
if (aerror) {
|
|
2562
|
+
return done(null, aerror);
|
|
2563
|
+
}
|
|
2564
|
+
done(tokenObj, null);
|
|
2565
|
+
});
|
|
2566
|
+
} else {
|
|
2567
|
+
done(tokenObj, null);
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2528
2571
|
/*
|
|
2529
2572
|
* INTERNAL FUNCTION: getTokenItem is used to retrieve a token items from
|
|
2530
2573
|
* memory based on the user provided
|
|
@@ -2551,7 +2594,7 @@ function getTokenItem(pathForToken, user, reqBody, invalidToken, callProperties,
|
|
|
2551
2594
|
done(null, rerror);
|
|
2552
2595
|
}
|
|
2553
2596
|
if (refToken !== null) {
|
|
2554
|
-
log.debug(`${origin}
|
|
2597
|
+
log.debug(`${origin}: Returning cached refresh token`);
|
|
2555
2598
|
if (!callProperties) {
|
|
2556
2599
|
callProperties = {};
|
|
2557
2600
|
}
|
|
@@ -2562,48 +2605,44 @@ function getTokenItem(pathForToken, user, reqBody, invalidToken, callProperties,
|
|
|
2562
2605
|
// Refresh the token if getRefreshToken entity exists
|
|
2563
2606
|
if (tokenSchema) {
|
|
2564
2607
|
runRefreshToken = true;
|
|
2608
|
+
} else {
|
|
2609
|
+
log.debug(`${origin}: Refresh token schema does not exist, will not refresh token`);
|
|
2610
|
+
runRefreshToken = false;
|
|
2565
2611
|
}
|
|
2566
2612
|
});
|
|
2567
|
-
} else
|
|
2613
|
+
} else {
|
|
2614
|
+
runRefreshToken = false;
|
|
2615
|
+
}
|
|
2568
2616
|
});
|
|
2569
2617
|
// No valid token found, Need to get a new token and add it to the token list
|
|
2570
2618
|
buildTokenRequest(pathForToken, reqBody, callProperties, (dyntoken, berror) => {
|
|
2571
|
-
if (berror) {
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
const tokenObj = {
|
|
2591
|
-
token: findPrimaryTokenInResult(dyntoken, dyntoken.front, dyntoken.end),
|
|
2592
|
-
tokenp2: findSecondaryTokenInResult(dyntoken, dyntoken.front, dyntoken.end),
|
|
2593
|
-
refreshToken: dyntoken.refreshToken
|
|
2594
|
-
};
|
|
2595
|
-
|
|
2596
|
-
// if this is worth caching
|
|
2597
|
-
if (timeout && timeout > 0) {
|
|
2598
|
-
// since this is adding the token for future use, do not care when it comes back
|
|
2599
|
-
addTokenItem(user, reqBody, tokenObj, timeout, (addedtoken, aerror) => {
|
|
2600
|
-
if (aerror) {
|
|
2601
|
-
done(null, aerror);
|
|
2619
|
+
if (berror || !dyntoken) {
|
|
2620
|
+
if (runRefreshToken) {
|
|
2621
|
+
log.debug(`${origin}: Failed to refresh token, use auth steps to get a new token`);
|
|
2622
|
+
runRefreshToken = false;
|
|
2623
|
+
buildTokenRequest(pathForToken, reqBody, callProperties, (innerDyntoken, innerBerror) => {
|
|
2624
|
+
if (innerBerror) {
|
|
2625
|
+
// done(null, innerBerror);
|
|
2626
|
+
return done(innerBerror);
|
|
2627
|
+
}
|
|
2628
|
+
if (!innerDyntoken) {
|
|
2629
|
+
// done(null, 'No Token returned');
|
|
2630
|
+
return done(new Error('No Token returned'));
|
|
2631
|
+
}
|
|
2632
|
+
handleToken(innerDyntoken, user, reqBody, done);
|
|
2633
|
+
});
|
|
2634
|
+
} else {
|
|
2635
|
+
if (berror) {
|
|
2636
|
+
// done(null, berror);
|
|
2637
|
+
return done(berror);
|
|
2602
2638
|
}
|
|
2603
|
-
|
|
2604
|
-
|
|
2639
|
+
if (!dyntoken) {
|
|
2640
|
+
// done(null, 'No Token returned');
|
|
2641
|
+
return done(new Error('No Token returned'));
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2605
2644
|
} else {
|
|
2606
|
-
|
|
2645
|
+
handleToken(dyntoken, user, reqBody, done);
|
|
2607
2646
|
}
|
|
2608
2647
|
});
|
|
2609
2648
|
}
|
|
@@ -3076,17 +3115,19 @@ async function getMfaFinalTokens(request, callProperties, invalidToken) {
|
|
|
3076
3115
|
// If cached refresh token is valid and there is action for getRefreshToken, run refresh token
|
|
3077
3116
|
if (tokenSchema) {
|
|
3078
3117
|
runRefreshToken = true;
|
|
3118
|
+
} else {
|
|
3119
|
+
log.debug(`${origin}: Refresh token schema does not exist, will not refresh token`);
|
|
3120
|
+
runRefreshToken = false;
|
|
3079
3121
|
}
|
|
3080
3122
|
});
|
|
3081
3123
|
if (runRefreshToken) {
|
|
3082
3124
|
finalTokens = await buildTokenRequest(request.header.path, request.authData, callProperties).catch((error) => { // eslint-disable-line no-await-in-loop
|
|
3083
|
-
log.
|
|
3084
|
-
throw error;
|
|
3125
|
+
log.debug(`${origin}: Failed to refresh token, run auth steps to obtain a new token`);
|
|
3085
3126
|
});
|
|
3086
3127
|
if (finalTokens) {
|
|
3087
3128
|
await cacheMfaToken(cachedTokenIdentifier, finalTokens).catch((error) => log.error(error));
|
|
3129
|
+
return;
|
|
3088
3130
|
}
|
|
3089
|
-
return;
|
|
3090
3131
|
}
|
|
3091
3132
|
}
|
|
3092
3133
|
runRefreshToken = false;
|
|
@@ -3581,6 +3622,8 @@ function handleEndResponse(request, makeResp, overallTime, callback) {
|
|
|
3581
3622
|
|
|
3582
3623
|
if (makeResp.code === -2) {
|
|
3583
3624
|
errorObj = transUtilInst.formatErrorObject(origin, 'Request Timeout', [makeResp.code], makeResp.code, makeResp, null);
|
|
3625
|
+
} else if (makeResp.code === -1) {
|
|
3626
|
+
errorObj = transUtilInst.formatErrorObject(origin, 'Disconnect', [makeResp.code], makeResp.code, makeResp, null);
|
|
3584
3627
|
} else {
|
|
3585
3628
|
errorObj = transUtilInst.formatErrorObject(origin, 'Error On Request', [makeResp.code], makeResp.code, makeResp, null);
|
|
3586
3629
|
}
|
|
@@ -3710,6 +3753,8 @@ function handleEndThrottleResponse(request, myTransTime, claimedLic, makeResp, r
|
|
|
3710
3753
|
|
|
3711
3754
|
if (makeResp.code === -2) {
|
|
3712
3755
|
errorObj = transUtilInst.formatErrorObject(origin, 'Request Timeout', [makeResp.code], makeResp.code, makeResp, null);
|
|
3756
|
+
} else if (makeResp.code === -1) {
|
|
3757
|
+
errorObj = transUtilInst.formatErrorObject(origin, 'Disconnect', [makeResp.code], makeResp.code, makeResp, null);
|
|
3713
3758
|
} else {
|
|
3714
3759
|
errorObj = transUtilInst.formatErrorObject(origin, 'Error On Request', [makeResp.code], makeResp.code, makeResp, null);
|
|
3715
3760
|
}
|
|
@@ -4845,6 +4890,8 @@ class ConnectorRest {
|
|
|
4845
4890
|
|
|
4846
4891
|
if (pres.code === -2) {
|
|
4847
4892
|
errorObj = transUtilInst.formatErrorObject(origin, 'Request Timeout', [pres.code], pres.code, pres, null);
|
|
4893
|
+
} else if (pres.code === -1) {
|
|
4894
|
+
errorObj = transUtilInst.formatErrorObject(origin, 'Disconnect', [pres.code], pres.code, pres, null);
|
|
4848
4895
|
} else {
|
|
4849
4896
|
errorObj = transUtilInst.formatErrorObject(origin, 'Error On Request', [pres.code], pres.code, pres, null);
|
|
4850
4897
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itentialopensource/adapter-utils",
|
|
3
|
-
"version": "5.9.
|
|
3
|
+
"version": "5.9.2",
|
|
4
4
|
"description": "Itential Adapter Utility Libraries",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"postinstall": "node utils/setup.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"async-lock": "^1.4.0",
|
|
30
30
|
"aws-sdk": "^2.1665.0",
|
|
31
31
|
"aws4": "^1.9.1",
|
|
32
|
-
"cookie": "^0.
|
|
32
|
+
"cookie": "^0.7.1",
|
|
33
33
|
"crypto-js": "^4.1.1",
|
|
34
34
|
"ejs": "^3.1.10",
|
|
35
35
|
"form-data": "^4.0.0",
|
|
Binary file
|