diff options
Diffstat (limited to 'packages/meshbay-hub/src')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/group-settings.js | 19 |
1 files changed, 17 insertions, 2 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 4d67348..16f6901 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/group-settings.js @@ -727,11 +727,23 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, * wrapped for them; if the hub removal then fails, they are a member on paper * with no key. The other order would leave them able to reach a node that * still serves them. + * + * **A node that refuses does not cancel the hub half.** It used to: the node + * call threw, the whole removal ended there, and the person stayed a member + * everywhere — the list here (the hub answers it), the owner's other + * sessions, the administrator's view — with nothing said about which half + * had failed. Someone invited to the wrong group hit it every time, because + * a node holds no member row for an invitation nobody has redeemed and + * answered "no such member in that group" to the only button offering to + * 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. */ const removeMember = useCallback(async (member) => { const transport = transportRef && transportRef.current; setError(''); setRemoving(member.user_id); + let nodeError = ''; try { if (platform.node.available) { try { @@ -747,14 +759,17 @@ function GroupSettingsPanel({ groupId, group, token, transportRef, gekRef, const signFn = (sk && window.MeshBayKeys) ? (transcript) => window.MeshBayKeys.signBytes(sk, transcript) : null; - await transport.revokeMember(member.user_id, signFn); + try { + await transport.revokeMember(member.user_id, signFn); + } catch (err) { nodeError = err.message; } } await hubFetch(`/v1/groups/${groupId}/members/${member.username}`, { method: 'DELETE', token, }); loadMembers(); + if (nodeError) setError(nodeError); } catch (err) { - setError(err.message); + setError(nodeError ? `${nodeError} — ${err.message}` : err.message); } finally { setRemoving(''); } |