node-opcua-server 2.78.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.
- package/dist/base_server.js +0 -11
- package/dist/base_server.js.map +1 -1
- package/dist/monitored_item.d.ts +8 -2
- package/dist/monitored_item.js +24 -6
- package/dist/monitored_item.js.map +1 -1
- package/dist/node_sampler.js.map +1 -1
- package/dist/opcua_server.js +66 -60
- package/dist/opcua_server.js.map +1 -1
- package/dist/sampling_func.d.ts +3 -0
- package/dist/sampling_func.js +3 -0
- package/dist/sampling_func.js.map +1 -0
- package/dist/server_engine.d.ts +2 -1
- package/dist/server_engine.js +2 -1
- package/dist/server_engine.js.map +1 -1
- package/dist/server_session.d.ts +5 -2
- package/dist/server_session.js +22 -2
- package/dist/server_session.js.map +1 -1
- package/dist/server_subscription.js +1 -1
- package/dist/server_subscription.js.map +1 -1
- package/dist/user_manager.js +27 -3
- package/dist/user_manager.js.map +1 -1
- package/package.json +34 -34
- package/source/base_server.ts +0 -11
- package/source/monitored_item.ts +36 -13
- package/source/node_sampler.ts +5 -2
- package/source/opcua_server.ts +84 -74
- package/source/sampling_func.ts +8 -0
- package/source/server_engine.ts +5 -2
- package/source/server_session.ts +18 -4
- package/source/server_subscription.ts +1 -1
- package/source/user_manager.ts +28 -4
package/dist/opcua_server.js
CHANGED
|
@@ -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(
|
|
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 (
|
|
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,
|
|
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(
|
|
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(
|
|
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.
|
|
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
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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);
|