node-opcua-client 2.163.1 → 2.165.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.
Files changed (53) hide show
  1. package/dist/client_base.js +1 -1
  2. package/dist/client_base.js.map +1 -1
  3. package/dist/client_monitored_item.js +1 -1
  4. package/dist/client_monitored_item.js.map +1 -1
  5. package/dist/client_monitored_item_group.js +1 -1
  6. package/dist/client_monitored_item_group.js.map +1 -1
  7. package/dist/client_monitored_item_toolbox.js +4 -4
  8. package/dist/client_monitored_item_toolbox.js.map +1 -1
  9. package/dist/client_session_keepalive_manager.js +3 -3
  10. package/dist/client_session_keepalive_manager.js.map +1 -1
  11. package/dist/client_subscription.js +1 -1
  12. package/dist/client_subscription.js.map +1 -1
  13. package/dist/private/client_base_impl.js +33 -28
  14. package/dist/private/client_base_impl.js.map +1 -1
  15. package/dist/private/client_monitored_item_impl.js +1 -2
  16. package/dist/private/client_monitored_item_impl.js.map +1 -1
  17. package/dist/private/client_publish_engine.js +14 -3
  18. package/dist/private/client_publish_engine.js.map +1 -1
  19. package/dist/private/client_session_impl.js +58 -58
  20. package/dist/private/client_session_impl.js.map +1 -1
  21. package/dist/private/client_subscription_impl.js +11 -11
  22. package/dist/private/client_subscription_impl.js.map +1 -1
  23. package/dist/private/opcua_client_impl.js +15 -15
  24. package/dist/private/opcua_client_impl.js.map +1 -1
  25. package/dist/private/reconnection/client_publish_engine_reconnection.js +2 -2
  26. package/dist/private/reconnection/client_publish_engine_reconnection.js.map +1 -1
  27. package/dist/private/reconnection/client_subscription_reconnection.js +9 -9
  28. package/dist/private/reconnection/client_subscription_reconnection.js.map +1 -1
  29. package/dist/private/reconnection/reconnection.js +8 -8
  30. package/dist/private/reconnection/reconnection.js.map +1 -1
  31. package/dist/tools/read_history_server_capabilities.js +3 -3
  32. package/dist/tools/read_history_server_capabilities.js.map +1 -1
  33. package/dist/verify.d.ts +3 -3
  34. package/dist/verify.js +11 -9
  35. package/dist/verify.js.map +1 -1
  36. package/package.json +46 -46
  37. package/source/client_base.ts +1 -1
  38. package/source/client_monitored_item.ts +1 -1
  39. package/source/client_monitored_item_group.ts +1 -1
  40. package/source/client_monitored_item_toolbox.ts +4 -4
  41. package/source/client_session_keepalive_manager.ts +3 -3
  42. package/source/client_subscription.ts +1 -1
  43. package/source/private/client_base_impl.ts +35 -29
  44. package/source/private/client_monitored_item_impl.ts +1 -2
  45. package/source/private/client_publish_engine.ts +18 -3
  46. package/source/private/client_session_impl.ts +58 -58
  47. package/source/private/client_subscription_impl.ts +11 -11
  48. package/source/private/opcua_client_impl.ts +15 -15
  49. package/source/private/reconnection/client_publish_engine_reconnection.ts +2 -2
  50. package/source/private/reconnection/client_subscription_reconnection.ts +6 -6
  51. package/source/private/reconnection/reconnection.ts +8 -8
  52. package/source/tools/read_history_server_capabilities.ts +3 -3
  53. package/source/verify.ts +40 -43
@@ -1,8 +1,7 @@
1
- import { promisify } from "util";
1
+ import { promisify } from "node:util";
2
2
  import assert from "node-opcua-assert";
3
3
  import { TimestampsToReturn } from "node-opcua-data-value";
4
- import { make_debugLog, checkDebugFlag } from "node-opcua-debug";
5
- import { warningLog } from "node-opcua-pki";
4
+ import { make_debugLog, checkDebugFlag, make_warningLog } from "node-opcua-debug";
6
5
  import { MonitoredItemCreateRequestOptions, CreateMonitoredItemsRequest, CreateMonitoredItemsResponse } from "node-opcua-types";
7
6
 
8
7
  import {
@@ -18,6 +17,7 @@ import { _shouldNotContinue } from "./reconnection";
18
17
 
19
18
  const debugLog = make_debugLog("RECONNECTION");
20
19
  const doDebug = checkDebugFlag("RECONNECTION");
20
+ const warningLog = make_warningLog("RECONNECTION");
21
21
 
22
22
  async function createMonitoredItemsAndRespectOperationalLimits(
23
23
  session: IBasicSessionReadAsync & IBasicSessionWithSubscription,
@@ -82,7 +82,7 @@ export async function recreateSubscriptionAndMonitoredItem(_subscription: Client
82
82
  });
83
83
 
84
84
  const session = subscription.session;
85
- // istanbul ignore next
85
+ // c8 ignore next
86
86
  if (!session) {
87
87
  throw new Error("no session");
88
88
  }
@@ -97,13 +97,13 @@ export async function recreateSubscriptionAndMonitoredItem(_subscription: Client
97
97
  let _errCount = 0;
98
98
  monitoredItemResults.forEach((monitoredItemResult, index) => {
99
99
  const itemToCreate = itemsToCreate[index];
100
- /* istanbul ignore next */
100
+ /* c8 ignore next */
101
101
  if (!itemToCreate || !itemToCreate.requestedParameters) {
102
102
  _errCount++;
103
103
  return;
104
104
  }
105
105
  const clientHandle = itemToCreate.requestedParameters.clientHandle;
106
- /* istanbul ignore next */
106
+ /* c8 ignore next */
107
107
  if (!clientHandle) {
108
108
  _errCount++;
109
109
  return;
@@ -192,7 +192,7 @@ function repair_client_session_by_recreating_a_new_session(
192
192
  // and may be upgraded in between, we have to invalidate the extra data type manager
193
193
  invalidateExtraDataTypeManager(session);
194
194
 
195
- // istanbul ignore next
195
+ // c8 ignore next
196
196
  if (doDebug) {
197
197
  debugLog(" repairing client session by_recreating a new session for old session ", session.sessionId.toString());
198
198
  }
@@ -247,7 +247,7 @@ function repair_client_session_by_recreating_a_new_session(
247
247
  // prettier-ignore
248
248
  { const err = _shouldNotContinue(session); if (err) { return innerCallback(err); } }
249
249
 
250
- // istanbul ignore next
250
+ // c8 ignore next
251
251
  doDebug && debugLog(chalk.bgWhite.red(" => suspend old session publish engine...."));
252
252
  session.getPublishEngine().suspend(true);
253
253
  innerCallback();
@@ -275,7 +275,7 @@ function repair_client_session_by_recreating_a_new_session(
275
275
  newSession,
276
276
  newSession.userIdentityInfo!,
277
277
  (err: Error | null, session1?: ClientSessionImpl) => {
278
- // istanbul ignore next
278
+ // c8 ignore next
279
279
  doDebug && debugLog(" => activating a new session .... Done err=", err ? err.message : "null");
280
280
  if (err) {
281
281
  doDebug &&
@@ -293,9 +293,9 @@ function repair_client_session_by_recreating_a_new_session(
293
293
  if (err2) {
294
294
  warningLog("closing session", err2.message);
295
295
  }
296
- // istanbul ignore next
296
+ // c8 ignore next
297
297
  doDebug && debugLog("the temporary replacement session is now closed");
298
- // istanbul ignore next
298
+ // c8 ignore next
299
299
  doDebug && debugLog(" err ", err.message, "propagated upwards");
300
300
  innerCallback(err);
301
301
  });
@@ -372,7 +372,7 @@ function repair_client_session_by_recreating_a_new_session(
372
372
  }
373
373
 
374
374
  const results = transferSubscriptionsResponse.results || [];
375
- // istanbul ignore next
375
+ // c8 ignore next
376
376
  if (doDebug) {
377
377
  debugLog(
378
378
  chalk.cyan(" => transfer subscriptions done"),
@@ -550,7 +550,7 @@ export function repair_client_session(client: IClientBase, session: ClientSessio
550
550
  return;
551
551
  }
552
552
 
553
- // istanbul ignore next
553
+ // c8 ignore next
554
554
  doDebug && debugLog(chalk.yellow("session has been restored"), session.sessionId.toString());
555
555
  session.emit("session_restored");
556
556
  callback(err);
@@ -561,7 +561,7 @@ export function repair_client_session(client: IClientBase, session: ClientSessio
561
561
  const otherCallbacks = privateSession._reconnecting.pendingCallbacks.splice(0);
562
562
  // re-inject element in queue
563
563
 
564
- // istanbul ignore next
564
+ // c8 ignore next
565
565
  if (transactionQueue.length > 0) {
566
566
  doDebug && debugLog(chalk.yellow("re-injecting transaction queue"), transactionQueue.length);
567
567
  transactionQueue.forEach((e: any) => privateSession._reconnecting.pendingTransactions.push(e));
@@ -37,7 +37,7 @@ export function readHistoryServerCapabilities(
37
37
  if (err) {
38
38
  return callback(err);
39
39
  }
40
- /* istanbul ignore next */
40
+ /* c8 ignore next */
41
41
  if (!result) {
42
42
  return callback(new Error("Internal Error"));
43
43
  }
@@ -89,7 +89,7 @@ export function readHistoryServerCapabilities(
89
89
  if (innerErr) {
90
90
  return callback(innerErr);
91
91
  }
92
- /* istanbul ignore next */
92
+ /* c8 ignore next */
93
93
  if (!results) {
94
94
  return callback(new Error("Internal Error"));
95
95
  }
@@ -111,7 +111,7 @@ export function readHistoryServerCapabilities(
111
111
  if (err2) {
112
112
  return callback(err2);
113
113
  }
114
- /* istanbul ignore next */
114
+ /* c8 ignore next */
115
115
  if (!dataValues) {
116
116
  return callback(new Error("Internal Error"));
117
117
  }
package/source/verify.ts CHANGED
@@ -1,17 +1,12 @@
1
- import { OPCUACertificateManager } from "node-opcua-certificate-manager";
2
- import { OPCUASecureObject } from "node-opcua-common";
1
+ import type { OPCUACertificateManager } from "node-opcua-certificate-manager";
2
+ import type { OPCUASecureObject } from "node-opcua-common";
3
3
 
4
- import {
5
- Certificate,
6
- exploreCertificate,
7
- explorePrivateKey,
8
- publicKeyAndPrivateKeyMatches
9
- } from "node-opcua-crypto/web";
4
+ import { type Certificate, exploreCertificate, explorePrivateKey, publicKeyAndPrivateKeyMatches } from "node-opcua-crypto/web";
10
5
  import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
11
- import { VerifyCertificateOptions } from "node-opcua-pki";
6
+ import type { VerifyCertificateOptions } from "node-opcua-pki";
12
7
 
13
- const doDebug = checkDebugFlag(__filename);
14
- const debugLog = make_debugLog(__filename);
8
+ const _doDebug = checkDebugFlag(__filename);
9
+ const _debugLog = make_debugLog(__filename);
15
10
  const errorLog = make_errorLog(__filename);
16
11
  const warningLog = make_warningLog(__filename);
17
12
 
@@ -29,8 +24,8 @@ export function verifyIsOPCUAValidCertificate(
29
24
  // certificate is not active yet
30
25
  warningLog(
31
26
  `[NODE-OPCUA-W02] The certificate is not active yet\n` +
32
- `notBefore ${certificateInfo.tbsCertificate.validity.notBefore.toISOString()}\n` +
33
- `certificateFile ${certificateFile}`
27
+ `notBefore ${certificateInfo.tbsCertificate.validity.notBefore.toISOString()}\n` +
28
+ `certificateFile ${certificateFile}`
34
29
  );
35
30
  }
36
31
  // check that certificate has not expired
@@ -38,9 +33,9 @@ export function verifyIsOPCUAValidCertificate(
38
33
  // certificate is obsolete
39
34
  warningLog(
40
35
  `[NODE-OPCUA-W03] The certificate has expired\n` +
41
- `Please regenerate a valid certificate\n` +
42
- `notAfter = ${certificateInfo.tbsCertificate.validity.notAfter.toISOString()}\n` +
43
- `certificateFile= ${certificateFile}`
36
+ `Please regenerate a valid certificate\n` +
37
+ `notAfter = ${certificateInfo.tbsCertificate.validity.notAfter.toISOString()}\n` +
38
+ `certificateFile= ${certificateFile}`
44
39
  );
45
40
  } else {
46
41
  const tenDays = 10 * 24 * 60 * 60 * 1000;
@@ -48,9 +43,9 @@ export function verifyIsOPCUAValidCertificate(
48
43
  // certificate is going to expired very soon
49
44
  warningLog(
50
45
  `[NODE-OPCUA-W05] The certificate is about to expire in less than 10 days.\n` +
51
- `Please regenerate a valid certificate as soon as possible\n` +
52
- `notAfter = ${certificateInfo.tbsCertificate.validity.notAfter.toISOString()}\n` +
53
- `certificateFile= ${certificateFile}\n`
46
+ `Please regenerate a valid certificate as soon as possible\n` +
47
+ `notAfter = ${certificateInfo.tbsCertificate.validity.notAfter.toISOString()}\n` +
48
+ `certificateFile= ${certificateFile}\n`
54
49
  );
55
50
  }
56
51
  }
@@ -59,46 +54,46 @@ export function verifyIsOPCUAValidCertificate(
59
54
  if (!uniformResourceIdentifier) {
60
55
  warningLog(
61
56
  `[NODE-OPCUA-W14] The certificate subjectAltName uniformResourceIdentifier is missing.\n` +
62
- `Please regenerate a specific certificate with a uniformResourceIdentifier that matches your ${type} applicationUri\n` +
63
- `applicationUri = ${applicationUri}\n` +
64
- `certificateFile = ${certificateFile}\n`
57
+ `Please regenerate a specific certificate with a uniformResourceIdentifier that matches your ${type} applicationUri\n` +
58
+ `applicationUri = ${applicationUri}\n` +
59
+ `certificateFile = ${certificateFile}\n`
65
60
  );
66
61
  return;
67
62
  } else if (uniformResourceIdentifier[0] !== applicationUri) {
68
63
  warningLog(
69
64
  `[NODE-OPCUA-W06] The certificate subjectAltName does not match the ${type} applicationUri\n` +
70
- `Please regenerate a specific certificate that matches your ${type} applicationUri\n` +
71
- `certificate subjectAltName = ${uniformResourceIdentifier[0]}\n` +
72
- `${type} applicationUri = ${applicationUri}\n` +
73
- `certificateFile = ${certificateFile}\n`
65
+ `Please regenerate a specific certificate that matches your ${type} applicationUri\n` +
66
+ `certificate subjectAltName = ${uniformResourceIdentifier[0]}\n` +
67
+ `${type} applicationUri = ${applicationUri}\n` +
68
+ `certificateFile = ${certificateFile}\n`
74
69
  );
75
70
  }
76
71
  const keyUsage = certificateInfo.tbsCertificate.extensions?.keyUsage;
77
72
  if (!keyUsage) {
78
- warningLog(`[NODE-OPCUA-W15] The certificate keyUsage is missing\n` + `certificateFile = ${certificateFile}`);
73
+ warningLog(`[NODE-OPCUA-W15] The certificate keyUsage is missing\ncertificateFile = ${certificateFile}`);
79
74
  } else {
80
75
  // spec says that certificate shall include digitalSignature, nonRepudiation, keyEncipherment and dataEncipherment.
81
76
  // Other key uses are allowed.
82
77
  if (!keyUsage.digitalSignature || !keyUsage.nonRepudiation || !keyUsage.keyEncipherment || !keyUsage.dataEncipherment) {
83
78
  warningLog(
84
79
  `[NODE-OPCUA-W16] The certificate keyUsage must include digitalSignature, nonRepudiation, keyEncipherment and dataEncipherment.\n` +
85
- `see https://reference.opcfoundation.org/v104/Core/docs/Part6/6.2.2/\n` +
86
- `certificateFile = ${certificateFile}`
80
+ `see https://reference.opcfoundation.org/v104/Core/docs/Part6/6.2.2/\n` +
81
+ `certificateFile = ${certificateFile}`
87
82
  );
88
83
  warningLog(`keyUsage = ${JSON.stringify(keyUsage, null, " ")}`);
89
84
  }
90
85
  }
91
86
  const extKeyUsage = certificateInfo.tbsCertificate.extensions?.extKeyUsage;
92
87
  if (!extKeyUsage) {
93
- warningLog(`[NODE-OPCUA-W17] The certificate extKeyUsage is missing\n` + `certificateFile = ${certificateFile}`);
88
+ warningLog(`[NODE-OPCUA-W17] The certificate extKeyUsage is missing\ncertificateFile = ${certificateFile}`);
94
89
  } else {
95
90
  // spec says that certificate shall include digitalSignature, nonRepudiation, keyEncipherment and dataEncipherment.
96
91
  // Other key uses are allowed.
97
92
  if (!extKeyUsage.clientAuth && !extKeyUsage.serverAuth) {
98
93
  warningLog(
99
94
  `[NODE-OPCUA-W18] The certificate extKeyUsage must include clientAuth and/or serverAuth.\n` +
100
- `see https://reference.opcfoundation.org/v104/Core/docs/Part6/6.2.2/\n` +
101
- `certificateFile = ${certificateFile}`
95
+ `see https://reference.opcfoundation.org/v104/Core/docs/Part6/6.2.2/\n` +
96
+ `certificateFile = ${certificateFile}`
102
97
  );
103
98
  }
104
99
  }
@@ -107,14 +102,14 @@ export function verifyIsOPCUAValidCertificate(
107
102
  if (keyLengthInBits < 1024) {
108
103
  errorLog(
109
104
  `[NODE-OPCUA-W19] The public key length shall be greater than or equal to 1024 bits. key length is ${keyLengthInBits}.\n` +
110
- `see https://reference.opcfoundation.org/v104/GDS/docs/7.6.3/\n` +
111
- `certificateFile = ${certificateFile}`
105
+ `see https://reference.opcfoundation.org/v104/GDS/docs/7.6.3/\n` +
106
+ `certificateFile = ${certificateFile}`
112
107
  );
113
108
  } else if (keyLengthInBits < 2048) {
114
109
  warningLog(
115
110
  `[NODE-OPCUA-W23] key lengths less than 2048 are considered insecure. key length is ${keyLengthInBits}\n` +
116
- `see https://reference.opcfoundation.org/v104/Core/docs/Part2/6.8/\n` +
117
- `certificateFile = ${certificateFile}`
111
+ `see https://reference.opcfoundation.org/v104/Core/docs/Part2/6.8/\n` +
112
+ `certificateFile = ${certificateFile}`
118
113
  );
119
114
  }
120
115
  }
@@ -145,23 +140,25 @@ export async function performCertificateSanityCheck(
145
140
  if (keyLengthInBits <= 1024) {
146
141
  warningLog(
147
142
  `[NODE-OPCUA-W04] The public/private key pair uses a key length which is equal or lower than 1024 bits. ( key length was ${keyLengthInBits} )\n` +
148
- `OPCUA version 1.04 requires that security key length are greater or equal to 2048 bits.\n` +
149
- `The ${serverOrClient} is operating at risk. `
143
+ `OPCUA version 1.04 requires that security key length are greater or equal to 2048 bits.\n` +
144
+ `The ${serverOrClient} is operating at risk. `
150
145
  );
151
146
  }
152
- // verify that the certificate has a valid date and has expected extensions fields such as DNS and IP.
153
- const status1 = await certificateManager.trustCertificate(certificate);
154
147
 
155
148
  const options: VerifyCertificateOptions = {
156
149
  acceptOutdatedCertificate: false,
157
150
  acceptOutDatedIssuerCertificate: false,
158
- acceptPendingCertificate: false,
151
+ acceptPendingCertificate: false
159
152
  };
160
153
 
161
154
  const status = await certificateManager.verifyCertificate(certificate, options);
162
155
 
163
- if (status !== "Good") {
164
- warningLog("[NODE-OPCUA-W04] Warning: the certificate status is = ", status, " file = ", secureObject.certificateFile);
156
+ // BadCertificateUntrusted is expected for the application's own
157
+ // certificate it does not need to be in its own trust list.
158
+ // Only warn about genuinely problematic statuses (expired,
159
+ // revoked, invalid signature, etc.).
160
+ if (status !== "Good" && status !== "BadCertificateUntrusted") {
161
+ warningLog("[NODE-OPCUA-W35] Warning: the certificate status is = ", status, " file = ", secureObject.certificateFile);
165
162
  }
166
163
 
167
164
  verifyIsOPCUAValidCertificate(certificate, secureObject.certificateFile, serverOrClient, applicationUri);