@stamhoofd/backend 2.122.3 → 2.122.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamhoofd/backend",
3
- "version": "2.122.3",
3
+ "version": "2.122.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -57,20 +57,20 @@
57
57
  "@simonbackx/simple-endpoints": "1.21.1",
58
58
  "@simonbackx/simple-errors": "1.5.0",
59
59
  "@simonbackx/simple-logging": "1.0.1",
60
- "@stamhoofd/backend-env": "2.122.3",
61
- "@stamhoofd/backend-i18n": "2.122.3",
62
- "@stamhoofd/backend-middleware": "2.122.3",
63
- "@stamhoofd/crons": "2.122.3",
64
- "@stamhoofd/email": "2.122.3",
65
- "@stamhoofd/excel-writer": "2.122.3",
66
- "@stamhoofd/logging": "2.122.3",
67
- "@stamhoofd/models": "2.122.3",
68
- "@stamhoofd/object-differ": "2.122.3",
69
- "@stamhoofd/queues": "2.122.3",
70
- "@stamhoofd/sql": "2.122.3",
71
- "@stamhoofd/structures": "2.122.3",
72
- "@stamhoofd/types": "2.122.3",
73
- "@stamhoofd/utility": "2.122.3",
60
+ "@stamhoofd/backend-env": "2.122.4",
61
+ "@stamhoofd/backend-i18n": "2.122.4",
62
+ "@stamhoofd/backend-middleware": "2.122.4",
63
+ "@stamhoofd/crons": "2.122.4",
64
+ "@stamhoofd/email": "2.122.4",
65
+ "@stamhoofd/excel-writer": "2.122.4",
66
+ "@stamhoofd/logging": "2.122.4",
67
+ "@stamhoofd/models": "2.122.4",
68
+ "@stamhoofd/object-differ": "2.122.4",
69
+ "@stamhoofd/queues": "2.122.4",
70
+ "@stamhoofd/sql": "2.122.4",
71
+ "@stamhoofd/structures": "2.122.4",
72
+ "@stamhoofd/types": "2.122.4",
73
+ "@stamhoofd/utility": "2.122.4",
74
74
  "archiver": "7.0.1",
75
75
  "axios": "1.16.0",
76
76
  "base-x": "3.0.11",
@@ -91,7 +91,7 @@
91
91
  "stripe": "16.12.0"
92
92
  },
93
93
  "devDependencies": {
94
- "@stamhoofd/test-utils": "2.122.3",
94
+ "@stamhoofd/test-utils": "2.122.4",
95
95
  "@types/cookie": "0.6.0",
96
96
  "@types/luxon": "3.7.1",
97
97
  "@types/mailparser": "3.4.6",
@@ -107,5 +107,5 @@
107
107
  "publishConfig": {
108
108
  "access": "public"
109
109
  },
110
- "gitHead": "86bf4ada3c0296f6acb919ac2b40361931246bfa"
110
+ "gitHead": "4258dcd68de9636eb141d48192d4e73da3c814df"
111
111
  }
@@ -0,0 +1,277 @@
1
+ import { Migration } from '@simonbackx/simple-database';
2
+ import { Group, Organization, Webshop } from '@stamhoofd/models';
3
+ import type { GroupCategory, PermissionRole } from '@stamhoofd/structures';
4
+ import { AccessRight, PermissionLevel, PermissionsResourceType, ResourcePermissions } from '@stamhoofd/structures';
5
+ import { SeedTools } from '../helpers/SeedTools.js';
6
+
7
+ export default new Migration(async () => {
8
+ if (STAMHOOFD.environment === 'test') {
9
+ console.log('skipped in tests');
10
+ return;
11
+ }
12
+
13
+ if (STAMHOOFD.platformName.toLowerCase() !== 'stamhoofd') {
14
+ console.log('skipped for platform (only runs for Stamhoofd): ' + STAMHOOFD.platformName);
15
+ return;
16
+ }
17
+
18
+ const dryRun = false;
19
+ await start(dryRun);
20
+
21
+ if (dryRun) {
22
+ throw new Error('Migration did not finish because of dryRun');
23
+ }
24
+ });
25
+
26
+ async function start(dryRun: boolean) {
27
+ await SeedTools.loop({
28
+ query: Organization.select(),
29
+ batchSize: 50,
30
+ useTransactionPerBatch: true,
31
+ action: async (organization: Organization) => {
32
+ const groups: Group[] = await Group.select()
33
+ .where('organizationId', organization.id)
34
+ // only for current period
35
+ .where('periodId', organization.periodId)
36
+ .fetch();
37
+
38
+ if (groups.length === 0) {
39
+ return;
40
+ }
41
+
42
+ // handle group permissions
43
+ for (const group of groups) {
44
+ const groupPermissions = group.privateSettings.permissions;
45
+ if (!groupPermissions) {
46
+ continue;
47
+ }
48
+
49
+ for (const role of groupPermissions.read) {
50
+ handlePermissionRoleForGroup(organization, group, role, PermissionLevel.Read);
51
+ }
52
+
53
+ for (const role of groupPermissions.write) {
54
+ handlePermissionRoleForGroup(organization, group, role, PermissionLevel.Write);
55
+ }
56
+
57
+ for (const role of groupPermissions.full) {
58
+ handlePermissionRoleForGroup(organization, group, role, PermissionLevel.Full);
59
+ }
60
+ }
61
+
62
+ // handle group category permissions
63
+ for (const oldCategory of organization.meta.categories) {
64
+ const groupCategoryPermissions = oldCategory.settings.permissions;
65
+ if (!groupCategoryPermissions) {
66
+ continue;
67
+ }
68
+
69
+ for (const createPermission of groupCategoryPermissions.create) {
70
+ handleCreateForGroupCategory(organization, oldCategory, createPermission);
71
+ }
72
+
73
+ const groupPermissions = groupCategoryPermissions.groupPermissions;
74
+
75
+ if (groupPermissions) {
76
+ for (const role of groupPermissions.read) {
77
+ handlePermissionRoleForGroupCategory(organization, oldCategory, role, PermissionLevel.Read);
78
+ }
79
+
80
+ for (const role of groupPermissions.write) {
81
+ handlePermissionRoleForGroupCategory(organization, oldCategory, role, PermissionLevel.Write);
82
+ }
83
+
84
+ for (const role of groupPermissions.full) {
85
+ handlePermissionRoleForGroupCategory(organization, oldCategory, role, PermissionLevel.Full);
86
+ }
87
+ }
88
+ }
89
+
90
+ // handle webshops
91
+ const webshops: Webshop[] = await Webshop.select()
92
+ .where('organizationId', organization.id)
93
+ .fetch();
94
+
95
+ for (const webshop of webshops) {
96
+ const scanPermissions = webshop.privateMeta.scanPermissions;
97
+
98
+ // scan permissions are always write
99
+ if (scanPermissions) {
100
+ for (const role of scanPermissions.write) {
101
+ handleScanForWebshop(organization, webshop, role);
102
+ }
103
+
104
+ if (scanPermissions.read.length) {
105
+ throw new Error('Not expected to have read permissions on webshop scanPermissions, webshop: ' + webshop.id);
106
+ }
107
+
108
+ if (scanPermissions.full.length) {
109
+ throw new Error('Not expected to have full permissions on webshop scanPermissions, webshop: ' + webshop.id);
110
+ }
111
+ }
112
+
113
+ const permissions = webshop.privateMeta.permissions;
114
+ if (permissions) {
115
+ for (const role of permissions.read) {
116
+ handlePermissionRoleForWebshop(organization, webshop, role, PermissionLevel.Read);
117
+ }
118
+
119
+ for (const role of permissions.write) {
120
+ handlePermissionRoleForWebshop(organization, webshop, role, PermissionLevel.Write);
121
+ }
122
+
123
+ for (const role of permissions.full) {
124
+ handlePermissionRoleForWebshop(organization, webshop, role, PermissionLevel.Full);
125
+ }
126
+ }
127
+ }
128
+
129
+ if (!dryRun) {
130
+ await organization.save();
131
+ }
132
+ },
133
+
134
+ });
135
+ }
136
+
137
+ // groups
138
+ function handlePermissionRoleForGroup(organization: Organization, group: Group, permissionRole: PermissionRole, level: PermissionLevel) {
139
+ const organizationRole = getOrganizationRole(organization, permissionRole);
140
+ if (!organizationRole) {
141
+ return;
142
+ }
143
+
144
+ let allGroupPermissions = organizationRole.resources.get(PermissionsResourceType.Groups);
145
+
146
+ if (!allGroupPermissions) {
147
+ allGroupPermissions = new Map<string, ResourcePermissions>();
148
+ organizationRole.resources.set(PermissionsResourceType.Groups, allGroupPermissions);
149
+ }
150
+
151
+ const specificGroupPermissions: ResourcePermissions | undefined = allGroupPermissions.get(group.id);
152
+
153
+ const convertedRessourcePermissions = ResourcePermissions.create({ level, resourceName: group.settings.name.toString() });
154
+
155
+ if (!specificGroupPermissions) {
156
+ allGroupPermissions.set(group.id, convertedRessourcePermissions);
157
+ return;
158
+ }
159
+
160
+ specificGroupPermissions.merge(convertedRessourcePermissions);
161
+ return;
162
+ }
163
+
164
+ // categories
165
+ function handleCreateForGroupCategory(organization: Organization, oldCategory: GroupCategory, permissionRole: PermissionRole) {
166
+ const organizationRole = getOrganizationRole(organization, permissionRole);
167
+ if (!organizationRole) {
168
+ return;
169
+ }
170
+
171
+ let allGroupCategoryPermissions = organizationRole.resources.get(PermissionsResourceType.GroupCategories);
172
+
173
+ if (!allGroupCategoryPermissions) {
174
+ allGroupCategoryPermissions = new Map<string, ResourcePermissions>();
175
+ organizationRole.resources.set(PermissionsResourceType.GroupCategories, allGroupCategoryPermissions);
176
+ }
177
+
178
+ const specificGroupCategoryPermissions: ResourcePermissions | undefined = allGroupCategoryPermissions.get(oldCategory.id);
179
+
180
+ if (specificGroupCategoryPermissions) {
181
+ if (!specificGroupCategoryPermissions.accessRights.includes(AccessRight.OrganizationCreateGroups)) {
182
+ specificGroupCategoryPermissions.accessRights.push(AccessRight.OrganizationCreateGroups);
183
+ }
184
+ return;
185
+ }
186
+
187
+ allGroupCategoryPermissions.set(oldCategory.id, ResourcePermissions.create({ resourceName: oldCategory.settings.name, accessRights: [AccessRight.OrganizationCreateGroups] }));
188
+ }
189
+
190
+ function handlePermissionRoleForGroupCategory(organization: Organization, oldCategory: GroupCategory, permissionRole: PermissionRole, level: PermissionLevel) {
191
+ const organizationRole = getOrganizationRole(organization, permissionRole);
192
+ if (!organizationRole) {
193
+ return;
194
+ }
195
+
196
+ let allGroupCategoryPermissions = organizationRole.resources.get(PermissionsResourceType.GroupCategories);
197
+
198
+ if (!allGroupCategoryPermissions) {
199
+ allGroupCategoryPermissions = new Map<string, ResourcePermissions>();
200
+ organizationRole.resources.set(PermissionsResourceType.GroupCategories, allGroupCategoryPermissions);
201
+ }
202
+
203
+ const specificGroupCategoryPermissions: ResourcePermissions | undefined = allGroupCategoryPermissions.get(oldCategory.id);
204
+
205
+ const convertedRessourcePermissions = ResourcePermissions.create({ level, resourceName: oldCategory.settings.name });
206
+
207
+ if (!specificGroupCategoryPermissions) {
208
+ allGroupCategoryPermissions.set(oldCategory.id, convertedRessourcePermissions);
209
+ return;
210
+ }
211
+
212
+ specificGroupCategoryPermissions.merge(convertedRessourcePermissions);
213
+ return;
214
+ }
215
+
216
+ // webshops
217
+ function handleScanForWebshop(organization: Organization, webshop: Webshop, permissionRole: PermissionRole) {
218
+ const organizationRole = getOrganizationRole(organization, permissionRole);
219
+ if (!organizationRole) {
220
+ return;
221
+ }
222
+
223
+ let allWebshopPermissions = organizationRole.resources.get(PermissionsResourceType.Webshops);
224
+
225
+ if (!allWebshopPermissions) {
226
+ allWebshopPermissions = new Map<string, ResourcePermissions>();
227
+ organizationRole.resources.set(PermissionsResourceType.Webshops, allWebshopPermissions);
228
+ }
229
+
230
+ const specificWebshopPermissions: ResourcePermissions | undefined = allWebshopPermissions.get(webshop.id);
231
+
232
+ if (specificWebshopPermissions) {
233
+ if (!specificWebshopPermissions.accessRights.includes(AccessRight.WebshopScanTickets)) {
234
+ specificWebshopPermissions.accessRights.push(AccessRight.WebshopScanTickets);
235
+ }
236
+ return;
237
+ }
238
+
239
+ allWebshopPermissions.set(webshop.id, ResourcePermissions.create({ resourceName: webshop.meta.name, accessRights: [AccessRight.WebshopScanTickets] }));
240
+ }
241
+
242
+ function handlePermissionRoleForWebshop(organization: Organization, webshop: Webshop, permissionRole: PermissionRole, level: PermissionLevel) {
243
+ const organizationRole = getOrganizationRole(organization, permissionRole);
244
+ if (!organizationRole) {
245
+ return;
246
+ }
247
+
248
+ let allWebshopPermissions = organizationRole.resources.get(PermissionsResourceType.Webshops);
249
+
250
+ if (!allWebshopPermissions) {
251
+ allWebshopPermissions = new Map<string, ResourcePermissions>();
252
+ organizationRole.resources.set(PermissionsResourceType.Webshops, allWebshopPermissions);
253
+ }
254
+
255
+ const specificWebshopPermissions: ResourcePermissions | undefined = allWebshopPermissions.get(webshop.id);
256
+
257
+ const convertedRessourcePermissions = ResourcePermissions.create({ level, resourceName: webshop.meta.name });
258
+
259
+ if (!specificWebshopPermissions) {
260
+ allWebshopPermissions.set(webshop.id, convertedRessourcePermissions);
261
+ return;
262
+ }
263
+
264
+ specificWebshopPermissions.merge(convertedRessourcePermissions);
265
+ return;
266
+ }
267
+
268
+ function getOrganizationRole(organization: Organization, permissionRole: PermissionRole) {
269
+ const organizationRole = organization.privateMeta.roles.find(r => r.id === permissionRole.id);
270
+ if (!organizationRole) {
271
+ console.error(`Could not find role for organization ${organization.id} (${organization.name}) and role ${permissionRole.id} (${permissionRole.name})`);
272
+ return;
273
+ }
274
+
275
+ // console.error(`Did find role for organization ${organization.id} (${organization.name}) and role ${permissionRole.id} (${permissionRole.name})`);
276
+ return organizationRole;
277
+ }