Stop offering to share mail folders, and let a share be removed
Sharing a mail folder does nothing. `Mailbox/set` takes the `shareWith` map, `Mailbox/get` reads it back, and the folder never appears for the account it was shared with -- confirmed on the live 0.16.19 with a folder shared read-only to another account on the same server, which never saw it. Stalwart's sharing documentation lists calendars, address books and file storage; mail folders are not among them. Nothing anywhere reports a failure, so a client that trusts what it reads back shows the share as live for ever, which is what happened. The entry point is withdrawn. Address book sharing goes with it on a report that it behaved the same way -- not reproduced, and contradicted by Stalwart's own docs, so that one is expected back; it is out because offering a share nobody can verify was worse than the gap. Files and calendars are untouched. Removing a share was impossible, for a reason worth writing down. The dialog rendered the list of who a thing was shared with *inside* the branch that runs when the directory has principals to offer. A server with `allowDirectoryQueries` off returns none -- that is the default, and it is how these shares came to be made in the first place -- so the dialog showed one line of hint and nothing else. The share was there, and there was no way to see it, let alone remove it. The list is now rendered whatever the directory says; only the control for adding somebody new depends on having somebody to add. So the withdrawn entry points do not strand what they created: a folder or book already shared still offers "Stop sharing", which is the one thing you want when the share is invisible everywhere else. The API was never the problem, which is worth recording since it was the first guess: `shareWith: null` is accepted and clears the map, tested against the live server on the stuck folder, which is now unshared.
This commit is contained in:
@@ -104,9 +104,17 @@ export function ShareDialog({ kind, id, name, shareWith, onClose }: { kind: Kind
|
||||
|
||||
return (
|
||||
<Dialog open onClose={onClose} title={`Share “${name}”`} size="lg" footer={<><button className="btn" onClick={onClose}>Cancel</button><button className="btn btn-primary" disabled={busy} onClick={() => void save()}>Save</button></>}>
|
||||
{!principals.length ? (
|
||||
<p className="hint">No other users found in the directory, or sharing is not enabled on this server.</p>
|
||||
) : (
|
||||
{/* The list of who it is shared with is rendered whether or not anybody
|
||||
can be *added*. It used to sit inside the branch below, so a server
|
||||
with directory queries switched off -- which is the default, and which
|
||||
returns no principals -- showed nothing but the hint, and an existing
|
||||
share could not be seen, let alone removed. */}
|
||||
{!principals.length && (
|
||||
<p className="hint" style={{ marginBottom: 12 }}>
|
||||
No other users found in the directory, so nobody new can be added. Sharing already in place is listed below and can still be removed.
|
||||
</p>
|
||||
)}
|
||||
{principals.length > 0 && (
|
||||
<>
|
||||
<div className="row" style={{ marginBottom: 12 }}>
|
||||
<select className="select" value={pick} onChange={(e) => setPick(e.target.value)}>
|
||||
@@ -118,7 +126,9 @@ export function ShareDialog({ kind, id, name, shareWith, onClose }: { kind: Kind
|
||||
<button className="btn" disabled={!pick} onClick={() => { const p = principals.find((x) => x.id === pick); if (p) add(p, "reader"); }}>Viewer</button>
|
||||
<button className="btn btn-primary" disabled={!pick} onClick={() => { const p = principals.find((x) => x.id === pick); if (p) add(p, "editor"); }}>Editor</button>
|
||||
</div>
|
||||
{Object.entries(rights).map(([pid, r]) => {
|
||||
</>
|
||||
)}
|
||||
{Object.entries(rights).map(([pid, r]) => {
|
||||
const p = principals.find((x) => x.id === pid);
|
||||
return (
|
||||
<div key={pid} className="card">
|
||||
@@ -136,10 +146,8 @@ export function ShareDialog({ kind, id, name, shareWith, onClose }: { kind: Kind
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{!Object.keys(rights).length && <p className="hint">Not shared with anyone yet.</p>}
|
||||
</>
|
||||
)}
|
||||
})}
|
||||
{!Object.keys(rights).length && <p className="hint">Not shared with anyone yet.</p>}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user