@itentialopensource/adapter-utils 5.9.0 → 5.9.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/CHANGELOG.md CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ ## 5.9.1 [09-26-2024]
3
+
4
+ * Update refresh token logic
5
+
6
+ See merge request itentialopensource/adapter-utils!304
7
+
8
+ ---
9
+
2
10
  ## 5.9.0 [09-23-2024]
3
11
 
4
12
  * 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",
@@ -2131,7 +2131,7 @@ async function buildTokenRequest(reqPath, reqBody, callProperties, callback) {
2131
2131
 
2132
2132
  // if this is not a get, need to add the info to the request
2133
2133
  if (options.method !== 'GET') {
2134
- if (authMethod !== 'multi_step_authentication') {
2134
+ if (authMethod !== 'multi_step_authentication' && !runRefreshToken) {
2135
2135
  creds = {
2136
2136
  username: useUser,
2137
2137
  password: usePass
@@ -2203,16 +2203,17 @@ async function buildTokenRequest(reqPath, reqBody, callProperties, callback) {
2203
2203
  Object.assign(creds, body);
2204
2204
  // If there are query variables, add them to the path
2205
2205
  if (Object.keys(query).length > 0) {
2206
+ const systemQuery = transUtilInst.mapToOutboundEntity(query, tokenSchema.requestSchema);
2206
2207
  let refTokenQueryString = '';
2207
2208
  if (encodeUri === true) {
2208
- refTokenQueryString += querystring.stringify(query);
2209
+ refTokenQueryString += querystring.stringify(systemQuery);
2209
2210
  } else {
2210
- const refTokenQueryKeys = Object.keys(query);
2211
+ const refTokenQueryKeys = Object.keys(systemQuery);
2211
2212
  for (let k = 0; k < refTokenQueryKeys.length; k += 1) {
2212
2213
  if (k > 0) {
2213
2214
  refTokenQueryString += '&';
2214
2215
  }
2215
- refTokenQueryString += `${refTokenQueryKeys[k]}=${query[refTokenQueryKeys[k]]}`;
2216
+ refTokenQueryString += `${refTokenQueryKeys[k]}=${systemQuery[refTokenQueryKeys[k]]}`;
2216
2217
  }
2217
2218
  }
2218
2219
  // append to the path
@@ -2525,6 +2526,36 @@ function getCachedRefToken(cachedTokenIdentifier, invalidToken) {
2525
2526
  });
2526
2527
  }
2527
2528
 
2529
+ function handleToken(dyntoken, user, reqBody, done) {
2530
+ let timeout = tokenTimeout;
2531
+ // if we should use the timeout from the token request
2532
+ if (timeout === 0) {
2533
+ timeout = findExpireInResult(dyntoken);
2534
+ } else {
2535
+ // otherwise add the timeout to the current time
2536
+ timeout += new Date().getTime();
2537
+ }
2538
+
2539
+ const tokenObj = {
2540
+ token: findPrimaryTokenInResult(dyntoken, dyntoken.front, dyntoken.end),
2541
+ tokenp2: findSecondaryTokenInResult(dyntoken, dyntoken.front, dyntoken.end),
2542
+ refreshToken: dyntoken.refreshToken
2543
+ };
2544
+
2545
+ // if this is worth caching
2546
+ if (timeout && timeout > 0) {
2547
+ // since this is adding the token for future use, do not care when it comes back
2548
+ addTokenItem(user, reqBody, tokenObj, timeout, (addedtoken, aerror) => {
2549
+ if (aerror) {
2550
+ return done(null, aerror);
2551
+ }
2552
+ done(tokenObj, null);
2553
+ });
2554
+ } else {
2555
+ done(tokenObj, null);
2556
+ }
2557
+ }
2558
+
2528
2559
  /*
2529
2560
  * INTERNAL FUNCTION: getTokenItem is used to retrieve a token items from
2530
2561
  * memory based on the user provided
@@ -2551,7 +2582,7 @@ function getTokenItem(pathForToken, user, reqBody, invalidToken, callProperties,
2551
2582
  done(null, rerror);
2552
2583
  }
2553
2584
  if (refToken !== null) {
2554
- log.debug(`${origin}-returning cached refresh token`);
2585
+ log.debug(`${origin}: Returning cached refresh token`);
2555
2586
  if (!callProperties) {
2556
2587
  callProperties = {};
2557
2588
  }
@@ -2562,48 +2593,44 @@ function getTokenItem(pathForToken, user, reqBody, invalidToken, callProperties,
2562
2593
  // Refresh the token if getRefreshToken entity exists
2563
2594
  if (tokenSchema) {
2564
2595
  runRefreshToken = true;
2596
+ } else {
2597
+ log.debug(`${origin}: Refresh token schema does not exist, will not refresh token`);
2598
+ runRefreshToken = false;
2565
2599
  }
2566
2600
  });
2567
- } else runRefreshToken = false;
2601
+ } else {
2602
+ runRefreshToken = false;
2603
+ }
2568
2604
  });
2569
2605
  // No valid token found, Need to get a new token and add it to the token list
2570
2606
  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);
2607
+ if (berror || !dyntoken) {
2608
+ if (runRefreshToken) {
2609
+ log.debug(`${origin}: Failed to refresh token, use auth steps to get a new token`);
2610
+ runRefreshToken = false;
2611
+ buildTokenRequest(pathForToken, reqBody, callProperties, (innerDyntoken, innerBerror) => {
2612
+ if (innerBerror) {
2613
+ // done(null, innerBerror);
2614
+ return done(innerBerror);
2615
+ }
2616
+ if (!innerDyntoken) {
2617
+ // done(null, 'No Token returned');
2618
+ return done(new Error('No Token returned'));
2619
+ }
2620
+ handleToken(innerDyntoken, user, reqBody, done);
2621
+ });
2622
+ } else {
2623
+ if (berror) {
2624
+ // done(null, berror);
2625
+ return done(berror);
2602
2626
  }
2603
- done(tokenObj, null);
2604
- });
2627
+ if (!dyntoken) {
2628
+ // done(null, 'No Token returned');
2629
+ return done(new Error('No Token returned'));
2630
+ }
2631
+ }
2605
2632
  } else {
2606
- done(tokenObj, null);
2633
+ handleToken(dyntoken, user, reqBody, done);
2607
2634
  }
2608
2635
  });
2609
2636
  }
@@ -3076,17 +3103,19 @@ async function getMfaFinalTokens(request, callProperties, invalidToken) {
3076
3103
  // If cached refresh token is valid and there is action for getRefreshToken, run refresh token
3077
3104
  if (tokenSchema) {
3078
3105
  runRefreshToken = true;
3106
+ } else {
3107
+ log.debug(`${origin}: Refresh token schema does not exist, will not refresh token`);
3108
+ runRefreshToken = false;
3079
3109
  }
3080
3110
  });
3081
3111
  if (runRefreshToken) {
3082
3112
  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;
3113
+ log.debug(`${origin}: Failed to refresh token, run auth steps to obtain a new token`);
3085
3114
  });
3086
3115
  if (finalTokens) {
3087
3116
  await cacheMfaToken(cachedTokenIdentifier, finalTokens).catch((error) => log.error(error));
3117
+ return;
3088
3118
  }
3089
- return;
3090
3119
  }
3091
3120
  }
3092
3121
  runRefreshToken = false;
@@ -3581,6 +3610,8 @@ function handleEndResponse(request, makeResp, overallTime, callback) {
3581
3610
 
3582
3611
  if (makeResp.code === -2) {
3583
3612
  errorObj = transUtilInst.formatErrorObject(origin, 'Request Timeout', [makeResp.code], makeResp.code, makeResp, null);
3613
+ } else if (makeResp.code === -1) {
3614
+ errorObj = transUtilInst.formatErrorObject(origin, 'Disconnect', [makeResp.code], makeResp.code, makeResp, null);
3584
3615
  } else {
3585
3616
  errorObj = transUtilInst.formatErrorObject(origin, 'Error On Request', [makeResp.code], makeResp.code, makeResp, null);
3586
3617
  }
@@ -3710,6 +3741,8 @@ function handleEndThrottleResponse(request, myTransTime, claimedLic, makeResp, r
3710
3741
 
3711
3742
  if (makeResp.code === -2) {
3712
3743
  errorObj = transUtilInst.formatErrorObject(origin, 'Request Timeout', [makeResp.code], makeResp.code, makeResp, null);
3744
+ } else if (makeResp.code === -1) {
3745
+ errorObj = transUtilInst.formatErrorObject(origin, 'Disconnect', [makeResp.code], makeResp.code, makeResp, null);
3713
3746
  } else {
3714
3747
  errorObj = transUtilInst.formatErrorObject(origin, 'Error On Request', [makeResp.code], makeResp.code, makeResp, null);
3715
3748
  }
@@ -4845,6 +4878,8 @@ class ConnectorRest {
4845
4878
 
4846
4879
  if (pres.code === -2) {
4847
4880
  errorObj = transUtilInst.formatErrorObject(origin, 'Request Timeout', [pres.code], pres.code, pres, null);
4881
+ } else if (pres.code === -1) {
4882
+ errorObj = transUtilInst.formatErrorObject(origin, 'Disconnect', [pres.code], pres.code, pres, null);
4848
4883
  } else {
4849
4884
  errorObj = transUtilInst.formatErrorObject(origin, 'Error On Request', [pres.code], pres.code, pres, null);
4850
4885
  }
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.1",
4
4
  "description": "Itential Adapter Utility Libraries",
5
5
  "scripts": {
6
6
  "postinstall": "node utils/setup.js",
Binary file