Public Access
fix(freelancer-edit): save sends the hash and uses PATCH
The save was authorised by the record id alone — ids are small sequential integers, publicly visible on every directory card, so a PATCH carrying only an id let one visitor overwrite another's listing. The save now: - uses PATCH (C.saveMethod), matching n8n - carries the hash in the body under the same "has" key the delete already sends, so save and delete share one credential path, alongside the record id - refuses to fire at all when the page holds no hash, and says why in the status line Everything else is unchanged: the 15-point gate, receipt only on 2xx, the honest failure line that keeps the edits, the save.disabled handling and the DELETE shape.
This commit is contained in:
1 parent
768dc1151a
commit
7dfd5aec9b
1 file changed
+18
-6
@@ -164,9 +164,11 @@
|
|||||||
hashKeys: ["has", "hash"],
|
hashKeys: ["has", "hash"],
|
||||||
// Wire name used OUTWARD on the GET query string.
|
// Wire name used OUTWARD on the GET query string.
|
||||||
hashWireKey: "has",
|
hashWireKey: "has",
|
||||||
// SAVE: POST with the record id — the admin path's convention (POST with an id =
|
// SAVE: PATCH the existing record, carrying BOTH the hash (the credential, same key
|
||||||
// update an existing record). Match this method in the n8n workflow.
|
// the delete already sends) and the record id. An id alone authorises nothing: record
|
||||||
saveMethod: "POST",
|
// ids are small sequential integers, publicly visible on every directory card, so a
|
||||||
|
// request without the hash is refused before it is sent. Match this method in n8n.
|
||||||
|
saveMethod: "PATCH",
|
||||||
// DELETE: unverified. A route that refuses it (404/405/501) is a clear failure and
|
// DELETE: unverified. A route that refuses it (404/405/501) is a clear failure and
|
||||||
// this page never reports success on a non-2xx. Match this method in the workflow.
|
// this page never reports success on a non-2xx. Match this method in the workflow.
|
||||||
deleteMethod: "DELETE",
|
deleteMethod: "DELETE",
|
||||||
@@ -566,12 +568,22 @@
|
|||||||
focusTotalLine.setAttribute("data-bad", "1");
|
focusTotalLine.setAttribute("data-bad", "1");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// A save is authorised by the HASH, not by the id. If this page holds no hash there
|
||||||
|
// is nothing to prove ownership, so the request is not fired at all — a PATCH
|
||||||
|
// carrying only an id is exactly the hole this closes. Say why, do not fail silently.
|
||||||
|
if (!hash) {
|
||||||
|
line.className = "status state-err";
|
||||||
|
line.textContent = "This link arrived without its code, so we cannot save your " +
|
||||||
|
"changes. Open it again from the email that brought you here.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
save.disabled = true;
|
save.disabled = true;
|
||||||
line.className = "status";
|
line.className = "status";
|
||||||
line.textContent = "Saving…";
|
line.textContent = "Saving…";
|
||||||
// The body shape: the record's id + every field this form owns. SAVE_METHOD is
|
// The body shape: the credential (the SAME "has" key the delete sends, one
|
||||||
// C.saveMethod ("POST", the admin path's convention).
|
// credential path for both) + the record's id + every field this form owns.
|
||||||
var payload = { id: rec && rec.id !== undefined ? rec.id : undefined };
|
// Method is C.saveMethod ("PATCH").
|
||||||
|
var payload = { has: hash, id: rec && rec.id !== undefined ? rec.id : undefined };
|
||||||
payload.Name = document.getElementById("edName").value.trim();
|
payload.Name = document.getElementById("edName").value.trim();
|
||||||
payload.Focus = document.getElementById("edFocus").value.trim();
|
payload.Focus = document.getElementById("edFocus").value.trim();
|
||||||
payload.description = document.getElementById("edDescription").value.trim();
|
payload.description = document.getElementById("edDescription").value.trim();
|
||||||
|
|||||||
Reference in new issue
Block a user