Share files and folders with other people #91

Closed
opened 2026-08-27 16:07:25 +00:00 by jcoffey-dev · 0 comments
Owner

Calendars and address books have been shareable since JMAP Sharing went in. Files never was — though Stalwart treats file storage as a first-class thing to share, and ihasmail has carried the types for it all along. FilesRights and FileNode.shareWith were already declared; what was missing was asking for the property, offering the dialog, and saying so in the list.

Checked against live 0.16.19 first

Read-only, because building a picker against a mock that agrees with you proves nothing:

  • FileNode/get returns shareWith, and myRights carries all six rights — mayShare among them, true on one's own nodes. The menu entry has a real right to gate on, unlike folder sharing, which is offered ungated because MailboxRights has no such right.
  • Principal/query answers now that allowDirectoryQueries is on: six individuals, no groups.
  • ShareNotification/get is implemented. Worth knowing for later; nothing here reads it yet.

Also learned, and relevant to anyone touching the Files queries: filter: { parentId: null } is refused with a request-level HTTP 400 that kills every method call in the request, not just that one. files.ts already uses isTopLevel: true for the root and is fine — but a batched query per tree level would take the whole pane down with it.

The editor preset stops short on purpose

Read, add files, edit contents — and no further. Rename and delete stay with whoever shared the folder: someone given a folder to work in should not be able to rename the thing they were given, or delete it out from under the person who shared it. Both are still there to tick by hand.

One finding earned its own test

Stalwart answers shareWith as {} for a node shared with nobody, not null — every unshared node in a live account came back that way. A truthiness test on the property is true for every node the server has ever returned, so a badge driven by one reports the entire account as shared while being, technically, about the right property. isShared counts keys, and the test says why.

Verified

Against the mock, end to end: sharing Documents with a principal as Editor persists mayRead, mayAddChildren and mayModifyContent and nothing else; the badge appears on that folder and not on the file beside it; re-opening shows the saved rights rather than an empty form, which is what proves fileNodeProps is really asking for the property.

npm run typecheck clean; 297 web and 77 server tests pass, four of them new.

Nothing was written to the live account.

🤖 Generated with Claude Code

Merged 2026-08-27 as coffey-labs/ihasmail@fb789bc36f

Rebuilt from: git history, session transcript.

Calendars and address books have been shareable since JMAP Sharing went in. Files never was — though Stalwart treats file storage as a first-class thing to share, and ihasmail has carried the types for it all along. `FilesRights` and `FileNode.shareWith` were already declared; what was missing was asking for the property, offering the dialog, and saying so in the list. ### Checked against live 0.16.19 first Read-only, because building a picker against a mock that agrees with you proves nothing: - `FileNode/get` returns `shareWith`, and `myRights` carries all six rights — `mayShare` among them, true on one's own nodes. The menu entry has a real right to gate on, unlike folder sharing, which is offered ungated because `MailboxRights` has no such right. - `Principal/query` answers now that `allowDirectoryQueries` is on: six individuals, no groups. - `ShareNotification/get` is implemented. Worth knowing for later; nothing here reads it yet. Also learned, and relevant to anyone touching the Files queries: `filter: { parentId: null }` is refused with a **request-level HTTP 400** that kills every method call in the request, not just that one. `files.ts` already uses `isTopLevel: true` for the root and is fine — but a batched query per tree level would take the whole pane down with it. ### The editor preset stops short on purpose Read, add files, edit contents — and no further. Rename and delete stay with whoever shared the folder: someone given a folder to work in should not be able to rename the thing they were given, or delete it out from under the person who shared it. Both are still there to tick by hand. ### One finding earned its own test Stalwart answers `shareWith` as `{}` for a node shared with nobody, not `null` — every unshared node in a live account came back that way. A truthiness test on the property is true for every node the server has ever returned, so a badge driven by one reports the entire account as shared while being, technically, about the right property. `isShared` counts keys, and the test says why. ### Verified Against the mock, end to end: sharing Documents with a principal as Editor persists `mayRead`, `mayAddChildren` and `mayModifyContent` and nothing else; the badge appears on that folder and not on the file beside it; re-opening shows the saved rights rather than an empty form, which is what proves `fileNodeProps` is really asking for the property. `npm run typecheck` clean; 297 web and 77 server tests pass, four of them new. Nothing was written to the live account. 🤖 Generated with [Claude Code](https://claude.com/claude-code) **Merged** 2026-08-27 as coffey-labs/ihasmail@fb789bc36f44 <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.