@7365admin1/core 3.48.1-staging.177 → 3.48.1-staging.179
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/.changeset/facility-booking-site-scope.md +10 -0
- package/.changeset/max-seats-zero-unlimited.md +11 -0
- package/dist/index.js +18 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +96 -78
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/facility-booking-scope.e2e.test.mjs +456 -0
- package/test/e2e/harness.mjs +24 -1
- package/test/e2e/org-invite-seats.e2e.test.mjs +148 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the facility booking routes to the estate. `/api/facility-bookings` carried
|
|
6
|
+
`requireAuth` and nothing else on all five routes: any signed-in account could book
|
|
7
|
+
a facility at another estate, list another client's bookings, and read, rewrite or
|
|
8
|
+
cancel any booking by id alone — including moving a booking to a different estate.
|
|
9
|
+
Reach is now checked on the site named in the request, and on the stored row where
|
|
10
|
+
the request names only an id.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Treat a maximum seat count of 0 as unlimited when an organisation sends an
|
|
6
|
+
invitation. `createOrganizationInvite` read the subscription's `maxSeats` through
|
|
7
|
+
`?? 0` and then refused on any falsy value, so an organisation configured with 0
|
|
8
|
+
seats — which the plan dialog offers and the console labels UNLIMITED — had every
|
|
9
|
+
invitation rejected with "No seats configured for organization." 0 now admits
|
|
10
|
+
invitations without a cap, a real limit is still enforced at the limit, and only a
|
|
11
|
+
genuinely absent or non-numeric value is still treated as a misconfiguration.
|
package/dist/index.js
CHANGED
|
@@ -55697,6 +55697,14 @@ function useSiteFacilityBookingController() {
|
|
|
55697
55697
|
getSiteFacilityBookingById: _getSiteFacilityBookingById,
|
|
55698
55698
|
deleteSiteFacilityBookingById: _deleteSiteFacilityBookingById
|
|
55699
55699
|
} = useSiteFacilityBookingRepo();
|
|
55700
|
+
async function loadReachable(req, id) {
|
|
55701
|
+
const booking = await _getSiteFacilityBookingById(id);
|
|
55702
|
+
const { canReach } = await siteReachOf(req);
|
|
55703
|
+
if (!await canReach(booking)) {
|
|
55704
|
+
throw new import_node_server_utils168.NotFoundError("Site facility booking not found.");
|
|
55705
|
+
}
|
|
55706
|
+
return booking;
|
|
55707
|
+
}
|
|
55700
55708
|
async function add(req, res, next) {
|
|
55701
55709
|
try {
|
|
55702
55710
|
const { error, value } = schemaSiteFacilityBooking.validate(req.body, {
|
|
@@ -55708,6 +55716,7 @@ function useSiteFacilityBookingController() {
|
|
|
55708
55716
|
next(new import_node_server_utils168.BadRequestError(messages));
|
|
55709
55717
|
return;
|
|
55710
55718
|
}
|
|
55719
|
+
await requireSiteReach(req, value.site);
|
|
55711
55720
|
const data = await _add(value);
|
|
55712
55721
|
res.status(201).json(data);
|
|
55713
55722
|
return;
|
|
@@ -55741,6 +55750,7 @@ function useSiteFacilityBookingController() {
|
|
|
55741
55750
|
const sortObj = {
|
|
55742
55751
|
[sort]: order === "asc" /* ASC */ ? 1 : -1
|
|
55743
55752
|
};
|
|
55753
|
+
await requireSiteReach(req, site);
|
|
55744
55754
|
const data = await _getAll({
|
|
55745
55755
|
search,
|
|
55746
55756
|
page,
|
|
@@ -55768,7 +55778,7 @@ function useSiteFacilityBookingController() {
|
|
|
55768
55778
|
next(new import_node_server_utils168.BadRequestError(error.message));
|
|
55769
55779
|
return;
|
|
55770
55780
|
}
|
|
55771
|
-
const data = await
|
|
55781
|
+
const data = await loadReachable(req, value._id);
|
|
55772
55782
|
res.status(200).json(data);
|
|
55773
55783
|
return;
|
|
55774
55784
|
} catch (error) {
|
|
@@ -55792,6 +55802,9 @@ function useSiteFacilityBookingController() {
|
|
|
55792
55802
|
}
|
|
55793
55803
|
const { _id, ...rest } = value;
|
|
55794
55804
|
try {
|
|
55805
|
+
await loadReachable(req, _id);
|
|
55806
|
+
if (rest.site)
|
|
55807
|
+
await requireSiteReach(req, rest.site);
|
|
55795
55808
|
const result = await _updateSiteFacilityBookingById(_id, rest);
|
|
55796
55809
|
res.status(200).json({ message: result });
|
|
55797
55810
|
return;
|
|
@@ -55814,6 +55827,7 @@ function useSiteFacilityBookingController() {
|
|
|
55814
55827
|
}
|
|
55815
55828
|
const { _id } = value;
|
|
55816
55829
|
try {
|
|
55830
|
+
await loadReachable(req, _id);
|
|
55817
55831
|
await _deleteSiteFacilityBookingById(_id);
|
|
55818
55832
|
res.status(200).json({ message: "Successfully deleted site facility booking." });
|
|
55819
55833
|
return;
|
|
@@ -80429,12 +80443,12 @@ function useVerificationServiceV2() {
|
|
|
80429
80443
|
_countMemberByOrg(orgId),
|
|
80430
80444
|
_countPendingOrgInvites(orgId)
|
|
80431
80445
|
]);
|
|
80432
|
-
const maxSeats = subscription?.maxSeats
|
|
80433
|
-
if (!maxSeats) {
|
|
80446
|
+
const maxSeats = subscription?.maxSeats;
|
|
80447
|
+
if (typeof maxSeats !== "number" || !Number.isFinite(maxSeats)) {
|
|
80434
80448
|
throw new import_node_server_utils260.BadRequestError("No seats configured for organization.");
|
|
80435
80449
|
}
|
|
80436
80450
|
const usedSeats = memberCount + pendingInviteCount;
|
|
80437
|
-
if (usedSeats >= maxSeats) {
|
|
80451
|
+
if (maxSeats > 0 && usedSeats >= maxSeats) {
|
|
80438
80452
|
throw new import_node_server_utils260.BadRequestError("No available seats for new invitation.");
|
|
80439
80453
|
}
|
|
80440
80454
|
return createUserInvite({ email, metadata });
|