ibm-cloud-sdk-core 2.0.4 → 2.1.0

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,3 +1,10 @@
1
+ # [2.1.0](https://github.com/IBM/node-sdk-core/compare/v2.0.4...v2.1.0) (2020-02-14)
2
+
3
+
4
+ ### Features
5
+
6
+ * Pace token refresh requests to avoid rate-limiting ([#79](https://github.com/IBM/node-sdk-core/issues/79)) ([d908c0d](https://github.com/IBM/node-sdk-core/commit/d908c0d16ca9d16803b010ee3311c8589983e6c8))
7
+
1
8
  ## [2.0.4](https://github.com/IBM/node-sdk-core/compare/v2.0.3...v2.0.4) (2020-01-30)
2
9
 
3
10
 
@@ -44,6 +44,7 @@ export declare class JwtTokenManager {
44
44
  protected requestWrapperInstance: RequestWrapper;
45
45
  private tokenInfo;
46
46
  private expireTime;
47
+ private refreshTime;
47
48
  /**
48
49
  * Create a new [[JwtTokenManager]] instance.
49
50
  * @constructor
@@ -84,30 +85,26 @@ export declare class JwtTokenManager {
84
85
  */
85
86
  protected requestToken(): Promise<any>;
86
87
  /**
87
- * Check if currently stored token is "expired"
88
- * i.e. past the window to request a new token
88
+ * Check if currently stored token is expired
89
89
  *
90
90
  * @private
91
91
  * @returns {boolean}
92
92
  */
93
93
  private isTokenExpired;
94
94
  /**
95
- * Save the JWT service response and the calculated expiration time to the object's state.
95
+ * Check if currently stored token should be refreshed
96
+ * i.e. past the window to request a new token
96
97
  *
97
- * @param tokenResponse - Response object from JWT service request
98
98
  * @private
99
- * @returns {void}
99
+ * @returns {boolean}
100
100
  */
101
- private saveTokenInfo;
101
+ private tokenNeedsRefresh;
102
102
  /**
103
- * Decode the access token and calculate the time to request a new token.
104
- *
105
- * A time buffer prevents the edge case of the token expiring before the request could be made.
106
- * The buffer will be a fraction of the total time to live - we are using 80%
103
+ * Save the JWT service response and the calculated expiration time to the object's state.
107
104
  *
108
- * @param accessToken - JSON Web Token received from the service
105
+ * @param tokenResponse - Response object from JWT service request
109
106
  * @private
110
107
  * @returns {void}
111
108
  */
112
- private calculateTimeForNewToken;
109
+ private saveTokenInfo;
113
110
  }
@@ -69,6 +69,12 @@ var JwtTokenManager = /** @class */ (function () {
69
69
  });
70
70
  }
71
71
  else {
72
+ // If refresh needed, kick one off
73
+ if (this.tokenNeedsRefresh()) {
74
+ this.requestToken().then(function (tokenResponse) {
75
+ _this.saveTokenInfo(tokenResponse.result);
76
+ });
77
+ }
72
78
  // 2. use valid, managed token
73
79
  return Promise.resolve(this.tokenInfo[this.tokenName]);
74
80
  }
@@ -110,8 +116,7 @@ var JwtTokenManager = /** @class */ (function () {
110
116
  return Promise.reject(err);
111
117
  };
112
118
  /**
113
- * Check if currently stored token is "expired"
114
- * i.e. past the window to request a new token
119
+ * Check if currently stored token is expired
115
120
  *
116
121
  * @private
117
122
  * @returns {boolean}
@@ -122,7 +127,24 @@ var JwtTokenManager = /** @class */ (function () {
122
127
  return true;
123
128
  }
124
129
  var currentTime = getCurrentTime();
125
- return expireTime < currentTime;
130
+ return expireTime <= currentTime;
131
+ };
132
+ /**
133
+ * Check if currently stored token should be refreshed
134
+ * i.e. past the window to request a new token
135
+ *
136
+ * @private
137
+ * @returns {boolean}
138
+ */
139
+ JwtTokenManager.prototype.tokenNeedsRefresh = function () {
140
+ var refreshTime = this.refreshTime;
141
+ var currentTime = getCurrentTime();
142
+ if (refreshTime && refreshTime > currentTime) {
143
+ return false;
144
+ }
145
+ // Update refreshTime to 60 seconds from now to avoid redundant refreshes
146
+ this.refreshTime = currentTime + 60;
147
+ return true;
126
148
  };
127
149
  /**
128
150
  * Save the JWT service response and the calculated expiration time to the object's state.
@@ -138,36 +160,27 @@ var JwtTokenManager = /** @class */ (function () {
138
160
  logger_1.default.error(err);
139
161
  throw new Error(err);
140
162
  }
141
- this.expireTime = this.calculateTimeForNewToken(accessToken);
142
- this.tokenInfo = extend({}, tokenResponse);
143
- };
144
- /**
145
- * Decode the access token and calculate the time to request a new token.
146
- *
147
- * A time buffer prevents the edge case of the token expiring before the request could be made.
148
- * The buffer will be a fraction of the total time to live - we are using 80%
149
- *
150
- * @param accessToken - JSON Web Token received from the service
151
- * @private
152
- * @returns {void}
153
- */
154
- JwtTokenManager.prototype.calculateTimeForNewToken = function (accessToken) {
155
163
  // the time of expiration is found by decoding the JWT access token
156
164
  // exp is the time of expire and iat is the time of token retrieval
157
- var timeForNewToken;
158
165
  var decodedResponse = jwt.decode(accessToken);
159
- if (decodedResponse) {
160
- var exp = decodedResponse.exp, iat = decodedResponse.iat;
161
- var fractionOfTtl = 0.8;
162
- var timeToLive = exp - iat;
163
- timeForNewToken = exp - (timeToLive * (1.0 - fractionOfTtl));
164
- }
165
- else {
166
+ if (!decodedResponse) {
166
167
  var err = 'Access token recieved is not a valid JWT';
167
168
  logger_1.default.error(err);
168
169
  throw new Error(err);
169
170
  }
170
- return timeForNewToken;
171
+ var exp = decodedResponse.exp, iat = decodedResponse.iat;
172
+ // There are no required claims in JWT
173
+ if (!exp || !iat) {
174
+ this.expireTime = 0;
175
+ this.refreshTime = 0;
176
+ }
177
+ else {
178
+ var fractionOfTtl = 0.8;
179
+ var timeToLive = exp - iat;
180
+ this.expireTime = exp;
181
+ this.refreshTime = exp - (timeToLive * (1.0 - fractionOfTtl));
182
+ }
183
+ this.tokenInfo = extend({}, tokenResponse);
171
184
  };
172
185
  return JwtTokenManager;
173
186
  }());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ibm-cloud-sdk-core",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "Core functionality to support SDKs generated with IBM's OpenAPI 3 SDK Generator.",
5
5
  "main": "index",
6
6
  "repository": {