node-opcua-server 2.165.2 → 2.167.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.
@@ -1,38 +1,36 @@
1
- /**
1
+ /**
2
2
  * @module node-opcua-server
3
3
  */
4
4
  // tslint:disable:no-console
5
- import { EventEmitter } from "events";
5
+ import { EventEmitter } from "node:events";
6
6
  import chalk from "chalk";
7
7
 
8
8
  import { assert } from "node-opcua-assert";
9
- import { UAString } from "node-opcua-basic-types";
10
- import {
11
- coerceLocalizedText,
12
- LocalizedTextOptions,
13
- OPCUAClientBase,
14
- OPCUAClientBaseOptions,
15
- ResponseCallback
16
- } from "node-opcua-client";
17
- import { make_debugLog, checkDebugFlag, make_warningLog } from "node-opcua-debug";
9
+ import type { UAString } from "node-opcua-basic-types";
10
+ import type { OPCUACertificateManager } from "node-opcua-certificate-manager";
11
+ import { coerceLocalizedText, type LocalizedTextOptions, OPCUAClientBase, type ResponseCallback } from "node-opcua-client";
12
+ import { exploreCertificate } from "node-opcua-crypto/web";
13
+ import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
18
14
  import { resolveFullyQualifiedDomainName } from "node-opcua-hostname";
19
15
  import { coerceSecurityPolicy, MessageSecurityMode, SecurityPolicy } from "node-opcua-secure-channel";
20
16
  import {
21
17
  RegisterServer2Request,
22
- RegisterServer2Response,
18
+ type RegisterServer2Response,
23
19
  RegisterServerRequest,
24
- RegisterServerResponse
20
+ type RegisterServerResponse
25
21
  } from "node-opcua-service-discovery";
26
- import { ApplicationType, EndpointDescription, MdnsDiscoveryConfiguration, RegisteredServerOptions } from "node-opcua-types";
27
- import { exploreCertificate } from "node-opcua-crypto/web";
28
- import { OPCUACertificateManager } from "node-opcua-certificate-manager";
29
- import { IRegisterServerManager, RegisterServerManagerStatus } from "./i_register_server_manager";
30
-
31
- const doDebug = checkDebugFlag("REGISTER_LDS");
22
+ import {
23
+ type ApplicationType,
24
+ type EndpointDescription,
25
+ MdnsDiscoveryConfiguration,
26
+ type RegisteredServerOptions
27
+ } from "node-opcua-types";
28
+ import { type IRegisterServerManager, RegisterServerManagerStatus } from "./i_register_server_manager";
29
+
30
+ const _doDebug = checkDebugFlag("REGISTER_LDS");
32
31
  const debugLog = make_debugLog("REGISTER_LDS");
33
32
  const warningLog = make_warningLog("REGISTER_LDS");
34
33
 
35
-
36
34
  const g_DefaultRegistrationServerTimeout = 8 * 60 * 1000; // 8 minutes
37
35
 
38
36
  function securityPolicyLevel(securityPolicy: UAString): number {
@@ -110,7 +108,7 @@ function constructRegisteredServer(server: IPartialServer, isOnline: boolean): R
110
108
  assert(!isOnline || discoveryUrls.length >= 1, "expecting some discoveryUrls if we go online .... ");
111
109
 
112
110
  const info = exploreCertificate(server.getCertificate());
113
- const commonName = info.tbsCertificate.subject.commonName!;
111
+ const _commonName = info.tbsCertificate.subject.commonName ?? "";
114
112
 
115
113
  const serverUri = info.tbsCertificate.extensions?.subjectAltName?.uniformResourceIdentifier[0];
116
114
  // c8 ignore next
@@ -122,7 +120,7 @@ function constructRegisteredServer(server: IPartialServer, isOnline: boolean): R
122
120
  "\n subjectAltName : ",
123
121
  info.tbsCertificate.extensions?.subjectAltName,
124
122
  "\n commonName : ",
125
- info.tbsCertificate.subject.commonName!,
123
+ info.tbsCertificate.subject.commonName,
126
124
  "\n serverInfo.applicationUri : ",
127
125
  server.serverInfo.applicationUri
128
126
  );
@@ -203,7 +201,7 @@ async function sendRegisterServerRequest(server: IPartialServer, client: ClientB
203
201
  const request = constructRegisterServer2Request(server, isOnline);
204
202
 
205
203
  await new Promise<void>((resolve, reject) => {
206
- client.performMessageTransaction(request, (err: Error | null, response?: RegisterServer2Response) => {
204
+ client.performMessageTransaction(request, (err: Error | null, _response?: RegisterServer2Response) => {
207
205
  if (!err) {
208
206
  // RegisterServerResponse
209
207
  debugLog("RegisterServerManager#_registerServer sendRegisterServer2Request has succeeded (isOnline", isOnline, ")");
@@ -213,7 +211,7 @@ async function sendRegisterServerRequest(server: IPartialServer, client: ClientB
213
211
  debugLog("RegisterServerManager#_registerServer" + " falling back to using sendRegisterServerRequest instead");
214
212
  // fall back to
215
213
  const request1 = constructRegisterServerRequest(server, isOnline);
216
- client.performMessageTransaction(request1, (err1: Error | null, response1?: RegisterServerResponse) => {
214
+ client.performMessageTransaction(request1, (err1: Error | null, _response1?: RegisterServerResponse) => {
217
215
  if (!err1) {
218
216
  debugLog(
219
217
  "RegisterServerManager#_registerServer sendRegisterServerRequest " + "has succeeded (isOnline",
@@ -227,10 +225,9 @@ async function sendRegisterServerRequest(server: IPartialServer, client: ClientB
227
225
  isOnline,
228
226
  ")"
229
227
  );
230
- reject(err1!)
228
+ reject(err1);
231
229
  });
232
230
  });
233
-
234
231
  });
235
232
  }
236
233
 
@@ -256,7 +253,7 @@ export interface RegisterServerManagerOptions {
256
253
  let g_registeringClientCounter = 0;
257
254
  /**
258
255
  * RegisterServerManager is responsible to Register an opcua server on a LDS or LDS-ME server
259
- * This class takes in charge :
256
+ * This class takes in charge :
260
257
  * - the initial registration of a server
261
258
  * - the regular registration renewal (every 8 minutes or so ...)
262
259
  * - dealing with cases where LDS is not up and running when server starts.
@@ -349,7 +346,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
349
346
  public async start(): Promise<void> {
350
347
  debugLog("RegisterServerManager#start");
351
348
  if (this.state !== RegisterServerManagerStatus.INACTIVE) {
352
- throw new Error("RegisterServer process already started: " + RegisterServerManagerStatus[this.state]);
349
+ throw new Error(`RegisterServer process already started: ${RegisterServerManagerStatus[this.state]}`);
353
350
  }
354
351
  this.discoveryServerEndpointUrl = resolveFullyQualifiedDomainName(this.discoveryServerEndpointUrl);
355
352
 
@@ -359,7 +356,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
359
356
  // This method is called without await to ensure it is non-blocking.
360
357
  // The catch block handles any synchronous errors.
361
358
  this.#_runRegistrationProcess().catch((err) => {
362
- warningLog("Synchronous error in #_runRegistrationProcess: ", (err?.message));
359
+ warningLog("Synchronous error in #_runRegistrationProcess: ", err?.message);
363
360
  });
364
361
  }
365
362
 
@@ -370,7 +367,12 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
370
367
  */
371
368
  async #_runRegistrationProcess(): Promise<void> {
372
369
  while (this.getState() !== RegisterServerManagerStatus.WAITING && !this.#_isTerminating()) {
373
- debugLog("RegisterServerManager#_runRegistrationProcess - state =", RegisterServerManagerStatus[this.state], "isTerminating =", this.#_isTerminating());
370
+ debugLog(
371
+ "RegisterServerManager#_runRegistrationProcess - state =",
372
+ RegisterServerManagerStatus[this.state],
373
+ "isTerminating =",
374
+ this.#_isTerminating()
375
+ );
374
376
  try {
375
377
  if (this.getState() === RegisterServerManagerStatus.INACTIVE) {
376
378
  this.#_setState(RegisterServerManagerStatus.INITIALIZING);
@@ -399,7 +401,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
399
401
  this.#_trigger_next();
400
402
  return;
401
403
  } catch (err) {
402
- debugLog("RegisterServerManager#_runRegistrationProcess - operation failed!", ((err as Error).message));
404
+ debugLog("RegisterServerManager#_runRegistrationProcess - operation failed!", (err as Error).message);
403
405
  if (!this.#_isTerminating()) {
404
406
  this.#_setState(RegisterServerManagerStatus.INACTIVE);
405
407
  this.#_emitEvent("serverRegistrationFailure");
@@ -413,7 +415,10 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
413
415
  }
414
416
  }
415
417
  #_isTerminating(): boolean {
416
- return this.getState() === RegisterServerManagerStatus.UNREGISTERING || this.getState() === RegisterServerManagerStatus.DISPOSING
418
+ return (
419
+ this.getState() === RegisterServerManagerStatus.UNREGISTERING ||
420
+ this.getState() === RegisterServerManagerStatus.DISPOSING
421
+ );
417
422
  }
418
423
 
419
424
  /**
@@ -435,30 +440,28 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
435
440
  assert(typeof this.discoveryServerEndpointUrl === "string");
436
441
  assert(this.state === RegisterServerManagerStatus.INITIALIZING);
437
442
 
438
-
439
443
  this.selectedEndpoint = undefined;
440
444
 
441
- const applicationName = coerceLocalizedText(this.server.serverInfo.applicationName!)?.text || undefined;
445
+ const applicationName = coerceLocalizedText(this.server.serverInfo.applicationName)?.text || undefined;
442
446
  this.server.serverCertificateManager.referenceCounter++;
443
447
 
444
448
  const server = this.server;
445
449
  const prefix = `Client-${g_registeringClientCounter++}`;
446
450
  const action = "initializing";
447
451
  const ldsInfo = this.discoveryServerEndpointUrl;
448
- const serverInfo = this.server?.serverInfo.applicationUri!;
449
- const clientName = `${prefix} for server ${serverInfo} to LDS ${ldsInfo} for ${action}`;
452
+ const serverAppUri = this.server?.serverInfo.applicationUri ?? "";
453
+ const clientName = `${prefix} for server ${serverAppUri} to LDS ${ldsInfo} for ${action}`;
450
454
 
451
455
  const registrationClient = OPCUAClientBase.create({
452
456
  clientName,
453
457
  applicationName,
454
- applicationUri: server.serverInfo.applicationUri!,
458
+ applicationUri: server.serverInfo.applicationUri ?? "",
455
459
  connectionStrategy: infinite_connectivity_strategy,
456
460
  clientCertificateManager: server.serverCertificateManager,
457
461
  certificateFile: server.certificateFile,
458
462
  privateKeyFile: server.privateKeyFile
459
463
  }) as ClientBaseEx;
460
464
 
461
-
462
465
  registrationClient.on("backoff", (nbRetry: number, delay: number) => {
463
466
  if (this.state !== RegisterServerManagerStatus.INITIALIZING) return; // Ignore event if state has changed
464
467
  debugLog("RegisterServerManager - received backoff");
@@ -489,24 +492,18 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
489
492
  return;
490
493
  }
491
494
 
492
-
493
- const endpoints: EndpointDescription[] | undefined = await registrationClient.getEndpoints();
494
- const endpoint = findSecureEndpoint(endpoints!);
495
+ const endpoints = await registrationClient.getEndpoints();
496
+ if (!endpoints || endpoints.length === 0) {
497
+ throw new Error("Cannot retrieve endpoints from discovery server");
498
+ }
499
+ const endpoint = findSecureEndpoint(endpoints);
495
500
  if (!endpoint) {
496
501
  throw new Error("Cannot find Secure endpoint");
497
502
  }
498
503
 
499
- if (endpoint.serverCertificate) {
500
- assert(endpoint.serverCertificate);
501
- this.selectedEndpoint = endpoint;
502
- } else {
503
- this.selectedEndpoint = undefined;
504
- }
504
+ this.selectedEndpoint = endpoint.serverCertificate ? endpoint : undefined;
505
505
 
506
506
  this._serverEndpoints = registrationClient._serverEndpoints;
507
- } catch (err) {
508
- // Do not set state to INACTIVE or rethrow here, let the caller handle it.
509
- throw err;
510
507
  } finally {
511
508
  if (this._registration_client) {
512
509
  const tmp = this._registration_client;
@@ -557,7 +554,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
557
554
  this.#_setState(RegisterServerManagerStatus.REGISTERING);
558
555
  this.#_emitEvent("serverRegistrationPending");
559
556
 
560
- this.#_registerOrUnregisterServer(/*isOnline=*/true)
557
+ this.#_registerOrUnregisterServer(/*isOnline=*/ true)
561
558
  .then(() => after_register())
562
559
  .catch((err) => after_register(err));
563
560
  }, this.timeout);
@@ -577,7 +574,6 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
577
574
  this._registrationTimerId = null;
578
575
  }
579
576
 
580
-
581
577
  // Immediately set state to signal a stop
582
578
  this.#_setState(RegisterServerManagerStatus.UNREGISTERING);
583
579
 
@@ -586,7 +582,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
586
582
 
587
583
  if (this.selectedEndpoint) {
588
584
  try {
589
- await this.#_registerOrUnregisterServer(/* isOnline= */false);
585
+ await this.#_registerOrUnregisterServer(/* isOnline= */ false);
590
586
  this.#_setState(RegisterServerManagerStatus.UNREGISTERED);
591
587
  this.#_emitEvent("serverUnregistered");
592
588
  } catch (err) {
@@ -615,9 +611,12 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
615
611
  debugLog("RegisterServerManager#_registerServer isOnline:", isOnline);
616
612
 
617
613
  assert(this.selectedEndpoint, "must have a selected endpoint");
618
- assert(this.server!.serverType !== undefined, " must have a valid server Type");
614
+ assert(this.server?.serverType !== undefined, " must have a valid server Type");
619
615
 
620
- const server = this.server!;
616
+ if (!this.server) {
617
+ throw new Error("RegisterServerManager: server is not set");
618
+ }
619
+ const server = this.server;
621
620
  const selectedEndpoint = this.selectedEndpoint;
622
621
  if (!selectedEndpoint) {
623
622
  warningLog("Warning: cannot register server - no endpoint available");
@@ -626,18 +625,18 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
626
625
  }
627
626
 
628
627
  server.serverCertificateManager.referenceCounter++;
629
- const applicationName: string | undefined = coerceLocalizedText(server.serverInfo.applicationName!)?.text || undefined;
628
+ const applicationName: string | undefined = coerceLocalizedText(server.serverInfo.applicationName)?.text || undefined;
630
629
 
631
630
  const prefix = `Client-${g_registeringClientCounter++}`;
632
631
  const action = isOnline ? "registering" : "unregistering";
633
632
  const ldsInfo = this.discoveryServerEndpointUrl;
634
- const serverInfo = server.serverInfo.applicationUri!;
635
- const clientName = `${prefix} for server ${serverInfo} to LDS ${ldsInfo} for ${action}`;
633
+ const serverAppUri = server.serverInfo.applicationUri ?? "";
634
+ const clientName = `${prefix} for server ${serverAppUri} to LDS ${ldsInfo} for ${action}`;
636
635
 
637
636
  const client = OPCUAClientBase.create({
638
637
  clientName,
639
638
  applicationName,
640
- applicationUri: server.serverInfo.applicationUri!,
639
+ applicationUri: server.serverInfo.applicationUri ?? "",
641
640
  connectionStrategy: no_retry_connectivity_strategy,
642
641
  clientCertificateManager: server.serverCertificateManager,
643
642
 
@@ -645,8 +644,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
645
644
  securityPolicy: coerceSecurityPolicy(selectedEndpoint.securityPolicyUri),
646
645
  serverCertificate: selectedEndpoint.serverCertificate,
647
646
  certificateFile: server.certificateFile,
648
- privateKeyFile: server.privateKeyFile,
649
-
647
+ privateKeyFile: server.privateKeyFile
650
648
  }) as ClientBaseEx;
651
649
  client.on("backoff", (nbRetry, delay) => {
652
650
  debugLog(client.clientCertificateManager, "backoff trying to connect to the LDS has failed", nbRetry, delay);
@@ -654,30 +652,36 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
654
652
 
655
653
  this._registration_client = client;
656
654
 
657
- debugLog("lds endpoint uri : ", selectedEndpoint.endpointUrl);
655
+ const endpointUrl = selectedEndpoint.endpointUrl;
656
+ if (!endpointUrl) {
657
+ throw new Error("selectedEndpoint.endpointUrl is missing — cannot connect to LDS");
658
+ }
659
+ debugLog("lds endpoint uri : ", endpointUrl);
658
660
 
659
- const state = isOnline ? "UnRegisterServer" : "RegisterServer";
661
+ const state = isOnline ? "RegisterServer" : "UnRegisterServer";
660
662
  try {
661
- await client.connect(selectedEndpoint!.endpointUrl!);
663
+ await client.connect(endpointUrl);
662
664
 
663
665
  // Check state again after connection is established
664
666
  if (this.getState() === expectedState) {
665
667
  try {
666
- await sendRegisterServerRequest(server, client as ClientBaseEx, isOnline)
668
+ await sendRegisterServerRequest(server, client as ClientBaseEx, isOnline);
667
669
  } catch (err) {
668
670
  if (this.getState() !== expectedState) {
669
- warningLog(`${state} '${this.server!.serverInfo.applicationUri}' to the LDS has failed during secure connection to the LDS server`);
670
- warningLog(chalk.red(" Error message:"), (err as Error).message); // Do not rethrow here, let the caller
671
+ warningLog(
672
+ `${state} '${this.server?.serverInfo.applicationUri}' to the LDS has failed during secure connection to the LDS server`
673
+ );
674
+ warningLog(chalk.red(" Error message:"), (err as Error).message); // Do not rethrow here, let the caller
671
675
  }
672
676
  }
673
677
  } else {
674
678
  debugLog("RegisterServerManager#_registerServer: aborted ");
675
679
  }
676
-
677
680
  } catch (err) {
678
681
  if (this.getState() !== expectedState) {
679
-
680
- warningLog(`${state} '${this.server!.serverInfo.applicationUri}' cannot connect to LDS at endpoint ${client.clientName}, ${selectedEndpoint.endpointUrl} :`);
682
+ warningLog(
683
+ `${state} '${this.server?.serverInfo.applicationUri}' cannot connect to LDS at endpoint ${client.clientName}, ${selectedEndpoint.endpointUrl} :`
684
+ );
681
685
  warningLog(chalk.red(" Error message:"), (err as Error).message);
682
686
  }
683
687
  } finally {
@@ -700,8 +704,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
700
704
  if (this._registration_client) {
701
705
  const client = this._registration_client;
702
706
  this._registration_client = null;
703
- debugLog("RegisterServerManager#_cancel_pending_client_if_any "
704
- + "=> wee need to disconnect_registration_client");
707
+ debugLog("RegisterServerManager#_cancel_pending_client_if_any " + "=> wee need to disconnect_registration_client");
705
708
  try {
706
709
  await client.disconnect();
707
710
  } catch (err) {
@@ -10,7 +10,7 @@ import chalk from "chalk";
10
10
 
11
11
  import { assert } from "node-opcua-assert";
12
12
  import type { OPCUACertificateManager } from "node-opcua-certificate-manager";
13
- import { type Certificate, makeSHA1Thumbprint, type PrivateKey, split_der } from "node-opcua-crypto/web";
13
+ import { type Certificate, combine_der, makeSHA1Thumbprint, type PrivateKey, split_der } from "node-opcua-crypto/web";
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 {
@@ -69,9 +69,8 @@ function extractChannelData(channel: ServerSecureChannelLayer): IChannelData {
69
69
 
70
70
  function dumpChannelInfo(channels: ServerSecureChannelLayer[]): void {
71
71
  function d(s: IServerSessionBase) {
72
- return `[ status=${s.status} lastSeen=${s.clientLastContactTime.toFixed(0)}ms sessionName=${s.sessionName} timeout=${
73
- s.sessionTimeout
74
- } ]`;
72
+ return `[ status=${s.status} lastSeen=${s.clientLastContactTime.toFixed(0)}ms sessionName=${s.sessionName} timeout=${s.sessionTimeout
73
+ } ]`;
75
74
  }
76
75
  function dumpChannel(channel: ServerSecureChannelLayer): void {
77
76
  console.log("------------------------------------------------------");
@@ -98,7 +97,8 @@ function dumpChannelInfo(channels: ServerSecureChannelLayer[]): void {
98
97
  console.log("------------------------------------------------------");
99
98
  }
100
99
 
101
- const emptyCertificate = Buffer.alloc(0);
100
+ const emptyCertificateChain: Certificate[] = [];
101
+
102
102
  // biome-ignore lint/suspicious/noExplicitAny: deliberate null→PrivateKey sentinel
103
103
  const emptyPrivateKey = null as any as PrivateKey;
104
104
 
@@ -116,7 +116,7 @@ export interface OPCUAServerEndPointOptions {
116
116
  /**
117
117
  * the DER certificate chain
118
118
  */
119
- certificateChain: Certificate;
119
+ certificateChain: Certificate[];
120
120
 
121
121
  /**
122
122
  * privateKey
@@ -333,7 +333,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
333
333
  public _on_connectionRefused?: (socketData: ISocketData) => void;
334
334
  public _on_openSecureChannelFailure?: (socketData: ISocketData, channelData: IChannelData) => void;
335
335
 
336
- private _certificateChain: Certificate;
336
+ private _certificateChain: Certificate[];
337
337
  private _privateKey: PrivateKey;
338
338
  private _channels: { [key: string]: ServerSecureChannelLayer };
339
339
  private _server?: Server;
@@ -390,7 +390,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
390
390
  }
391
391
 
392
392
  public dispose(): void {
393
- this._certificateChain = emptyCertificate;
393
+ this._certificateChain = emptyCertificateChain;
394
394
  this._privateKey = emptyPrivateKey;
395
395
 
396
396
  assert(Object.keys(this._channels).length === 0, "OPCUAServerEndPoint channels must have been deleted");
@@ -417,7 +417,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
417
417
  " l = " +
418
418
  this._endpoints.length +
419
419
  " " +
420
- makeSHA1Thumbprint(this.getCertificateChain()).toString("hex");
420
+ makeSHA1Thumbprint(this.getCertificate()).toString("hex");
421
421
  return txt;
422
422
  }
423
423
 
@@ -429,13 +429,13 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
429
429
  * Returns the X509 DER form of the server certificate
430
430
  */
431
431
  public getCertificate(): Certificate {
432
- return split_der(this.getCertificateChain())[0];
432
+ return this.getCertificateChain()[0];
433
433
  }
434
434
 
435
435
  /**
436
436
  * Returns the X509 DER form of the server certificate
437
437
  */
438
- public getCertificateChain(): Certificate {
438
+ public getCertificateChain(): Certificate[] {
439
439
  return this._certificateChain;
440
440
  }
441
441
 
@@ -687,7 +687,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
687
687
 
688
688
  this._server.listen(
689
689
  listenOptions,
690
- /*"::",*/ (err?: Error) => {
690
+ /*"::",*/(err?: Error) => {
691
691
  // 'listening' listener
692
692
  debugLog(chalk.green.bold("LISTENING TO PORT "), this.port, "err ", err);
693
693
  assert(!err, " cannot listen to port ");
@@ -877,7 +877,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
877
877
  debugLog(
878
878
  chalk.bgWhite.cyan(
879
879
  "OPCUAServerEndPoint#_on_client_connection " +
880
- "SERVER END POINT IS PROBABLY SHUTTING DOWN !!! - Connection is refused"
880
+ "SERVER END POINT IS PROBABLY SHUTTING DOWN !!! - Connection is refused"
881
881
  )
882
882
  );
883
883
  socket.end();
@@ -887,7 +887,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
887
887
  console.log(
888
888
  chalk.bgWhite.cyan(
889
889
  "OPCUAServerEndPoint#_on_client_connection " +
890
- "The maximum number of connection has been reached - Connection is refused"
890
+ "The maximum number of connection has been reached - Connection is refused"
891
891
  )
892
892
  );
893
893
  const reason = `maxConnections reached (${this.maxConnections})`;
@@ -1130,7 +1130,7 @@ interface MakeEndpointDescriptionOptions {
1130
1130
  */
1131
1131
  hostname: string;
1132
1132
 
1133
- serverCertificateChain: Certificate;
1133
+ serverCertificateChain: Certificate[];
1134
1134
  /**
1135
1135
  *
1136
1136
  */
@@ -1224,13 +1224,6 @@ function estimateSecurityLevel(securityMode: MessageSecurityMode, securityPolicy
1224
1224
  * @private
1225
1225
  */
1226
1226
  function _makeEndpointDescription(options: MakeEndpointDescriptionOptions, parent: OPCUAServerEndPoint): EndpointDescriptionEx {
1227
- assert(Object.prototype.hasOwnProperty.call(options, "serverCertificateChain"));
1228
- assert(!Object.prototype.hasOwnProperty.call(options, "serverCertificate"));
1229
- assert(!!options.securityMode); // s.MessageSecurityMode
1230
- assert(!!options.securityPolicy);
1231
- assert(options.server !== null && typeof options.server === "object");
1232
- assert(!!options.hostname && typeof options.hostname === "string");
1233
- assert(typeof options.restricted === "boolean");
1234
1227
 
1235
1228
  const u = (n: string) => getUniqueName(n, options.collection);
1236
1229
  options.securityLevel =
@@ -1353,7 +1346,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions, paren
1353
1346
  endpointUrl: "<to be evaluated at run time>", // options.endpointUrl,
1354
1347
 
1355
1348
  server: undefined, // options.server,
1356
- serverCertificate: options.serverCertificateChain,
1349
+ serverCertificate: options.serverCertificateChain.length > 0 ? combine_der(options.serverCertificateChain) : undefined,
1357
1350
 
1358
1351
  securityMode: options.securityMode,
1359
1352
  securityPolicyUri,