mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
fix(api): put a ceiling on editing a managed record's identity
`PATCH /api/managed-profiles/{id}` had none, while creating a record and
inviting a Guardian have both been capped at ten an hour since they shipped —
one family answering the same abuse three ways. It matters more here than the
count suggests: `updateManagedProfile` opens a transaction and takes an
advisory lock on the id it was HANDED before it decides the caller is not a
Guardian of it, so an unthrottled caller can name any id and make the database
hold a lock about it.
The refusal now lands before the id is read, on the same bucket convention and
with the same ceiling as creation. The GET beside it stays unlimited, matching
the guardian roster read next to it: both are cheap identity reads a Guardian
may already make. The 429 is documented on the contract and the edit form's
message mapping grew the arm creation already had.
This commit is contained in:
1 parent
c673255355
commit
0c46df1413
4 files changed
+54
-9
No files matched your search
@@ -366,16 +366,19 @@ export function managedProfileEditPatch(
|
||||
/**
|
||||
* The message for a refused edit.
|
||||
*
|
||||
* The same four arms creation carries, minus the rate limit it does not have,
|
||||
* and with the same reasoning: the step-up arm is a gate rather than a failure
|
||||
* and must not read as one, and a 422 is a disagreement between this form's
|
||||
* bounds and the route's rather than something the person typed — the
|
||||
* multi-issue envelope's `details.issues` never reach the browser.
|
||||
* The arms creation carries plus the one it does not need, and with the same
|
||||
* reasoning: the step-up arm is a gate rather than a failure and must not read
|
||||
* as one, a 429 is a wait rather than a failure and reuses creation's own line,
|
||||
* and a 422 is a disagreement between this form's bounds and the route's rather
|
||||
* than something the person typed — the multi-issue envelope's `details.issues`
|
||||
* never reach the browser. The 404 is this route's alone: the record can be
|
||||
* ended by another Guardian while the form sits open.
|
||||
*/
|
||||
export function editManagedProfileErrorKey(err: unknown): string {
|
||||
if (!(err instanceof ApiError)) return "recordSharing.managed.errorOffline";
|
||||
if (err.status === 401) return stepUpErrorKey(err);
|
||||
if (err.status === 422) return "recordSharing.managed.errorInvalid";
|
||||
if (err.status === 429) return "recordSharing.managed.errorRateLimit";
|
||||
if (err.status === 404) return "recordSharing.managed.editErrorGone";
|
||||
return "recordSharing.managed.editErrorFailed";
|
||||
}
|
||||
Reference in new issue
Block a user