node-opcua-client 2.183.1 → 2.184.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/dist/alarms_and_conditions/client_alarm_tools.d.ts +1 -0
- package/dist/alarms_and_conditions/client_alarm_tools.d.ts.map +1 -0
- package/dist/alarms_and_conditions/client_alarm_tools.js +23 -27
- package/dist/alarms_and_conditions/client_alarm_tools.js.map +1 -1
- package/dist/alarms_and_conditions/client_tools.d.ts +1 -0
- package/dist/alarms_and_conditions/client_tools.d.ts.map +1 -0
- package/dist/alarms_and_conditions/client_tools.js +17 -19
- package/dist/alarms_and_conditions/client_tools.js.map +1 -1
- package/dist/client_base.d.ts +1 -0
- package/dist/client_base.d.ts.map +1 -0
- package/dist/client_base.js +3 -6
- package/dist/client_base.js.map +1 -1
- package/dist/client_monitored_item.d.ts +1 -0
- package/dist/client_monitored_item.d.ts.map +1 -0
- package/dist/client_monitored_item.js +4 -7
- package/dist/client_monitored_item.js.map +1 -1
- package/dist/client_monitored_item_base.d.ts +1 -0
- package/dist/client_monitored_item_base.d.ts.map +1 -0
- package/dist/client_monitored_item_base.js +1 -2
- package/dist/client_monitored_item_group.d.ts +1 -0
- package/dist/client_monitored_item_group.d.ts.map +1 -0
- package/dist/client_monitored_item_group.js +2 -5
- package/dist/client_monitored_item_group.js.map +1 -1
- package/dist/client_monitored_item_toolbox.d.ts +1 -0
- package/dist/client_monitored_item_toolbox.d.ts.map +1 -0
- package/dist/client_monitored_item_toolbox.js +21 -27
- package/dist/client_monitored_item_toolbox.js.map +1 -1
- package/dist/client_session.d.ts +2 -1
- package/dist/client_session.d.ts.map +1 -0
- package/dist/client_session.js +2 -7
- package/dist/client_session.js.map +1 -1
- package/dist/client_session_keepalive_manager.d.ts +1 -0
- package/dist/client_session_keepalive_manager.d.ts.map +1 -0
- package/dist/client_session_keepalive_manager.js +24 -31
- package/dist/client_session_keepalive_manager.js.map +1 -1
- package/dist/client_subscription.d.ts +1 -0
- package/dist/client_subscription.d.ts.map +1 -0
- package/dist/client_subscription.js +1 -5
- package/dist/client_subscription.js.map +1 -1
- package/dist/client_utils.d.ts +1 -0
- package/dist/client_utils.d.ts.map +1 -0
- package/dist/client_utils.js +7 -10
- package/dist/client_utils.js.map +1 -1
- package/dist/common.d.ts +1 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +1 -2
- package/dist/common.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -118
- package/dist/index.js.map +1 -1
- package/dist/opcua_client.d.ts +1 -0
- package/dist/opcua_client.d.ts.map +1 -0
- package/dist/opcua_client.js +6 -10
- package/dist/opcua_client.js.map +1 -1
- package/dist/private/client_base_impl.d.ts +1 -0
- package/dist/private/client_base_impl.d.ts.map +1 -0
- package/dist/private/client_base_impl.js +146 -150
- package/dist/private/client_base_impl.js.map +1 -1
- package/dist/private/client_monitored_item_base_impl.d.ts +1 -0
- package/dist/private/client_monitored_item_base_impl.d.ts.map +1 -0
- package/dist/private/client_monitored_item_base_impl.js +1 -2
- package/dist/private/client_monitored_item_base_impl.js.map +1 -1
- package/dist/private/client_monitored_item_group_impl.d.ts +1 -0
- package/dist/private/client_monitored_item_group_impl.d.ts.map +1 -0
- package/dist/private/client_monitored_item_group_impl.js +31 -35
- package/dist/private/client_monitored_item_group_impl.js.map +1 -1
- package/dist/private/client_monitored_item_impl.d.ts +1 -0
- package/dist/private/client_monitored_item_impl.d.ts.map +1 -0
- package/dist/private/client_monitored_item_impl.js +41 -45
- package/dist/private/client_monitored_item_impl.js.map +1 -1
- package/dist/private/client_publish_engine.d.ts +1 -0
- package/dist/private/client_publish_engine.d.ts.map +1 -0
- package/dist/private/client_publish_engine.js +47 -54
- package/dist/private/client_publish_engine.js.map +1 -1
- package/dist/private/client_session_impl.d.ts +1 -0
- package/dist/private/client_session_impl.d.ts.map +1 -0
- package/dist/private/client_session_impl.js +231 -238
- package/dist/private/client_session_impl.js.map +1 -1
- package/dist/private/client_subscription_impl.d.ts +1 -0
- package/dist/private/client_subscription_impl.d.ts.map +1 -0
- package/dist/private/client_subscription_impl.js +93 -102
- package/dist/private/client_subscription_impl.js.map +1 -1
- package/dist/private/i_private_client.d.ts +1 -0
- package/dist/private/i_private_client.d.ts.map +1 -0
- package/dist/private/i_private_client.js +1 -2
- package/dist/private/opcua_client_impl.d.ts +1 -0
- package/dist/private/opcua_client_impl.d.ts.map +1 -0
- package/dist/private/opcua_client_impl.js +138 -145
- package/dist/private/opcua_client_impl.js.map +1 -1
- package/dist/private/performance.d.ts +1 -0
- package/dist/private/performance.d.ts.map +1 -0
- package/dist/private/performance.js +1 -4
- package/dist/private/performance.js.map +1 -1
- package/dist/private/reconnection/client_publish_engine_reconnection.d.ts +1 -0
- package/dist/private/reconnection/client_publish_engine_reconnection.d.ts.map +1 -0
- package/dist/private/reconnection/client_publish_engine_reconnection.js +28 -34
- package/dist/private/reconnection/client_publish_engine_reconnection.js.map +1 -1
- package/dist/private/reconnection/client_reconnection.d.ts +1 -0
- package/dist/private/reconnection/client_reconnection.d.ts.map +1 -0
- package/dist/private/reconnection/client_reconnection.js +1 -4
- package/dist/private/reconnection/client_reconnection.js.map +1 -1
- package/dist/private/reconnection/client_subscription_reconnection.d.ts +1 -0
- package/dist/private/reconnection/client_subscription_reconnection.d.ts.map +1 -0
- package/dist/private/reconnection/client_subscription_reconnection.js +25 -31
- package/dist/private/reconnection/client_subscription_reconnection.js.map +1 -1
- package/dist/private/reconnection/reconnection.d.ts +1 -0
- package/dist/private/reconnection/reconnection.d.ts.map +1 -0
- package/dist/private/reconnection/reconnection.js +50 -59
- package/dist/private/reconnection/reconnection.js.map +1 -1
- package/dist/reverse/client_reverse_connect.d.ts +1 -0
- package/dist/reverse/client_reverse_connect.d.ts.map +1 -0
- package/dist/reverse/client_reverse_connect.js +20 -24
- package/dist/reverse/client_reverse_connect.js.map +1 -1
- package/dist/tools/findservers.d.ts +1 -0
- package/dist/tools/findservers.d.ts.map +1 -0
- package/dist/tools/findservers.js +7 -13
- package/dist/tools/findservers.js.map +1 -1
- package/dist/tools/read_history_server_capabilities.d.ts +1 -0
- package/dist/tools/read_history_server_capabilities.d.ts.map +1 -0
- package/dist/tools/read_history_server_capabilities.js +13 -16
- package/dist/tools/read_history_server_capabilities.js.map +1 -1
- package/dist/user_identity_info.d.ts +2 -1
- package/dist/user_identity_info.d.ts.map +1 -0
- package/dist/user_identity_info.js +1 -2
- package/dist/verify.d.ts +1 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +15 -19
- package/dist/verify.js.map +1 -1
- package/package.json +48 -47
- package/source/alarms_and_conditions/client_alarm_tools.ts +1 -1
- package/source/client_monitored_item_toolbox.ts +1 -1
- package/source/client_session.ts +1 -1
- package/source/index.ts +5 -3
- package/source/private/client_base_impl.ts +5 -2
- package/source/private/client_publish_engine.ts +16 -16
- package/source/private/client_subscription_impl.ts +1 -1
- package/source/private/opcua_client_impl.ts +4 -4
- package/source/private/reconnection/client_publish_engine_reconnection.ts +7 -7
- package/source/private/reconnection/client_subscription_reconnection.ts +5 -5
- package/source/private/reconnection/reconnection.ts +3 -3
- package/source/reverse/client_reverse_connect.ts +1 -1
- package/source/user_identity_info.ts +1 -1
|
@@ -1,36 +1,30 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @module node-opcua-client-private
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const reconnection_js_1 = require("./reconnection/reconnection.js");
|
|
30
|
-
const doDebug = (0, node_opcua_debug_1.checkDebugFlag)("opcua_client_impl");
|
|
31
|
-
const debugLog = (0, node_opcua_debug_1.make_debugLog)("opcua_client_impl");
|
|
32
|
-
const errorLog = (0, node_opcua_debug_1.make_errorLog)("opcua_client_impl");
|
|
33
|
-
const warningLog = (0, node_opcua_debug_1.make_warningLog)("opcua_client_impl");
|
|
4
|
+
import { createPublicKey } from "node:crypto";
|
|
5
|
+
import { callbackify } from "node:util";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import { assert } from "node-opcua-assert";
|
|
8
|
+
import { DataTypeExtractStrategy } from "node-opcua-client-dynamic-extension-object";
|
|
9
|
+
import { combine_der, exploreCertificate, extractPublicKeyFromCertificateSync, makePrivateKeyFromPem, toPem } from "node-opcua-crypto/web";
|
|
10
|
+
import { LocalizedText } from "node-opcua-data-model";
|
|
11
|
+
import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
12
|
+
import { extractFullyQualifiedDomainName } from "node-opcua-hostname";
|
|
13
|
+
import { readNamespaceArray } from "node-opcua-pseudo-session";
|
|
14
|
+
import { computeSignatureAsync, fromURI, getCryptoFactory, SecurityPolicy } from "node-opcua-secure-channel";
|
|
15
|
+
import { ApplicationType, EndpointDescription, UserTokenType } from "node-opcua-service-endpoints";
|
|
16
|
+
import { MessageSecurityMode } from "node-opcua-service-secure-channel";
|
|
17
|
+
import { ActivateSessionRequest, ActivateSessionResponse, AnonymousIdentityToken, CreateSessionRequest, CreateSessionResponse, UserNameIdentityToken, X509IdentityToken } from "node-opcua-service-session";
|
|
18
|
+
import { StatusCodes } from "node-opcua-status-code";
|
|
19
|
+
import { isNullOrUndefined, matchUri, randomBytes } from "node-opcua-utils";
|
|
20
|
+
import { OPCUAClient } from "../opcua_client.js";
|
|
21
|
+
import { ClientBaseImpl } from "./client_base_impl.js";
|
|
22
|
+
import { ClientSessionImpl } from "./client_session_impl.js";
|
|
23
|
+
import { repair_client_sessions } from "./reconnection/reconnection.js";
|
|
24
|
+
const doDebug = checkDebugFlag("opcua_client_impl");
|
|
25
|
+
const debugLog = make_debugLog("opcua_client_impl");
|
|
26
|
+
const errorLog = make_errorLog("opcua_client_impl");
|
|
27
|
+
const warningLog = make_warningLog("opcua_client_impl");
|
|
34
28
|
let x509PemPrivateKeyWarningEmitted = false;
|
|
35
29
|
function warnOnceAboutX509PemPrivateKey() {
|
|
36
30
|
if (x509PemPrivateKeyWarningEmitted) {
|
|
@@ -61,21 +55,21 @@ function verifyEndpointDescriptionMatches(_client, _responseServerEndpoints) {
|
|
|
61
55
|
return true;
|
|
62
56
|
}
|
|
63
57
|
const hasDeprecatedSecurityPolicy = (userIdentity) => {
|
|
64
|
-
return (userIdentity.securityPolicyUri ===
|
|
65
|
-
userIdentity.securityPolicyUri ===
|
|
58
|
+
return (userIdentity.securityPolicyUri === SecurityPolicy.Basic128Rsa15 ||
|
|
59
|
+
userIdentity.securityPolicyUri === SecurityPolicy.Basic128);
|
|
66
60
|
};
|
|
67
61
|
const ordered = [
|
|
68
62
|
// obsolete
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
SecurityPolicy.Basic128Rsa15,
|
|
64
|
+
SecurityPolicy.Basic192Rsa15,
|
|
65
|
+
SecurityPolicy.Basic256,
|
|
66
|
+
SecurityPolicy.None,
|
|
67
|
+
SecurityPolicy.Basic128,
|
|
68
|
+
SecurityPolicy.Basic192,
|
|
69
|
+
SecurityPolicy.Basic256Rsa15,
|
|
70
|
+
SecurityPolicy.Basic256Sha256,
|
|
71
|
+
SecurityPolicy.Aes128_Sha256_RsaOaep,
|
|
72
|
+
SecurityPolicy.Aes256_Sha256_RsaPss
|
|
79
73
|
];
|
|
80
74
|
const _compareSecurityPolicy = (a, b) => {
|
|
81
75
|
if (a === b) {
|
|
@@ -108,9 +102,9 @@ function findUserTokenPolicy(endpointDescription, userTokenType) {
|
|
|
108
102
|
r = r.filter((userIdentity) => !hasDeprecatedSecurityPolicy(userIdentity));
|
|
109
103
|
}
|
|
110
104
|
if (r.length > 1) {
|
|
111
|
-
if (endpointDescription.securityMode ===
|
|
105
|
+
if (endpointDescription.securityMode === MessageSecurityMode.SignAndEncrypt) {
|
|
112
106
|
// no encryption will do if available
|
|
113
|
-
const unencrypted = r.find((userIdentity) => userIdentity.securityPolicyUri ===
|
|
107
|
+
const unencrypted = r.find((userIdentity) => userIdentity.securityPolicyUri === SecurityPolicy.None || !userIdentity.securityPolicyUri);
|
|
114
108
|
if (unencrypted)
|
|
115
109
|
return unencrypted;
|
|
116
110
|
}
|
|
@@ -121,11 +115,11 @@ function findUserTokenPolicy(endpointDescription, userTokenType) {
|
|
|
121
115
|
}
|
|
122
116
|
function createAnonymousIdentityToken(context) {
|
|
123
117
|
const endpoint = context.endpoint;
|
|
124
|
-
const userTokenPolicy = findUserTokenPolicy(endpoint,
|
|
118
|
+
const userTokenPolicy = findUserTokenPolicy(endpoint, UserTokenType.Anonymous);
|
|
125
119
|
if (!userTokenPolicy) {
|
|
126
120
|
throw new Error("Cannot find ANONYMOUS user token policy in end point description");
|
|
127
121
|
}
|
|
128
|
-
return new
|
|
122
|
+
return new AnonymousIdentityToken({ policyId: userTokenPolicy.policyId });
|
|
129
123
|
}
|
|
130
124
|
/**
|
|
131
125
|
*
|
|
@@ -136,28 +130,28 @@ function createAnonymousIdentityToken(context) {
|
|
|
136
130
|
*/
|
|
137
131
|
async function createX509IdentityToken(context, certificate, userKey) {
|
|
138
132
|
const endpoint = context.endpoint;
|
|
139
|
-
|
|
140
|
-
const userTokenPolicy = findUserTokenPolicy(endpoint,
|
|
141
|
-
|
|
133
|
+
assert(endpoint instanceof EndpointDescription);
|
|
134
|
+
const userTokenPolicy = findUserTokenPolicy(endpoint, UserTokenType.Certificate);
|
|
135
|
+
/* c8 ignore next */
|
|
142
136
|
if (!userTokenPolicy) {
|
|
143
137
|
throw new Error("Cannot find Certificate (X509) user token policy in end point description");
|
|
144
138
|
}
|
|
145
|
-
let securityPolicy =
|
|
139
|
+
let securityPolicy = fromURI(userTokenPolicy.securityPolicyUri);
|
|
146
140
|
// if the security policy is not specified we use the session security policy
|
|
147
|
-
if (securityPolicy ===
|
|
141
|
+
if (securityPolicy === SecurityPolicy.Invalid) {
|
|
148
142
|
securityPolicy = context.securityPolicy;
|
|
149
143
|
}
|
|
150
|
-
const userIdentityToken = new
|
|
144
|
+
const userIdentityToken = new X509IdentityToken({
|
|
151
145
|
certificateData: certificate,
|
|
152
146
|
policyId: userTokenPolicy.policyId
|
|
153
147
|
});
|
|
154
148
|
const serverCertificate = context.serverCertificate;
|
|
155
|
-
|
|
149
|
+
assert(serverCertificate instanceof Buffer);
|
|
156
150
|
const serverNonce = context.serverNonce || Buffer.alloc(0);
|
|
157
|
-
|
|
151
|
+
assert(serverNonce instanceof Buffer);
|
|
158
152
|
// see Release 1.02 155 OPC Unified Architecture, Part 4
|
|
159
|
-
const cryptoFactory =
|
|
160
|
-
|
|
153
|
+
const cryptoFactory = getCryptoFactory(securityPolicy);
|
|
154
|
+
/* c8 ignore next */
|
|
161
155
|
if (!cryptoFactory) {
|
|
162
156
|
throw new Error(" Unsupported security Policy");
|
|
163
157
|
}
|
|
@@ -192,15 +186,15 @@ async function createX509IdentityToken(context, certificate, userKey) {
|
|
|
192
186
|
// The data to sign is created by appending the last serverNonce to the serverCertificate
|
|
193
187
|
// The signature generated with the key associated with the User Certificate —
|
|
194
188
|
// possibly produced inside an HSM/smartcard, when the user supplied keyOperations
|
|
195
|
-
const userTokenSignature = (await
|
|
189
|
+
const userTokenSignature = (await computeSignatureAsync(serverCertificate, serverNonce, userKey, securityPolicy));
|
|
196
190
|
return { userIdentityToken, userTokenSignature };
|
|
197
191
|
}
|
|
198
192
|
function createUserNameIdentityToken(session, userName, password) {
|
|
199
193
|
// assert(endpoint instanceof EndpointDescription);
|
|
200
|
-
|
|
201
|
-
|
|
194
|
+
assert(userName === null || typeof userName === "string");
|
|
195
|
+
assert(password === null || typeof password === "string");
|
|
202
196
|
const endpoint = session.endpoint;
|
|
203
|
-
|
|
197
|
+
assert(endpoint instanceof EndpointDescription);
|
|
204
198
|
/**
|
|
205
199
|
* OPC Unified Architecture 1.0.4: Part 4 155
|
|
206
200
|
* Each UserIdentityToken allowed by an Endpoint shall have a UserTokenPolicy specified in the
|
|
@@ -210,21 +204,21 @@ function createUserNameIdentityToken(session, userName, password) {
|
|
|
210
204
|
* is required.
|
|
211
205
|
*
|
|
212
206
|
*/
|
|
213
|
-
const userTokenPolicy = findUserTokenPolicy(endpoint,
|
|
214
|
-
|
|
207
|
+
const userTokenPolicy = findUserTokenPolicy(endpoint, UserTokenType.UserName);
|
|
208
|
+
/* c8 ignore next */
|
|
215
209
|
if (!userTokenPolicy) {
|
|
216
210
|
throw new Error("Cannot find USERNAME user token policy in end point description");
|
|
217
211
|
}
|
|
218
|
-
let securityPolicy =
|
|
212
|
+
let securityPolicy = fromURI(userTokenPolicy.securityPolicyUri);
|
|
219
213
|
// if the security policy is not specified we use the session security policy
|
|
220
|
-
if (securityPolicy ===
|
|
214
|
+
if (securityPolicy === SecurityPolicy.Invalid) {
|
|
221
215
|
securityPolicy = session.securityPolicy;
|
|
222
216
|
}
|
|
223
217
|
let identityToken;
|
|
224
218
|
let serverCertificate = session.serverCertificate;
|
|
225
219
|
// if server does not provide certificate use unencrypted password
|
|
226
220
|
if (!serverCertificate || serverCertificate.length === 0) {
|
|
227
|
-
identityToken = new
|
|
221
|
+
identityToken = new UserNameIdentityToken({
|
|
228
222
|
encryptionAlgorithm: null,
|
|
229
223
|
password: Buffer.from(password, "utf-8"),
|
|
230
224
|
policyId: userTokenPolicy.policyId,
|
|
@@ -232,19 +226,19 @@ function createUserNameIdentityToken(session, userName, password) {
|
|
|
232
226
|
});
|
|
233
227
|
return identityToken;
|
|
234
228
|
}
|
|
235
|
-
|
|
236
|
-
serverCertificate =
|
|
237
|
-
const publicKey =
|
|
229
|
+
assert(serverCertificate instanceof Buffer);
|
|
230
|
+
serverCertificate = toPem(serverCertificate, "CERTIFICATE");
|
|
231
|
+
const publicKey = createPublicKey(extractPublicKeyFromCertificateSync(serverCertificate));
|
|
238
232
|
const serverNonce = session.serverNonce || Buffer.alloc(0);
|
|
239
|
-
|
|
233
|
+
assert(serverNonce instanceof Buffer);
|
|
240
234
|
// If None is specified for the UserTokenPolicy and SecurityPolicy is None
|
|
241
235
|
// then the password only contains the UTF-8 encoded password.
|
|
242
236
|
// note: this means that password is sent in clear text to the server
|
|
243
237
|
// note: OPCUA specification discourages use of unencrypted password
|
|
244
238
|
// but some old OPCUA server may only provide this policy and we
|
|
245
239
|
// still have to support in the client?
|
|
246
|
-
if (securityPolicy ===
|
|
247
|
-
identityToken = new
|
|
240
|
+
if (securityPolicy === SecurityPolicy.None) {
|
|
241
|
+
identityToken = new UserNameIdentityToken({
|
|
248
242
|
encryptionAlgorithm: null,
|
|
249
243
|
password: Buffer.from(password, "utf-8"),
|
|
250
244
|
policyId: userTokenPolicy.policyId,
|
|
@@ -253,12 +247,12 @@ function createUserNameIdentityToken(session, userName, password) {
|
|
|
253
247
|
return identityToken;
|
|
254
248
|
}
|
|
255
249
|
// see Release 1.02 155 OPC Unified Architecture, Part 4
|
|
256
|
-
const cryptoFactory =
|
|
257
|
-
|
|
250
|
+
const cryptoFactory = getCryptoFactory(securityPolicy);
|
|
251
|
+
/* c8 ignore next */
|
|
258
252
|
if (!cryptoFactory) {
|
|
259
253
|
throw new Error(` Unsupported security Policy ${securityPolicy.toString()}`);
|
|
260
254
|
}
|
|
261
|
-
identityToken = new
|
|
255
|
+
identityToken = new UserNameIdentityToken({
|
|
262
256
|
encryptionAlgorithm: cryptoFactory.asymmetricEncryptionAlgorithm,
|
|
263
257
|
password: Buffer.from(password, "utf-8"),
|
|
264
258
|
policyId: userTokenPolicy.policyId,
|
|
@@ -285,7 +279,7 @@ function _adjustRevisedSessionTimeout(revisedSessionTimeout, requestedTimeout) {
|
|
|
285
279
|
}
|
|
286
280
|
return revisedSessionTimeout;
|
|
287
281
|
}
|
|
288
|
-
class OPCUAClientImpl extends
|
|
282
|
+
export class OPCUAClientImpl extends ClientBaseImpl {
|
|
289
283
|
static minimumRevisedSessionTimeout = 100.0;
|
|
290
284
|
_retryCreateSessionTimer;
|
|
291
285
|
static create(options) {
|
|
@@ -301,7 +295,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
301
295
|
constructor(options) {
|
|
302
296
|
options = options || {};
|
|
303
297
|
super(options);
|
|
304
|
-
this.dataTypeExtractStrategy = options.dataTypeExtractStrategy ||
|
|
298
|
+
this.dataTypeExtractStrategy = options.dataTypeExtractStrategy || DataTypeExtractStrategy.Auto;
|
|
305
299
|
// @property endpointMustExist {Boolean}
|
|
306
300
|
// if set to true , create Session will only accept connection from server which endpoint_url has been reported
|
|
307
301
|
// by GetEndpointsRequest.
|
|
@@ -313,7 +307,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
313
307
|
warningLog("Warning: endpoint_must_exist is now deprecated, use endpointMustExist instead");
|
|
314
308
|
options.endpointMustExist = options.endpoint_must_exist;
|
|
315
309
|
}
|
|
316
|
-
this.endpointMustExist =
|
|
310
|
+
this.endpointMustExist = isNullOrUndefined(options.endpointMustExist) ? true : !!options.endpointMustExist;
|
|
317
311
|
this.requestedSessionTimeout = options.requestedSessionTimeout || 60000; // 1 minute
|
|
318
312
|
this.___sessionName_counter = 0;
|
|
319
313
|
this.endpoint = undefined;
|
|
@@ -326,11 +320,11 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
326
320
|
// biome-ignore lint/suspicious/noExplicitAny: overload implementation
|
|
327
321
|
createSession(...args) {
|
|
328
322
|
if (args.length === 1) {
|
|
329
|
-
return this.createSession({ type:
|
|
323
|
+
return this.createSession({ type: UserTokenType.Anonymous }, args[0]);
|
|
330
324
|
}
|
|
331
|
-
const userIdentityInfo = args[0] || { type:
|
|
325
|
+
const userIdentityInfo = args[0] || { type: UserTokenType.Anonymous };
|
|
332
326
|
const callback = args[1];
|
|
333
|
-
|
|
327
|
+
assert(typeof callback === "function");
|
|
334
328
|
this._createSession((err, session) => {
|
|
335
329
|
if (err) {
|
|
336
330
|
callback(err);
|
|
@@ -363,7 +357,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
363
357
|
// biome-ignore lint/suspicious/noExplicitAny: overload implementation
|
|
364
358
|
createSession2(...args) {
|
|
365
359
|
if (args.length === 1) {
|
|
366
|
-
return this.createSession2({ type:
|
|
360
|
+
return this.createSession2({ type: UserTokenType.Anonymous }, args[0]);
|
|
367
361
|
}
|
|
368
362
|
const userIdentityInfo = args[0];
|
|
369
363
|
const callback = args[1];
|
|
@@ -393,7 +387,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
393
387
|
const session = args[0];
|
|
394
388
|
const userIdentityInfo = args[1];
|
|
395
389
|
const callback = args[2];
|
|
396
|
-
|
|
390
|
+
assert(typeof callback === "function");
|
|
397
391
|
session.changeUser(userIdentityInfo, callback);
|
|
398
392
|
}
|
|
399
393
|
closeSession(session, deleteSubscriptions, callback) {
|
|
@@ -412,7 +406,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
412
406
|
};
|
|
413
407
|
}
|
|
414
408
|
toString() {
|
|
415
|
-
let str =
|
|
409
|
+
let str = ClientBaseImpl.prototype.toString.call(this);
|
|
416
410
|
str += ` requestedSessionTimeout....... ${this.requestedSessionTimeout}\n`;
|
|
417
411
|
str += ` endpointUrl................... ${this.endpointUrl}\n`;
|
|
418
412
|
str += ` serverUri..................... ${this.serverUri}\n`;
|
|
@@ -442,13 +436,13 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
442
436
|
* const create
|
|
443
437
|
*/
|
|
444
438
|
static async createSession(endpointUrl, userIdentity, clientOptions) {
|
|
445
|
-
const client =
|
|
439
|
+
const client = OPCUAClient.create(clientOptions || {});
|
|
446
440
|
await client.connect(endpointUrl);
|
|
447
441
|
const session = await client.createSession2(userIdentity);
|
|
448
442
|
// biome-ignore lint/suspicious/noExplicitAny: monkey patch close
|
|
449
443
|
const oldClose = session.close;
|
|
450
444
|
// biome-ignore lint/suspicious/noExplicitAny: monkey patch close
|
|
451
|
-
session.close =
|
|
445
|
+
session.close = withCallback((...args) => {
|
|
452
446
|
if (args.length === 1) {
|
|
453
447
|
return session.close(true, args[0]);
|
|
454
448
|
}
|
|
@@ -470,10 +464,10 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
470
464
|
* @returns
|
|
471
465
|
*/
|
|
472
466
|
async withSessionAsync(connectionPoint, func) {
|
|
473
|
-
|
|
474
|
-
|
|
467
|
+
assert(typeof func === "function");
|
|
468
|
+
assert(func.length === 1, "expecting a single argument in func");
|
|
475
469
|
const endpointUrl = typeof connectionPoint === "string" ? connectionPoint : connectionPoint.endpointUrl;
|
|
476
|
-
const userIdentity = typeof connectionPoint === "string" ? { type:
|
|
470
|
+
const userIdentity = typeof connectionPoint === "string" ? { type: UserTokenType.Anonymous } : connectionPoint.userIdentity;
|
|
477
471
|
this.on("backoff", (count, delay) => {
|
|
478
472
|
warningLog("cannot connect to ", endpointUrl, `attempt #${count}`, " retrying in ", delay);
|
|
479
473
|
});
|
|
@@ -482,7 +476,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
482
476
|
const session = await this.createSession2(userIdentity);
|
|
483
477
|
let result;
|
|
484
478
|
// always need this
|
|
485
|
-
await
|
|
479
|
+
await readNamespaceArray(session);
|
|
486
480
|
try {
|
|
487
481
|
result = await func(session);
|
|
488
482
|
return result;
|
|
@@ -505,7 +499,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
505
499
|
}
|
|
506
500
|
async withSubscriptionAsync(connectionPoint, parameters, func) {
|
|
507
501
|
return await this.withSessionAsync(connectionPoint, async (session) => {
|
|
508
|
-
|
|
502
|
+
assert(session, " session must exist");
|
|
509
503
|
const client1 = this;
|
|
510
504
|
if (client1.beforeSubscriptionRecreate) {
|
|
511
505
|
await client1.beforeSubscriptionRecreate(session);
|
|
@@ -527,7 +521,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
527
521
|
// biome-ignore lint/suspicious/noExplicitAny: overload implementation
|
|
528
522
|
reactivateSession(session, callback) {
|
|
529
523
|
const internalSession = session;
|
|
530
|
-
|
|
524
|
+
assert(typeof callback === "function");
|
|
531
525
|
if (!this._secureChannel) {
|
|
532
526
|
return callback?.(new Error(" client must be connected first"));
|
|
533
527
|
}
|
|
@@ -536,11 +530,11 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
536
530
|
return callback?.(new Error(" End point must exist " +
|
|
537
531
|
this._secureChannel?.endpointUrl +
|
|
538
532
|
" securityMode = " +
|
|
539
|
-
|
|
533
|
+
MessageSecurityMode[this.securityMode] +
|
|
540
534
|
" securityPolicy = " +
|
|
541
535
|
this.securityPolicy));
|
|
542
536
|
}
|
|
543
|
-
|
|
537
|
+
assert(!internalSession._client || matchUri(internalSession._client.endpointUrl, this.endpointUrl), "cannot reactivateSession on a different endpoint");
|
|
544
538
|
const old_client = internalSession._client;
|
|
545
539
|
// c8 ignore next
|
|
546
540
|
doDebug && debugLog("OPCUAClientImpl#reactivateSession");
|
|
@@ -550,19 +544,19 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
550
544
|
// remove session from old client:
|
|
551
545
|
if (old_client) {
|
|
552
546
|
old_client._removeSession(internalSession);
|
|
553
|
-
|
|
547
|
+
assert(old_client._sessions.indexOf(internalSession) === -1);
|
|
554
548
|
}
|
|
555
549
|
this._addSession(internalSession);
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
550
|
+
assert(internalSession._client === this);
|
|
551
|
+
assert(!internalSession._closed, "session should not vbe closed");
|
|
552
|
+
assert(this._sessions.indexOf(internalSession) !== -1);
|
|
559
553
|
}
|
|
560
554
|
callback?.();
|
|
561
555
|
}
|
|
562
556
|
else {
|
|
563
557
|
// c8 ignore next
|
|
564
558
|
if (doDebug) {
|
|
565
|
-
debugLog(
|
|
559
|
+
debugLog(chalk.red.bgWhite("reactivateSession has failed !"), err.message);
|
|
566
560
|
}
|
|
567
561
|
callback?.(err);
|
|
568
562
|
}
|
|
@@ -574,7 +568,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
574
568
|
*/
|
|
575
569
|
_on_connection_reestablished(callback) {
|
|
576
570
|
super._on_connection_reestablished(( /*err?: Error*/) => {
|
|
577
|
-
|
|
571
|
+
repair_client_sessions(this, callback);
|
|
578
572
|
});
|
|
579
573
|
}
|
|
580
574
|
/**
|
|
@@ -583,10 +577,10 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
583
577
|
* @private
|
|
584
578
|
*/
|
|
585
579
|
#createSession_step3(session, callback) {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
580
|
+
assert(typeof callback === "function");
|
|
581
|
+
assert(this.serverUri !== undefined, ` must have a valid server URI ${this.serverUri}`);
|
|
582
|
+
assert(this.endpointUrl !== undefined, " must have a valid server endpointUrl");
|
|
583
|
+
assert(this.endpoint);
|
|
590
584
|
// c8 ignore next
|
|
591
585
|
if (!this._secureChannel) {
|
|
592
586
|
callback(new Error("Invalid channel"));
|
|
@@ -594,8 +588,8 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
594
588
|
}
|
|
595
589
|
const applicationUri = this._getApplicationUri();
|
|
596
590
|
const applicationDescription = {
|
|
597
|
-
applicationName: new
|
|
598
|
-
applicationType:
|
|
591
|
+
applicationName: new LocalizedText({ text: this.applicationName, locale: null }),
|
|
592
|
+
applicationType: ApplicationType.Client,
|
|
599
593
|
applicationUri,
|
|
600
594
|
discoveryProfileUri: undefined,
|
|
601
595
|
discoveryUrls: [],
|
|
@@ -604,10 +598,10 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
604
598
|
};
|
|
605
599
|
// note : do not confuse CreateSessionRequest.clientNonce with OpenSecureChannelRequest.clientNonce
|
|
606
600
|
// which are two different nonce, with different size (although they share the same name )
|
|
607
|
-
this.clientNonce =
|
|
601
|
+
this.clientNonce = randomBytes(32);
|
|
608
602
|
// recycle session name if already exists
|
|
609
603
|
const sessionName = session.name;
|
|
610
|
-
const request = new
|
|
604
|
+
const request = new CreateSessionRequest({
|
|
611
605
|
clientCertificate: this.getCertificate(),
|
|
612
606
|
clientDescription: applicationDescription,
|
|
613
607
|
clientNonce: this.clientNonce,
|
|
@@ -618,7 +612,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
618
612
|
sessionName
|
|
619
613
|
});
|
|
620
614
|
// a client Nonce must be provided if security mode is set
|
|
621
|
-
|
|
615
|
+
assert(this._secureChannel.securityMode === MessageSecurityMode.None || request.clientNonce !== null);
|
|
622
616
|
this.performMessageTransaction(request, (err, response) => {
|
|
623
617
|
/* c8 ignore next */
|
|
624
618
|
if (err) {
|
|
@@ -634,13 +628,13 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
634
628
|
// return;
|
|
635
629
|
}
|
|
636
630
|
/* c8 ignore next */
|
|
637
|
-
if (!response || !(response instanceof
|
|
631
|
+
if (!response || !(response instanceof CreateSessionResponse)) {
|
|
638
632
|
return callback(new Error("internal error"));
|
|
639
633
|
}
|
|
640
|
-
if (response.responseHeader.serviceResult ===
|
|
634
|
+
if (response.responseHeader.serviceResult === StatusCodes.BadTooManySessions) {
|
|
641
635
|
return callback(new Error(response.responseHeader.serviceResult.toString()));
|
|
642
636
|
}
|
|
643
|
-
if (response.responseHeader.serviceResult !==
|
|
637
|
+
if (response.responseHeader.serviceResult !== StatusCodes.Good) {
|
|
644
638
|
err = new Error(`Error ${response.responseHeader.serviceResult.name} ${response.responseHeader.serviceResult.description}`);
|
|
645
639
|
return callback(err);
|
|
646
640
|
}
|
|
@@ -676,7 +670,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
676
670
|
* @private
|
|
677
671
|
*/
|
|
678
672
|
__createSession_step2(session, callback) {
|
|
679
|
-
|
|
673
|
+
callbackify(extractFullyQualifiedDomainName)(() => {
|
|
680
674
|
this.#createSession_step3(session, callback);
|
|
681
675
|
});
|
|
682
676
|
}
|
|
@@ -686,7 +680,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
686
680
|
*/
|
|
687
681
|
_activateSession(session, userIdentityInfo, callback) {
|
|
688
682
|
// see OPCUA Part 4 - $7.35
|
|
689
|
-
|
|
683
|
+
assert(typeof callback === "function");
|
|
690
684
|
// c8 ignore next
|
|
691
685
|
if (!this._secureChannel) {
|
|
692
686
|
callback(new Error(" No secure channel"));
|
|
@@ -709,9 +703,9 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
709
703
|
const serverCertificate = session.serverCertificate;
|
|
710
704
|
// If the securityPolicyUri is None and none of the UserTokenPolicies requires encryption,
|
|
711
705
|
// the Client shall ignore the ApplicationInstanceCertificate (serverCertificate)
|
|
712
|
-
|
|
706
|
+
assert(serverCertificate === null || serverCertificate instanceof Buffer);
|
|
713
707
|
const serverNonce = session.serverNonce;
|
|
714
|
-
|
|
708
|
+
assert(!serverNonce || serverNonce instanceof Buffer);
|
|
715
709
|
// make sure session is attached to this client
|
|
716
710
|
const _old_client = session._client;
|
|
717
711
|
session._client = this;
|
|
@@ -743,7 +737,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
743
737
|
const userTokenSignature = data.userTokenSignature;
|
|
744
738
|
// TODO. fill the ActivateSessionRequest
|
|
745
739
|
// see 5.6.3.2 Parameters OPC Unified Architecture, Part 4 30 Release 1.02
|
|
746
|
-
const request = new
|
|
740
|
+
const request = new ActivateSessionRequest({
|
|
747
741
|
// This is a signature generated with the private key associated with the
|
|
748
742
|
// clientCertificate. The SignatureAlgorithm shall be the AsymmetricSignatureAlgorithm
|
|
749
743
|
// specified in the SecurityPolicy for the Endpoint. The SignatureData type is defined in 7.30.
|
|
@@ -791,7 +785,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
791
785
|
session.noteServerAnswer(err1, response);
|
|
792
786
|
if (!err1 && response && response.responseHeader.serviceResult.isGoodish()) {
|
|
793
787
|
/* c8 ignore next */
|
|
794
|
-
if (!(response instanceof
|
|
788
|
+
if (!(response instanceof ActivateSessionResponse)) {
|
|
795
789
|
return callback(new Error("Internal Error"));
|
|
796
790
|
}
|
|
797
791
|
if (!validateServerNonce(response.serverNonce)) {
|
|
@@ -832,7 +826,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
832
826
|
if (!current || current.length === 0) {
|
|
833
827
|
return;
|
|
834
828
|
}
|
|
835
|
-
const currentDer = Array.isArray(current) ?
|
|
829
|
+
const currentDer = Array.isArray(current) ? combine_der(current) : current;
|
|
836
830
|
if (session.serverCertificate?.equals(currentDer)) {
|
|
837
831
|
return;
|
|
838
832
|
}
|
|
@@ -859,13 +853,13 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
859
853
|
const certificate = this.getCertificate();
|
|
860
854
|
let applicationUri;
|
|
861
855
|
if (certificate) {
|
|
862
|
-
const e =
|
|
856
|
+
const e = exploreCertificate(certificate);
|
|
863
857
|
if (e.tbsCertificate.extensions?.subjectAltName?.uniformResourceIdentifier) {
|
|
864
858
|
applicationUri = e.tbsCertificate.extensions.subjectAltName.uniformResourceIdentifier[0];
|
|
865
859
|
}
|
|
866
860
|
else {
|
|
867
861
|
errorLog("Certificate has no extensions.subjectAltName.uniformResourceIdentifier, ");
|
|
868
|
-
errorLog(
|
|
862
|
+
errorLog(toPem(certificate, "CERTIFICATE"));
|
|
869
863
|
applicationUri = this._getBuiltApplicationUri();
|
|
870
864
|
}
|
|
871
865
|
}
|
|
@@ -879,7 +873,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
879
873
|
* @private
|
|
880
874
|
*/
|
|
881
875
|
__resolveEndPoint() {
|
|
882
|
-
this.securityPolicy = this.securityPolicy ||
|
|
876
|
+
this.securityPolicy = this.securityPolicy || SecurityPolicy.None;
|
|
883
877
|
let endpoint = this.findEndpoint(this._secureChannel?.endpointUrl || "", this.securityMode, this.securityPolicy);
|
|
884
878
|
this.endpoint = endpoint;
|
|
885
879
|
// this is explained here : see OPCUA Part 4 Version 1.02 $5.4.1 page 12:
|
|
@@ -889,7 +883,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
889
883
|
if (!this.endpoint) {
|
|
890
884
|
if (this.endpointMustExist) {
|
|
891
885
|
warningLog("OPCUAClientImpl#endpointMustExist = true and endpoint with url ", this._secureChannel?.endpointUrl, " cannot be found");
|
|
892
|
-
const infos = this._serverEndpoints.map((endpoint) => `${endpoint.endpointUrl} ${
|
|
886
|
+
const infos = this._serverEndpoints.map((endpoint) => `${endpoint.endpointUrl} ${MessageSecurityMode[endpoint.securityMode]}, ${endpoint.securityPolicyUri} `);
|
|
893
887
|
warningLog("Valid endpoints are ");
|
|
894
888
|
warningLog(` ${infos.join("\n ")}`);
|
|
895
889
|
return false;
|
|
@@ -913,31 +907,31 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
913
907
|
* @private
|
|
914
908
|
*/
|
|
915
909
|
_createSession(callback) {
|
|
916
|
-
|
|
917
|
-
|
|
910
|
+
assert(typeof callback === "function");
|
|
911
|
+
assert(this._secureChannel);
|
|
918
912
|
if (!this.__resolveEndPoint() || !this.endpoint) {
|
|
919
913
|
/* c8 ignore next */
|
|
920
914
|
if (this._serverEndpoints) {
|
|
921
915
|
warningLog("server endpoints =", this._serverEndpoints
|
|
922
916
|
.map((endpoint) => endpoint.endpointUrl +
|
|
923
917
|
" " +
|
|
924
|
-
|
|
918
|
+
MessageSecurityMode[endpoint.securityMode] +
|
|
925
919
|
" " +
|
|
926
920
|
endpoint.securityPolicyUri +
|
|
927
921
|
" " +
|
|
928
|
-
endpoint.userIdentityTokens?.map((u) =>
|
|
922
|
+
endpoint.userIdentityTokens?.map((u) => UserTokenType[u.tokenType]).join(","))
|
|
929
923
|
.join("\n"));
|
|
930
924
|
}
|
|
931
925
|
return callback(new Error(" End point must exist " +
|
|
932
926
|
this._secureChannel?.endpointUrl +
|
|
933
927
|
" securityMode = " +
|
|
934
|
-
|
|
928
|
+
MessageSecurityMode[this.securityMode] +
|
|
935
929
|
" securityPolicy = " +
|
|
936
930
|
this.securityPolicy));
|
|
937
931
|
}
|
|
938
932
|
this.serverUri = this.endpoint.server.applicationUri || "invalid application uri";
|
|
939
933
|
this.endpointUrl = this._secureChannel?.endpointUrl || "";
|
|
940
|
-
const session = new
|
|
934
|
+
const session = new ClientSessionImpl(this);
|
|
941
935
|
session.name = this._nextSessionName();
|
|
942
936
|
this.__createSession_step2(session, callback);
|
|
943
937
|
}
|
|
@@ -948,7 +942,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
948
942
|
computeClientSignature(channel, serverCertificate, serverNonce) {
|
|
949
943
|
// through the opaque key-operations path: works whether the client's
|
|
950
944
|
// application instance key is local or HSM/KMS-held
|
|
951
|
-
return
|
|
945
|
+
return computeSignatureAsync(serverCertificate, serverNonce || Buffer.alloc(0), this.getKeyOperations(), channel.securityPolicy);
|
|
952
946
|
}
|
|
953
947
|
/**
|
|
954
948
|
*
|
|
@@ -958,24 +952,24 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
958
952
|
// biome-ignore lint/suspicious/noExplicitAny: user provided object that needs soft type coercion
|
|
959
953
|
function coerceUserIdentityInfo(identityInfo) {
|
|
960
954
|
if (!identityInfo) {
|
|
961
|
-
return { type:
|
|
955
|
+
return { type: UserTokenType.Anonymous };
|
|
962
956
|
}
|
|
963
957
|
if (Object.hasOwn(identityInfo, "type")) {
|
|
964
958
|
return identityInfo;
|
|
965
959
|
}
|
|
966
960
|
if (Object.hasOwn(identityInfo, "userName")) {
|
|
967
|
-
identityInfo.type =
|
|
961
|
+
identityInfo.type = UserTokenType.UserName;
|
|
968
962
|
return identityInfo;
|
|
969
963
|
}
|
|
970
964
|
if (Object.hasOwn(identityInfo, "certificateData")) {
|
|
971
|
-
identityInfo.type =
|
|
965
|
+
identityInfo.type = UserTokenType.Certificate;
|
|
972
966
|
return identityInfo;
|
|
973
967
|
}
|
|
974
|
-
identityInfo.type =
|
|
968
|
+
identityInfo.type = UserTokenType.Anonymous;
|
|
975
969
|
return identityInfo;
|
|
976
970
|
}
|
|
977
971
|
userIdentityInfo = coerceUserIdentityInfo(userIdentityInfo);
|
|
978
|
-
|
|
972
|
+
assert(typeof callback === "function");
|
|
979
973
|
if (null === userIdentityInfo) {
|
|
980
974
|
return callback(null, {
|
|
981
975
|
userIdentityToken: null,
|
|
@@ -989,16 +983,16 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
989
983
|
};
|
|
990
984
|
try {
|
|
991
985
|
switch (userIdentityInfo.type) {
|
|
992
|
-
case
|
|
986
|
+
case UserTokenType.Anonymous:
|
|
993
987
|
userIdentityToken = createAnonymousIdentityToken(context);
|
|
994
988
|
break;
|
|
995
|
-
case
|
|
989
|
+
case UserTokenType.UserName: {
|
|
996
990
|
const userName = userIdentityInfo.userName || "";
|
|
997
991
|
const password = userIdentityInfo.password || "";
|
|
998
992
|
userIdentityToken = createUserNameIdentityToken(context, userName, password);
|
|
999
993
|
break;
|
|
1000
994
|
}
|
|
1001
|
-
case
|
|
995
|
+
case UserTokenType.Certificate: {
|
|
1002
996
|
const certificate = userIdentityInfo.certificateData;
|
|
1003
997
|
if (!userIdentityInfo.privateKey === !userIdentityInfo.keyOperations) {
|
|
1004
998
|
return callback(new Error("CLIENT: a X509 user identity requires exactly one of 'privateKey' (PEM) or 'keyOperations'"));
|
|
@@ -1008,7 +1002,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
1008
1002
|
}
|
|
1009
1003
|
const userKey = userIdentityInfo.keyOperations
|
|
1010
1004
|
? userIdentityInfo.keyOperations
|
|
1011
|
-
:
|
|
1005
|
+
: makePrivateKeyFromPem(userIdentityInfo.privateKey);
|
|
1012
1006
|
createX509IdentityToken(context, certificate, userKey).then((x509Data) => callback(null, x509Data), (err) => callback(err));
|
|
1013
1007
|
return;
|
|
1014
1008
|
}
|
|
@@ -1026,8 +1020,7 @@ class OPCUAClientImpl extends client_base_impl_js_1.ClientBaseImpl {
|
|
|
1026
1020
|
return callback(null, { userIdentityToken, userTokenSignature });
|
|
1027
1021
|
}
|
|
1028
1022
|
}
|
|
1029
|
-
|
|
1030
|
-
const thenify_ex_1 = require("thenify-ex");
|
|
1023
|
+
import { withCallback } from "thenify-ex";
|
|
1031
1024
|
/**
|
|
1032
1025
|
|
|
1033
1026
|
*
|
|
@@ -1045,16 +1038,16 @@ const thenify_ex_1 = require("thenify-ex");
|
|
|
1045
1038
|
* const session = client.createSession(userIdentityInfo);
|
|
1046
1039
|
*
|
|
1047
1040
|
*/
|
|
1048
|
-
OPCUAClientImpl.prototype.createSession =
|
|
1049
|
-
OPCUAClientImpl.prototype.createSession2 =
|
|
1041
|
+
OPCUAClientImpl.prototype.createSession = withCallback(OPCUAClientImpl.prototype.createSession);
|
|
1042
|
+
OPCUAClientImpl.prototype.createSession2 = withCallback(OPCUAClientImpl.prototype.createSession2);
|
|
1050
1043
|
/**
|
|
1051
1044
|
*/
|
|
1052
|
-
OPCUAClientImpl.prototype.changeSessionIdentity =
|
|
1045
|
+
OPCUAClientImpl.prototype.changeSessionIdentity = withCallback(OPCUAClientImpl.prototype.changeSessionIdentity);
|
|
1053
1046
|
/**
|
|
1054
1047
|
* @example
|
|
1055
1048
|
* const session = await client.createSession();
|
|
1056
1049
|
* await client.closeSession(session);
|
|
1057
1050
|
*/
|
|
1058
|
-
OPCUAClientImpl.prototype.closeSession =
|
|
1059
|
-
OPCUAClientImpl.prototype.reactivateSession =
|
|
1051
|
+
OPCUAClientImpl.prototype.closeSession = withCallback(OPCUAClientImpl.prototype.closeSession);
|
|
1052
|
+
OPCUAClientImpl.prototype.reactivateSession = withCallback(OPCUAClientImpl.prototype.reactivateSession);
|
|
1060
1053
|
//# sourceMappingURL=opcua_client_impl.js.map
|