node-opcua-server 2.164.2 → 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.
@@ -2,76 +2,74 @@
2
2
  /**
3
3
  * @module node-opcua-server
4
4
  */
5
- import { randomBytes } from "crypto";
6
- import { EventEmitter } from "events";
7
- import { callbackify, types } from "util";
5
+ import { randomBytes } from "node:crypto";
6
+ import { callbackify, types } from "node:util";
8
7
 
9
- import async from "async";
10
8
  import chalk from "chalk";
11
-
12
- import { extractFullyQualifiedDomainName, getFullyQualifiedDomainName } from "node-opcua-hostname";
13
-
14
- import { assert } from "node-opcua-assert";
15
- import { isNullOrUndefined } from "node-opcua-utils";
16
-
17
9
  import {
18
- AddressSpace,
19
- PseudoVariantBoolean,
20
- PseudoVariantByteString,
21
- PseudoVariantDateTime,
22
- PseudoVariantDuration,
23
- PseudoVariantExtensionObject,
24
- PseudoVariantExtensionObjectArray,
25
- PseudoVariantLocalizedText,
26
- PseudoVariantNodeId,
27
- PseudoVariantString,
28
- RaiseEventData,
29
- SessionContext,
30
- UAObject,
31
- UAVariable,
32
- ISessionContext,
33
- UAView,
34
- EventTypeLike,
35
- UAObjectType,
36
- PseudoVariantStringPredefined,
10
+ type AddressSpace,
11
+ type EventTypeLike,
12
+ type IRolePolicyOverride,
13
+ type IServerBase,
14
+ type ISessionContext,
37
15
  innerBrowse,
38
16
  innerBrowseNext,
39
- UAEventType
17
+ type PseudoVariant,
18
+ type PseudoVariantBoolean,
19
+ type PseudoVariantByteString,
20
+ type PseudoVariantDateTime,
21
+ type PseudoVariantDuration,
22
+ type PseudoVariantExtensionObject,
23
+ type PseudoVariantExtensionObjectArray,
24
+ type PseudoVariantLocalizedText,
25
+ type PseudoVariantNodeId,
26
+ type PseudoVariantString,
27
+ type PseudoVariantStringPredefined,
28
+ type RaiseEventData,
29
+ SessionContext,
30
+ type UAEventType,
31
+ type UAObject,
32
+ type UAObjectType,
33
+ type UAVariable,
34
+ type UAView
40
35
  } from "node-opcua-address-space";
41
- import { getDefaultCertificateManager, OPCUACertificateManager } from "node-opcua-certificate-manager";
36
+ import { assert } from "node-opcua-assert";
37
+ import type { ByteString, UAString } from "node-opcua-basic-types";
38
+ import { getDefaultCertificateManager, type OPCUACertificateManager } from "node-opcua-certificate-manager";
42
39
  import { ServerState } from "node-opcua-common";
43
- import { Certificate, exploreCertificate, Nonce } from "node-opcua-crypto/web";
40
+ import { type Certificate, exploreCertificate, type Nonce } from "node-opcua-crypto/web";
44
41
  import {
45
42
  AttributeIds,
46
43
  filterDiagnosticOperationLevel,
47
44
  filterDiagnosticServiceLevel,
45
+ LocalizedText,
48
46
  NodeClass,
49
47
  RESPONSE_DIAGNOSTICS_MASK_ALL
50
48
  } from "node-opcua-data-model";
51
49
  import { DataValue } from "node-opcua-data-value";
52
50
  import { dump, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
53
- import { NodeId } from "node-opcua-nodeid";
51
+ import { extractFullyQualifiedDomainName, getFullyQualifiedDomainName, isIPAddress } from "node-opcua-hostname";
52
+ import type { NodeId } from "node-opcua-nodeid";
54
53
  import { ObjectRegistry } from "node-opcua-object-registry";
55
54
  import {
56
- AsymmetricAlgorithmSecurityHeader,
57
55
  coerceSecurityPolicy,
58
56
  computeSignature,
59
57
  fromURI,
60
58
  getCryptoFactory,
61
- Message,
59
+ type Message,
62
60
  MessageSecurityMode,
63
61
  nonceAlreadyBeenUsed,
64
- Request,
65
- Response,
62
+ type Request,
63
+ type Response,
66
64
  SecurityPolicy,
67
- ServerSecureChannelLayer,
68
- SignatureData,
65
+ type ServerSecureChannelLayer,
66
+ type SignatureData,
69
67
  verifySignature
70
68
  } from "node-opcua-secure-channel";
71
69
  import { BrowseNextRequest, BrowseNextResponse, BrowseRequest, BrowseResponse } from "node-opcua-service-browse";
72
70
  import { CallRequest, CallResponse } from "node-opcua-service-call";
73
71
  import { ApplicationType, UserTokenType } from "node-opcua-service-endpoints";
74
- import { HistoryReadRequest, HistoryReadResponse, HistoryReadResult, HistoryUpdateResponse } from "node-opcua-service-history";
72
+ import { HistoryReadRequest, HistoryReadResponse, type HistoryReadResult, HistoryUpdateResponse } from "node-opcua-service-history";
75
73
  import {
76
74
  AddNodesResponse,
77
75
  AddReferencesResponse,
@@ -129,57 +127,48 @@ import {
129
127
  TranslateBrowsePathsToNodeIdsResponse
130
128
  } from "node-opcua-service-translate-browse-path";
131
129
  import { WriteRequest, WriteResponse } from "node-opcua-service-write";
132
- import { CallbackT, ErrorCallback, StatusCode, StatusCodes } from "node-opcua-status-code";
130
+ import { type CallbackT, StatusCode, StatusCodes } from "node-opcua-status-code";
133
131
  import {
134
- ApplicationDescriptionOptions,
135
- BrowseResult,
136
- BuildInfo,
137
- CallMethodResultOptions,
132
+ type ApplicationDescriptionOptions,
133
+ type BrowseDescriptionOptions,
134
+ type BrowseResult,
135
+ type BuildInfo,
136
+ type BuildInfoOptions,
138
137
  CancelResponse,
139
138
  EndpointDescription,
140
- MonitoredItemModifyRequest,
141
- MonitoringMode,
142
- UserIdentityToken,
143
- UserTokenPolicy,
144
- BuildInfoOptions,
145
- MonitoredItemCreateResult,
146
139
  IssuedIdentityToken,
147
- BrowseResultOptions,
140
+ type MonitoredItemCreateResult,
141
+ type MonitoredItemModifyRequest,
142
+ MonitoringMode,
148
143
  ServiceFault,
149
- ServerDiagnosticsSummaryDataType,
150
- BrowseDescriptionOptions
144
+ type UserIdentityToken,
145
+ type UserTokenPolicy
151
146
  } from "node-opcua-types";
152
- import { DataType } from "node-opcua-variant";
153
- import { VariantArrayType } from "node-opcua-variant";
154
- import { matchUri } from "node-opcua-utils";
147
+ import { isNullOrUndefined, matchUri } from "node-opcua-utils";
148
+ import { DataType, type Variant, VariantArrayType } from "node-opcua-variant";
149
+ import { withCallback } from "thenify-ex";
155
150
 
156
- import { UAString } from "node-opcua-basic-types";
157
- import { ObjectIds, ObjectTypeIds } from "node-opcua-constants";
158
- import { OPCUABaseServer, OPCUABaseServerOptions } from "./base_server";
151
+ import { OPCUABaseServer, type OPCUABaseServerOptions } from "./base_server";
159
152
  import { Factory } from "./factory";
160
- import { IRegisterServerManager } from "./i_register_server_manager";
153
+ import type { IChannelData } from "./i_channel_data";
154
+ import type { IRegisterServerManager } from "./i_register_server_manager";
155
+ import type { ISocketData } from "./i_socket_data";
161
156
  import { MonitoredItem } from "./monitored_item";
162
157
  import { RegisterServerManager } from "./register_server_manager";
163
158
  import { RegisterServerManagerHidden } from "./register_server_manager_hidden";
164
159
  import { RegisterServerManagerMDNSONLY } from "./register_server_manager_mdns_only";
165
- import { ServerCapabilitiesOptions } from "./server_capabilities";
166
- import { EndpointDescriptionEx, IServerTransportSettings, OPCUAServerEndPoint } from "./server_end_point";
167
- import { ClosingReason, CreateSessionOption, ServerEngine } from "./server_engine";
168
- import { ServerSession } from "./server_session";
169
- import { CreateMonitoredItemHook, DeleteMonitoredItemHook, Subscription } from "./server_subscription";
170
- import { ISocketData } from "./i_socket_data";
171
- import { IChannelData } from "./i_channel_data";
172
- import { UAUserManagerBase, makeUserManager, UserManagerOptions } from "./user_manager";
160
+ import type { SamplingFunc } from "./sampling_func";
161
+ import type { ServerCapabilitiesOptions } from "./server_capabilities";
162
+ import { type AdvertisedEndpoint, type EndpointDescriptionEx, type IServerTransportSettings, OPCUAServerEndPoint, normalizeAdvertisedEndpoints, parseOpcTcpUrl } from "./server_end_point";
163
+ import { type ClosingReason, type CreateSessionOption, ServerEngine } from "./server_engine";
164
+ import type { ServerSession } from "./server_session";
165
+ import type { CreateMonitoredItemHook, DeleteMonitoredItemHook, Subscription } from "./server_subscription";
166
+ import { makeUserManager, type UAUserManagerBase, type UserManagerOptions } from "./user_manager";
173
167
  import { bindRoleSet } from "./user_manager_ua";
174
- import { SamplingFunc } from "./sampling_func";
175
168
 
176
169
  function isSubscriptionIdInvalid(subscriptionId: number): boolean {
177
170
  return subscriptionId < 0 || subscriptionId >= 0xffffffff;
178
171
  }
179
-
180
- // tslint:disable-next-line:no-var-requires
181
- import { withCallback } from "thenify-ex";
182
- // tslint:disable-next-line:no-var-requires
183
172
  const package_info = require("../package.json");
184
173
  const debugLog = make_debugLog(__filename);
185
174
  const errorLog = make_errorLog(__filename);
@@ -187,11 +176,16 @@ const warningLog = make_warningLog(__filename);
187
176
 
188
177
  const default_maxConnectionsPerEndpoint = 10;
189
178
 
190
- function g_sendError(channel: ServerSecureChannelLayer, message: Message, ResponseClass: any, statusCode: StatusCode): void {
179
+ function g_sendError(
180
+ channel: ServerSecureChannelLayer,
181
+ message: Message,
182
+ _ResponseClass: ResponseClassType,
183
+ statusCode: StatusCode
184
+ ): void {
191
185
  const response = new ServiceFault({
192
186
  responseHeader: { serviceResult: statusCode }
193
187
  });
194
- return channel.send_response("MSG", response, message);
188
+ channel.send_response("MSG", response, message);
195
189
  }
196
190
 
197
191
  const default_build_info: BuildInfoOptions = {
@@ -238,7 +232,7 @@ function _adjust_session_timeout(sessionTimeout: number) {
238
232
 
239
233
  function channel_has_session(channel: ServerSecureChannelLayer, session: ServerSession): boolean {
240
234
  if (session.channel === channel) {
241
- assert(Object.prototype.hasOwnProperty.call(channel.sessionTokens, session.authenticationToken.toString()));
235
+ assert(Object.hasOwn(channel.sessionTokens, session.authenticationToken.toString()));
242
236
  return true;
243
237
  }
244
238
  return false;
@@ -253,13 +247,13 @@ function moveSessionToChannel(session: ServerSession, channel: ServerSecureChann
253
247
  session._detach_channel();
254
248
  session._attach_channel(channel);
255
249
 
256
- assert(session.channel!.channelId === channel.channelId);
250
+ assert(session.channel?.channelId === channel.channelId);
257
251
  }
258
252
 
259
253
  async function _attempt_to_close_some_old_unactivated_session(server: OPCUAServer) {
260
- const session = server.engine!.getOldestInactiveSession();
254
+ const session = server.engine?.getOldestInactiveSession();
261
255
  if (session) {
262
- await server.engine!.closeSession(session.authenticationToken, false, "Forcing");
256
+ await server.engine?.closeSession(session.authenticationToken, false, "Forcing");
263
257
  }
264
258
  }
265
259
 
@@ -282,12 +276,12 @@ function getRequiredEndpointInfo(endpoint: EndpointDescription) {
282
276
  userIdentityTokens: endpoint.userIdentityTokens
283
277
  });
284
278
  // reduce even further by explicitly setting unwanted members to null
285
- e.server.applicationName = null as any;
279
+ e.server.applicationName = new LocalizedText({ text: "" });
286
280
  // xx e.server.applicationType = null as any;
287
281
  e.server.gatewayServerUri = null;
288
282
  e.server.discoveryProfileUri = null;
289
283
  e.server.discoveryUrls = null;
290
- e.serverCertificate = null as any;
284
+ e.serverCertificate = null as unknown as Buffer;
291
285
  return e;
292
286
  }
293
287
 
@@ -301,8 +295,8 @@ function _serverEndpointsForCreateSessionResponse(server: OPCUAServer, endpointU
301
295
  // https://reference.opcfoundation.org/v104/Core/docs/Part4/5.6.2/
302
296
  // https://reference.opcfoundation.org/v105/Core/docs/Part4/5.6.2/
303
297
  return server
304
- ._get_endpoints(endpointUrl)
305
- .filter((e) => !(e as any).restricted) // remove restricted endpoints
298
+ .findMatchingEndpoints(endpointUrl)
299
+ .filter((e) => !(e as unknown as { restricted: boolean }).restricted) // remove restricted endpoints
306
300
  .filter((e) => matchUri(e.endpointUrl, endpointUrl))
307
301
  .map(getRequiredEndpointInfo);
308
302
  }
@@ -325,7 +319,10 @@ function findUserTokenByPolicy(
325
319
  policyId: SecurityPolicy | string | null
326
320
  ): UserTokenPolicy | null {
327
321
  assert(endpoint_description instanceof EndpointDescription);
328
- const r = endpoint_description.userIdentityTokens!.filter(
322
+ if (!endpoint_description.userIdentityTokens) {
323
+ return null;
324
+ }
325
+ const r = endpoint_description.userIdentityTokens.filter(
329
326
  (userIdentity: UserTokenPolicy) =>
330
327
  userIdentity.tokenType === userTokenType && (!policyId || userIdentity.policyId === policyId)
331
328
  );
@@ -334,7 +331,10 @@ function findUserTokenByPolicy(
334
331
 
335
332
  function findUserTokenPolicy(endpoint_description: EndpointDescription, userTokenType: UserTokenType): UserTokenPolicy | null {
336
333
  assert(endpoint_description instanceof EndpointDescription);
337
- const r = endpoint_description.userIdentityTokens!.filter((userIdentity: UserTokenPolicy) => {
334
+ if (!endpoint_description.userIdentityTokens) {
335
+ return null;
336
+ }
337
+ const r = endpoint_description.userIdentityTokens.filter((userIdentity: UserTokenPolicy) => {
338
338
  assert(userIdentity.tokenType !== undefined);
339
339
  return userIdentity.tokenType === userTokenType;
340
340
  });
@@ -350,7 +350,13 @@ function createAnonymousIdentityToken(endpoint_desc: EndpointDescription) {
350
350
  return new AnonymousIdentityToken({ policyId: userTokenPolicy.policyId });
351
351
  }
352
352
 
353
- function sameIdentityToken(token1: UserIdentityToken, token2: UserIdentityToken): boolean {
353
+ function sameIdentityToken(token1?: UserIdentityToken, token2?: UserIdentityToken): boolean {
354
+ if (!token1 && !token2) {
355
+ return true;
356
+ }
357
+ if (!token1 || !token2) {
358
+ return false;
359
+ }
354
360
  if (token1 instanceof UserNameIdentityToken) {
355
361
  if (!(token2 instanceof UserNameIdentityToken)) {
356
362
  return false;
@@ -388,7 +394,7 @@ function getTokenType(userIdentityToken: UserIdentityToken): UserTokenType {
388
394
  }
389
395
  return UserTokenType.Invalid;
390
396
  }
391
- function thumbprint(certificate?: Certificate): string {
397
+ function thumbprint(certificate?: Certificate | null): string {
392
398
  return certificate ? certificate.toString("base64") : "";
393
399
  }
394
400
 
@@ -408,7 +414,7 @@ function monitoredItem_read_and_record_value(
408
414
  context: ISessionContext,
409
415
  oldValue: DataValue,
410
416
  node: UAVariable,
411
- itemToMonitor: any,
417
+ itemToMonitor: ReadValueId,
412
418
  callback: (err: Error | null, dataValue?: DataValue) => void
413
419
  ) {
414
420
  assert(self instanceof MonitoredItem);
@@ -429,7 +435,7 @@ function monitoredItem_read_and_record_value_async(
429
435
  context: ISessionContext,
430
436
  oldValue: DataValue,
431
437
  node: UAVariable,
432
- itemToMonitor: any,
438
+ itemToMonitor: ReadValueId,
433
439
  callback: (err: Error | null, dataValue?: DataValue) => void
434
440
  ) {
435
441
  assert(context instanceof SessionContext);
@@ -444,7 +450,7 @@ function monitoredItem_read_and_record_value_async(
444
450
  });
445
451
  }
446
452
 
447
- function build_scanning_node_function(addressSpace: AddressSpace, itemToMonitor: any): SamplingFunc {
453
+ function build_scanning_node_function(addressSpace: AddressSpace, itemToMonitor: ReadValueId): SamplingFunc {
448
454
  assert(itemToMonitor instanceof ReadValueId);
449
455
 
450
456
  const node = addressSpace.findNode(itemToMonitor.nodeId) as UAVariable;
@@ -508,7 +514,7 @@ function build_scanning_node_function(addressSpace: AddressSpace, itemToMonitor:
508
514
  }
509
515
  }
510
516
 
511
- function prepareMonitoredItem(context: ISessionContext, addressSpace: AddressSpace, monitoredItem: MonitoredItem) {
517
+ function prepareMonitoredItem(_context: ISessionContext, addressSpace: AddressSpace, monitoredItem: MonitoredItem) {
512
518
  const itemToMonitor = monitoredItem.itemToMonitor;
513
519
  const readNodeFunc = build_scanning_node_function(addressSpace, itemToMonitor);
514
520
  monitoredItem.samplingFunc = readNodeFunc;
@@ -590,7 +596,7 @@ function _installRegisterServerManager(self: OPCUAServer) {
590
596
  }
591
597
 
592
598
  function validate_applicationUri(channel: ServerSecureChannelLayer, request: CreateSessionRequest): boolean {
593
- const applicationUri = request.clientDescription.applicationUri!;
599
+ const applicationUri = request.clientDescription.applicationUri || "";
594
600
  const clientCertificate = request.clientCertificate;
595
601
  // if session is insecure there is no need to check certificate information
596
602
  if (channel.securityMode === MessageSecurityMode.None) {
@@ -600,7 +606,7 @@ function validate_applicationUri(channel: ServerSecureChannelLayer, request: Cre
600
606
  return true; // can't check
601
607
  }
602
608
  const e = exploreCertificate(clientCertificate);
603
- const uniformResourceIdentifier = e.tbsCertificate.extensions!.subjectAltName?.uniformResourceIdentifier ?? null;
609
+ const uniformResourceIdentifier = e.tbsCertificate.extensions?.subjectAltName?.uniformResourceIdentifier ?? null;
604
610
  const applicationUriFromCert =
605
611
  uniformResourceIdentifier && uniformResourceIdentifier.length > 0 ? uniformResourceIdentifier[0] : null;
606
612
 
@@ -623,7 +629,7 @@ function validate_security_endpoint(
623
629
  endpoint?: EndpointDescription;
624
630
  } {
625
631
  debugLog("validate_security_endpoint = ", request.endpointUrl);
626
- let endpoints = server._get_endpoints(request.endpointUrl);
632
+ let endpoints = server.findMatchingEndpoints(request.endpointUrl);
627
633
  // endpointUrl String The network address that the Client used to access the Session Endpoint.
628
634
  // The HostName portion of the URL should be one of the HostNames for the application that are
629
635
  // specified in the Server’s ApplicationInstanceCertificate (see 7.2). The Server shall raise an
@@ -636,22 +642,22 @@ function validate_security_endpoint(
636
642
  // sometime endpoints have a extra leading "/" that can be ignored
637
643
  // don't be too harsh.
638
644
  if (endpoints.length === 0 && request.endpointUrl?.endsWith("/")) {
639
- endpoints = server._get_endpoints(request.endpointUrl.slice(0, -1));
645
+ endpoints = server.findMatchingEndpoints(request.endpointUrl.slice(0, -1));
640
646
  }
641
647
 
642
648
  if (endpoints.length === 0) {
643
649
  // we have a UrlMismatch here
644
- const ua_server = server.engine.addressSpace!.rootFolder.objects.server;
650
+ const ua_server = server.engine.addressSpace?.rootFolder.objects.server;
645
651
  if (!request.endpointUrl?.match(/localhost/i) || OPCUAServer.requestExactEndpointUrl) {
646
652
  warningLog("Cannot find suitable endpoints in available endpoints. endpointUri =", request.endpointUrl);
647
653
  }
648
- ua_server.raiseEvent("AuditUrlMismatchEventType", {
654
+ ua_server?.raiseEvent("AuditUrlMismatchEventType", {
649
655
  endpointUrl: { dataType: DataType.String, value: request.endpointUrl }
650
656
  });
651
657
  if (OPCUAServer.requestExactEndpointUrl) {
652
658
  return { errCode: StatusCodes.BadServiceUnsupported };
653
659
  } else {
654
- endpoints = server._get_endpoints(null);
660
+ endpoints = server.findMatchingEndpoints(null);
655
661
  }
656
662
  }
657
663
  // ignore restricted endpoints
@@ -665,7 +671,7 @@ function validate_security_endpoint(
665
671
  return { errCode: StatusCodes.BadSecurityModeRejected };
666
672
  }
667
673
  const endpoints_matching_security_policy = endpoints_matching_security_mode.filter((e: EndpointDescription) => {
668
- return e.securityPolicyUri === channel!.securityPolicy;
674
+ return e.securityPolicyUri === channel?.securityPolicy;
669
675
  });
670
676
 
671
677
  if (endpoints_matching_security_policy.length === 0) {
@@ -674,7 +680,10 @@ function validate_security_endpoint(
674
680
  if (endpoints_matching_security_policy.length !== 1) {
675
681
  debugLog("endpoints_matching_security_policy= ", endpoints_matching_security_policy.length);
676
682
  }
677
- return { errCode: StatusCodes.Good, endpoint: endpoints_matching_security_policy[0] };
683
+ return {
684
+ errCode: StatusCodes.Good,
685
+ endpoint: endpoints_matching_security_policy[0]
686
+ };
678
687
  }
679
688
 
680
689
  export function filterDiagnosticInfo(returnDiagnostics: number, response: CallResponse): void {
@@ -748,6 +757,21 @@ export interface OPCUAServerEndpointOptions {
748
757
  /** alternate hostname or IP to use */
749
758
  alternateHostname?: string | string[];
750
759
 
760
+ /**
761
+ * Additional endpoint URL(s) to advertise.
762
+ *
763
+ * Use when the server is behind Docker port-mapping, a reverse proxy,
764
+ * or a NAT gateway. Each URL is parsed to extract hostname and port.
765
+ * Each entry can be a plain URL string (inherits all security
766
+ * settings from the main endpoint) or an
767
+ * `AdvertisedEndpointConfig` object with per-URL overrides.
768
+ * The server still listens on `port`.
769
+ *
770
+ * @example "opc.tcp://localhost:48481"
771
+ * @example ["opc.tcp://localhost:48481", { url: "opc.tcp://public:4840", securityModes: [MessageSecurityMode.SignAndEncrypt] }]
772
+ */
773
+ advertisedEndpoints?: AdvertisedEndpoint | AdvertisedEndpoint[];
774
+
751
775
  /**
752
776
  * true, if discovery service on secure channel shall be disabled
753
777
  */
@@ -925,39 +949,18 @@ export interface OPCUAServerOptions extends OPCUABaseServerOptions, OPCUAServerE
925
949
  transportSettings?: IServerTransportSettings;
926
950
  }
927
951
 
928
- // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
929
- export interface OPCUAServer {
930
- /**
931
- *
932
- */
933
- engine: ServerEngine;
934
- /**
935
- *
936
- */
937
- registerServerMethod: RegisterServerMethod;
938
- /**
939
- *
940
- */
941
- discoveryServerEndpointUrl: string;
942
- /**
943
- *
944
- */
945
- registerServerManager?: IRegisterServerManager;
946
- /**
947
- *
948
- */
949
- capabilitiesForMDNS: string[];
950
- /**
951
- *
952
- */
953
- userCertificateManager: OPCUACertificateManager;
954
- }
955
-
956
952
  const g_requestExactEndpointUrl = !!process.env.NODEOPCUA_SERVER_REQUEST_EXACT_ENDPOINT_URL;
957
953
  /**
958
954
  *
959
955
  */
960
956
  export class OPCUAServer extends OPCUABaseServer {
957
+ public engine!: ServerEngine;
958
+ public registerServerMethod: RegisterServerMethod;
959
+ public discoveryServerEndpointUrl!: string;
960
+ public registerServerManager?: IRegisterServerManager;
961
+ public capabilitiesForMDNS: string[];
962
+ public userCertificateManager: OPCUACertificateManager;
963
+
961
964
  static defaultShutdownTimeout = 100; // 250 ms
962
965
  /**
963
966
  * if requestExactEndpointUrl is set to true the server will only accept createSession that have a endpointUrl that strictly matches
@@ -1069,6 +1072,126 @@ export class OPCUAServer extends OPCUABaseServer {
1069
1072
  return this.engine ? this.engine.isAuditing : false;
1070
1073
  }
1071
1074
 
1075
+ /**
1076
+ * Set the current server state.
1077
+ *
1078
+ * Updates both the internal state and the
1079
+ * `Server.ServerStatus.State` variable in the
1080
+ * address space so that OPC UA reads reflect the
1081
+ * new state immediately.
1082
+ */
1083
+ public setServerState(serverState: ServerState): void {
1084
+ this.engine.setServerState(serverState);
1085
+ }
1086
+
1087
+ /**
1088
+ * Read the current `ServerState` from the
1089
+ * internal server status.
1090
+ */
1091
+ public getServerState(): ServerState {
1092
+ return this.engine.getServerState();
1093
+ }
1094
+
1095
+ /**
1096
+ * Set or clear a temporary role-policy override.
1097
+ *
1098
+ * When set, the override's `getUserRoles(username)`
1099
+ * is called **before** the default `userManager`.
1100
+ * Returning a `NodeId[]` overrides the roles;
1101
+ * returning `null` falls through to the default.
1102
+ *
1103
+ * Call with `null` to remove the override and
1104
+ * restore default behavior.
1105
+ */
1106
+ public setRolePolicyOverride(override: IRolePolicyOverride | null): void {
1107
+ (this as unknown as IServerBase).rolePolicyOverride = override;
1108
+ }
1109
+
1110
+ /**
1111
+ * Set `ServerConfiguration.InApplicationSetup` in
1112
+ * the address space.
1113
+ *
1114
+ * Indicates whether the server is in its initial
1115
+ * application setup phase (e.g. awaiting GDS
1116
+ * provisioning).
1117
+ */
1118
+ public setInApplicationSetup(value: boolean): void {
1119
+ this.engine.setInApplicationSetup(value);
1120
+ }
1121
+
1122
+ /**
1123
+ * Read the current value of
1124
+ * `ServerConfiguration.InApplicationSetup`.
1125
+ */
1126
+ public getInApplicationSetup(): boolean {
1127
+ return this.engine.getInApplicationSetup();
1128
+ }
1129
+
1130
+ /**
1131
+ * Collect additional hostnames for the self-signed certificate SAN.
1132
+ *
1133
+ * Merges hostnames from `alternateHostname` and parsed
1134
+ * `advertisedEndpoints` URLs so the certificate covers all
1135
+ * configured addresses.
1136
+ *
1137
+ * IP literals (v4/v6) are **excluded** — they are handled by
1138
+ * `getConfiguredIPs()` and placed in the SAN `iPAddress` entries.
1139
+ *
1140
+ * @internal
1141
+ */
1142
+ protected override getConfiguredHostnames(): string[] {
1143
+ return this._collectAlternateValues().hostnames;
1144
+ }
1145
+
1146
+ /**
1147
+ * Collect additional IP addresses for the self-signed certificate SAN.
1148
+ *
1149
+ * Merges IP literals from `alternateHostname` and parsed
1150
+ * `advertisedEndpoints` URLs so the certificate covers all
1151
+ * configured IP addresses.
1152
+ *
1153
+ * @internal
1154
+ */
1155
+ protected override getConfiguredIPs(): string[] {
1156
+ return this._collectAlternateValues().ips;
1157
+ }
1158
+
1159
+ /**
1160
+ * Classify all values from `alternateHostname` and
1161
+ * `advertisedEndpoints` into hostnames vs IP addresses using
1162
+ * `isIPAddress()` (wraps `net.isIP()`).
1163
+ */
1164
+ private _collectAlternateValues(): { hostnames: string[]; ips: string[] } {
1165
+ const hostnames: string[] = [];
1166
+ const ips: string[] = [];
1167
+
1168
+ // alternateHostname
1169
+ const alt = this.options.alternateHostname;
1170
+ if (alt) {
1171
+ const altArray = Array.isArray(alt) ? alt : [alt];
1172
+ for (const value of altArray) {
1173
+ if (isIPAddress(value)) {
1174
+ ips.push(value);
1175
+ } else {
1176
+ hostnames.push(value);
1177
+ }
1178
+ }
1179
+ }
1180
+
1181
+ // advertisedEndpoints — normalize to AdvertisedEndpointConfig[]
1182
+ const advList = normalizeAdvertisedEndpoints(this.options.advertisedEndpoints);
1183
+ for (const config of advList) {
1184
+ const { hostname } = parseOpcTcpUrl(config.url);
1185
+ if (isIPAddress(hostname)) {
1186
+ ips.push(hostname);
1187
+ } else {
1188
+ hostnames.push(hostname);
1189
+ }
1190
+ }
1191
+
1192
+ return { hostnames, ips };
1193
+ }
1194
+
1072
1195
  public static registry = new ObjectRegistry();
1073
1196
  public static fallbackSessionName = "Client didn't provide a meaningful sessionName ...";
1074
1197
  /**
@@ -1175,7 +1298,7 @@ export class OPCUAServer extends OPCUABaseServer {
1175
1298
 
1176
1299
  // note: applicationUri is handled in a special way
1177
1300
  this.engine = new ServerEngine({
1178
- applicationUri: () => this.serverInfo.applicationUri!,
1301
+ applicationUri: () => this.serverInfo.applicationUri || "",
1179
1302
  buildInfo,
1180
1303
  isAuditing: options.isAuditing,
1181
1304
  serverCapabilities: options.serverCapabilities,
@@ -1213,6 +1336,7 @@ export class OPCUAServer extends OPCUABaseServer {
1213
1336
  host: options.host,
1214
1337
  allowAnonymous: options.allowAnonymous,
1215
1338
  alternateHostname: options.alternateHostname,
1339
+ advertisedEndpoints: options.advertisedEndpoints,
1216
1340
  disableDiscovery: options.disableDiscovery,
1217
1341
  securityModes: options.securityModes,
1218
1342
  securityPolicies: options.securityPolicies
@@ -1220,7 +1344,7 @@ export class OPCUAServer extends OPCUABaseServer {
1220
1344
  }
1221
1345
  // todo should self.serverInfo.productUri match self.engine.buildInfo.productUri ?
1222
1346
  for (const endpointOptions of endpointDefinitions) {
1223
- const endPoint = this.createEndpointDescriptions(options!, endpointOptions);
1347
+ const endPoint = this.createEndpointDescriptions(options, endpointOptions);
1224
1348
  this.endpoints.push(endPoint);
1225
1349
  endPoint.on("message", (message: Message, channel: ServerSecureChannelLayer) => {
1226
1350
  this.on_request(message, channel);
@@ -1262,7 +1386,7 @@ export class OPCUAServer extends OPCUABaseServer {
1262
1386
  */
1263
1387
  public initialize(): Promise<void>;
1264
1388
  public initialize(done: () => void): void;
1265
- public initialize(...args: [any?, ...any[]]): any {
1389
+ public initialize(...args: [((err?: Error) => void)?]): Promise<void> | void {
1266
1390
  const done = args[0] as (err?: Error) => void;
1267
1391
  assert(!this.initialized, "server is already initialized"); // already initialized ?
1268
1392
 
@@ -1278,7 +1402,11 @@ export class OPCUAServer extends OPCUABaseServer {
1278
1402
  .then(() => {
1279
1403
  OPCUAServer.registry.register(this);
1280
1404
  this.engine.initialize(this.options, () => {
1281
- bindRoleSet(this.userManager, this.engine.addressSpace!);
1405
+ if (!this.engine.addressSpace) {
1406
+ done(new Error("no addressSpace"));
1407
+ return;
1408
+ }
1409
+ bindRoleSet(this.userManager, this.engine.addressSpace);
1282
1410
  setImmediate(() => {
1283
1411
  this.emit("post_initialize");
1284
1412
  done();
@@ -1295,38 +1423,36 @@ export class OPCUAServer extends OPCUABaseServer {
1295
1423
  */
1296
1424
  public start(): Promise<void>;
1297
1425
  public start(done: () => void): void;
1298
- public start(...args: [any?, ...any[]]): any {
1299
- const done = args[0] as () => void;
1300
- const tasks: any[] = [];
1301
-
1302
- tasks.push(callbackify(extractFullyQualifiedDomainName));
1426
+ public start(...args: [((err?: Error) => void)?]): Promise<void> | void {
1427
+ const callback = args[0];
1428
+ if (callback) {
1429
+ return super.start(callback);
1430
+ }
1431
+ return super.start();
1432
+ }
1433
+ /**
1434
+ * Initiate the server by starting all its endpoints
1435
+ * @private
1436
+ */
1437
+ public async startAsync(): Promise<void> {
1438
+ await extractFullyQualifiedDomainName();
1303
1439
 
1304
1440
  if (!this.initialized) {
1305
- tasks.push((callback: ErrorCallback) => {
1306
- this.initialize(callback);
1307
- });
1441
+ await this.initialize();
1308
1442
  }
1309
- tasks.push((callback: ErrorCallback) => {
1310
- super.start((err?: Error | null) => {
1311
- if (err) {
1312
- this.shutdown((/*err2*/ err2?: Error) => {
1313
- callback(err);
1314
- });
1315
- } else {
1316
- // we start the registration process asynchronously
1317
- // as we want to make server immediately available
1318
- this.registerServerManager!.start().then(() => {
1319
- /* empty */
1320
- }).catch((err) => {
1321
- /* empty */
1322
- });
1323
1443
 
1324
- setImmediate(callback);
1325
- }
1326
- });
1327
- });
1444
+ try {
1445
+ await super.startAsync();
1446
+ } catch (err) {
1447
+ await this.shutdown();
1448
+ throw err;
1449
+ }
1328
1450
 
1329
- async.series(tasks, done);
1451
+ // we start the registration process asynchronously
1452
+ // as we want to make server immediately available
1453
+ this.registerServerManager?.start().catch(() => {
1454
+ /* empty */
1455
+ });
1330
1456
  }
1331
1457
 
1332
1458
  /**
@@ -1356,7 +1482,7 @@ export class OPCUAServer extends OPCUABaseServer {
1356
1482
  public shutdown(timeout?: number): Promise<void>;
1357
1483
  public shutdown(callback: (err?: Error) => void): void;
1358
1484
  public shutdown(timeout: number, callback: (err?: Error) => void): void;
1359
- public shutdown(...args: [any?, ...any[]]): any {
1485
+ public shutdown(...args: [number | ((err?: Error) => void) | undefined, ...((err?: Error) => void)[]]): Promise<void> | void {
1360
1486
  const timeout = args.length === 1 ? OPCUAServer.defaultShutdownTimeout : (args[0] as number);
1361
1487
  const callback = (args.length === 1 ? args[0] : args[1]) as (err?: Error) => void;
1362
1488
  assert(typeof callback === "function");
@@ -1380,28 +1506,31 @@ export class OPCUAServer extends OPCUABaseServer {
1380
1506
  const shutdownTime = new Date(Date.now() + timeout);
1381
1507
  this.engine.setShutdownTime(shutdownTime);
1382
1508
 
1383
- debugLog("OPCUAServer is now un-registering itself from the discovery server " + this.buildInfo);
1384
- this.registerServerManager!.stop()
1509
+ debugLog("OPCUAServer is now un-registering itself from the discovery server ", this.buildInfo);
1510
+ if (!this.registerServerManager) {
1511
+ callback(new Error("invalid register server manager"));
1512
+ return;
1513
+ }
1514
+ this.registerServerManager
1515
+ .stop()
1385
1516
  .then(() => {
1386
1517
  debugLog("OPCUAServer unregistered from discovery server successfully");
1387
-
1388
1518
  })
1389
1519
  .catch((err) => {
1390
1520
  debugLog("OPCUAServer unregistered from discovery server with err: ", err.message);
1391
- }).finally(() => {
1392
-
1521
+ })
1522
+ .finally(() => {
1393
1523
  setTimeout(async () => {
1394
1524
  await this.engine.shutdown();
1395
1525
 
1396
1526
  debugLog("OPCUAServer#shutdown: started");
1397
- OPCUABaseServer.prototype.shutdown.call(this, (err1?: Error) => {
1527
+ OPCUABaseServer.prototype.shutdown.call(this, (err1?: Error | null) => {
1398
1528
  debugLog("OPCUAServer#shutdown: completed");
1399
1529
 
1400
1530
  this.dispose();
1401
- callback(err1);
1531
+ callback(err1 || undefined);
1402
1532
  });
1403
1533
  }, timeout);
1404
-
1405
1534
  });
1406
1535
  }
1407
1536
 
@@ -1457,12 +1586,12 @@ export class OPCUAServer extends OPCUABaseServer {
1457
1586
  if (typeof eventType === "string") {
1458
1587
  eventTypeNode = this.engine.addressSpace.findEventType(eventType);
1459
1588
  if (eventTypeNode) {
1460
- return server.raiseEvent(eventTypeNode, options);
1589
+ server.raiseEvent(eventTypeNode, options);
1461
1590
  } else {
1462
1591
  console.warn(" cannot find event type ", eventType);
1463
1592
  }
1464
1593
  } else {
1465
- return server.raiseEvent(eventTypeNode, options);
1594
+ server.raiseEvent(eventTypeNode, options);
1466
1595
  }
1467
1596
  }
1468
1597
 
@@ -1512,32 +1641,34 @@ export class OPCUAServer extends OPCUABaseServer {
1512
1641
  channel: ServerSecureChannelLayer,
1513
1642
  clientSignature: SignatureData
1514
1643
  ): boolean {
1515
- const clientCertificate = channel.clientCertificate!;
1644
+ const clientCertificate = channel.clientCertificate;
1516
1645
  const securityPolicy = channel.securityPolicy;
1517
1646
  const serverCertificate = this.getCertificate();
1518
- const result = verifySignature(serverCertificate, session.nonce!, clientSignature, clientCertificate, securityPolicy);
1647
+ const result = verifySignature(serverCertificate, session.nonce, clientSignature, clientCertificate, securityPolicy);
1519
1648
  return result;
1520
1649
  }
1521
1650
 
1522
1651
  protected isValidUserNameIdentityToken(
1523
1652
  channel: ServerSecureChannelLayer,
1524
- session: ServerSession,
1653
+ _session: ServerSession,
1525
1654
  userTokenPolicy: UserTokenPolicy,
1526
1655
  userIdentityToken: UserNameIdentityToken,
1527
- userTokenSignature: SignatureData,
1656
+ _userTokenSignature: SignatureData,
1528
1657
  callback: (err: Error | null, statusCode?: StatusCode) => void
1529
1658
  ): void {
1530
1659
  assert(userIdentityToken instanceof UserNameIdentityToken);
1531
1660
 
1532
1661
  const securityPolicy = adjustSecurityPolicy(channel, userTokenPolicy.securityPolicyUri);
1533
1662
  if (securityPolicy === SecurityPolicy.None) {
1534
- return callback(null, StatusCodes.Good);
1663
+ callback(null, StatusCodes.Good);
1664
+ return;
1535
1665
  }
1536
1666
  const cryptoFactory = getCryptoFactory(securityPolicy);
1537
1667
 
1538
1668
  /* c8 ignore next */
1539
1669
  if (!cryptoFactory) {
1540
- return callback(null, StatusCodes.BadSecurityPolicyRejected);
1670
+ callback(null, StatusCodes.BadSecurityPolicyRejected);
1671
+ return;
1541
1672
  }
1542
1673
 
1543
1674
  /* c8 ignore next */
@@ -1545,14 +1676,16 @@ export class OPCUAServer extends OPCUABaseServer {
1545
1676
  errorLog("invalid encryptionAlgorithm");
1546
1677
  errorLog("userTokenPolicy", userTokenPolicy.toString());
1547
1678
  errorLog("userTokenPolicy", userIdentityToken.toString());
1548
- return callback(null, StatusCodes.BadIdentityTokenInvalid);
1679
+ callback(null, StatusCodes.BadIdentityTokenInvalid);
1680
+ return;
1549
1681
  }
1550
1682
  const userName = userIdentityToken.userName;
1551
1683
  const password = userIdentityToken.password;
1552
1684
  if (!userName || !password) {
1553
- return callback(null, StatusCodes.BadIdentityTokenInvalid);
1685
+ callback(null, StatusCodes.BadIdentityTokenInvalid);
1686
+ return;
1554
1687
  }
1555
- return callback(null, StatusCodes.Good);
1688
+ callback(null, StatusCodes.Good);
1556
1689
  }
1557
1690
 
1558
1691
  protected isValidX509IdentityToken(
@@ -1571,37 +1704,40 @@ export class OPCUAServer extends OPCUABaseServer {
1571
1704
  const cryptoFactory = getCryptoFactory(securityPolicy);
1572
1705
  /* c8 ignore next */
1573
1706
  if (!cryptoFactory) {
1574
- return callback(null, StatusCodes.BadSecurityPolicyRejected);
1707
+ callback(null, StatusCodes.BadSecurityPolicyRejected);
1708
+ return;
1575
1709
  }
1576
1710
 
1577
1711
  if (!userTokenSignature || !userTokenSignature.signature) {
1578
1712
  this.raiseEvent("AuditCreateSessionEventType", {});
1579
-
1580
- return callback(null, StatusCodes.BadUserSignatureInvalid);
1713
+ callback(null, StatusCodes.BadUserSignatureInvalid);
1714
+ return;
1581
1715
  }
1582
1716
 
1583
1717
  if (userIdentityToken.policyId !== userTokenPolicy.policyId) {
1584
1718
  errorLog("invalid encryptionAlgorithm");
1585
1719
  errorLog("userTokenPolicy", userTokenPolicy.toString());
1586
1720
  errorLog("userTokenPolicy", userIdentityToken.toString());
1587
- return callback(null, StatusCodes.BadSecurityPolicyRejected);
1721
+ callback(null, StatusCodes.BadSecurityPolicyRejected);
1722
+ return;
1588
1723
  }
1589
1724
  const certificate = userIdentityToken.certificateData; /* as Certificate*/
1590
- const nonce = session.nonce!;
1725
+ const nonce = session.nonce;
1726
+ if (!nonce || nonce.length === 0) {
1727
+ callback(null, StatusCodes.BadNonceInvalid);
1728
+ return;
1729
+ }
1591
1730
  const serverCertificate = this.getCertificate();
1592
-
1593
- assert(serverCertificate instanceof Buffer);
1594
- assert(certificate instanceof Buffer, "expecting certificate to be a Buffer");
1595
- assert(nonce instanceof Buffer, "expecting nonce to be a Buffer");
1596
1731
  assert(userTokenSignature.signature instanceof Buffer, "expecting userTokenSignature to be a Buffer");
1597
1732
 
1598
1733
  // verify proof of possession by checking certificate signature & server nonce correctness
1599
1734
  if (!verifySignature(serverCertificate, nonce, userTokenSignature, certificate, securityPolicy)) {
1600
- return callback(null, StatusCodes.BadUserSignatureInvalid);
1735
+ callback(null, StatusCodes.BadUserSignatureInvalid);
1736
+ return;
1601
1737
  }
1602
1738
 
1603
1739
  // verify if certificate is Valid
1604
- this.userCertificateManager!.checkCertificate(certificate, (err, certificateStatus) => {
1740
+ this.userCertificateManager.checkCertificate(certificate, (err, certificateStatus) => {
1605
1741
  /* c8 ignore next */
1606
1742
  if (err) {
1607
1743
  return callback(err);
@@ -1612,31 +1748,55 @@ export class OPCUAServer extends OPCUABaseServer {
1612
1748
  break;
1613
1749
  case StatusCodes.BadCertificateUntrusted:
1614
1750
  this.raiseEvent("AuditCertificateUntrustedEventType", {
1615
- certificate: { dataType: DataType.ByteString, value: certificate },
1616
- sourceName: { dataType: DataType.String, value: "Security/Certificate" }
1751
+ certificate: {
1752
+ dataType: DataType.ByteString,
1753
+ value: certificate
1754
+ },
1755
+ sourceName: {
1756
+ dataType: DataType.String,
1757
+ value: "Security/Certificate"
1758
+ }
1617
1759
  });
1618
1760
  break;
1619
1761
  case StatusCodes.BadCertificateTimeInvalid:
1620
1762
  case StatusCodes.BadCertificateIssuerTimeInvalid:
1621
1763
  this.raiseEvent("AuditCertificateExpiredEventType", {
1622
- certificate: { dataType: DataType.ByteString, value: certificate },
1623
- sourceName: { dataType: DataType.String, value: "Security/Certificate" }
1764
+ certificate: {
1765
+ dataType: DataType.ByteString,
1766
+ value: certificate
1767
+ },
1768
+ sourceName: {
1769
+ dataType: DataType.String,
1770
+ value: "Security/Certificate"
1771
+ }
1624
1772
  });
1625
1773
  break;
1626
1774
  case StatusCodes.BadCertificateRevoked:
1627
1775
  case StatusCodes.BadCertificateRevocationUnknown:
1628
1776
  case StatusCodes.BadCertificateIssuerRevocationUnknown:
1629
1777
  this.raiseEvent("AuditCertificateRevokedEventType", {
1630
- certificate: { dataType: DataType.ByteString, value: certificate },
1631
- sourceName: { dataType: DataType.String, value: "Security/Certificate" }
1778
+ certificate: {
1779
+ dataType: DataType.ByteString,
1780
+ value: certificate
1781
+ },
1782
+ sourceName: {
1783
+ dataType: DataType.String,
1784
+ value: "Security/Certificate"
1785
+ }
1632
1786
  });
1633
1787
  break;
1634
1788
  case StatusCodes.BadCertificateIssuerUseNotAllowed:
1635
1789
  case StatusCodes.BadCertificateUseNotAllowed:
1636
1790
  case StatusCodes.BadSecurityChecksFailed:
1637
1791
  this.raiseEvent("AuditCertificateMismatchEventType", {
1638
- certificate: { dataType: DataType.ByteString, value: certificate },
1639
- sourceName: { dataType: DataType.String, value: "Security/Certificate" }
1792
+ certificate: {
1793
+ dataType: DataType.ByteString,
1794
+ value: certificate
1795
+ },
1796
+ sourceName: {
1797
+ dataType: DataType.String,
1798
+ value: "Security/Certificate"
1799
+ }
1640
1800
  });
1641
1801
  break;
1642
1802
  }
@@ -1688,8 +1848,12 @@ export class OPCUAServer extends OPCUABaseServer {
1688
1848
 
1689
1849
  const securityPolicy = adjustSecurityPolicy(channel, userTokenPolicy.securityPolicyUri);
1690
1850
 
1691
- const userName = userIdentityToken.userName!;
1692
- let password: any = userIdentityToken.password;
1851
+ const userName = userIdentityToken.userName;
1852
+ if (!userName) {
1853
+ callback(new Error(" expecting a no null username"));
1854
+ return;
1855
+ }
1856
+ let password: ByteString | string = userIdentityToken.password;
1693
1857
 
1694
1858
  // decrypt password if necessary
1695
1859
  if (securityPolicy === SecurityPolicy.None) {
@@ -1698,20 +1862,24 @@ export class OPCUAServer extends OPCUABaseServer {
1698
1862
  } else {
1699
1863
  const serverPrivateKey = this.getPrivateKey();
1700
1864
 
1701
- const serverNonce = session.nonce!;
1702
- assert(serverNonce instanceof Buffer);
1865
+ const serverNonce = session.nonce;
1866
+ if (!serverNonce) {
1867
+ callback(new Error(" expecting a no null nonce"));
1868
+ return;
1869
+ }
1703
1870
 
1704
1871
  const cryptoFactory = getCryptoFactory(securityPolicy);
1705
1872
  /* c8 ignore next */
1706
1873
  if (!cryptoFactory) {
1707
- return callback(new Error(" Unsupported security Policy"));
1874
+ callback(new Error(" Unsupported security Policy"));
1875
+ return;
1708
1876
  }
1709
1877
 
1710
1878
  const buff = cryptoFactory.asymmetricDecrypt(password, serverPrivateKey);
1711
1879
 
1712
1880
  // server certificate may be invalid and asymmetricDecrypt may fail
1713
1881
  if (!buff || buff.length < 4) {
1714
- async.setImmediate(() => callback(null, false));
1882
+ setImmediate(() => callback(null, false));
1715
1883
  return;
1716
1884
  }
1717
1885
 
@@ -1744,34 +1912,23 @@ export class OPCUAServer extends OPCUABaseServer {
1744
1912
 
1745
1913
  const userTokenType = getTokenType(userIdentityToken);
1746
1914
 
1747
- const userTokenPolicy = findUserTokenByPolicy(endpointDescription, userTokenType, userIdentityToken.policyId!);
1915
+ const userTokenPolicy = findUserTokenByPolicy(endpointDescription, userTokenType, userIdentityToken.policyId);
1748
1916
  if (!userTokenPolicy) {
1749
1917
  // cannot find token with this policyId
1750
- return callback(null, StatusCodes.BadIdentityTokenInvalid);
1918
+ callback(null, StatusCodes.BadIdentityTokenInvalid);
1919
+ return;
1751
1920
  }
1752
1921
  //
1753
1922
  if (userIdentityToken instanceof UserNameIdentityToken) {
1754
- return this.isValidUserNameIdentityToken(
1755
- channel,
1756
- session,
1757
- userTokenPolicy,
1758
- userIdentityToken,
1759
- userTokenSignature,
1760
- callback
1761
- );
1923
+ this.isValidUserNameIdentityToken(channel, session, userTokenPolicy, userIdentityToken, userTokenSignature, callback);
1924
+ return;
1762
1925
  }
1763
1926
  if (userIdentityToken instanceof X509IdentityToken) {
1764
- return this.isValidX509IdentityToken(
1765
- channel,
1766
- session,
1767
- userTokenPolicy,
1768
- userIdentityToken,
1769
- userTokenSignature,
1770
- callback
1771
- );
1927
+ this.isValidX509IdentityToken(channel, session, userTokenPolicy, userIdentityToken, userTokenSignature, callback);
1928
+ return;
1772
1929
  }
1773
1930
 
1774
- return callback(null, StatusCodes.Good);
1931
+ callback(null, StatusCodes.Good);
1775
1932
  }
1776
1933
 
1777
1934
  /**
@@ -1793,16 +1950,18 @@ export class OPCUAServer extends OPCUABaseServer {
1793
1950
  assert(typeof callback === "function");
1794
1951
 
1795
1952
  const userTokenType = getTokenType(userIdentityToken);
1796
- const userTokenPolicy = findUserTokenByPolicy(session.getEndpointDescription(), userTokenType, userIdentityToken.policyId!);
1953
+ const userTokenPolicy = findUserTokenByPolicy(session.getEndpointDescription(), userTokenType, userIdentityToken.policyId);
1797
1954
  /** c8 ignore next */
1798
1955
  if (!userTokenPolicy) {
1799
- return callback(null, false);
1956
+ callback(null, false);
1957
+ return;
1800
1958
  }
1801
1959
  // find if a userToken exists
1802
1960
  if (userIdentityToken instanceof UserNameIdentityToken) {
1803
- return this.userNameIdentityTokenAuthenticateUser(channel, session, userTokenPolicy, userIdentityToken, callback);
1961
+ this.userNameIdentityTokenAuthenticateUser(channel, session, userTokenPolicy, userIdentityToken, callback);
1962
+ return;
1804
1963
  }
1805
- async.setImmediate(callback.bind(null, null, true));
1964
+ setImmediate(callback.bind(null, null, true));
1806
1965
  }
1807
1966
 
1808
1967
  protected makeServerNonce(): Nonce {
@@ -1870,17 +2029,14 @@ export class OPCUAServer extends OPCUABaseServer {
1870
2029
  if (channel.securityMode !== MessageSecurityMode.None) {
1871
2030
  errorLog(
1872
2031
  chalk.red("SERVER with secure connection: Missing or invalid client Nonce "),
1873
- request.clientNonce && request.clientNonce.toString("hex")
2032
+ request.clientNonce?.toString("hex")
1874
2033
  );
1875
2034
 
1876
2035
  return rejectConnection(this, StatusCodes.BadNonceInvalid);
1877
2036
  }
1878
2037
  }
1879
2038
  if (nonceAlreadyBeenUsed(request.clientNonce)) {
1880
- errorLog(
1881
- chalk.red("SERVER with secure connection: Nonce has already been used"),
1882
- request.clientNonce && request.clientNonce.toString("hex")
1883
- );
2039
+ errorLog(chalk.red("SERVER with secure connection: Nonce has already been used"), request.clientNonce?.toString("hex"));
1884
2040
 
1885
2041
  return rejectConnection(this, StatusCodes.BadNonceInvalid);
1886
2042
  }
@@ -1932,7 +2088,7 @@ export class OPCUAServer extends OPCUABaseServer {
1932
2088
 
1933
2089
  const hasEncryption = true;
1934
2090
  // If the securityPolicyUri is None and none of the UserTokenPolicies requires encryption
1935
- if (session.channel!.securityMode === MessageSecurityMode.None) {
2091
+ if (session.channel?.securityMode === MessageSecurityMode.None) {
1936
2092
  // ToDo: Check that none of our insecure endpoint has a a UserTokenPolicy that require encryption
1937
2093
  // and set hasEncryption = false under this condition
1938
2094
  }
@@ -1969,7 +2125,7 @@ export class OPCUAServer extends OPCUABaseServer {
1969
2125
  // securityPolicyUri, userIdentityTokens, transportProfileUri and securityLevel with all
1970
2126
  // other parameters set to null. Only the recommended parameters shall be verified by
1971
2127
  // the client.
1972
- serverEndpoints: _serverEndpointsForCreateSessionResponse(this, session.endpoint!.endpointUrl, request.serverUri),
2128
+ serverEndpoints: _serverEndpointsForCreateSessionResponse(this, session.endpoint?.endpointUrl || "", request.serverUri),
1973
2129
 
1974
2130
  // This parameter is deprecated and the array shall be empty.
1975
2131
  serverSoftwareCertificates: null,
@@ -1995,7 +2151,7 @@ export class OPCUAServer extends OPCUABaseServer {
1995
2151
  assert(typeof reason === "string");
1996
2152
  if (this.isAuditing) {
1997
2153
  assert(reason === "Timeout" || reason === "Terminated" || reason === "CloseSession" || reason === "Forcing");
1998
- const sourceName = "Session/" + reason;
2154
+ const sourceName = `Session/${reason}`;
1999
2155
 
2000
2156
  this.raiseEvent("AuditSessionEventType", {
2001
2157
  /* part 5 - 6.4.3 AuditEventType */
@@ -2047,18 +2203,27 @@ export class OPCUAServer extends OPCUABaseServer {
2047
2203
  // identifier in all AuditEvents related to the Session Service Set (AuditCreateSessionEventType,
2048
2204
  // AuditActivateSessionEventType and their subtypes) and the SecureChannel Service Set
2049
2205
  // (AuditChannelEventType and its subtypes
2050
- secureChannelId: { dataType: "String", value: session.channel!.channelId!.toString() },
2206
+ secureChannelId: {
2207
+ dataType: "String",
2208
+ value: session.channel?.channelId?.toString() ?? ""
2209
+ },
2051
2210
 
2052
2211
  // Duration
2053
- revisedSessionTimeout: { dataType: "Duration", value: session.sessionTimeout },
2212
+ revisedSessionTimeout: {
2213
+ dataType: "Duration",
2214
+ value: session.sessionTimeout
2215
+ },
2054
2216
 
2055
2217
  // clientCertificate
2056
- clientCertificate: { dataType: "ByteString", value: session.channel!.clientCertificate },
2218
+ clientCertificate: {
2219
+ dataType: "ByteString",
2220
+ value: session.channel?.clientCertificate ?? null
2221
+ },
2057
2222
 
2058
2223
  // clientCertificateThumbprint
2059
2224
  clientCertificateThumbprint: {
2060
2225
  dataType: "String",
2061
- value: thumbprint(session.channel!.clientCertificate!)
2226
+ value: thumbprint(session.channel?.clientCertificate)
2062
2227
  }
2063
2228
  });
2064
2229
  }
@@ -2101,20 +2266,21 @@ export class OPCUAServer extends OPCUABaseServer {
2101
2266
  server.engine.incrementSecurityRejectedSessionCount();
2102
2267
  }
2103
2268
 
2104
- const response1 = new ActivateSessionResponse({ responseHeader: { serviceResult: statusCode } });
2269
+ const response1 = new ActivateSessionResponse({
2270
+ responseHeader: { serviceResult: statusCode }
2271
+ });
2105
2272
 
2106
2273
  channel.send_response("MSG", response1, message);
2107
2274
  }
2108
2275
 
2109
- let response;
2110
-
2111
2276
  /* c8 ignore next */
2112
2277
  if (!session) {
2113
2278
  // this may happen when the server has been restarted and a client tries to reconnect, thinking
2114
2279
  // that the previous session may still be active
2115
2280
  debugLog(chalk.yellow.bold(" Bad Session in _on_ActivateSessionRequest"), authenticationToken.toString());
2116
2281
 
2117
- return rejectConnection(this, StatusCodes.BadSessionIdInvalid);
2282
+ rejectConnection(this, StatusCodes.BadSessionIdInvalid);
2283
+ return;
2118
2284
  }
2119
2285
 
2120
2286
  // tslint:disable-next-line: no-unused-expression
@@ -2128,8 +2294,9 @@ export class OPCUAServer extends OPCUABaseServer {
2128
2294
  if (!channel_has_session(channel, session)) {
2129
2295
  // it looks like session activation is being using a channel that is not the
2130
2296
  // one that have been used to create the session
2131
- errorLog(" channel.sessionTokens === " + Object.keys(channel.sessionTokens).join(" "));
2132
- return rejectConnection(this, StatusCodes.BadSessionNotActivated);
2297
+ errorLog(` channel.sessionTokens === ${Object.keys(channel.sessionTokens).join(" ")}`);
2298
+ rejectConnection(this, StatusCodes.BadSessionNotActivated);
2299
+ return;
2133
2300
  }
2134
2301
  }
2135
2302
 
@@ -2139,47 +2306,58 @@ export class OPCUAServer extends OPCUABaseServer {
2139
2306
  // SecureChannel is the same as the Certificate used to create the original SecureChannel.
2140
2307
 
2141
2308
  if (session.status === "active") {
2142
- if (session.channel!.channelId !== channel.channelId) {
2309
+ if (session.channel?.channelId !== channel.channelId) {
2143
2310
  warningLog(
2144
2311
  " Session ",
2145
2312
  session.sessionName,
2146
2313
  " is being transferred from channel",
2147
- chalk.cyan(session.channel!.channelId!.toString()),
2314
+ chalk.cyan(session.channel?.channelId?.toString()),
2148
2315
  " to channel ",
2149
- chalk.cyan(channel.channelId!.toString())
2316
+ chalk.cyan(channel.channelId?.toString())
2150
2317
  );
2151
2318
 
2152
2319
  // session is being reassigned to a new Channel,
2153
2320
  // we shall verify that the certificate used to create the Session is the same as the current
2154
2321
  // channel certificate.
2155
- const old_channel_cert_thumbprint = thumbprint(session.channel!.clientCertificate!);
2156
- const new_channel_cert_thumbprint = thumbprint(channel.clientCertificate!);
2322
+ const old_channel_cert_thumbprint = thumbprint(session.channel?.clientCertificate);
2323
+ const new_channel_cert_thumbprint = thumbprint(channel.clientCertificate);
2157
2324
 
2158
2325
  if (old_channel_cert_thumbprint !== new_channel_cert_thumbprint) {
2159
- return rejectConnection(this, StatusCodes.BadNoValidCertificates); // not sure about this code !
2326
+ rejectConnection(this, StatusCodes.BadNoValidCertificates); // not sure about this code !
2327
+ return;
2160
2328
  }
2161
2329
 
2162
2330
  // ... In addition the Server shall verify that the Client supplied a UserIdentityToken that is
2163
2331
  // identical to the token currently associated with the Session reassign session to new channel.
2164
- if (!sameIdentityToken(session.userIdentityToken!, request.userIdentityToken as UserIdentityToken)) {
2165
- return rejectConnection(this, StatusCodes.BadIdentityChangeNotSupported); // not sure about this code !
2332
+ if (!sameIdentityToken(session.userIdentityToken, request.userIdentityToken as UserIdentityToken)) {
2333
+ rejectConnection(this, StatusCodes.BadIdentityChangeNotSupported); // not sure about this code !
2334
+ return;
2166
2335
  }
2167
2336
  }
2168
2337
  } else if (session.status === "screwed") {
2169
2338
  // session has been used before being activated => this should be detected and session should be dismissed.
2170
- return rejectConnection(this, StatusCodes.BadSessionClosed);
2339
+ rejectConnection(this, StatusCodes.BadSessionClosed);
2340
+ return;
2171
2341
  } else if (session.status === "closed") {
2172
2342
  warningLog(chalk.yellow.bold(" Bad Session Closed in _on_ActivateSessionRequest"), authenticationToken.toString());
2173
- return rejectConnection(this, StatusCodes.BadSessionClosed);
2343
+ rejectConnection(this, StatusCodes.BadSessionClosed);
2344
+ return;
2174
2345
  }
2175
2346
 
2176
2347
  // verify clientSignature provided by the client
2177
2348
  if (!this.verifyClientSignature(session, channel, request.clientSignature)) {
2178
- return rejectConnection(this, StatusCodes.BadApplicationSignatureInvalid);
2349
+ rejectConnection(this, StatusCodes.BadApplicationSignatureInvalid);
2350
+ return;
2351
+ }
2352
+
2353
+ const endpoint = session.endpoint;
2354
+ if (!endpoint) {
2355
+ rejectConnection(this, StatusCodes.BadSessionIdInvalid);
2356
+ return;
2179
2357
  }
2180
2358
 
2181
2359
  // userIdentityToken may be missing , assume anonymous access then
2182
- request.userIdentityToken = request.userIdentityToken || createAnonymousIdentityToken(session.endpoint!);
2360
+ request.userIdentityToken = request.userIdentityToken || createAnonymousIdentityToken(endpoint);
2183
2361
 
2184
2362
  // check request.userIdentityToken is correct ( expected type and correctly formed)
2185
2363
  this.isValidUserIdentityToken(
@@ -2187,8 +2365,8 @@ export class OPCUAServer extends OPCUABaseServer {
2187
2365
  session,
2188
2366
  request.userIdentityToken as UserIdentityToken,
2189
2367
  request.userTokenSignature,
2190
- session.endpoint!,
2191
- (err: Error | null, statusCode?: StatusCode) => {
2368
+ endpoint,
2369
+ (_err: Error | null, statusCode?: StatusCode) => {
2192
2370
  if (!statusCode || statusCode.isNotGood()) {
2193
2371
  /* c8 ignore next */
2194
2372
  if (!(statusCode && statusCode instanceof StatusCode)) {
@@ -2223,7 +2401,9 @@ export class OPCUAServer extends OPCUABaseServer {
2223
2401
 
2224
2402
  session.status = "active";
2225
2403
 
2226
- response = new ActivateSessionResponse({ serverNonce: session.nonce });
2404
+ const response = new ActivateSessionResponse({
2405
+ serverNonce: session.nonce
2406
+ });
2227
2407
  channel.send_response("MSG", response, message);
2228
2408
 
2229
2409
  // send OPCUA Event Notification
@@ -2267,7 +2447,7 @@ export class OPCUAServer extends OPCUABaseServer {
2267
2447
  if (request.constructor.name !== "PublishRequest") {
2268
2448
  errorLog(
2269
2449
  chalk.red.bgWhite(
2270
- "ERROR: channel.channelId !== session.channelId on processing request " + request.constructor.name
2450
+ `ERROR: channel.channelId !== session.channelId on processing request ${request.constructor.name}`
2271
2451
  ),
2272
2452
  channel.channelId,
2273
2453
  session.channelId
@@ -2342,12 +2522,14 @@ export class OPCUAServer extends OPCUABaseServer {
2342
2522
  return g_sendError(channel, message, ResponseClass, statusCode);
2343
2523
  }
2344
2524
 
2345
- let response: any;
2346
2525
  /* c8 ignore next */
2347
2526
  if (!message.session || message.session_statusCode !== StatusCodes.Good) {
2348
- const errMessage = "=>" + message.session_statusCode?.toString();
2349
- response = new ServiceFault({ responseHeader: { serviceResult: message.session_statusCode } });
2350
- debugLog(chalk.red.bold(errMessage), chalk.yellow(message.session_statusCode!.toString()), response.constructor.name);
2527
+ const sessionStatusCode = message.session_statusCode ?? StatusCodes.BadInternalError;
2528
+ const errMessage = `=>${sessionStatusCode.toString()}`;
2529
+ const response = new ServiceFault({
2530
+ responseHeader: { serviceResult: sessionStatusCode }
2531
+ });
2532
+ debugLog(chalk.red.bold(errMessage), chalk.yellow(sessionStatusCode.toString()), response.constructor.name);
2351
2533
  return sendResponse(response);
2352
2534
  }
2353
2535
 
@@ -2403,7 +2585,7 @@ export class OPCUAServer extends OPCUABaseServer {
2403
2585
  ): Promise<void> {
2404
2586
  assert(typeof actionToPerform === "function");
2405
2587
  const request = message.request as unknown as { subscriptionId: number };
2406
- assert(Object.prototype.hasOwnProperty.call(request, "subscriptionId"));
2588
+ assert(Object.hasOwn(request, "subscriptionId"));
2407
2589
 
2408
2590
  this._apply_on_SessionObject(
2409
2591
  ResponseClass,
@@ -2432,7 +2614,7 @@ export class OPCUAServer extends OPCUABaseServer {
2432
2614
  ): void {
2433
2615
  assert(typeof actionToPerform === "function");
2434
2616
  const request = message.request as unknown as { subscriptionIds: number[] };
2435
- assert(Object.prototype.hasOwnProperty.call(request, "subscriptionIds"));
2617
+ assert(Object.hasOwn(request, "subscriptionIds"));
2436
2618
 
2437
2619
  this._apply_on_SessionObject(
2438
2620
  ResponseClass,
@@ -2470,7 +2652,7 @@ export class OPCUAServer extends OPCUABaseServer {
2470
2652
  responseHeader: {
2471
2653
  serviceResult
2472
2654
  },
2473
- results: results as any
2655
+ results: results as unknown as StatusCode[]
2474
2656
  });
2475
2657
  sendResponse(response);
2476
2658
  }
@@ -2507,7 +2689,10 @@ export class OPCUAServer extends OPCUABaseServer {
2507
2689
  if (session) {
2508
2690
  const subscriptions = session.publishEngine.subscriptions;
2509
2691
  for (const subscription of subscriptions) {
2510
- await subscription.applyOnMonitoredItem(this.options.onDeleteMonitoredItem.bind(null, subscription) as any);
2692
+ const onDeleteFn = this.options.onDeleteMonitoredItem;
2693
+ await subscription.applyOnMonitoredItem(async (monitoredItem: MonitoredItem) => {
2694
+ await onDeleteFn(subscription, monitoredItem);
2695
+ });
2511
2696
  }
2512
2697
  }
2513
2698
  }
@@ -2522,8 +2707,6 @@ export class OPCUAServer extends OPCUABaseServer {
2522
2707
  const request = message.request as CloseSessionRequest;
2523
2708
  assert(request instanceof CloseSessionRequest);
2524
2709
 
2525
- let response;
2526
-
2527
2710
  message.session_statusCode = StatusCodes.Good;
2528
2711
 
2529
2712
  function sendError(statusCode: StatusCode) {
@@ -2540,11 +2723,12 @@ export class OPCUAServer extends OPCUABaseServer {
2540
2723
 
2541
2724
  const session = message.session;
2542
2725
  if (!session) {
2543
- return sendError(StatusCodes.BadSessionIdInvalid);
2726
+ sendError(StatusCodes.BadSessionIdInvalid);
2727
+ return;
2544
2728
  }
2545
2729
 
2546
2730
  // session has been created but not activated !
2547
- const wasNotActivated = session.status === "new";
2731
+ const _wasNotActivated = session.status === "new";
2548
2732
 
2549
2733
  (async () => {
2550
2734
  try {
@@ -2554,9 +2738,9 @@ export class OPCUAServer extends OPCUABaseServer {
2554
2738
  // return sendError(StatusCodes.BadSessionNotActivated);
2555
2739
  // }
2556
2740
 
2557
- response = new CloseSessionResponse({});
2741
+ const response = new CloseSessionResponse({});
2558
2742
  sendResponse(response);
2559
- } catch (err) {
2743
+ } catch (_err) {
2560
2744
  sendError(StatusCodes.BadInternalError);
2561
2745
  }
2562
2746
  })();
@@ -2571,7 +2755,7 @@ export class OPCUAServer extends OPCUABaseServer {
2571
2755
  protected _on_BrowseRequest(message: Message, channel: ServerSecureChannelLayer): void {
2572
2756
  const request = message.request as BrowseRequest;
2573
2757
  assert(request instanceof BrowseRequest);
2574
- const diagnostic: any = {};
2758
+ const diagnostic: Record<string, unknown> = {};
2575
2759
 
2576
2760
  this._apply_on_SessionObject(
2577
2761
  BrowseResponse,
@@ -2581,7 +2765,11 @@ export class OPCUAServer extends OPCUABaseServer {
2581
2765
  let response: BrowseResponse;
2582
2766
  // test view
2583
2767
  if (request.view && !request.view.viewId.isEmpty()) {
2584
- let theView: UAView | null = this.engine!.addressSpace!.findNode(request.view.viewId) as UAView;
2768
+ const addressSpace = this.engine.addressSpace;
2769
+ if (!addressSpace) {
2770
+ return sendError(StatusCodes.BadInternalError);
2771
+ }
2772
+ let theView: UAView | null = addressSpace.findNode(request.view.viewId) as UAView;
2585
2773
  if (theView && theView.nodeClass !== NodeClass.View) {
2586
2774
  // Error: theView is not a View
2587
2775
  diagnostic.localizedText = { text: "Expecting a view here" };
@@ -2607,9 +2795,9 @@ export class OPCUAServer extends OPCUABaseServer {
2607
2795
  assert(request.nodesToBrowse[0].schema.name === "BrowseDescription");
2608
2796
 
2609
2797
  const context = session.sessionContext;
2610
- const browseAll = (nodesToBrowse: BrowseDescriptionOptions[], callack: CallbackT<BrowseResult[]>) => {
2798
+ const browseAll = (_nodesToBrowse: BrowseDescriptionOptions[], callack: CallbackT<BrowseResult[]>) => {
2611
2799
  const f = callbackify(this.engine.browseWithAutomaticExpansion).bind(this.engine);
2612
- (f as any)(request.nodesToBrowse, context, callack);
2800
+ f(request.nodesToBrowse ?? [], context, callack);
2613
2801
  };
2614
2802
  // handle continuation point and requestedMaxReferencesPerNode
2615
2803
  const maxBrowseContinuationPoints = this.engine.serverCapabilities.maxBrowseContinuationPoints;
@@ -2623,7 +2811,7 @@ export class OPCUAServer extends OPCUABaseServer {
2623
2811
  maxBrowseContinuationPoints
2624
2812
  },
2625
2813
  request.nodesToBrowse,
2626
- (err, results) => {
2814
+ (_err, results) => {
2627
2815
  if (!results) {
2628
2816
  return sendError(StatusCodes.BadInternalError);
2629
2817
  }
@@ -2716,10 +2904,10 @@ export class OPCUAServer extends OPCUABaseServer {
2716
2904
  }
2717
2905
 
2718
2906
  // ask for a refresh of asynchronous variables
2719
- this.engine.refreshValues(request.nodesToRead, request.maxAge, (err?: Error | null) => {
2907
+ this.engine.refreshValues(request.nodesToRead, request.maxAge, (_err?: Error | null) => {
2720
2908
  this.engine.read(context, request).then((results) => {
2721
2909
  assert(results[0].schema.name === "DataValue");
2722
- assert(results.length === request.nodesToRead!.length);
2910
+ assert(results.length === request.nodesToRead?.length);
2723
2911
 
2724
2912
  const response = new ReadResponse({
2725
2913
  diagnosticInfos: undefined,
@@ -2727,7 +2915,7 @@ export class OPCUAServer extends OPCUABaseServer {
2727
2915
  });
2728
2916
  // set it here for performance
2729
2917
  response.results = results;
2730
- assert(response.diagnosticInfos!.length === 0);
2918
+ assert(response.diagnosticInfos?.length === 0);
2731
2919
  sendResponse(response);
2732
2920
  });
2733
2921
  });
@@ -2746,8 +2934,6 @@ export class OPCUAServer extends OPCUABaseServer {
2746
2934
  message,
2747
2935
  channel,
2748
2936
  (session: ServerSession, sendResponse: (response: Response) => void, sendError: (statsCode: StatusCode) => void) => {
2749
- let response;
2750
-
2751
2937
  const timestampsToReturn = request.timestampsToReturn;
2752
2938
 
2753
2939
  if (timestampsToReturn === TimestampsToReturn.Invalid) {
@@ -2790,17 +2976,17 @@ export class OPCUAServer extends OPCUABaseServer {
2790
2976
  .historyRead(context, request)
2791
2977
  .then((results: HistoryReadResult[]) => {
2792
2978
  assert(results[0].schema.name === "HistoryReadResult");
2793
- assert(results.length === request.nodesToRead!.length);
2979
+ assert(results.length === request.nodesToRead?.length);
2794
2980
 
2795
- response = new HistoryReadResponse({
2981
+ const response = new HistoryReadResponse({
2796
2982
  diagnosticInfos: undefined,
2797
2983
  results
2798
2984
  });
2799
2985
 
2800
- assert(response.diagnosticInfos!.length === 0);
2986
+ assert(response.diagnosticInfos?.length === 0);
2801
2987
  sendResponse(response);
2802
2988
  })
2803
- .catch((err) => {
2989
+ .catch((_err) => {
2804
2990
  return sendError(StatusCodes.BadHistoryOperationInvalid);
2805
2991
  });
2806
2992
  });
@@ -2832,8 +3018,6 @@ export class OPCUAServer extends OPCUABaseServer {
2832
3018
  message,
2833
3019
  channel,
2834
3020
  (session: ServerSession, sendResponse: (response: Response) => void, sendError: (statusCode: StatusCode) => void) => {
2835
- let response;
2836
-
2837
3021
  if (!request.nodesToWrite || request.nodesToWrite.length === 0) {
2838
3022
  return sendError(StatusCodes.BadNothingToDo);
2839
3023
  }
@@ -2856,8 +3040,8 @@ export class OPCUAServer extends OPCUABaseServer {
2856
3040
  this.engine
2857
3041
  .write(context, request.nodesToWrite)
2858
3042
  .then((results: StatusCode[]) => {
2859
- assert(results!.length === request.nodesToWrite!.length);
2860
- response = new WriteResponse({
3043
+ assert(results?.length === request.nodesToWrite?.length);
3044
+ const response = new WriteResponse({
2861
3045
  diagnosticInfos: undefined,
2862
3046
  results
2863
3047
  });
@@ -2874,8 +3058,11 @@ export class OPCUAServer extends OPCUABaseServer {
2874
3058
  // subscription services
2875
3059
  protected _on_CreateSubscriptionRequest(message: Message, channel: ServerSecureChannelLayer): void {
2876
3060
  const engine = this.engine;
2877
- const addressSpace = engine.addressSpace!;
2878
-
3061
+ const addressSpace = engine.addressSpace;
3062
+ if (!addressSpace) {
3063
+ g_sendError(channel, message, CreateSubscriptionResponse, StatusCodes.BadSessionClosed);
3064
+ return;
3065
+ }
2879
3066
  const request = message.request as CreateSubscriptionRequest;
2880
3067
  assert(request instanceof CreateSubscriptionRequest);
2881
3068
 
@@ -2965,7 +3152,11 @@ export class OPCUAServer extends OPCUABaseServer {
2965
3152
 
2966
3153
  protected _on_CreateMonitoredItemsRequest(message: Message, channel: ServerSecureChannelLayer): void {
2967
3154
  const engine = this.engine;
2968
- const addressSpace = engine.addressSpace!;
3155
+ const addressSpace = engine.addressSpace;
3156
+ if (!addressSpace) {
3157
+ g_sendError(channel, message, CreateMonitoredItemsResponse, StatusCodes.BadSessionClosed);
3158
+ return;
3159
+ }
2969
3160
 
2970
3161
  const request = message.request as CreateMonitoredItemsRequest;
2971
3162
  assert(request instanceof CreateMonitoredItemsRequest);
@@ -2975,7 +3166,7 @@ export class OPCUAServer extends OPCUABaseServer {
2975
3166
  message,
2976
3167
  channel,
2977
3168
  async (
2978
- session: ServerSession,
3169
+ _session: ServerSession,
2979
3170
  subscription: Subscription,
2980
3171
  sendResponse: (response: Response) => void,
2981
3172
  sendError: (statusCode: StatusCode) => void
@@ -3004,7 +3195,9 @@ export class OPCUAServer extends OPCUABaseServer {
3004
3195
  monitoredItemCreateRequest
3005
3196
  );
3006
3197
  if (monitoredItem) {
3007
- await options.onCreateMonitoredItem!(subscription, monitoredItem);
3198
+ if (options.onCreateMonitoredItem) {
3199
+ await options.onCreateMonitoredItem(subscription, monitoredItem);
3200
+ }
3008
3201
  subscription.postCreateMonitoredItem(monitoredItem, monitoredItemCreateRequest, createResult);
3009
3202
  }
3010
3203
  return createResult;
@@ -3042,10 +3235,10 @@ export class OPCUAServer extends OPCUABaseServer {
3042
3235
  message,
3043
3236
  channel,
3044
3237
  async (
3045
- session: ServerSession,
3238
+ _session: ServerSession,
3046
3239
  subscription: Subscription,
3047
3240
  sendResponse: (response: ModifySubscriptionResponse) => void,
3048
- sendError: (statusCode: StatusCode) => void
3241
+ _sendError: (statusCode: StatusCode) => void
3049
3242
  ) => {
3050
3243
  subscription.modify(request);
3051
3244
 
@@ -3069,7 +3262,7 @@ export class OPCUAServer extends OPCUABaseServer {
3069
3262
  message,
3070
3263
  channel,
3071
3264
  async (
3072
- session: ServerSession,
3265
+ _session: ServerSession,
3073
3266
  subscription: Subscription,
3074
3267
  sendResponse: (response: ModifyMonitoredItemsResponse) => void,
3075
3268
  sendError: (statusCode: StatusCode) => void
@@ -3096,7 +3289,9 @@ export class OPCUAServer extends OPCUABaseServer {
3096
3289
  const monitoredItemId = item.monitoredItemId;
3097
3290
  const monitoredItem = subscription.getMonitoredItem(monitoredItemId);
3098
3291
  if (!monitoredItem) {
3099
- return new MonitoredItemModifyResult({ statusCode: StatusCodes.BadMonitoredItemIdInvalid });
3292
+ return new MonitoredItemModifyResult({
3293
+ statusCode: StatusCodes.BadMonitoredItemIdInvalid
3294
+ });
3100
3295
  }
3101
3296
 
3102
3297
  // adjust samplingInterval if === -1
@@ -3124,7 +3319,7 @@ export class OPCUAServer extends OPCUABaseServer {
3124
3319
  PublishResponse,
3125
3320
  message,
3126
3321
  channel,
3127
- (session: ServerSession, sendResponse: (response: Response) => void, sendError: (statusCode: StatusCode) => void) => {
3322
+ (session: ServerSession, sendResponse: (response: Response) => void, _sendError: (statusCode: StatusCode) => void) => {
3128
3323
  assert(session);
3129
3324
  assert(session.publishEngine); // server.publishEngine doesn't exists, OPCUAServer has probably shut down already
3130
3325
  session.publishEngine._on_PublishRequest(request, (_request1, response) => {
@@ -3142,7 +3337,7 @@ export class OPCUAServer extends OPCUABaseServer {
3142
3337
  SetPublishingModeResponse,
3143
3338
  message,
3144
3339
  channel,
3145
- async (session: ServerSession, subscription: Subscription) => {
3340
+ async (_session: ServerSession, subscription: Subscription) => {
3146
3341
  return subscription.setPublishingMode(publishingEnabled);
3147
3342
  }
3148
3343
  );
@@ -3157,7 +3352,7 @@ export class OPCUAServer extends OPCUABaseServer {
3157
3352
  message,
3158
3353
  channel,
3159
3354
  async (
3160
- session: ServerSession,
3355
+ _session: ServerSession,
3161
3356
  subscription: Subscription,
3162
3357
  sendResponse: (response: Response) => void,
3163
3358
  sendError: (statusCode: StatusCode) => void
@@ -3209,7 +3404,7 @@ export class OPCUAServer extends OPCUABaseServer {
3209
3404
  message,
3210
3405
  channel,
3211
3406
  async (
3212
- session: ServerSession,
3407
+ _session: ServerSession,
3213
3408
  subscription: Subscription,
3214
3409
  sendResponse: (response: Response) => void,
3215
3410
  sendError: (statusCode: StatusCode) => void
@@ -3237,7 +3432,9 @@ export class OPCUAServer extends OPCUABaseServer {
3237
3432
  linksToRemove
3238
3433
  );
3239
3434
  if (statusCode.isNotGood()) {
3240
- const response = new ServiceFault({ responseHeader: { serviceResult: statusCode } });
3435
+ const response = new ServiceFault({
3436
+ responseHeader: { serviceResult: statusCode }
3437
+ });
3241
3438
  sendResponse(response);
3242
3439
  } else {
3243
3440
  const response = new SetTriggeringResponse({
@@ -3258,7 +3455,11 @@ export class OPCUAServer extends OPCUABaseServer {
3258
3455
  if (!this.options.onDeleteMonitoredItem) {
3259
3456
  return;
3260
3457
  }
3261
- await subscription.applyOnMonitoredItem(this.options.onDeleteMonitoredItem.bind(null, subscription) as any);
3458
+ const t = this.options.onDeleteMonitoredItem.bind(null, subscription);
3459
+ const functor = async (monitoredItem: MonitoredItem) => {
3460
+ await t(monitoredItem);
3461
+ };
3462
+ await subscription.applyOnMonitoredItem(functor);
3262
3463
  }
3263
3464
  protected _on_RepublishRequest(message: Message, channel: ServerSecureChannelLayer): void {
3264
3465
  const request = message.request as RepublishRequest;
@@ -3269,7 +3470,7 @@ export class OPCUAServer extends OPCUABaseServer {
3269
3470
  message,
3270
3471
  channel,
3271
3472
  async (
3272
- session: ServerSession,
3473
+ _session: ServerSession,
3273
3474
  subscription: Subscription,
3274
3475
  sendResponse: (response: Response) => void,
3275
3476
  sendError: (statusCode: StatusCode) => void
@@ -3311,7 +3512,7 @@ export class OPCUAServer extends OPCUABaseServer {
3311
3512
  message,
3312
3513
  channel,
3313
3514
  async (
3314
- session: ServerSession,
3515
+ _session: ServerSession,
3315
3516
  subscription: Subscription,
3316
3517
  sendResponse: (response: Response) => void,
3317
3518
  sendError: (statusCode: StatusCode) => void
@@ -3360,7 +3561,7 @@ export class OPCUAServer extends OPCUABaseServer {
3360
3561
  message,
3361
3562
  channel,
3362
3563
  async (
3363
- session: ServerSession,
3564
+ _session: ServerSession,
3364
3565
  sendResponse: (response: Response) => void,
3365
3566
  sendError: (statusCode: StatusCode) => void
3366
3567
  ) => {
@@ -3385,7 +3586,7 @@ export class OPCUAServer extends OPCUABaseServer {
3385
3586
  });
3386
3587
  sendResponse(response);
3387
3588
  })
3388
- .catch((err) => {
3589
+ .catch((_err) => {
3389
3590
  sendError(StatusCodes.BadInternalError);
3390
3591
  });
3391
3592
  }
@@ -3406,8 +3607,6 @@ export class OPCUAServer extends OPCUABaseServer {
3406
3607
  message,
3407
3608
  channel,
3408
3609
  (session: ServerSession, sendResponse: (response: Response) => void, sendError: (statusCode: StatusCode) => void) => {
3409
- let response;
3410
-
3411
3610
  if (!request.methodsToCall || request.methodsToCall.length === 0) {
3412
3611
  return sendError(StatusCodes.BadNothingToDo);
3413
3612
  }
@@ -3428,7 +3627,7 @@ export class OPCUAServer extends OPCUABaseServer {
3428
3627
  filterDiagnosticInfo(request.requestHeader.returnDiagnostics, response);
3429
3628
  sendResponse(response);
3430
3629
  })
3431
- .catch((err) => {
3630
+ .catch((_err) => {
3432
3631
  sendError(StatusCodes.BadInternalError);
3433
3632
  });
3434
3633
  }
@@ -3502,7 +3701,7 @@ export class OPCUAServer extends OPCUABaseServer {
3502
3701
 
3503
3702
  /* c8 ignore next */
3504
3703
  protected _on_Cancel(message: Message, channel: ServerSecureChannelLayer): void {
3505
- return g_sendError(channel, message, CancelResponse, StatusCodes.BadServiceUnsupported);
3704
+ g_sendError(channel, message, CancelResponse, StatusCodes.BadServiceUnsupported);
3506
3705
  }
3507
3706
 
3508
3707
  // NodeManagement Service Set Overview
@@ -3511,38 +3710,38 @@ export class OPCUAServer extends OPCUABaseServer {
3511
3710
  //
3512
3711
  /* c8 ignore next */
3513
3712
  protected _on_AddNodes(message: Message, channel: ServerSecureChannelLayer): void {
3514
- return g_sendError(channel, message, AddNodesResponse, StatusCodes.BadServiceUnsupported);
3713
+ g_sendError(channel, message, AddNodesResponse, StatusCodes.BadServiceUnsupported);
3515
3714
  }
3516
3715
 
3517
3716
  /* c8 ignore next */
3518
3717
  protected _on_AddReferences(message: Message, channel: ServerSecureChannelLayer): void {
3519
- return g_sendError(channel, message, AddReferencesResponse, StatusCodes.BadServiceUnsupported);
3718
+ g_sendError(channel, message, AddReferencesResponse, StatusCodes.BadServiceUnsupported);
3520
3719
  }
3521
3720
 
3522
3721
  /* c8 ignore next */
3523
3722
  protected _on_DeleteNodes(message: Message, channel: ServerSecureChannelLayer): void {
3524
- return g_sendError(channel, message, DeleteNodesResponse, StatusCodes.BadServiceUnsupported);
3723
+ g_sendError(channel, message, DeleteNodesResponse, StatusCodes.BadServiceUnsupported);
3525
3724
  }
3526
3725
 
3527
3726
  /* c8 ignore next */
3528
3727
  protected _on_DeleteReferences(message: Message, channel: ServerSecureChannelLayer): void {
3529
- return g_sendError(channel, message, DeleteReferencesResponse, StatusCodes.BadServiceUnsupported);
3728
+ g_sendError(channel, message, DeleteReferencesResponse, StatusCodes.BadServiceUnsupported);
3530
3729
  }
3531
3730
 
3532
3731
  // Query Service
3533
3732
  /* c8 ignore next */
3534
3733
  protected _on_QueryFirst(message: Message, channel: ServerSecureChannelLayer): void {
3535
- return g_sendError(channel, message, QueryFirstResponse, StatusCodes.BadServiceUnsupported);
3734
+ g_sendError(channel, message, QueryFirstResponse, StatusCodes.BadServiceUnsupported);
3536
3735
  }
3537
3736
 
3538
3737
  /* c8 ignore next */
3539
3738
  protected _on_QueryNext(message: Message, channel: ServerSecureChannelLayer): void {
3540
- return g_sendError(channel, message, QueryNextResponse, StatusCodes.BadServiceUnsupported);
3739
+ g_sendError(channel, message, QueryNextResponse, StatusCodes.BadServiceUnsupported);
3541
3740
  }
3542
3741
 
3543
3742
  /* c8 ignore next */
3544
3743
  protected _on_HistoryUpdate(message: Message, channel: ServerSecureChannelLayer): void {
3545
- return g_sendError(channel, message, HistoryUpdateResponse, StatusCodes.BadServiceUnsupported);
3744
+ g_sendError(channel, message, HistoryUpdateResponse, StatusCodes.BadServiceUnsupported);
3546
3745
  }
3547
3746
 
3548
3747
  private createEndpoint(
@@ -3588,8 +3787,8 @@ export class OPCUAServer extends OPCUABaseServer {
3588
3787
 
3589
3788
  /* c8 ignore next */
3590
3789
  if (
3591
- !Object.prototype.hasOwnProperty.call(endpointOptions, "port") ||
3592
- !isFinite(endpointOptions.port!) ||
3790
+ !Object.hasOwn(endpointOptions, "port") ||
3791
+ !Number.isFinite(endpointOptions.port) ||
3593
3792
  typeof endpointOptions.port !== "number"
3594
3793
  ) {
3595
3794
  throw new Error(
@@ -3602,10 +3801,9 @@ export class OPCUAServer extends OPCUABaseServer {
3602
3801
  const endPoint = this.createEndpoint(port, serverOption);
3603
3802
 
3604
3803
  endpointOptions.alternateHostname = endpointOptions.alternateHostname || [];
3605
- const alternateHostname =
3606
- endpointOptions.alternateHostname instanceof Array
3607
- ? endpointOptions.alternateHostname
3608
- : [endpointOptions.alternateHostname];
3804
+ const alternateHostname = Array.isArray(endpointOptions.alternateHostname)
3805
+ ? endpointOptions.alternateHostname
3806
+ : [endpointOptions.alternateHostname];
3609
3807
  const allowAnonymous = endpointOptions.allowAnonymous === undefined ? true : !!endpointOptions.allowAnonymous;
3610
3808
 
3611
3809
  endPoint.addStandardEndpointDescriptions({
@@ -3619,7 +3817,9 @@ export class OPCUAServer extends OPCUABaseServer {
3619
3817
 
3620
3818
  disableDiscovery: !!endpointOptions.disableDiscovery,
3621
3819
  // xx hostname,
3622
- resourcePath: serverOption.resourcePath || ""
3820
+ resourcePath: serverOption.resourcePath || "",
3821
+
3822
+ advertisedEndpoints: endpointOptions.advertisedEndpoints,
3623
3823
 
3624
3824
  // TODO userTokenTypes: endpointOptions.userTokenTypes || undefined,
3625
3825
 
@@ -3632,6 +3832,90 @@ export class OPCUAServer extends OPCUABaseServer {
3632
3832
  await super.initializeCM();
3633
3833
  await this.userCertificateManager.initialize();
3634
3834
  }
3835
+
3836
+ public on(event: "create_session", eventHandler: (session: ServerSession) => void): this;
3837
+
3838
+ public on(event: "session_activated", eventHandler: (session: ServerSession) => void): this;
3839
+
3840
+ public on(event: "session_closed", eventHandler: (session: ServerSession, reason: string) => void): this;
3841
+
3842
+ public on(event: "post_initialize", eventHandler: () => void): this;
3843
+
3844
+ /**
3845
+ * emitted when the server is trying to registered the LDS
3846
+ * but when the connection to the lds has failed
3847
+ * serverRegistrationPending is sent when the backoff signal of the
3848
+ * connection process is raised
3849
+ * @event serverRegistrationPending
3850
+ */
3851
+ public on(event: "serverRegistrationPending", eventHandler: () => void): this;
3852
+
3853
+ /**
3854
+ * event raised when server has been successfully registered on the local discovery server
3855
+ * @event serverRegistered
3856
+ */
3857
+ public on(event: "serverRegistered", eventHandler: () => void): this;
3858
+
3859
+ /**
3860
+ * event raised when server registration has been successfully renewed on the local discovery server
3861
+ * @event serverRegistered
3862
+ */
3863
+ public on(event: "serverRegistrationRenewed", eventHandler: () => void): this;
3864
+
3865
+ /**
3866
+ * event raised when server has been successfully unregistered from the local discovery server
3867
+ * @event serverUnregistered
3868
+ */
3869
+ public on(event: "serverUnregistered", eventHandler: () => void): this;
3870
+
3871
+ /**
3872
+ * event raised after the server has raised an OPCUA event toward a client
3873
+ */
3874
+ public on(event: "event", eventHandler: (eventData: unknown) => void): this;
3875
+
3876
+ /**
3877
+ * event raised when the server received a request from one of its connected client.
3878
+ * useful for trace purpose.
3879
+ */
3880
+ public on(event: "request", eventHandler: (request: Request, channel: ServerSecureChannelLayer) => void): this;
3881
+
3882
+ /**
3883
+ * event raised when the server send an response to a request to one of its connected client.
3884
+ * useful for trace purpose.
3885
+ */
3886
+ public on(event: "response", eventHandler: (request: Response, channel: ServerSecureChannelLayer) => void): this;
3887
+
3888
+ /**
3889
+ * event raised when a new secure channel is opened
3890
+ */
3891
+ public on(event: "newChannel", eventHandler: (channel: ServerSecureChannelLayer, endpoint: OPCUAServerEndPoint) => void): this;
3892
+
3893
+ /**
3894
+ * event raised when a new secure channel is closed
3895
+ */
3896
+ public on(
3897
+ event: "closeChannel",
3898
+ eventHandler: (channel: ServerSecureChannelLayer, endpoint: OPCUAServerEndPoint) => void
3899
+ ): this;
3900
+
3901
+ /**
3902
+ * event raised when the server refused a tcp connection from a client. ( for instance because too any connections)
3903
+ */
3904
+ public on(event: "connectionRefused", eventHandler: (socketData: ISocketData, endpoint: OPCUAServerEndPoint) => void): this;
3905
+
3906
+ /**
3907
+ * event raised when a OpenSecureChannel has failed, it could be a invalid certificate or malformed message
3908
+ */
3909
+ public on(
3910
+ event: "openSecureChannelFailure",
3911
+ eventHandler: (socketData: ISocketData, channelData: IChannelData, endpoint: OPCUAServerEndPoint) => void
3912
+ ): this;
3913
+
3914
+ public on(event: string, eventHandler: (...args: unknown[]) => void): this;
3915
+ // biome-ignore lint/suspicious/noExplicitAny: must match EventEmitter.on() signature
3916
+ public on(event: string, eventHandler: (...args: any[]) => void): this {
3917
+ return super.on(event, eventHandler);
3918
+ }
3635
3919
  }
3636
3920
 
3637
3921
  const userIdentityTokenPasswordRemoved = (userIdentityToken?: UserIdentityToken): UserIdentityToken => {
@@ -3688,7 +3972,10 @@ function raiseAuditActivateSessionEventType(this: OPCUAServer, session: ServerSe
3688
3972
  // use the same identifier in all AuditEvents related to the Session Service Set
3689
3973
  // (AuditCreateSessionEventType, AuditActivateSessionEventType and their subtypes) and
3690
3974
  // the SecureChannel Service Set (AuditChannelEventType and its subtypes).
3691
- secureChannelId: { dataType: "String", value: session.channel!.channelId!.toString() }
3975
+ secureChannelId: {
3976
+ dataType: "String",
3977
+ value: session.channel?.channelId?.toString() ?? ""
3978
+ }
3692
3979
  });
3693
3980
  }
3694
3981
  }
@@ -3711,7 +3998,7 @@ export interface RaiseEventAuditEventData extends RaiseEventData {
3711
3998
 
3712
3999
  export interface RaiseEventAuditUpdateMethodEventData extends RaiseEventAuditEventData {
3713
4000
  methodId: PseudoVariantNodeId;
3714
- inputArguments: any;
4001
+ inputArguments: PseudoVariant | Variant | UAEventType | undefined;
3715
4002
  }
3716
4003
 
3717
4004
  export interface RaiseEventAuditConditionCommentEventData extends RaiseEventAuditUpdateMethodEventData {
@@ -3727,6 +4014,7 @@ export interface RaiseEventAuditSessionEventData extends RaiseEventAuditEventDat
3727
4014
  }
3728
4015
 
3729
4016
  export interface RaiseEventAuditCreateSessionEventData extends RaiseEventAuditSessionEventData {
4017
+ sessionId: PseudoVariantNodeId;
3730
4018
  /**
3731
4019
  * part 5 - 6.4.8 AuditCreateSessionEventType
3732
4020
  * SecureChannelId shall uniquely identify the SecureChannel.
@@ -3846,115 +4134,7 @@ export interface RaiseAuditCertificateRevokedEventData extends RaiseAuditCertifi
3846
4134
  * There are no additional Properties defined for this EventType
3847
4135
  */
3848
4136
  export interface RaiseAuditCertificateMismatchEventData extends RaiseAuditCertificateEventData { }
3849
- export interface OPCUAServer {
3850
- /**
3851
- * @internal
3852
- * @param eventType
3853
- * @param options
3854
- */
3855
- raiseEvent(eventType: "AuditSessionEventType", options: RaiseEventAuditSessionEventData): void;
3856
-
3857
- raiseEvent(eventType: "AuditCreateSessionEventType", options: RaiseEventAuditCreateSessionEventData): void;
3858
-
3859
- raiseEvent(eventType: "AuditActivateSessionEventType", options: RaiseEventAuditActivateSessionEventData): void;
3860
-
3861
- raiseEvent(eventType: "AuditCreateSessionEventType", options: RaiseEventData): void;
3862
-
3863
- raiseEvent(eventType: "AuditConditionCommentEventType", options: RaiseEventAuditConditionCommentEventData): void;
3864
-
3865
- raiseEvent(eventType: "AuditUrlMismatchEventType", options: RaiseEventAuditUrlMismatchEventTypeData): void;
3866
-
3867
- raiseEvent(eventType: "TransitionEventType", options: RaiseEventTransitionEventData): void;
3868
-
3869
- raiseEvent(eventType: "AuditCertificateInvalidEventType", options: RaiseAuditCertificateInvalidEventData): void;
3870
- raiseEvent(eventType: "AuditCertificateExpiredEventType", options: RaiseAuditCertificateExpiredEventData): void;
3871
- raiseEvent(eventType: "AuditCertificateUntrustedEventType", options: RaiseAuditCertificateUntrustedEventData): void;
3872
- raiseEvent(eventType: "AuditCertificateRevokedEventType", options: RaiseAuditCertificateRevokedEventData): void;
3873
- raiseEvent(eventType: "AuditCertificateMismatchEventType", options: RaiseAuditCertificateMismatchEventData): void;
3874
- raiseEvent(eventType: UAEventType, options: RaiseEventData): void;
3875
- }
3876
-
3877
- // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
3878
- export interface OPCUAServer extends EventEmitter {
3879
- on(event: "create_session", eventHandler: (session: ServerSession) => void): this;
3880
-
3881
- on(event: "session_activated", eventHandler: (session: ServerSession) => void): this;
3882
-
3883
- on(event: "session_closed", eventHandler: (session: ServerSession, reason: string) => void): this;
3884
-
3885
- on(event: "post_initialize", eventHandler: () => void): this;
3886
-
3887
- /**
3888
- * emitted when the server is trying to registered the LDS
3889
- * but when the connection to the lds has failed
3890
- * serverRegistrationPending is sent when the backoff signal of the
3891
- * connection process is raised
3892
- * @event serverRegistrationPending
3893
- */
3894
- on(event: "serverRegistrationPending", eventHandler: () => void): this;
3895
-
3896
- /**
3897
- * event raised when server has been successfully registered on the local discovery server
3898
- * @event serverRegistered
3899
- */
3900
- on(event: "serverRegistered", eventHandler: () => void): this;
3901
-
3902
- /**
3903
- * event raised when server registration has been successfully renewed on the local discovery server
3904
- * @event serverRegistered
3905
- */
3906
- on(event: "serverRegistrationRenewed", eventHandler: () => void): this;
3907
-
3908
- /**
3909
- * event raised when server has been successfully unregistered from the local discovery server
3910
- * @event serverUnregistered
3911
- */
3912
- on(event: "serverUnregistered", eventHandler: () => void): this;
3913
-
3914
- /**
3915
- * event raised after the server has raised an OPCUA event toward a client
3916
- */
3917
- on(event: "event", eventHandler: (eventData: any) => void): this;
3918
-
3919
- /**
3920
- * event raised when the server received a request from one of its connected client.
3921
- * useful for trace purpose.
3922
- */
3923
- on(event: "request", eventHandler: (request: Request, channel: ServerSecureChannelLayer) => void): this;
3924
-
3925
- /**
3926
- * event raised when the server send an response to a request to one of its connected client.
3927
- * useful for trace purpose.
3928
- */
3929
- on(event: "response", eventHandler: (request: Response, channel: ServerSecureChannelLayer) => void): this;
3930
-
3931
- /**
3932
- * event raised when a new secure channel is opened
3933
- */
3934
- on(event: "newChannel", eventHandler: (channel: ServerSecureChannelLayer, endpoint: OPCUAServerEndPoint) => void): this;
3935
-
3936
- /**
3937
- * event raised when a new secure channel is closed
3938
- */
3939
- on(event: "closeChannel", eventHandler: (channel: ServerSecureChannelLayer, endpoint: OPCUAServerEndPoint) => void): this;
3940
-
3941
- /**
3942
- * event raised when the server refused a tcp connection from a client. ( for instance because too any connections)
3943
- */
3944
- on(event: "connectionRefused", eventHandler: (socketData: ISocketData, endpoint: OPCUAServerEndPoint) => void): this;
3945
-
3946
- /**
3947
- * event raised when a OpenSecureChannel has failed, it could be a invalid certificate or malformed message
3948
- */
3949
- on(
3950
- event: "openSecureChannelFailure",
3951
- eventHandler: (socketData: ISocketData, channelData: IChannelData, endpoint: OPCUAServerEndPoint) => void
3952
- ): this;
3953
-
3954
- on(event: string, eventHandler: (...args: [any?, ...any[]]) => void): this;
3955
- }
3956
4137
 
3957
4138
  const opts = { multiArgs: false };
3958
- OPCUAServer.prototype.start = withCallback(OPCUAServer.prototype.start, opts);
3959
4139
  OPCUAServer.prototype.initialize = withCallback(OPCUAServer.prototype.initialize, opts);
3960
4140
  OPCUAServer.prototype.shutdown = withCallback(OPCUAServer.prototype.shutdown, opts);