mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-26 06:19:49 +00:00
7e7bb61989
* fix(invitations): a pending invitation dies with its inviter's authority (BUG-3770) An accept re-read the inviter's membership and let it through when the inviter was no longer a member, so a removed owner's pending codes kept minting members until they expired. requireInviterScopeTx now refuses unless the inviter is still a member, still an owner, and not restricted to specific collections: one share-locked select of role and scope on Postgres, never upgraded. A demotion, a removal (there is no self-leave door) and a restriction all refuse with the existing inviter_scope_changed at all three accept doors. Instance admins stay exempt. The doors that offer an Accept use the same predicate, unlocked (InviterCanStillGrant): the pending list hides such an invitation (hidden, not deleted, so it returns if the authority does), and the /join preview reports inviter_can_grant, which the page turns into an "inviter can no longer grant access" state with no Accept and no form. Five fixtures built invitations whose inviter held no authority in any reachable state (an invitee inviting itself, an owner_id user with no member row); they now invite from a real owner. Claude-Session: https://claude.ai/code/session_01MPeShv3DBfM9C94PTvMnqi * docs(api): the inviter re-check covers removal and demotion; preview inviter_can_grant (BUG-3770) Claude-Session: https://claude.ai/code/session_01MPeShv3DBfM9C94PTvMnqi