@stamhoofd/backend 2.83.4 → 2.84.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/index.ts +19 -4
- package/package.json +18 -14
- package/src/crons/amazon-ses.ts +26 -5
- package/src/crons/balance-emails.ts +18 -17
- package/src/email-recipient-loaders/registrations.ts +87 -0
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +5 -2
- package/src/endpoints/global/email/PatchEmailEndpoint.test.ts +40 -40
- package/src/endpoints/global/events/PatchEventNotificationsEndpoint.test.ts +28 -22
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +81 -49
- package/src/endpoints/global/files/UploadFile.ts +11 -16
- package/src/endpoints/global/groups/GetGroupsEndpoint.test.ts +234 -0
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +117 -43
- package/src/endpoints/global/members/GetMembersEndpoint.test.ts +1054 -0
- package/src/endpoints/global/members/GetMembersEndpoint.ts +163 -141
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +6 -6
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +0 -16
- package/src/endpoints/global/members/helpers/validateGroupFilter.ts +73 -0
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +1 -2
- package/src/endpoints/global/registration/GetRegistrationsCountEndpoint.ts +43 -0
- package/src/endpoints/global/registration/GetRegistrationsEndpoint.test.ts +1016 -0
- package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +234 -0
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +5 -5
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +474 -554
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +191 -52
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +107 -9
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.test.ts +89 -0
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +9 -6
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.test.ts +88 -0
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +0 -6
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +10 -6
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +10 -25
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +0 -5
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +0 -5
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.ts +4 -0
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +1 -0
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.test.ts +44 -19
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +140 -25
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +40 -10
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.test.ts +2 -2
- package/src/endpoints/organization/dashboard/users/PatchApiUserEndpoint.test.ts +2 -2
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +4 -1
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +2 -2
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +2 -2
- package/src/excel-loaders/members.ts +233 -232
- package/src/excel-loaders/payments.ts +1 -1
- package/src/excel-loaders/receivable-balances.ts +1 -1
- package/src/excel-loaders/registrations.ts +153 -0
- package/src/helpers/AdminPermissionChecker.ts +65 -37
- package/src/helpers/AuthenticatedStructures.ts +43 -3
- package/src/helpers/Context.ts +29 -1
- package/src/helpers/GlobalHelper.ts +3 -1
- package/src/helpers/GroupedThrottledQueue.test.ts +219 -0
- package/src/helpers/GroupedThrottledQueue.ts +108 -0
- package/src/helpers/LimitedFilteredRequestHelper.ts +26 -1
- package/src/helpers/MemberCharger.ts +0 -5
- package/src/helpers/MembershipCharger.ts +3 -9
- package/src/helpers/OrganizationCharger.ts +0 -5
- package/src/helpers/ThrottledQueue.test.ts +194 -0
- package/src/helpers/ThrottledQueue.ts +145 -0
- package/src/helpers/XlsxTransformerColumnHelper.ts +44 -1
- package/src/middleware/ContextMiddleware.ts +1 -1
- package/src/seeds/1728928974-update-cached-outstanding-balance-from-items.ts +2 -1
- package/src/seeds/1735577912-update-cached-outstanding-balance-from-items.ts +2 -1
- package/src/services/BalanceItemPaymentService.ts +1 -33
- package/src/services/BalanceItemService.ts +167 -48
- package/src/services/FileSignService.ts +18 -13
- package/src/services/MemberRecordStore.ts +28 -19
- package/src/services/PaymentReallocationService.test.ts +25 -14
- package/src/services/PaymentReallocationService.ts +29 -10
- package/src/services/PaymentService.ts +4 -16
- package/src/services/PlatformMembershipService.ts +8 -4
- package/src/services/RegistrationService.ts +66 -2
- package/src/sql-filters/base-registration-filter-compilers.ts +43 -0
- package/src/sql-filters/groups.ts +67 -0
- package/src/sql-filters/members.ts +33 -58
- package/src/sql-filters/organization-registration-periods.ts +8 -0
- package/src/sql-filters/registration-periods.ts +8 -0
- package/src/sql-filters/registrations.ts +11 -22
- package/src/sql-sorters/groups.ts +24 -0
- package/src/sql-sorters/organization-registration-periods.ts +24 -0
- package/src/sql-sorters/registration-periods.ts +47 -0
- package/src/sql-sorters/registrations.ts +77 -0
- package/tests/actions/patchOrganizationMember.ts +27 -0
- package/tests/actions/patchPaymentStatus.ts +45 -0
- package/tests/actions/patchUserMember.ts +27 -0
- package/tests/assertions/assertBalances.ts +49 -0
- package/tests/e2e/api-rate-limits.test.ts +5 -5
- package/tests/e2e/bundle-discounts.test.ts +4060 -0
- package/tests/e2e/charge-members.test.ts +27 -24
- package/tests/e2e/documents.test.ts +398 -0
- package/tests/e2e/register.test.ts +292 -312
- package/tests/helpers/PayconiqMocker.ts +55 -0
- package/tests/init/index.ts +5 -0
- package/tests/init/initAdmin.ts +14 -0
- package/tests/init/initBundleDiscount.ts +47 -0
- package/tests/init/initPayconiq.ts +9 -0
- package/tests/init/initPlatformAdmin.ts +13 -0
- package/tests/init/initStripe.ts +21 -0
- package/tests/jest.setup.ts +29 -0
- package/src/seeds-temporary/1736266448-recall-balance-item-price-paid.ts +0 -70
|
@@ -0,0 +1,1016 @@
|
|
|
1
|
+
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { EventFactory, GroupFactory, MemberFactory, OrganizationFactory, RegistrationFactory, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
|
|
3
|
+
import { AccessRight, EventMeta, GroupType, LimitedFilteredRequest, NamedObject, PermissionLevel, PermissionRoleDetailed, Permissions, PermissionsResourceType, ResourcePermissions } from '@stamhoofd/structures';
|
|
4
|
+
import { STExpect, TestUtils } from '@stamhoofd/test-utils';
|
|
5
|
+
import { testServer } from '../../../../tests/helpers/TestServer';
|
|
6
|
+
import { GetRegistrationsEndpoint } from './GetRegistrationsEndpoint';
|
|
7
|
+
|
|
8
|
+
const baseUrl = `/registrations`;
|
|
9
|
+
const endpoint = new GetRegistrationsEndpoint();
|
|
10
|
+
|
|
11
|
+
describe('Endpoint.GetRegistrationsEndpoint', () => {
|
|
12
|
+
let period: RegistrationPeriod;
|
|
13
|
+
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
TestUtils.setEnvironment('userMode', 'platform');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
period = await new RegistrationPeriodFactory({
|
|
20
|
+
startDate: new Date(2023, 0, 1),
|
|
21
|
+
endDate: new Date(2023, 11, 31),
|
|
22
|
+
}).create();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('Permission checking', () => {
|
|
26
|
+
test('Allowed: Can fetch registrations for a given group', async () => {
|
|
27
|
+
// Setup
|
|
28
|
+
const role = PermissionRoleDetailed.create({
|
|
29
|
+
name: 'Test Role',
|
|
30
|
+
accessRights: [],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const resources = new Map();
|
|
34
|
+
|
|
35
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
36
|
+
.create();
|
|
37
|
+
|
|
38
|
+
const user = await new UserFactory({
|
|
39
|
+
organization,
|
|
40
|
+
permissions: Permissions.create({
|
|
41
|
+
level: PermissionLevel.None,
|
|
42
|
+
roles: [
|
|
43
|
+
role,
|
|
44
|
+
],
|
|
45
|
+
resources,
|
|
46
|
+
}),
|
|
47
|
+
})
|
|
48
|
+
.create();
|
|
49
|
+
|
|
50
|
+
const token = await Token.createToken(user);
|
|
51
|
+
const member1 = await new MemberFactory({ }).create();
|
|
52
|
+
const member2 = await new MemberFactory({ }).create();
|
|
53
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
54
|
+
|
|
55
|
+
resources.set(
|
|
56
|
+
PermissionsResourceType.Groups, new Map([[
|
|
57
|
+
group.id,
|
|
58
|
+
ResourcePermissions.create({
|
|
59
|
+
level: PermissionLevel.Read,
|
|
60
|
+
}),
|
|
61
|
+
]]),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
await user.save();
|
|
65
|
+
|
|
66
|
+
const registration1 = await new RegistrationFactory({ member: member1, group }).create();
|
|
67
|
+
const registration2 = await new RegistrationFactory({ member: member2, group }).create();
|
|
68
|
+
|
|
69
|
+
// Try to request members for this group
|
|
70
|
+
const request = Request.get({
|
|
71
|
+
path: baseUrl,
|
|
72
|
+
host: organization.getApiHost(),
|
|
73
|
+
query: new LimitedFilteredRequest({
|
|
74
|
+
filter: {
|
|
75
|
+
groupId: group.id,
|
|
76
|
+
},
|
|
77
|
+
limit: 10,
|
|
78
|
+
}),
|
|
79
|
+
headers: {
|
|
80
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const response = await testServer.test(endpoint, request);
|
|
84
|
+
expect(response.status).toBe(200);
|
|
85
|
+
expect(response.body.results.registrations).toHaveLength(2);
|
|
86
|
+
|
|
87
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
88
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
89
|
+
expect.objectContaining({ id: registration1.id }),
|
|
90
|
+
expect.objectContaining({ id: registration2.id }),
|
|
91
|
+
]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('Not allowed: Cannot fetch registrations for a given group', async () => {
|
|
95
|
+
// Same test, but without giving the user permissions to read the group
|
|
96
|
+
// Setup
|
|
97
|
+
const role = PermissionRoleDetailed.create({
|
|
98
|
+
name: 'Test Role',
|
|
99
|
+
accessRights: [],
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const resources = new Map();
|
|
103
|
+
|
|
104
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
105
|
+
.create();
|
|
106
|
+
|
|
107
|
+
const user = await new UserFactory({
|
|
108
|
+
organization,
|
|
109
|
+
permissions: Permissions.create({
|
|
110
|
+
level: PermissionLevel.None,
|
|
111
|
+
roles: [
|
|
112
|
+
role,
|
|
113
|
+
],
|
|
114
|
+
resources,
|
|
115
|
+
}),
|
|
116
|
+
})
|
|
117
|
+
.create();
|
|
118
|
+
|
|
119
|
+
const token = await Token.createToken(user);
|
|
120
|
+
const member1 = await new MemberFactory({ }).create();
|
|
121
|
+
const member2 = await new MemberFactory({ }).create();
|
|
122
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
123
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
124
|
+
|
|
125
|
+
// Give permission to a different group
|
|
126
|
+
resources.set(
|
|
127
|
+
PermissionsResourceType.Groups, new Map([[
|
|
128
|
+
group2.id,
|
|
129
|
+
ResourcePermissions.create({
|
|
130
|
+
level: PermissionLevel.Read,
|
|
131
|
+
}),
|
|
132
|
+
]]),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
await user.save();
|
|
136
|
+
|
|
137
|
+
await new RegistrationFactory({ member: member1, group }).create();
|
|
138
|
+
await new RegistrationFactory({ member: member2, group }).create();
|
|
139
|
+
|
|
140
|
+
// Try to request members for this group
|
|
141
|
+
const request = Request.get({
|
|
142
|
+
path: baseUrl,
|
|
143
|
+
host: organization.getApiHost(),
|
|
144
|
+
query: new LimitedFilteredRequest({
|
|
145
|
+
filter: {
|
|
146
|
+
groupId: group.id,
|
|
147
|
+
},
|
|
148
|
+
limit: 10,
|
|
149
|
+
}),
|
|
150
|
+
headers: {
|
|
151
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
await expect(testServer.test(endpoint, request)).rejects.toThrow(
|
|
155
|
+
STExpect.errorWithCode('permission_denied'),
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('Allowed: Can fetch registrations for multiple groups at the same time', async () => {
|
|
160
|
+
// Same test, but without giving the user permissions to read the group
|
|
161
|
+
// Setup
|
|
162
|
+
const role = PermissionRoleDetailed.create({
|
|
163
|
+
name: 'Test Role',
|
|
164
|
+
accessRights: [],
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const resources = new Map();
|
|
168
|
+
|
|
169
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
170
|
+
.create();
|
|
171
|
+
|
|
172
|
+
const user = await new UserFactory({
|
|
173
|
+
organization,
|
|
174
|
+
permissions: Permissions.create({
|
|
175
|
+
level: PermissionLevel.None,
|
|
176
|
+
roles: [
|
|
177
|
+
role,
|
|
178
|
+
],
|
|
179
|
+
resources,
|
|
180
|
+
}),
|
|
181
|
+
})
|
|
182
|
+
.create();
|
|
183
|
+
|
|
184
|
+
const token = await Token.createToken(user);
|
|
185
|
+
const member1 = await new MemberFactory({ }).create();
|
|
186
|
+
const member2 = await new MemberFactory({ }).create();
|
|
187
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
188
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
189
|
+
|
|
190
|
+
// Give permission to a different group
|
|
191
|
+
resources.set(
|
|
192
|
+
PermissionsResourceType.Groups, new Map([[
|
|
193
|
+
group.id,
|
|
194
|
+
ResourcePermissions.create({
|
|
195
|
+
level: PermissionLevel.Read,
|
|
196
|
+
}),
|
|
197
|
+
], [
|
|
198
|
+
group2.id,
|
|
199
|
+
ResourcePermissions.create({
|
|
200
|
+
level: PermissionLevel.Write,
|
|
201
|
+
}),
|
|
202
|
+
]]),
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
await user.save();
|
|
206
|
+
|
|
207
|
+
const registration1 = await new RegistrationFactory({ member: member1, group }).create();
|
|
208
|
+
const registration2 = await new RegistrationFactory({ member: member2, group: group2 }).create();
|
|
209
|
+
|
|
210
|
+
// Try to request members for this group
|
|
211
|
+
const request = Request.get({
|
|
212
|
+
path: baseUrl,
|
|
213
|
+
host: organization.getApiHost(),
|
|
214
|
+
query: new LimitedFilteredRequest({
|
|
215
|
+
filter: {
|
|
216
|
+
groupId: {
|
|
217
|
+
$in: [group.id, group2.id],
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
limit: 10,
|
|
221
|
+
}),
|
|
222
|
+
headers: {
|
|
223
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
const response = await testServer.test(endpoint, request);
|
|
227
|
+
expect(response.status).toBe(200);
|
|
228
|
+
expect(response.body.results.registrations).toHaveLength(2);
|
|
229
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
230
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
231
|
+
expect.objectContaining({ id: registration1.id }),
|
|
232
|
+
expect.objectContaining({ id: registration2.id }),
|
|
233
|
+
]);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('Not allowed: Cannot fetch registrations for multiple groups at the same time if no permissions for one of them', async () => {
|
|
237
|
+
// Same test, but without giving the user permissions to read the group
|
|
238
|
+
// Setup
|
|
239
|
+
const role = PermissionRoleDetailed.create({
|
|
240
|
+
name: 'Test Role',
|
|
241
|
+
accessRights: [],
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const resources = new Map();
|
|
245
|
+
|
|
246
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
247
|
+
.create();
|
|
248
|
+
|
|
249
|
+
const user = await new UserFactory({
|
|
250
|
+
organization,
|
|
251
|
+
permissions: Permissions.create({
|
|
252
|
+
level: PermissionLevel.None,
|
|
253
|
+
roles: [
|
|
254
|
+
role,
|
|
255
|
+
],
|
|
256
|
+
resources,
|
|
257
|
+
}),
|
|
258
|
+
})
|
|
259
|
+
.create();
|
|
260
|
+
|
|
261
|
+
const token = await Token.createToken(user);
|
|
262
|
+
const member1 = await new MemberFactory({ }).create();
|
|
263
|
+
const member2 = await new MemberFactory({ }).create();
|
|
264
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
265
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
266
|
+
|
|
267
|
+
// Only give permissions for one group
|
|
268
|
+
resources.set(
|
|
269
|
+
PermissionsResourceType.Groups, new Map([[
|
|
270
|
+
group.id,
|
|
271
|
+
ResourcePermissions.create({
|
|
272
|
+
level: PermissionLevel.Read,
|
|
273
|
+
}),
|
|
274
|
+
]]),
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
await user.save();
|
|
278
|
+
|
|
279
|
+
await new RegistrationFactory({ member: member1, group }).create();
|
|
280
|
+
await new RegistrationFactory({ member: member2, group: group2 }).create();
|
|
281
|
+
|
|
282
|
+
// Try to request members for this group
|
|
283
|
+
const request = Request.get({
|
|
284
|
+
path: baseUrl,
|
|
285
|
+
host: organization.getApiHost(),
|
|
286
|
+
query: new LimitedFilteredRequest({
|
|
287
|
+
filter: {
|
|
288
|
+
groupId: {
|
|
289
|
+
$in: [group.id, group2.id],
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
limit: 10,
|
|
293
|
+
}),
|
|
294
|
+
headers: {
|
|
295
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
await expect(testServer.test(endpoint, request)).rejects.toThrow(
|
|
299
|
+
STExpect.errorWithCode('permission_denied'),
|
|
300
|
+
);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test('Allowed: Can fetch all registrations if permissions for at least one group', async () => {
|
|
304
|
+
// Same test, but without giving the user permissions to read the group
|
|
305
|
+
// Setup
|
|
306
|
+
const role = PermissionRoleDetailed.create({
|
|
307
|
+
name: 'Test Role',
|
|
308
|
+
accessRights: [],
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const resources = new Map();
|
|
312
|
+
|
|
313
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
314
|
+
.create();
|
|
315
|
+
|
|
316
|
+
const user = await new UserFactory({
|
|
317
|
+
organization,
|
|
318
|
+
permissions: Permissions.create({
|
|
319
|
+
level: PermissionLevel.None,
|
|
320
|
+
roles: [
|
|
321
|
+
role,
|
|
322
|
+
],
|
|
323
|
+
resources,
|
|
324
|
+
}),
|
|
325
|
+
})
|
|
326
|
+
.create();
|
|
327
|
+
|
|
328
|
+
const token = await Token.createToken(user);
|
|
329
|
+
const member1 = await new MemberFactory({ }).create();
|
|
330
|
+
const member2 = await new MemberFactory({ }).create();
|
|
331
|
+
const member3 = await new MemberFactory({ }).create();
|
|
332
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
333
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
334
|
+
const group3 = await new GroupFactory({ organization, period }).create();
|
|
335
|
+
|
|
336
|
+
// Give permission for 2 / 3 groups
|
|
337
|
+
resources.set(
|
|
338
|
+
PermissionsResourceType.Groups, new Map([[
|
|
339
|
+
group.id,
|
|
340
|
+
ResourcePermissions.create({
|
|
341
|
+
level: PermissionLevel.Read,
|
|
342
|
+
}),
|
|
343
|
+
], [
|
|
344
|
+
group2.id,
|
|
345
|
+
ResourcePermissions.create({
|
|
346
|
+
level: PermissionLevel.Write,
|
|
347
|
+
}),
|
|
348
|
+
]]),
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
await user.save();
|
|
352
|
+
|
|
353
|
+
const registration1 = await new RegistrationFactory({ member: member1, group }).create();
|
|
354
|
+
const registration2 = await new RegistrationFactory({ member: member2, group: group2 }).create();
|
|
355
|
+
await new RegistrationFactory({ member: member3, group: group3 }).create();
|
|
356
|
+
|
|
357
|
+
// Try to request registrations for this group
|
|
358
|
+
const request = Request.get({
|
|
359
|
+
path: baseUrl,
|
|
360
|
+
host: organization.getApiHost(),
|
|
361
|
+
query: new LimitedFilteredRequest({
|
|
362
|
+
limit: 10,
|
|
363
|
+
}),
|
|
364
|
+
headers: {
|
|
365
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
const response = await testServer.test(endpoint, request);
|
|
369
|
+
expect(response.status).toBe(200);
|
|
370
|
+
expect(response.body.results.registrations).toHaveLength(2);
|
|
371
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
372
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
373
|
+
expect.objectContaining({ id: registration1.id }),
|
|
374
|
+
expect.objectContaining({ id: registration2.id }),
|
|
375
|
+
]);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test('Not allowed: Cannot fetch all registrations if no permissions for a single group', async () => {
|
|
379
|
+
// Same test, but without giving the user permissions to read the group
|
|
380
|
+
// Setup
|
|
381
|
+
const role = PermissionRoleDetailed.create({
|
|
382
|
+
name: 'Test Role',
|
|
383
|
+
accessRights: [AccessRight.WebshopScanTickets],
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const resources = new Map();
|
|
387
|
+
|
|
388
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
389
|
+
.create();
|
|
390
|
+
|
|
391
|
+
const user = await new UserFactory({
|
|
392
|
+
organization,
|
|
393
|
+
permissions: Permissions.create({
|
|
394
|
+
level: PermissionLevel.None,
|
|
395
|
+
roles: [
|
|
396
|
+
role,
|
|
397
|
+
],
|
|
398
|
+
resources,
|
|
399
|
+
}),
|
|
400
|
+
})
|
|
401
|
+
.create();
|
|
402
|
+
|
|
403
|
+
const token = await Token.createToken(user);
|
|
404
|
+
const member1 = await new MemberFactory({ }).create();
|
|
405
|
+
const member2 = await new MemberFactory({ }).create();
|
|
406
|
+
const member3 = await new MemberFactory({ }).create();
|
|
407
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
408
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
409
|
+
const group3 = await new GroupFactory({ organization, period }).create();
|
|
410
|
+
|
|
411
|
+
await user.save();
|
|
412
|
+
|
|
413
|
+
await new RegistrationFactory({ member: member1, group }).create();
|
|
414
|
+
await new RegistrationFactory({ member: member2, group: group2 }).create();
|
|
415
|
+
await new RegistrationFactory({ member: member3, group: group3 }).create();
|
|
416
|
+
|
|
417
|
+
// Try to request members for this group
|
|
418
|
+
const request = Request.get({
|
|
419
|
+
path: baseUrl,
|
|
420
|
+
host: organization.getApiHost(),
|
|
421
|
+
query: new LimitedFilteredRequest({
|
|
422
|
+
limit: 10,
|
|
423
|
+
}),
|
|
424
|
+
headers: {
|
|
425
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
await expect(testServer.test(endpoint, request)).rejects.toThrow(
|
|
429
|
+
STExpect.errorWithCode('permission_denied'),
|
|
430
|
+
);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test('Allowed: A user inherits permissions for an event', async () => {
|
|
434
|
+
// Same test, but without giving the user permissions to read the group
|
|
435
|
+
// Setup
|
|
436
|
+
const role = PermissionRoleDetailed.create({
|
|
437
|
+
name: 'Test Role',
|
|
438
|
+
accessRights: [],
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
const resources = new Map();
|
|
442
|
+
|
|
443
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
444
|
+
.create();
|
|
445
|
+
|
|
446
|
+
const user = await new UserFactory({
|
|
447
|
+
organization,
|
|
448
|
+
permissions: Permissions.create({
|
|
449
|
+
level: PermissionLevel.None,
|
|
450
|
+
roles: [
|
|
451
|
+
role,
|
|
452
|
+
],
|
|
453
|
+
resources,
|
|
454
|
+
}),
|
|
455
|
+
})
|
|
456
|
+
.create();
|
|
457
|
+
|
|
458
|
+
const token = await Token.createToken(user);
|
|
459
|
+
const member1 = await new MemberFactory({ }).create();
|
|
460
|
+
const member2 = await new MemberFactory({ }).create();
|
|
461
|
+
|
|
462
|
+
const defaultGroup = await new GroupFactory({ organization, period }).create();
|
|
463
|
+
const group = await new GroupFactory({ organization, period, type: GroupType.EventRegistration }).create();
|
|
464
|
+
await new EventFactory({
|
|
465
|
+
organization,
|
|
466
|
+
group,
|
|
467
|
+
startDate: period.startDate,
|
|
468
|
+
endDate: period.endDate,
|
|
469
|
+
meta: EventMeta.create({
|
|
470
|
+
groups: [
|
|
471
|
+
NamedObject.create({
|
|
472
|
+
id: defaultGroup.id,
|
|
473
|
+
name: defaultGroup.settings.name.toString(),
|
|
474
|
+
}),
|
|
475
|
+
],
|
|
476
|
+
}),
|
|
477
|
+
}).create();
|
|
478
|
+
|
|
479
|
+
// Give the user write permissions to all events targeted to the default group
|
|
480
|
+
resources.set(
|
|
481
|
+
PermissionsResourceType.Groups, new Map([[
|
|
482
|
+
defaultGroup.id,
|
|
483
|
+
ResourcePermissions.create({
|
|
484
|
+
level: PermissionLevel.None,
|
|
485
|
+
accessRights: [AccessRight.EventWrite],
|
|
486
|
+
}),
|
|
487
|
+
]]),
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
await user.save();
|
|
491
|
+
|
|
492
|
+
const registration1 = await new RegistrationFactory({ member: member1, group }).create();
|
|
493
|
+
const registration2 = await new RegistrationFactory({ member: member2, group }).create();
|
|
494
|
+
|
|
495
|
+
// Try to request members for this group
|
|
496
|
+
const request = Request.get({
|
|
497
|
+
path: baseUrl,
|
|
498
|
+
host: organization.getApiHost(),
|
|
499
|
+
query: new LimitedFilteredRequest({
|
|
500
|
+
filter: {
|
|
501
|
+
groupId: group.id,
|
|
502
|
+
},
|
|
503
|
+
limit: 10,
|
|
504
|
+
}),
|
|
505
|
+
headers: {
|
|
506
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
507
|
+
},
|
|
508
|
+
});
|
|
509
|
+
const response = await testServer.test(endpoint, request);
|
|
510
|
+
expect(response.status).toBe(200);
|
|
511
|
+
expect(response.body.results.registrations).toHaveLength(2);
|
|
512
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
513
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
514
|
+
expect.objectContaining({ id: registration1.id }),
|
|
515
|
+
expect.objectContaining({ id: registration2.id }),
|
|
516
|
+
]);
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
test('Allowed: A user inherits permissions for the waiting list of an event', async () => {
|
|
520
|
+
// Same test, but without giving the user permissions to read the group
|
|
521
|
+
// Setup
|
|
522
|
+
const role = PermissionRoleDetailed.create({
|
|
523
|
+
name: 'Test Role',
|
|
524
|
+
accessRights: [],
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
const resources = new Map();
|
|
528
|
+
|
|
529
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
530
|
+
.create();
|
|
531
|
+
|
|
532
|
+
const user = await new UserFactory({
|
|
533
|
+
organization,
|
|
534
|
+
permissions: Permissions.create({
|
|
535
|
+
level: PermissionLevel.None,
|
|
536
|
+
roles: [
|
|
537
|
+
role,
|
|
538
|
+
],
|
|
539
|
+
resources,
|
|
540
|
+
}),
|
|
541
|
+
})
|
|
542
|
+
.create();
|
|
543
|
+
|
|
544
|
+
const token = await Token.createToken(user);
|
|
545
|
+
const member1 = await new MemberFactory({ }).create();
|
|
546
|
+
const member2 = await new MemberFactory({ }).create();
|
|
547
|
+
const member3 = await new MemberFactory({ }).create();
|
|
548
|
+
|
|
549
|
+
const defaultGroup = await new GroupFactory({ organization, period }).create();
|
|
550
|
+
const waitingList = await new GroupFactory({ organization, period, type: GroupType.WaitingList }).create();
|
|
551
|
+
const group = await new GroupFactory({ organization, period, type: GroupType.EventRegistration, waitingListId: waitingList.id }).create();
|
|
552
|
+
|
|
553
|
+
await new EventFactory({
|
|
554
|
+
organization,
|
|
555
|
+
group,
|
|
556
|
+
startDate: period.startDate,
|
|
557
|
+
endDate: period.endDate,
|
|
558
|
+
meta: EventMeta.create({
|
|
559
|
+
groups: [
|
|
560
|
+
NamedObject.create({
|
|
561
|
+
id: defaultGroup.id,
|
|
562
|
+
name: defaultGroup.settings.name.toString(),
|
|
563
|
+
}),
|
|
564
|
+
],
|
|
565
|
+
}),
|
|
566
|
+
}).create();
|
|
567
|
+
|
|
568
|
+
// Give the user write permissions to all events targeted to the default group
|
|
569
|
+
resources.set(
|
|
570
|
+
PermissionsResourceType.Groups, new Map([[
|
|
571
|
+
defaultGroup.id,
|
|
572
|
+
ResourcePermissions.create({
|
|
573
|
+
level: PermissionLevel.None,
|
|
574
|
+
accessRights: [AccessRight.EventWrite],
|
|
575
|
+
}),
|
|
576
|
+
]]),
|
|
577
|
+
);
|
|
578
|
+
|
|
579
|
+
await user.save();
|
|
580
|
+
|
|
581
|
+
const registration1 = await new RegistrationFactory({ member: member1, group: waitingList }).create();
|
|
582
|
+
const registration2 = await new RegistrationFactory({ member: member2, group: waitingList }).create();
|
|
583
|
+
await new RegistrationFactory({ member: member3, group }).create();
|
|
584
|
+
|
|
585
|
+
// Try to request members for this group
|
|
586
|
+
const request = Request.get({
|
|
587
|
+
path: baseUrl,
|
|
588
|
+
host: organization.getApiHost(),
|
|
589
|
+
query: new LimitedFilteredRequest({
|
|
590
|
+
filter: {
|
|
591
|
+
groupId: waitingList.id,
|
|
592
|
+
},
|
|
593
|
+
limit: 10,
|
|
594
|
+
}),
|
|
595
|
+
headers: {
|
|
596
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
const response = await testServer.test(endpoint, request);
|
|
600
|
+
expect(response.status).toBe(200);
|
|
601
|
+
expect(response.body.results.registrations).toHaveLength(2);
|
|
602
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
603
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
604
|
+
expect.objectContaining({ id: registration1.id }),
|
|
605
|
+
expect.objectContaining({ id: registration2.id }),
|
|
606
|
+
]);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
test('Not allowed: A user cannot request registrations of an event if no permission to events', async () => {
|
|
610
|
+
// Same test, but without giving the user permissions to read the group
|
|
611
|
+
// Setup
|
|
612
|
+
const role = PermissionRoleDetailed.create({
|
|
613
|
+
name: 'Test Role',
|
|
614
|
+
accessRights: [],
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
const resources = new Map();
|
|
618
|
+
|
|
619
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
620
|
+
.create();
|
|
621
|
+
|
|
622
|
+
const user = await new UserFactory({
|
|
623
|
+
organization,
|
|
624
|
+
permissions: Permissions.create({
|
|
625
|
+
level: PermissionLevel.None,
|
|
626
|
+
roles: [
|
|
627
|
+
role,
|
|
628
|
+
],
|
|
629
|
+
resources,
|
|
630
|
+
}),
|
|
631
|
+
})
|
|
632
|
+
.create();
|
|
633
|
+
|
|
634
|
+
const token = await Token.createToken(user);
|
|
635
|
+
const member1 = await new MemberFactory({ }).create();
|
|
636
|
+
const member2 = await new MemberFactory({ }).create();
|
|
637
|
+
|
|
638
|
+
const defaultGroup = await new GroupFactory({ organization, period }).create();
|
|
639
|
+
const group = await new GroupFactory({ organization, period, type: GroupType.EventRegistration }).create();
|
|
640
|
+
await new EventFactory({
|
|
641
|
+
organization,
|
|
642
|
+
group,
|
|
643
|
+
startDate: period.startDate,
|
|
644
|
+
endDate: period.endDate,
|
|
645
|
+
meta: EventMeta.create({
|
|
646
|
+
groups: [
|
|
647
|
+
NamedObject.create({
|
|
648
|
+
id: defaultGroup.id,
|
|
649
|
+
name: defaultGroup.settings.name.toString(),
|
|
650
|
+
}),
|
|
651
|
+
],
|
|
652
|
+
}),
|
|
653
|
+
}).create();
|
|
654
|
+
|
|
655
|
+
// The user can read registrations for default group, but not events for default group
|
|
656
|
+
resources.set(
|
|
657
|
+
PermissionsResourceType.Groups, new Map([[
|
|
658
|
+
defaultGroup.id,
|
|
659
|
+
ResourcePermissions.create({
|
|
660
|
+
level: PermissionLevel.Read,
|
|
661
|
+
accessRights: [],
|
|
662
|
+
}),
|
|
663
|
+
]]),
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
await user.save();
|
|
667
|
+
|
|
668
|
+
await new RegistrationFactory({ member: member1, group }).create();
|
|
669
|
+
await new RegistrationFactory({ member: member2, group }).create();
|
|
670
|
+
|
|
671
|
+
// Try to request registrations for this group
|
|
672
|
+
const request = Request.get({
|
|
673
|
+
path: baseUrl,
|
|
674
|
+
host: organization.getApiHost(),
|
|
675
|
+
query: new LimitedFilteredRequest({
|
|
676
|
+
filter: {
|
|
677
|
+
groupId: group.id,
|
|
678
|
+
},
|
|
679
|
+
limit: 10,
|
|
680
|
+
}),
|
|
681
|
+
headers: {
|
|
682
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
683
|
+
},
|
|
684
|
+
});
|
|
685
|
+
await expect(testServer.test(endpoint, request)).rejects.toThrow(
|
|
686
|
+
STExpect.errorWithCode('permission_denied'),
|
|
687
|
+
);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
test('Not allowed: A user cannot request all registrations if only access to events for a single group', async () => {
|
|
691
|
+
// Same test, but without giving the user permissions to read the group
|
|
692
|
+
// Setup
|
|
693
|
+
const role = PermissionRoleDetailed.create({
|
|
694
|
+
name: 'Test Role',
|
|
695
|
+
accessRights: [],
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
const resources = new Map();
|
|
699
|
+
|
|
700
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
701
|
+
.create();
|
|
702
|
+
|
|
703
|
+
const user = await new UserFactory({
|
|
704
|
+
organization,
|
|
705
|
+
permissions: Permissions.create({
|
|
706
|
+
level: PermissionLevel.None,
|
|
707
|
+
roles: [
|
|
708
|
+
role,
|
|
709
|
+
],
|
|
710
|
+
resources,
|
|
711
|
+
}),
|
|
712
|
+
})
|
|
713
|
+
.create();
|
|
714
|
+
|
|
715
|
+
const token = await Token.createToken(user);
|
|
716
|
+
const member1 = await new MemberFactory({ }).create();
|
|
717
|
+
const member2 = await new MemberFactory({ }).create();
|
|
718
|
+
|
|
719
|
+
const defaultGroup = await new GroupFactory({ organization, period }).create();
|
|
720
|
+
const group = await new GroupFactory({ organization, period, type: GroupType.EventRegistration }).create();
|
|
721
|
+
|
|
722
|
+
// Event for all members of the organization (so no permission to this event)
|
|
723
|
+
await new EventFactory({
|
|
724
|
+
organization,
|
|
725
|
+
group,
|
|
726
|
+
startDate: period.startDate,
|
|
727
|
+
endDate: period.endDate,
|
|
728
|
+
}).create();
|
|
729
|
+
|
|
730
|
+
// The user can read members registered for default group, but not events for default group
|
|
731
|
+
resources.set(
|
|
732
|
+
PermissionsResourceType.Groups, new Map([[
|
|
733
|
+
defaultGroup.id,
|
|
734
|
+
ResourcePermissions.create({
|
|
735
|
+
level: PermissionLevel.Read,
|
|
736
|
+
accessRights: [AccessRight.EventWrite],
|
|
737
|
+
}),
|
|
738
|
+
]]),
|
|
739
|
+
);
|
|
740
|
+
|
|
741
|
+
await user.save();
|
|
742
|
+
|
|
743
|
+
await new RegistrationFactory({ member: member1, group }).create();
|
|
744
|
+
await new RegistrationFactory({ member: member2, group }).create();
|
|
745
|
+
|
|
746
|
+
// Try to request registrations for this group
|
|
747
|
+
const request = Request.get({
|
|
748
|
+
path: baseUrl,
|
|
749
|
+
host: organization.getApiHost(),
|
|
750
|
+
query: new LimitedFilteredRequest({
|
|
751
|
+
filter: {
|
|
752
|
+
groupId: group.id,
|
|
753
|
+
},
|
|
754
|
+
limit: 10,
|
|
755
|
+
}),
|
|
756
|
+
headers: {
|
|
757
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
758
|
+
},
|
|
759
|
+
});
|
|
760
|
+
await expect(testServer.test(endpoint, request)).rejects.toThrow(
|
|
761
|
+
STExpect.errorWithCode('permission_denied'),
|
|
762
|
+
);
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
test('Not allowed: A user cannot request registrations for the waiting list of an event if no permissions for event', async () => {
|
|
766
|
+
// Same test, but without giving the user permissions to read the group
|
|
767
|
+
// Setup
|
|
768
|
+
const role = PermissionRoleDetailed.create({
|
|
769
|
+
name: 'Test Role',
|
|
770
|
+
accessRights: [],
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
const resources = new Map();
|
|
774
|
+
|
|
775
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
776
|
+
.create();
|
|
777
|
+
|
|
778
|
+
const user = await new UserFactory({
|
|
779
|
+
organization,
|
|
780
|
+
permissions: Permissions.create({
|
|
781
|
+
level: PermissionLevel.None,
|
|
782
|
+
roles: [
|
|
783
|
+
role,
|
|
784
|
+
],
|
|
785
|
+
resources,
|
|
786
|
+
}),
|
|
787
|
+
})
|
|
788
|
+
.create();
|
|
789
|
+
|
|
790
|
+
const token = await Token.createToken(user);
|
|
791
|
+
const member1 = await new MemberFactory({ }).create();
|
|
792
|
+
const member2 = await new MemberFactory({ }).create();
|
|
793
|
+
const member3 = await new MemberFactory({ }).create();
|
|
794
|
+
|
|
795
|
+
const defaultGroup = await new GroupFactory({ organization, period }).create();
|
|
796
|
+
const waitingList = await new GroupFactory({ organization, period, type: GroupType.WaitingList }).create();
|
|
797
|
+
const group = await new GroupFactory({ organization, period, type: GroupType.EventRegistration, waitingListId: waitingList.id }).create();
|
|
798
|
+
|
|
799
|
+
await new EventFactory({
|
|
800
|
+
organization,
|
|
801
|
+
group,
|
|
802
|
+
startDate: period.startDate,
|
|
803
|
+
endDate: period.endDate,
|
|
804
|
+
meta: EventMeta.create({
|
|
805
|
+
groups: [
|
|
806
|
+
NamedObject.create({
|
|
807
|
+
id: defaultGroup.id,
|
|
808
|
+
name: defaultGroup.settings.name.toString(),
|
|
809
|
+
}),
|
|
810
|
+
],
|
|
811
|
+
}),
|
|
812
|
+
}).create();
|
|
813
|
+
|
|
814
|
+
// The user can read members registered for default group, but not events for default group
|
|
815
|
+
resources.set(
|
|
816
|
+
PermissionsResourceType.Groups, new Map([[
|
|
817
|
+
defaultGroup.id,
|
|
818
|
+
ResourcePermissions.create({
|
|
819
|
+
level: PermissionLevel.Read,
|
|
820
|
+
accessRights: [],
|
|
821
|
+
}),
|
|
822
|
+
]]),
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
await user.save();
|
|
826
|
+
|
|
827
|
+
await new RegistrationFactory({ member: member1, group: waitingList }).create();
|
|
828
|
+
await new RegistrationFactory({ member: member2, group: waitingList }).create();
|
|
829
|
+
await new RegistrationFactory({ member: member3, group }).create();
|
|
830
|
+
|
|
831
|
+
// Try to request members for this group
|
|
832
|
+
const request = Request.get({
|
|
833
|
+
path: baseUrl,
|
|
834
|
+
host: organization.getApiHost(),
|
|
835
|
+
query: new LimitedFilteredRequest({
|
|
836
|
+
filter: {
|
|
837
|
+
groupId: waitingList.id,
|
|
838
|
+
},
|
|
839
|
+
limit: 10,
|
|
840
|
+
}),
|
|
841
|
+
headers: {
|
|
842
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
843
|
+
},
|
|
844
|
+
});
|
|
845
|
+
await expect(testServer.test(endpoint, request)).rejects.toThrow(
|
|
846
|
+
STExpect.errorWithCode('permission_denied'),
|
|
847
|
+
);
|
|
848
|
+
});
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
describe('Default filtering', () => {
|
|
852
|
+
test('A user without read permissions for all groups will only see registrations of membership groups', async () => {
|
|
853
|
+
// Same test, but without giving the user permissions to read the group
|
|
854
|
+
// Setup
|
|
855
|
+
const role = PermissionRoleDetailed.create({
|
|
856
|
+
name: 'Test Role',
|
|
857
|
+
accessRights: [],
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
const resources = new Map();
|
|
861
|
+
|
|
862
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
863
|
+
.create();
|
|
864
|
+
|
|
865
|
+
const user = await new UserFactory({
|
|
866
|
+
organization,
|
|
867
|
+
permissions: Permissions.create({
|
|
868
|
+
level: PermissionLevel.None,
|
|
869
|
+
roles: [
|
|
870
|
+
role,
|
|
871
|
+
],
|
|
872
|
+
resources,
|
|
873
|
+
}),
|
|
874
|
+
})
|
|
875
|
+
.create();
|
|
876
|
+
|
|
877
|
+
const token = await Token.createToken(user);
|
|
878
|
+
const member1 = await new MemberFactory({ }).create();
|
|
879
|
+
const member2 = await new MemberFactory({ }).create();
|
|
880
|
+
const member3 = await new MemberFactory({ }).create();
|
|
881
|
+
const member4 = await new MemberFactory({ }).create();
|
|
882
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
883
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
884
|
+
const group3 = await new GroupFactory({ organization, period }).create();
|
|
885
|
+
|
|
886
|
+
const group4 = await new GroupFactory({ organization, period, type: GroupType.EventRegistration }).create();
|
|
887
|
+
|
|
888
|
+
// Give permission for 2 / 3 groups + one event group
|
|
889
|
+
resources.set(
|
|
890
|
+
PermissionsResourceType.Groups, new Map([[
|
|
891
|
+
group.id,
|
|
892
|
+
ResourcePermissions.create({
|
|
893
|
+
level: PermissionLevel.Read,
|
|
894
|
+
}),
|
|
895
|
+
], [
|
|
896
|
+
group2.id,
|
|
897
|
+
ResourcePermissions.create({
|
|
898
|
+
level: PermissionLevel.Write,
|
|
899
|
+
}),
|
|
900
|
+
], [
|
|
901
|
+
group4.id,
|
|
902
|
+
ResourcePermissions.create({
|
|
903
|
+
level: PermissionLevel.Read,
|
|
904
|
+
}),
|
|
905
|
+
]]),
|
|
906
|
+
);
|
|
907
|
+
|
|
908
|
+
await user.save();
|
|
909
|
+
|
|
910
|
+
const registration1 = await new RegistrationFactory({ member: member1, group }).create();
|
|
911
|
+
const registration2 = await new RegistrationFactory({ member: member2, group: group2 }).create();
|
|
912
|
+
await new RegistrationFactory({ member: member3, group: group3 }).create();
|
|
913
|
+
await new RegistrationFactory({ member: member4, group: group4 }).create();
|
|
914
|
+
|
|
915
|
+
// Try to request all registrations
|
|
916
|
+
const request = Request.get({
|
|
917
|
+
path: baseUrl,
|
|
918
|
+
host: organization.getApiHost(),
|
|
919
|
+
query: new LimitedFilteredRequest({
|
|
920
|
+
limit: 10,
|
|
921
|
+
}),
|
|
922
|
+
headers: {
|
|
923
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
924
|
+
},
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
// Response only includes registrations for a membership group, not the event group
|
|
928
|
+
const response = await testServer.test(endpoint, request);
|
|
929
|
+
expect(response.status).toBe(200);
|
|
930
|
+
expect(response.body.results.registrations).toHaveLength(2);
|
|
931
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
932
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
933
|
+
expect.objectContaining({ id: registration1.id }),
|
|
934
|
+
expect.objectContaining({ id: registration2.id }),
|
|
935
|
+
]);
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
test('A user with read permissions for all groups will also see registrations for event groups', async () => {
|
|
939
|
+
// Same test, but without giving the user permissions to read the group
|
|
940
|
+
// Setup
|
|
941
|
+
const role = PermissionRoleDetailed.create({
|
|
942
|
+
name: 'Test Role',
|
|
943
|
+
accessRights: [],
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
const resources = new Map();
|
|
947
|
+
|
|
948
|
+
const organization = await new OrganizationFactory({ period, roles: [role] })
|
|
949
|
+
.create();
|
|
950
|
+
|
|
951
|
+
const user = await new UserFactory({
|
|
952
|
+
organization,
|
|
953
|
+
permissions: Permissions.create({
|
|
954
|
+
level: PermissionLevel.None,
|
|
955
|
+
roles: [
|
|
956
|
+
role,
|
|
957
|
+
],
|
|
958
|
+
resources,
|
|
959
|
+
}),
|
|
960
|
+
})
|
|
961
|
+
.create();
|
|
962
|
+
|
|
963
|
+
const token = await Token.createToken(user);
|
|
964
|
+
const member1 = await new MemberFactory({ }).create();
|
|
965
|
+
const member2 = await new MemberFactory({ }).create();
|
|
966
|
+
const member3 = await new MemberFactory({ }).create();
|
|
967
|
+
const member4 = await new MemberFactory({ }).create();
|
|
968
|
+
const group = await new GroupFactory({ organization, period }).create();
|
|
969
|
+
const group2 = await new GroupFactory({ organization, period }).create();
|
|
970
|
+
const group3 = await new GroupFactory({ organization, period }).create();
|
|
971
|
+
|
|
972
|
+
const group4 = await new GroupFactory({ organization, period, type: GroupType.EventRegistration }).create();
|
|
973
|
+
|
|
974
|
+
// Give permission to all groups
|
|
975
|
+
resources.set(
|
|
976
|
+
PermissionsResourceType.Groups, new Map([[
|
|
977
|
+
'',
|
|
978
|
+
ResourcePermissions.create({
|
|
979
|
+
level: PermissionLevel.Read,
|
|
980
|
+
}),
|
|
981
|
+
]]),
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
await user.save();
|
|
985
|
+
|
|
986
|
+
const registration1 = await new RegistrationFactory({ member: member1, group }).create();
|
|
987
|
+
const registration2 = await new RegistrationFactory({ member: member2, group: group2 }).create();
|
|
988
|
+
const registration3 = await new RegistrationFactory({ member: member3, group: group3 }).create();
|
|
989
|
+
const registration4 = await new RegistrationFactory({ member: member4, group: group4 }).create();
|
|
990
|
+
|
|
991
|
+
// Try to request all members
|
|
992
|
+
const request = Request.get({
|
|
993
|
+
path: baseUrl,
|
|
994
|
+
host: organization.getApiHost(),
|
|
995
|
+
query: new LimitedFilteredRequest({
|
|
996
|
+
limit: 10,
|
|
997
|
+
}),
|
|
998
|
+
headers: {
|
|
999
|
+
authorization: 'Bearer ' + token.accessToken,
|
|
1000
|
+
},
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
// Response only includes members registered in a membership group, not the event group
|
|
1004
|
+
const response = await testServer.test(endpoint, request);
|
|
1005
|
+
expect(response.status).toBe(200);
|
|
1006
|
+
expect(response.body.results.registrations).toHaveLength(4);
|
|
1007
|
+
// Check ids are matching without depending on ordering using jest extended
|
|
1008
|
+
expect(response.body.results.registrations).toIncludeSameMembers([
|
|
1009
|
+
expect.objectContaining({ id: registration1.id }),
|
|
1010
|
+
expect.objectContaining({ id: registration2.id }),
|
|
1011
|
+
expect.objectContaining({ id: registration3.id }),
|
|
1012
|
+
expect.objectContaining({ id: registration4.id }),
|
|
1013
|
+
]);
|
|
1014
|
+
});
|
|
1015
|
+
});
|
|
1016
|
+
});
|