Skip to content

Comments

feat: enhance Discord invite generation with application-specific handling#2579

Merged
iamitprakash merged 2 commits intodevelopfrom
anuj/fix-generate-invite
Feb 24, 2026
Merged

feat: enhance Discord invite generation with application-specific handling#2579
iamitprakash merged 2 commits intodevelopfrom
anuj/fix-generate-invite

Conversation

@AnujChhikara
Copy link
Contributor

@AnujChhikara AnujChhikara commented Feb 22, 2026

Date: 22 feb, 2026

Developer Name: @AnujChhikara


Issue Ticket Number

Description

  • Added applicationId and role validation in the invite generation process.
  • Updated the invite retrieval method to support application-scoped invites.
  • Enhanced middleware to pass applicationId to the request object.
  • Implemented tests for application-specific invite generation scenarios.

Documentation Updated?

  • Yes
  • No

Under Feature Flag

  • Yes
  • No

Database Changes

  • Yes
  • No

Breaking Changes

  • Yes
  • No

Development Tested?

  • Yes
  • No

Screenshots

Screenshot 1
screen-recording-2026-02-23-at-95438-am_8zl6qODr.mp4

Test Coverage

Screenshot 1 image

Additional Notes

…dling

- Added applicationId and role validation in the invite generation process.
- Updated the invite retrieval method to support application-scoped invites.
- Enhanced middleware to pass applicationId to the request object.
- Implemented tests for application-specific invite generation scenarios.
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

Walkthrough

This pull request extends Discord invite functionality to be application-scoped. Changes include modifying the controller to extract and validate application identifiers, implementing a new model function to fetch invites by both user and application, updating the middleware to populate the application ID in the request, extending TypeScript type definitions, and adding corresponding test coverage.

Changes

Cohort / File(s) Summary
Discord Invite Model
models/discordactions.js
Added new getUserDiscordInviteByApplication(userId, applicationId) function that fetches Discord invites filtered by both userId and applicationId, with proper error handling and logging.
Discord Controller Logic
controllers/discordactions.js
Updated generateInviteForUser to extract applicationId and role from request properties, added guard clause validating both values, switched to getUserDiscordInviteByApplication for application-scoped lookup, and extended invite payload to include applicationId in storage.
Request Type Definition
types/global.d.ts
Extended CustomRequest type with new optional field approvedApplicationId?: string to support application-scoped request data.
Middleware Integration
middlewares/checkCanGenerateDiscordLink.ts
Added single line to populate req.approvedApplicationId from approved application data in success path.
Integration & Unit Tests
test/integration/discordactions.test.js, test/unit/models/discordactions.test.js
Added integration test verifying 409 response for duplicate application invites; added unit tests for getUserDiscordInviteByApplication covering matching invites, missing documents, and legacy documents without applicationId; added tests for latest invite selection by createdAt ordering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • iamitprakash
  • prakashchoudhary07

Poem

🐰 A Discord invite, now scoped so tight,
One app at a time, doing it right!
No more mix-ups, each one's its own,
Application-bound, a cleaner zone!
✨ Hop hop, the invites align!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: enhancing Discord invite generation with application-specific handling, which aligns with the substantial modifications across controllers, middleware, models, and tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description clearly relates to the changeset, detailing specific changes made to applicationId handling, invite retrieval methods, and middleware updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch anuj/fix-generate-invite

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controllers/discordactions.js (1)

497-503: ⚠️ Potential issue | 🟡 Minor

TOCTOU race condition between existence check and invite creation.

Two concurrent requests from the same user+application can both pass the getUserDiscordInviteByApplication check before either commits to addInviteToInviteModel, resulting in duplicate invite documents. Since Firestore doesn't offer row-level locks, the safest mitigation is wrapping both operations in a Firestore transaction, or alternatively accepting the low probability and adding a unique constraint at the data layer (e.g., a dedicated document keyed by userId_applicationId).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controllers/discordactions.js` around lines 497 - 503, The current two-step
check using discordRolesModel.getUserDiscordInviteByApplication followed by
addInviteToInviteModel introduces a TOCTOU race; modify the logic so
existence-check and create happen atomically: either (1) perform both operations
inside a Firestore transaction (use the same firestore instance and
transaction.get on the invite query/document then transaction.create/update to
add the invite) around getUserDiscordInviteByApplication/addInviteToInviteModel,
or (2) switch to a single write that fails if a sentinel/unique document keyed
by `${userId}_${applicationId}` already exists (create that document with a
deterministic ID and treat create failure as “already exists”); change the code
paths that call getUserDiscordInviteByApplication and addInviteToInviteModel to
use the chosen atomic approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controllers/discordactions.js`:
- Around line 491-494: The new guard blocks super users because
checkCanGenerateDiscordLink short-circuits without setting
req.approvedApplicationId/req.approvedApplicationRole, so update the controller
around the applicationId/role check to handle the super-user path separately:
detect super users (e.g., req.user.isSuperUser or the same flag used by
checkCanGenerateDiscordLink) and either accept applicationId from
req.query/req.body for super users or skip the application-scoped guard for
them; keep the existing behavior for non-super users by continuing to read
req.approvedApplicationId and req.approvedApplicationRole and returning 403 only
when those are missing for non-super users.

In `@models/discordactions.js`:
- Around line 1269-1273: The compound query using
discordInvitesModel.where("userId","==", userId).where("applicationId","==",
applicationId) requires a composite Firestore index to avoid inefficient
index-merge scans; add a composite index entry in firestore.indexes.json for the
collection "discord-invites" with fields userId ASC and applicationId ASC so the
query in models/discordactions.js (the discordInvitesModel compound equality
query) uses the dedicated composite index.
- Line 1280: Replace the incorrect logger call in the catch block that currently
uses logger.log("error in getting user invite by application", err) with
logger.error so the error is recorded at the proper severity; locate the catch
handling around the code that fetches user invites (search for the string "error
in getting user invite by application" or the surrounding function where user
invites are retrieved) and change logger.log to logger.error while keeping the
same message and error variable.

In `@test/integration/discordactions.test.js`:
- Around line 1176-1197: Add integration tests to cover the successful and
missing-application cases for the application-scoped POST
/discord-actions/invite flow: add a test that stubs
ApplicationModel.getUserApplications to return the accepted app, stubs
discordRolesModel.getUserDiscordInviteByApplication to return notFound: true and
stubs discordRolesModel.createDiscordInvite (or the method used to create
invites) to resolve with an object containing inviteLink, then assert the
endpoint returns 201 and res.body.inviteLink; also add a test that simulates
ApplicationModel.getUserApplications returning no application (or missing
application data) and assert the endpoint returns 403 with message "Application
data is required". Use the same test harness variables (app, userAuthToken,
cookieName) and the existing describe "POST /discord-actions/invite
(application-scoped)" to place these tests.

In `@test/unit/models/discordactions.test.js`:
- Around line 894-911: The test assumes getUserDiscordInvite returns the latest
invite by createdAt but the implementation (getUserDiscordInvite in
models/discordactions.js) does a plain where("userId","==",userId).get() with no
ordering; either update getUserDiscordInvite to explicitly order and limit
(e.g., append .orderBy("createdAt","desc").limit(1) to the query and return that
single doc) if the intended behavior is "latest", or remove/adjust the unit test
to not assert a specific inviteLink and instead test only deterministic behavior
(such as using getUserDiscordInviteByApplication or checking notFound). Ensure
you change only the function/query or the test assertion so behavior and tests
align.
- Around line 914-942: The new tests in the describe blocks
getUserDiscordInviteByApplication and the recently-added test in
getUserDiscordInvite create Firestore documents but lack cleanup; add an
afterEach(() => cleanDb()) inside each affected describe block (or move the new
test into its own nested describe with afterEach) so cleanDb() is run after
every test; target the describe blocks named "getUserDiscordInviteByApplication"
and "getUserDiscordInvite" and ensure afterEach invokes the existing cleanDb
helper.

---

Outside diff comments:
In `@controllers/discordactions.js`:
- Around line 497-503: The current two-step check using
discordRolesModel.getUserDiscordInviteByApplication followed by
addInviteToInviteModel introduces a TOCTOU race; modify the logic so
existence-check and create happen atomically: either (1) perform both operations
inside a Firestore transaction (use the same firestore instance and
transaction.get on the invite query/document then transaction.create/update to
add the invite) around getUserDiscordInviteByApplication/addInviteToInviteModel,
or (2) switch to a single write that fails if a sentinel/unique document keyed
by `${userId}_${applicationId}` already exists (create that document with a
deterministic ID and treat create failure as “already exists”); change the code
paths that call getUserDiscordInviteByApplication and addInviteToInviteModel to
use the chosen atomic approach.

@iamitprakash iamitprakash merged commit 6b705b0 into develop Feb 24, 2026
4 checks passed
@iamitprakash iamitprakash deleted the anuj/fix-generate-invite branch February 24, 2026 19:18
@AnujChhikara AnujChhikara mentioned this pull request Feb 24, 2026
10 tasks
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.

3 participants