node-opcua-server 2.117.0 → 2.119.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 (41) hide show
  1. package/dist/addressSpace_accessor.js.map +1 -1
  2. package/dist/base_server.js +14 -37
  3. package/dist/base_server.js.map +1 -1
  4. package/dist/factory.js.map +1 -1
  5. package/dist/helper.js +4 -24
  6. package/dist/helper.js.map +1 -1
  7. package/dist/history_server_capabilities.js.map +1 -1
  8. package/dist/monitored_item.js.map +1 -1
  9. package/dist/node_sampler.js.map +1 -1
  10. package/dist/opcua_server.d.ts +14 -2
  11. package/dist/opcua_server.js +46 -44
  12. package/dist/opcua_server.js.map +1 -1
  13. package/dist/queue.js.map +1 -1
  14. package/dist/register_server_manager.js +4 -27
  15. package/dist/register_server_manager.js.map +1 -1
  16. package/dist/register_server_manager_mdns_only.js +1 -1
  17. package/dist/register_server_manager_mdns_only.js.map +1 -1
  18. package/dist/server_capabilities.js +2 -2
  19. package/dist/server_capabilities.js.map +1 -1
  20. package/dist/server_end_point.d.ts +5 -0
  21. package/dist/server_end_point.js +49 -45
  22. package/dist/server_end_point.js.map +1 -1
  23. package/dist/server_engine.d.ts +25 -1
  24. package/dist/server_engine.js +26 -27
  25. package/dist/server_engine.js.map +1 -1
  26. package/dist/server_publish_engine.js.map +1 -1
  27. package/dist/server_session.js +1 -1
  28. package/dist/server_session.js.map +1 -1
  29. package/dist/server_subscription.d.ts +5 -5
  30. package/dist/server_subscription.js.map +1 -1
  31. package/dist/sessions_compatible_for_transfer.js.map +1 -1
  32. package/dist/user_manager.js.map +1 -1
  33. package/dist/user_manager_ua.js.map +1 -1
  34. package/dist/validate_filter.js.map +1 -1
  35. package/package.json +41 -41
  36. package/source/base_server.ts +4 -4
  37. package/source/helper.ts +1 -1
  38. package/source/opcua_server.ts +62 -20
  39. package/source/register_server_manager.ts +1 -1
  40. package/source/server_end_point.ts +51 -20
  41. package/source/server_engine.ts +80 -2
@@ -1,12 +1,13 @@
1
+ /* eslint-disable max-statements */
1
2
  /**
2
3
  * @module node-opcua-server
3
4
  */
4
5
  // tslint:disable:no-console
5
6
  import { EventEmitter } from "events";
6
- import * as net from "net";
7
+ import net from "net";
7
8
  import { Server, Socket } from "net";
8
9
  import chalk from "chalk";
9
- import * as async from "async";
10
+ import async from "async";
10
11
 
11
12
  import { assert } from "node-opcua-assert";
12
13
  import { OPCUACertificateManager } from "node-opcua-certificate-manager";
@@ -120,6 +121,10 @@ export interface OPCUAServerEndPointOptions {
120
121
  * the tcp port
121
122
  */
122
123
  port: number;
124
+ /**
125
+ * the tcp host
126
+ */
127
+ host?: string;
123
128
  /**
124
129
  * the DER certificate chain
125
130
  */
@@ -207,6 +212,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
207
212
  * the tcp port
208
213
  */
209
214
  public port: number;
215
+ public host: string | undefined;
210
216
  public certificateManager: OPCUACertificateManager;
211
217
  public defaultSecureTokenLifetime: number;
212
218
  public maxConnections: number;
@@ -244,6 +250,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
244
250
  options.port = options.port || 0;
245
251
 
246
252
  this.port = parseInt(options.port.toString(), 10);
253
+ this.host = options.host;
247
254
  assert(typeof this.port === "number");
248
255
 
249
256
  this._certificateChain = options.certificateChain;
@@ -294,9 +301,8 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
294
301
  }
295
302
 
296
303
  public toString(): string {
304
+ const privateKeyThumpPrint = makePrivateKeyThumbPrint(this.getPrivateKey());
297
305
 
298
- const privateKeyThumpPrint = makePrivateKeyThumbPrint(this.getPrivateKey())
299
-
300
306
  const txt =
301
307
  " end point" +
302
308
  this._counter +
@@ -510,8 +516,13 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
510
516
  debugLog("server is listening");
511
517
  });
512
518
 
519
+ const listenOptions: net.ListenOptions = {
520
+ port: this.port,
521
+ host: this.host
522
+ };
523
+
513
524
  this._server!.listen(
514
- this.port,
525
+ listenOptions,
515
526
  /*"::",*/ (err?: Error) => {
516
527
  // 'listening' listener
517
528
  debugLog(chalk.green.bold("LISTENING TO PORT "), this.port, "err ", err);
@@ -1111,22 +1122,42 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions, paren
1111
1122
  // when channel session security is not "None",
1112
1123
  // userIdentityTokens can be left to null.
1113
1124
  // in this case this mean that secure policy will be the same as connection security policy
1114
- registerIdentity({
1115
- policyId: u("usernamePassword"),
1116
- tokenType: UserTokenType.UserName,
1117
- issuedTokenType: null,
1118
- issuerEndpointUrl: null,
1119
- securityPolicyUri: null
1120
- });
1125
+ // istanbul ignore next
1126
+ if (process.env.NODEOPCUA_SERVER_EMULATE_SIEMENS) {
1127
+ // However, for some reason SIEMENS plc requires that password get encrypted even though
1128
+ // the secure channel is also encrypted ....
1129
+ // you can set the NODEOPCUA_SERVER_EMULATE_SIEMENS env variable to simulate this behavior
1130
+ const registerIdentity3 = (tokenType: UserTokenType, securityPolicy: SecurityPolicy, name: string) => {
1131
+ const identity = {
1132
+ policyId: u(name),
1133
+ tokenType,
1134
+ issuedTokenType: null,
1135
+ issuerEndpointUrl: null,
1136
+ securityPolicyUri: securityPolicy
1137
+ };
1138
+ userIdentityTokens.push(identity);
1139
+ };
1140
+ registerIdentity3(UserTokenType.UserName, SecurityPolicy.Basic256, "username_basic256");
1141
+ registerIdentity3(UserTokenType.UserName, SecurityPolicy.Basic128Rsa15, "username_basic128Rsa15");
1142
+ registerIdentity3(UserTokenType.UserName, SecurityPolicy.Basic256Sha256, "username_basic256Sha256");
1143
+ } else {
1144
+ registerIdentity({
1145
+ policyId: u("usernamePassword"),
1146
+ tokenType: UserTokenType.UserName,
1147
+ issuedTokenType: null,
1148
+ issuerEndpointUrl: null,
1149
+ securityPolicyUri: null
1150
+ });
1121
1151
 
1122
- registerIdentity({
1123
- policyId: u("certificateX509"),
1124
- tokenType: UserTokenType.Certificate,
1152
+ registerIdentity({
1153
+ policyId: u("certificateX509"),
1154
+ tokenType: UserTokenType.Certificate,
1125
1155
 
1126
- issuedTokenType: null,
1127
- issuerEndpointUrl: null,
1128
- securityPolicyUri: null
1129
- });
1156
+ issuedTokenType: null,
1157
+ issuerEndpointUrl: null,
1158
+ securityPolicyUri: null
1159
+ });
1160
+ }
1130
1161
  }
1131
1162
 
1132
1163
  registerIdentity({
@@ -1155,7 +1186,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions, paren
1155
1186
  endpoint._parent = parent;
1156
1187
 
1157
1188
  // endpointUrl is dynamic as port number may be adjusted
1158
- // when the tcp socker start listening
1189
+ // when the tcp socket start listening
1159
1190
  (endpoint as any).__defineGetter__("endpointUrl", () => {
1160
1191
  const port = endpoint._parent.port;
1161
1192
  const resourcePath = options.resourcePath || "";
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { EventEmitter } from "events";
5
5
  import { types } from "util";
6
- import * as async from "async";
6
+ import async from "async";
7
7
  import chalk from "chalk";
8
8
  import { assert } from "node-opcua-assert";
9
9
  import { BinaryStream } from "node-opcua-binary-stream";
@@ -65,7 +65,8 @@ import {
65
65
  CallMethodResultOptions,
66
66
  ReadRequestOptions,
67
67
  BrowseDescriptionOptions,
68
- CallMethodRequest
68
+ CallMethodRequest,
69
+ ApplicationType
69
70
  } from "node-opcua-types";
70
71
  import { DataType, isValidVariant, Variant, VariantArrayType } from "node-opcua-variant";
71
72
 
@@ -287,7 +288,39 @@ function _get_next_subscriptionId() {
287
288
  }
288
289
 
289
290
  export type StringGetter = () => string;
291
+ export type StringArrayGetter = () => string[];
292
+ export type ApplicationTypeGetter = () => ApplicationType;
293
+ export type BooleanGetter = () => boolean;
290
294
 
295
+ export interface ServerConfigurationOptions {
296
+ applicationUri?: string | StringGetter;
297
+ applicationType?: ApplicationType | ApplicationTypeGetter; // default "Server"
298
+
299
+ hasSecureElement?: boolean | BooleanGetter; // default true
300
+
301
+ multicastDnsEnabled?: boolean | BooleanGetter; // default true
302
+
303
+ productUri?: string | StringGetter;
304
+
305
+ // /** @restricted only in professional version */
306
+ // resetToServerDefaults: () => Promise<void>;
307
+ // /** @restricted only in professional version */
308
+ // setAdminPassword?: (password: string) => Promise<void>;
309
+
310
+ /**
311
+ * The SupportedPrivateKeyFormats specifies the PrivateKey formats supported by the Server.
312
+ * Possible values include “PEM” (see RFC 5958) or “PFX” (see PKCS #12).
313
+ * @default ["PEM"]
314
+ */
315
+ supportedPrivateKeyFormat: string[] | StringArrayGetter;
316
+
317
+ /**
318
+ * The ServerCapabilities Property specifies the capabilities from Annex D
319
+ * ( see https://reference.opcfoundation.org/GDS/v104/docs/D) which the Server supports. The value is
320
+ * the same as the value reported to the LocalDiscoveryServer when the Server calls the RegisterServer2 Service.
321
+ */
322
+ serverCapabilities?: string[] | StringArrayGetter; // default|"N/A"]
323
+ }
291
324
  export interface ServerEngineOptions {
292
325
  applicationUri: string | StringGetter;
293
326
 
@@ -299,6 +332,7 @@ export interface ServerEngineOptions {
299
332
  serverDiagnosticsEnabled?: boolean;
300
333
  serverCapabilities?: ServerCapabilitiesOptions;
301
334
  historyServerCapabilities?: HistoryServerCapabilitiesOptions;
335
+ serverConfiguration?: ServerConfigurationOptions;
302
336
  }
303
337
 
304
338
  export interface CreateSessionOption {
@@ -322,6 +356,7 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
322
356
  public serverDiagnosticsEnabled: boolean;
323
357
  public serverCapabilities: ServerCapabilities;
324
358
  public historyServerCapabilities: HistoryServerCapabilities;
359
+ public serverConfiguration: ServerConfigurationOptions;
325
360
  public clientDescription?: ApplicationDescription;
326
361
 
327
362
  public addressSpace: AddressSpace | null;
@@ -367,6 +402,10 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
367
402
  // --------------------------------------------------- ServerCapabilities
368
403
  options.serverCapabilities = options.serverCapabilities || {};
369
404
 
405
+ options.serverConfiguration = options.serverConfiguration || {
406
+ supportedPrivateKeyFormat: ["PEM"]
407
+ };
408
+
370
409
  // https://profiles.opcfoundation.org/profile
371
410
  options.serverCapabilities.serverProfileArray = options.serverCapabilities.serverProfileArray || [
372
411
  "http://opcfoundation.org/UA-Profile/Server/Standard", // Standard UA Server Profile",
@@ -405,6 +444,8 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
405
444
  return MonitoredItem.minimumSamplingInterval;
406
445
  });
407
446
 
447
+ this.serverConfiguration = options.serverConfiguration;
448
+
408
449
  this.historyServerCapabilities = new HistoryServerCapabilities(options.historyServerCapabilities);
409
450
 
410
451
  // --------------------------------------------------- serverDiagnosticsSummary extension Object
@@ -1133,12 +1174,49 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
1133
1174
  });
1134
1175
  };
1135
1176
 
1177
+ type Getter<T> = () => T;
1178
+ function r<T>(a: undefined | T | Getter<T>, defaultValue: T): T {
1179
+ if (a === undefined) return defaultValue;
1180
+ if (typeof a === "function") {
1181
+ return (a as any)();
1182
+ }
1183
+ return a;
1184
+ }
1185
+ const bindServerConfigurationBasic = () => {
1186
+ bindStandardArray(VariableIds.ServerConfiguration_ServerCapabilities, DataType.String, DataType.String, () =>
1187
+ r(this.serverConfiguration.serverCapabilities, ["NA"])
1188
+ );
1189
+ bindStandardScalar(VariableIds.ServerConfiguration_ApplicationType, DataType.Int32, () =>
1190
+ r(this.serverConfiguration.applicationType, ApplicationType.Server)
1191
+ );
1192
+ bindStandardScalar(VariableIds.ServerConfiguration_ApplicationUri, DataType.String, () =>
1193
+ r(this.serverConfiguration.applicationUri, "")
1194
+ );
1195
+ bindStandardScalar(VariableIds.ServerConfiguration_ProductUri, DataType.String, () =>
1196
+ r(this.serverConfiguration.productUri, "")
1197
+ );
1198
+ bindStandardScalar(VariableIds.ServerConfiguration_HasSecureElement, DataType.Boolean, () =>
1199
+ r(this.serverConfiguration.hasSecureElement, false)
1200
+ );
1201
+ bindStandardScalar(VariableIds.ServerConfiguration_MulticastDnsEnabled, DataType.Boolean, () =>
1202
+ r(this.serverConfiguration.multicastDnsEnabled, false)
1203
+ );
1204
+ bindStandardArray(
1205
+ VariableIds.ServerConfiguration_SupportedPrivateKeyFormats,
1206
+ DataType.String,
1207
+ DataType.String,
1208
+ () => r(this.serverConfiguration.supportedPrivateKeyFormat, ["PEM"])
1209
+ );
1210
+ };
1211
+
1136
1212
  bindServerDiagnostics();
1137
1213
 
1138
1214
  bindServerStatus();
1139
1215
 
1140
1216
  bindServerCapabilities();
1141
1217
 
1218
+ bindServerConfigurationBasic();
1219
+
1142
1220
  bindHistoryServerCapabilities();
1143
1221
 
1144
1222
  const bindExtraStuff = () => {