node-opcua-client 2.103.0 → 2.104.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 (44) hide show
  1. package/dist/alarms_and_conditions/client_alarm_tools_dump_event.js +6 -3
  2. package/dist/alarms_and_conditions/client_alarm_tools_dump_event.js.map +1 -1
  3. package/dist/alarms_and_conditions/client_tools.js +24 -1
  4. package/dist/alarms_and_conditions/client_tools.js.map +1 -1
  5. package/dist/client_base.js +1 -1
  6. package/dist/client_base.js.map +1 -1
  7. package/dist/client_monitored_item_toolbox.js +5 -2
  8. package/dist/client_monitored_item_toolbox.js.map +1 -1
  9. package/dist/client_session_keepalive_manager.js +5 -2
  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/index.js +14 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/private/client_base_impl.js +69 -29
  16. package/dist/private/client_base_impl.js.map +1 -1
  17. package/dist/private/client_publish_engine.js +39 -13
  18. package/dist/private/client_publish_engine.js.map +1 -1
  19. package/dist/private/client_session_impl.js +24 -21
  20. package/dist/private/client_session_impl.js.map +1 -1
  21. package/dist/private/client_subscription_impl.js +45 -19
  22. package/dist/private/client_subscription_impl.js.map +1 -1
  23. package/dist/private/opcua_client_impl.js +31 -5
  24. package/dist/private/opcua_client_impl.js.map +1 -1
  25. package/dist/reconnection.js +52 -26
  26. package/dist/reconnection.js.map +1 -1
  27. package/dist/tools/findservers.js +24 -1
  28. package/dist/tools/findservers.js.map +1 -1
  29. package/dist/tools/read_history_server_capabilities.js.map +1 -1
  30. package/dist/verify.d.ts +1 -1
  31. package/dist/verify.js +9 -8
  32. package/dist/verify.js.map +1 -1
  33. package/package.json +47 -47
  34. package/source/alarms_and_conditions/client_alarm_tools_dump_event.ts +1 -1
  35. package/source/client_monitored_item_toolbox.ts +1 -1
  36. package/source/client_session_keepalive_manager.ts +1 -1
  37. package/source/private/client_base_impl.ts +36 -22
  38. package/source/private/client_publish_engine.ts +1 -1
  39. package/source/private/client_session_impl.ts +1 -1
  40. package/source/private/client_subscription_impl.ts +1 -1
  41. package/source/private/opcua_client_impl.ts +1 -2
  42. package/source/reconnection.ts +1 -1
  43. package/source/tools/read_history_server_capabilities.ts +6 -0
  44. package/source/verify.ts +9 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-client",
3
- "version": "2.103.0",
3
+ "version": "2.104.0",
4
4
  "description": "pure nodejs OPCUA SDK - module client",
5
5
  "scripts": {
6
6
  "clean": "npx rimraf node_modules dist *.tsbuildinfo certificates",
@@ -13,61 +13,61 @@
13
13
  "main": "./dist/index.js",
14
14
  "types": "./dist/index.d.ts",
15
15
  "dependencies": {
16
- "@ster5/global-mutex": "^1.2.0",
17
- "@types/async": "^3.2.18",
16
+ "@ster5/global-mutex": "^2.0.0",
17
+ "@types/async": "^3.2.20",
18
18
  "async": "^3.2.4",
19
19
  "chalk": "4.1.2",
20
- "node-opcua-assert": "2.98.1",
21
- "node-opcua-basic-types": "2.99.0",
22
- "node-opcua-buffer-utils": "2.98.1",
23
- "node-opcua-certificate-manager": "2.99.0",
24
- "node-opcua-client-dynamic-extension-object": "2.103.0",
25
- "node-opcua-common": "2.103.0",
20
+ "node-opcua-assert": "2.104.0",
21
+ "node-opcua-basic-types": "2.104.0",
22
+ "node-opcua-buffer-utils": "2.104.0",
23
+ "node-opcua-certificate-manager": "2.104.0",
24
+ "node-opcua-client-dynamic-extension-object": "2.104.0",
25
+ "node-opcua-common": "2.104.0",
26
26
  "node-opcua-constants": "2.98.1",
27
- "node-opcua-crypto": "^2.1.2",
28
- "node-opcua-data-model": "2.102.0",
29
- "node-opcua-data-value": "2.102.0",
30
- "node-opcua-date-time": "2.99.0",
31
- "node-opcua-debug": "2.99.0",
32
- "node-opcua-extension-object": "2.99.0",
33
- "node-opcua-hostname": "2.98.1",
34
- "node-opcua-nodeid": "2.99.0",
35
- "node-opcua-object-registry": "2.99.0",
36
- "node-opcua-pki": "^3.0.2",
37
- "node-opcua-pseudo-session": "2.103.0",
38
- "node-opcua-schemas": "2.103.0",
39
- "node-opcua-secure-channel": "2.103.0",
40
- "node-opcua-service-browse": "2.103.0",
41
- "node-opcua-service-call": "2.103.0",
42
- "node-opcua-service-discovery": "2.103.0",
43
- "node-opcua-service-endpoints": "2.103.0",
44
- "node-opcua-service-filter": "2.103.0",
45
- "node-opcua-service-history": "2.103.0",
46
- "node-opcua-service-query": "2.103.0",
47
- "node-opcua-service-read": "2.103.0",
48
- "node-opcua-service-register-node": "2.103.0",
49
- "node-opcua-service-secure-channel": "2.103.0",
50
- "node-opcua-service-session": "2.103.0",
51
- "node-opcua-service-subscription": "2.103.0",
52
- "node-opcua-service-translate-browse-path": "2.103.0",
53
- "node-opcua-service-write": "2.103.0",
54
- "node-opcua-status-code": "2.98.1",
55
- "node-opcua-types": "2.103.0",
56
- "node-opcua-utils": "2.98.1",
57
- "node-opcua-variant": "2.102.0",
27
+ "node-opcua-crypto": "3.0.5",
28
+ "node-opcua-data-model": "2.104.0",
29
+ "node-opcua-data-value": "2.104.0",
30
+ "node-opcua-date-time": "2.104.0",
31
+ "node-opcua-debug": "2.104.0",
32
+ "node-opcua-extension-object": "2.104.0",
33
+ "node-opcua-hostname": "2.104.0",
34
+ "node-opcua-nodeid": "2.104.0",
35
+ "node-opcua-object-registry": "2.104.0",
36
+ "node-opcua-pki": "4.2.0",
37
+ "node-opcua-pseudo-session": "2.104.0",
38
+ "node-opcua-schemas": "2.104.0",
39
+ "node-opcua-secure-channel": "2.104.0",
40
+ "node-opcua-service-browse": "2.104.0",
41
+ "node-opcua-service-call": "2.104.0",
42
+ "node-opcua-service-discovery": "2.104.0",
43
+ "node-opcua-service-endpoints": "2.104.0",
44
+ "node-opcua-service-filter": "2.104.0",
45
+ "node-opcua-service-history": "2.104.0",
46
+ "node-opcua-service-query": "2.104.0",
47
+ "node-opcua-service-read": "2.104.0",
48
+ "node-opcua-service-register-node": "2.104.0",
49
+ "node-opcua-service-secure-channel": "2.104.0",
50
+ "node-opcua-service-session": "2.104.0",
51
+ "node-opcua-service-subscription": "2.104.0",
52
+ "node-opcua-service-translate-browse-path": "2.104.0",
53
+ "node-opcua-service-write": "2.104.0",
54
+ "node-opcua-status-code": "2.104.0",
55
+ "node-opcua-types": "2.104.0",
56
+ "node-opcua-utils": "2.104.0",
57
+ "node-opcua-variant": "2.104.0",
58
58
  "thenify": "^3.3.1"
59
59
  },
60
60
  "devDependencies": {
61
- "@types/underscore": "^1.11.4",
61
+ "@types/underscore": "^1.11.5",
62
62
  "dequeue": "^1.0.5",
63
63
  "mocha": "^10.2.0",
64
- "node-opcua-address-space": "2.103.0",
65
- "node-opcua-binary-stream": "2.98.1",
66
- "node-opcua-factory": "2.99.0",
67
- "node-opcua-leak-detector": "2.99.0",
64
+ "node-opcua-address-space": "2.104.0",
65
+ "node-opcua-binary-stream": "2.104.0",
66
+ "node-opcua-factory": "2.104.0",
67
+ "node-opcua-leak-detector": "2.104.0",
68
68
  "node-opcua-nodesets": "2.103.0",
69
69
  "should": "^13.2.3",
70
- "sinon": "^15.0.3",
70
+ "sinon": "^15.1.0",
71
71
  "underscore": "^1.13.6"
72
72
  },
73
73
  "eslintConfig": {
@@ -90,7 +90,7 @@
90
90
  "internet of things"
91
91
  ],
92
92
  "homepage": "http://node-opcua.github.io/",
93
- "gitHead": "e206cac2daf39bd07e5ac6cbd744f966bb54759e",
93
+ "gitHead": "3cd6d355e8b3c66822d08a3ca682659ea5d1a55d",
94
94
  "files": [
95
95
  "dist",
96
96
  "source"
@@ -1,4 +1,4 @@
1
- import * as chalk from "chalk";
1
+ import chalk from "chalk";
2
2
  import { AttributeIds } from "node-opcua-data-model";
3
3
  import { NodeId } from "node-opcua-nodeid";
4
4
  import { IBasicSession } from "node-opcua-pseudo-session";
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @module node-opcua-client
3
3
  */
4
- import * as chalk from "chalk";
4
+ import chalk from "chalk";
5
5
 
6
6
  import { assert } from "node-opcua-assert";
7
7
  import { TimestampsToReturn } from "node-opcua-data-value";
@@ -2,7 +2,7 @@
2
2
  * @module node-opcua-client
3
3
  */
4
4
  import { EventEmitter } from "events";
5
- import * as chalk from "chalk";
5
+ import chalk from "chalk";
6
6
  import { assert } from "node-opcua-assert";
7
7
  import { ServerState } from "node-opcua-common";
8
8
  import { VariableIds } from "node-opcua-constants";
@@ -5,12 +5,11 @@
5
5
  import * as fs from "fs";
6
6
  import * as path from "path";
7
7
  import * as async from "async";
8
- import * as chalk from "chalk";
9
-
8
+ import chalk from "chalk";
10
9
  import { withLock } from "@ster5/global-mutex";
11
10
  import { assert } from "node-opcua-assert";
12
11
  import { IOPCUASecureObjectOptions, OPCUASecureObject } from "node-opcua-common";
13
- import { Certificate, makeSHA1Thumbprint, Nonce } from "node-opcua-crypto";
12
+ import { Certificate, makeSHA1Thumbprint, Nonce, split_der } from "node-opcua-crypto";
14
13
  import { installPeriodicClockAdjustment, periodicClockAdjustment, uninstallPeriodicClockAdjustment } from "node-opcua-date-time";
15
14
  import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
16
15
 
@@ -750,11 +749,14 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
750
749
  if ((this as any)._inCreateDefaultCertificate) {
751
750
  errorLog("Internal error : re-entrancy in createDefaultCertificate!");
752
751
  }
753
-
754
752
  (this as any)._inCreateDefaultCertificate = true;
755
753
  if (!fs.existsSync(this.certificateFile)) {
756
- const lockfile = path.join(this.certificateFile + ".lock");
757
- await withLock({ lockfile: lockfile, maxStaleDuration: 60 * 1000, retryInterval: 100 }, async () => {
754
+ await withLock({ fileToLock: this.certificateFile + ".mutex" }, async () => {
755
+ if (fs.existsSync(this.certificateFile)) {
756
+ // the file may have been created in between
757
+ return;
758
+ }
759
+ console.log("Creating default certificate ... please wait");
758
760
  if (this.disconnecting) return;
759
761
 
760
762
  await ClientBaseImpl.createCertificate(
@@ -797,13 +799,10 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
797
799
  if (!fs.existsSync(this.privateKeyFile)) {
798
800
  throw new Error(" cannot locate private key file " + this.privateKeyFile);
799
801
  }
800
-
801
802
  if (this.disconnecting) return;
802
803
 
803
- const lockfile = path.join(this.certificateFile + ".lock");
804
- await withLock({ lockfile: lockfile, maxStaleDuration: 60 * 1000, retryInterval: 100 }, async () => {
805
- if (this.disconnecting) return;
806
- await performCertificateSanityCheck.call(this, "client", this.clientCertificateManager, this._getBuiltApplicationUri());
804
+ await this.clientCertificateManager.withLock2(async () => {
805
+ await performCertificateSanityCheck(this, "client", this.clientCertificateManager, this._getBuiltApplicationUri());
807
806
  });
808
807
  }
809
808
 
@@ -938,6 +937,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
938
937
  /* */
939
938
  this._handleDisconnectionWhileConnecting(err, callback);
940
939
  } else {
940
+ console.log("REMOVE ME", err.stack);
941
941
  err = new Error("The connection may have been rejected by server,\n" + "Err = (" + err.message + ")");
942
942
  this._handleUnrecoverableConnectionFailure(err, callback);
943
943
  }
@@ -1289,12 +1289,12 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
1289
1289
  tmpChannel = null;
1290
1290
  this._destroy_secure_channel();
1291
1291
  this._setInternalState("disconnected");
1292
- setImmediate(callback);
1292
+ callback();
1293
1293
  });
1294
1294
  } else {
1295
1295
  this._setInternalState("disconnected");
1296
- // this.emit("close", null);
1297
- setImmediate(callback);
1296
+ // this.emit("close", null);
1297
+ callback();
1298
1298
  }
1299
1299
  }
1300
1300
 
@@ -1416,14 +1416,28 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
1416
1416
  _verify_serverCertificate(this.clientCertificateManager, endpoint.serverCertificate, (err1?: Error) => {
1417
1417
  if (err1) {
1418
1418
  warningLog("[NODE-OPCUA-W25] client's server certificate verification has failed ", err1.message);
1419
- warningLog(" ", this.clientCertificateManager.rootDir);
1420
- warningLog(
1421
- " ",
1422
- endpoint.serverCertificate.toString("base64").replace(/(.{80})/g, "$1\n ")
1423
- );
1424
- warningLog(
1425
- " verify that server certificate is trusted or that server certificate issuer's certificate is present in the issuer folder"
1426
- );
1419
+ warningLog(" clientCertificateManager.rootDir = ", this.clientCertificateManager.rootDir);
1420
+
1421
+ const f = (b: Buffer) =>
1422
+ " " + b.toString("base64").replace(/(.{80})/g, "$1\n ");
1423
+
1424
+ const chain = split_der(endpoint.serverCertificate);
1425
+ warningLog(` server certificate contains ${chain.length} elements`);
1426
+ for (let i = 0; i < chain.length; i++) {
1427
+ const c = chain[i];
1428
+ warningLog("certificate", i, "\n" + f(c));
1429
+ }
1430
+ if (chain.length > 1) {
1431
+ warningLog(
1432
+ " verify also that the issuer certificate is trusted and the issuer's certificate is present in the issuer.cert folder\n" +
1433
+ " of the client certificate manager located in ",
1434
+ this.clientCertificateManager.rootDir
1435
+ );
1436
+ } else {
1437
+ warningLog(
1438
+ " verify that the server certificate is trusted or that server certificate issuer's certificate is present in the issuer folder"
1439
+ );
1440
+ }
1427
1441
  return callback(err1);
1428
1442
  }
1429
1443
  this.serverCertificate = endpoint.serverCertificate;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { types } from "util";
5
5
  import * as async from "async";
6
- import * as chalk from "chalk";
6
+ import chalk from "chalk";
7
7
  import { assert } from "node-opcua-assert";
8
8
  import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
9
9
  import { PublishRequest, PublishResponse, RepublishRequest, RepublishResponse } from "node-opcua-service-subscription";
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { EventEmitter } from "events";
5
5
  import { callbackify } from "util";
6
- import * as chalk from "chalk";
6
+ import chalk from "chalk";
7
7
  import { assert } from "node-opcua-assert";
8
8
  import { AggregateFunction } from "node-opcua-constants";
9
9
  import { DateTime } from "node-opcua-basic-types";
@@ -4,7 +4,7 @@
4
4
  // tslint:disable:unified-signatures
5
5
  import { EventEmitter } from "events";
6
6
  import * as async from "async";
7
- import * as chalk from "chalk";
7
+ import chalk from "chalk";
8
8
 
9
9
  import { assert } from "node-opcua-assert";
10
10
  import { AttributeIds } from "node-opcua-data-model";
@@ -9,7 +9,7 @@ import * as crypto from "crypto";
9
9
  import { createPublicKey } from "crypto";
10
10
  import { callbackify } from "util";
11
11
  import * as async from "async";
12
- import * as chalk from "chalk";
12
+ import chalk from "chalk";
13
13
 
14
14
  import { assert } from "node-opcua-assert";
15
15
  import { createFastUninitializedBuffer } from "node-opcua-buffer-utils";
@@ -19,7 +19,6 @@ import {
19
19
  extractPublicKeyFromCertificateSync,
20
20
  Nonce,
21
21
  PrivateKey,
22
- PrivateKeyPEM,
23
22
  toPem
24
23
  } from "node-opcua-crypto";
25
24
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  // tslint:disable:only-arrow-functions
6
6
  import * as async from "async";
7
- import * as chalk from "chalk";
7
+ import chalk from "chalk";
8
8
  import { assert } from "node-opcua-assert";
9
9
  import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
10
10
  import { TransferSubscriptionsRequest, TransferSubscriptionsResponse } from "node-opcua-service-subscription";
@@ -55,18 +55,24 @@ export function readHistoryServerCapabilities(
55
55
  const properties = [
56
56
  "AccessHistoryDataCapability",
57
57
  "AccessHistoryEventsCapability",
58
+
58
59
  "DeleteAtTimeCapability",
59
60
  "DeleteRawCapability",
60
61
  "DeleteEventCapability",
62
+
61
63
  "InsertAnnotationCapability",
62
64
  "InsertDataCapability",
63
65
  "InsertEventCapability",
66
+
64
67
  "ReplaceDataCapability",
65
68
  "ReplaceEventCapability",
69
+
66
70
  "UpdateDataCapability",
67
71
  "UpdateEventCapability",
72
+
68
73
  "MaxReturnDataValues",
69
74
  "MaxReturnEventValues",
75
+
70
76
  "AggregateFunctions/AnnotationCount",
71
77
  "AggregateFunctions/Average",
72
78
  "AggregateFunctions/Count",
package/source/verify.ts CHANGED
@@ -86,6 +86,7 @@ export function verifyIsOPCUAValidCertificate(
86
86
  `see https://reference.opcfoundation.org/v104/Core/docs/Part6/6.2.2/\n` +
87
87
  `certificateFile = ${certificateFile}`
88
88
  );
89
+ warningLog(`keyUsage = ${JSON.stringify(keyUsage, null, " ")}`);
89
90
  }
90
91
  }
91
92
  const extKeyUsage = certificateInfo.tbsCertificate.extensions?.extKeyUsage;
@@ -120,21 +121,21 @@ export function verifyIsOPCUAValidCertificate(
120
121
  }
121
122
 
122
123
  export async function performCertificateSanityCheck(
123
- this: OPCUASecureObject,
124
+ secureObject: OPCUASecureObject,
124
125
  serverOrClient: "server" | "client",
125
126
  certificateManager: OPCUACertificateManager,
126
127
  applicationUri: string
127
128
  ): Promise<void> {
128
- // verify that certificate is matching private key, and inform the developper if not
129
- const certificate = this.getCertificate();
130
- const privateKey = this.getPrivateKey();
129
+ // verify that certificate is matching private key, and inform the developer if not
130
+ const certificate = secureObject.getCertificate();
131
+ const privateKey = secureObject.getPrivateKey();
131
132
  //
132
133
  if (!publicKeyAndPrivateKeyMatches(certificate, privateKey)) {
133
134
  errorLog("[NODE-OPCUA-E01] Configuration error : the certificate and the private key do not match !");
134
135
  errorLog(" please check the configuration of the OPCUA Server");
135
- errorLog(" privateKey= ", this.privateKeyFile);
136
+ errorLog(" privateKey= ", secureObject.privateKeyFile);
136
137
  errorLog(" certificateManager.privateKey= ", certificateManager.privateKey);
137
- errorLog(" certificateFile= ", this.certificateFile);
138
+ errorLog(" certificateFile= ", secureObject.certificateFile);
138
139
  throw new Error(
139
140
  "[NODE-OPCUA-E01] Configuration error : the certificate and the private key do not match ! please fix your configuration"
140
141
  );
@@ -154,8 +155,8 @@ export async function performCertificateSanityCheck(
154
155
  const status = await certificateManager.verifyCertificateAsync(certificate);
155
156
 
156
157
  if (status !== "Good") {
157
- warningLog("[NODE-OPCUA-W04] Warning: the certificate status is = ", status, " file = ", this.certificateFile);
158
+ warningLog("[NODE-OPCUA-W04] Warning: the certificate status is = ", status, " file = ", secureObject.certificateFile);
158
159
  }
159
160
 
160
- verifyIsOPCUAValidCertificate(certificate, this.certificateFile, serverOrClient, applicationUri);
161
+ verifyIsOPCUAValidCertificate(certificate, secureObject.certificateFile, serverOrClient, applicationUri);
161
162
  }