Fix #1: Registration endpoint validates email addresses#2
Fix #1: Registration endpoint validates email addresses#2
Conversation
Wire `validateEmail` into the registration handler so invalid or missing emails are rejected with a 400 response. Guard `app.listen` with `require.main === module` so the server does not auto-start during tests. Add integration tests covering valid registration, missing name, invalid email, and missing email. Update test script glob to include src-root files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
elo-mate
left a comment
There was a problem hiding this comment.
PR Review — Reviewed by PR Review Agent
Verdict: Flag for human review
The code quality is good — no issues found. Flagged solely because this PR touches the registration endpoint (auth flow), which requires human sign-off per review policy.
Checklist
| Category | Status | Notes |
|---|---|---|
| Code Quality | ✅ Pass | Clean, readable, follows existing patterns |
| Standards (CLAUDE.md) | ✅ Pass | CommonJS, input validation via src/utils/, proper HTTP codes, branch/PR naming conventions |
| Security | ✅ Pass | No secrets, no eval, user input validated, no stack traces leaked |
| Testing | ✅ Pass | 4 meaningful integration tests using node:test + node:assert |
| Scope | ✅ Pass | Tightly scoped to issue #1, no unrelated changes |
| CI | No CI checks configured on this branch |
Highlights
validateEmailcorrectly wired into/register— invalid/missing emails now return400require.main === moduleguard is the right pattern for testability- Test helper uses dynamic port (
server.listen(0)) — avoids port conflicts - Test coverage is thorough: valid case + 3 rejection cases
Why flagged
This PR modifies the POST /register endpoint, which is part of the authentication/registration flow. Per policy, changes touching auth require human review before merge — even when the code looks correct.
Human review requested — please give this a once-over and approve if satisfied.
elo-mate
left a comment
There was a problem hiding this comment.
Automated weekly PR security scan — 2026-03-09. No critical/high findings. Two medium and one low finding noted as inline comments below.
| @@ -11,11 +11,14 @@ app.get('/', (req, res) => { | |||
| app.post('/register', (req, res) => { | |||
| const { email, name } = req.body; | |||
|
|
|||
There was a problem hiding this comment.
[Medium] req.body may be undefined causing unhandled 500
If the request arrives without Content-Type: application/json, Express will not populate req.body, leaving it undefined. Destructuring undefined throws a TypeError that bubbles up as a 500.
Suggested fix:
const { email, name } = req.body ?? {};This ensures a safe empty object fallback, and the existing !name / validateEmail checks will then return the correct 400 responses.
| @@ -11,11 +11,14 @@ app.get('/', (req, res) => { | |||
| app.post('/register', (req, res) => { | |||
| const { email, name } = req.body; | |||
|
|
|||
There was a problem hiding this comment.
[Medium] req.body may be undefined, causing an unhandled 500
If a request arrives without Content-Type: application/json, Express will skip body parsing and leave req.body as undefined. Destructuring undefined throws a TypeError that produces an unhandled 500 rather than a clean 400.
Suggested fix:
const { email, name } = req.body ?? {};With the ?? {} fallback, the existing !name and validateEmail(email) checks will both short-circuit correctly and return the expected 400 responses.
| } | ||
|
|
||
| res.status(201).json({ message: 'User registered', email, name }); | ||
| }); |
There was a problem hiding this comment.
[Low] name field is not validated as a string type
!name only checks for falsy values. A JSON body like {"name": []} or {"name": {}} passes the check (arrays and objects are truthy), and the raw value is echoed back in the 201 response, which could cause unexpected behaviour downstream.
Suggested fix:
if (!name || typeof name !== 'string') {
return res.status(400).json({ error: 'Name is required' });
}|
[Low] The pattern This is a low-severity logic issue (not a security bypass) — consider adding a stricter pattern or a well-tested library such as |
Closes #1
Changes
validateEmailinto thePOST /registerhandler so invalid/missing emails return a 400 with"Invalid email address"app.listenwithrequire.main === moduleso the server does not auto-start when the module is required in testssrc/index.test.jswith 4 integration tests covering the registration endpoint (valid, missing name, invalid email, missing email)npm testglob pattern to also pick up test files directly insrc/Testing
npm test— all 6 tests pass (4 new registration tests + 2 existing validateEmail unit tests)