feat: add input validation and filtering to tasks API#2
feat: add input validation and filtering to tasks API#2abhinavguptas wants to merge 1 commit intomainfrom
Conversation
- Validate title (required, max 200 chars) on create and update - Sanitize inputs with trim() before storing - Parse :id as integer with NaN guard on all routes - Add ?completed filter to GET /tasks - Track updatedAt timestamp on PATCH
🩺 Dr. Concret.io — 🔴 Changes RequestedThis pull request significantly improves the robustness of the tasks API by adding comprehensive input validation, sanitization, and filtering capabilities. The changes address several common API vulnerabilities and enhance data integrity. However, there are a couple of critical correctness issues related to type coercion in the PATCH endpoint that need to be addressed before merging. Highlights
Findings (4)
Missing Coding StandardsThis repository has no coding standards files. Consider creating:
🩺 Dr. Concret.io · Model: gemini-2.5-flash · Tokens: 2749 in, 1692 out · Cost: ~$.0138 |
| const task = tasks.find(t => t.id === id); | ||
| if (!task) return res.status(404).json({ error: 'Task not found' }); | ||
| Object.assign(task, req.body); | ||
|
|
There was a problem hiding this comment.
🩺 [HIGH] correctness: Incorrect boolean coercion for 'completed' in PATCH
The Boolean(completed) conversion will incorrectly interpret string values like 'false' as true. If a client sends {"completed": "false"} in the request body, the task will be marked as completed. This can lead to incorrect task states.
Suggestion:
| Explicitly check for string 'true'/'false' if string input is expected, or ensure the input is a proper boolean. For JSON bodies, `req.body.completed` should already be a boolean if sent correctly. |
| if (isNaN(id)) return res.status(400).json({ error: 'Invalid task ID' }); | ||
|
|
||
| const task = tasks.find(t => t.id === id); | ||
| if (!task) return res.status(404).json({ error: 'Task not found' }); |
There was a problem hiding this comment.
🩺 [HIGH] correctness: Incorrect handling of null for 'description' in PATCH
If description is null in the request body, String(description).trim() will convert it to the string literal 'null'. This prevents users from explicitly clearing a task's description.
Suggestion:
| if (!task) return res.status(404).json({ error: 'Task not found' }); | |
| Modify the logic to `task.description = description === null ? null : String(description).trim();` to correctly handle `null` values. |
| if (!task) return res.status(404).json({ error: 'Task not found' }); | ||
| res.json(task); | ||
| }); | ||
|
|
There was a problem hiding this comment.
🩺 [MEDIUM] quality: Missing validation for 'description' field
The description field is not validated for length or type in either POST or PATCH requests. While optional, an excessively long or non-string description could lead to data quality issues or unexpected behavior.
Suggestion:
| Add validation for `description` (e.g., max length) within the `validateTask` function or a similar helper, applying it when `description` is provided. |
Hardens the tasks routes with proper input validation, sanitization, and filtering.
Changes
?completedfilter on GET /tasksupdatedAttimestamp on PATCH