Skip to content

Conversation

@codervivek5
Copy link
Owner

@codervivek5 codervivek5 commented Oct 5, 2025

Fixes Issue

Changes proposed

Screenshots

Note to reviewers

Summary by CodeRabbit

  • New Features

    • Sessions now use database-backed storage for improved reliability across restarts and persist up to one week.
  • Bug Fixes / Improvements

    • Clearer, more specific validation and error messages for signup, login, and OTP flows; OTP verification now confirms and clears codes on success.
  • Chores

    • Added dependency to support DB-backed sessions; added IDE/project metadata and Android build/resource placeholders; minor formatting cleanup.

@vercel
Copy link

vercel bot commented Oct 5, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
vigybag Ready Ready Preview Comment Oct 8, 2025 8:23pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 5, 2025

Walkthrough

Replaces in-memory/previous session storage with MongoDB-backed sessions via connect-mongo in backend/app.js (uses MONGO_URI, collection: 'sessions', cookie maxAge = 1 week). Adds connect-mongo to dependencies. Clarifies several authController messages and splits uniqueness checks. Inserts a blank line in backend/models/Subscriber.js. Several Android IDE and resource files added/modified.

Changes

Cohort / File(s) Summary
Session storage & dependency
backend/app.js, package.json
Configure Express session middleware to use MongoStore.create({ mongoUrl: process.env.MONGO_URI, collection: 'sessions' }); set cookie maxAge to one week. Add connect-mongo@^5.1.0 to dependencies.
Auth controller message/flow tweaks
backend/controllers/authController.js
Refine validation and error messages for signup/login/OTP flows; split uniqueness checks for email and username; ensure early returns on specific validation failures; clear OTP fields on successful verification. No exported signatures changed.
Model formatting
backend/models/Subscriber.js
Inserted a blank line after require statements; no functional changes.
Android IDE config (added)
Android/.idea/.name, Android/.idea/AndroidProjectSystem.xml, Android/.idea/caches/deviceStreaming.xml, Android/.idea/compiler.xml, Android/.idea/migrations.xml, Android/.idea/runConfigurations.xml
Added various Android Studio/IntelliJ project and cache configuration files (device streaming cache, compiler target, migrations, run configurations, project system id, project name).
Android IDE file removed
Android/.idea/modules.xml
Deleted IDE module configuration file.
Android Gradle / properties
Android/app/kotlin/new.properties
Added Gradle JVM args (-Xmx4g -Dfile.encoding=UTF-8) and an extra properties line/comment.
Android resources (fonts / xml)
Android/app/src/main/res/font/inria_sans.xml, Android/app/src/main/res/font/inria_sans_bold.xml, Android/app/src/main/res/xml/data_extraction_rules.xml
Added minimal/empty font resource files and an empty data_extraction_rules.xml PreferenceScreen resource.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Client
  participant Server as Express App
  participant Session as express-session
  participant Mongo as MongoDB (connect-mongo)

  Note right of Session: Session middleware now uses MongoStore (connect-mongo)

  User->>Client: HTTP request
  Client->>Server: Request (cookie may include session ID)
  Server->>Session: middleware checks session
  alt session ID present
    Session->>Mongo: load session by ID
    Mongo-->>Session: session data
  else no/expired session
    Session->>Mongo: create/store session
    Mongo-->>Session: new session record
  end
  Session-->>Server: attach req.session
  Server-->>Client: response (set-session-cookie if created)
  Note over Client: cookie.maxAge = 7 days
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I burrowed deep to stash each trace,
One-week cookies nest in Mongo's place.
Messages polished, checks split in two,
Blank lines hopped in, IDEs anew.
A rabbit winks — commit and chew! 🐇🍪

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description only contains the repository’s template headings without any actual content in the sections, so it does not document which issues are fixed, what changes are proposed, or include any relevant details for reviewers. Please fill out the template by linking any related issue, listing the specific changes made (such as the MongoStore session configuration in app.js), and providing any context or screenshots necessary for thorough review.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately describes the main change of updating app.js for session handling, which matches the modifications in the pull request, although it contains a minor typographical error in “handing.”
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ 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 backend

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
Contributor

@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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3263de2 and 6df301d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • backend/app.js (2 hunks)
  • backend/models/Subscriber.js (1 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/app.js (1)
backend/config/db.js (1)
  • mongoose (5-13)
🔇 Additional comments (4)
backend/models/Subscriber.js (1)

5-5: LGTM!

The blank line improves code readability after the require statements. No functional changes.

backend/app.js (2)

6-6: LGTM!

The MongoStore import is correct and follows the standard CommonJS require pattern.


34-34: LGTM!

Using an environment variable with a fallback for the session secret is a good security practice.

package.json (1)

18-18: No changes needed: connect-mongo@^5.1.0 is the latest stable version and has no reported security advisories.

Comment on lines +38 to +44
store: MongoStore.create({
mongoUrl: process.env.MONGO_URI,
collectionName: 'sessions' // Optional: name of the collection to store sessions
}),
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 7 // Optional: 1 week
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Critical: Environment variable mismatch and missing security configurations.

Several issues identified:

  1. Environment variable inconsistency: Line 39 uses process.env.MONGO_URI, but the related code snippet from backend/config/db.js shows config.mongoURI is used. Verify these are the same variable or if there's a mismatch.

  2. Missing error handling: No error handling if MongoStore.create() fails. This could cause the application to crash silently.

  3. Missing cookie security options: The cookie configuration lacks essential security flags:

    • httpOnly: true - prevents client-side JS access to the cookie
    • secure: true - ensures cookie is only sent over HTTPS (should be conditional on production)
    • sameSite - protects against CSRF attacks
  4. No session TTL: Consider adding a ttl option to control how long sessions persist in MongoDB (independent of cookie expiration).

  5. No store error handlers: MongoDB connection issues won't be caught.

First, verify the environment variable naming:

Apply this diff to add error handling and security options:

     // 2. CONFIGURE THE MONGOSTORE
     store: MongoStore.create({
       mongoUrl: process.env.MONGO_URI,
-      collectionName: 'sessions' // Optional: name of the collection to store sessions
+      collectionName: 'sessions',
+      ttl: 1000 * 60 * 60 * 24 * 7 // Match cookie maxAge (7 days)
     }),
     cookie: {
-      maxAge: 1000 * 60 * 60 * 24 * 7 // Optional: 1 week
+      maxAge: 1000 * 60 * 60 * 24 * 7, // 1 week
+      httpOnly: true, // Prevent XSS attacks
+      secure: process.env.NODE_ENV === 'production', // HTTPS only in production
+      sameSite: 'lax' // CSRF protection
     }
   })
 );
+
+// Handle store errors
+app.use(session({}).store.on('error', (error) => {
+  console.error('Session store error:', error);
+}));

Note: After verifying the environment variable, you may need to adjust line 39 to use the correct variable name (either process.env.MONGO_URI or access it through a config object).


🏁 Script executed:

#!/bin/bash
# Check for MONGO_URI usage across the codebase
echo "=== Searching for MONGO_URI usage ==="
rg -n "MONGO_URI" --type js

echo -e "\n=== Searching for mongoURI usage ==="
rg -n "mongoURI" --type js

echo -e "\n=== Checking backend/config/db.js for config object ==="
cat backend/config/db.js

Length of output: 781


Consolidate session config & enforce security (backend/app.js:38-44)

  • Switch to config.mongoURI (from backend/config/config.js) instead of process.env.MONGO_URI.
  • Attach store.on('error', …) to handle session-store failures.
  • Harden cookies: httpOnly: true, secure: process.env.NODE_ENV==='production', sameSite: 'lax'.
  • Add a ttl in MongoStore.create to match the cookie’s maxAge.
🤖 Prompt for AI Agents
In backend/app.js around lines 38 to 44, the session store and cookie config
need consolidation and hardening: replace process.env.MONGO_URI with
config.mongoURI (import from backend/config/config.js), pass a ttl to
MongoStore.create equal to the cookie maxAge in seconds, capture the returned
store instance and attach store.on('error', err => processLogger.error('Session
store error', err)) to handle store failures, and harden the cookie options by
adding httpOnly: true, secure: process.env.NODE_ENV === 'production', and
sameSite: 'lax' while keeping maxAge as-is.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (2)
Android/.idea/caches/deviceStreaming.xml (1)

1-915: Drop IDE cache from source control

DeviceStreaming.xml is an Android Studio cache file with user/device-specific selections. Keeping it under version control creates noisy diffs and accidental churn, and it is regenerated automatically by the IDE. Please remove it from the repo and add it to the appropriate ignore list.

Android/.idea/runConfigurations.xml (1)

1-17: Exclude user-specific run configuration preferences

This file toggles Android Studio run configuration producers, which is a local IDE preference. Checking it in will override other contributors’ defaults and produces noisy history. Recommend dropping it from the repo and adding it to the ignore list instead.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6df301d and f764bdb.

📒 Files selected for processing (11)
  • Android/.idea/.name (1 hunks)
  • Android/.idea/AndroidProjectSystem.xml (1 hunks)
  • Android/.idea/caches/deviceStreaming.xml (1 hunks)
  • Android/.idea/compiler.xml (1 hunks)
  • Android/.idea/migrations.xml (1 hunks)
  • Android/.idea/modules.xml (0 hunks)
  • Android/.idea/runConfigurations.xml (1 hunks)
  • Android/app/kotlin/new.properties (1 hunks)
  • Android/app/src/main/res/font/inria_sans.xml (1 hunks)
  • Android/app/src/main/res/font/inria_sans_bold.xml (1 hunks)
  • Android/app/src/main/res/xml/data_extraction_rules.xml (1 hunks)
💤 Files with no reviewable changes (1)
  • Android/.idea/modules.xml
✅ Files skipped from review due to trivial changes (8)
  • Android/app/src/main/res/font/inria_sans_bold.xml
  • Android/.idea/.name
  • Android/.idea/AndroidProjectSystem.xml
  • Android/.idea/migrations.xml
  • Android/app/src/main/res/font/inria_sans.xml
  • Android/app/kotlin/new.properties
  • Android/app/src/main/res/xml/data_extraction_rules.xml
  • Android/.idea/compiler.xml

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
backend/controllers/authController.js (1)

82-84: Consider more robust phone validation for international support.

The current validation only accepts exactly 10 unformatted digits, which is restrictive and likely region-specific. This approach:

  • Doesn't support international phone numbers with country codes
  • Doesn't allow common formatting (parentheses, dashes, spaces)
  • May frustrate users who expect to enter their phone numbers in familiar formats

If your application needs to support international users or flexible phone number formats, consider using a library like libphonenumber-js for more robust validation. If the application is specifically for a single region (e.g., India), the current implementation may be acceptable.

Example implementation with libphonenumber-js:

+const { parsePhoneNumber, isValidPhoneNumber } = require('libphonenumber-js');
+
 // ... in signup function ...
-    if (!/^\d{10}$/.test(phone)) {
-      return res.status(400).json({ message: "Phone must be 10 digits." });
+    if (!isValidPhoneNumber(phone, 'IN')) { // 'IN' for India, or omit for international
+      return res.status(400).json({ message: "Invalid phone number." });
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f764bdb and b396728.

📒 Files selected for processing (1)
  • backend/controllers/authController.js (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/controllers/authController.js (1)
src/User/pages/UserAuth/UserAuth.jsx (3)
  • phone (35-35)
  • username (33-33)
  • e (97-144)
🔇 Additional comments (3)
backend/controllers/authController.js (3)

79-93: LGTM! Improved error messages for better UX.

The validation error messages are now more specific and informative, providing clear feedback to users about what went wrong with their input. This improves the user experience without introducing security concerns.


130-130: LGTM! Login error messages follow security best practices.

The updated error messages correctly:

  • Provide clear feedback for missing credentials (line 130)
  • Use generic "Invalid email or password." messages (lines 138, 163) to prevent user enumeration attacks

This approach aligns with security best practices for authentication flows.

Also applies to: 138-138, 163-163


281-281: LGTM! OTP error messages provide good UX with reasonable security.

The updated OTP error messages strike a good balance:

  • Line 281: Generic "Invalid email or OTP." prevents revealing which field is wrong
  • Line 296: Specific "OTP expired." helps users understand they need to request a new OTP
  • Line 301: Clear "Invalid code." provides direct feedback

Also applies to: 296-296, 301-301

Comment on lines +95 to 104
// Check uniqueness separately
const existingUserByEmail = await User.findOne({ email }).lean();
if (existingUserByEmail) {
return res.status(400).json({ message: "Email already exists." });
}

if (existingUserByEmail || existingUserByUsername) {
// Generic message
return res.status(400).json({ message: "Unable to process request." });
const existingUserByUsername = await User.findOne({ username }).lean();
if (existingUserByUsername) {
return res.status(400).json({ message: "Username already exists." });
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

User enumeration vulnerability introduced by split uniqueness checks.

The split uniqueness checks with distinct error messages ("Email already exists." vs "Username already exists.") create a user enumeration vector. An attacker can probe the signup endpoint to discover which emails and usernames are registered in the system.

While this approach improves UX by providing specific feedback, it trades off security. Note that your login and OTP endpoints correctly prevent enumeration with generic messages (lines 138, 212).

If user enumeration is a concern for your application's threat model, consider:

  • Returning a generic message like "Email or username already exists." or
  • Returning a generic "Invalid request." message for all validation failures, or
  • Accepting the trade-off if UX is prioritized over this specific security concern

Apply this diff if you want to prevent user enumeration:

-    // Check uniqueness separately
-    const existingUserByEmail = await User.findOne({ email }).lean();
-    if (existingUserByEmail) {
-      return res.status(400).json({ message: "Email already exists." });
-    }
-
-    const existingUserByUsername = await User.findOne({ username }).lean();
-    if (existingUserByUsername) {
-      return res.status(400).json({ message: "Username already exists." });
+    // Check uniqueness (prevent enumeration with generic message)
+    const existingUserByEmail = await User.findOne({ email }).lean();
+    const existingUserByUsername = await User.findOne({ username }).lean();
+    if (existingUserByEmail || existingUserByUsername) {
+      return res.status(400).json({ message: "Email or username already exists." });
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Check uniqueness separately
const existingUserByEmail = await User.findOne({ email }).lean();
if (existingUserByEmail) {
return res.status(400).json({ message: "Email already exists." });
}
if (existingUserByEmail || existingUserByUsername) {
// Generic message
return res.status(400).json({ message: "Unable to process request." });
const existingUserByUsername = await User.findOne({ username }).lean();
if (existingUserByUsername) {
return res.status(400).json({ message: "Username already exists." });
}
// Check uniqueness (prevent enumeration with generic message)
const existingUserByEmail = await User.findOne({ email }).lean();
const existingUserByUsername = await User.findOne({ username }).lean();
if (existingUserByEmail || existingUserByUsername) {
return res.status(400).json({ message: "Email or username already exists." });
}
🤖 Prompt for AI Agents
In backend/controllers/authController.js around lines 95 to 104, the separate
uniqueness checks leak whether an email or username exists; change the responses
to a single, non-distinct message to prevent user enumeration. Replace the two
distinct 400 responses with one generic 400 response (e.g., "Email or username
already exists." or "Invalid request.") whenever either existingUserByEmail or
existingUserByUsername is true, so callers cannot distinguish which field
triggered the failure.

@codervivek5 codervivek5 merged commit 103e070 into main Oct 8, 2025
3 checks passed
@github-actions
Copy link

github-actions bot commented Oct 8, 2025

Congratulations, Your pull request has been successfully merged 🥳🎉 Thank you for your valuable contribution to the project 🚀 Keep contributing!! ✨

📢 Don’t forget to share your VigyBag PR on LinkedIn and tag @VigyBag and me — we’d love to celebrate your achievement with you! 🔗💡

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