Michael Wiencek 3be4a854cb MBS-13959: Prevent submitting relationships for a different source entity
The simplified cause of this issue was that all relationship/external link
editor forms shared the same `sessionStorage` keys. Normally that wasn't a
problem, because the keys were only read on POST and overwritten on form
submission. The problem occurred when a POST happened with no form submission,
while at the same time `sessionStorage` still had data from a previous form.
(One way that could happen was being logged out, as the login form performs a
POST to the destination endpoint.)

This commit adds a number of mitigations for this issue on both the client and
server side:

 * On the client side, we now use separate keys for each entity, and make sure
   to clear them whenever we can. (That's actually a bit more important now
   that the number of keys could otherwise grow infinitely with the number of
   entities one edits within the same tab.)

 * On the server side, we now check whether the source entity of each
   submitted link or relationship matches the entity whose edit page was
   submitted. That's done indirectly by changing how
   `Controller::Role::EditRelationships` loads relationships: instead of
   trusting each relationship ID to belong to the source and blindly
   passing it to `get_by_id`, we pass all relationship IDs to `load_subset`
   instead, which already restricts the source entity column.

   While it would've technically been possible to verify the source entity of
   each individual relationship from `get_by_id`, it would've also required
   figuring out their (original) direction, which `load_subset` does for us.
2025-03-07 17:46:53 -06:00
..