@vuu-ui/vuu-data-test 4.0.0-alpha.10 → 4.0.0-alpha.12
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/package.json +7 -7
- package/src/local-datasource-provider/LocalDatasourceProvider.js +52 -43
- package/src/user-admin/UserAdminModule.js +163 -8
- package/src/user-admin/initialSnapshot.js +49 -65
- package/types/local-datasource-provider/LocalDatasourceProvider.d.ts +15 -1
- package/types/user-admin/UserAdminModule.d.ts +5 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.0.0-alpha.
|
|
2
|
+
"version": "4.0.0-alpha.12",
|
|
3
3
|
"main": "./src/index.js",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "heswell",
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@heswell/module-admin": "1.0.0",
|
|
14
14
|
"@heswell/user-admin": "1.0.1",
|
|
15
|
-
"@vuu-ui/vuu-data-editing": "4.0.0-alpha.
|
|
16
|
-
"@vuu-ui/vuu-data-local": "4.0.0-alpha.
|
|
17
|
-
"@vuu-ui/vuu-utils": "4.0.0-alpha.
|
|
15
|
+
"@vuu-ui/vuu-data-editing": "4.0.0-alpha.12",
|
|
16
|
+
"@vuu-ui/vuu-data-local": "4.0.0-alpha.12",
|
|
17
|
+
"@vuu-ui/vuu-utils": "4.0.0-alpha.12"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@vuu-ui/vuu-data-types": "4.0.0-alpha.
|
|
21
|
-
"@vuu-ui/vuu-protocol-types": "4.0.0-alpha.
|
|
22
|
-
"@vuu-ui/vuu-table-types": "4.0.0-alpha.
|
|
20
|
+
"@vuu-ui/vuu-data-types": "4.0.0-alpha.12",
|
|
21
|
+
"@vuu-ui/vuu-protocol-types": "4.0.0-alpha.12",
|
|
22
|
+
"@vuu-ui/vuu-table-types": "4.0.0-alpha.12"
|
|
23
23
|
},
|
|
24
24
|
"sideEffects": false,
|
|
25
25
|
"files": [
|
|
@@ -1,50 +1,59 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { DataProvider } from "@vuu-ui/core";
|
|
3
3
|
import { DataProvider as vuu_utils_DataProvider } from "@vuu-ui/vuu-utils";
|
|
4
|
-
import ModuleContainer from "../core/module/ModuleContainer.js";
|
|
4
|
+
import ModuleContainer, { ensureVuuModule } from "../core/module/ModuleContainer.js";
|
|
5
5
|
import TableContainer from "../core/table/TableContainer.js";
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
const createLocalDataSourceProvider = (moduleNames)=>{
|
|
7
|
+
const getModule = (moduleName)=>{
|
|
8
|
+
if (moduleNames && !moduleNames.has(moduleName)) throw Error(`[LocalDataSourceProvider] module ${moduleName} is not available on this server`);
|
|
9
|
+
return ModuleContainer.get(moduleName);
|
|
10
|
+
};
|
|
11
|
+
const serverAPI = {
|
|
12
|
+
getTableList: async ()=>{
|
|
13
|
+
const tables = [];
|
|
14
|
+
for (const moduleName of moduleNames ?? ModuleContainer.moduleNames)for (const tableName of getModule(moduleName).getTableList())tables.push(TableContainer.getTable(tableName).schema.table);
|
|
15
|
+
return {
|
|
16
|
+
tables
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
getTableSchema: async ({ module, table })=>getModule(module).getTableSchema(table),
|
|
20
|
+
rpcCall: async ()=>{
|
|
21
|
+
throw Error("RpcCall no longer supported on LocalDataSourceProvider ServerAPI");
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const getServerAPI = async ()=>serverAPI;
|
|
25
|
+
class VuuDataSource {
|
|
26
|
+
constructor({ aggregations, columns, filterSpec, groupBy, session, sort, table, viewport, visualLink }){
|
|
27
|
+
const config = {
|
|
28
|
+
aggregations,
|
|
29
|
+
columns,
|
|
30
|
+
filterSpec,
|
|
31
|
+
groupBy,
|
|
32
|
+
session,
|
|
33
|
+
sort,
|
|
34
|
+
visualLink
|
|
35
|
+
};
|
|
36
|
+
const module = getModule(table.module);
|
|
37
|
+
return module.createDataSource(table.table, viewport, config);
|
|
38
|
+
}
|
|
23
39
|
}
|
|
24
|
-
}
|
|
25
|
-
const getServerAPI = async ()=>serverAPI;
|
|
26
|
-
class VuuDataSource {
|
|
27
|
-
constructor({ aggregations, columns, filterSpec, groupBy, session, sort, table, viewport, visualLink }){
|
|
28
|
-
const config = {
|
|
29
|
-
aggregations,
|
|
30
|
-
columns,
|
|
31
|
-
filterSpec,
|
|
32
|
-
groupBy,
|
|
33
|
-
session,
|
|
34
|
-
sort,
|
|
35
|
-
visualLink
|
|
36
|
-
};
|
|
37
|
-
const module = ModuleContainer.get(table.module);
|
|
38
|
-
return module.createDataSource(table.table, viewport, config);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const LocalDataSourceProvider = ({ children })=>/*#__PURE__*/ jsx(vuu_utils_DataProvider, {
|
|
42
|
-
VuuDataSource: VuuDataSource,
|
|
43
|
-
getServerAPI: getServerAPI,
|
|
44
|
-
children: /*#__PURE__*/ jsx(DataProvider, {
|
|
40
|
+
const DataSourceProvider = ({ children })=>/*#__PURE__*/ jsx(vuu_utils_DataProvider, {
|
|
45
41
|
VuuDataSource: VuuDataSource,
|
|
46
42
|
getServerAPI: getServerAPI,
|
|
47
|
-
children:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
children: /*#__PURE__*/ jsx(DataProvider, {
|
|
44
|
+
VuuDataSource: VuuDataSource,
|
|
45
|
+
getServerAPI: getServerAPI,
|
|
46
|
+
children: children
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
return DataSourceProvider;
|
|
50
|
+
};
|
|
51
|
+
const LocalDataSourceProvider = createLocalDataSourceProvider();
|
|
52
|
+
const createLocalVuuServer = ({ connectionId, modules })=>{
|
|
53
|
+
modules.forEach(ensureVuuModule);
|
|
54
|
+
return {
|
|
55
|
+
connectionId,
|
|
56
|
+
DataSourceProvider: createLocalDataSourceProvider(new Set(modules.map(({ name })=>name)))
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export { LocalDataSourceProvider, createLocalVuuServer };
|
|
@@ -65,6 +65,19 @@ const parseAssignments = (value)=>{
|
|
|
65
65
|
if (!Array.isArray(parsed) || parsed.some((assignment)=>!isRecord(assignment) || "string" != typeof assignment.accessRole || 0 === assignment.accessRole.length || "string" != typeof assignment.groupId || 0 === assignment.groupId.length || Object.keys(assignment).some((name)=>"accessRole" !== name && "groupId" !== name))) throw new Error("assignments must be a JSON array of accessRole and groupId strings");
|
|
66
66
|
return parsed;
|
|
67
67
|
};
|
|
68
|
+
const parseSessionRoleAssignments = (value)=>{
|
|
69
|
+
if ("string" != typeof value) throw new Error("role_assignments must be a serialized array");
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(value);
|
|
73
|
+
} catch {
|
|
74
|
+
throw new Error("role_assignments must be a valid JSON array");
|
|
75
|
+
}
|
|
76
|
+
if (!Array.isArray(parsed) || parsed.some((roleId)=>"string" != typeof roleId || !roleId)) throw new Error("role_assignments must be an array of role ID strings");
|
|
77
|
+
return [
|
|
78
|
+
...new Set(parsed)
|
|
79
|
+
];
|
|
80
|
+
};
|
|
68
81
|
const parseSessionPermissions = (value)=>{
|
|
69
82
|
if ("string" != typeof value) throw new Error("permissions must be a serialized array");
|
|
70
83
|
let parsed;
|
|
@@ -206,17 +219,32 @@ class UserAdminModule extends VuuModule {
|
|
|
206
219
|
}
|
|
207
220
|
createSessionTable(sourceTable, sessionTableName, editSessionMode, dataSource, sessionType) {
|
|
208
221
|
const sessionTable = super.createSessionTable(sourceTable, sessionTableName, editSessionMode, dataSource, sessionType);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
...sessionTable.schema,
|
|
212
|
-
columns: sessionTable.schema.columns.concat({
|
|
222
|
+
const extraColumns = "users" === sourceTable.name ? [
|
|
223
|
+
{
|
|
213
224
|
name: "permissions",
|
|
214
225
|
serverDataType: "string"
|
|
215
|
-
}
|
|
226
|
+
}
|
|
227
|
+
] : "groups" === sourceTable.name ? [
|
|
228
|
+
{
|
|
229
|
+
name: "group_name",
|
|
230
|
+
serverDataType: "string"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: "role_assignments",
|
|
234
|
+
serverDataType: "string"
|
|
235
|
+
}
|
|
236
|
+
] : [];
|
|
237
|
+
const columnsToAdd = extraColumns.filter(({ name })=>!sessionTable.schema.columns.some((column)=>column.name === name));
|
|
238
|
+
if (0 === columnsToAdd.length) return sessionTable;
|
|
239
|
+
const sessionSchema = {
|
|
240
|
+
...sessionTable.schema,
|
|
241
|
+
columns: sessionTable.schema.columns.concat(columnsToAdd)
|
|
216
242
|
};
|
|
217
|
-
return new Table(sessionSchema, sessionTable.data.map((row)=>row.concat("")), buildDataColumnMapFromSchema(sessionSchema));
|
|
243
|
+
return new Table(sessionSchema, sessionTable.data.map((row)=>row.concat(columnsToAdd.map(()=>""))), buildDataColumnMapFromSchema(sessionSchema));
|
|
218
244
|
}
|
|
219
245
|
async beforeSessionSave(sourceTable, sessionTable) {
|
|
246
|
+
if ("roles" === sourceTable.name) return void await this.saveClientRolesFromSession(sessionTable);
|
|
247
|
+
if ("groups" === sourceTable.name) return void await this.saveGroupsFromSession(sessionTable);
|
|
220
248
|
if ("users" !== sourceTable.name) return;
|
|
221
249
|
const permissionsIndex = sessionTable.map.permissions;
|
|
222
250
|
const actionIndex = sessionTable.map.vuuAction;
|
|
@@ -230,8 +258,135 @@ class UserAdminModule extends VuuModule {
|
|
|
230
258
|
if ("string" == typeof row[permissionsIndex] && "" !== row[permissionsIndex]) await this.store.setUserModuleAccess(userId, parseSessionPermissions(row[permissionsIndex]));
|
|
231
259
|
}
|
|
232
260
|
}
|
|
233
|
-
async afterSessionSave(sourceTable) {
|
|
234
|
-
|
|
261
|
+
async afterSessionSave(sourceTable, sessionTable) {
|
|
262
|
+
const roleCreationSaved = "roles" === sourceTable.name && sessionTable.data.some((row)=>"addRow" === row[sessionTable.map.vuuAction] && "client role created" === row[sessionTable.map.vuuMsg]);
|
|
263
|
+
const groupChangesSaved = "groups" === sourceTable.name && sessionTable.data.some((row)=>"group created" === row[sessionTable.map.vuuMsg] || "group roles updated" === row[sessionTable.map.vuuMsg]);
|
|
264
|
+
if ("users" === sourceTable.name || roleCreationSaved || groupChangesSaved) await this.reconcile();
|
|
265
|
+
}
|
|
266
|
+
async saveGroupsFromSession(sessionTable) {
|
|
267
|
+
const actionIndex = sessionTable.map.vuuAction;
|
|
268
|
+
const messageIndex = sessionTable.map.vuuMsg;
|
|
269
|
+
const keyIndex = sessionTable.map[sessionTable.schema.key];
|
|
270
|
+
const groupIdIndex = sessionTable.map.group_id;
|
|
271
|
+
const groupNameIndex = sessionTable.map.group_name;
|
|
272
|
+
const roleAssignmentsIndex = sessionTable.map.role_assignments;
|
|
273
|
+
for (const row of sessionTable.data)if ("addRow" !== row[actionIndex] || row[messageIndex]) {
|
|
274
|
+
if ("editCell" === row[actionIndex] && "string" == typeof row[roleAssignmentsIndex] && "" !== row[roleAssignmentsIndex]) {
|
|
275
|
+
const groupId = requiredString({
|
|
276
|
+
group_id: row[groupIdIndex]
|
|
277
|
+
}, "group_id");
|
|
278
|
+
const roleIds = parseSessionRoleAssignments(row[roleAssignmentsIndex]);
|
|
279
|
+
await this.saveGroupRoleAssignments(groupId, roleIds, await this.store.snapshot());
|
|
280
|
+
sessionTable.update(String(row[keyIndex]), "vuuMsg", "group roles updated");
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
const name = requiredString({
|
|
284
|
+
group_name: row[groupNameIndex]
|
|
285
|
+
}, "group_name").trim();
|
|
286
|
+
if (!name) throw new Error("group_name must be a non-empty string");
|
|
287
|
+
const roleIds = parseSessionRoleAssignments(row[roleAssignmentsIndex]);
|
|
288
|
+
const before = await this.store.snapshot();
|
|
289
|
+
this.resolveGroupRoleAssignments(roleIds, before);
|
|
290
|
+
const existingGroupIds = new Set(before.groups.map(({ id })=>id));
|
|
291
|
+
await this.store.addGroup({
|
|
292
|
+
name
|
|
293
|
+
});
|
|
294
|
+
const snapshot = await this.store.snapshot();
|
|
295
|
+
const group = snapshot.groups.find(({ id, name: groupName })=>!existingGroupIds.has(id) && groupName === name);
|
|
296
|
+
if (!group) throw new Error("Created group could not be found");
|
|
297
|
+
await this.saveGroupRoleAssignments(group.id, roleIds, snapshot);
|
|
298
|
+
sessionTable.update(String(row[keyIndex]), "vuuMsg", "group created");
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
async saveGroupRoleAssignments(groupId, desiredRoleIds, snapshot) {
|
|
302
|
+
if (!snapshot.groups.some(({ id })=>id === groupId)) throw new Error(`User admin group not found: ${groupId}`);
|
|
303
|
+
const groupRoles = snapshot.groupRoles.filter(({ group })=>group.id === groupId);
|
|
304
|
+
const roleAssignmentsById = new Map(snapshot.clientRoles.map((assignment)=>[
|
|
305
|
+
assignment.role.id,
|
|
306
|
+
assignment
|
|
307
|
+
]));
|
|
308
|
+
const desiredRoleSet = new Set(desiredRoleIds);
|
|
309
|
+
const currentAssignments = groupRoles.map(({ role })=>{
|
|
310
|
+
const assignment = roleAssignmentsById.get(role.id);
|
|
311
|
+
if (!assignment) throw new Error(`Assigned user admin role no longer exists: ${role.id}`);
|
|
312
|
+
return assignment;
|
|
313
|
+
});
|
|
314
|
+
const currentRoleSet = new Set(groupRoles.map(({ role })=>role.id));
|
|
315
|
+
const desiredAssignments = this.resolveGroupRoleAssignments(desiredRoleIds, snapshot);
|
|
316
|
+
for (const assignment of currentAssignments)if (!desiredRoleSet.has(assignment.role.id)) {
|
|
317
|
+
const clientRef = assignment.role.clientRole && assignment.client?.clientId ? {
|
|
318
|
+
clientKey: assignment.client.clientId
|
|
319
|
+
} : void 0;
|
|
320
|
+
await this.store.removeRoleFromGroup({
|
|
321
|
+
groupId
|
|
322
|
+
}, {
|
|
323
|
+
roleId: assignment.role.id
|
|
324
|
+
}, clientRef);
|
|
325
|
+
}
|
|
326
|
+
for (const assignment of desiredAssignments)if (!currentRoleSet.has(assignment.role.id)) {
|
|
327
|
+
const clientRef = assignment.role.clientRole && assignment.client?.clientId ? {
|
|
328
|
+
clientKey: assignment.client.clientId
|
|
329
|
+
} : void 0;
|
|
330
|
+
await this.store.addRoleToGroup({
|
|
331
|
+
groupId
|
|
332
|
+
}, {
|
|
333
|
+
roleId: assignment.role.id
|
|
334
|
+
}, clientRef);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
resolveGroupRoleAssignments(roleIds, snapshot) {
|
|
338
|
+
const roleAssignmentsById = new Map(snapshot.clientRoles.map((assignment)=>[
|
|
339
|
+
assignment.role.id,
|
|
340
|
+
assignment
|
|
341
|
+
]));
|
|
342
|
+
return roleIds.map((roleId)=>{
|
|
343
|
+
const assignment = roleAssignmentsById.get(roleId);
|
|
344
|
+
if (!assignment) throw new Error(`User admin role not found: ${roleId}`);
|
|
345
|
+
if (assignment.role.clientRole && !assignment.client?.clientId) throw new Error(`User admin client role has no owning client: ${roleId}`);
|
|
346
|
+
return assignment;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
async saveClientRolesFromSession(sessionTable) {
|
|
350
|
+
const actionIndex = sessionTable.map.vuuAction;
|
|
351
|
+
const messageIndex = sessionTable.map.vuuMsg;
|
|
352
|
+
const keyIndex = sessionTable.map[sessionTable.schema.key];
|
|
353
|
+
const snapshot = await this.store.snapshot();
|
|
354
|
+
const clientsById = new Map(snapshot.clients.map((client)=>[
|
|
355
|
+
client.id,
|
|
356
|
+
client
|
|
357
|
+
]));
|
|
358
|
+
const pendingRoles = [
|
|
359
|
+
...sessionTable.data
|
|
360
|
+
].flatMap((row)=>{
|
|
361
|
+
if ("addRow" !== row[actionIndex] || row[messageIndex]) return [];
|
|
362
|
+
const params = Object.fromEntries(sessionTable.schema.columns.map(({ name })=>[
|
|
363
|
+
name,
|
|
364
|
+
row[sessionTable.map[name]]
|
|
365
|
+
]));
|
|
366
|
+
const roleName = requiredString(params, "role_name").trim();
|
|
367
|
+
if (!roleName) throw new Error("role_name must be a non-empty string");
|
|
368
|
+
const clientId = requiredString(params, "client_id");
|
|
369
|
+
const clientIdentifier = requiredString(params, "client_identifier");
|
|
370
|
+
const client = clientsById.get(clientId);
|
|
371
|
+
if (!client || client.clientId !== clientIdentifier) throw new Error("client_id and client_identifier must identify the same client");
|
|
372
|
+
return [
|
|
373
|
+
{
|
|
374
|
+
client,
|
|
375
|
+
description: optionalString(params, "description") ?? "",
|
|
376
|
+
roleName,
|
|
377
|
+
row
|
|
378
|
+
}
|
|
379
|
+
];
|
|
380
|
+
});
|
|
381
|
+
for (const { client, description, roleName, row } of pendingRoles){
|
|
382
|
+
await this.store.addClientRole({
|
|
383
|
+
clientKey: client.clientId
|
|
384
|
+
}, {
|
|
385
|
+
description,
|
|
386
|
+
name: roleName
|
|
387
|
+
});
|
|
388
|
+
sessionTable.update(String(row[keyIndex]), "vuuMsg", "client role created");
|
|
389
|
+
}
|
|
235
390
|
}
|
|
236
391
|
mutation = (rpcName, mutate)=>async (request)=>{
|
|
237
392
|
try {
|
|
@@ -6,6 +6,34 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
6
6
|
enabled: true,
|
|
7
7
|
id: "client-portal",
|
|
8
8
|
name: "VUU Portal"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
clientId: "vuu-user-admin",
|
|
12
|
+
description: "User administration",
|
|
13
|
+
enabled: true,
|
|
14
|
+
id: "client-user-admin",
|
|
15
|
+
name: "User Admin"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
clientId: "vuu-basket-trading",
|
|
19
|
+
description: "Basket trading",
|
|
20
|
+
enabled: true,
|
|
21
|
+
id: "client-basket-trading",
|
|
22
|
+
name: "Basket Trading"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
clientId: "vuu-module-admin",
|
|
26
|
+
description: "Module administration",
|
|
27
|
+
enabled: true,
|
|
28
|
+
id: "client-module-admin",
|
|
29
|
+
name: "Module Admin"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
clientId: "vuu-feature-filter-table",
|
|
33
|
+
description: "Instrument tables",
|
|
34
|
+
enabled: true,
|
|
35
|
+
id: "client-feature-filter-table",
|
|
36
|
+
name: "Instruments"
|
|
9
37
|
}
|
|
10
38
|
],
|
|
11
39
|
clientRoles: [
|
|
@@ -67,13 +95,13 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
67
95
|
},
|
|
68
96
|
{
|
|
69
97
|
client: {
|
|
70
|
-
clientId: "vuu-
|
|
71
|
-
id: "client-
|
|
72
|
-
name: "
|
|
98
|
+
clientId: "vuu-user-admin",
|
|
99
|
+
id: "client-user-admin",
|
|
100
|
+
name: "User Admin"
|
|
73
101
|
},
|
|
74
102
|
role: {
|
|
75
103
|
clientRole: true,
|
|
76
|
-
containerId: "client-
|
|
104
|
+
containerId: "client-user-admin",
|
|
77
105
|
id: "role-user-admin-admin",
|
|
78
106
|
name: "user-admin-admin",
|
|
79
107
|
roleDisplayName: "admin"
|
|
@@ -81,13 +109,13 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
81
109
|
},
|
|
82
110
|
{
|
|
83
111
|
client: {
|
|
84
|
-
clientId: "vuu-
|
|
85
|
-
id: "client-
|
|
86
|
-
name: "
|
|
112
|
+
clientId: "vuu-module-admin",
|
|
113
|
+
id: "client-module-admin",
|
|
114
|
+
name: "Module Admin"
|
|
87
115
|
},
|
|
88
116
|
role: {
|
|
89
117
|
clientRole: true,
|
|
90
|
-
containerId: "client-
|
|
118
|
+
containerId: "client-module-admin",
|
|
91
119
|
id: "role-module-admin-admin",
|
|
92
120
|
name: "module-admin-admin",
|
|
93
121
|
roleDisplayName: "admin"
|
|
@@ -95,29 +123,17 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
95
123
|
},
|
|
96
124
|
{
|
|
97
125
|
client: {
|
|
98
|
-
clientId: "vuu-
|
|
99
|
-
id: "client-
|
|
100
|
-
name: "
|
|
126
|
+
clientId: "vuu-basket-trading",
|
|
127
|
+
id: "client-basket-trading",
|
|
128
|
+
name: "Basket Trading"
|
|
101
129
|
},
|
|
102
130
|
role: {
|
|
103
131
|
clientRole: true,
|
|
104
|
-
containerId: "client-
|
|
132
|
+
containerId: "client-basket-trading",
|
|
105
133
|
id: "role-basket-trading-trade",
|
|
106
134
|
name: "basket-trading-trade",
|
|
107
135
|
roleDisplayName: "trade"
|
|
108
136
|
}
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
client: {
|
|
112
|
-
clientId: "realm",
|
|
113
|
-
id: "realm",
|
|
114
|
-
name: "Realm"
|
|
115
|
-
},
|
|
116
|
-
role: {
|
|
117
|
-
id: "role-admin",
|
|
118
|
-
name: "admin",
|
|
119
|
-
roleDisplayName: "admin"
|
|
120
|
-
}
|
|
121
137
|
}
|
|
122
138
|
],
|
|
123
139
|
groupRoles: [
|
|
@@ -225,9 +241,9 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
225
241
|
},
|
|
226
242
|
{
|
|
227
243
|
client: {
|
|
228
|
-
clientId: "vuu-
|
|
229
|
-
id: "client-
|
|
230
|
-
name: "
|
|
244
|
+
clientId: "vuu-user-admin",
|
|
245
|
+
id: "client-user-admin",
|
|
246
|
+
name: "User Admin"
|
|
231
247
|
},
|
|
232
248
|
group: {
|
|
233
249
|
id: "group-user-admin-admin",
|
|
@@ -261,9 +277,9 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
261
277
|
},
|
|
262
278
|
{
|
|
263
279
|
client: {
|
|
264
|
-
clientId: "vuu-
|
|
265
|
-
id: "client-
|
|
266
|
-
name: "
|
|
280
|
+
clientId: "vuu-module-admin",
|
|
281
|
+
id: "client-module-admin",
|
|
282
|
+
name: "Module Admin"
|
|
267
283
|
},
|
|
268
284
|
group: {
|
|
269
285
|
id: "group-module-admin-admin",
|
|
@@ -297,9 +313,9 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
297
313
|
},
|
|
298
314
|
{
|
|
299
315
|
client: {
|
|
300
|
-
clientId: "vuu-
|
|
301
|
-
id: "client-
|
|
302
|
-
name: "
|
|
316
|
+
clientId: "vuu-basket-trading",
|
|
317
|
+
id: "client-basket-trading",
|
|
318
|
+
name: "Basket Trading"
|
|
303
319
|
},
|
|
304
320
|
group: {
|
|
305
321
|
id: "group-basket-trading-trade",
|
|
@@ -312,19 +328,6 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
312
328
|
name: "basket-trading-trade",
|
|
313
329
|
roleDisplayName: "trade"
|
|
314
330
|
}
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
group: {
|
|
318
|
-
id: "group-admins",
|
|
319
|
-
name: "administrators",
|
|
320
|
-
groupDisplayName: "administrators",
|
|
321
|
-
path: "/vuu/administrators"
|
|
322
|
-
},
|
|
323
|
-
role: {
|
|
324
|
-
id: "role-admin",
|
|
325
|
-
name: "admin",
|
|
326
|
-
roleDisplayName: "admin"
|
|
327
|
-
}
|
|
328
331
|
}
|
|
329
332
|
],
|
|
330
333
|
groups: [
|
|
@@ -381,12 +384,6 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
381
384
|
name: "basket-trading-trade",
|
|
382
385
|
groupDisplayName: "trade",
|
|
383
386
|
path: "/vuu/basket-trading-trade"
|
|
384
|
-
},
|
|
385
|
-
{
|
|
386
|
-
id: "group-admins",
|
|
387
|
-
name: "administrators",
|
|
388
|
-
groupDisplayName: "administrators",
|
|
389
|
-
path: "/vuu/administrators"
|
|
390
387
|
}
|
|
391
388
|
],
|
|
392
389
|
timestamp: 1710000000000,
|
|
@@ -438,19 +435,6 @@ const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
|
438
435
|
id: "user-alice",
|
|
439
436
|
username: "alice"
|
|
440
437
|
}
|
|
441
|
-
},
|
|
442
|
-
{
|
|
443
|
-
group: {
|
|
444
|
-
id: "group-admins",
|
|
445
|
-
name: "administrators",
|
|
446
|
-
groupDisplayName: "administrators",
|
|
447
|
-
path: "/vuu/administrators"
|
|
448
|
-
},
|
|
449
|
-
user: {
|
|
450
|
-
email: "alice@example.com",
|
|
451
|
-
id: "user-alice",
|
|
452
|
-
username: "alice"
|
|
453
|
-
}
|
|
454
438
|
}
|
|
455
439
|
],
|
|
456
440
|
users: [
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
+
import { type LocalVuuServer } from "@vuu-ui/core";
|
|
1
2
|
import type { ReactNode } from "react";
|
|
2
|
-
|
|
3
|
+
import type { VuuModule } from "../core/module/VuuModule";
|
|
4
|
+
/** Data context covering every VuuModule registered in the browser. */
|
|
5
|
+
export declare const LocalDataSourceProvider: ({ children }: {
|
|
3
6
|
children: ReactNode;
|
|
4
7
|
}) => import("react").JSX.Element;
|
|
8
|
+
export interface LocalVuuServerOptions {
|
|
9
|
+
/** Matches the `vuu.connectionId` of the modules this server serves. */
|
|
10
|
+
connectionId: string;
|
|
11
|
+
modules: VuuModule<any>[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Simulates a Vuu server in the browser, publishing the tables of the given
|
|
15
|
+
* modules. Pass the result to a local-mode `AuthenticationProvider` as one of
|
|
16
|
+
* its `localServers`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const createLocalVuuServer: ({ connectionId, modules, }: LocalVuuServerOptions) => LocalVuuServer;
|
|
@@ -25,7 +25,11 @@ export declare class UserAdminModule extends VuuModule<UserAdminTableName> {
|
|
|
25
25
|
reconcile(): Promise<void>;
|
|
26
26
|
protected createSessionTable(sourceTable: Table, sessionTableName: string, editSessionMode: import("@vuu-ui/vuu-data-types").EditSessionMode | import("@vuu-ui/vuu-data-types").CopyOption, dataSource: import("../TickingArrayDataSource").TickingArrayDataSource, sessionType?: import("@vuu-ui/vuu-data-types").SessionType): Table;
|
|
27
27
|
protected beforeSessionSave(sourceTable: Table, sessionTable: Table): Promise<void>;
|
|
28
|
-
protected afterSessionSave(sourceTable: Table): Promise<void>;
|
|
28
|
+
protected afterSessionSave(sourceTable: Table, sessionTable: Table): Promise<void>;
|
|
29
|
+
private saveGroupsFromSession;
|
|
30
|
+
private saveGroupRoleAssignments;
|
|
31
|
+
private resolveGroupRoleAssignments;
|
|
32
|
+
private saveClientRolesFromSession;
|
|
29
33
|
private mutation;
|
|
30
34
|
private addUser;
|
|
31
35
|
private updateUser;
|