Skip to content

feat: add applicant image upload functionality#2564

Merged
iamitprakash merged 1 commit intodevelopfrom
anuj/application-user-image-upload
Feb 21, 2026
Merged

feat: add applicant image upload functionality#2564
iamitprakash merged 1 commit intodevelopfrom
anuj/application-user-image-upload

Conversation

@AnujChhikara
Copy link
Contributor

@AnujChhikara AnujChhikara commented Feb 2, 2026

Date: 17 Feb, 2026

Developer Name: @AnujChhikara


Issue Ticket Number

Description

  • Modify the current user picture upload endpoint to support application image upload functionality

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-21.at.1.52.27.AM.mov

Test Coverage

Screenshot 1 image image

Additional Notes

@AnujChhikara AnujChhikara self-assigned this Feb 2, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

A new application picture upload feature is added, including error message constants, Cloudinary configuration, a POST endpoint with file validation middleware, image service integration for Cloudinary uploads, and comprehensive test coverage for both success and failure scenarios.

Changes

Cohort / File(s) Summary
Constants
constants/application.ts, constants/cloudinary.ts
Added error messages for picture file validation (PICTURE_FILE_MISSING, PICTURE_FILE_EMPTY) and Cloudinary configuration for application folder and tags.
Picture Upload Implementation
middlewares/validators/application.ts, controllers/applications.ts, routes/applications.ts, services/imageService.js
New middleware validator for picture uploads with file presence, buffer, and MIME type checks; controller endpoint for handling uploads; route definition with Multer integration; service function to encode and upload images to Cloudinary.
Test Coverage
test/integration/application.test.ts, test/unit/controllers/applications.test.ts, test/unit/middlewares/application-validator.test.ts
Integration tests for authenticated/unauthenticated upload scenarios and unit tests for controller and middleware validation with success and error path coverage.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Router
    participant Authenticate as Auth Middleware
    participant ValidatePic as Validator Middleware
    participant Controller
    participant ImageService
    participant Cloudinary

    Client->>Router: POST /applications/picture (file, auth token)
    Router->>Authenticate: Check authentication
    Authenticate->>Router: User verified
    Router->>ValidatePic: Validate file
    ValidatePic->>ValidatePic: Check file presence & MIME type
    ValidatePic->>Router: Validation passed
    Router->>Controller: Forward request
    Controller->>ImageService: uploadApplicationImage({file, userId})
    ImageService->>ImageService: Encode to Base64 Data URI
    ImageService->>Cloudinary: Upload with public_id
    Cloudinary-->>ImageService: Return publicId & URL
    ImageService-->>Controller: Return {publicId, url}
    Controller-->>Client: 201 Created {message, image}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • iamitprakash

Poem

🐰 A file hops into the burrow with care,
Validated thrice through the validator's snare,
To Cloudinary's clouds it takes flight,
201 success, the picture shines bright!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding image upload functionality for applicants, which matches the primary objective of the pull request across all modified files.
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, mentioning applicant/application image upload functionality which aligns with all modified files.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch anuj/application-user-image-upload

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.

@MayankBansal12 MayankBansal12 marked this pull request as ready for review February 4, 2026 05:50
@MayankBansal12
Copy link
Member

@coderabbitai review bro

@coderabbitai
Copy link

coderabbitai bot commented Feb 4, 2026

@MayankBansal12: Sure thing! I'll review the changes in this PR right away. 🚀

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 3

🤖 Fix all issues with AI agents
In `@routes/applications.ts`:
- Around line 19-25: The POST /picture route lacks rate limiting—add the
existing commonRateLimiter middleware into the router.post middleware chain
before the upload handler so requests hit rate limits; specifically update the
router.post call that currently lists authenticate, upload.single("profile"),
applicationValidator.validateApplicationPicture, and
applications.postUserPicture to include commonRateLimiter (imported from
middlewares/rateLimiting.js) in the middleware sequence (e.g., after
authenticate and before upload.single) so the route uses commonRateLimiter and
still calls applicationValidator.validateApplicationPicture and
applications.postUserPicture.

In `@test/integration/application.test.ts`:
- Around line 361-397: Add integration tests for the validation/error paths
around the POST /applications/picture route: add a test that sends no attachment
and asserts the response is the expected validation error from
validateApplicationPicture (e.g., 400 and appropriate error message), a test
that attaches an invalid file type (e.g., .txt or .gif) and asserts the
middleware returns the correct validation response, and a test where
sinon.stub(imageService, "uploadApplicationImage") is made to reject to assert
the route returns the service error (status/code and message) and is handled
correctly; place these alongside the existing tests in application.test.ts and
reuse the same auth cookie setup (cookieName/secondUserJwt) and
mockUploadResponse reference but adjust stubbing/attachment to trigger each
path.
- Around line 381-396: The test stubs imageService.uploadApplicationImage but
never restores it, risking test pollution; update the test suite to restore the
stub after the case by adding an afterEach that calls sinon.restore() (or
explicitly calls uploadApplicationImage.restore() if you capture the stub
variable) so the stub created in the "should return 201 and image data when
authenticated with valid image" test is removed before other tests run; locate
the stub usage in the test that posts to "/applications/picture" and add the
afterEach cleanup alongside other per-test cleanup blocks.

@AnujChhikara AnujChhikara force-pushed the anuj/application-user-image-upload branch from 36bf39e to 856f32d Compare February 5, 2026 19:39
Suvidh-kaushik
Suvidh-kaushik previously approved these changes Feb 6, 2026
MayankBansal12
MayankBansal12 previously approved these changes Feb 16, 2026
Copy link
Contributor

@prakashchoudhary07 prakashchoudhary07 left a comment

Choose a reason for hiding this comment

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

@AnujChhikara Why is this needed? Don't we already have a profile uploading API route?

@AnujChhikara
Copy link
Contributor Author

@AnujChhikara Why is this needed? Don't we already have a profile uploading API route?

Yes Sir we do have another route for the image upload but that has the validation that user should be part of discord and some other functionality like adding image for verification for both discord and that uploaded image.

Here is the link for that part Upload Image function

@prakashchoudhary07
Copy link
Contributor

@AnujChhikara Why is this needed? Don't we already have a profile uploading API route?

Yes Sir we do have another route for the image upload but that has the validation that user should be part of discord and some other functionality like adding image for verification for both discord and that uploaded image.

Here is the link for that part Upload Image function

Okay, so what do we have to do to use the existing route?

@AnujChhikara
Copy link
Contributor Author

@AnujChhikara Why is this needed? Don't we already have a profile uploading API route?

Yes Sir we do have another route for the image upload but that has the validation that user should be part of discord and some other functionality like adding image for verification for both discord and that uploaded image.
Here is the link for that part Upload Image function

Okay, so what do we have to do to use the existing route?

We can use query param here and based on that make the discord user middleware optional and then need to create one function that based on query param trigger old image upload function or this application image upload function

iamitprakash
iamitprakash previously approved these changes Feb 19, 2026
router.post("/picture", authenticate, checkIsVerifiedDiscord, upload.single("profile"), users.postUserPicture);
router.post(
"/picture",
authenticate,

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
This route handler performs
authorization
, but is not rate-limited.
This route handler performs
authorization
, but is not rate-limited.

Copilot Autofix

AI 7 days ago

In general, this should be fixed by introducing a rate-limiting middleware (for example using the well-known express-rate-limit package) and applying it to the sensitive route(s) that perform authentication/authorization and potentially expensive operations. The middleware should be configured with reasonable windowMs and max values to balance protection and usability, and should be placed early enough in the middleware chain that expensive handlers (like file parsing and business logic) are not invoked when the limit is exceeded.

For this specific code, the most targeted change that does not alter existing functionality is:

  • Import express-rate-limit at the top of routes/users.js.
  • Define a limiter specifically for the /picture upload route (e.g., something like userPictureUploadLimiter allowing a small number of uploads per minute per IP).
  • Insert this limiter in the middleware chain for the /picture POST route before the Multer upload.single("profile") middleware, so that excessive requests are rejected before file parsing and subsequent authorization/Discord checks.

Concretely:

  • At the top of routes/users.js after the existing require statements, add const rateLimit = require("express-rate-limit"); and a new const userPictureUploadLimiter = rateLimit({ ... }) definition.
  • Modify the router.post("/picture", ...) route to insert userPictureUploadLimiter between authenticate and upload.single("profile").
    No other routes need to be changed to address this specific alert; the change remains tightly scoped to the flagged route and uses a standard, well-known dependency.
Suggested changeset 2
routes/users.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/routes/users.js b/routes/users.js
--- a/routes/users.js
+++ b/routes/users.js
@@ -16,7 +16,15 @@
 const { userAuthorization } = require("../middlewares/userAuthorization");
 const conditionalMiddleware = require("../middlewares/conditionalMiddleware");
 const skipWhenApplicationType = require("../middlewares/pictureRouteMiddleware");
+const rateLimit = require("express-rate-limit");
 
+const userPictureUploadLimiter = rateLimit({
+  windowMs: 15 * 60 * 1000, // 15 minutes
+  max: 50, // limit each IP to 50 picture upload requests per windowMs
+  standardHeaders: true,
+  legacyHeaders: false,
+});
+
 router.post("/", authorizeAndAuthenticate([ROLES.SUPERUSER], [Services.CRON_JOB_HANDLER]), users.markUnverified);
 router.post("/update-in-discord", authenticate, authorizeRoles([SUPERUSER]), users.setInDiscordScript);
 router.post("/verify", authenticate, users.verifyUser);
@@ -69,6 +76,7 @@
 router.post(
   "/picture",
   authenticate,
+  userPictureUploadLimiter,
   upload.single("profile"),
   skipWhenApplicationType(checkIsVerifiedDiscord),
   users.handleUserPictureUpload
EOF
@@ -16,7 +16,15 @@
const { userAuthorization } = require("../middlewares/userAuthorization");
const conditionalMiddleware = require("../middlewares/conditionalMiddleware");
const skipWhenApplicationType = require("../middlewares/pictureRouteMiddleware");
const rateLimit = require("express-rate-limit");

const userPictureUploadLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 50, // limit each IP to 50 picture upload requests per windowMs
standardHeaders: true,
legacyHeaders: false,
});

router.post("/", authorizeAndAuthenticate([ROLES.SUPERUSER], [Services.CRON_JOB_HANDLER]), users.markUnverified);
router.post("/update-in-discord", authenticate, authorizeRoles([SUPERUSER]), users.setInDiscordScript);
router.post("/verify", authenticate, users.verifyUser);
@@ -69,6 +76,7 @@
router.post(
"/picture",
authenticate,
userPictureUploadLimiter,
upload.single("profile"),
skipWhenApplicationType(checkIsVerifiedDiscord),
users.handleUserPictureUpload
package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -42,7 +42,8 @@
     "passport-github2": "0.1.12",
     "passport-google-oauth20": "^2.0.0",
     "rate-limiter-flexible": "5.0.3",
-    "winston": "3.13.0"
+    "winston": "3.13.0",
+    "express-rate-limit": "^8.2.1"
   },
   "devDependencies": {
     "@types/chai": "4.3.16",
EOF
@@ -42,7 +42,8 @@
"passport-github2": "0.1.12",
"passport-google-oauth20": "^2.0.0",
"rate-limiter-flexible": "5.0.3",
"winston": "3.13.0"
"winston": "3.13.0",
"express-rate-limit": "^8.2.1"
},
"devDependencies": {
"@types/chai": "4.3.16",
This fix introduces these dependencies
Package Version Security advisories
express-rate-limit (npm) 8.2.1 None
Copilot is powered by AI and may make mistakes. Always verify output.
@iamitprakash iamitprakash merged commit 696cf34 into develop Feb 21, 2026
3 of 4 checks passed
@iamitprakash iamitprakash deleted the anuj/application-user-image-upload branch February 21, 2026 07:39
@AnujChhikara AnujChhikara mentioned this pull request Feb 21, 2026
10 tasks
iamitprakash added a commit that referenced this pull request Feb 21, 2026
* Merge pull request #2576 from RealDevSquad/2569-refactor-test-for-group-idle

fix: test expectations for idle user

* feat: enhance application scoring and update validation (#2573)

* feat: enhance application scoring and update validation

- Added score handling in nudgeApplication logic to increment score on nudging.
- Updated application creation to set an initial score of 50.
- Enhanced application update validation to include optional fields: firstName, lastName, college, skills, city, state, country, and role.
- Improved integration tests to verify score updates and application modifications.
- Adjusted unit tests to reflect changes in application scoring logic.

* feat: introduce application scoring system and update application queries

* test: refactor application update test for invalid role handling

* refactor: remove firstName and lastName from application update validation and tests

* refactor: rename 'college' to 'institution' in application validation, service, and tests

* feat: implement user picture upload handling for application type (#2564)

---------

Co-authored-by: Vinit khandal <vinit224488@gmail.com>
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.

5 participants