node-opcua-server 2.100.0 → 2.102.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-server",
3
- "version": "2.100.0",
3
+ "version": "2.102.0",
4
4
  "description": "pure nodejs OPCUA SDK - module server",
5
5
  "scripts": {
6
6
  "build": "tsc -b",
@@ -17,19 +17,19 @@
17
17
  "chalk": "4.1.2",
18
18
  "dequeue": "^1.0.5",
19
19
  "lodash": "4.17.21",
20
- "node-opcua-address-space": "2.100.0",
21
- "node-opcua-address-space-base": "2.100.0",
20
+ "node-opcua-address-space": "2.102.0",
21
+ "node-opcua-address-space-base": "2.102.0",
22
22
  "node-opcua-assert": "2.98.1",
23
23
  "node-opcua-basic-types": "2.99.0",
24
24
  "node-opcua-binary-stream": "2.98.1",
25
25
  "node-opcua-certificate-manager": "2.99.0",
26
- "node-opcua-client": "2.100.0",
27
- "node-opcua-client-dynamic-extension-object": "2.99.0",
28
- "node-opcua-common": "2.99.0",
26
+ "node-opcua-client": "2.102.0",
27
+ "node-opcua-client-dynamic-extension-object": "2.102.0",
28
+ "node-opcua-common": "2.102.0",
29
29
  "node-opcua-constants": "2.98.1",
30
30
  "node-opcua-crypto": "^2.1.2",
31
- "node-opcua-data-model": "2.99.0",
32
- "node-opcua-data-value": "2.99.0",
31
+ "node-opcua-data-model": "2.102.0",
32
+ "node-opcua-data-value": "2.102.0",
33
33
  "node-opcua-date-time": "2.99.0",
34
34
  "node-opcua-debug": "2.99.0",
35
35
  "node-opcua-extension-object": "2.99.0",
@@ -37,32 +37,32 @@
37
37
  "node-opcua-hostname": "2.98.1",
38
38
  "node-opcua-nodeid": "2.99.0",
39
39
  "node-opcua-nodesets": "2.99.0",
40
- "node-opcua-numeric-range": "2.99.0",
40
+ "node-opcua-numeric-range": "2.102.0",
41
41
  "node-opcua-object-registry": "2.99.0",
42
- "node-opcua-secure-channel": "2.99.0",
43
- "node-opcua-service-browse": "2.99.0",
44
- "node-opcua-service-call": "2.99.0",
45
- "node-opcua-service-discovery": "2.99.0",
46
- "node-opcua-service-endpoints": "2.99.0",
47
- "node-opcua-service-filter": "2.100.0",
48
- "node-opcua-service-history": "2.99.0",
49
- "node-opcua-service-node-management": "2.99.0",
50
- "node-opcua-service-query": "2.99.0",
51
- "node-opcua-service-read": "2.99.0",
52
- "node-opcua-service-register-node": "2.99.0",
53
- "node-opcua-service-secure-channel": "2.99.0",
54
- "node-opcua-service-session": "2.99.0",
55
- "node-opcua-service-subscription": "2.99.0",
56
- "node-opcua-service-translate-browse-path": "2.99.0",
57
- "node-opcua-service-write": "2.99.0",
42
+ "node-opcua-secure-channel": "2.102.0",
43
+ "node-opcua-service-browse": "2.102.0",
44
+ "node-opcua-service-call": "2.102.0",
45
+ "node-opcua-service-discovery": "2.102.0",
46
+ "node-opcua-service-endpoints": "2.102.0",
47
+ "node-opcua-service-filter": "2.102.0",
48
+ "node-opcua-service-history": "2.102.0",
49
+ "node-opcua-service-node-management": "2.102.0",
50
+ "node-opcua-service-query": "2.102.0",
51
+ "node-opcua-service-read": "2.102.0",
52
+ "node-opcua-service-register-node": "2.102.0",
53
+ "node-opcua-service-secure-channel": "2.102.0",
54
+ "node-opcua-service-session": "2.102.0",
55
+ "node-opcua-service-subscription": "2.102.0",
56
+ "node-opcua-service-translate-browse-path": "2.102.0",
57
+ "node-opcua-service-write": "2.102.0",
58
58
  "node-opcua-status-code": "2.98.1",
59
- "node-opcua-types": "2.99.0",
59
+ "node-opcua-types": "2.102.0",
60
60
  "node-opcua-utils": "2.98.1",
61
- "node-opcua-variant": "2.99.0",
61
+ "node-opcua-variant": "2.102.0",
62
62
  "thenify": "^3.3.1"
63
63
  },
64
64
  "devDependencies": {
65
- "node-opcua-data-access": "2.99.0",
65
+ "node-opcua-data-access": "2.102.0",
66
66
  "node-opcua-leak-detector": "2.99.0",
67
67
  "node-opcua-pki": "^3.0.2",
68
68
  "node-opcua-test-helpers": "2.98.1",
@@ -85,7 +85,7 @@
85
85
  "internet of things"
86
86
  ],
87
87
  "homepage": "http://node-opcua.github.io/",
88
- "gitHead": "e143ff72418bb3db8c0a2cb8d4b7e54a90521a73",
88
+ "gitHead": "07dcdd8e8c7f2b55544c6e23023093e35674829c",
89
89
  "files": [
90
90
  "dist",
91
91
  "source"
@@ -5,6 +5,7 @@
5
5
  import * as fs from "fs";
6
6
  import * as path from "path";
7
7
  import * as os from "os";
8
+ import { types } from "util";
8
9
  import * as async from "async";
9
10
  import * as chalk from "chalk";
10
11
  import { withLock } from "@ster5/global-mutex";
@@ -400,7 +401,7 @@ export class OPCUABaseServer extends OPCUASecureObject {
400
401
 
401
402
  let additional_messages = [];
402
403
  additional_messages.push("EXCEPTION CAUGHT WHILE PROCESSING REQUEST !!! " + request.schema.name);
403
- if (err instanceof Error) {
404
+ if (types.isNativeError(err)) {
404
405
  additional_messages.push(err.message);
405
406
  if (err.stack) {
406
407
  additional_messages = additional_messages.concat(err.stack.split("\n"));
@@ -8,7 +8,7 @@
8
8
 
9
9
  import * as crypto from "crypto";
10
10
  import { EventEmitter } from "events";
11
- import { callbackify } from "util";
11
+ import { callbackify, types } from "util";
12
12
 
13
13
  import * as async from "async";
14
14
  import * as chalk from "chalk";
@@ -168,7 +168,7 @@ import { RegisterServerManager } from "./register_server_manager";
168
168
  import { RegisterServerManagerHidden } from "./register_server_manager_hidden";
169
169
  import { RegisterServerManagerMDNSONLY } from "./register_server_manager_mdns_only";
170
170
  import { ServerCapabilitiesOptions } from "./server_capabilities";
171
- import { OPCUAServerEndPoint } from "./server_end_point";
171
+ import { EndpointDescriptionEx, OPCUAServerEndPoint } from "./server_end_point";
172
172
  import { ClosingReason, CreateSessionOption, ServerEngine } from "./server_engine";
173
173
  import { ServerSession } from "./server_session";
174
174
  import { CreateMonitoredItemHook, DeleteMonitoredItemHook, Subscription } from "./server_subscription";
@@ -642,10 +642,10 @@ function validate_security_endpoint(
642
642
  if (endpoints.length === 0) {
643
643
  // we have a UrlMismatch here
644
644
  const ua_server = server.engine.addressSpace!.rootFolder.objects.server;
645
+ errorLog("Cannot find suitable endpoints in available endpoints. endpointUri =", request.endpointUrl);
645
646
  ua_server.raiseEvent("AuditUrlMismatchEventType", {
646
647
  endpointUrl: { dataType: DataType.String, value: request.endpointUrl }
647
648
  });
648
- debugLog("Cannot find endpoint in available endpoints with endpointUri", request.endpointUrl);
649
649
  if (OPCUAServer.requestExactEndpointUrl) {
650
650
  return { errCode: StatusCodes.BadServiceUnsupported };
651
651
  } else {
@@ -653,7 +653,7 @@ function validate_security_endpoint(
653
653
  }
654
654
  }
655
655
  // ignore restricted endpoints
656
- endpoints = endpoints.filter((e: EndpointDescription) => !(e as any).restricted);
656
+ endpoints = endpoints.filter((e: EndpointDescription) => !(e as EndpointDescriptionEx).restricted);
657
657
 
658
658
  const endpoints_matching_security_mode = endpoints.filter((e: EndpointDescription) => {
659
659
  return e.securityMode === channel.securityMode;
@@ -1148,7 +1148,7 @@ export class OPCUAServer extends OPCUABaseServer {
1148
1148
  const hostname = getFullyQualifiedDomainName();
1149
1149
 
1150
1150
  endpointDefinitions.push({
1151
- port: options.port || 26543,
1151
+ port: options.port === undefined ? 26543 : options.port,
1152
1152
 
1153
1153
  allowAnonymous: options.allowAnonymous,
1154
1154
  alternateHostname: options.alternateHostname,
@@ -2257,7 +2257,7 @@ export class OPCUAServer extends OPCUABaseServer {
2257
2257
  } catch (err) {
2258
2258
  warningLog(err);
2259
2259
  // istanbul ignore next
2260
- if (err instanceof Error) {
2260
+ if (types.isNativeError(err)) {
2261
2261
  // istanbul ignore next
2262
2262
  errorLog(
2263
2263
  "Internal error in issuing response\nplease contact support@sterfive.com",
@@ -3526,7 +3526,7 @@ export class OPCUAServer extends OPCUABaseServer {
3526
3526
  }
3527
3527
  const hostname = getFullyQualifiedDomainName();
3528
3528
  endpointOptions.hostname = endpointOptions.hostname || hostname;
3529
- endpointOptions.port = endpointOptions.port || 26543;
3529
+ endpointOptions.port = endpointOptions.port === undefined ? 26543 : endpointOptions.port ;
3530
3530
 
3531
3531
  /* istanbul ignore next */
3532
3532
  if (
@@ -43,10 +43,12 @@ export class RegisterServerManagerMDNSONLY extends EventEmitter implements IRegi
43
43
  }
44
44
  assert(this.server instanceof OPCUABaseServer);
45
45
 
46
+ const host = "TODO-find how to extract hostname";
46
47
  this.bonjour.announcedOnMulticastSubnetWithCallback({
47
48
  capabilities: this.server.capabilitiesForMDNS,
48
49
  name: this.server.serverInfo.applicationUri!,
49
50
  path: "/", // <- to do
51
+ host,
50
52
  port: this.server.endpoints[0].port
51
53
  }, ()=>{
52
54
  this.emit("serverRegistered");
@@ -9,8 +9,8 @@ import * as chalk from "chalk";
9
9
  import * as async from "async";
10
10
 
11
11
  import { assert } from "node-opcua-assert";
12
- import { ICertificateManager, OPCUACertificateManager } from "node-opcua-certificate-manager";
13
- import { Certificate, convertPEMtoDER, makeSHA1Thumbprint, PrivateKey, PrivateKeyPEM, split_der } from "node-opcua-crypto";
12
+ import { OPCUACertificateManager } from "node-opcua-certificate-manager";
13
+ import { Certificate, makeSHA1Thumbprint, PrivateKey, split_der } from "node-opcua-crypto";
14
14
  import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
15
15
  import { getFullyQualifiedDomainName, resolveFullyQualifiedDomainName } from "node-opcua-hostname";
16
16
  import {
@@ -20,7 +20,6 @@ import {
20
20
  ServerSecureChannelLayer,
21
21
  ServerSecureChannelParent,
22
22
  toURI,
23
- AsymmetricAlgorithmSecurityHeader,
24
23
  IServerSessionBase,
25
24
  Message
26
25
  } from "node-opcua-secure-channel";
@@ -83,9 +82,8 @@ function extractChannelData(channel: ServerSecureChannelLayer): IChannelData {
83
82
 
84
83
  function dumpChannelInfo(channels: ServerSecureChannelLayer[]): void {
85
84
  function d(s: IServerSessionBase) {
86
- return `[ status=${s.status} lastSeen=${s.clientLastContactTime.toFixed(0)}ms sessionName=${s.sessionName} timeout=${
87
- s.sessionTimeout
88
- } ]`;
85
+ return `[ status=${s.status} lastSeen=${s.clientLastContactTime.toFixed(0)}ms sessionName=${s.sessionName} timeout=${s.sessionTimeout
86
+ } ]`;
89
87
  }
90
88
  function dumpChannel(channel: ServerSecureChannelLayer): void {
91
89
  console.log("------------------------------------------------------");
@@ -381,7 +379,6 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
381
379
  }
382
380
  //
383
381
 
384
- const port = this.port;
385
382
 
386
383
  // resource Path is a string added at the end of the url such as "/UA/Server"
387
384
  const resourcePath = (options.resourcePath || "").replace(/\\/g, "/");
@@ -389,7 +386,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
389
386
  assert(resourcePath.length === 0 || resourcePath.charAt(0) === "/", "resourcePath should start with /");
390
387
 
391
388
  const hostname = options.hostname || getFullyQualifiedDomainName();
392
- const endpointUrl = `opc.tcp://${hostname}:${port}${resourcePath}`;
389
+ const endpointUrl = `opc.tcp://${hostname}:${this.port}${resourcePath}`;
393
390
 
394
391
  const endpoint_desc = this.getEndpointDescription(securityMode, securityPolicy, endpointUrl);
395
392
 
@@ -404,10 +401,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
404
401
  this._endpoints.push(
405
402
  _makeEndpointDescription({
406
403
  collection: this._policy_deduplicator,
407
- endpointUrl,
408
404
  hostname,
409
- port,
410
-
411
405
  server: this.serverInfo,
412
406
  serverCertificateChain: this.getCertificateChain(),
413
407
 
@@ -421,7 +415,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
421
415
  securityPolicies: options.securityPolicies || [],
422
416
 
423
417
  userTokenTypes
424
- })
418
+ }, this)
425
419
  );
426
420
  }
427
421
 
@@ -511,16 +505,23 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
511
505
  this._server!.on("listening", () => {
512
506
  debugLog("server is listening");
513
507
  });
508
+
514
509
  this._server!.listen(
515
510
  this.port,
516
- /*"::",*/ (err?: Error) => {
511
+ /*"::",*/(err?: Error) => {
517
512
  // 'listening' listener
518
513
  debugLog(chalk.green.bold("LISTENING TO PORT "), this.port, "err ", err);
519
514
  assert(!err, " cannot listen to port ");
520
515
  this._started = true;
516
+ if (!this.port) {
517
+ const add = this._server!.address()!;
518
+ this.port = typeof add !== "string" ? add.port : this.port;
519
+
520
+ }
521
521
  this._end_listen();
522
522
  }
523
523
  );
524
+
524
525
  }
525
526
 
526
527
  public killClientSockets(callback: (err?: Error) => void): void {
@@ -691,7 +692,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
691
692
  debugLog(
692
693
  chalk.bgWhite.cyan(
693
694
  "OPCUAServerEndPoint#_on_client_connection " +
694
- "SERVER END POINT IS PROBABLY SHUTTING DOWN !!! - Connection is refused"
695
+ "SERVER END POINT IS PROBABLY SHUTTING DOWN !!! - Connection is refused"
695
696
  )
696
697
  );
697
698
  socket.end();
@@ -701,7 +702,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
701
702
  console.log(
702
703
  chalk.bgWhite.cyan(
703
704
  "OPCUAServerEndPoint#_on_client_connection " +
704
- "The maximum number of connection has been reached - Connection is refused"
705
+ "The maximum number of connection has been reached - Connection is refused"
705
706
  )
706
707
  );
707
708
  const reason = "maxConnections reached (" + this.maxConnections + ")";
@@ -937,19 +938,11 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
937
938
  }
938
939
 
939
940
  interface MakeEndpointDescriptionOptions {
940
- /**
941
- * port number s
942
- */
943
- port: number;
944
941
 
945
942
  /**
946
943
  * @default default hostname (default value will be full qualified domain name)
947
944
  */
948
945
  hostname: string;
949
- /**
950
- *
951
- */
952
- endpointUrl: string;
953
946
 
954
947
  serverCertificateChain: Certificate;
955
948
  /**
@@ -1000,7 +993,8 @@ interface MakeEndpointDescriptionOptions {
1000
993
  noUserIdentityTokens?: boolean;
1001
994
  }
1002
995
 
1003
- interface EndpointDescriptionEx extends EndpointDescription {
996
+ export interface EndpointDescriptionEx extends EndpointDescription {
997
+ _parent: OPCUAServerEndPoint;
1004
998
  restricted: boolean;
1005
999
  }
1006
1000
 
@@ -1038,8 +1032,7 @@ function estimateSecurityLevel(securityMode: MessageSecurityMode, securityPolicy
1038
1032
  /**
1039
1033
  * @private
1040
1034
  */
1041
- function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): EndpointDescriptionEx {
1042
- assert(isFinite(options.port), "expecting a valid port number");
1035
+ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions, parent: OPCUAServerEndPoint): EndpointDescriptionEx {
1043
1036
  assert(Object.prototype.hasOwnProperty.call(options, "serverCertificateChain"));
1044
1037
  assert(!Object.prototype.hasOwnProperty.call(options, "serverCertificate"));
1045
1038
  assert(!!options.securityMode); // s.MessageSecurityMode
@@ -1146,7 +1139,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp
1146
1139
  }
1147
1140
  // return the endpoint object
1148
1141
  const endpoint = new EndpointDescription({
1149
- endpointUrl: options.endpointUrl,
1142
+ endpointUrl: '<to be evaluated at run time>',// options.endpointUrl,
1150
1143
 
1151
1144
  server: undefined, // options.server,
1152
1145
  serverCertificate: options.serverCertificateChain,
@@ -1158,9 +1151,16 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp
1158
1151
  securityLevel: options.securityLevel,
1159
1152
  transportProfileUri: default_transportProfileUri
1160
1153
  }) as EndpointDescriptionEx;
1161
-
1154
+ endpoint._parent = parent;
1155
+
1156
+ // endpointUrl is dynamic as port number may be adjusted
1157
+ // when the tcp socker start listening
1162
1158
  (endpoint as any).__defineGetter__("endpointUrl", () => {
1163
- return resolveFullyQualifiedDomainName(options.endpointUrl);
1159
+ const port = endpoint._parent.port;
1160
+ const resourcePath = options.resourcePath || "";
1161
+ const hostname = options.hostname;
1162
+ const endpointUrl = `opc.tcp://${hostname}:${port}${resourcePath}`;
1163
+ return resolveFullyQualifiedDomainName(endpointUrl);
1164
1164
  });
1165
1165
 
1166
1166
  endpoint.server = options.server;
@@ -2,6 +2,7 @@
2
2
  * @module node-opcua-server
3
3
  */
4
4
  import { EventEmitter } from "events";
5
+ import { types } from "util";
5
6
  import * as async from "async";
6
7
  import * as chalk from "chalk";
7
8
  import { assert } from "node-opcua-assert";
@@ -1353,7 +1354,7 @@ export class ServerEngine extends EventEmitter {
1353
1354
  await node.onFirstBrowseAction();
1354
1355
  node.onFirstBrowseAction = undefined;
1355
1356
  } catch (err) {
1356
- if (err instanceof Error) {
1357
+ if (types.isNativeError(err)) {
1357
1358
  errorLog("onFirstBrowseAction method has failed", err.message);
1358
1359
  }
1359
1360
  errorLog(err);
@@ -1,3 +1,4 @@
1
+ import { types } from "util";
1
2
  import { IUserManager, UARoleSet } from "node-opcua-address-space";
2
3
  import { NodeId } from "node-opcua-nodeid";
3
4
  import { IdentityMappingRuleType } from "node-opcua-types";
@@ -52,7 +53,7 @@ export class UAUserManager1 extends UAUserManagerBase {
52
53
  try {
53
54
  return this.options.getUserRoles(user);
54
55
  } catch (err) {
55
- if (err instanceof Error) {
56
+ if (types.isNativeError(err)) {
56
57
  errorLog(
57
58
  "[NODE-OPCUA-E27] userManager provided getUserRoles method has thrown an exception, please fix your code! "
58
59
  );
@@ -75,7 +76,7 @@ export class UAUserManager1 extends UAUserManagerBase {
75
76
  const authorized = this.options.isValidUser!.call(session, username, password);
76
77
  return authorized;
77
78
  } catch (err) {
78
- if (err instanceof Error) {
79
+ if (types.isNativeError(err)) {
79
80
  errorLog(
80
81
  "[NODE-OPCUA-E26] userManager provided isValidUser method has thrown an exception, please fix your code!"
81
82
  );