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
|
|
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
|
-
*
|
|
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 {
|
|
99
|
+
* @returns {boolean}
|
|
100
100
|
*/
|
|
101
|
-
private
|
|
101
|
+
private tokenNeedsRefresh;
|
|
102
102
|
/**
|
|
103
|
-
*
|
|
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
|
|
105
|
+
* @param tokenResponse - Response object from JWT service request
|
|
109
106
|
* @private
|
|
110
107
|
* @returns {void}
|
|
111
108
|
*/
|
|
112
|
-
private
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
}());
|