@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.
- package/PermissionKey_BE.d.ts +9 -6
- package/PermissionKey_BE.js +20 -9
- package/RequirePermission.d.ts +21 -0
- package/RequirePermission.js +47 -0
- package/_entity/permission-access-level/ModuleBE_PermissionAccessLevelDB.d.ts +5 -9
- package/_entity/permission-access-level/ModuleBE_PermissionAccessLevelDB.js +1 -7
- package/_entity/permission-access-level/module-pack.d.ts +1 -1
- package/_entity/permission-access-level/module-pack.js +2 -2
- package/_entity/permission-api/ModuleBE_PermissionAPIDB.d.ts +6 -8
- package/_entity/permission-api/ModuleBE_PermissionAPIDB.js +4 -4
- package/_entity/permission-api/module-pack.d.ts +1 -1
- package/_entity/permission-api/module-pack.js +2 -2
- package/_entity/permission-domain/ModuleBE_PermissionDomainDB.d.ts +4 -10
- package/_entity/permission-domain/ModuleBE_PermissionDomainDB.js +1 -4
- package/_entity/permission-domain/module-pack.d.ts +1 -1
- package/_entity/permission-domain/module-pack.js +2 -2
- package/_entity/permission-group/ModuleBE_PermissionGroupDB.d.ts +5 -7
- package/_entity/permission-group/ModuleBE_PermissionGroupDB.js +10 -7
- package/_entity/permission-group/module-pack.d.ts +1 -1
- package/_entity/permission-group/module-pack.js +2 -2
- package/_entity/permission-project/ModuleBE_PermissionProjectDB.d.ts +4 -6
- package/_entity/permission-project/ModuleBE_PermissionProjectDB.js +1 -1
- package/_entity/permission-project/module-pack.d.ts +1 -1
- package/_entity/permission-project/module-pack.js +2 -2
- package/_entity/permission-user/ModuleBE_PermissionUserAPI.d.ts +4 -3
- package/_entity/permission-user/ModuleBE_PermissionUserAPI.js +63 -10
- package/_entity/permission-user/ModuleBE_PermissionUserDB.d.ts +8 -10
- package/_entity/permission-user/ModuleBE_PermissionUserDB.js +33 -18
- package/core/external-api-paths.d.ts +13 -0
- package/core/external-api-paths.js +13 -0
- package/core/function-permission-registry.d.ts +25 -0
- package/core/function-permission-registry.js +50 -0
- package/core/utils.d.ts +4 -4
- package/core/utils.js +7 -7
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/modules/ModuleBE_Permissions.d.ts +10 -4
- package/modules/ModuleBE_Permissions.js +365 -264
- package/modules/ModuleBE_PermissionsAssert.d.ts +20 -3
- package/modules/ModuleBE_PermissionsAssert.js +271 -205
- package/modules/consts.d.ts +2 -2
- package/modules/consts.js +5 -5
- package/modules/index.d.ts +1 -0
- package/modules/index.js +1 -0
- package/package.json +13 -12
- package/permissions-wire.d.ts +46 -0
- package/permissions-wire.js +47 -0
- package/permissions.js +29 -31
- package/types.d.ts +3 -3
|
@@ -1,15 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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:
|
|
402
|
+
path: endpoint.path,
|
|
306
403
|
_auditorId,
|
|
307
|
-
accessLevelIds: [
|
|
404
|
+
accessLevelIds: [accessLevel._id]
|
|
308
405
|
};
|
|
309
406
|
}));
|
|
310
407
|
});
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
408
|
+
apis.push(...flatArray(_apis));
|
|
409
|
+
return apis;
|
|
410
|
+
}));
|
|
314
411
|
}));
|
|
315
|
-
|
|
316
|
-
|
|
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
|
-
|
|
332
|
-
|
|
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
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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();
|