@7365admin1/core 3.48.1-staging.188 → 3.48.1-staging.190

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.
@@ -0,0 +1,23 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ Scope a subscription's invoices to the subscription's owner.
6
+
7
+ `GET /api/invoices/subscription/:id` carried `requireAuth` and nothing more, and
8
+ `invoice.controller.ts` held no authorization identifier of any kind: the
9
+ subscription id came off the URL and went straight into the query. Being signed
10
+ in anywhere on the platform was therefore enough to page through another
11
+ organisation's billing history — invoice numbers, amounts, line-item
12
+ descriptions, due dates and payment status.
13
+
14
+ A new module-named `requireInvoiceReach` takes the verdict off the STORED
15
+ subscription, never from anything the caller supplied. A subscription is owned
16
+ by an organisation OR by a single user, so both are checked: `siteReachOf`'s
17
+ `canReach` answers the organisation half, and the personal half is the caller
18
+ being that user. A subscription that names neither is refused. "Not yours",
19
+ "does not exist" and "not a valid id" all answer 404 identically, so
20
+ subscription ids cannot be enumerated.
21
+
22
+ Read access to invoice records only — no card handling, no payment gateway and
23
+ no money movement is touched.
@@ -0,0 +1,12 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ Scope the site facility routes to the estate. `/api/site-facilities` carried
6
+ `requireAuth` and nothing else on all six routes: any signed-in account could add a
7
+ facility to another estate, list another client's facilities — or, by omitting the
8
+ optional `site` filter, every estate's facilities at once — and read, rewrite or
9
+ archive any facility by id alone, including its opening hours, booking fees, deposit
10
+ and policies. Reach is now checked on the site named in the request, and on the
11
+ stored row where the request names only an id; the unfiltered cross-estate list is
12
+ left to platform staff.
package/dist/index.js CHANGED
@@ -31022,6 +31022,15 @@ var import_node_server_utils82 = require("@7365admin1/node-server-utils");
31022
31022
  var import_joi39 = __toESM(require("joi"));
31023
31023
  function useInvoiceController() {
31024
31024
  const { getBySubscriptionId: _getBySubscriptionId } = useInvoiceRepo();
31025
+ const { getById: _getSubscriptionById } = useSubscriptionRepo();
31026
+ async function requireInvoiceReach(req, id) {
31027
+ const subscription = await _getSubscriptionById(id).catch(() => null);
31028
+ const { actor, canReach } = await siteReachOf(req);
31029
+ const owned = await canReach(subscription) || Boolean(actor.id) && Boolean(subscription?.user) && subscription?.user?.toString() === actor.id;
31030
+ if (!owned) {
31031
+ throw new import_node_server_utils82.NotFoundError("Subscription not found.");
31032
+ }
31033
+ }
31025
31034
  async function getBySubscriptionId(req, res, next) {
31026
31035
  const validation = import_joi39.default.object({
31027
31036
  id: import_joi39.default.string().required(),
@@ -31044,6 +31053,7 @@ function useInvoiceController() {
31044
31053
  const page = parseInt(req.query.page ?? "1");
31045
31054
  const limit = parseInt(req.query.limit ?? "10");
31046
31055
  try {
31056
+ await requireInvoiceReach(req, id);
31047
31057
  const data = await _getBySubscriptionId({
31048
31058
  id,
31049
31059
  search,
@@ -54711,6 +54721,14 @@ function useSiteFacilityController() {
54711
54721
  getSiteFacilityById: _getSiteFacilityById,
54712
54722
  deleteSiteFacilityById: _deleteSiteFacilityById
54713
54723
  } = useSiteFacilityRepo();
54724
+ async function requireFacilityReach(req, id) {
54725
+ const facility = await _getSiteFacilityById(id);
54726
+ const { canReach } = await siteReachOf(req);
54727
+ if (!await canReach(facility)) {
54728
+ throw new import_node_server_utils162.NotFoundError("Site facility not found.");
54729
+ }
54730
+ return facility;
54731
+ }
54714
54732
  async function add(req, res, next) {
54715
54733
  const payload = { ...req.body };
54716
54734
  const { error } = schemaSiteFacility.validate(payload, {
@@ -54723,6 +54741,7 @@ function useSiteFacilityController() {
54723
54741
  return;
54724
54742
  }
54725
54743
  try {
54744
+ await requireSiteReach(req, payload.site);
54726
54745
  const data = await _add(payload);
54727
54746
  res.status(201).json(data);
54728
54747
  return;
@@ -54769,6 +54788,13 @@ function useSiteFacilityController() {
54769
54788
  }
54770
54789
  });
54771
54790
  try {
54791
+ if (site) {
54792
+ await requireSiteReach(req, site);
54793
+ } else {
54794
+ const { actor } = await siteReachOf(req);
54795
+ if (!actor.isSuperAdmin)
54796
+ throw new import_node_server_utils162.UnauthorizedError("Not authorized.");
54797
+ }
54772
54798
  const data = await _getAll({
54773
54799
  search,
54774
54800
  page,
@@ -54795,7 +54821,7 @@ function useSiteFacilityController() {
54795
54821
  return;
54796
54822
  }
54797
54823
  try {
54798
- const data = await _getSiteFacilityById(_id);
54824
+ const data = await requireFacilityReach(req, _id);
54799
54825
  res.status(200).json(data);
54800
54826
  return;
54801
54827
  } catch (error2) {
@@ -54817,6 +54843,7 @@ function useSiteFacilityController() {
54817
54843
  return;
54818
54844
  }
54819
54845
  try {
54846
+ await requireFacilityReach(req, _id);
54820
54847
  const result = await _updateSiteFacilityById(_id, req.body);
54821
54848
  res.status(200).json({ message: result });
54822
54849
  return;
@@ -54836,6 +54863,7 @@ function useSiteFacilityController() {
54836
54863
  return;
54837
54864
  }
54838
54865
  try {
54866
+ await requireFacilityReach(req, _id);
54839
54867
  await _deleteSiteFacilityById(_id);
54840
54868
  res.status(200).json({ message: "Successfully deleted site facility." });
54841
54869
  return;
@@ -54862,6 +54890,7 @@ function useSiteFacilityController() {
54862
54890
  return next(new import_node_server_utils162.BadRequestError(error.message));
54863
54891
  }
54864
54892
  try {
54893
+ await requireSiteReach(req, value.site);
54865
54894
  const data = await _getSiteFacilityTimeSlotById(
54866
54895
  payload._id,
54867
54896
  value.date,