node-opcua-role-set-server 2.174.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.
Files changed (55) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +188 -0
  3. package/dist/audit.d.ts +33 -0
  4. package/dist/audit.js +28 -0
  5. package/dist/audit.js.map +1 -0
  6. package/dist/bind_restriction_methods.d.ts +31 -0
  7. package/dist/bind_restriction_methods.js +94 -0
  8. package/dist/bind_restriction_methods.js.map +1 -0
  9. package/dist/bind_role_methods.d.ts +48 -0
  10. package/dist/bind_role_methods.js +143 -0
  11. package/dist/bind_role_methods.js.map +1 -0
  12. package/dist/bind_user_management.d.ts +58 -0
  13. package/dist/bind_user_management.js +153 -0
  14. package/dist/bind_user_management.js.map +1 -0
  15. package/dist/harden.d.ts +35 -0
  16. package/dist/harden.js +28 -0
  17. package/dist/harden.js.map +1 -0
  18. package/dist/index.d.ts +13 -0
  19. package/dist/index.js +35 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/install_role_based_security.d.ts +78 -0
  22. package/dist/install_role_based_security.js +41 -0
  23. package/dist/install_role_based_security.js.map +1 -0
  24. package/dist/install_role_set.d.ts +73 -0
  25. package/dist/install_role_set.js +308 -0
  26. package/dist/install_role_set.js.map +1 -0
  27. package/dist/install_user_management.d.ts +68 -0
  28. package/dist/install_user_management.js +158 -0
  29. package/dist/install_user_management.js.map +1 -0
  30. package/dist/role_set_resolver.d.ts +23 -0
  31. package/dist/role_set_resolver.js +30 -0
  32. package/dist/role_set_resolver.js.map +1 -0
  33. package/dist/security_checks.d.ts +25 -0
  34. package/dist/security_checks.js +41 -0
  35. package/dist/security_checks.js.map +1 -0
  36. package/dist/user_management_user_manager.d.ts +37 -0
  37. package/dist/user_management_user_manager.js +72 -0
  38. package/dist/user_management_user_manager.js.map +1 -0
  39. package/dist/variant_args.d.ts +13 -0
  40. package/dist/variant_args.js +18 -0
  41. package/dist/variant_args.js.map +1 -0
  42. package/package.json +54 -0
  43. package/source/audit.ts +53 -0
  44. package/source/bind_restriction_methods.ts +117 -0
  45. package/source/bind_role_methods.ts +196 -0
  46. package/source/bind_user_management.ts +215 -0
  47. package/source/harden.ts +46 -0
  48. package/source/index.ts +48 -0
  49. package/source/install_role_based_security.ts +130 -0
  50. package/source/install_role_set.ts +426 -0
  51. package/source/install_user_management.ts +250 -0
  52. package/source/role_set_resolver.ts +38 -0
  53. package/source/security_checks.ts +47 -0
  54. package/source/user_management_user_manager.ts +104 -0
  55. package/source/variant_args.ts +22 -0
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ /**
3
+ * @module node-opcua-role-set-server
4
+ *
5
+ * Install RoleSet management on an OPC UA server.
6
+ *
7
+ * This function is designed to be called **after** the server has started
8
+ * (when the address space is available). It:
9
+ * - Creates an InMemoryIdentityMappingStore (optionally loaded from disk)
10
+ * - Registers a RoleSetResolver on server.roleResolvers
11
+ * - Binds AddIdentity / RemoveIdentity on each Role and keeps the Identities
12
+ * Property in sync with the store
13
+ * - Binds AddRole / RemoveRole (OPC 10000-18 §4.2): custom Roles are created
14
+ * as `ns=1;g=<uuid>` instances of RoleType (collision-proof, stable when
15
+ * persisted); well-known Roles cannot be removed.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.installRoleSet = installRoleSet;
19
+ const node_crypto_1 = require("node:crypto");
20
+ const node_opcua_constants_1 = require("node-opcua-constants");
21
+ const node_opcua_data_model_1 = require("node-opcua-data-model");
22
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
23
+ const node_opcua_role_set_common_1 = require("node-opcua-role-set-common");
24
+ const node_opcua_status_code_1 = require("node-opcua-status-code");
25
+ const node_opcua_types_1 = require("node-opcua-types");
26
+ const node_opcua_variant_1 = require("node-opcua-variant");
27
+ const audit_js_1 = require("./audit.js");
28
+ const bind_restriction_methods_js_1 = require("./bind_restriction_methods.js");
29
+ const bind_role_methods_js_1 = require("./bind_role_methods.js");
30
+ const harden_js_1 = require("./harden.js");
31
+ const role_set_resolver_js_1 = require("./role_set_resolver.js");
32
+ const security_checks_js_1 = require("./security_checks.js");
33
+ const variant_args_js_1 = require("./variant_args.js");
34
+ const UA_NAMESPACE_URI = "http://opcfoundation.org/UA/";
35
+ /** Iterate the Role components of a RoleSet (UAObjects of type RoleType). */
36
+ function forEachRole(roleSet, fn) {
37
+ for (const c of roleSet.getComponents()) {
38
+ if (c.nodeClass !== node_opcua_data_model_1.NodeClass.Object)
39
+ continue;
40
+ const obj = c;
41
+ if (obj.typeDefinitionObj.browseName.name !== "RoleType")
42
+ continue;
43
+ fn(obj);
44
+ }
45
+ }
46
+ /** True for the standard well-known Roles (ns=0 numeric NodeIds, OPC 10000-3). */
47
+ function isWellKnownRoleNodeId(nodeId) {
48
+ if (nodeId.namespace !== 0 || nodeId.identifierType !== node_opcua_nodeid_1.NodeIdType.NUMERIC) {
49
+ return false;
50
+ }
51
+ const values = Object.values(node_opcua_role_set_common_1.WellKnownRoles).filter((v) => typeof v === "number");
52
+ return values.includes(nodeId.value);
53
+ }
54
+ /** The BrowseNames of the standard well-known Roles (OPC 10000-3). */
55
+ const WELL_KNOWN_ROLE_NAMES = new Set(Object.keys(node_opcua_role_set_common_1.WellKnownRoles).filter((k) => Number.isNaN(Number(k))));
56
+ /**
57
+ * Install RoleSet management on an OPC UA server. Call this **after**
58
+ * `server.start()` so the address space is available.
59
+ */
60
+ async function installRoleSet(server, options) {
61
+ const addressSpace = server.engine.addressSpace;
62
+ if (!addressSpace) {
63
+ throw new Error("installRoleSet: address space is not available. Call this after server.start().");
64
+ }
65
+ const roleSet = addressSpace.findNode(node_opcua_constants_1.ObjectIds.Server_ServerCapabilities_RoleSet);
66
+ if (!roleSet) {
67
+ throw new Error("installRoleSet: RoleSet node (i=15606) not found in address space.");
68
+ }
69
+ // The consolidated archive is owned either by a shared coordinator (when also
70
+ // installing user management into the same file) or created from the path here.
71
+ const persistence = options?.persistence ??
72
+ (options?.persistencePath ? new node_opcua_role_set_common_1.ArchiveStore(options.persistencePath, { secret: options.persistenceSecret }) : undefined);
73
+ // Load the whole configuration from the single consolidated archive (if any).
74
+ const archive = persistence ? await persistence.load() : undefined;
75
+ const store = options?.store ?? new node_opcua_role_set_common_1.InMemoryIdentityMappingStore();
76
+ (0, node_opcua_role_set_common_1.identitiesFromBase64)(store, archive?.identities);
77
+ const restrictionStore = new node_opcua_role_set_common_1.InMemoryRoleRestrictionStore();
78
+ if (archive?.restrictions) {
79
+ (0, node_opcua_role_set_common_1.deserializeRestrictions)(restrictionStore, archive.restrictions);
80
+ }
81
+ const resolver = new role_set_resolver_js_1.RoleSetResolver(store, restrictionStore);
82
+ server.roleResolvers ??= [];
83
+ server.roleResolvers.push(resolver);
84
+ function refreshIdentities(role) {
85
+ role.identities.setValueFromSource({
86
+ dataType: node_opcua_variant_1.DataType.ExtensionObject,
87
+ value: store.getIdentitiesForRole(role.nodeId)
88
+ });
89
+ }
90
+ /** Refresh a Role's Applications/Endpoints restriction variables from the store. */
91
+ function refreshRestrictions(role) {
92
+ role.applications?.setValueFromSource({
93
+ dataType: node_opcua_variant_1.DataType.String,
94
+ arrayType: node_opcua_variant_1.VariantArrayType.Array,
95
+ value: restrictionStore.getApplications(role.nodeId)
96
+ });
97
+ role.applicationsExclude?.setValueFromSource({
98
+ dataType: node_opcua_variant_1.DataType.Boolean,
99
+ value: restrictionStore.getApplicationsExclude(role.nodeId)
100
+ });
101
+ role.endpoints?.setValueFromSource({
102
+ dataType: node_opcua_variant_1.DataType.ExtensionObject,
103
+ arrayType: node_opcua_variant_1.VariantArrayType.Array,
104
+ value: restrictionStore.getEndpoints(role.nodeId).map((e) => new node_opcua_types_1.EndpointType(e))
105
+ });
106
+ role.endpointsExclude?.setValueFromSource({
107
+ dataType: node_opcua_variant_1.DataType.Boolean,
108
+ value: restrictionStore.getEndpointsExclude(role.nodeId)
109
+ });
110
+ }
111
+ const customRoles = [];
112
+ // Register the sections we own; the coordinator gathers these (plus any users
113
+ // registered by installUserManagement) and rewrites the one file atomically.
114
+ persistence?.setIdentitiesProvider(() => (0, node_opcua_role_set_common_1.identitiesToBase64)(store));
115
+ persistence?.setRolesProvider(() => customRoles);
116
+ persistence?.setRestrictionsProvider(() => (0, node_opcua_role_set_common_1.serializeRestrictions)(restrictionStore));
117
+ /** Snapshot every store into the single consolidated archive (atomic write). */
118
+ async function persist() {
119
+ await persistence?.save();
120
+ }
121
+ /** Refresh every Role's variables and persist the whole configuration. */
122
+ const afterMutation = async () => {
123
+ forEachRole(roleSet, (role) => {
124
+ refreshIdentities(role);
125
+ refreshRestrictions(role);
126
+ });
127
+ await persist();
128
+ };
129
+ // Raise a RoleMappingRuleChangedAuditEventType on the Server object (§4.5).
130
+ // The IdentityMappingRule carries no secret, so it is included.
131
+ const serverObject = addressSpace.rootFolder?.objects?.server;
132
+ const raiseRoleMappingAudit = (audit) => {
133
+ (0, audit_js_1.raiseAuditMethodEvent)(serverObject, "RoleMappingRuleChangedAuditEventType", {
134
+ sourceNode: audit.roleNodeId,
135
+ sourceName: `Method/${audit.method}`,
136
+ methodId: audit.methodNodeId,
137
+ clientUserId: audit.userName,
138
+ status: audit.statusCode === node_opcua_status_code_1.StatusCodes.Good,
139
+ message: `${audit.method} on role ${audit.roleNodeId.toString()} by '${audit.userName}' → ${audit.statusCode.name}`,
140
+ inputArguments: audit.inputArguments
141
+ });
142
+ };
143
+ const methodOptions = { store, onMutation: afterMutation, onAudit: raiseRoleMappingAudit };
144
+ const addIdentityHandler = (0, bind_role_methods_js_1.makeAddIdentityHandler)(methodOptions);
145
+ const removeIdentityHandler = (0, bind_role_methods_js_1.makeRemoveIdentityHandler)(methodOptions);
146
+ const restrictionMethodOptions = {
147
+ restrictionStore,
148
+ onMutation: afterMutation,
149
+ onAudit: raiseRoleMappingAudit
150
+ };
151
+ const addApplicationHandler = (0, bind_restriction_methods_js_1.makeAddApplicationHandler)(restrictionMethodOptions);
152
+ const removeApplicationHandler = (0, bind_restriction_methods_js_1.makeRemoveApplicationHandler)(restrictionMethodOptions);
153
+ const addEndpointHandler = (0, bind_restriction_methods_js_1.makeAddEndpointHandler)(restrictionMethodOptions);
154
+ const removeEndpointHandler = (0, bind_restriction_methods_js_1.makeRemoveEndpointHandler)(restrictionMethodOptions);
155
+ /** Bind the identity + restriction Methods on a Role and seed its variables. */
156
+ function bindRoleMethods(role) {
157
+ refreshIdentities(role);
158
+ refreshRestrictions(role);
159
+ role.addIdentity?.bindMethod(addIdentityHandler);
160
+ role.removeIdentity?.bindMethod(removeIdentityHandler);
161
+ role.addApplication?.bindMethod(addApplicationHandler);
162
+ role.removeApplication?.bindMethod(removeApplicationHandler);
163
+ role.addEndpoint?.bindMethod(addEndpointHandler);
164
+ role.removeEndpoint?.bindMethod(removeEndpointHandler);
165
+ hardenRole(role);
166
+ }
167
+ /**
168
+ * Hide a Role's sensitive Properties and configuration Methods from
169
+ * non-admin Browse and require an encrypted channel (§4.4.1). The Role node
170
+ * itself stays browsable so the RoleSet hierarchy remains visible.
171
+ */
172
+ function hardenRole(role) {
173
+ (0, harden_js_1.hardenAdminOnly)(role.identities);
174
+ (0, harden_js_1.hardenAdminOnly)(role.applications);
175
+ (0, harden_js_1.hardenAdminOnly)(role.applicationsExclude);
176
+ (0, harden_js_1.hardenAdminOnly)(role.endpoints);
177
+ (0, harden_js_1.hardenAdminOnly)(role.endpointsExclude);
178
+ (0, harden_js_1.hardenAdminOnly)(role.addIdentity);
179
+ (0, harden_js_1.hardenAdminOnly)(role.removeIdentity);
180
+ (0, harden_js_1.hardenAdminOnly)(role.addApplication);
181
+ (0, harden_js_1.hardenAdminOnly)(role.removeApplication);
182
+ (0, harden_js_1.hardenAdminOnly)(role.addEndpoint);
183
+ (0, harden_js_1.hardenAdminOnly)(role.removeEndpoint);
184
+ }
185
+ /** Create a RoleType instance (with the configuration Methods) and bind it. */
186
+ const createRoleNode = (roleName, browseNameNamespace, nodeId) => {
187
+ const roleType = addressSpace.findObjectType("RoleType");
188
+ if (!roleType) {
189
+ throw new Error("installRoleSet: RoleType ObjectType not found");
190
+ }
191
+ const role = roleType.instantiate({
192
+ browseName: { name: roleName, namespaceIndex: browseNameNamespace },
193
+ componentOf: roleSet,
194
+ nodeId,
195
+ optionals: [
196
+ "AddIdentity",
197
+ "RemoveIdentity",
198
+ "AddApplication",
199
+ "RemoveApplication",
200
+ "AddEndpoint",
201
+ "RemoveEndpoint",
202
+ "Applications",
203
+ "ApplicationsExclude",
204
+ "Endpoints",
205
+ "EndpointsExclude"
206
+ ]
207
+ });
208
+ bindRoleMethods(role);
209
+ return role;
210
+ };
211
+ // Recreate persisted custom Roles before binding the standard ones.
212
+ for (const def of archive?.roles ?? []) {
213
+ const nodeId = (0, node_opcua_nodeid_1.resolveNodeId)(def.nodeId);
214
+ const nsIndex = def.namespaceUri ? ensureNamespace(addressSpace, def.namespaceUri) : addressSpace.getOwnNamespace().index;
215
+ if (!addressSpace.findNode(nodeId)) {
216
+ createRoleNode(def.roleName, nsIndex, nodeId);
217
+ }
218
+ customRoles.push(def);
219
+ }
220
+ // Bind the configuration Methods on every current Role and seed its variables.
221
+ forEachRole(roleSet, bindRoleMethods);
222
+ // AddRole (§4.2.2)
223
+ const addRoleHandler = async function (inputArguments, context) {
224
+ const insecure = (0, security_checks_js_1.checkEncryptedChannel)(context);
225
+ if (insecure)
226
+ return insecure;
227
+ const denied = (0, security_checks_js_1.checkSecurityAdminAccess)(context);
228
+ if (denied)
229
+ return denied;
230
+ const roleName = (0, variant_args_js_1.asString)(inputArguments[0]);
231
+ if (!roleName) {
232
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
233
+ }
234
+ // A custom Role must not impersonate a well-known Role (which already
235
+ // exists in ns=0); reject the name in any namespace (§4.2.2).
236
+ if (WELL_KNOWN_ROLE_NAMES.has(roleName)) {
237
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadAlreadyExists };
238
+ }
239
+ const namespaceUri = (0, variant_args_js_1.asString)(inputArguments[1]) ?? "";
240
+ const browseNameNamespace = namespaceUri && namespaceUri !== UA_NAMESPACE_URI
241
+ ? ensureNamespace(addressSpace, namespaceUri)
242
+ : namespaceUri === UA_NAMESPACE_URI
243
+ ? 0
244
+ : addressSpace.getOwnNamespace().index;
245
+ // The RoleName must be unique within the RoleSet (§4.2.2). We check by
246
+ // name across *all* namespaces (not just name+namespace) so a custom Role
247
+ // can never duplicate the name of any existing Role — well-known or custom.
248
+ const exists = roleSet.getComponents().some((c) => c.browseName.name === roleName);
249
+ if (exists) {
250
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadAlreadyExists };
251
+ }
252
+ // GUID NodeId in the server's own namespace (collision-proof, persisted)
253
+ const nodeId = new node_opcua_nodeid_1.NodeId(node_opcua_nodeid_1.NodeIdType.GUID, (0, node_crypto_1.randomUUID)().toUpperCase(), addressSpace.getOwnNamespace().index);
254
+ createRoleNode(roleName, browseNameNamespace, nodeId);
255
+ customRoles.push({ nodeId: nodeId.toString(), roleName, namespaceUri });
256
+ await persist();
257
+ return {
258
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
259
+ outputArguments: [{ dataType: node_opcua_variant_1.DataType.NodeId, value: nodeId }]
260
+ };
261
+ };
262
+ // RemoveRole (§4.2.3)
263
+ const removeRoleHandler = async function (inputArguments, context) {
264
+ const insecure = (0, security_checks_js_1.checkEncryptedChannel)(context);
265
+ if (insecure)
266
+ return insecure;
267
+ const denied = (0, security_checks_js_1.checkSecurityAdminAccess)(context);
268
+ if (denied)
269
+ return denied;
270
+ const roleNodeId = inputArguments[0]?.value;
271
+ if (!(roleNodeId instanceof node_opcua_nodeid_1.NodeId)) {
272
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
273
+ }
274
+ // Well-known Roles are required by the Server and cannot be removed (§4.3)
275
+ if (isWellKnownRoleNodeId(roleNodeId)) {
276
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadRequestNotAllowed };
277
+ }
278
+ const node = addressSpace.findNode(roleNodeId);
279
+ if (node?.typeDefinitionObj?.browseName.name !== "RoleType") {
280
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown };
281
+ }
282
+ // remove the node, its identity mappings and the persisted definition
283
+ for (const rule of store.getIdentitiesForRole(roleNodeId)) {
284
+ store.removeIdentity(roleNodeId, rule);
285
+ }
286
+ addressSpace.deleteNode(roleNodeId);
287
+ const idx = customRoles.findIndex((r) => (0, node_opcua_nodeid_1.sameNodeId)((0, node_opcua_nodeid_1.resolveNodeId)(r.nodeId), roleNodeId));
288
+ if (idx >= 0)
289
+ customRoles.splice(idx, 1);
290
+ await persist();
291
+ return { statusCode: node_opcua_status_code_1.StatusCodes.Good };
292
+ };
293
+ if (roleSet.addRole) {
294
+ roleSet.addRole.bindMethod(addRoleHandler);
295
+ (0, harden_js_1.hardenAdminOnly)(roleSet.addRole);
296
+ }
297
+ if (roleSet.removeRole) {
298
+ roleSet.removeRole.bindMethod(removeRoleHandler);
299
+ (0, harden_js_1.hardenAdminOnly)(roleSet.removeRole);
300
+ }
301
+ return { store, restrictionStore, resolver };
302
+ }
303
+ /** Resolve a namespace URI to its index, registering it if necessary. */
304
+ function ensureNamespace(addressSpace, namespaceUri) {
305
+ const idx = addressSpace.getNamespaceIndex(namespaceUri);
306
+ return idx >= 0 ? idx : addressSpace.registerNamespace(namespaceUri).index;
307
+ }
308
+ //# sourceMappingURL=install_role_set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install_role_set.js","sourceRoot":"","sources":["../source/install_role_set.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @module node-opcua-role-set-server
3
+ *
4
+ * Install User Management (OPC 10000-18 §5) on an OPC UA server.
5
+ *
6
+ * Binds the AddUser / ModifyUser / RemoveUser / ChangePassword Methods of the
7
+ * standard `UserManagement` Object (i=24290, ComponentOf ServerConfiguration)
8
+ * to an {@link InMemoryUserManagementStore}, keeps the `Users` Property in sync
9
+ * with the store, and publishes the password policy via `PasswordLength` /
10
+ * `PasswordOptions`.
11
+ */
12
+ import type { IAddressSpace } from "node-opcua-address-space";
13
+ import type { NodeId } from "node-opcua-nodeid";
14
+ import { ArchiveStore, type IUserManagementStore, type PasswordPolicy } from "node-opcua-role-set-common";
15
+ export interface InstallUserManagementOptions {
16
+ /** Password policy published via PasswordLength / PasswordOptions and enforced by the store. */
17
+ policy?: PasswordPolicy;
18
+ /**
19
+ * Existing user store to bind the Methods to. When omitted a new
20
+ * {@link InMemoryUserManagementStore} is created. Inject a shared store when
21
+ * the same store also backs the server `userManager`
22
+ * (see `createUserManager`).
23
+ */
24
+ store?: IUserManagementStore;
25
+ /**
26
+ * A shared {@link ArchiveStore} coordinating one consolidated file across
27
+ * `installRoleSet` and `installUserManagement`. Pass the **same** instance to
28
+ * both so users (salted scrypt hashes) live in the same archive as the role
29
+ * config; install order does not matter (unregistered sections are preserved).
30
+ * When omitted, an internal one is created from `persistencePath`.
31
+ */
32
+ persistence?: ArchiveStore;
33
+ /** Path to a users-only archive (used when no shared {@link persistence} is given). */
34
+ persistencePath?: string;
35
+ /** Encrypt the users-only archive at rest (see `installRoleSet`'s `persistenceSecret`). */
36
+ persistenceSecret?: string;
37
+ }
38
+ export interface InstallUserManagementResult {
39
+ store: IUserManagementStore;
40
+ }
41
+ /** A live session as seen by {@link IServerForUserManagement} — enough to identify and close it. */
42
+ export interface IActiveSession {
43
+ readonly authenticationToken: NodeId;
44
+ /** The activated user-identity token (a {@link UserNameIdentityToken} for username logins). */
45
+ readonly userIdentityToken?: unknown;
46
+ }
47
+ /**
48
+ * Minimal server shape: access to the address space, and — optionally — to the
49
+ * live sessions so a disabled/removed user's sessions can be terminated
50
+ * (§5.2.6-7). When `getSessions`/`closeSession` are absent (e.g. a bare test
51
+ * double) the feature is silently skipped. The real `OPCUAServer`'s engine
52
+ * provides both.
53
+ */
54
+ export interface IServerForUserManagement {
55
+ engine: {
56
+ addressSpace: IAddressSpace | null;
57
+ getSessions?(): IActiveSession[];
58
+ closeSession?(authenticationToken: NodeId, deleteSubscriptions: boolean, reason: string): void;
59
+ };
60
+ }
61
+ /**
62
+ * Install User Management on an OPC UA server.
63
+ *
64
+ * Call this **after** the server has started and the address space is
65
+ * available (the standard nodeset must be loaded so the `UserManagement`
66
+ * Object exists).
67
+ */
68
+ export declare function installUserManagement(server: IServerForUserManagement, options?: InstallUserManagementOptions): Promise<InstallUserManagementResult>;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.installUserManagement = installUserManagement;
4
+ const node_opcua_constants_1 = require("node-opcua-constants");
5
+ const node_opcua_role_set_common_1 = require("node-opcua-role-set-common");
6
+ const node_opcua_status_code_1 = require("node-opcua-status-code");
7
+ const node_opcua_types_1 = require("node-opcua-types");
8
+ const node_opcua_variant_1 = require("node-opcua-variant");
9
+ const audit_js_1 = require("./audit.js");
10
+ const bind_user_management_js_1 = require("./bind_user_management.js");
11
+ const harden_js_1 = require("./harden.js");
12
+ /** PasswordOptionsMask bit values (OPC 10000-18 §5.2.2). */
13
+ const PasswordOptions = {
14
+ RequiresUpperCaseCharacters: 1 << 5,
15
+ RequiresLowerCaseCharacters: 1 << 6,
16
+ RequiresDigitCharacters: 1 << 7,
17
+ RequiresSpecialCharacters: 1 << 8
18
+ };
19
+ /**
20
+ * Build a "close every active session of this user" function from the server's
21
+ * engine, or `undefined` if the engine does not expose session control. Closing
22
+ * deletes the user's subscriptions too — a deactivated user keeps nothing live.
23
+ */
24
+ function makeSessionCloser(engine) {
25
+ const { getSessions, closeSession } = engine;
26
+ if (!getSessions || !closeSession)
27
+ return undefined;
28
+ return (userName) => {
29
+ let closed = 0;
30
+ // snapshot first: closeSession mutates the engine's session map
31
+ for (const session of getSessions.call(engine)) {
32
+ const token = session.userIdentityToken;
33
+ if (token instanceof node_opcua_types_1.UserNameIdentityToken && token.userName === userName) {
34
+ closeSession.call(engine, session.authenticationToken, /* deleteSubscriptions */ true, "Terminated");
35
+ closed += 1;
36
+ }
37
+ }
38
+ return closed;
39
+ };
40
+ }
41
+ function passwordOptionsMask(policy) {
42
+ let mask = 0;
43
+ if (policy.requireUpperCase)
44
+ mask |= PasswordOptions.RequiresUpperCaseCharacters;
45
+ if (policy.requireLowerCase)
46
+ mask |= PasswordOptions.RequiresLowerCaseCharacters;
47
+ if (policy.requireDigit)
48
+ mask |= PasswordOptions.RequiresDigitCharacters;
49
+ if (policy.requireSpecial)
50
+ mask |= PasswordOptions.RequiresSpecialCharacters;
51
+ return mask;
52
+ }
53
+ /**
54
+ * Install User Management on an OPC UA server.
55
+ *
56
+ * Call this **after** the server has started and the address space is
57
+ * available (the standard nodeset must be loaded so the `UserManagement`
58
+ * Object exists).
59
+ */
60
+ async function installUserManagement(server, options) {
61
+ const addressSpace = server.engine.addressSpace;
62
+ if (!addressSpace) {
63
+ throw new Error("installUserManagement: address space is not available. Call this after server.start().");
64
+ }
65
+ const userManagement = addressSpace.findNode(node_opcua_constants_1.ObjectIds.UserManagement);
66
+ if (!userManagement) {
67
+ throw new Error("installUserManagement: UserManagement Object (i=24290) not found in address space.");
68
+ }
69
+ const policy = options?.policy ?? {};
70
+ const store = options?.store ?? new node_opcua_role_set_common_1.InMemoryUserManagementStore(policy);
71
+ // Consolidated-archive coordination: hydrate persisted users (salted hashes)
72
+ // and register the `users` section so a shared coordinator persists them
73
+ // alongside the role configuration.
74
+ const persistence = options?.persistence ??
75
+ (options?.persistencePath ? new node_opcua_role_set_common_1.ArchiveStore(options.persistencePath, { secret: options.persistenceSecret }) : undefined);
76
+ if (persistence && store.importUsers) {
77
+ const archive = await persistence.load();
78
+ if (archive?.users)
79
+ store.importUsers(archive.users);
80
+ }
81
+ const exportUsers = store.exportUsers?.bind(store);
82
+ if (persistence && exportUsers) {
83
+ persistence.setUsersProvider(() => exportUsers());
84
+ }
85
+ const usersVar = addressSpace.findNode(node_opcua_constants_1.VariableIds.UserManagement_Users);
86
+ function refreshUsers() {
87
+ usersVar?.setValueFromSource({
88
+ dataType: node_opcua_variant_1.DataType.ExtensionObject,
89
+ arrayType: node_opcua_variant_1.VariantArrayType.Array,
90
+ value: store.getUsers().map((u) => new node_opcua_types_1.UserManagementDataType({
91
+ userName: u.userName,
92
+ userConfiguration: u.userConfiguration,
93
+ description: u.description
94
+ }))
95
+ });
96
+ }
97
+ // Raise an AuditUpdateMethodEventType on the Server object for each managed
98
+ // user-management call — WITHOUT any password (only who/what/whom/result).
99
+ const serverObject = addressSpace.rootFolder?.objects?.server;
100
+ const closeSessionsForUser = makeSessionCloser(server.engine);
101
+ const methodOptions = {
102
+ store,
103
+ onMutation: async () => {
104
+ refreshUsers();
105
+ await persistence?.save();
106
+ },
107
+ onUserDeactivated: closeSessionsForUser
108
+ ? (userName) => {
109
+ const closed = closeSessionsForUser(userName);
110
+ if (closed > 0) {
111
+ (0, audit_js_1.raiseAuditMethodEvent)(serverObject, "AuditUpdateMethodEventType", {
112
+ sourceNode: userManagement.nodeId,
113
+ sourceName: "Method/UserDeactivated",
114
+ clientUserId: userName,
115
+ status: true,
116
+ message: `terminated ${closed} active session(s) of deactivated user '${userName}'`
117
+ });
118
+ }
119
+ }
120
+ : undefined,
121
+ onAudit: (audit) => {
122
+ (0, audit_js_1.raiseAuditMethodEvent)(serverObject, "AuditUpdateMethodEventType", {
123
+ sourceNode: userManagement.nodeId,
124
+ sourceName: `Method/${audit.method}`,
125
+ methodId: audit.methodNodeId,
126
+ clientUserId: audit.callerUserName,
127
+ status: audit.statusCode === node_opcua_status_code_1.StatusCodes.Good,
128
+ message: `${audit.method}('${audit.targetUserName}') by '${audit.callerUserName}' → ${audit.statusCode.name}`
129
+ // NOTE: inputArguments deliberately omitted — they contain passwords
130
+ });
131
+ }
132
+ };
133
+ // Bind and harden the Methods: the three administrative Methods (and the
134
+ // Users list, which reveals account names) are SecurityAdmin-only over an
135
+ // encrypted channel; ChangePassword stays callable by any authenticated user
136
+ // but still requires encryption (§4.4.1 / §5.2.8).
137
+ (0, harden_js_1.hardenAdminOnly)(bindMethod(addressSpace, node_opcua_constants_1.MethodIds.UserManagement_AddUser, (0, bind_user_management_js_1.makeAddUserHandler)(methodOptions)));
138
+ (0, harden_js_1.hardenAdminOnly)(bindMethod(addressSpace, node_opcua_constants_1.MethodIds.UserManagement_ModifyUser, (0, bind_user_management_js_1.makeModifyUserHandler)(methodOptions)));
139
+ (0, harden_js_1.hardenAdminOnly)(bindMethod(addressSpace, node_opcua_constants_1.MethodIds.UserManagement_RemoveUser, (0, bind_user_management_js_1.makeRemoveUserHandler)(methodOptions)));
140
+ (0, harden_js_1.hardenEncryptedOnly)(bindMethod(addressSpace, node_opcua_constants_1.MethodIds.UserManagement_ChangePassword, (0, bind_user_management_js_1.makeChangePasswordHandler)(methodOptions)));
141
+ (0, harden_js_1.hardenAdminOnly)(usersVar);
142
+ // Publish the password policy and the initial (empty) user list.
143
+ const lengthVar = addressSpace.findNode(node_opcua_constants_1.VariableIds.UserManagement_PasswordLength);
144
+ lengthVar?.setValueFromSource({
145
+ dataType: node_opcua_variant_1.DataType.ExtensionObject,
146
+ value: new node_opcua_types_1.Range({ low: policy.minLength ?? 0, high: policy.maxLength ?? 0 })
147
+ });
148
+ const optionsVar = addressSpace.findNode(node_opcua_constants_1.VariableIds.UserManagement_PasswordOptions);
149
+ optionsVar?.setValueFromSource({ dataType: node_opcua_variant_1.DataType.UInt32, value: passwordOptionsMask(policy) });
150
+ refreshUsers();
151
+ return { store };
152
+ }
153
+ function bindMethod(addressSpace, methodNodeId, handler) {
154
+ const method = addressSpace.findNode(methodNodeId);
155
+ method?.bindMethod(handler);
156
+ return method;
157
+ }
158
+ //# sourceMappingURL=install_user_management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install_user_management.js","sourceRoot":"","sources":["../source/install_user_management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module node-opcua-role-set-server
3
+ *
4
+ * IRoleResolver adapter backed by an IIdentityMappingStore, optionally enforcing
5
+ * per-Role application/endpoint restrictions (OPC 10000-18 §4.4.1).
6
+ */
7
+ import type { NodeId } from "node-opcua-nodeid";
8
+ import type { AnyUserIdentityToken, IIdentityMappingStore, IRoleRestrictionStore, ResolutionContext } from "node-opcua-role-set-common";
9
+ /**
10
+ * Adapts an {@link IIdentityMappingStore} (and an optional
11
+ * {@link IRoleRestrictionStore}) to the `IRoleResolver` contract so it can be
12
+ * registered on `OPCUAServer.roleResolvers`.
13
+ *
14
+ * A Role is granted when the UserIdentityToken matches **and** — if a
15
+ * restriction store is provided and a resolution context is available — the
16
+ * Session's application/endpoint comply with the Role's restrictions.
17
+ */
18
+ export declare class RoleSetResolver {
19
+ private readonly store;
20
+ private readonly restrictionStore?;
21
+ constructor(store: IIdentityMappingStore, restrictionStore?: IRoleRestrictionStore | undefined);
22
+ resolveRoles(userIdentityToken: AnyUserIdentityToken, context?: ResolutionContext): NodeId[];
23
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleSetResolver = void 0;
4
+ /**
5
+ * Adapts an {@link IIdentityMappingStore} (and an optional
6
+ * {@link IRoleRestrictionStore}) to the `IRoleResolver` contract so it can be
7
+ * registered on `OPCUAServer.roleResolvers`.
8
+ *
9
+ * A Role is granted when the UserIdentityToken matches **and** — if a
10
+ * restriction store is provided and a resolution context is available — the
11
+ * Session's application/endpoint comply with the Role's restrictions.
12
+ */
13
+ class RoleSetResolver {
14
+ store;
15
+ restrictionStore;
16
+ constructor(store, restrictionStore) {
17
+ this.store = store;
18
+ this.restrictionStore = restrictionStore;
19
+ }
20
+ resolveRoles(userIdentityToken, context) {
21
+ const roles = this.store.resolveRoles(userIdentityToken);
22
+ if (!this.restrictionStore || !context) {
23
+ return roles;
24
+ }
25
+ const restrictionStore = this.restrictionStore;
26
+ return roles.filter((roleId) => restrictionStore.complies(roleId, context));
27
+ }
28
+ }
29
+ exports.RoleSetResolver = RoleSetResolver;
30
+ //# sourceMappingURL=role_set_resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role_set_resolver.js","sourceRoot":"","sources":["../source/role_set_resolver.ts"],"names":[],"mappings":";;;AAcA;;;;;;;;GAQG;AACH,MAAa,eAAe;IAEH;IACA;IAFrB,YACqB,KAA4B,EAC5B,gBAAwC;QADxC,UAAK,GAAL,KAAK,CAAuB;QAC5B,qBAAgB,GAAhB,gBAAgB,CAAwB;IAC1D,CAAC;IAEG,YAAY,CAAC,iBAAuC,EAAE,OAA2B;QACpF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC/C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAChF,CAAC;CACJ;AAdD,0CAcC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @module node-opcua-role-set-server
3
+ *
4
+ * Shared authorization checks for the RoleType and UserManagement Methods
5
+ * (OPC 10000-18 §4.4 / §5.2): all require the SecurityAdmin Role and an
6
+ * encrypted SecureChannel.
7
+ */
8
+ import type { ISessionContext } from "node-opcua-address-space-base";
9
+ import type { CallMethodResultOptions } from "node-opcua-service-call";
10
+ /**
11
+ * Verify the calling session holds the SecurityAdmin role.
12
+ * @returns a `Bad_UserAccessDenied` denial, or `null` if authorized.
13
+ */
14
+ export declare function checkSecurityAdminAccess(context: ISessionContext): CallMethodResultOptions | null;
15
+ /**
16
+ * Verify the call arrives over an encrypted (SignAndEncrypt) SecureChannel
17
+ * (OPC 10000-18 — `Bad_SecurityModeInsufficient`).
18
+ *
19
+ * When the channel security mode cannot be determined (e.g. an in-process
20
+ * `PseudoSession` with no channel), the check is skipped — such sessions are
21
+ * inherently local/trusted. Remote sessions always expose a channel mode.
22
+ *
23
+ * @returns a denial result, or `null` if the channel is acceptable.
24
+ */
25
+ export declare function checkEncryptedChannel(context: ISessionContext): CallMethodResultOptions | null;