Invite an address straight to a folder: invitations on the shard #185

Merged
nectenda-agent merged 1 commit from worktree-nec-123-folder-invitations into main 2026-09-26 18:53:45 +01:00
Collaborator

Task: NEC-123 — https://projectron.nerchure.com/tasks/123

Server half of "invite straight to a folder". Collaborating took two invitations — a seat in the organisation, then a per-folder grant from the members dialog after they joined — and the second is the one people missed.

  • Migration 11: folder_invitations (folder, organisation, address, role, inviter, expiry, claimed/revoked/lapsed). No key material.
  • POST/GET/DELETE /folders/:id/invitations: owners only, 404 to non-members, 409 ALREADY_IN_ORGANISATION for someone already seated (the client adds them directly instead), 403 NOT_HOSTED on self-hosted servers because a claim matches on an address only the identity service verifies.
  • Claimed on /auth/join (every way in) and on /auth/session (catch-up), only inside the folder's organisation and only while the inviter still owns the folder; otherwise marked lapsed and shown to the owners.
  • GET /folders/awaiting-keys: members of folders the caller owns who lack a key the caller holds, for the plugin to wrap automatically (next pull request).
  • Moves with an account; cascades with its folder.
  • docs/ux-review-relay.md: the UX comparison with Relay that motivated this and the cards that follow (NEC-124 to NEC-128).
  • security-model.md: the new metadata listed under "What is not encrypted".

Mutation-checked: removing the organisation filter, the inviter-still-owner rule, the expiry, the hosted-only refusal and the already-seated refusal each fails a test.

Changelog

Owners can invite an email address straight to a shared folder, and the person becomes a member of it the moment they join.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NnpsVLx9NmMG2N2nJnA8mR

Task: NEC-123 — https://projectron.nerchure.com/tasks/123 Server half of "invite straight to a folder". Collaborating took two invitations — a seat in the organisation, then a per-folder grant from the members dialog after they joined — and the second is the one people missed. - Migration 11: `folder_invitations` (folder, organisation, address, role, inviter, expiry, claimed/revoked/lapsed). No key material. - `POST/GET/DELETE /folders/:id/invitations`: owners only, 404 to non-members, 409 `ALREADY_IN_ORGANISATION` for someone already seated (the client adds them directly instead), 403 `NOT_HOSTED` on self-hosted servers because a claim matches on an address only the identity service verifies. - Claimed on `/auth/join` (every way in) and on `/auth/session` (catch-up), only inside the folder's organisation and only while the inviter still owns the folder; otherwise marked lapsed and shown to the owners. - `GET /folders/awaiting-keys`: members of folders the caller owns who lack a key the caller holds, for the plugin to wrap automatically (next pull request). - Moves with an account; cascades with its folder. - `docs/ux-review-relay.md`: the UX comparison with Relay that motivated this and the cards that follow (NEC-124 to NEC-128). - `security-model.md`: the new metadata listed under "What is not encrypted". Mutation-checked: removing the organisation filter, the inviter-still-owner rule, the expiry, the hosted-only refusal and the already-seated refusal each fails a test. ## Changelog Owners can invite an email address straight to a shared folder, and the person becomes a member of it the moment they join. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01NnpsVLx9NmMG2N2nJnA8mR
Record folder invitations on the shard, claimed when the address joins
All checks were successful
Release note / release-note (pull_request) Successful in 14s
CI / build (pull_request) Successful in 4m50s
CI / e2e (pull_request) Successful in 5m21s
CI / promote (pull_request) Has been skipped
Deploy site / deploy (push) Successful in 48s
CI / build (push) Successful in 4m57s
CI / e2e (push) Successful in 5m16s
CI / promote (push) Successful in 30s
866ce6d7de
Collaborating took two invitations: a seat in the organisation, then a
per-folder grant from the members dialog after they had joined. The second
is the one people missed. An owner can now invite an address straight to a
folder; the shard records it (no key material) and makes the person a
member when they take a seat by any route, inside that organisation only
and only while the inviter still owns the folder. /folders/awaiting-keys
tells an owner's client who still needs a key wrapped, which the plugin
change that follows does automatically.

Hosted only: a claim matches on an address the identity service verified.

Also docs/ux-review-relay.md, the comparison with Relay that led here.

Task: NEC-123

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NnpsVLx9NmMG2N2nJnA8mR
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Nectenda/nectenda!185
No description provided.