diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-21 01:35:13 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-21 01:35:13 +0200 |
| commit | 03bcfcdef2ff9a3d6ed0776f7580a45a5401ef37 (patch) | |
| tree | 84fa39ced04e0d82da1f40176e218b200c274761 /packages/meshbay-hub/src | |
| parent | 90e26beff212e4994b8e4f18c8260f2aa8a9b40c (diff) | |
| download | meshbay-03bcfcdef2ff9a3d6ed0776f7580a45a5401ef37.tar.gz | |
fix(hub): removing from a group no longer unpins the account
The node half called `unpin` after `revoke`, and an unpin takes no group:
it deletes the identity and every member row the account holds on this
node, and drops the stored keypair bundle with them. Taking somebody out
of one group took them out of all of them, silently. `revoke` is
group-scoped and is what withdraws the key.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/group-settings.js | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js index 16f6901..d7a1a66 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js @@ -738,6 +738,22 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, * take them back out. The hub half only ever removes access, so it is not * the half to skip when the other is in doubt; what the node said is * reported once the removal has been done, rather than in place of it. + * + * **The node half is `revoke`, and only `revoke`.** It used to unpin as + * well, and an unpin takes no group: `roster.unpin` deletes the identity and + * *every* member row the account holds on this node, and `ops.unpin_member` + * drops the stored keypair bundle with them. So taking somebody out of one + * group took them out of all of them — and a person removed from a group + * they had only been invited to lost the one they had been reading all + * afternoon, six hours before anyone noticed. Nothing on the node said so: + * the loopback path writes no audit entry, so the journal showed a clean + * join and then, hours later, a refusal with nothing in between. Their + * invitation was already spent, so there was no way back that did not start + * with a new code. Membership is per group; a pinned identity is the + * person's key for this whole node, and forgetting it is a separate + * operator decision with its own button (`node-page.js`). The MNP branch + * below never unpinned, which is the tell that this call was the odd one + * out rather than the pair of the other. */ const removeMember = useCallback(async (member) => { const transport = transportRef && transportRef.current; @@ -750,10 +766,6 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, await platform.node.call('POST', `/api/members/${member.user_id}/revoke?group_id=${groupId}`); } catch { /* best effort — node may not host this group */ } - try { - await platform.node.call('POST', - `/api/members/${member.user_id}/unpin`); - } catch { /* best effort */ } } else if (transport && transport.connected && operatorPaired) { const sk = transport.sessionKeys && transport.sessionKeys.skEdB64; const signFn = (sk && window.MeshBayKeys) |