@barchart/portfolio-client-js 1.4.7 → 2.0.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/.releases/2.0.0.md +10 -0
- package/gulpfile.js +2 -11
- package/lib/common/Configuration.js +46 -23
- package/lib/gateway/PortfolioGateway.js +150 -127
- package/lib/index.js +2 -2
- package/lib/security/JwtProvider.js +188 -0
- package/lib/security/meta.js +14 -0
- package/package.json +6 -6
- package/example/example.css +0 -124
- package/example/example.html +0 -98
- package/example/example.js +0 -22074
- package/example/js/startup.js +0 -963
- package/lib/gateway/jwt/JwtGateway.js +0 -410
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
const assert = require('@barchart/common-js/lang/assert'),
|
|
2
|
-
Disposable = require('@barchart/common-js/lang/Disposable'),
|
|
3
|
-
Scheduler = require('@barchart/common-js/timing/Scheduler');
|
|
4
|
-
|
|
5
|
-
const EndpointBuilder = require('@barchart/common-js/api/http/builders/EndpointBuilder'),
|
|
6
|
-
Endpoint = require('@barchart/common-js/api/http/definitions/Endpoint'),
|
|
7
|
-
FailureReason = require('@barchart/common-js/api/failures/FailureReason'),
|
|
8
|
-
FailureType = require('@barchart/common-js/api/failures/FailureType'),
|
|
9
|
-
Gateway = require('@barchart/common-js/api/http/Gateway'),
|
|
10
|
-
ProtocolType = require('@barchart/common-js/api/http/definitions/ProtocolType'),
|
|
11
|
-
RequestInterceptor = require('@barchart/common-js/api/http/interceptors/RequestInterceptor'),
|
|
12
|
-
ResponseInterceptor = require('@barchart/common-js/api/http/interceptors/ResponseInterceptor'),
|
|
13
|
-
VerbType = require('@barchart/common-js/api/http/definitions/VerbType');
|
|
14
|
-
|
|
15
|
-
const Configuration = require('./../../common/Configuration');
|
|
16
|
-
|
|
17
|
-
module.exports = (() => {
|
|
18
|
-
'use strict';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Web service gateway for translating external JWT tokens into standardized
|
|
22
|
-
* Barchart JWT tokens.
|
|
23
|
-
*
|
|
24
|
-
* @public
|
|
25
|
-
* @param {Endpoint} endpoint
|
|
26
|
-
* @param {Number=} refreshInterval - Interval, in milliseconds, which a token refresh should occur. If zero, the token does not need to be refreshed.
|
|
27
|
-
* @extends {Disposable}
|
|
28
|
-
*/
|
|
29
|
-
class JwtGateway extends Disposable {
|
|
30
|
-
constructor(endpoint, refreshInterval) {
|
|
31
|
-
super();
|
|
32
|
-
|
|
33
|
-
assert.argumentIsRequired(endpoint, 'endpoint', Endpoint, 'Endpoint');
|
|
34
|
-
assert.argumentIsOptional(refreshInterval, 'refreshInterval', Number);
|
|
35
|
-
|
|
36
|
-
this._started = false;
|
|
37
|
-
this._startPromise = null;
|
|
38
|
-
|
|
39
|
-
this._endpoint = endpoint;
|
|
40
|
-
|
|
41
|
-
this._refreshInterval = refreshInterval || 0;
|
|
42
|
-
this._refreshJitter = Math.floor(this._refreshInterval / 10);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Initializes the connection to the remote server and returns a promise
|
|
47
|
-
* containing the current instance
|
|
48
|
-
*
|
|
49
|
-
* @public
|
|
50
|
-
* @returns {Promise<JwtGateway>}
|
|
51
|
-
*/
|
|
52
|
-
start() {
|
|
53
|
-
return Promise.resolve()
|
|
54
|
-
.then(() => {
|
|
55
|
-
if (this._startPromise === null) {
|
|
56
|
-
this._startPromise = Promise.resolve()
|
|
57
|
-
.then(() => {
|
|
58
|
-
this._started = true;
|
|
59
|
-
|
|
60
|
-
return this;
|
|
61
|
-
}).catch((e) => {
|
|
62
|
-
this._startPromise = null;
|
|
63
|
-
|
|
64
|
-
return Promise.reject(e);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return this._startPromise;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Retrieves a JWT token from the remote server.
|
|
74
|
-
*
|
|
75
|
-
* @public
|
|
76
|
-
* @returns {Promise<String>}
|
|
77
|
-
*/
|
|
78
|
-
readToken() {
|
|
79
|
-
return Promise.resolve()
|
|
80
|
-
.then(() => {
|
|
81
|
-
checkStart.call(this);
|
|
82
|
-
|
|
83
|
-
return Gateway.invoke(this._endpoint);
|
|
84
|
-
}).catch((e) => {
|
|
85
|
-
const failure = FailureReason.forRequest({ endpoint: this._endpoint })
|
|
86
|
-
.addItem(FailureType.REQUEST_IDENTITY_FAILURE)
|
|
87
|
-
.format();
|
|
88
|
-
|
|
89
|
-
return Promise.reject(failure);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Returns a {@link RequestInterceptor} suitable for use with other API calls.
|
|
95
|
-
*
|
|
96
|
-
* @public
|
|
97
|
-
* @returns {RequestInterceptor}
|
|
98
|
-
*/
|
|
99
|
-
toRequestInterceptor() {
|
|
100
|
-
const scheduler = new Scheduler();
|
|
101
|
-
|
|
102
|
-
let refreshPromise = null;
|
|
103
|
-
let refreshTime = null;
|
|
104
|
-
|
|
105
|
-
const refreshToken = () => {
|
|
106
|
-
if (refreshPromise === null || (this._refreshInterval > 0 && refreshTime !== null && getTime() > (refreshTime + this._refreshInterval + this._refreshJitter))) {
|
|
107
|
-
refreshPromise = scheduler.backoff(() => this.readToken(), 750, 'Read JWT token', 3)
|
|
108
|
-
.then((token) => {
|
|
109
|
-
refreshTime = getTime();
|
|
110
|
-
|
|
111
|
-
return token;
|
|
112
|
-
}).catch((e) => {
|
|
113
|
-
refreshPromise = null;
|
|
114
|
-
refreshTime = null;
|
|
115
|
-
|
|
116
|
-
return Promise.reject(e);
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return refreshPromise;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const delegate = (options, endpoint) => {
|
|
124
|
-
return refreshToken()
|
|
125
|
-
.then((token) => {
|
|
126
|
-
options.headers = options.headers || { };
|
|
127
|
-
options.headers.Authorization = `Bearer ${token}`;
|
|
128
|
-
|
|
129
|
-
return options;
|
|
130
|
-
}).catch((e) => {
|
|
131
|
-
const failure = FailureReason.forRequest({ endpoint: endpoint })
|
|
132
|
-
.addItem(FailureType.REQUEST_IDENTITY_FAILURE)
|
|
133
|
-
.format();
|
|
134
|
-
|
|
135
|
-
return Promise.reject(failure);
|
|
136
|
-
});
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
return RequestInterceptor.fromDelegate(delegate);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Creates and starts a new {@link JwtGateway} for use in the development environment.
|
|
144
|
-
*
|
|
145
|
-
* @public
|
|
146
|
-
* @static
|
|
147
|
-
* @param {String} userId - The identifier of the user to impersonate.
|
|
148
|
-
* @param {String} userLegacyId - The legacy identifier of the user to impersonate.
|
|
149
|
-
* @returns {Promise<JwtGateway>}
|
|
150
|
-
*/
|
|
151
|
-
static forDevelopment(userId, userLegacyId) {
|
|
152
|
-
return start(new JwtGateway(forDevelopment(userId, userLegacyId), 180000));
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Creates and starts a new {@link RequestInterceptor} for use in the development environment.
|
|
157
|
-
*
|
|
158
|
-
* @public
|
|
159
|
-
* @static
|
|
160
|
-
* @param {String} userId - The identifier of the user to impersonate.
|
|
161
|
-
* @returns {Promise<RequestInterceptor>}
|
|
162
|
-
*/
|
|
163
|
-
static forDevelopmentClient(userId, userLegacyId) {
|
|
164
|
-
return JwtGateway.forDevelopment(userId, userLegacyId)
|
|
165
|
-
.then((jwtGateway) => {
|
|
166
|
-
return jwtGateway.toRequestInterceptor();
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Creates and starts a new {@link JwtGateway} for use in the staging environment.
|
|
172
|
-
*
|
|
173
|
-
* @public
|
|
174
|
-
* @static
|
|
175
|
-
* @param {Promise<RequestInterceptor>} externalRequestInterceptorPromise
|
|
176
|
-
* @returns {Promise<JwtGateway>}
|
|
177
|
-
*/
|
|
178
|
-
static forStaging(externalRequestInterceptorPromise) {
|
|
179
|
-
return externalRequestInterceptorPromise.then((externalRequestInterceptor) => {
|
|
180
|
-
return start(new JwtGateway(forStaging(externalRequestInterceptor), 300000));
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Creates and starts a new {@link RequestInterceptor} for use in the staging environment.
|
|
186
|
-
*
|
|
187
|
-
* @public
|
|
188
|
-
* @static
|
|
189
|
-
* @param {Promise<RequestInterceptor>} externalRequestInterceptorPromise
|
|
190
|
-
* @returns {Promise<RequestInterceptor>}
|
|
191
|
-
*/
|
|
192
|
-
static forStagingClient(externalRequestInterceptorPromise) {
|
|
193
|
-
return JwtGateway.forStaging(externalRequestInterceptorPromise)
|
|
194
|
-
.then((jwtGateway) => {
|
|
195
|
-
return jwtGateway.toRequestInterceptor();
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Creates and starts a new {@link JwtGateway} for use in the production environment.
|
|
201
|
-
*
|
|
202
|
-
* @public
|
|
203
|
-
* @static
|
|
204
|
-
* @param {Promise<RequestInterceptor>} externalRequestInterceptorPromise
|
|
205
|
-
* @returns {Promise<JwtGateway>}
|
|
206
|
-
*/
|
|
207
|
-
static forProduction(externalRequestInterceptorPromise) {
|
|
208
|
-
return externalRequestInterceptorPromise.then((externalRequestInterceptor) => {
|
|
209
|
-
return start(new JwtGateway(forProduction(externalRequestInterceptor), 300000));
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Creates and starts a new {@link RequestInterceptor} for use in the production environment.
|
|
215
|
-
*
|
|
216
|
-
* @public
|
|
217
|
-
* @static
|
|
218
|
-
* @param {Promise<RequestInterceptor>} externalRequestInterceptorPromise
|
|
219
|
-
* @returns {Promise<RequestInterceptor>}
|
|
220
|
-
*/
|
|
221
|
-
static forProductionClient(externalRequestInterceptorPromise) {
|
|
222
|
-
return JwtGateway.forProduction(externalRequestInterceptorPromise)
|
|
223
|
-
.then((jwtGateway) => {
|
|
224
|
-
return jwtGateway.toRequestInterceptor();
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Creates and starts a new {@link JwtGateway} for use in the internal admin environment.
|
|
230
|
-
*
|
|
231
|
-
* @public
|
|
232
|
-
* @static
|
|
233
|
-
* @param {String} userId - The identifier of the user to impersonate.
|
|
234
|
-
* @param {String} userLegacyId - The legacy identifier of the user to impersonate.
|
|
235
|
-
* @returns {Promise<JwtGateway>}
|
|
236
|
-
*/
|
|
237
|
-
static forAdmin(userId, userLegacyId) {
|
|
238
|
-
return start(new JwtGateway(forAdmin(userId, userLegacyId), 180000));
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Creates and starts a new {@link RequestInterceptor} for use in the internal admin environment.
|
|
243
|
-
*
|
|
244
|
-
* @public
|
|
245
|
-
* @static
|
|
246
|
-
* @param {String} userId - The identifier of the user to impersonate.
|
|
247
|
-
* @returns {Promise<RequestInterceptor>}
|
|
248
|
-
*/
|
|
249
|
-
static forAdminClient(userId, userLegacyId) {
|
|
250
|
-
return JwtGateway.forAdmin(userId, userLegacyId)
|
|
251
|
-
.then((jwtGateway) => {
|
|
252
|
-
return jwtGateway.toRequestInterceptor();
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Creates and starts a new {@link JwtGateway} for use in the demo environment.
|
|
258
|
-
*
|
|
259
|
-
* @public
|
|
260
|
-
* @static
|
|
261
|
-
* @param {String} userId - The identifier of the user to impersonate.
|
|
262
|
-
* @returns {Promise<JwtGateway>}
|
|
263
|
-
*/
|
|
264
|
-
static forDemo(userId) {
|
|
265
|
-
return start(new JwtGateway(forDemo(userId), 180000));
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Creates and starts a new {@link RequestInterceptor} for use in the demo environment.
|
|
270
|
-
*
|
|
271
|
-
* @public
|
|
272
|
-
* @static
|
|
273
|
-
* @param {String} userId - The identifier of the user to impersonate.
|
|
274
|
-
* @returns {Promise<RequestInterceptor>}
|
|
275
|
-
*/
|
|
276
|
-
static forDemoClient(userId) {
|
|
277
|
-
return JwtGateway.forDemo(userId)
|
|
278
|
-
.then((jwtGateway) => {
|
|
279
|
-
return jwtGateway.toRequestInterceptor();
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
_onDispose() {
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
toString() {
|
|
288
|
-
return '[JwtGateway]';
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
function start(gateway) {
|
|
293
|
-
return gateway.start()
|
|
294
|
-
.then(() => {
|
|
295
|
-
return gateway;
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
function checkStart() {
|
|
300
|
-
if (this.getIsDisposed()) {
|
|
301
|
-
throw new Error('Unable to use gateway, the gateway has been disposed.');
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (!this._started) {
|
|
305
|
-
throw new Error('Unable to use gateway, the gateway has not started.');
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function getTime() {
|
|
310
|
-
return (new Date()).getTime();
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
function forDevelopment(userId, legacyUserId) {
|
|
314
|
-
return EndpointBuilder.for('read-jwt-token-for-development', 'lookup user identity')
|
|
315
|
-
.withVerb(VerbType.GET)
|
|
316
|
-
.withProtocol(ProtocolType.HTTPS)
|
|
317
|
-
.withHost(Configuration.developmentHost)
|
|
318
|
-
.withPathBuilder((pb) => {
|
|
319
|
-
pb.withLiteralParameter('token', 'token')
|
|
320
|
-
.withLiteralParameter('barchart', 'barchart')
|
|
321
|
-
.withLiteralParameter('generator', 'generator');
|
|
322
|
-
})
|
|
323
|
-
.withQueryBuilder((qb) => {
|
|
324
|
-
qb.withLiteralParameter('user', 'userId', userId)
|
|
325
|
-
.withLiteralParameter('legacy user', 'userLegacyId', legacyUserId)
|
|
326
|
-
.withLiteralParameter('user context', 'userContext', 'TGAM')
|
|
327
|
-
.withLiteralParameter('user permission level', 'userPermissions', 'registered');
|
|
328
|
-
})
|
|
329
|
-
.withResponseInterceptor(ResponseInterceptor.DATA)
|
|
330
|
-
.endpoint;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
function forStaging(externalRequestInterceptor) {
|
|
334
|
-
return EndpointBuilder.for('translate-jwt-token-for-staging', 'lookup Barchart user identity')
|
|
335
|
-
.withVerb(VerbType.GET)
|
|
336
|
-
.withProtocol(ProtocolType.HTTPS)
|
|
337
|
-
.withHost(Configuration.stagingHost)
|
|
338
|
-
.withPathBuilder((pb) => {
|
|
339
|
-
pb.withLiteralParameter('token', 'token')
|
|
340
|
-
.withLiteralParameter('system', 'tgam')
|
|
341
|
-
.withLiteralParameter('converter', 'converter');
|
|
342
|
-
})
|
|
343
|
-
.withRequestInterceptor(externalRequestInterceptor)
|
|
344
|
-
.withResponseInterceptor(ResponseInterceptor.DATA)
|
|
345
|
-
.endpoint;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function forDemo(userId) {
|
|
349
|
-
return EndpointBuilder.for('read-jwt-token-for-demo', 'lookup user identity')
|
|
350
|
-
.withVerb(VerbType.GET)
|
|
351
|
-
.withProtocol(ProtocolType.HTTPS)
|
|
352
|
-
.withHost(Configuration.demoHost)
|
|
353
|
-
.withPathBuilder((pb) => {
|
|
354
|
-
pb.withLiteralParameter('token', 'token')
|
|
355
|
-
.withLiteralParameter('barchart', 'barchart')
|
|
356
|
-
.withLiteralParameter('generator', 'generator');
|
|
357
|
-
})
|
|
358
|
-
.withQueryBuilder((qb) => {
|
|
359
|
-
qb.withLiteralParameter('user', 'userId', userId)
|
|
360
|
-
.withLiteralParameter('legacy user', 'userLegacyId', userId)
|
|
361
|
-
.withLiteralParameter('user context', 'userContext', 'Barchart')
|
|
362
|
-
.withLiteralParameter('user permission level', 'userPermissions', 'registered');
|
|
363
|
-
})
|
|
364
|
-
.withResponseInterceptor(ResponseInterceptor.DATA)
|
|
365
|
-
.endpoint;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function forProduction(externalRequestInterceptor) {
|
|
369
|
-
return EndpointBuilder.for('translate-jwt-token-for-production', 'lookup Barchart user identity')
|
|
370
|
-
.withVerb(VerbType.GET)
|
|
371
|
-
.withProtocol(ProtocolType.HTTPS)
|
|
372
|
-
.withHost(Configuration.productionHost)
|
|
373
|
-
.withPathBuilder((pb) => {
|
|
374
|
-
pb.withLiteralParameter('token', 'token')
|
|
375
|
-
.withLiteralParameter('system', 'tgam')
|
|
376
|
-
.withLiteralParameter('converter', 'converter');
|
|
377
|
-
})
|
|
378
|
-
.withRequestInterceptor(externalRequestInterceptor)
|
|
379
|
-
.withResponseInterceptor(ResponseInterceptor.DATA)
|
|
380
|
-
.endpoint;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
function forAdmin(userId, legacyUserId) {
|
|
384
|
-
return EndpointBuilder.for('read-jwt-token-for-admin', 'lookup user identity')
|
|
385
|
-
.withVerb(VerbType.GET)
|
|
386
|
-
.withProtocol(ProtocolType.HTTPS)
|
|
387
|
-
.withHost(Configuration.adminHost)
|
|
388
|
-
.withPathBuilder((pb) => {
|
|
389
|
-
pb.withLiteralParameter('token', 'token')
|
|
390
|
-
.withLiteralParameter('barchart', 'barchart')
|
|
391
|
-
.withLiteralParameter('generator', 'generator');
|
|
392
|
-
})
|
|
393
|
-
.withQueryBuilder((qb) => {
|
|
394
|
-
if (userId) {
|
|
395
|
-
qb.withLiteralParameter('user', 'userId', userId);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (legacyUserId) {
|
|
399
|
-
qb.withLiteralParameter('legacy user', 'userLegacyId', legacyUserId);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
qb.withLiteralParameter('user context', 'userContext', 'TGAM')
|
|
403
|
-
.withLiteralParameter('user permission level', 'userPermissions', 'registered');
|
|
404
|
-
})
|
|
405
|
-
.withResponseInterceptor(ResponseInterceptor.DATA)
|
|
406
|
-
.endpoint;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return JwtGateway;
|
|
410
|
-
})();
|