@factset/frontgate-js-sdk 7.0.11 → 7.1.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 +74 -242
- package/dist/lib/esnext/connection/util/Compressor.js +2 -0
- package/dist/lib/esnext/logger/AbstractLogger.js +1 -0
- package/dist/lib/esnext/logger/WinstonLogger.js +3 -1
- package/dist/lib/esnext/mixins/MessageCompressorMixin.js +1 -1
- package/dist/lib/esnext/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.js +165 -0
- package/dist/lib/esnext/mixins/auth/SessionAuthMixin.js +19 -21
- package/dist/lib/esnext/mixins/auth/UserPasswordAuthMixin.js +2 -4
- package/dist/lib/esnext/mixins/auth/index.js +1 -0
- package/dist/lib/esnext/mixins/connection/FrontgateWSMixin.js +1 -1
- package/dist/lib/esnext/mixins/subscription/EndpointSubscriptionMixin.js +1 -1
- package/dist/lib/esnext/version.js +1 -1
- package/dist/lib/node/connection/util/Compressor.js +2 -0
- package/dist/lib/node/logger/AbstractLogger.js +1 -0
- package/dist/lib/node/logger/WinstonLogger.js +3 -1
- package/dist/lib/node/mixins/MessageCompressorMixin.js +1 -1
- package/dist/lib/node/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.js +169 -0
- package/dist/lib/node/mixins/auth/SessionAuthMixin.js +19 -21
- package/dist/lib/node/mixins/auth/UserPasswordAuthMixin.js +2 -4
- package/dist/lib/node/mixins/auth/index.js +1 -0
- package/dist/lib/node/mixins/connection/FrontgateWSMixin.js +1 -1
- package/dist/lib/node/mixins/subscription/EndpointSubscriptionMixin.js +1 -1
- package/dist/lib/node/version.js +1 -1
- package/dist/lib/types/authentication/util/SecretGenerator.d.ts +4 -2
- package/dist/lib/types/mixins/AuthTokenRequestMixin.d.ts +1 -14
- package/dist/lib/types/mixins/EndpointRequestMixin.d.ts +2 -12
- package/dist/lib/types/mixins/HTTPProxyRequestMixin.d.ts +2 -11
- package/dist/lib/types/mixins/LoggerMixin.d.ts +1 -9
- package/dist/lib/types/mixins/MessageCompressorMixin.d.ts +1 -11
- package/dist/lib/types/mixins/OpenTelemetryMixin.d.ts +1 -16
- package/dist/lib/types/mixins/PingMixin.d.ts +1 -10
- package/dist/lib/types/mixins/ReconnectMixin.d.ts +1 -13
- package/dist/lib/types/mixins/RemoteLoggerMixin.d.ts +1 -10
- package/dist/lib/types/mixins/RequestMixin.d.ts +1 -10
- package/dist/lib/types/mixins/auth/AppAuthMixin.d.ts +2 -20
- package/dist/lib/types/mixins/auth/CookieTokenAuthMixin.d.ts +1 -10
- package/dist/lib/types/mixins/auth/FetchAuthenticationMixin.d.ts +2 -49
- package/dist/lib/types/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.d.ts +4 -0
- package/dist/lib/types/mixins/auth/SessionAuthMixin.d.ts +2 -57
- package/dist/lib/types/mixins/auth/TokenAuthMixin.d.ts +1 -12
- package/dist/lib/types/mixins/auth/UserCredentialAuthMixin.d.ts +2 -20
- package/dist/lib/types/mixins/auth/UserPasswordAuthMixin.d.ts +2 -20
- package/dist/lib/types/mixins/auth/index.d.ts +1 -0
- package/dist/lib/types/mixins/connection/FrontgateWSMixin.d.ts +2 -42
- package/dist/lib/types/mixins/connection/index.d.ts +1 -1
- package/dist/lib/types/mixins/index.d.ts +2 -2
- package/dist/lib/types/mixins/subscription/DataObserver.d.ts +1 -1
- package/dist/lib/types/mixins/subscription/EndpointSubscriptionMixin.d.ts +2 -15
- package/dist/lib/types/mixins/subscription/RawSubscriptionMixin.d.ts +1 -18
- package/dist/lib/umd/mdg2.client.min.umd.js +1 -1
- package/dist/lib/umd/mdg2.client.umd.js +4517 -4839
- package/package.json +5 -5
|
@@ -13,7 +13,9 @@ export class WinstonLogger extends AbstractLogger {
|
|
|
13
13
|
super(name);
|
|
14
14
|
this.name = name;
|
|
15
15
|
this.logger = logger;
|
|
16
|
-
|
|
16
|
+
if (logger.trace) {
|
|
17
|
+
this.trace = Function.prototype.bind.call(logger.trace, logger);
|
|
18
|
+
}
|
|
17
19
|
this.debug = Function.prototype.bind.call(logger.debug, logger);
|
|
18
20
|
this.info = Function.prototype.bind.call(logger.info, logger);
|
|
19
21
|
this.warn = Function.prototype.bind.call(logger.warn, logger);
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
import { ID_APP_AUTHENTICATED, ID_USER_AUTHENTICATED } from '../../authentication';
|
|
13
|
+
import { Compressor } from '../../connection/util/Compressor';
|
|
14
|
+
import { LogLevel } from '../../logger';
|
|
15
|
+
import { AuthenticationByTokenRequest } from '../../message/request/AuthenticationByTokenRequest';
|
|
16
|
+
import { createExtendedMixinFactory, wsConnection } from '../.';
|
|
17
|
+
var FetchConnectionConfigurationResponseHeaders;
|
|
18
|
+
(function (FetchConnectionConfigurationResponseHeaders) {
|
|
19
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_HOST"] = "frontgate-host";
|
|
20
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_PATH_PREFIX"] = "frontgate-path-prefix";
|
|
21
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR"] = "frontgate-split-authentication-token-second-factor";
|
|
22
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TYPE"] = "frontgate-authentication-type";
|
|
23
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TOKEN"] = "frontgate-authentication-token";
|
|
24
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PORT"] = "frontgate-websocket-port";
|
|
25
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PROTOCOL"] = "frontgate-websocket-protocol";
|
|
26
|
+
})(FetchConnectionConfigurationResponseHeaders || (FetchConnectionConfigurationResponseHeaders = {}));
|
|
27
|
+
export const fetchAuthWithOptionalCompressor = (config, input, init) => {
|
|
28
|
+
const mixinFetchAuth = (Base) => {
|
|
29
|
+
var _instances, _token, _secondFactor, _shouldCompress, _compressor, _requestInfo, _requestInit, _fetchConnectionConfiguration, _a;
|
|
30
|
+
return _a = class extends wsConnection({
|
|
31
|
+
host: '',
|
|
32
|
+
pathPrefix: '',
|
|
33
|
+
port: 0,
|
|
34
|
+
tls: true,
|
|
35
|
+
maximumIdleIntervalInS: config.maximumIdleIntervalInS,
|
|
36
|
+
})(Base) {
|
|
37
|
+
constructor(...args) {
|
|
38
|
+
super(...args);
|
|
39
|
+
_instances.add(this);
|
|
40
|
+
_token.set(this, '');
|
|
41
|
+
_secondFactor.set(this, '');
|
|
42
|
+
_shouldCompress.set(this, false);
|
|
43
|
+
_compressor.set(this, void 0);
|
|
44
|
+
_requestInfo.set(this, void 0);
|
|
45
|
+
_requestInit.set(this, void 0);
|
|
46
|
+
__classPrivateFieldSet(this, _requestInfo, input, "f");
|
|
47
|
+
__classPrivateFieldSet(this, _requestInit, init, "f");
|
|
48
|
+
__classPrivateFieldSet(this, _compressor, new Compressor(), "f");
|
|
49
|
+
this.hooks.hook('frontgateConnection:reset', () => {
|
|
50
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
51
|
+
__classPrivateFieldGet(this, _compressor, "f").reset();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
this.hooks.hook('frontgateConnection:beforeSendMessage', (data) => {
|
|
55
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
56
|
+
const compressed = __classPrivateFieldGet(this, _compressor, "f").compress(data.msg);
|
|
57
|
+
data.msg = compressed;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
this.hooks.hook('frontgateConnection:afterReceiveMessage', (data) => {
|
|
61
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
62
|
+
const decompressed = __classPrivateFieldGet(this, _compressor, "f").decompress(new Uint8Array(data.msg));
|
|
63
|
+
data.msg = decompressed;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
this.hooks.hook('frontgateConnection:beforeConnect', async (settings) => {
|
|
67
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', ID_APP_AUTHENTICATED);
|
|
68
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
|
|
69
|
+
this.log(LogLevel.DEBUG, 'Fetching connection configuration');
|
|
70
|
+
const fetchConfig = await __classPrivateFieldGet(this, _instances, "m", _fetchConnectionConfiguration).call(this);
|
|
71
|
+
this.log(LogLevel.DEBUG, 'Connection configuration received', fetchConfig);
|
|
72
|
+
settings.url = fetchConfig.url;
|
|
73
|
+
if (fetchConfig.authtenticationType === 'token' && fetchConfig.authenticationToken) {
|
|
74
|
+
__classPrivateFieldSet(this, _token, fetchConfig.authenticationToken, "f");
|
|
75
|
+
}
|
|
76
|
+
else if (fetchConfig.splitAuthenticationTokenSecondFactor) {
|
|
77
|
+
__classPrivateFieldSet(this, _secondFactor, fetchConfig.splitAuthenticationTokenSecondFactor, "f");
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
throw new Error('Invalid authentication configuration');
|
|
81
|
+
}
|
|
82
|
+
this.log(LogLevel.DEBUG, 'Adding mdg2auth subprotocol');
|
|
83
|
+
if (__classPrivateFieldGet(this, _secondFactor, "f") !== '') {
|
|
84
|
+
settings.subProtocols.push(`mdg2auth-${__classPrivateFieldGet(this, _secondFactor, "f")}`);
|
|
85
|
+
}
|
|
86
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
87
|
+
settings.subProtocols.forEach((protocol, index) => {
|
|
88
|
+
if (protocol.includes('jsjson') && !protocol.includes('jsjsonc')) {
|
|
89
|
+
settings.subProtocols[index] = protocol.replace('jsjson', 'jsjsonc');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
const authFn = async (conf) => {
|
|
95
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', ID_APP_AUTHENTICATED);
|
|
96
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
|
|
97
|
+
const options = {
|
|
98
|
+
maximum_idle_interval: conf.maximumIdleInterval,
|
|
99
|
+
};
|
|
100
|
+
const tokenData = { b64: __classPrivateFieldGet(this, _token, "f") };
|
|
101
|
+
const request = new AuthenticationByTokenRequest(tokenData, options.maximum_idle_interval);
|
|
102
|
+
const message = request.toJson();
|
|
103
|
+
this.log(LogLevel.INFO, 'Sending message', message);
|
|
104
|
+
const msg = {
|
|
105
|
+
message,
|
|
106
|
+
callbackType: 'response',
|
|
107
|
+
callbackId: message.Message.replace('Request', 'Response'),
|
|
108
|
+
};
|
|
109
|
+
await this.hooks.callHook('frontgateConnection:sendMessage', msg);
|
|
110
|
+
this.hooks.hookOnce(`frontgateConnection:response:${msg.callbackId}`, (response) => {
|
|
111
|
+
this.log(LogLevel.INFO, 'Received response', response);
|
|
112
|
+
void this.hooks.callHook('frontgateConnection:authenticated');
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
this.hooks.hook('frontgateConnection:connected', authFn);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
_token = new WeakMap(),
|
|
119
|
+
_secondFactor = new WeakMap(),
|
|
120
|
+
_shouldCompress = new WeakMap(),
|
|
121
|
+
_compressor = new WeakMap(),
|
|
122
|
+
_requestInfo = new WeakMap(),
|
|
123
|
+
_requestInit = new WeakMap(),
|
|
124
|
+
_instances = new WeakSet(),
|
|
125
|
+
_fetchConnectionConfiguration = async function _fetchConnectionConfiguration() {
|
|
126
|
+
const response = await fetch(__classPrivateFieldGet(this, _requestInfo, "f"), __classPrivateFieldGet(this, _requestInit, "f"));
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
throw new Error(`Failed to fetch connection configuration: ${response.status} ${response.statusText}`);
|
|
129
|
+
}
|
|
130
|
+
const { headers } = response;
|
|
131
|
+
const host = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_HOST);
|
|
132
|
+
const pathPrefix = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_PATH_PREFIX);
|
|
133
|
+
const splitAuthenticationTokenSecondFactor = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR);
|
|
134
|
+
const authenticationType = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TYPE);
|
|
135
|
+
const authenticationToken = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TOKEN);
|
|
136
|
+
const port = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PORT) ?? '443';
|
|
137
|
+
const url = `wss://${host}:${port}${pathPrefix ?? ''}/ws`;
|
|
138
|
+
if (authenticationType === 'token' && !authenticationToken) {
|
|
139
|
+
throw new Error('Authentication token is required for token authentication');
|
|
140
|
+
}
|
|
141
|
+
if (authenticationType !== 'token' && !splitAuthenticationTokenSecondFactor) {
|
|
142
|
+
throw new Error('Split authentication token second factor is required');
|
|
143
|
+
}
|
|
144
|
+
const protocol = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PROTOCOL);
|
|
145
|
+
if (protocol === 'jsjsonc-v2') {
|
|
146
|
+
__classPrivateFieldSet(this, _shouldCompress, true, "f");
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
__classPrivateFieldSet(this, _shouldCompress, false, "f");
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
url,
|
|
153
|
+
authtenticationType: authenticationType,
|
|
154
|
+
authenticationToken,
|
|
155
|
+
splitAuthenticationTokenSecondFactor,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
_a;
|
|
159
|
+
};
|
|
160
|
+
return createExtendedMixinFactory(mixinFetchAuth, {
|
|
161
|
+
featureName: 'FetchAuthWithOptionalCompressor',
|
|
162
|
+
featureGroups: ['Auth', 'Connection'],
|
|
163
|
+
disabledFeatureGroups: ['Auth', 'Connection', 'Compression'],
|
|
164
|
+
});
|
|
165
|
+
};
|
|
@@ -30,12 +30,27 @@ export const sessionAuth = (config, idApplication, username, password, deploymen
|
|
|
30
30
|
_mdg2wstoken.set(this, void 0);
|
|
31
31
|
_sharedSecret.set(this, void 0);
|
|
32
32
|
_clientSecret.set(this, void 0);
|
|
33
|
+
this.connect = async () => {
|
|
34
|
+
__classPrivateFieldSet(this, _logOut, false, "f");
|
|
35
|
+
try {
|
|
36
|
+
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
37
|
+
await super.connect();
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
__classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
|
|
41
|
+
await super.connect();
|
|
42
|
+
const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
|
|
43
|
+
__classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
|
|
44
|
+
await super.disconnect();
|
|
45
|
+
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
46
|
+
await super.connect();
|
|
47
|
+
__classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
|
|
48
|
+
}
|
|
49
|
+
};
|
|
33
50
|
const plainSharedSecret = SecretGenerator.generateSharedSecret(username, password);
|
|
34
51
|
const plainClientSecret = SecretGenerator.generateClientSecret(username, password);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
38
|
-
}
|
|
52
|
+
__classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
|
|
53
|
+
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
39
54
|
this.hooks.hook('frontgateConnection:beforeConnect', (settings) => {
|
|
40
55
|
void this.hooks.callHook('frontgateConnection:setIdApp', ID_APP_AUTHENTICATED);
|
|
41
56
|
void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
|
|
@@ -83,23 +98,6 @@ export const sessionAuth = (config, idApplication, username, password, deploymen
|
|
|
83
98
|
await this.hooks.callHook('frontgateConnection:authenticated');
|
|
84
99
|
});
|
|
85
100
|
}
|
|
86
|
-
async connect() {
|
|
87
|
-
__classPrivateFieldSet(this, _logOut, false, "f");
|
|
88
|
-
try {
|
|
89
|
-
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
90
|
-
await super.connect();
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
__classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
|
|
94
|
-
await super.connect();
|
|
95
|
-
const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
|
|
96
|
-
__classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
|
|
97
|
-
await super.disconnect();
|
|
98
|
-
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
99
|
-
await super.connect();
|
|
100
|
-
__classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
101
|
async connectSession() {
|
|
104
102
|
__classPrivateFieldSet(this, _logOut, false, "f");
|
|
105
103
|
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
@@ -26,10 +26,8 @@ export const userPasswordAuth = (idApplication, username, password, deploymentSt
|
|
|
26
26
|
_clientSecret.set(this, void 0);
|
|
27
27
|
const plainSharedSecret = SecretGenerator.generateSharedSecret(username, password);
|
|
28
28
|
const plainClientSecret = SecretGenerator.generateClientSecret(username, password);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
32
|
-
}
|
|
29
|
+
__classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
|
|
30
|
+
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
33
31
|
this.hooks.hook('frontgateConnection:connected', async (conf) => {
|
|
34
32
|
void this.hooks.callHook('frontgateConnection:setIdApp', idApplication);
|
|
35
33
|
void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
|
|
@@ -34,7 +34,7 @@ export const wsConnection = (conf) => {
|
|
|
34
34
|
_jobId.set(this, 0);
|
|
35
35
|
_idApplication.set(this, void 0);
|
|
36
36
|
_idUser.set(this, void 0);
|
|
37
|
-
_message_buffer_size.set(this,
|
|
37
|
+
_message_buffer_size.set(this, 0);
|
|
38
38
|
_msgBuffer.set(this, []);
|
|
39
39
|
__classPrivateFieldSet(this, _idApplication, ID_APP_AUTHENTICATED, "f");
|
|
40
40
|
__classPrivateFieldSet(this, _idUser, ID_USER_NONE, "f");
|
|
@@ -111,7 +111,7 @@ export const endpointSubscriptions = (originalConfig) => {
|
|
|
111
111
|
observer.idJob = resp.header.id_job;
|
|
112
112
|
if (subscriptionZombie) {
|
|
113
113
|
this.log(LogLevel.WARN, `Zombie subscription detected for ${key}. Initiating unsubscribe.`);
|
|
114
|
-
observer.unsubscribe();
|
|
114
|
+
observer.unsubscribe?.();
|
|
115
115
|
res();
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PACKAGE_JSON = { version: '7.
|
|
1
|
+
export const PACKAGE_JSON = { version: '7.1.1', package: '@factset/frontgate-js-sdk' };
|
|
@@ -16,7 +16,9 @@ class WinstonLogger extends AbstractLogger_1.AbstractLogger {
|
|
|
16
16
|
super(name);
|
|
17
17
|
this.name = name;
|
|
18
18
|
this.logger = logger;
|
|
19
|
-
|
|
19
|
+
if (logger.trace) {
|
|
20
|
+
this.trace = Function.prototype.bind.call(logger.trace, logger);
|
|
21
|
+
}
|
|
20
22
|
this.debug = Function.prototype.bind.call(logger.debug, logger);
|
|
21
23
|
this.info = Function.prototype.bind.call(logger.info, logger);
|
|
22
24
|
this.warn = Function.prototype.bind.call(logger.warn, logger);
|
|
@@ -43,7 +43,7 @@ const messageCompressor = () => {
|
|
|
43
43
|
};
|
|
44
44
|
return (0, _1.createExtendedMixinFactory)(mixinCompressor, {
|
|
45
45
|
featureName: 'MessageCompressor',
|
|
46
|
-
featureGroups: ['
|
|
46
|
+
featureGroups: ['Compression'],
|
|
47
47
|
});
|
|
48
48
|
};
|
|
49
49
|
exports.messageCompressor = messageCompressor;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.fetchAuthWithOptionalCompressor = void 0;
|
|
15
|
+
const authentication_1 = require("../../authentication");
|
|
16
|
+
const Compressor_1 = require("../../connection/util/Compressor");
|
|
17
|
+
const logger_1 = require("../../logger");
|
|
18
|
+
const AuthenticationByTokenRequest_1 = require("../../message/request/AuthenticationByTokenRequest");
|
|
19
|
+
const _1 = require("../.");
|
|
20
|
+
var FetchConnectionConfigurationResponseHeaders;
|
|
21
|
+
(function (FetchConnectionConfigurationResponseHeaders) {
|
|
22
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_HOST"] = "frontgate-host";
|
|
23
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_PATH_PREFIX"] = "frontgate-path-prefix";
|
|
24
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR"] = "frontgate-split-authentication-token-second-factor";
|
|
25
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TYPE"] = "frontgate-authentication-type";
|
|
26
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TOKEN"] = "frontgate-authentication-token";
|
|
27
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PORT"] = "frontgate-websocket-port";
|
|
28
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PROTOCOL"] = "frontgate-websocket-protocol";
|
|
29
|
+
})(FetchConnectionConfigurationResponseHeaders || (FetchConnectionConfigurationResponseHeaders = {}));
|
|
30
|
+
const fetchAuthWithOptionalCompressor = (config, input, init) => {
|
|
31
|
+
const mixinFetchAuth = (Base) => {
|
|
32
|
+
var _instances, _token, _secondFactor, _shouldCompress, _compressor, _requestInfo, _requestInit, _fetchConnectionConfiguration, _a;
|
|
33
|
+
return _a = class extends (0, _1.wsConnection)({
|
|
34
|
+
host: '',
|
|
35
|
+
pathPrefix: '',
|
|
36
|
+
port: 0,
|
|
37
|
+
tls: true,
|
|
38
|
+
maximumIdleIntervalInS: config.maximumIdleIntervalInS,
|
|
39
|
+
})(Base) {
|
|
40
|
+
constructor(...args) {
|
|
41
|
+
super(...args);
|
|
42
|
+
_instances.add(this);
|
|
43
|
+
_token.set(this, '');
|
|
44
|
+
_secondFactor.set(this, '');
|
|
45
|
+
_shouldCompress.set(this, false);
|
|
46
|
+
_compressor.set(this, void 0);
|
|
47
|
+
_requestInfo.set(this, void 0);
|
|
48
|
+
_requestInit.set(this, void 0);
|
|
49
|
+
__classPrivateFieldSet(this, _requestInfo, input, "f");
|
|
50
|
+
__classPrivateFieldSet(this, _requestInit, init, "f");
|
|
51
|
+
__classPrivateFieldSet(this, _compressor, new Compressor_1.Compressor(), "f");
|
|
52
|
+
this.hooks.hook('frontgateConnection:reset', () => {
|
|
53
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
54
|
+
__classPrivateFieldGet(this, _compressor, "f").reset();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
this.hooks.hook('frontgateConnection:beforeSendMessage', (data) => {
|
|
58
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
59
|
+
const compressed = __classPrivateFieldGet(this, _compressor, "f").compress(data.msg);
|
|
60
|
+
data.msg = compressed;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
this.hooks.hook('frontgateConnection:afterReceiveMessage', (data) => {
|
|
64
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
65
|
+
const decompressed = __classPrivateFieldGet(this, _compressor, "f").decompress(new Uint8Array(data.msg));
|
|
66
|
+
data.msg = decompressed;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
this.hooks.hook('frontgateConnection:beforeConnect', async (settings) => {
|
|
70
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', authentication_1.ID_APP_AUTHENTICATED);
|
|
71
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
|
|
72
|
+
this.log(logger_1.LogLevel.DEBUG, 'Fetching connection configuration');
|
|
73
|
+
const fetchConfig = await __classPrivateFieldGet(this, _instances, "m", _fetchConnectionConfiguration).call(this);
|
|
74
|
+
this.log(logger_1.LogLevel.DEBUG, 'Connection configuration received', fetchConfig);
|
|
75
|
+
settings.url = fetchConfig.url;
|
|
76
|
+
if (fetchConfig.authtenticationType === 'token' && fetchConfig.authenticationToken) {
|
|
77
|
+
__classPrivateFieldSet(this, _token, fetchConfig.authenticationToken, "f");
|
|
78
|
+
}
|
|
79
|
+
else if (fetchConfig.splitAuthenticationTokenSecondFactor) {
|
|
80
|
+
__classPrivateFieldSet(this, _secondFactor, fetchConfig.splitAuthenticationTokenSecondFactor, "f");
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw new Error('Invalid authentication configuration');
|
|
84
|
+
}
|
|
85
|
+
this.log(logger_1.LogLevel.DEBUG, 'Adding mdg2auth subprotocol');
|
|
86
|
+
if (__classPrivateFieldGet(this, _secondFactor, "f") !== '') {
|
|
87
|
+
settings.subProtocols.push(`mdg2auth-${__classPrivateFieldGet(this, _secondFactor, "f")}`);
|
|
88
|
+
}
|
|
89
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
90
|
+
settings.subProtocols.forEach((protocol, index) => {
|
|
91
|
+
if (protocol.includes('jsjson') && !protocol.includes('jsjsonc')) {
|
|
92
|
+
settings.subProtocols[index] = protocol.replace('jsjson', 'jsjsonc');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const authFn = async (conf) => {
|
|
98
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', authentication_1.ID_APP_AUTHENTICATED);
|
|
99
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
|
|
100
|
+
const options = {
|
|
101
|
+
maximum_idle_interval: conf.maximumIdleInterval,
|
|
102
|
+
};
|
|
103
|
+
const tokenData = { b64: __classPrivateFieldGet(this, _token, "f") };
|
|
104
|
+
const request = new AuthenticationByTokenRequest_1.AuthenticationByTokenRequest(tokenData, options.maximum_idle_interval);
|
|
105
|
+
const message = request.toJson();
|
|
106
|
+
this.log(logger_1.LogLevel.INFO, 'Sending message', message);
|
|
107
|
+
const msg = {
|
|
108
|
+
message,
|
|
109
|
+
callbackType: 'response',
|
|
110
|
+
callbackId: message.Message.replace('Request', 'Response'),
|
|
111
|
+
};
|
|
112
|
+
await this.hooks.callHook('frontgateConnection:sendMessage', msg);
|
|
113
|
+
this.hooks.hookOnce(`frontgateConnection:response:${msg.callbackId}`, (response) => {
|
|
114
|
+
this.log(logger_1.LogLevel.INFO, 'Received response', response);
|
|
115
|
+
void this.hooks.callHook('frontgateConnection:authenticated');
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
this.hooks.hook('frontgateConnection:connected', authFn);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
_token = new WeakMap(),
|
|
122
|
+
_secondFactor = new WeakMap(),
|
|
123
|
+
_shouldCompress = new WeakMap(),
|
|
124
|
+
_compressor = new WeakMap(),
|
|
125
|
+
_requestInfo = new WeakMap(),
|
|
126
|
+
_requestInit = new WeakMap(),
|
|
127
|
+
_instances = new WeakSet(),
|
|
128
|
+
_fetchConnectionConfiguration = async function _fetchConnectionConfiguration() {
|
|
129
|
+
const response = await fetch(__classPrivateFieldGet(this, _requestInfo, "f"), __classPrivateFieldGet(this, _requestInit, "f"));
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
throw new Error(`Failed to fetch connection configuration: ${response.status} ${response.statusText}`);
|
|
132
|
+
}
|
|
133
|
+
const { headers } = response;
|
|
134
|
+
const host = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_HOST);
|
|
135
|
+
const pathPrefix = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_PATH_PREFIX);
|
|
136
|
+
const splitAuthenticationTokenSecondFactor = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR);
|
|
137
|
+
const authenticationType = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TYPE);
|
|
138
|
+
const authenticationToken = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TOKEN);
|
|
139
|
+
const port = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PORT) ?? '443';
|
|
140
|
+
const url = `wss://${host}:${port}${pathPrefix ?? ''}/ws`;
|
|
141
|
+
if (authenticationType === 'token' && !authenticationToken) {
|
|
142
|
+
throw new Error('Authentication token is required for token authentication');
|
|
143
|
+
}
|
|
144
|
+
if (authenticationType !== 'token' && !splitAuthenticationTokenSecondFactor) {
|
|
145
|
+
throw new Error('Split authentication token second factor is required');
|
|
146
|
+
}
|
|
147
|
+
const protocol = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PROTOCOL);
|
|
148
|
+
if (protocol === 'jsjsonc-v2') {
|
|
149
|
+
__classPrivateFieldSet(this, _shouldCompress, true, "f");
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
__classPrivateFieldSet(this, _shouldCompress, false, "f");
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
url,
|
|
156
|
+
authtenticationType: authenticationType,
|
|
157
|
+
authenticationToken,
|
|
158
|
+
splitAuthenticationTokenSecondFactor,
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
_a;
|
|
162
|
+
};
|
|
163
|
+
return (0, _1.createExtendedMixinFactory)(mixinFetchAuth, {
|
|
164
|
+
featureName: 'FetchAuthWithOptionalCompressor',
|
|
165
|
+
featureGroups: ['Auth', 'Connection'],
|
|
166
|
+
disabledFeatureGroups: ['Auth', 'Connection', 'Compression'],
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
exports.fetchAuthWithOptionalCompressor = fetchAuthWithOptionalCompressor;
|
|
@@ -33,12 +33,27 @@ const sessionAuth = (config, idApplication, username, password, deploymentStage)
|
|
|
33
33
|
_mdg2wstoken.set(this, void 0);
|
|
34
34
|
_sharedSecret.set(this, void 0);
|
|
35
35
|
_clientSecret.set(this, void 0);
|
|
36
|
+
this.connect = async () => {
|
|
37
|
+
__classPrivateFieldSet(this, _logOut, false, "f");
|
|
38
|
+
try {
|
|
39
|
+
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
40
|
+
await super.connect();
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
__classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
|
|
44
|
+
await super.connect();
|
|
45
|
+
const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
|
|
46
|
+
__classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
|
|
47
|
+
await super.disconnect();
|
|
48
|
+
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
49
|
+
await super.connect();
|
|
50
|
+
__classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
|
|
51
|
+
}
|
|
52
|
+
};
|
|
36
53
|
const plainSharedSecret = compat_1.SecretGenerator.generateSharedSecret(username, password);
|
|
37
54
|
const plainClientSecret = compat_1.SecretGenerator.generateClientSecret(username, password);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
41
|
-
}
|
|
55
|
+
__classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
|
|
56
|
+
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
42
57
|
this.hooks.hook('frontgateConnection:beforeConnect', (settings) => {
|
|
43
58
|
void this.hooks.callHook('frontgateConnection:setIdApp', authentication_1.ID_APP_AUTHENTICATED);
|
|
44
59
|
void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
|
|
@@ -86,23 +101,6 @@ const sessionAuth = (config, idApplication, username, password, deploymentStage)
|
|
|
86
101
|
await this.hooks.callHook('frontgateConnection:authenticated');
|
|
87
102
|
});
|
|
88
103
|
}
|
|
89
|
-
async connect() {
|
|
90
|
-
__classPrivateFieldSet(this, _logOut, false, "f");
|
|
91
|
-
try {
|
|
92
|
-
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
93
|
-
await super.connect();
|
|
94
|
-
}
|
|
95
|
-
catch (e) {
|
|
96
|
-
__classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
|
|
97
|
-
await super.connect();
|
|
98
|
-
const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
|
|
99
|
-
__classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
|
|
100
|
-
await super.disconnect();
|
|
101
|
-
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
102
|
-
await super.connect();
|
|
103
|
-
__classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
104
|
async connectSession() {
|
|
107
105
|
__classPrivateFieldSet(this, _logOut, false, "f");
|
|
108
106
|
__classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
|
|
@@ -29,10 +29,8 @@ const userPasswordAuth = (idApplication, username, password, deploymentStage) =>
|
|
|
29
29
|
_clientSecret.set(this, void 0);
|
|
30
30
|
const plainSharedSecret = compat_1.SecretGenerator.generateSharedSecret(username, password);
|
|
31
31
|
const plainClientSecret = compat_1.SecretGenerator.generateClientSecret(username, password);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
35
|
-
}
|
|
32
|
+
__classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
|
|
33
|
+
__classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
|
|
36
34
|
this.hooks.hook('frontgateConnection:connected', async (conf) => {
|
|
37
35
|
void this.hooks.callHook('frontgateConnection:setIdApp', idApplication);
|
|
38
36
|
void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
|
|
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./CookieTokenAuthMixin"), exports);
|
|
18
18
|
__exportStar(require("./TokenAuthMixin"), exports);
|
|
19
19
|
__exportStar(require("./FetchAuthenticationMixin"), exports);
|
|
20
|
+
__exportStar(require("./FetchAuthenticationWithOptionalCompressionMixin"), exports);
|
|
@@ -40,7 +40,7 @@ const wsConnection = (conf) => {
|
|
|
40
40
|
_jobId.set(this, 0);
|
|
41
41
|
_idApplication.set(this, void 0);
|
|
42
42
|
_idUser.set(this, void 0);
|
|
43
|
-
_message_buffer_size.set(this,
|
|
43
|
+
_message_buffer_size.set(this, 0);
|
|
44
44
|
_msgBuffer.set(this, []);
|
|
45
45
|
__classPrivateFieldSet(this, _idApplication, authentication_1.ID_APP_AUTHENTICATED, "f");
|
|
46
46
|
__classPrivateFieldSet(this, _idUser, authentication_1.ID_USER_NONE, "f");
|
|
@@ -114,7 +114,7 @@ const endpointSubscriptions = (originalConfig) => {
|
|
|
114
114
|
observer.idJob = resp.header.id_job;
|
|
115
115
|
if (subscriptionZombie) {
|
|
116
116
|
this.log(logger_1.LogLevel.WARN, `Zombie subscription detected for ${key}. Initiating unsubscribe.`);
|
|
117
|
-
observer.unsubscribe();
|
|
117
|
+
observer.unsubscribe?.();
|
|
118
118
|
res();
|
|
119
119
|
return;
|
|
120
120
|
}
|
package/dist/lib/node/version.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PACKAGE_JSON = void 0;
|
|
4
|
-
exports.PACKAGE_JSON = { version: '7.
|
|
4
|
+
exports.PACKAGE_JSON = { version: '7.1.1', package: '@factset/frontgate-js-sdk' };
|