@nu-art/permissions-backend 0.401.8 → 0.500.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 (49) hide show
  1. package/PermissionKey_BE.d.ts +9 -6
  2. package/PermissionKey_BE.js +20 -9
  3. package/RequirePermission.d.ts +21 -0
  4. package/RequirePermission.js +47 -0
  5. package/_entity/permission-access-level/ModuleBE_PermissionAccessLevelDB.d.ts +5 -9
  6. package/_entity/permission-access-level/ModuleBE_PermissionAccessLevelDB.js +1 -7
  7. package/_entity/permission-access-level/module-pack.d.ts +1 -1
  8. package/_entity/permission-access-level/module-pack.js +2 -2
  9. package/_entity/permission-api/ModuleBE_PermissionAPIDB.d.ts +6 -8
  10. package/_entity/permission-api/ModuleBE_PermissionAPIDB.js +4 -4
  11. package/_entity/permission-api/module-pack.d.ts +1 -1
  12. package/_entity/permission-api/module-pack.js +2 -2
  13. package/_entity/permission-domain/ModuleBE_PermissionDomainDB.d.ts +4 -10
  14. package/_entity/permission-domain/ModuleBE_PermissionDomainDB.js +1 -4
  15. package/_entity/permission-domain/module-pack.d.ts +1 -1
  16. package/_entity/permission-domain/module-pack.js +2 -2
  17. package/_entity/permission-group/ModuleBE_PermissionGroupDB.d.ts +5 -7
  18. package/_entity/permission-group/ModuleBE_PermissionGroupDB.js +10 -7
  19. package/_entity/permission-group/module-pack.d.ts +1 -1
  20. package/_entity/permission-group/module-pack.js +2 -2
  21. package/_entity/permission-project/ModuleBE_PermissionProjectDB.d.ts +4 -6
  22. package/_entity/permission-project/ModuleBE_PermissionProjectDB.js +1 -1
  23. package/_entity/permission-project/module-pack.d.ts +1 -1
  24. package/_entity/permission-project/module-pack.js +2 -2
  25. package/_entity/permission-user/ModuleBE_PermissionUserAPI.d.ts +4 -3
  26. package/_entity/permission-user/ModuleBE_PermissionUserAPI.js +63 -10
  27. package/_entity/permission-user/ModuleBE_PermissionUserDB.d.ts +8 -10
  28. package/_entity/permission-user/ModuleBE_PermissionUserDB.js +33 -18
  29. package/core/external-api-paths.d.ts +13 -0
  30. package/core/external-api-paths.js +13 -0
  31. package/core/function-permission-registry.d.ts +25 -0
  32. package/core/function-permission-registry.js +50 -0
  33. package/core/utils.d.ts +4 -4
  34. package/core/utils.js +7 -7
  35. package/index.d.ts +5 -0
  36. package/index.js +5 -0
  37. package/modules/ModuleBE_Permissions.d.ts +10 -4
  38. package/modules/ModuleBE_Permissions.js +365 -264
  39. package/modules/ModuleBE_PermissionsAssert.d.ts +20 -3
  40. package/modules/ModuleBE_PermissionsAssert.js +271 -205
  41. package/modules/consts.d.ts +2 -2
  42. package/modules/consts.js +5 -5
  43. package/modules/index.d.ts +1 -0
  44. package/modules/index.js +1 -0
  45. package/package.json +13 -12
  46. package/permissions-wire.d.ts +46 -0
  47. package/permissions-wire.js +47 -0
  48. package/permissions.js +29 -31
  49. package/types.d.ts +3 -3
@@ -1,15 +1,51 @@
1
- import { _keys, arrayToMap, Dispatcher, filterInstances, flatArray, Module, MUSTNeverHappenException, reduceToMap, RuntimeModules, } from '@nu-art/ts-common';
2
- import { addRoutes, createQueryServerApi, MemKey_ServerApi, ModuleBE_AppConfigDB, Storm } from '@nu-art/thunderstorm-backend';
3
- import { ApiDef_Permissions, DefaultAccessLevel_Admin, DefaultAccessLevel_NoAccess, DefaultAccessLevel_Read, DefaultAccessLevel_Write, defaultLevelsRouteLookupWords, DuplicateDefaultAccessLevels, } from '@nu-art/permissions-shared';
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
8
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
+ var _, done = false;
14
+ for (var i = decorators.length - 1; i >= 0; i--) {
15
+ var context = {};
16
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
+ if (kind === "accessor") {
21
+ if (result === void 0) continue;
22
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
+ if (_ = accept(result.get)) descriptor.get = _;
24
+ if (_ = accept(result.set)) descriptor.set = _;
25
+ if (_ = accept(result.init)) initializers.unshift(_);
26
+ }
27
+ else if (_ = accept(result)) {
28
+ if (kind === "field") initializers.unshift(_);
29
+ else descriptor[key] = _;
30
+ }
31
+ }
32
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
+ done = true;
34
+ };
35
+ import { _keys, arrayToMap, Dispatcher, filterInstances, flatArray, md5, Module, MUSTNeverHappenException, reduceToMap, } from '@nu-art/ts-common';
36
+ import { ApiHandler, MemKey_ServerApi } from '@nu-art/http-server';
37
+ import { RuntimeBE_Modules } from '@nu-art/db-api-backend';
38
+ import { ApiDef_Permissions, DefaultAccessLevel_Admin, DefaultAccessLevel_Delete, DefaultAccessLevel_NoAccess, DefaultAccessLevel_Read, DefaultAccessLevel_Write, defaultLevelsRouteLookupWords, DuplicateDefaultAccessLevels, toPermissionDomainId, toPermissionGroupId, toPermissionProjectId, trimStartingForwardSlash, } from '@nu-art/permissions-shared';
4
39
  import { MemKey_AccountId, ModuleBE_SessionDB } from '@nu-art/user-account-backend';
40
+ import { getRegisteredFunctionPermissions } from '../core/function-permission-registry.js';
5
41
  import { Domain_AccountManagement, Domain_Developer, Domain_PermissionsAssign, Domain_PermissionsDefine, PermissionsPackage_Developer, PermissionsPackage_Permissions } from '../permissions.js';
6
42
  import { ModuleBE_PermissionsAssert } from './ModuleBE_PermissionsAssert.js';
43
+ import { getCreatePermissionKeyDefaults, getEnvConfigRef } from '../permissions-wire.js';
7
44
  import { ModuleBE_PermissionAccessLevelDB, ModuleBE_PermissionAPIDB, ModuleBE_PermissionDomainDB, ModuleBE_PermissionGroupDB, ModuleBE_PermissionProjectDB, ModuleBE_PermissionUserDB } from '../_entity.js';
8
- import { trimStartingForwardSlash } from '@nu-art/thunderstorm-shared/route-tools';
9
45
  const dispatcher_collectPermissionsProjects = new Dispatcher('__collectPermissionsProjects');
10
46
  const GroupId_SuperAdmin = '8b54efda69b385a566735cca7be031d5';
11
47
  export const PermissionGroup_Permissions_SuperAdmin = {
12
- _id: GroupId_SuperAdmin,
48
+ _id: toPermissionGroupId(GroupId_SuperAdmin),
13
49
  name: 'Super Admin',
14
50
  uiLabel: 'Super Admin',
15
51
  accessLevels: {
@@ -20,7 +56,7 @@ export const PermissionGroup_Permissions_SuperAdmin = {
20
56
  }
21
57
  };
22
58
  export const PermissionGroup_Permissions_Viewer = {
23
- _id: '8c38d3bd2d76bbc37b5281f481c0bc1b',
59
+ _id: toPermissionGroupId('8c38d3bd2d76bbc37b5281f481c0bc1b'),
24
60
  name: 'Permissions Viewer',
25
61
  uiLabel: 'Permissions Viewer',
26
62
  accessLevels: {
@@ -30,7 +66,7 @@ export const PermissionGroup_Permissions_Viewer = {
30
66
  }
31
67
  };
32
68
  export const PermissionGroup_Permissions_Editor = {
33
- _id: '1524909cae174d0052b76a469b339218',
69
+ _id: toPermissionGroupId('1524909cae174d0052b76a469b339218'),
34
70
  name: 'Permissions Editor',
35
71
  uiLabel: 'Permissions Editor',
36
72
  accessLevels: {
@@ -40,7 +76,7 @@ export const PermissionGroup_Permissions_Editor = {
40
76
  }
41
77
  };
42
78
  export const PermissionGroup_Account_Manager = {
43
- _id: '6bb5feb12d0712ecee77f7f44188ec79',
79
+ _id: toPermissionGroupId('6bb5feb12d0712ecee77f7f44188ec79'),
44
80
  name: 'Accounts Manager',
45
81
  uiLabel: 'Accounts Manager',
46
82
  accessLevels: {
@@ -48,7 +84,7 @@ export const PermissionGroup_Account_Manager = {
48
84
  }
49
85
  };
50
86
  export const PermissionGroup_Account_Admin = {
51
- _id: '761a84bdde3f9be3fde9c50402a60401',
87
+ _id: toPermissionGroupId('761a84bdde3f9be3fde9c50402a60401'),
52
88
  name: 'Accounts Admin',
53
89
  uiLabel: 'Accounts Admin',
54
90
  accessLevels: {
@@ -56,7 +92,7 @@ export const PermissionGroup_Account_Admin = {
56
92
  }
57
93
  };
58
94
  export const PermissionGroup_Account_Viewer = {
59
- _id: '7343853a980149ec94f967ac7ff4ccc3',
95
+ _id: toPermissionGroupId('7343853a980149ec94f967ac7ff4ccc3'),
60
96
  name: 'Accounts Viewer',
61
97
  uiLabel: 'Accounts Viewer',
62
98
  accessLevels: {
@@ -80,278 +116,343 @@ export const PermissionGroups_Permissions = [
80
116
  // },
81
117
  ];
82
118
  export const PermissionProject_Permissions = {
83
- _id: 'f60db83936835e0be33e89caa365f0c3',
119
+ _id: toPermissionProjectId('f60db83936835e0be33e89caa365f0c3'),
84
120
  name: 'Permissions',
85
121
  packages: [PermissionsPackage_Permissions, PermissionsPackage_Developer],
86
122
  groups: PermissionGroups_Permissions
87
123
  };
88
- class ModuleBE_Permissions_Class extends Module {
89
- init() {
90
- super.init();
91
- addRoutes([
92
- createQueryServerApi(ApiDef_Permissions.v1.toggleStrictMode, this.toggleStrictMode),
93
- createQueryServerApi(ApiDef_Permissions.v1.createProject, this.__performProjectSetup().processor),
94
- // createBodyServerApi(ApiDef_Permissions.v1.connectDomainToRoutes, this.connectDomainToRoutes)
95
- ]);
96
- }
97
- // __collectPermissionsProjects() {
98
- // return PermissionProject_Permissions;
99
- // }
100
- async __collectSessionData(data) {
101
- const permissionUser = await ModuleBE_PermissionUserDB.query.uniqueAssert(data.accountId);
102
- const userGroups = filterInstances(await ModuleBE_PermissionGroupDB.query.all(permissionUser.groups.map(g => g.groupId)));
103
- const permissionMap = await this.getUserPermissionMap(userGroups);
104
- return {
105
- key: 'permissions', value: {
106
- domainToValueMap: permissionMap,
107
- roles: userGroups.map(group => ({ key: group.label, uiLabel: group.uiLabel })),
108
- }
109
- };
110
- }
111
- getUserPermissionMap = async (userGroups) => {
112
- const permissionMap = {};
113
- const levelMaps = filterInstances(userGroups.map(i => i._levelsMap));
114
- levelMaps.forEach(levelMap => {
115
- _keys(levelMap).forEach(domainId => {
116
- if (!permissionMap[domainId])
117
- permissionMap[domainId] = 0;
118
- if (levelMap[domainId] > permissionMap[domainId])
119
- permissionMap[domainId] = levelMap[domainId];
124
+ let ModuleBE_Permissions_Class = (() => {
125
+ let _classSuper = Module;
126
+ let _instanceExtraInitializers = [];
127
+ let _toggleStrictMode_decorators;
128
+ let _createProject_decorators;
129
+ return class ModuleBE_Permissions_Class extends _classSuper {
130
+ static {
131
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
132
+ _toggleStrictMode_decorators = [ApiHandler(ApiDef_Permissions.toggleStrictMode)];
133
+ _createProject_decorators = [ApiHandler(ApiDef_Permissions.createProject)];
134
+ __esDecorate(this, null, _toggleStrictMode_decorators, { kind: "method", name: "toggleStrictMode", static: false, private: false, access: { has: obj => "toggleStrictMode" in obj, get: obj => obj.toggleStrictMode }, metadata: _metadata }, null, _instanceExtraInitializers);
135
+ __esDecorate(this, null, _createProject_decorators, { kind: "method", name: "createProject", static: false, private: false, access: { has: obj => "createProject" in obj, get: obj => obj.createProject }, metadata: _metadata }, null, _instanceExtraInitializers);
136
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
137
+ }
138
+ init() {
139
+ super.init();
140
+ }
141
+ async toggleStrictMode(_params) {
142
+ const envConfigRef = getEnvConfigRef(ModuleBE_PermissionsAssert);
143
+ if (!envConfigRef)
144
+ return;
145
+ MemKey_ServerApi.get().addPostCallAction(async () => {
146
+ const currentConfig = await envConfigRef.get({});
147
+ currentConfig.strictMode = !currentConfig.strictMode;
148
+ await envConfigRef.set(currentConfig);
120
149
  });
121
- });
122
- //All domains that are not defined for the user, are NoAccess by default.
123
- const allDomains = await ModuleBE_PermissionDomainDB.query.where({});
124
- allDomains.forEach(domain => {
125
- if (!permissionMap[domain._id])
126
- permissionMap[domain._id] = DefaultAccessLevel_NoAccess.value; //"fill in the gaps" - All domains that are not defined for the user, are NoAccess by default.
127
- });
128
- return permissionMap;
129
- };
130
- toggleStrictMode = async () => {
131
- MemKey_ServerApi.get().addPostCallAction(async () => {
132
- const envConfigRef = Storm.getInstance().getEnvConfigRef(ModuleBE_PermissionsAssert);
133
- const currentConfig = await envConfigRef.get({});
134
- currentConfig.strictMode = !currentConfig.strictMode;
135
- await envConfigRef.set(currentConfig);
136
- });
137
- };
138
- __performProjectSetup() {
139
- return {
140
- priority: 0,
141
- processor: async () => {
142
- const projects = dispatcher_collectPermissionsProjects.dispatchModule();
143
- projects.reduce((issues, project) => {
144
- return project.packages.reduce((issues, _package) => {
145
- return issues;
146
- }, issues);
147
- }, []);
148
- // Create All Projects
149
- await this.createPermissionProjects(projects);
150
- // Create all AppConfigs
151
- await this.createPermissionsKeys(projects);
152
- //Assign Super Admin if necessary
153
- await this.assignSuperAdmin();
154
- }
155
- };
156
- }
157
- ;
158
- async createPermissionProjects(projects) {
159
- const map_nameToDBProject = await this.createProjects(projects);
160
- const map_nameToDbDomain = await this.createDomains(projects, map_nameToDBProject);
161
- const domainNameToLevelNameToDBAccessLevel = await this.createAccessLevels(projects, map_nameToDbDomain);
162
- await this.createGroups(projects, map_nameToDbDomain, domainNameToLevelNameToDBAccessLevel);
163
- await this.createApis(projects, domainNameToLevelNameToDBAccessLevel);
164
- }
165
- /**
166
- * Creates All the DB_PermissionProject
167
- *
168
- * @param projects - predefined permissions projects
169
- */
170
- async createProjects(projects) {
171
- this.logInfoBold('Creating Projects');
172
- const _auditorId = MemKey_AccountId.get();
173
- const preDBProjects = await ModuleBE_PermissionProjectDB.set.all(projects.map(project => ({
174
- _id: project._id,
175
- name: project.name,
176
- _auditorId
177
- })));
178
- const projectsMap_nameToDBProject = reduceToMap(preDBProjects, project => project.name, project => project);
179
- this.logInfoBold(`Created ${preDBProjects.length} Projects`);
180
- return projectsMap_nameToDBProject;
181
- }
182
- /**
183
- * Creates All the DB_PermissionDomains
184
- *
185
- * @param projects - predefined permissions projects
186
- * @param map_nameToDBProject
187
- */
188
- async createDomains(projects, map_nameToDBProject) {
189
- this.logInfoBold('Creating Domains');
190
- const _auditorId = MemKey_AccountId.get();
191
- const domainsToUpsert = flatArray(projects.map(project => project.packages.map(_package => _package.domains.map(domain => ({
192
- _id: domain._id,
193
- namespace: domain.namespace,
194
- projectId: map_nameToDBProject[project.name]._id,
195
- _auditorId
196
- })))));
197
- const dbDomain = await ModuleBE_PermissionDomainDB.set.all(domainsToUpsert);
198
- const domainsMap_nameToDbDomain = reduceToMap(dbDomain, domain => domain.namespace, domain => domain);
199
- this.logInfoBold(`Created ${dbDomain.length} Domains`);
200
- return domainsMap_nameToDbDomain;
201
- }
202
- /**
203
- * Creates All the DB_PermissionAccessLevel
204
- *
205
- * @param projects - predefined permissions projects
206
- * @param map_nameToDbDomain
207
- */
208
- async createAccessLevels(projects, map_nameToDbDomain) {
209
- this.logInfoBold('Creating Access Levels');
210
- const _auditorId = MemKey_AccountId.get();
211
- const levelsToUpsert = flatArray(projects.map(project => project.packages.map(_package => _package.domains.map(domain => {
212
- let levels = domain.levels;
213
- if (!levels)
214
- levels = DuplicateDefaultAccessLevels(domain._id);
215
- return levels.map(level => {
216
- return {
217
- _id: level._id,
218
- domainId: map_nameToDbDomain[domain.namespace]._id,
219
- value: level.value,
220
- name: level.name,
221
- uiLabel: level.name,
222
- _auditorId
223
- };
150
+ }
151
+ async createProject(_params) {
152
+ await this.__performProjectSetup().processor();
153
+ }
154
+ // __collectPermissionsProjects() {
155
+ // return PermissionProject_Permissions;
156
+ // }
157
+ async __collectSessionData(data) {
158
+ const permissionUserId = data.accountId;
159
+ const permissionUser = await ModuleBE_PermissionUserDB.query.uniqueAssert(permissionUserId);
160
+ const userGroups = filterInstances(await ModuleBE_PermissionGroupDB.query.all(permissionUser.groups.map(g => g.groupId)));
161
+ const permissionMap = await this.getUserPermissionMap(userGroups);
162
+ return {
163
+ key: 'permissions', value: {
164
+ domainToValueMap: permissionMap,
165
+ roles: userGroups.map(group => ({ key: group.label, uiLabel: group.uiLabel })),
166
+ }
167
+ };
168
+ }
169
+ getUserPermissionMap = (__runInitializers(this, _instanceExtraInitializers), async (userGroups) => {
170
+ const permissionMap = {};
171
+ const levelMaps = filterInstances(userGroups.map(i => i._levelsMap));
172
+ levelMaps.forEach(levelMap => {
173
+ _keys(levelMap).forEach(domainId => {
174
+ if (!permissionMap[domainId])
175
+ permissionMap[domainId] = 0;
176
+ if (levelMap[domainId] > permissionMap[domainId])
177
+ permissionMap[domainId] = levelMap[domainId];
178
+ });
224
179
  });
225
- }))));
226
- const dbLevels = await ModuleBE_PermissionAccessLevelDB.set.all(levelsToUpsert);
227
- const domainNameToLevelNameToDBAccessLevel = reduceToMap(dbLevels, level => level.domainId, (level, index, map) => {
228
- const domainLevels = map[level.domainId] || (map[level.domainId] = {});
229
- domainLevels[level.name] = level;
230
- return domainLevels;
180
+ //All domains that are not defined for the user, are NoAccess by default.
181
+ const allDomains = await ModuleBE_PermissionDomainDB.query.where({});
182
+ allDomains.forEach(domain => {
183
+ if (!permissionMap[domain._id])
184
+ permissionMap[domain._id] = DefaultAccessLevel_NoAccess.value; //"fill in the gaps" - All domains that are not defined for the user, are NoAccess by default.
185
+ });
186
+ return permissionMap;
231
187
  });
232
- this.logInfoBold(`Created ${dbLevels.length} Access Levels`);
233
- return domainNameToLevelNameToDBAccessLevel;
234
- }
235
- /**
236
- * Creates All the DB_PermissionGroup
237
- *
238
- * @param projects - predefined permissions projects
239
- * @param map_nameToDbDomain
240
- * @param domainNameToLevelNameToDBAccessLevel
241
- */
242
- async createGroups(projects, map_nameToDbDomain, domainNameToLevelNameToDBAccessLevel) {
243
- this.logInfoBold('Creating Groups');
244
- const _auditorId = MemKey_AccountId.get();
245
- const groupsToUpsert = flatArray(projects.map(project => {
246
- const groupsDef = flatArray([...project.packages.map(p => p.groups || []), ...project.groups || []]);
247
- return (groupsDef).map(group => {
248
- return {
249
- projectId: project._id,
250
- _id: group._id,
251
- _auditorId,
252
- label: group.name,
253
- uiLabel: group.name,
254
- accessLevelIds: _keys(group.accessLevels)
255
- .map(key => {
256
- const domainsMapNameToDbDomainElement = map_nameToDbDomain[key];
257
- if (!domainsMapNameToDbDomainElement)
258
- throw new MUSTNeverHappenException(`bah for key ${key}`);
259
- return domainNameToLevelNameToDBAccessLevel[domainsMapNameToDbDomainElement._id][group.accessLevels[key]]._id;
260
- })
261
- };
188
+ __performProjectSetup() {
189
+ return {
190
+ priority: 100,
191
+ processor: async () => {
192
+ const projects = dispatcher_collectPermissionsProjects.dispatchModule();
193
+ projects.reduce((issues, project) => {
194
+ return project.packages.reduce((issues, _package) => {
195
+ return issues;
196
+ }, issues);
197
+ }, []);
198
+ // Create All Projects
199
+ await this.createPermissionProjects(projects);
200
+ // Create domains/levels from function-permission registry (decorator-collected)
201
+ if (projects.length > 0)
202
+ await this.createDomainsAndLevelsFromFunctionPermissionRegistry(projects[0]._id);
203
+ // Create all AppConfigs
204
+ await this.createPermissionsKeys(projects);
205
+ //Assign Super Admin if necessary
206
+ await this.assignSuperAdmin();
207
+ }
208
+ };
209
+ }
210
+ /**
211
+ * Creates domains and access levels from the function-permission registry (populated by @RequirePermission decorators).
212
+ * New (scopeKey, value) pairs get domains/levels created; not assigned to anyone until explicitly assigned.
213
+ */
214
+ async createDomainsAndLevelsFromFunctionPermissionRegistry(projectId) {
215
+ const defs = getRegisteredFunctionPermissions();
216
+ if (defs.length === 0)
217
+ return;
218
+ this.logInfoBold('Creating domains/levels from function-permission registry');
219
+ const _auditorId = MemKey_AccountId.get();
220
+ const uniqueScopeKeys = [...new Set(defs.map(d => d.scopeKey))];
221
+ const domainIdByScopeKey = {};
222
+ for (const scopeKey of uniqueScopeKeys) {
223
+ const domainId = toPermissionDomainId(md5(`function-permission-domain/${scopeKey}`));
224
+ domainIdByScopeKey[scopeKey] = domainId;
225
+ await ModuleBE_PermissionDomainDB.set.all([{
226
+ _id: domainId,
227
+ namespace: scopeKey,
228
+ projectId,
229
+ _auditorId
230
+ }]);
231
+ }
232
+ const levelValueByName = {
233
+ 'No-Access': DefaultAccessLevel_NoAccess.value,
234
+ 'Read': DefaultAccessLevel_Read.value,
235
+ 'Write': DefaultAccessLevel_Write.value,
236
+ 'Delete': DefaultAccessLevel_Delete.value,
237
+ 'Admin': DefaultAccessLevel_Admin.value
238
+ };
239
+ for (const def of defs) {
240
+ const domainId = domainIdByScopeKey[def.scopeKey];
241
+ const levelValue = levelValueByName[def.value] ?? 100;
242
+ const levelId = md5(`${domainId}/${def.value}`);
243
+ await ModuleBE_PermissionAccessLevelDB.set.all([{
244
+ _id: levelId,
245
+ domainId,
246
+ name: def.value,
247
+ value: levelValue,
248
+ uiLabel: def.value,
249
+ _auditorId
250
+ }]);
251
+ def.domainId = domainId;
252
+ def.levelId = levelId;
253
+ def.levelValue = levelValue;
254
+ }
255
+ this.logInfoBold(`Created ${uniqueScopeKeys.length} domains and ${defs.length} access levels from function-permission registry`);
256
+ }
257
+ ;
258
+ async createPermissionProjects(projects) {
259
+ const map_nameToDBProject = await this.createProjects(projects);
260
+ const map_nameToDbDomain = await this.createDomains(projects, map_nameToDBProject);
261
+ const domainNameToLevelNameToDBAccessLevel = await this.createAccessLevels(projects, map_nameToDbDomain);
262
+ await this.createGroups(projects, map_nameToDbDomain, domainNameToLevelNameToDBAccessLevel);
263
+ await this.createApis(projects, domainNameToLevelNameToDBAccessLevel);
264
+ }
265
+ /**
266
+ * Creates All the DB_PermissionProject
267
+ *
268
+ * @param projects - predefined permissions projects
269
+ */
270
+ async createProjects(projects) {
271
+ this.logInfoBold('Creating Projects');
272
+ const _auditorId = MemKey_AccountId.get();
273
+ const preDBProjects = await ModuleBE_PermissionProjectDB.set.all(projects.map(project => ({
274
+ _id: project._id,
275
+ name: project.name,
276
+ _auditorId
277
+ })));
278
+ const projectsMap_nameToDBProject = reduceToMap(preDBProjects, project => project.name, project => project);
279
+ this.logInfoBold(`Created ${preDBProjects.length} Projects`);
280
+ return projectsMap_nameToDBProject;
281
+ }
282
+ /**
283
+ * Creates All the DB_PermissionDomains
284
+ *
285
+ * @param projects - predefined permissions projects
286
+ * @param map_nameToDBProject
287
+ */
288
+ async createDomains(projects, map_nameToDBProject) {
289
+ this.logInfoBold('Creating Domains');
290
+ const _auditorId = MemKey_AccountId.get();
291
+ const domainsToUpsert = flatArray(projects.map(project => project.packages.map(_package => _package.domains.map(domain => ({
292
+ _id: domain._id,
293
+ namespace: domain.namespace,
294
+ projectId: map_nameToDBProject[project.name]._id,
295
+ _auditorId
296
+ })))));
297
+ const dbDomain = await ModuleBE_PermissionDomainDB.set.all(domainsToUpsert);
298
+ const domainsMap_nameToDbDomain = reduceToMap(dbDomain, domain => domain.namespace, domain => domain);
299
+ this.logInfoBold(`Created ${dbDomain.length} Domains`);
300
+ return domainsMap_nameToDbDomain;
301
+ }
302
+ /**
303
+ * Creates All the DB_PermissionAccessLevel
304
+ *
305
+ * @param projects - predefined permissions projects
306
+ * @param map_nameToDbDomain
307
+ */
308
+ async createAccessLevels(projects, map_nameToDbDomain) {
309
+ this.logInfoBold('Creating Access Levels');
310
+ const _auditorId = MemKey_AccountId.get();
311
+ const levelsToUpsert = flatArray(projects.map(project => project.packages.map(_package => _package.domains.map(domain => {
312
+ let levels = domain.levels ?? DuplicateDefaultAccessLevels(domain._id);
313
+ return levels.map(level => {
314
+ return {
315
+ _id: level._id,
316
+ domainId: map_nameToDbDomain[domain.namespace]._id,
317
+ value: level.value,
318
+ name: level.name,
319
+ uiLabel: level.name,
320
+ _auditorId
321
+ };
322
+ });
323
+ }))));
324
+ const dbLevels = await ModuleBE_PermissionAccessLevelDB.set.all(levelsToUpsert);
325
+ const domainNameToLevelNameToDBAccessLevel = reduceToMap(dbLevels, level => level.domainId, (level, index, map) => {
326
+ const domainLevels = map[level.domainId] || (map[level.domainId] = {});
327
+ domainLevels[level.name] = level;
328
+ return domainLevels;
262
329
  });
263
- }));
264
- const dbGroups = await ModuleBE_PermissionGroupDB.set.all(groupsToUpsert);
265
- this.logInfoBold(`Created ${dbGroups.length} Groups`);
266
- }
267
- /**
268
- * Creates All the DB_PermissionApi
269
- *
270
- * @param projects - predefined permissions projects
271
- * @param domainNameToLevelNameToDBAccessLevel
272
- */
273
- async createApis(projects, domainNameToLevelNameToDBAccessLevel) {
274
- this.logInfoBold('Creating APIs');
275
- const _auditorId = MemKey_AccountId.get();
276
- const apisToUpsert = flatArray(projects.map(project => {
277
- return project.packages.map(_package => _package.domains.map(domain => {
278
- const apis = [];
279
- apis.push(...(domain.customApis || []).map(api => ({
280
- projectId: project._id,
281
- path: trimStartingForwardSlash(api.path),
282
- _auditorId,
283
- accessLevelIds: [domainNameToLevelNameToDBAccessLevel[api.domainId ?? domain._id][api.accessLevel]._id]
284
- })));
285
- const apiModules = arrayToMap(RuntimeModules()
286
- .filter((module) => !!module.apiDef && !!module.dbModule?.dbDef?.dbKey), item => item.dbModule.dbDef.dbKey);
287
- this.logDebug(_keys(apiModules));
288
- // / I think there is a bug here... comment it and see what happens
289
- const _apis = (domain.dbNames || []).map(dbName => {
290
- const apiModule = apiModules[dbName];
291
- if (!apiModule)
292
- throw new MUSTNeverHappenException(`Could not find api module with dbName: ${dbName}`);
293
- const _apiDefs = apiModule.apiDef;
294
- return _keys(_apiDefs).map(_apiDefKey => {
295
- const apiDefs = _apiDefs[_apiDefKey];
296
- return filterInstances(_keys(apiDefs).map(apiDefKey => {
297
- const apiDef = apiDefs[apiDefKey];
298
- const accessLevelNameToAssign = defaultLevelsRouteLookupWords[apiDef.path.substring(apiDef.path.lastIndexOf('/') + 1)];
330
+ this.logInfoBold(`Created ${dbLevels.length} Access Levels`);
331
+ return domainNameToLevelNameToDBAccessLevel;
332
+ }
333
+ /**
334
+ * Creates All the DB_PermissionGroup
335
+ *
336
+ * @param projects - predefined permissions projects
337
+ * @param map_nameToDbDomain
338
+ * @param domainNameToLevelNameToDBAccessLevel
339
+ */
340
+ async createGroups(projects, map_nameToDbDomain, domainNameToLevelNameToDBAccessLevel) {
341
+ this.logInfoBold('Creating Groups');
342
+ const _auditorId = MemKey_AccountId.get();
343
+ const groupsToUpsert = flatArray(projects.map(project => {
344
+ const groupsDef = flatArray([...project.packages.map(p => p.groups || []), ...project.groups || []]);
345
+ return (groupsDef).map(group => {
346
+ return {
347
+ projectId: project._id,
348
+ _id: group._id,
349
+ _auditorId,
350
+ label: group.name,
351
+ uiLabel: group.name,
352
+ accessLevelIds: _keys(group.accessLevels)
353
+ .map(key => {
354
+ const domainsMapNameToDbDomainElement = map_nameToDbDomain[key];
355
+ if (!domainsMapNameToDbDomainElement)
356
+ throw new MUSTNeverHappenException(`bah for key ${key}`);
357
+ return domainNameToLevelNameToDBAccessLevel[domainsMapNameToDbDomainElement._id][group.accessLevels[key]]._id;
358
+ })
359
+ };
360
+ });
361
+ }));
362
+ const dbGroups = await ModuleBE_PermissionGroupDB.set.all(groupsToUpsert);
363
+ this.logInfoBold(`Created ${dbGroups.length} Groups`);
364
+ }
365
+ /**
366
+ * Creates All the DB_PermissionApi (path-based).
367
+ * @deprecated API collection deprecated; use function-based permissions and @RequirePermission. Domains/levels from function-permission registry instead.
368
+ * @param projects - predefined permissions projects
369
+ * @param domainNameToLevelNameToDBAccessLevel
370
+ */
371
+ async createApis(projects, domainNameToLevelNameToDBAccessLevel) {
372
+ this.logInfoBold('Creating APIs');
373
+ const _auditorId = MemKey_AccountId.get();
374
+ const apisToUpsert = flatArray(projects.map(project => {
375
+ return project.packages.map(_package => _package.domains.map(domain => {
376
+ const apis = [];
377
+ apis.push(...(domain.customApis || []).map(api => ({
378
+ projectId: project._id,
379
+ path: trimStartingForwardSlash(api.path),
380
+ _auditorId,
381
+ accessLevelIds: [domainNameToLevelNameToDBAccessLevel[api.domainId ?? domain._id][api.accessLevel]._id]
382
+ })));
383
+ const apiModules = RuntimeBE_Modules();
384
+ const apiModulesMap = arrayToMap(apiModules, m => m.dbModule.dbDef.dbKey);
385
+ this.logDebug(_keys(apiModulesMap));
386
+ const crudEndpoints = ['query', 'queryUnique', 'upsert', 'upsertAll', 'deleteUnique', 'deleteQuery', 'deleteAll'];
387
+ const _apis = (domain.dbNames || []).map(dbName => {
388
+ const apiModule = apiModulesMap[dbName];
389
+ if (!apiModule)
390
+ throw new MUSTNeverHappenException(`Could not find api module with dbName: ${dbName}`);
391
+ const def = apiModule.crudApiDef;
392
+ return filterInstances(crudEndpoints.map(key => {
393
+ const endpoint = def[key];
394
+ if (!endpoint?.path)
395
+ return undefined;
396
+ const accessLevelNameToAssign = defaultLevelsRouteLookupWords[endpoint.path.substring(endpoint.path.lastIndexOf('/') + 1)];
299
397
  const accessLevel = domainNameToLevelNameToDBAccessLevel[domain._id][accessLevelNameToAssign];
300
398
  if (!accessLevel)
301
- return;
302
- const accessId = accessLevel._id;
399
+ return undefined;
303
400
  return {
304
401
  projectId: project._id,
305
- path: apiDef.path,
402
+ path: endpoint.path,
306
403
  _auditorId,
307
- accessLevelIds: [accessId]
404
+ accessLevelIds: [accessLevel._id]
308
405
  };
309
406
  }));
310
407
  });
311
- });
312
- apis.push(...flatArray(_apis));
313
- return apis;
408
+ apis.push(...flatArray(_apis));
409
+ return apis;
410
+ }));
314
411
  }));
315
- }));
316
- const dbApis = await ModuleBE_PermissionAPIDB.set.all(apisToUpsert);
317
- this.logInfoBold(`Created ${dbApis.length} APIs`);
318
- }
319
- /**
320
- * Creates permission keys associated with the given projects.
321
- *
322
- * @param projects - An array of projects.
323
- */
324
- async createPermissionsKeys(projects) {
325
- this.logInfoBold('Creating App Config');
326
- // const permissionKeysToCreate: PermissionKey_BE<any>[] = filterInstances(flatArray(projects.map(project => project.packages.map(_package => _package.domains.map(domain => domain.permissionKeys)))));
327
- try {
328
- await ModuleBE_AppConfigDB.createDefaults(this);
329
- this.logInfoBold('Created Permission Key defaults.');
412
+ const dbApis = await ModuleBE_PermissionAPIDB.set.all(apisToUpsert);
413
+ this.logInfoBold(`Created ${dbApis.length} APIs`);
330
414
  }
331
- catch (e) {
332
- this.logErrorBold('Failed creating Permission Key defaults.', e);
415
+ /**
416
+ * Creates permission keys associated with the given projects.
417
+ *
418
+ * @param projects - An array of projects.
419
+ */
420
+ async createPermissionsKeys(_projects) {
421
+ this.logInfoBold('Creating App Config');
422
+ const createDefaults = getCreatePermissionKeyDefaults();
423
+ if (createDefaults) {
424
+ try {
425
+ await createDefaults(this);
426
+ this.logInfoBold('Created Permission Key defaults.');
427
+ }
428
+ catch (e) {
429
+ this.logErrorBold('Failed creating Permission Key defaults.', e);
430
+ }
431
+ }
432
+ this.logInfoBold('Created App Config');
333
433
  }
334
- this.logInfoBold('Created App Config');
335
- }
336
- /**
337
- * If no "Super Admin" user is defined in the system!
338
- * The first user to press the create project button will become the "Super Admin" of the system
339
- *
340
- * If a "Super Admin" already exists in the system, a 403 will be thrown
341
- */
342
- assignSuperAdmin = async () => {
343
- this.logInfoBold('Assigning SuperAdmin permissions');
344
- const existingSuperAdmin = (await ModuleBE_PermissionUserDB.query.custom({
345
- where: { __groupIds: { $ac: GroupId_SuperAdmin } },
346
- limit: 1
347
- }))[0];
348
- if (existingSuperAdmin)
349
- return;
350
- const currentUser = await ModuleBE_PermissionUserDB.query.uniqueAssert(MemKey_AccountId.get());
351
- (currentUser.groups || (currentUser.groups = [])).push({ groupId: GroupId_SuperAdmin });
352
- await ModuleBE_PermissionUserDB.set.item(currentUser);
353
- await ModuleBE_SessionDB._session.rotate.reissue.bySession();
354
- this.logInfoBold('Assigned SuperAdmin permissions');
434
+ /**
435
+ * If no "Super Admin" user is defined in the system!
436
+ * The first user to press the create project button will become the "Super Admin" of the system
437
+ *
438
+ * If a "Super Admin" already exists in the system, a 403 will be thrown
439
+ */
440
+ assignSuperAdmin = async () => {
441
+ this.logInfoBold('Assigning SuperAdmin permissions');
442
+ const superAdminGroupId = toPermissionGroupId(GroupId_SuperAdmin);
443
+ const existingSuperAdmin = (await ModuleBE_PermissionUserDB.query.custom({
444
+ where: { __groupIds: { $ac: superAdminGroupId } },
445
+ limit: 1
446
+ }))[0];
447
+ if (existingSuperAdmin)
448
+ return;
449
+ const accountId = MemKey_AccountId.get();
450
+ const currentUser = await ModuleBE_PermissionUserDB.query.uniqueAssert(accountId);
451
+ (currentUser.groups || (currentUser.groups = [])).push({ groupId: superAdminGroupId });
452
+ await ModuleBE_PermissionUserDB.set.item(currentUser);
453
+ await ModuleBE_SessionDB._session.rotate.reissue.bySession();
454
+ this.logInfoBold('Assigned SuperAdmin permissions');
455
+ };
355
456
  };
356
- }
457
+ })();
357
458
  export const ModuleBE_Permissions = new ModuleBE_Permissions_Class();