node-opcua-address-space 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.
- package/dist/source/loader/load_nodeset2.d.ts +6 -4
- package/dist/source/loader/load_nodeset2.js +100 -59
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/session_context.d.ts +24 -0
- package/dist/source/session_context.js +34 -0
- package/dist/source/session_context.js.map +1 -1
- package/dist/src/address_space.d.ts +13 -1
- package/dist/src/address_space.js +20 -0
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/address_space_private.d.ts +2 -1
- package/dist/src/base_node_impl.d.ts +17 -17
- package/dist/src/base_node_impl.js +78 -58
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/ua_data_type_impl.d.ts +7 -11
- package/dist/src/ua_data_type_impl.js +30 -26
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_method_impl.js +71 -28
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.js +54 -2
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
- package/dist/tsconfig_base.tsbuildinfo +1 -1
- package/package.json +34 -34
- package/source/loader/load_nodeset2.ts +118 -95
- package/source/session_context.ts +52 -2
- package/src/address_space.ts +24 -1
- package/src/address_space_private.ts +4 -1
- package/src/base_node_impl.ts +142 -135
- package/src/ua_data_type_impl.ts +52 -81
- package/src/ua_method_impl.ts +82 -39
- package/src/ua_variable_impl_ext_obj.ts +46 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { assert } from "node-opcua-assert";
|
|
6
|
-
import { CertificateInternals, exploreCertificate } from "node-opcua-crypto/web";
|
|
6
|
+
import { Certificate, CertificateInternals, exploreCertificate } from "node-opcua-crypto/web";
|
|
7
7
|
import { AccessRestrictionsFlag, allPermissions, AttributeIds, PermissionFlag } from "node-opcua-data-model";
|
|
8
8
|
import { PreciseClock } from "node-opcua-date-time";
|
|
9
9
|
import { NodeId, NodeIdLike, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
|
|
@@ -99,8 +99,22 @@ export interface IUserManager {
|
|
|
99
99
|
*/
|
|
100
100
|
getUserRoles?: (user: string) => NodeId[];
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* A temporary override for role resolution.
|
|
105
|
+
*
|
|
106
|
+
* When set on the server, `getUserRoles` is called
|
|
107
|
+
* **before** the default `userManager`. Returning
|
|
108
|
+
* a `NodeId[]` overrides the roles; returning `null`
|
|
109
|
+
* falls through to the default resolution.
|
|
110
|
+
*/
|
|
111
|
+
export interface IRolePolicyOverride {
|
|
112
|
+
getUserRoles(username: string): NodeId[] | null;
|
|
113
|
+
}
|
|
114
|
+
|
|
102
115
|
export interface IServerBase {
|
|
103
116
|
userManager?: IUserManager;
|
|
117
|
+
rolePolicyOverride?: IRolePolicyOverride | null;
|
|
104
118
|
}
|
|
105
119
|
|
|
106
120
|
export interface SessionContextOptions {
|
|
@@ -206,6 +220,33 @@ export class SessionContext implements ISessionContext {
|
|
|
206
220
|
this.currentTime = undefined;
|
|
207
221
|
}
|
|
208
222
|
|
|
223
|
+
/**
|
|
224
|
+
* The client's application-instance certificate,
|
|
225
|
+
* or `null` if no secure channel is available.
|
|
226
|
+
*/
|
|
227
|
+
public get clientCertificate(): Certificate | null {
|
|
228
|
+
return this.session?.channel?.clientCertificate ?? null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* The application URI extracted from the client
|
|
233
|
+
* certificate's SubjectAltName, or `null` if
|
|
234
|
+
* no certificate is available.
|
|
235
|
+
*/
|
|
236
|
+
public get clientApplicationUri(): string | null {
|
|
237
|
+
const cert = this.clientCertificate;
|
|
238
|
+
if (!cert) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
const info = exploreCertificate(cert);
|
|
243
|
+
const san = info.tbsCertificate.extensions?.subjectAltName;
|
|
244
|
+
return san?.uniformResourceIdentifier?.[0] ?? null;
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
209
250
|
/**
|
|
210
251
|
* getCurrentUserRoles
|
|
211
252
|
*
|
|
@@ -228,6 +269,15 @@ export class SessionContext implements ISessionContext {
|
|
|
228
269
|
|
|
229
270
|
const username = getUserName(userIdentityToken);
|
|
230
271
|
|
|
272
|
+
// --- US-028: check role policy override first ---
|
|
273
|
+
if (this.server?.rolePolicyOverride) {
|
|
274
|
+
const overriddenRoles = this.server.rolePolicyOverride.getUserRoles(username);
|
|
275
|
+
if (overriddenRoles !== null) {
|
|
276
|
+
return overriddenRoles;
|
|
277
|
+
}
|
|
278
|
+
// null => fall through to default resolution
|
|
279
|
+
}
|
|
280
|
+
|
|
231
281
|
if (username === "anonymous") {
|
|
232
282
|
return anonymous;
|
|
233
283
|
}
|
|
@@ -305,7 +355,7 @@ export class SessionContext implements ISessionContext {
|
|
|
305
355
|
return true;
|
|
306
356
|
}
|
|
307
357
|
}
|
|
308
|
-
if (!this.session
|
|
358
|
+
if (!this.session) { return false; }
|
|
309
359
|
const securityMode = this.session?.channel?.securityMode;
|
|
310
360
|
if (accessRestrictions & AccessRestrictionsFlag.SigningRequired) {
|
|
311
361
|
if (securityMode !== MessageSecurityMode.Sign && securityMode !== MessageSecurityMode.SignAndEncrypt) {
|
package/src/address_space.ts
CHANGED
|
@@ -55,7 +55,8 @@ import {
|
|
|
55
55
|
IAddressSpace,
|
|
56
56
|
ShutdownTask,
|
|
57
57
|
RaiseEventData,
|
|
58
|
-
UAVariableT
|
|
58
|
+
UAVariableT,
|
|
59
|
+
MethodCallInterceptor
|
|
59
60
|
} from "node-opcua-address-space-base";
|
|
60
61
|
import { make_debugLog, make_warningLog, make_errorLog } from "node-opcua-debug";
|
|
61
62
|
|
|
@@ -191,6 +192,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
191
192
|
private _shutdownTask?: ShutdownTask[];
|
|
192
193
|
private _modelChangeTransactionCounter = 0;
|
|
193
194
|
private _modelChanges: ModelChangeStructureDataType[] = [];
|
|
195
|
+
public _methodCallInterceptors: MethodCallInterceptor[] = [];
|
|
194
196
|
|
|
195
197
|
constructor() {
|
|
196
198
|
this._private_namespaceIndex = 1;
|
|
@@ -1082,6 +1084,27 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1082
1084
|
this._shutdownTask.push(task);
|
|
1083
1085
|
}
|
|
1084
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* Register a method call interceptor.
|
|
1089
|
+
* Interceptors are called sequentially before each UAMethod.execute().
|
|
1090
|
+
* If any interceptor returns a non-Good StatusCode, the method call
|
|
1091
|
+
* is rejected and subsequent interceptors are skipped.
|
|
1092
|
+
*/
|
|
1093
|
+
public addMethodCallInterceptor(interceptor: MethodCallInterceptor): void {
|
|
1094
|
+
assert(typeof interceptor === "function");
|
|
1095
|
+
this._methodCallInterceptors.push(interceptor);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* Remove a previously registered method call interceptor.
|
|
1100
|
+
*/
|
|
1101
|
+
public removeMethodCallInterceptor(interceptor: MethodCallInterceptor): void {
|
|
1102
|
+
const index = this._methodCallInterceptors.indexOf(interceptor);
|
|
1103
|
+
if (index !== -1) {
|
|
1104
|
+
this._methodCallInterceptors.splice(index, 1);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1085
1108
|
public async shutdown(): Promise<void> {
|
|
1086
1109
|
const performTasks = async (tasks: ShutdownTask[]) => {
|
|
1087
1110
|
// perform registerShutdownTask
|
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
UAObjectType,
|
|
21
21
|
UAReference,
|
|
22
22
|
UAVariable,
|
|
23
|
-
ContinuationData
|
|
23
|
+
ContinuationData,
|
|
24
|
+
MethodCallInterceptor
|
|
24
25
|
} from "node-opcua-address-space-base";
|
|
25
26
|
import { UARootFolder } from "../source/ua_root_folder";
|
|
26
27
|
import { ExtensionObjectConstructorFuncWithSchema } from "../source/interfaces/extension_object_constructor";
|
|
@@ -89,4 +90,6 @@ export interface AddressSpacePrivate extends IAddressSpace {
|
|
|
89
90
|
) => void;
|
|
90
91
|
|
|
91
92
|
isEnumeration(dataType: NodeId): boolean;
|
|
93
|
+
|
|
94
|
+
_methodCallInterceptors: MethodCallInterceptor[];
|
|
92
95
|
}
|