@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 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",
@@ -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
- && tokenSchema.responseSchema.properties.token.placement && tokenSchema.responseSchema.properties.token.placement.toUpperCase() === 'HEADER') {
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(query);
2221
+ refTokenQueryString += querystring.stringify(systemQuery);
2209
2222
  } else {
2210
- const refTokenQueryKeys = Object.keys(query);
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]}=${query[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}-returning cached refresh token`);
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 runRefreshToken = false;
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
- // done(null, berror);
2573
- return done(berror);
2574
- }
2575
- if (!dyntoken) {
2576
- // done(null, 'No Token returned');
2577
- return done(new Error('No Token returned'));
2578
- }
2579
-
2580
- let timeout = tokenTimeout;
2581
-
2582
- // if we should use the timeout from the token request
2583
- if (timeout === 0) {
2584
- timeout = findExpireInResult(dyntoken);
2585
- } else {
2586
- // otherwise add the timeout to the current time
2587
- timeout += new Date().getTime();
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
- done(tokenObj, null);
2604
- });
2639
+ if (!dyntoken) {
2640
+ // done(null, 'No Token returned');
2641
+ return done(new Error('No Token returned'));
2642
+ }
2643
+ }
2605
2644
  } else {
2606
- done(tokenObj, null);
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.error(error);
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.0",
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.5.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