Skip to content

fix(groups): enforce invite role hierarchy - #604

Merged
junhoyeo merged 1 commit into
junhoyeo:mainfrom
IvGolovach:codex/groups-invite-role-hierarchy
May 27, 2026
Merged

fix(groups): enforce invite role hierarchy#604
junhoyeo merged 1 commit into
junhoyeo:mainfrom
IvGolovach:codex/groups-invite-role-hierarchy

Conversation

@IvGolovach

@IvGolovach IvGolovach commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR enforces the existing group role hierarchy when creating group invites. Admins can still invite regular members, and owners can still invite admins, but invites can no longer bypass the direct role-management restrictions.

Why

Direct member role changes already require the actor to outrank the target role. The invite route did not apply the same rule before creating an invite, so an admin could create an admin invite and grant peer-level permissions through the join flow.

Diff Scope

  • Applies canManageGroupRole in POST /api/groups/[slug]/invite before creating an invite.
  • Adds route coverage for admin-created admin invites, owner-created admin invites, admin-created member invites, owner-role invite rejection, and invalid-role fallback behavior.

Branch Integrity

  • Base: junhoyeo/tokscale:main
  • Validated base SHA: 8e73312f05f603d5184d36059e4ce2604322d492
  • Head: IvGolovach:codex/groups-invite-role-hierarchy
  • Head SHA: ae01b4648e7746bc0fe25d04cb00ae473324e46a
  • Ahead/behind: 0 behind / 1 ahead

Commit Integrity

  • ae01b4648e7746bc0fe25d04cb00ae473324e46a fix(groups): enforce invite role hierarchy
  • Final diff only touches the group invite route and targeted route test coverage.

Diff Hygiene

  • git diff --check origin/main...HEAD: PASS, no output
  • Forbidden/local artifact files: not present
  • DB migrations: not applicable; no schema changed
  • Ledger: not applicable; not required for this change family
  • Version: not applicable; not required for this change family

Validation

Validation mode: Mode 2 — narrow frontend route permission change.

  • bun x vitest run __tests__/api/groupInviteRoute.test.ts: PASS
  • bun x vitest run __tests__/api/groupInviteRoute.test.ts __tests__/api/groupInviteJoinRoute.test.ts __tests__/lib/groupInvites.test.ts __tests__/lib/groupHelpers.test.ts: PASS, 14 tests
  • bun x vitest run __tests__/api/group*.test.ts __tests__/lib/group*.test.ts: PASS, 20 tests
  • bun x eslint __tests__/api/groupInviteRoute.test.ts 'src/app/api/groups/[slug]/invite/route.ts': PASS
  • git diff --check origin/main...HEAD: PASS

Not used as proof: full frontend lint/typecheck currently report unrelated existing issues outside this diff, so this PR relies on targeted route coverage and targeted ESLint.

CI Context

Pending — required remote checks will run after the PR is opened.

Runtime Safety

This only tightens an existing permission check on invite creation. It does not change invite token format, invite acceptance persistence, group membership schema, or cache invalidation behavior. No invariant regression introduced.

Rollback Plan

Rollback: revert this PR.

DB downgrade: not applicable.

Data repair: not applicable.

Operational caveats: reverting would restore the invite-based role escalation path for group admins.

Known Residual Risks

None known for the scoped permission fix.

Validation
* Validation tier: Tier 2 - narrow runtime change, route-level permission check for group invite creation.
* bun x vitest run __tests__/api/groupInviteRoute.test.ts: PASS after fix; RED before fix failed as expected with admin-created admin invite returning 201 instead of 403.
* bun x vitest run __tests__/api/groupInviteRoute.test.ts __tests__/api/groupInviteJoinRoute.test.ts __tests__/lib/groupInvites.test.ts __tests__/lib/groupHelpers.test.ts: PASS, 14 tests.
* bun x vitest run __tests__/api/group*.test.ts __tests__/lib/group*.test.ts: PASS, 20 tests.
* bun x eslint __tests__/api/groupInviteRoute.test.ts 'src/app/api/groups/[slug]/invite/route.ts': PASS.
* git diff --check: PASS.
* git diff --cached --check: PASS.
* Ledger: not applicable - not required for selected validation tier/change family.
* Version: not applicable - not required for selected validation tier/change family.
* Not required: full frontend lint/typecheck for this targeted route change; when probed, bun run lint and bun x tsc -p tsconfig.json --noEmit fail on unrelated existing frontend issues outside this diff.

Rollback
* git revert HEAD
@vercel

vercel Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tokscale Ready Ready Preview, Comment May 25, 2026 9:28pm

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

@junhoyeo
junhoyeo merged commit 8c6df8e into junhoyeo:main May 27, 2026
5 checks passed
@junhoyeo

Copy link
Copy Markdown
Owner

@IvGolovach this has been merged to v3.0.0: https://github.com/junhoyeo/tokscale/releases/tag/v3.0.0 thanks for the contribution!

leecoder pushed a commit to leecoder/tokscale that referenced this pull request May 29, 2026
Validation
* Validation tier: Tier 2 - narrow runtime change, route-level permission check for group invite creation.
* bun x vitest run __tests__/api/groupInviteRoute.test.ts: PASS after fix; RED before fix failed as expected with admin-created admin invite returning 201 instead of 403.
* bun x vitest run __tests__/api/groupInviteRoute.test.ts __tests__/api/groupInviteJoinRoute.test.ts __tests__/lib/groupInvites.test.ts __tests__/lib/groupHelpers.test.ts: PASS, 14 tests.
* bun x vitest run __tests__/api/group*.test.ts __tests__/lib/group*.test.ts: PASS, 20 tests.
* bun x eslint __tests__/api/groupInviteRoute.test.ts 'src/app/api/groups/[slug]/invite/route.ts': PASS.
* git diff --check: PASS.
* git diff --cached --check: PASS.
* Ledger: not applicable - not required for selected validation tier/change family.
* Version: not applicable - not required for selected validation tier/change family.
* Not required: full frontend lint/typecheck for this targeted route change; when probed, bun run lint and bun x tsc -p tsconfig.json --noEmit fail on unrelated existing frontend issues outside this diff.

Rollback
* git revert HEAD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants