fix: enforce team scoping for campaign, contacts, and invites#356
fix: enforce team scoping for campaign, contacts, and invites#356
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 WalkthroughDatabase lookups and service calls are scoped to team or contact-book context across multiple routes and services. Contact and contactBook queries now include contactBookId or teamId filters; team invite resend now requires (teamId, inviteId, teamName) and uses a team-scoped findFirst; tests were added to assert authorization behavior for campaign updates, team invite resending, contact retrieval, and Stripe webhook secret handling. Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying usesend with
|
| Latest commit: |
ce4eec8
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://26462adc.usesend.pages.dev |
| Branch Preview URL: | https://fix-team-scope-authorization.usesend.pages.dev |
Greptile SummaryThis PR adds critical team-scoping security checks across campaign, contact, and team invite operations to prevent unauthorized cross-team data access. Key security improvements:
Test coverage:
All changes follow the repository's testing conventions and use proper mocking patterns. Confidence Score: 5/5
Last reviewed commit: 57852f7 |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/web/src/server/service/team-service.ts (1)
310-322: Team-scoped invite lookup is correct and consistent withdeleteTeamInvite.The switch from
findUnique(global byid) tofindFirstfiltered by bothteamIdandidproperly prevents cross-team invite resends. One minor nit:id: { equals: inviteId }can be simplified toid: inviteId— Prisma treats them equivalently infindFirst.🔧 Optional: simplify the where clause
const invite = await db.teamInvite.findFirst({ where: { teamId, - id: { - equals: inviteId, - }, + id: inviteId, }, });Same simplification could apply to
deleteTeamInviteat Line 339–344 for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/server/service/team-service.ts` around lines 310 - 322, Simplify the Prisma where clauses by replacing the verbose id: { equals: inviteId } with the shorthand id: inviteId in the team-scoped lookup in resendTeamInvite (the db.teamInvite.findFirst call) and apply the same simplification to the corresponding deleteTeamInvite lookup (where db.teamInvite is queried) for consistency.apps/web/src/server/api/routers/team-security.trpc.test.ts (1)
28-28: Note:~/envis not mocked — works only for the error path.The
resendTeamInviteservice usesenv.NEXTAUTH_URLafter finding an invite. Since the current test only covers thenull(not found) path, this works fine. If you later add a happy-path test, you'll need to mock~/envas well.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/server/api/routers/team-security.trpc.test.ts` at line 28, The test only mocks the webhook service but not the environment, so future happy-path tests for the resendTeamInvite flow will fail because resendTeamInvite reads env.NEXTAUTH_URL; update the test (apps/web/src/server/api/routers/team-security.trpc.test.ts) to mock ~/env before importing or invoking resendTeamInvite (use vi.mock for '~/env' to provide a NEXTAUTH_URL value) so the service sees a valid NEXTAUTH_URL during happy-path tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/web/src/server/api/routers/team-security.trpc.test.ts`:
- Line 28: The test only mocks the webhook service but not the environment, so
future happy-path tests for the resendTeamInvite flow will fail because
resendTeamInvite reads env.NEXTAUTH_URL; update the test
(apps/web/src/server/api/routers/team-security.trpc.test.ts) to mock ~/env
before importing or invoking resendTeamInvite (use vi.mock for '~/env' to
provide a NEXTAUTH_URL value) so the service sees a valid NEXTAUTH_URL during
happy-path tests.
In `@apps/web/src/server/service/team-service.ts`:
- Around line 310-322: Simplify the Prisma where clauses by replacing the
verbose id: { equals: inviteId } with the shorthand id: inviteId in the
team-scoped lookup in resendTeamInvite (the db.teamInvite.findFirst call) and
apply the same simplification to the corresponding deleteTeamInvite lookup
(where db.teamInvite is queried) for consistency.
* fix: enforce team-scoped lookups for campaign contacts and invites * fix(test): mock domain service in campaign security test
Summary
get-contactlookups to the validated contact book so cross-book contact IDs are not returnedresendTeamInvitebyteamIdand add focused regression tests for campaign, contacts API, and team invite flowsSTRIPE_WEBHOOK_SECRETas undefined in that test fileVerification
Summary by cubic
Enforces team scoping for campaigns, public contact lookups, and invite resends to prevent cross-team access. Adds focused authorization tests and makes the Stripe webhook test deterministic.
Written for commit ce4eec8. Summary will update on new commits.
Summary by CodeRabbit
Bug Fixes
Tests