Moved from objectstack-ai/objectstack#8092 at triage (file-at-destination: the fix is UI affordance gating in this repo). Filed 2026-08-12 by @baozhoutao from a multi-org console walkthrough, original grading priority:p2. Batch siblings: objectstack-ai/objectstack#8090 #8091 #8093 #8094.
Triage note: this is the UI half only. The server-side question — whether org_member should be able to read the invitation ledger at all — is escalated separately as objectstack-ai/objectstack#8095 (needs-user-decision); do not couple this card to that ruling.
On /_console/organizations/<slug>/members, a user whose org role is member is shown the Invite member button and a per-row Member actions menu containing Remove member — including on the row of the workspace Owner. Nothing is disabled or hidden; the action only fails after the user commits to it.
Repro
- User A owns workspace 甲; user B joins it as
member.
- As B, open
/_console/organizations/acme-jia/members.
Actual
The server does gate the write — POST /api/v1/auth/organization/invite-member as the member returns:
403 {"message":"You are not allowed to invite users to this organization",
"code":"YOU_ARE_NOT_ALLOWED_TO_INVITE_USERS_TO_THIS_ORGANIZATION"}
so this is a UI-gating gap, not a privilege escalation. (remove-member was not exercised destructively; a probe with a non-existent member returned 400 MEMBER_NOT_FOUND, i.e. the lookup runs before the permission check, so that path's gating is unverified from the client side and worth a look while fixing.)
Expected
A member sees no invite or remove affordances — matching the Settings tab of the very same page, which already gets this right: it replaces the form with "只有所有者可以修改设置。" and disables Delete organization while leaving Leave organization enabled. The members/invitations tabs simply never got the same treatment.
Where
packages/app-shell/src/console/organizations/manage/ — MembersPage (invite button + row actions) and InviteMemberDialog. The active member's role is already available via the org context used elsewhere on the page.
Environment
Local dev server http://localhost:8080, multi-org enabled, zh locale, observed 2026-08-12. The server was started by the maintainer and its exact commit is not verified.
On
/_console/organizations/<slug>/members, a user whose org role ismemberis shown the Invite member button and a per-row Member actions menu containing Remove member — including on the row of the workspace Owner. Nothing is disabled or hidden; the action only fails after the user commits to it.Repro
member./_console/organizations/acme-jia/members.Actual
You are not allowed to invite users to this organization(also see the i18n card console: organization & invitation UI ships untranslated English in a zh locale (6 sites, incl. icon-only aria-labels) #4474).…menu on every row, the Owner's included, offers Remove member.The server does gate the write —
POST /api/v1/auth/organization/invite-memberas the member returns:so this is a UI-gating gap, not a privilege escalation. (
remove-memberwas not exercised destructively; a probe with a non-existent member returned400 MEMBER_NOT_FOUND, i.e. the lookup runs before the permission check, so that path's gating is unverified from the client side and worth a look while fixing.)Expected
A
membersees no invite or remove affordances — matching the Settings tab of the very same page, which already gets this right: it replaces the form with "只有所有者可以修改设置。" and disables Delete organization while leaving Leave organization enabled. The members/invitations tabs simply never got the same treatment.Where
packages/app-shell/src/console/organizations/manage/—MembersPage(invite button + row actions) andInviteMemberDialog. The active member's role is already available via the org context used elsewhere on the page.Environment
Local dev server
http://localhost:8080, multi-org enabled, zh locale, observed 2026-08-12. The server was started by the maintainer and its exact commit is not verified.