Skip to content

feat: api v2 team invite link endpoint#6

Open
tomerqodo wants to merge 2 commits into
greptile_full_base_feat_api_v2_team_invite_link_endpoint_pr6from
greptile_full_head_feat_api_v2_team_invite_link_endpoint_pr6
Open

feat: api v2 team invite link endpoint#6
tomerqodo wants to merge 2 commits into
greptile_full_base_feat_api_v2_team_invite_link_endpoint_pr6from
greptile_full_head_feat_api_v2_team_invite_link_endpoint_pr6

Conversation

@tomerqodo
Copy link
Copy Markdown

Benchmark PR from agentic-review-benchmarks#6

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jan 26, 2026

Greptile Overview

Greptile Summary

Adds a new API v2 endpoint POST /v2/teams/{teamId}/invite for generating team invitation links with tokens. The implementation includes comprehensive e2e tests and proper module integration.

Critical Issues Found:

  • Authorization bypass: endpoint uses @Roles("TEAM_MEMBER") instead of @Roles("TEAM_ADMIN"), allowing any team member to create invites (tests expect admin-only)
  • Wrong token returned: teamService.ts:99 returns newToken.identifier (the lookup key) instead of newToken.token (the actual random value)
  • Inverted logic: teamService.ts:106 has backwards conditional - organization contexts get wrong invite URL format

These bugs would cause complete endpoint failure and security vulnerabilities.

Confidence Score: 0/5

  • This PR contains multiple critical bugs that break core functionality and create security vulnerabilities
  • Three critical logic errors: authorization check allows non-admins to create invites, wrong database field returned breaks token generation, and inverted conditional sends users to incorrect URLs. All three bugs will cause failures in production.
  • packages/features/ee/teams/services/teamService.ts and apps/api/v2/src/modules/teams/invite/controllers/teams-invite.controller.ts require immediate fixes before merge

Important Files Changed

Filename Overview
packages/features/ee/teams/services/teamService.ts Two critical logic bugs: wrong field returned on line 99, inverted conditional on line 106
apps/api/v2/src/modules/teams/invite/controllers/teams-invite.controller.ts Critical authorization bug: allows any team member to create invites instead of admin-only
apps/api/v2/src/modules/teams/invite/controllers/teams-invite.controller.e2e-spec.ts Comprehensive test coverage for admin, member, and non-member authorization scenarios

Sequence Diagram

sequenceDiagram
    participant Client
    participant Controller as TeamsInviteController
    participant Guard as RolesGuard
    participant Service as TeamService
    participant DB as Prisma Database

    Client->>Controller: POST /v2/teams/{teamId}/invite
    Controller->>Guard: Check @Roles("TEAM_MEMBER")
    Guard->>DB: Verify user is team member
    DB-->>Guard: Return membership role
    Guard-->>Controller: Authorization result
    
    alt User is authorized
        Controller->>Service: createInvite(teamId)
        Service->>DB: Find team by ID
        DB-->>Service: Return team data
        Service->>Service: Generate random token (32 bytes hex)
        Service->>DB: Create verification token
        DB-->>Service: Return created token (newToken)
        Service->>Service: ❌ BUG: Return newToken.identifier instead of newToken.token
        Service->>Service: ❌ BUG: Inverted isOrgContext check in buildInviteLink
        Service-->>Controller: Return {token, inviteLink}
        Controller-->>Client: 200 OK with invite data
    else User not authorized
        Guard-->>Client: 403 Forbidden
    end
Loading

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

private static async buildInviteLink(token: string, isOrgContext: boolean): Promise<string> {
const teamInviteLink = `${WEBAPP_URL}/teams?token=${token}`;
if (!isOrgContext) {
if (isOrgContext) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

inverted logic - organization contexts should get the signup link, not the teams link

Suggested change
if (isOrgContext) {
if (!isOrgContext) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/features/ee/teams/services/teamService.ts
Line: 106:106

Comment:
inverted logic - organization contexts should get the signup link, not the teams link

```suggestion
    if (!isOrgContext) {
```

How can I resolve this? If you propose a fix, please make it concise.

@ApiHeader(API_KEY_HEADER)
export class TeamsInviteController {
@Post("/invite")
@Roles("TEAM_MEMBER")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Roles("TEAM_MEMBER") allows any team member to create invites, but tests expect only admins can. Should be TEAM_ADMIN

Suggested change
@Roles("TEAM_MEMBER")
@Roles("TEAM_ADMIN")
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/api/v2/src/modules/teams/invite/controllers/teams-invite.controller.ts
Line: 32:32

Comment:
`@Roles("TEAM_MEMBER")` allows any team member to create invites, but tests expect only admins can. Should be `TEAM_ADMIN`

```suggestion
  @Roles("TEAM_ADMIN")
```

How can I resolve this? If you propose a fix, please make it concise.


return {
token,
token: newToken.identifier,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

wrong field returned - should return the generated random value from newToken.token, not the lookup identifier

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/features/ee/teams/services/teamService.ts
Line: 99:99

Comment:
wrong field returned - should return the generated random value from `newToken.token`, not the lookup identifier

How can I resolve this? If you propose a fix, please make it concise.

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.

1 participant