fix(auth): prevent concurrent signup race conditions and lost updates - #552
fix(auth): prevent concurrent signup race conditions and lost updates#552Namraa310806 wants to merge 3 commits into
Conversation
|
@Namraa310806 is attempting to deploy a commit to the firefistisdead's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR adds ChangesConcurrent-safe signup with file locking
Sequence Diagram(s)sequenceDiagram
participant Client
participant signup
participant lockfile
participant users.json
Client->>signup: POST /api/auth/signup
signup->>signup: validate email and password
signup->>lockfile: lock users.json
lockfile-->>signup: release function
signup->>users.json: read current users
alt email already exists
signup->>lockfile: release()
signup-->>Client: 400 User already exists
else new user
signup->>users.json: write updated users via temp file
signup->>lockfile: release()
signup-->>Client: 201 + token
end
alt error
signup->>lockfile: release() in catch
signup-->>Client: 500 Server error
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/controllers/authController.js (1)
2-2: ⚡ Quick winRemove unused symbols flagged by CI (
fsPromises,saveUsers).Line 2 and Lines 22-24 are now dead after the locked helper migration, and they keep lint warnings active.
Proposed cleanup
-const fsPromises = require("fs/promises"); @@ -const saveUsers = (users) => { - fs.writeFileSync(usersFile, JSON.stringify(users, null, 2)); -};Also applies to: 22-24
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/controllers/authController.js` at line 2, Remove the unused fsPromises import statement from line 2 and delete the saveUsers function definition from lines 22-24. These symbols became dead code after the locked helper migration and are causing lint warnings. Ensure no other code references these symbols before deletion.Sources: Linters/SAST tools, Pipeline failures
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server.test.js`:
- Around line 988-1014: The test "POST /api/auth/signup - concurrent
registrations prevent lost updates" currently only verifies HTTP response status
codes and token presence, but does not verify that all three users were actually
persisted in the database. A lost-update bug could still pass this test by
returning 201 for all concurrent requests while failing to store some users.
After the Promise.all(promises) completes and you verify the successCount, add
post-signup verification by attempting to login each of the three users with
their respective email and password credentials. Verify that each login attempt
succeeds to confirm all three accounts were actually persisted, ensuring the
test truly catches lost-update bugs rather than just checking surface-level
response codes.
- Around line 946-1050: The signup tests (POST /api/auth/signup - single user
registration succeeds, POST /api/auth/signup - duplicate email is rejected, POST
/api/auth/signup - concurrent registrations prevent lost updates, POST
/api/auth/signup - validates password strength, POST /api/auth/signup - rejects
missing email or password) are writing directly to the real src/data/users.json
file and not cleaning up afterward, causing state to persist across test runs.
To fix this, implement test isolation by either mocking the user data store with
an in-memory implementation specific to each test, using a temporary test
fixture that gets restored after each test, or implementing setup/teardown hooks
to clear or reset the users.json file before and after each test runs. Ensure
that each test operates on isolated state that does not affect subsequent test
runs or the committed repository state.
In `@src/controllers/authController.js`:
- Around line 43-45: The empty catch block at line 45 that follows the
fs.unlinkSync(tempFile) call is violating the ESLint no-empty rule and is hiding
potential cleanup failures. Replace the empty catch block with proper error
handling by either logging the error that occurred during the file deletion
attempt (using a logger at an appropriate level like warn or debug since this is
cleanup code) or adding an explanatory comment if the error is intentionally
ignored. This will satisfy the linter and provide visibility into cleanup
failures for debugging purposes.
---
Nitpick comments:
In `@src/controllers/authController.js`:
- Line 2: Remove the unused fsPromises import statement from line 2 and delete
the saveUsers function definition from lines 22-24. These symbols became dead
code after the locked helper migration and are causing lint warnings. Ensure no
other code references these symbols before deletion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 6cadb328-991e-440d-a208-fe9e282f4a8e
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (4)
package.jsonserver.test.jssrc/controllers/authController.jssrc/data/users.json
|
@FireFistisDead ready to merge without merge conflicts |
Summary
This PR fixes a race condition in the user registration flow that could cause lost updates and inconsistent user data during concurrent signup requests.
Previously, the authentication system used a read-modify-write pattern on
users.jsonwithout synchronization. Multiple simultaneous registration requests could read the same file state, perform independent modifications, and overwrite each other's changes when writing back to disk.This update introduces file locking, atomic writes, and concurrency-safe registration handling to ensure reliable user persistence under concurrent workloads.
Changes Made
Concurrency-Safe User Registration
proper-lockfile.users.jsonat a time.Duplicate User Validation Under Lock
Moved duplicate-email validation inside the protected critical section.
This ensures:
Atomic File Writes
Implemented atomic write operations using:
Benefits:
Lock Cleanup & Error Handling
Added safe lock release logic for:
This prevents stale locks and improves recovery behavior.
Regression Test Coverage
Added concurrent registration tests covering:
Reliability Impact
This change improves:
The application can now safely process concurrent signup requests without risking lost registrations or corrupted user data.
Security Impact
This change reduces the risk of:
Files Modified
Verification Checklist
Related Issue
Fixes #503
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests
POST /api/auth/signup, including success, duplicate rejection, password strength checks, missing fields, and concurrent signups.Chores