Skip to content

feat: add applicant image upload functionality#2564

Open
AnujChhikara wants to merge 4 commits intodevelopfrom
anuj/application-user-image-upload
Open

feat: add applicant image upload functionality#2564
AnujChhikara wants to merge 4 commits 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

  • Added new endpoint for the image upload for the applicants

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-03.at.1.50.48.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

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, describing the addition of a new endpoint for image upload for applicants, which is reflected across all modified files.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 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.

);
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 about 20 hours ago

In general, to fix this problem you introduce a rate-limiting middleware so that expensive or security-sensitive endpoints cannot be called arbitrarily often. In an Express app, this is typically done with a library such as express-rate-limit, configuring a reasonable window and maximum number of requests, and then inserting that middleware either globally or on specific routes.

The best fix here, without changing existing functionality, is to add express-rate-limit in this router file and apply a limiter specifically to the /picture POST route (and optionally other modifying endpoints if desired). This keeps the existing authentication, validation, upload, and controller behavior intact, but ensures that a single client cannot flood the server with repeated picture uploads. Concretely: in routes/applications.ts, add a require("express-rate-limit") at the top, define a limiter instance (e.g., const pictureRateLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }); or a stricter value suitable for file uploads), and then insert pictureRateLimiter as a middleware in the router.post("/picture", ...) chain immediately after the path and before authenticate. No other routes or behavior need to be changed.

Suggested changeset 2
routes/applications.ts

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/applications.ts b/routes/applications.ts
--- a/routes/applications.ts
+++ b/routes/applications.ts
@@ -1,4 +1,5 @@
 const express = require("express");
+const rateLimit = require("express-rate-limit");
 const { SUPERUSER } = require("../constants/roles");
 const authenticate = require("../middlewares/authenticate");
 const authorizeRoles = require("../middlewares/authorizeRoles");
@@ -9,6 +10,11 @@
 
 const router = express.Router();
 
+const pictureRateLimiter = rateLimit({
+  windowMs: 15 * 60 * 1000, // 15 minutes
+  max: 100, // limit each IP to 100 picture upload requests per windowMs
+});
+
 router.get(
   "/",
   authenticate,
@@ -18,6 +24,7 @@
 );
 router.post(
   "/picture",
+  pictureRateLimiter,
   authenticate,
   upload.single("profile"),
   applicationValidator.validateApplicationPicture,
EOF
@@ -1,4 +1,5 @@
const express = require("express");
const rateLimit = require("express-rate-limit");
const { SUPERUSER } = require("../constants/roles");
const authenticate = require("../middlewares/authenticate");
const authorizeRoles = require("../middlewares/authorizeRoles");
@@ -9,6 +10,11 @@

const router = express.Router();

const pictureRateLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 picture upload requests per windowMs
});

router.get(
"/",
authenticate,
@@ -18,6 +24,7 @@
);
router.post(
"/picture",
pictureRateLimiter,
authenticate,
upload.single("profile"),
applicationValidator.validateApplicationPicture,
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.
@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
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