node-opcua-server 2.77.0 → 2.79.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.
@@ -271,15 +271,14 @@ function monitoredItem_read_and_record_value_async(self, context, oldValue, node
271
271
  callback(err, dataValue);
272
272
  });
273
273
  }
274
- function build_scanning_node_function(context, addressSpace, monitoredItem, itemToMonitor) {
275
- (0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
274
+ function build_scanning_node_function(addressSpace, itemToMonitor) {
276
275
  (0, node_opcua_assert_1.assert)(itemToMonitor instanceof node_opcua_service_read_1.ReadValueId);
277
276
  const node = addressSpace.findNode(itemToMonitor.nodeId);
278
277
  /* istanbul ignore next */
279
278
  if (!node) {
280
279
  errorLog(" INVALID NODE ID , ", itemToMonitor.nodeId.toString());
281
280
  (0, node_opcua_debug_1.dump)(itemToMonitor);
282
- return (oldData, callback) => {
281
+ return (_sessionContext, _oldData, callback) => {
283
282
  callback(null, new node_opcua_data_value_1.DataValue({
284
283
  statusCode: node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown,
285
284
  value: { dataType: node_opcua_variant_1.DataType.Null, value: 0 }
@@ -291,11 +290,11 @@ function build_scanning_node_function(context, addressSpace, monitoredItem, item
291
290
  const monitoredItem_read_and_record_value_func = itemToMonitor.attributeId === node_opcua_data_model_1.AttributeIds.Value && typeof node.readValueAsync === "function"
292
291
  ? monitoredItem_read_and_record_value_async
293
292
  : monitoredItem_read_and_record_value;
294
- return function func(oldDataValue, callback) {
293
+ return function func(sessionContext, oldDataValue, callback) {
295
294
  (0, node_opcua_assert_1.assert)(this instanceof monitored_item_1.MonitoredItem);
296
295
  (0, node_opcua_assert_1.assert)(oldDataValue instanceof node_opcua_data_value_1.DataValue);
297
296
  (0, node_opcua_assert_1.assert)(typeof callback === "function");
298
- monitoredItem_read_and_record_value_func(this, context, oldDataValue, node, itemToMonitor, callback);
297
+ monitoredItem_read_and_record_value_func(this, sessionContext, oldDataValue, node, itemToMonitor, callback);
299
298
  };
300
299
  }
301
300
  else {
@@ -303,18 +302,18 @@ function build_scanning_node_function(context, addressSpace, monitoredItem, item
303
302
  // The filter is not used for these Attributes. Any change in value for these Attributes
304
303
  // causes a Notification to be generated.
305
304
  // only record value when it has changed
306
- return function func(oldDataValue, callback) {
305
+ return function func(sessionContext, oldDataValue, callback) {
307
306
  (0, node_opcua_assert_1.assert)(this instanceof monitored_item_1.MonitoredItem);
308
307
  (0, node_opcua_assert_1.assert)(oldDataValue instanceof node_opcua_data_value_1.DataValue);
309
308
  (0, node_opcua_assert_1.assert)(typeof callback === "function");
310
- const newDataValue = node.readAttribute(null, itemToMonitor.attributeId);
309
+ const newDataValue = node.readAttribute(sessionContext, itemToMonitor.attributeId);
311
310
  callback(null, newDataValue);
312
311
  };
313
312
  }
314
313
  }
315
314
  function prepareMonitoredItem(context, addressSpace, monitoredItem) {
316
315
  const itemToMonitor = monitoredItem.itemToMonitor;
317
- const readNodeFunc = build_scanning_node_function(context, addressSpace, monitoredItem, itemToMonitor);
316
+ const readNodeFunc = build_scanning_node_function(addressSpace, itemToMonitor);
318
317
  monitoredItem.samplingFunc = readNodeFunc;
319
318
  }
320
319
  function isMonitoringModeValid(monitoringMode) {
@@ -989,7 +988,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
989
988
  return;
990
989
  }
991
990
  const length = buff.readUInt32LE(0) - serverNonce.length;
992
- password = buff.slice(4, 4 + length).toString("utf-8");
991
+ password = buff.subarray(4, 4 + length).toString("utf-8");
993
992
  }
994
993
  this.userManager
995
994
  .isValidUser(session, userName, password)
@@ -1114,7 +1113,8 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1114
1113
  // see Release 1.02 27 OPC Unified Architecture, Part 4
1115
1114
  const session = this.createSession({
1116
1115
  clientDescription: request.clientDescription,
1117
- sessionTimeout: revisedSessionTimeout
1116
+ sessionTimeout: revisedSessionTimeout,
1117
+ server: this
1118
1118
  });
1119
1119
  session.endpoint = endpoint;
1120
1120
  (0, node_opcua_assert_1.assert)(session);
@@ -1325,7 +1325,6 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1325
1325
  return rejectConnection(this, node_opcua_status_code_1.StatusCodes.BadIdentityChangeNotSupported); // not sure about this code !
1326
1326
  }
1327
1327
  }
1328
- moveSessionToChannel(session, channel);
1329
1328
  }
1330
1329
  else if (session.status === "screwed") {
1331
1330
  // session has been used before being activated => this should be detected and session should be dismissed.
@@ -1350,7 +1349,6 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1350
1349
  }
1351
1350
  return rejectConnection(this, statusCode);
1352
1351
  }
1353
- session.userIdentityToken = request.userIdentityToken;
1354
1352
  // check if user access is granted
1355
1353
  this.isUserAuthorized(channel, session, request.userIdentityToken, (err1, authorized) => {
1356
1354
  /* istanbul ignore next */
@@ -1361,6 +1359,10 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1361
1359
  return rejectConnection(this, node_opcua_status_code_1.StatusCodes.BadUserAccessDenied);
1362
1360
  }
1363
1361
  else {
1362
+ if (session.status === "active") {
1363
+ moveSessionToChannel(session, channel);
1364
+ }
1365
+ session.userIdentityToken = request.userIdentityToken;
1364
1366
  // extract : OPC UA part 4 - 5.6.3
1365
1367
  // Once used, a serverNonce cannot be used again. For that reason, the Server returns a new
1366
1368
  // serverNonce each time the ActivateSession Service is called.
@@ -1368,12 +1370,6 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1368
1370
  session.status = "active";
1369
1371
  response = new node_opcua_service_session_1.ActivateSessionResponse({ serverNonce: session.nonce });
1370
1372
  channel.send_response("MSG", response, message);
1371
- const userIdentityTokenPasswordRemoved = (userIdentityToken) => {
1372
- const a = userIdentityToken.clone();
1373
- // remove password
1374
- a.password = "*************";
1375
- return a;
1376
- };
1377
1373
  // send OPCUA Event Notification
1378
1374
  // see part 5 : 6.4.3 AuditEventType
1379
1375
  // 6.4.7 AuditSessionEventType
@@ -1381,42 +1377,9 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1381
1377
  (0, node_opcua_assert_1.assert)(session.nodeId); // sessionId
1382
1378
  // xx assert(session.channel.clientCertificate instanceof Buffer);
1383
1379
  (0, node_opcua_assert_1.assert)(session.sessionTimeout > 0);
1384
- if (this.isAuditing) {
1385
- this.raiseEvent("AuditActivateSessionEventType", {
1386
- /* part 5 - 6.4.3 AuditEventType */
1387
- actionTimeStamp: { dataType: "DateTime", value: new Date() },
1388
- status: { dataType: "Boolean", value: true },
1389
- serverId: { dataType: "String", value: "" },
1390
- // ClientAuditEntryId contains the human-readable AuditEntryId defined in Part 3.
1391
- clientAuditEntryId: { dataType: "String", value: "" },
1392
- // The ClientUserId identifies the user of the client requesting an action.
1393
- // The ClientUserId can be obtained from the UserIdentityToken passed in the
1394
- // ActivateSession call.
1395
- clientUserId: { dataType: "String", value: "cc" },
1396
- sourceName: { dataType: "String", value: "Session/ActivateSession" },
1397
- /* part 5 - 6.4.7 AuditSessionEventType */
1398
- sessionId: { dataType: "NodeId", value: session.nodeId },
1399
- /* part 5 - 6.4.10 AuditActivateSessionEventType */
1400
- clientSoftwareCertificates: {
1401
- arrayType: node_opcua_variant_2.VariantArrayType.Array,
1402
- dataType: "ExtensionObject" /* SignedSoftwareCertificate */,
1403
- value: []
1404
- },
1405
- // UserIdentityToken reflects the userIdentityToken parameter of the ActivateSession
1406
- // Service call.
1407
- // For Username/Password tokens the password should NOT be included.
1408
- userIdentityToken: {
1409
- dataType: "ExtensionObject" /* UserIdentityToken */,
1410
- value: userIdentityTokenPasswordRemoved(session.userIdentityToken)
1411
- },
1412
- // SecureChannelId shall uniquely identify the SecureChannel. The application shall
1413
- // use the same identifier in all AuditEvents related to the Session Service Set
1414
- // (AuditCreateSessionEventType, AuditActivateSessionEventType and their subtypes) and
1415
- // the SecureChannel Service Set (AuditChannelEventType and its subtypes).
1416
- secureChannelId: { dataType: "String", value: session.channel.channelId.toString() }
1417
- });
1418
- }
1419
- this.emit("session_activated", session, userIdentityTokenPasswordRemoved);
1380
+ raiseAuditActivateSessionEventType.call(this, session);
1381
+ this.emit("session_activated", session, userIdentityTokenPasswordRemoved(session.userIdentityToken));
1382
+ session.resendMonitoredItemInitialValues();
1420
1383
  }
1421
1384
  });
1422
1385
  });
@@ -1672,7 +1635,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1672
1635
  // limit results to requestedMaxReferencesPerNode further so it never exceed a too big number
1673
1636
  const requestedMaxReferencesPerNode = Math.min(9876, request.requestedMaxReferencesPerNode);
1674
1637
  (0, node_opcua_assert_1.assert)(request.nodesToBrowse[0].schema.name === "BrowseDescription");
1675
- const context = new node_opcua_address_space_1.SessionContext({ session, server: this });
1638
+ const context = session.sessionContext;
1676
1639
  const f = (0, util_1.callbackify)(this.engine.browseWithAutomaticExpansion).bind(this.engine);
1677
1640
  f(request.nodesToBrowse, context, (err, results) => {
1678
1641
  // istanbul ignore next
@@ -1745,7 +1708,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1745
1708
  const request = message.request;
1746
1709
  (0, node_opcua_assert_1.assert)(request instanceof node_opcua_service_read_1.ReadRequest);
1747
1710
  this._apply_on_SessionObject(node_opcua_service_read_1.ReadResponse, message, channel, (session, sendResponse, sendError) => {
1748
- const context = new node_opcua_address_space_1.SessionContext({ session, server: this });
1711
+ const context = session.sessionContext;
1749
1712
  let response;
1750
1713
  let results = [];
1751
1714
  const timestampsToReturn = request.timestampsToReturn;
@@ -1819,7 +1782,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1819
1782
  return sendError(node_opcua_status_code_1.StatusCodes.BadTooManyOperations);
1820
1783
  }
1821
1784
  }
1822
- const context = new node_opcua_address_space_1.SessionContext({ session, server: this });
1785
+ const context = session.sessionContext;
1823
1786
  // ask for a refresh of asynchronous variables
1824
1787
  this.engine.refreshValues(request.nodesToRead, 0, (err) => {
1825
1788
  (0, node_opcua_assert_1.assert)(!err, " error not handled here , fix me"); // TODO
@@ -1874,7 +1837,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1874
1837
  for (const nodeToWrite of request.nodesToWrite) {
1875
1838
  nodeToWrite.nodeId = session.resolveRegisteredNode(nodeToWrite.nodeId);
1876
1839
  }
1877
- const context = new node_opcua_address_space_1.SessionContext({ session, server: this });
1840
+ const context = session.sessionContext;
1878
1841
  (0, node_opcua_assert_1.assert)(request.nodesToWrite[0].schema.name === "WriteValue");
1879
1842
  this.engine.write(context, request.nodesToWrite, (err, results) => {
1880
1843
  if (err) {
@@ -1898,7 +1861,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
1898
1861
  const request = message.request;
1899
1862
  (0, node_opcua_assert_1.assert)(request instanceof node_opcua_service_subscription_1.CreateSubscriptionRequest);
1900
1863
  this._apply_on_SessionObject(node_opcua_service_subscription_1.CreateSubscriptionResponse, message, channel, (session, sendResponse, sendError) => {
1901
- const context = new node_opcua_address_space_1.SessionContext({ session, server: this });
1864
+ const context = session.sessionContext;
1902
1865
  if (session.currentSubscriptionCount >= this.engine.serverCapabilities.maxSubscriptionsPerSession) {
1903
1866
  return sendError(node_opcua_status_code_1.StatusCodes.BadTooManySubscriptions);
1904
1867
  }
@@ -2253,7 +2216,7 @@ class OPCUAServer extends base_server_1.OPCUABaseServer {
2253
2216
  }
2254
2217
  /* jshint validthis: true */
2255
2218
  const addressSpace = this.engine.addressSpace;
2256
- const context = new node_opcua_address_space_1.SessionContext({ session, server: this });
2219
+ const context = session.sessionContext;
2257
2220
  async.map(request.methodsToCall, node_opcua_address_space_1.callMethodHelper.bind(null, context, addressSpace), (err, results) => {
2258
2221
  /* istanbul ignore next */
2259
2222
  if (err) {
@@ -2425,6 +2388,49 @@ OPCUAServer.fallbackSessionName = "Client didn't provide a meaningful sessionNam
2425
2388
  * @deprecated
2426
2389
  */
2427
2390
  OPCUAServer.deprectated_MAX_SUBSCRIPTION = 50;
2391
+ const userIdentityTokenPasswordRemoved = (userIdentityToken) => {
2392
+ const a = userIdentityToken.clone();
2393
+ // remove password
2394
+ a.password = "*************";
2395
+ return a;
2396
+ };
2397
+ function raiseAuditActivateSessionEventType(session) {
2398
+ if (this.isAuditing) {
2399
+ this.raiseEvent("AuditActivateSessionEventType", {
2400
+ /* part 5 - 6.4.3 AuditEventType */
2401
+ actionTimeStamp: { dataType: "DateTime", value: new Date() },
2402
+ status: { dataType: "Boolean", value: true },
2403
+ serverId: { dataType: "String", value: "" },
2404
+ // ClientAuditEntryId contains the human-readable AuditEntryId defined in Part 3.
2405
+ clientAuditEntryId: { dataType: "String", value: "" },
2406
+ // The ClientUserId identifies the user of the client requesting an action.
2407
+ // The ClientUserId can be obtained from the UserIdentityToken passed in the
2408
+ // ActivateSession call.
2409
+ clientUserId: { dataType: "String", value: "cc" },
2410
+ sourceName: { dataType: "String", value: "Session/ActivateSession" },
2411
+ /* part 5 - 6.4.7 AuditSessionEventType */
2412
+ sessionId: { dataType: "NodeId", value: session.nodeId },
2413
+ /* part 5 - 6.4.10 AuditActivateSessionEventType */
2414
+ clientSoftwareCertificates: {
2415
+ arrayType: node_opcua_variant_2.VariantArrayType.Array,
2416
+ dataType: "ExtensionObject" /* SignedSoftwareCertificate */,
2417
+ value: []
2418
+ },
2419
+ // UserIdentityToken reflects the userIdentityToken parameter of the ActivateSession
2420
+ // Service call.
2421
+ // For Username/Password tokens the password should NOT be included.
2422
+ userIdentityToken: {
2423
+ dataType: "ExtensionObject" /* UserIdentityToken */,
2424
+ value: userIdentityTokenPasswordRemoved(session.userIdentityToken)
2425
+ },
2426
+ // SecureChannelId shall uniquely identify the SecureChannel. The application shall
2427
+ // use the same identifier in all AuditEvents related to the Session Service Set
2428
+ // (AuditCreateSessionEventType, AuditActivateSessionEventType and their subtypes) and
2429
+ // the SecureChannel Service Set (AuditChannelEventType and its subtypes).
2430
+ secureChannelId: { dataType: "String", value: session.channel.channelId.toString() }
2431
+ });
2432
+ }
2433
+ }
2428
2434
  const opts = { multiArgs: false };
2429
2435
  OPCUAServer.prototype.start = thenify.withCallback(OPCUAServer.prototype.start, opts);
2430
2436
  OPCUAServer.prototype.initialize = thenify.withCallback(OPCUAServer.prototype.initialize, opts);