@7365admin1/core 3.47.1-staging.136 → 3.47.1-staging.137

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,35 @@
1
+ ---
2
+ "@7365admin1/core": minor
3
+ ---
4
+
5
+ Restrict the unauthenticated invitation-status write to the one transition its
6
+ callers actually perform.
7
+
8
+ `PATCH /api/auth/verification/status` (`API-core auth.route.ts:36`) carries no
9
+ middleware, and it cannot be given any: every caller is an invitation-landing
10
+ page opened from an emailed link **before an account exists** —
11
+ `web-app-main` `pages/verify/invitation/[id].vue`,
12
+ `pages/verify/service-provider/[id].vue`,
13
+ `pages/verify/service-provider-invite/[id].vue` and
14
+ `pages/sign-up-invite/service-provider/index.vue`, all through
15
+ `layer-common composables/useLocalAuth.ts:130`. Adding `requireAuth` would break
16
+ invitation acceptance for everybody, including the shipped clients.
17
+
18
+ What is restricted instead is what an anonymous caller may *do*. Each of those
19
+ pages calls `GET /auth/verify/:id` first, and `verify`
20
+ (`verification.service.ts:661-690`) already refuses an invitation that is
21
+ expired, cancelled or complete — so the only transition a real caller ever
22
+ performs is `pending -> complete`. Accepting the other three states let anyone
23
+ who learned an invitation id:
24
+
25
+ - set a used invitation back to `pending` and replay it,
26
+ - revive a `cancelled` or `expired` invitation, or
27
+ - burn somebody else's pending invitation by marking it `complete` before they
28
+ opened the email.
29
+
30
+ The handler now accepts only `complete`, loads the invitation and requires it to
31
+ be `pending`. Completing an already-complete invitation still answers 200 so a
32
+ page that calls this twice is not broken. Cancelling an invitation on purpose
33
+ keeps its own session-protected endpoint,
34
+ `PUT /api/verifications/:id/cancel` (`verification.route.ts:13`), so no
35
+ capability is removed.
package/dist/index.js CHANGED
@@ -19440,7 +19440,7 @@ function useVerificationController() {
19440
19440
  updateStatusById: _updateStatusById,
19441
19441
  cancelUserInvitation: _cancelUserInvitation
19442
19442
  } = useVerificationService();
19443
- const { getVerifications: _getVerifications } = useVerificationRepo();
19443
+ const { getVerifications: _getVerifications, getById: _getVerificationById } = useVerificationRepo();
19444
19444
  async function createUserInvite(req, res, next) {
19445
19445
  const payload = { ...req.body };
19446
19446
  const validation = import_joi21.default.object({
@@ -19825,7 +19825,7 @@ function useVerificationController() {
19825
19825
  async function updateVerificationStatus(req, res, next) {
19826
19826
  const validation = import_joi21.default.object({
19827
19827
  id: import_joi21.default.string().hex().required(),
19828
- status: import_joi21.default.string().valid("pending", "complete", "expired", "cancelled").required()
19828
+ status: import_joi21.default.string().valid("complete").required()
19829
19829
  });
19830
19830
  const { error } = validation.validate(req.body);
19831
19831
  if (error) {
@@ -19835,6 +19835,23 @@ function useVerificationController() {
19835
19835
  }
19836
19836
  try {
19837
19837
  const { id, status } = req.body;
19838
+ const verification = await _getVerificationById(id);
19839
+ if (!verification) {
19840
+ next(new import_node_server_utils47.BadRequestError("Verification not found."));
19841
+ return;
19842
+ }
19843
+ if (verification.status === "complete") {
19844
+ res.json({ message: "Successfully updated verification status." });
19845
+ return;
19846
+ }
19847
+ if (verification.status !== "pending") {
19848
+ next(
19849
+ new import_node_server_utils47.BadRequestError(
19850
+ `Verification is ${verification.status} and cannot be completed.`
19851
+ )
19852
+ );
19853
+ return;
19854
+ }
19838
19855
  const result = await _updateStatusById(id, status);
19839
19856
  res.json({ message: result });
19840
19857
  return;