@vuu-ui/vuu-data-test 4.0.0-alpha.2 → 4.0.0-alpha.20
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/README.md +8 -0
- package/package.json +11 -9
- package/src/Table.js +5 -5
- package/src/core/filter/PermissionFilter.js +60 -0
- package/src/core/filter/PermissionFilteredTable.js +59 -0
- package/src/core/module/ModuleContainer.js +8 -0
- package/src/core/module/VuuModule.js +54 -6
- package/src/core/table/TableContainer.js +1 -1
- package/src/core/user/CurrentUser.js +13 -0
- package/src/index.js +7 -0
- package/src/local-datasource-provider/LocalDatasourceProvider.js +53 -43
- package/src/module-admin/ModuleAdminModule.js +124 -0
- package/src/module-admin/index.js +3 -0
- package/src/module-admin/module-admin-schemas.js +107 -0
- package/src/module-admin/snapshot-projection.js +29 -0
- package/src/notifications/NotificationModule.js +93 -0
- package/src/notifications/NotificationsSchema.js +52 -0
- package/src/notifications/index.js +6 -0
- package/src/notifications/simulated/DismissNotificationRpcHandler.js +36 -0
- package/src/notifications/simulated/SimulatedNotificationsModule.js +14 -0
- package/src/notifications/simulated/SimulatedNotificationsProvider.js +151 -0
- package/src/notifications/simulated/notificationsModule.js +3 -0
- package/src/schemas.js +8 -2
- package/src/user-admin/UserAdminModule.js +567 -0
- package/src/user-admin/index.js +3 -0
- package/src/user-admin/initialSnapshot.js +461 -0
- package/src/user-admin/snapshot-projection.js +151 -0
- package/types/core/filter/PermissionFilter.d.ts +41 -0
- package/types/core/filter/PermissionFilteredTable.d.ts +24 -0
- package/types/core/module/ModuleContainer.d.ts +6 -3
- package/types/core/module/VuuModule.d.ts +22 -0
- package/types/core/table/TableContainer.d.ts +5 -5
- package/types/core/user/CurrentUser.d.ts +14 -0
- package/types/index.d.ts +7 -0
- package/types/local-datasource-provider/LocalDatasourceProvider.d.ts +15 -1
- package/types/module-admin/ModuleAdminModule.d.ts +32 -0
- package/types/module-admin/index.d.ts +4 -0
- package/types/module-admin/module-admin-schemas.d.ts +4 -0
- package/types/module-admin/snapshot-projection.d.ts +13 -0
- package/types/notifications/NotificationModule.d.ts +39 -0
- package/types/notifications/NotificationsSchema.d.ts +20 -0
- package/types/notifications/index.d.ts +6 -0
- package/types/notifications/simulated/DismissNotificationRpcHandler.d.ts +8 -0
- package/types/notifications/simulated/SimulatedNotificationsModule.d.ts +2 -0
- package/types/notifications/simulated/SimulatedNotificationsProvider.d.ts +21 -0
- package/types/notifications/simulated/notificationsModule.d.ts +5 -0
- package/types/schemas.d.ts +5 -3
- package/types/user-admin/UserAdminModule.d.ts +54 -0
- package/types/user-admin/index.d.ts +3 -0
- package/types/user-admin/initialSnapshot.d.ts +2 -0
- package/types/user-admin/snapshot-projection.d.ts +9 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
const USER_ADMIN_INITIAL_SNAPSHOT = {
|
|
2
|
+
clients: [
|
|
3
|
+
{
|
|
4
|
+
clientId: "vuu-portal",
|
|
5
|
+
description: "VUU portal",
|
|
6
|
+
enabled: true,
|
|
7
|
+
id: "client-portal",
|
|
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"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
clientRoles: [
|
|
40
|
+
{
|
|
41
|
+
client: {
|
|
42
|
+
clientId: "vuu-portal",
|
|
43
|
+
id: "client-portal",
|
|
44
|
+
name: "VUU Portal"
|
|
45
|
+
},
|
|
46
|
+
role: {
|
|
47
|
+
clientRole: true,
|
|
48
|
+
containerId: "client-portal",
|
|
49
|
+
id: "role-user-admin-access",
|
|
50
|
+
name: "user-admin-access",
|
|
51
|
+
roleDisplayName: "access"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
client: {
|
|
56
|
+
clientId: "vuu-portal",
|
|
57
|
+
id: "client-portal",
|
|
58
|
+
name: "VUU Portal"
|
|
59
|
+
},
|
|
60
|
+
role: {
|
|
61
|
+
clientRole: true,
|
|
62
|
+
containerId: "client-portal",
|
|
63
|
+
id: "role-feature-filter-table-access",
|
|
64
|
+
name: "feature-filter-table-access",
|
|
65
|
+
roleDisplayName: "access"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
client: {
|
|
70
|
+
clientId: "vuu-portal",
|
|
71
|
+
id: "client-portal",
|
|
72
|
+
name: "VUU Portal"
|
|
73
|
+
},
|
|
74
|
+
role: {
|
|
75
|
+
clientRole: true,
|
|
76
|
+
containerId: "client-portal",
|
|
77
|
+
id: "role-module-admin-access",
|
|
78
|
+
name: "module-admin-access",
|
|
79
|
+
roleDisplayName: "access"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
client: {
|
|
84
|
+
clientId: "vuu-portal",
|
|
85
|
+
id: "client-portal",
|
|
86
|
+
name: "VUU Portal"
|
|
87
|
+
},
|
|
88
|
+
role: {
|
|
89
|
+
clientRole: true,
|
|
90
|
+
containerId: "client-portal",
|
|
91
|
+
id: "role-basket-trading-access",
|
|
92
|
+
name: "basket-trading-access",
|
|
93
|
+
roleDisplayName: "access"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
client: {
|
|
98
|
+
clientId: "vuu-user-admin",
|
|
99
|
+
id: "client-user-admin",
|
|
100
|
+
name: "User Admin"
|
|
101
|
+
},
|
|
102
|
+
role: {
|
|
103
|
+
clientRole: true,
|
|
104
|
+
containerId: "client-user-admin",
|
|
105
|
+
id: "role-user-admin-admin",
|
|
106
|
+
name: "user-admin-admin",
|
|
107
|
+
roleDisplayName: "admin"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
client: {
|
|
112
|
+
clientId: "vuu-module-admin",
|
|
113
|
+
id: "client-module-admin",
|
|
114
|
+
name: "Module Admin"
|
|
115
|
+
},
|
|
116
|
+
role: {
|
|
117
|
+
clientRole: true,
|
|
118
|
+
containerId: "client-module-admin",
|
|
119
|
+
id: "role-module-admin-admin",
|
|
120
|
+
name: "module-admin-admin",
|
|
121
|
+
roleDisplayName: "admin"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
client: {
|
|
126
|
+
clientId: "vuu-basket-trading",
|
|
127
|
+
id: "client-basket-trading",
|
|
128
|
+
name: "Basket Trading"
|
|
129
|
+
},
|
|
130
|
+
role: {
|
|
131
|
+
clientRole: true,
|
|
132
|
+
containerId: "client-basket-trading",
|
|
133
|
+
id: "role-basket-trading-trade",
|
|
134
|
+
name: "basket-trading-trade",
|
|
135
|
+
roleDisplayName: "trade"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
groupRoles: [
|
|
140
|
+
{
|
|
141
|
+
client: {
|
|
142
|
+
clientId: "vuu-portal",
|
|
143
|
+
id: "client-portal",
|
|
144
|
+
name: "VUU Portal"
|
|
145
|
+
},
|
|
146
|
+
group: {
|
|
147
|
+
id: "group-user-admin-read",
|
|
148
|
+
name: "user-admin-read",
|
|
149
|
+
groupDisplayName: "read",
|
|
150
|
+
moduleAccessDefaultRoles: [
|
|
151
|
+
"user-admin-access"
|
|
152
|
+
],
|
|
153
|
+
path: "/vuu/user-admin-read"
|
|
154
|
+
},
|
|
155
|
+
role: {
|
|
156
|
+
id: "role-user-admin-access",
|
|
157
|
+
name: "user-admin-access",
|
|
158
|
+
roleDisplayName: "access"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
client: {
|
|
163
|
+
clientId: "vuu-portal",
|
|
164
|
+
id: "client-portal",
|
|
165
|
+
name: "VUU Portal"
|
|
166
|
+
},
|
|
167
|
+
group: {
|
|
168
|
+
id: "group-feature-filter-table-read",
|
|
169
|
+
name: "feature-filter-table-read",
|
|
170
|
+
groupDisplayName: "read",
|
|
171
|
+
moduleAccessDefaultRoles: [
|
|
172
|
+
"feature-filter-table-access"
|
|
173
|
+
],
|
|
174
|
+
path: "/vuu/feature-filter-table-read"
|
|
175
|
+
},
|
|
176
|
+
role: {
|
|
177
|
+
id: "role-feature-filter-table-access",
|
|
178
|
+
name: "feature-filter-table-access",
|
|
179
|
+
roleDisplayName: "access"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
client: {
|
|
184
|
+
clientId: "vuu-portal",
|
|
185
|
+
id: "client-portal",
|
|
186
|
+
name: "VUU Portal"
|
|
187
|
+
},
|
|
188
|
+
group: {
|
|
189
|
+
id: "group-module-admin-read",
|
|
190
|
+
name: "module-admin-read",
|
|
191
|
+
groupDisplayName: "read",
|
|
192
|
+
moduleAccessDefaultRoles: [
|
|
193
|
+
"module-admin-access"
|
|
194
|
+
],
|
|
195
|
+
path: "/vuu/module-admin-read"
|
|
196
|
+
},
|
|
197
|
+
role: {
|
|
198
|
+
id: "role-module-admin-access",
|
|
199
|
+
name: "module-admin-access",
|
|
200
|
+
roleDisplayName: "access"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
client: {
|
|
205
|
+
clientId: "vuu-portal",
|
|
206
|
+
id: "client-portal",
|
|
207
|
+
name: "VUU Portal"
|
|
208
|
+
},
|
|
209
|
+
group: {
|
|
210
|
+
id: "group-basket-trading-read",
|
|
211
|
+
name: "basket-trading-read",
|
|
212
|
+
groupDisplayName: "read",
|
|
213
|
+
moduleAccessDefaultRoles: [
|
|
214
|
+
"basket-trading-access"
|
|
215
|
+
],
|
|
216
|
+
path: "/vuu/basket-trading-read"
|
|
217
|
+
},
|
|
218
|
+
role: {
|
|
219
|
+
id: "role-basket-trading-access",
|
|
220
|
+
name: "basket-trading-access",
|
|
221
|
+
roleDisplayName: "access"
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
client: {
|
|
226
|
+
clientId: "vuu-portal",
|
|
227
|
+
id: "client-portal",
|
|
228
|
+
name: "VUU Portal"
|
|
229
|
+
},
|
|
230
|
+
group: {
|
|
231
|
+
id: "group-user-admin-admin",
|
|
232
|
+
name: "user-admin-admin",
|
|
233
|
+
groupDisplayName: "admin",
|
|
234
|
+
path: "/vuu/user-admin-admin"
|
|
235
|
+
},
|
|
236
|
+
role: {
|
|
237
|
+
id: "role-user-admin-access",
|
|
238
|
+
name: "user-admin-access",
|
|
239
|
+
roleDisplayName: "access"
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
client: {
|
|
244
|
+
clientId: "vuu-user-admin",
|
|
245
|
+
id: "client-user-admin",
|
|
246
|
+
name: "User Admin"
|
|
247
|
+
},
|
|
248
|
+
group: {
|
|
249
|
+
id: "group-user-admin-admin",
|
|
250
|
+
name: "user-admin-admin",
|
|
251
|
+
groupDisplayName: "admin",
|
|
252
|
+
path: "/vuu/user-admin-admin"
|
|
253
|
+
},
|
|
254
|
+
role: {
|
|
255
|
+
id: "role-user-admin-admin",
|
|
256
|
+
name: "user-admin-admin",
|
|
257
|
+
roleDisplayName: "admin"
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
client: {
|
|
262
|
+
clientId: "vuu-portal",
|
|
263
|
+
id: "client-portal",
|
|
264
|
+
name: "VUU Portal"
|
|
265
|
+
},
|
|
266
|
+
group: {
|
|
267
|
+
id: "group-module-admin-admin",
|
|
268
|
+
name: "module-admin-admin",
|
|
269
|
+
groupDisplayName: "admin",
|
|
270
|
+
path: "/vuu/module-admin-admin"
|
|
271
|
+
},
|
|
272
|
+
role: {
|
|
273
|
+
id: "role-module-admin-access",
|
|
274
|
+
name: "module-admin-access",
|
|
275
|
+
roleDisplayName: "access"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
client: {
|
|
280
|
+
clientId: "vuu-module-admin",
|
|
281
|
+
id: "client-module-admin",
|
|
282
|
+
name: "Module Admin"
|
|
283
|
+
},
|
|
284
|
+
group: {
|
|
285
|
+
id: "group-module-admin-admin",
|
|
286
|
+
name: "module-admin-admin",
|
|
287
|
+
groupDisplayName: "admin",
|
|
288
|
+
path: "/vuu/module-admin-admin"
|
|
289
|
+
},
|
|
290
|
+
role: {
|
|
291
|
+
id: "role-module-admin-admin",
|
|
292
|
+
name: "module-admin-admin",
|
|
293
|
+
roleDisplayName: "admin"
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
client: {
|
|
298
|
+
clientId: "vuu-portal",
|
|
299
|
+
id: "client-portal",
|
|
300
|
+
name: "VUU Portal"
|
|
301
|
+
},
|
|
302
|
+
group: {
|
|
303
|
+
id: "group-basket-trading-trade",
|
|
304
|
+
name: "basket-trading-trade",
|
|
305
|
+
groupDisplayName: "trade",
|
|
306
|
+
path: "/vuu/basket-trading-trade"
|
|
307
|
+
},
|
|
308
|
+
role: {
|
|
309
|
+
id: "role-basket-trading-access",
|
|
310
|
+
name: "basket-trading-access",
|
|
311
|
+
roleDisplayName: "access"
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
client: {
|
|
316
|
+
clientId: "vuu-basket-trading",
|
|
317
|
+
id: "client-basket-trading",
|
|
318
|
+
name: "Basket Trading"
|
|
319
|
+
},
|
|
320
|
+
group: {
|
|
321
|
+
id: "group-basket-trading-trade",
|
|
322
|
+
name: "basket-trading-trade",
|
|
323
|
+
groupDisplayName: "trade",
|
|
324
|
+
path: "/vuu/basket-trading-trade"
|
|
325
|
+
},
|
|
326
|
+
role: {
|
|
327
|
+
id: "role-basket-trading-trade",
|
|
328
|
+
name: "basket-trading-trade",
|
|
329
|
+
roleDisplayName: "trade"
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
],
|
|
333
|
+
groups: [
|
|
334
|
+
{
|
|
335
|
+
id: "group-user-admin-read",
|
|
336
|
+
name: "user-admin-read",
|
|
337
|
+
groupDisplayName: "read",
|
|
338
|
+
moduleAccessDefaultRoles: [
|
|
339
|
+
"user-admin-access"
|
|
340
|
+
],
|
|
341
|
+
path: "/vuu/user-admin-read"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
id: "group-module-admin-read",
|
|
345
|
+
name: "module-admin-read",
|
|
346
|
+
groupDisplayName: "read",
|
|
347
|
+
moduleAccessDefaultRoles: [
|
|
348
|
+
"module-admin-access"
|
|
349
|
+
],
|
|
350
|
+
path: "/vuu/module-admin-read"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
id: "group-basket-trading-read",
|
|
354
|
+
name: "basket-trading-read",
|
|
355
|
+
groupDisplayName: "read",
|
|
356
|
+
moduleAccessDefaultRoles: [
|
|
357
|
+
"basket-trading-access"
|
|
358
|
+
],
|
|
359
|
+
path: "/vuu/basket-trading-read"
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
id: "group-feature-filter-table-read",
|
|
363
|
+
name: "feature-filter-table-read",
|
|
364
|
+
groupDisplayName: "read",
|
|
365
|
+
moduleAccessDefaultRoles: [
|
|
366
|
+
"feature-filter-table-access"
|
|
367
|
+
],
|
|
368
|
+
path: "/vuu/feature-filter-table-read"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
id: "group-user-admin-admin",
|
|
372
|
+
name: "user-admin-admin",
|
|
373
|
+
groupDisplayName: "admin",
|
|
374
|
+
path: "/vuu/user-admin-admin"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
id: "group-module-admin-admin",
|
|
378
|
+
name: "module-admin-admin",
|
|
379
|
+
groupDisplayName: "admin",
|
|
380
|
+
path: "/vuu/module-admin-admin"
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: "group-basket-trading-trade",
|
|
384
|
+
name: "basket-trading-trade",
|
|
385
|
+
groupDisplayName: "trade",
|
|
386
|
+
path: "/vuu/basket-trading-trade"
|
|
387
|
+
}
|
|
388
|
+
],
|
|
389
|
+
timestamp: 1710000000000,
|
|
390
|
+
userGroups: [
|
|
391
|
+
{
|
|
392
|
+
group: {
|
|
393
|
+
id: "group-user-admin-read",
|
|
394
|
+
name: "user-admin-read",
|
|
395
|
+
groupDisplayName: "read",
|
|
396
|
+
moduleAccessDefaultRoles: [
|
|
397
|
+
"user-admin-access"
|
|
398
|
+
],
|
|
399
|
+
path: "/vuu/user-admin-read"
|
|
400
|
+
},
|
|
401
|
+
user: {
|
|
402
|
+
email: "alice@example.com",
|
|
403
|
+
id: "user-alice",
|
|
404
|
+
username: "alice"
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
group: {
|
|
409
|
+
id: "group-module-admin-read",
|
|
410
|
+
name: "module-admin-read",
|
|
411
|
+
groupDisplayName: "read",
|
|
412
|
+
moduleAccessDefaultRoles: [
|
|
413
|
+
"module-admin-access"
|
|
414
|
+
],
|
|
415
|
+
path: "/vuu/module-admin-read"
|
|
416
|
+
},
|
|
417
|
+
user: {
|
|
418
|
+
email: "bob@example.com",
|
|
419
|
+
id: "user-bob",
|
|
420
|
+
username: "bob"
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
group: {
|
|
425
|
+
id: "group-basket-trading-read",
|
|
426
|
+
name: "basket-trading-read",
|
|
427
|
+
groupDisplayName: "read",
|
|
428
|
+
moduleAccessDefaultRoles: [
|
|
429
|
+
"basket-trading-access"
|
|
430
|
+
],
|
|
431
|
+
path: "/vuu/basket-trading-read"
|
|
432
|
+
},
|
|
433
|
+
user: {
|
|
434
|
+
email: "alice@example.com",
|
|
435
|
+
id: "user-alice",
|
|
436
|
+
username: "alice"
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
],
|
|
440
|
+
users: [
|
|
441
|
+
{
|
|
442
|
+
email: "alice@example.com",
|
|
443
|
+
emailVerified: true,
|
|
444
|
+
enabled: true,
|
|
445
|
+
firstName: "Alice",
|
|
446
|
+
id: "user-alice",
|
|
447
|
+
lastName: "Admin",
|
|
448
|
+
username: "alice"
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
email: "bob@example.com",
|
|
452
|
+
emailVerified: true,
|
|
453
|
+
enabled: true,
|
|
454
|
+
firstName: "Bob",
|
|
455
|
+
id: "user-bob",
|
|
456
|
+
lastName: "Builder",
|
|
457
|
+
username: "bob"
|
|
458
|
+
}
|
|
459
|
+
]
|
|
460
|
+
};
|
|
461
|
+
export { USER_ADMIN_INITIAL_SNAPSHOT };
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const rowsEqual = (left, right)=>left.length === right.length && left.every((value, index)=>value === right[index]);
|
|
2
|
+
const membershipId = (userId, groupId)=>`${userId}:${groupId}`;
|
|
3
|
+
const assignmentId = (groupId, roleId)=>`${groupId}:${roleId}`;
|
|
4
|
+
const resolveDisplayName = (name, configuredDisplayName)=>configuredDisplayName ?? name.split("-").at(-1) ?? name;
|
|
5
|
+
const groupDisplayName = ({ groupDisplayName: configuredDisplayName, name })=>resolveDisplayName(name, configuredDisplayName);
|
|
6
|
+
const roleDisplayName = ({ roleDisplayName: configuredDisplayName, name })=>resolveDisplayName(name, configuredDisplayName);
|
|
7
|
+
const systemValues = (timestamp)=>({
|
|
8
|
+
vuuCreatedTimestamp: timestamp,
|
|
9
|
+
vuuMsg: "",
|
|
10
|
+
vuuUpdatedTimestamp: timestamp
|
|
11
|
+
});
|
|
12
|
+
const toRow = (table, values)=>table.schema.columns.map(({ name })=>values[name] ?? "");
|
|
13
|
+
const userRoleIds = (snapshot, userId)=>{
|
|
14
|
+
const groupIds = new Set(snapshot.userGroups.filter(({ user })=>user.id === userId).map(({ group })=>group.id));
|
|
15
|
+
return new Set(snapshot.groupRoles.filter(({ group })=>groupIds.has(group.id)).map(({ role })=>role.id));
|
|
16
|
+
};
|
|
17
|
+
const moduleAccessRoles = (snapshot, userId)=>Array.from(new Set(snapshot.groupRoles.filter(({ group, role })=>snapshot.userGroups.some(({ user, group: userGroup })=>user.id === userId && userGroup.id === group.id) && role.name.endsWith("-access")).map(({ role })=>role.name))).sort();
|
|
18
|
+
const projectUserAdminSnapshot = (snapshot, tables)=>{
|
|
19
|
+
const system = systemValues(snapshot.timestamp);
|
|
20
|
+
const membershipRows = snapshot.userGroups.map(({ user, group })=>({
|
|
21
|
+
group,
|
|
22
|
+
membership_id: membershipId(user.id, group.id),
|
|
23
|
+
user
|
|
24
|
+
}));
|
|
25
|
+
const assignmentRows = snapshot.groupRoles.map(({ client, group, role })=>({
|
|
26
|
+
assignment_id: assignmentId(group.id, role.id),
|
|
27
|
+
client,
|
|
28
|
+
group,
|
|
29
|
+
role
|
|
30
|
+
}));
|
|
31
|
+
return {
|
|
32
|
+
users: snapshot.users.map((user)=>{
|
|
33
|
+
const accessRoles = moduleAccessRoles(snapshot, user.id);
|
|
34
|
+
return toRow(tables.users, {
|
|
35
|
+
...system,
|
|
36
|
+
email: user.email ?? "",
|
|
37
|
+
email_verified: user.emailVerified ?? false,
|
|
38
|
+
enabled: user.enabled ?? true,
|
|
39
|
+
first_name: user.firstName ?? "",
|
|
40
|
+
group_count: snapshot.userGroups.filter(({ user: member })=>member.id === user.id).length,
|
|
41
|
+
last_login: 0,
|
|
42
|
+
last_name: user.lastName ?? "",
|
|
43
|
+
module_access: accessRoles.join(","),
|
|
44
|
+
module_access_count: accessRoles.length,
|
|
45
|
+
password_update_required: user.requiredActions?.includes("UPDATE_PASSWORD") ?? false,
|
|
46
|
+
role_count: userRoleIds(snapshot, user.id).size,
|
|
47
|
+
user_id: user.id,
|
|
48
|
+
username: user.username
|
|
49
|
+
});
|
|
50
|
+
}),
|
|
51
|
+
groups: snapshot.groups.map((group)=>toRow(tables.groups, {
|
|
52
|
+
...system,
|
|
53
|
+
group_display_name: groupDisplayName(group),
|
|
54
|
+
group_id: group.id,
|
|
55
|
+
group_path: group.path ?? `/${group.name}`,
|
|
56
|
+
parent_group_id: group.parentId ?? "",
|
|
57
|
+
role_count: snapshot.groupRoles.filter(({ group: assignmentGroup })=>assignmentGroup.id === group.id).length,
|
|
58
|
+
user_count: snapshot.userGroups.filter(({ group: memberGroup })=>memberGroup.id === group.id).length
|
|
59
|
+
})),
|
|
60
|
+
clients: snapshot.clients.map((client)=>toRow(tables.clients, {
|
|
61
|
+
...system,
|
|
62
|
+
client_id: client.id,
|
|
63
|
+
client_identifier: client.clientId,
|
|
64
|
+
client_name: client.name ?? "",
|
|
65
|
+
description: client.description ?? "",
|
|
66
|
+
enabled: client.enabled ?? true
|
|
67
|
+
})),
|
|
68
|
+
roles: snapshot.clientRoles.map(({ client, role })=>toRow(tables.roles, {
|
|
69
|
+
...system,
|
|
70
|
+
client_id: role.containerId ?? client.id,
|
|
71
|
+
client_identifier: client.clientId,
|
|
72
|
+
client_name: client.name ?? "",
|
|
73
|
+
description: role.description ?? "",
|
|
74
|
+
group_count: snapshot.groupRoles.filter(({ role: groupRole })=>groupRole.id === role.id).length,
|
|
75
|
+
role_id: role.id,
|
|
76
|
+
role_display_name: roleDisplayName(role),
|
|
77
|
+
role_name: role.name,
|
|
78
|
+
user_count: new Set(snapshot.userGroups.filter(({ group })=>snapshot.groupRoles.some(({ group: roleGroup, role: groupRole })=>group.id === roleGroup.id && groupRole.id === role.id)).map(({ user })=>user.id)).size
|
|
79
|
+
})),
|
|
80
|
+
user_groups: membershipRows.map(({ group, membership_id, user })=>toRow(tables.user_groups, {
|
|
81
|
+
...system,
|
|
82
|
+
group_display_name: groupDisplayName(group),
|
|
83
|
+
group_id: group.id,
|
|
84
|
+
group_name: group.name,
|
|
85
|
+
group_path: group.path ?? `/${group.name}`,
|
|
86
|
+
membership_id,
|
|
87
|
+
user_id: user.id,
|
|
88
|
+
username: user.username
|
|
89
|
+
})),
|
|
90
|
+
group_roles: assignmentRows.map(({ assignment_id, client, group, role })=>toRow(tables.group_roles, {
|
|
91
|
+
...system,
|
|
92
|
+
assignment_id,
|
|
93
|
+
client_id: client?.id ?? "",
|
|
94
|
+
client_identifier: client?.clientId ?? "",
|
|
95
|
+
client_name: client?.name ?? "",
|
|
96
|
+
group_id: group.id,
|
|
97
|
+
group_display_name: groupDisplayName(group),
|
|
98
|
+
group_name: group.name,
|
|
99
|
+
role_id: role.id,
|
|
100
|
+
role_display_name: roleDisplayName(role),
|
|
101
|
+
role_name: role.name
|
|
102
|
+
})),
|
|
103
|
+
user_group_roles: membershipRows.flatMap(({ group, membership_id, user })=>assignmentRows.filter(({ group: assignmentGroup })=>assignmentGroup.id === group.id).map(({ assignment_id, client, role })=>toRow(tables.user_group_roles, {
|
|
104
|
+
...system,
|
|
105
|
+
assignment_id,
|
|
106
|
+
client_id: client?.id ?? "",
|
|
107
|
+
client_identifier: client?.clientId ?? "",
|
|
108
|
+
client_name: client?.name ?? "",
|
|
109
|
+
email: user.email ?? "",
|
|
110
|
+
email_verified: user.emailVerified ?? false,
|
|
111
|
+
enabled: user.enabled ?? true,
|
|
112
|
+
first_name: user.firstName ?? "",
|
|
113
|
+
group_id: group.id,
|
|
114
|
+
group_display_name: groupDisplayName(group),
|
|
115
|
+
group_name: group.name,
|
|
116
|
+
group_path: group.path ?? `/${group.name}`,
|
|
117
|
+
id: `${membership_id}:${assignment_id}`,
|
|
118
|
+
last_login: 0,
|
|
119
|
+
last_name: user.lastName ?? "",
|
|
120
|
+
membership_id,
|
|
121
|
+
password_update_required: user.requiredActions?.includes("UPDATE_PASSWORD") ?? false,
|
|
122
|
+
role_id: role.id,
|
|
123
|
+
role_display_name: roleDisplayName(role),
|
|
124
|
+
role_name: role.name,
|
|
125
|
+
user_id: user.id,
|
|
126
|
+
username: user.username
|
|
127
|
+
})))
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
const reconcileUserAdminTables = (snapshot, tables)=>{
|
|
131
|
+
const projected = projectUserAdminSnapshot(snapshot, tables);
|
|
132
|
+
for (const tableName of Object.keys(tables)){
|
|
133
|
+
const table = tables[tableName];
|
|
134
|
+
const desiredRows = projected[tableName];
|
|
135
|
+
const keyIndex = table.map[table.schema.key];
|
|
136
|
+
const desiredKeys = new Set(desiredRows.map((row)=>String(row[keyIndex])));
|
|
137
|
+
for (const existingRow of [
|
|
138
|
+
...table.data
|
|
139
|
+
]){
|
|
140
|
+
const key = String(existingRow[keyIndex]);
|
|
141
|
+
if (!desiredKeys.has(key)) table.delete(key);
|
|
142
|
+
}
|
|
143
|
+
for (const row of desiredRows){
|
|
144
|
+
const key = String(row[keyIndex]);
|
|
145
|
+
const existingRow = table.findByKey(key);
|
|
146
|
+
if (void 0 === existingRow) table.insert(row);
|
|
147
|
+
else if (!rowsEqual(existingRow, row)) table.updateRow(row);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
export { projectUserAdminSnapshot, reconcileUserAdminTables, resolveDisplayName };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
|
|
2
|
+
import type { VuuModuleUser } from "../user/CurrentUser";
|
|
3
|
+
import type { ColumnMap } from "@vuu-ui/vuu-utils";
|
|
4
|
+
import type tableContainer from "../table/TableContainer";
|
|
5
|
+
export type TableRow = Array<bigint | VuuRowDataItemType>;
|
|
6
|
+
export type RowPredicate = (row: TableRow) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Read access to a single row, by column name.
|
|
9
|
+
*/
|
|
10
|
+
export interface RowData {
|
|
11
|
+
get: (columnName: string) => bigint | VuuRowDataItemType | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Restricts the rows of a table visible through a viewport, typically
|
|
15
|
+
* based on the user that owns the viewport. Permission filters are applied
|
|
16
|
+
* in addition to any client filter.
|
|
17
|
+
*/
|
|
18
|
+
export interface PermissionFilter {
|
|
19
|
+
/**
|
|
20
|
+
* Bind this permission filter to the column layout of a table, returning a
|
|
21
|
+
* predicate that can be evaluated against raw table rows.
|
|
22
|
+
*/
|
|
23
|
+
createPredicate: (columnMap: ColumnMap) => RowPredicate;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The subset of viewport state available to a PermissionFunction.
|
|
27
|
+
*/
|
|
28
|
+
export interface PermissionViewport {
|
|
29
|
+
id: string;
|
|
30
|
+
user: VuuModuleUser;
|
|
31
|
+
}
|
|
32
|
+
export type TableContainer = typeof tableContainer;
|
|
33
|
+
/**
|
|
34
|
+
* Creates the PermissionFilter for a viewport. Configured per table on a VuuModule.
|
|
35
|
+
*/
|
|
36
|
+
export type PermissionFunction = (viewport: PermissionViewport, tableContainer: TableContainer) => PermissionFilter;
|
|
37
|
+
export declare const AllowAllPermissionFilter: PermissionFilter;
|
|
38
|
+
export declare const DenyAllPermissionFilter: PermissionFilter;
|
|
39
|
+
export declare function PermissionFilter(rowPredicate: (row: RowData) => boolean): PermissionFilter;
|
|
40
|
+
export declare function PermissionFilter(columnName: string, allowedValues: Set<string>): PermissionFilter;
|
|
41
|
+
export declare function PermissionFilter(filters: Iterable<PermissionFilter>): PermissionFilter;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Table } from "../../Table";
|
|
2
|
+
import type { RowPredicate } from "./PermissionFilter";
|
|
3
|
+
/**
|
|
4
|
+
* A per-viewport view of a source table, containing only those rows that
|
|
5
|
+
* satisfy a permission predicate. Changes to the source table are mirrored,
|
|
6
|
+
* an update that moves a row into or out of the permitted set is emitted as
|
|
7
|
+
* an insert or delete.
|
|
8
|
+
*/
|
|
9
|
+
export declare class PermissionFilteredTable extends Table {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(source: Table, predicate: RowPredicate);
|
|
12
|
+
get source(): Table;
|
|
13
|
+
/**
|
|
14
|
+
* Start mirroring changes from the source table. Invoked on construction,
|
|
15
|
+
* only needs to be called again following dispose.
|
|
16
|
+
*/
|
|
17
|
+
attach(): void;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
private contains;
|
|
20
|
+
private handleSourceInsert;
|
|
21
|
+
private handleSourceUpdate;
|
|
22
|
+
private handleSourceDelete;
|
|
23
|
+
private replaceRow;
|
|
24
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { VuuModule } from "./VuuModule";
|
|
1
|
+
import type { VuuModule } from "./VuuModule";
|
|
2
|
+
type RegisteredVuuModule = VuuModule<any>;
|
|
2
3
|
declare class ModuleContainer {
|
|
3
4
|
#private;
|
|
4
5
|
private constructor();
|
|
5
6
|
static get instance(): ModuleContainer;
|
|
6
|
-
register(module:
|
|
7
|
-
|
|
7
|
+
register(module: RegisteredVuuModule): void;
|
|
8
|
+
has(name: string): boolean;
|
|
9
|
+
get(name: string): RegisteredVuuModule;
|
|
8
10
|
get moduleNames(): MapIterator<string>;
|
|
9
11
|
}
|
|
10
12
|
declare const _default: ModuleContainer;
|
|
11
13
|
export default _default;
|
|
14
|
+
export declare const ensureVuuModule: <T extends RegisteredVuuModule>(module: T) => T;
|