feat: group management UI in AclMembersPanel (#307)#310
Open
schmug wants to merge 2 commits into
Open
Conversation
Extends the per-mailbox ACL to support Cloudflare Access group grants alongside the existing email-member list, so orgs can manage mailbox access by team/role without maintaining per-mailbox email lists. Key changes: - `MailboxAcl.groups?: string[]` — optional field; absent = no group grants; existing email-only ACL blobs remain valid without migration - `callerGroupsFromJwt()` — decodes the `groups` claim from the already-verified CF Access JWT (no re-verification, sourced only from the signed token, never a spoofable header) - `callerInAcl()` gains a third `callerGroups` param; access is granted when the caller is in `members` OR belongs to a granted group name - `requireMailbox` and `GET /api/v1/mailboxes` both extract groups from the JWT and pass them to `callerInAcl` - `POST /api/v1/mailboxes/:id/acl/groups` and `DELETE /api/v1/mailboxes/:id/acl/groups/:name` — owner-only group add/remove; `GET /acl` now returns `groups[]` alongside owner/members Tests: callerInAcl group-grant, deny non-member, email-only unchanged, no-ACL backwards-compat, callerGroupsFromJwt, requireMailbox integration (1093 passing, 0 failing) Deferred (follow-up): group management in AclMembersPanel UI https://claude.ai/code/session_019pmwmDXFom1HzioGUAgAbF
Adds a Groups section below Members in AclMembersPanel with add/remove controls mirroring the existing member UI. Extends api.ts with addAclGroup/removeAclGroup, adds useAddAclGroup/useRemoveAclGroup hooks, updates useMailboxAcl return type to include groups: string[], and extends acl-members route tests to cover POST /groups (idempotent add), DELETE /groups/:name, and non-owner 403. https://claude.ai/code/session_01WpLc5TwgfQr642pqrvgs1q
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ais-hub | 5e1785a | Commit Preview URL Branch Preview URL |
May 22 2026, 11:18 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
AclMembersPanelwith an add (plain-text input) and per-group remove button, mirroring the existing member UI patternapp/services/api.tswithaddAclGroup/removeAclGroupAPI calls; addsuseAddAclGroup/useRemoveAclGroupmutation hooks inapp/queries/mailboxes.ts; updatesuseMailboxAclreturn type to includegroups: string[]tests/routes/acl-members.test.tswith route-level tests forPOST /acl/groups(idempotent add, non-owner 403, missing field 400) andDELETE /acl/groups/:name(remove, non-owner 403, URL-encoded group name)Closes #307
Stacking note: This branch builds on
claude/wizardly-einstein-cgUZc(PR #306). Before merging #307, flip its base tomainand rebase withgit rebase --onto origin/main 86d47e7to drop the upstream commits cleanly.Test plan
npm test— 1100 passing, 0 failingnpm run typecheck— no TypeScript errorsPOST /acl/groupsadds group, idempotent on duplicate, 403 for non-owner, 400 for missing fieldDELETE /acl/groups/:nameremoves group, 403 for non-owner, URL-decodes group name with spacesAclMembersPanelrenders a Groups section listing current groups with remove buttonssettings-behavior,hub-settings,security-settings,settings-attachment-scannerto expose the two new hooksAcceptance items
useMailboxAclquery remains in error state, panel never renders edit controlsuseMailboxAclreturn type includesgroups: string[]; TypeScript is happyhttps://claude.ai/code/session_01WpLc5TwgfQr642pqrvgs1q
Generated by Claude Code