Skip to content

Add task category feature with predefined priority levels#17

Draft
Claude wants to merge 2 commits into
mainfrom
claude/add-task-category-dropdown-again
Draft

Add task category feature with predefined priority levels#17
Claude wants to merge 2 commits into
mainfrom
claude/add-task-category-dropdown-again

Conversation

@Claude

@Claude Claude AI commented Apr 8, 2026

Copy link
Copy Markdown
  • Understand the PR review feedback
  • Add category allowlist validation in backend createTask (return 400 for invalid values, normalize case)
  • Add category allowlist validation in backend updateTask (return 400 for invalid values, normalize case)
  • Fix XSS vulnerability in addTaskToDOM by using DOM methods instead of innerHTML
  • Add aria-label to the category <select> in index.html for accessibility

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a predefined “category/priority” field for tasks (Low/Medium/High) across the backend API and the vanilla JS frontend, including UI controls and styling for category badges.

Changes:

  • Backend: adds category support on task creation (defaulting to Medium) and task updates.
  • Frontend: adds a category <select> in the task form and sends the selected category when creating tasks.
  • UI: adds CSS variables and badge styles to visually distinguish categories in both light/dark themes.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
backend/controllers/tasksController.js Persists category on create and update endpoints.
frontend/index.html Adds a category dropdown to the create-task form.
frontend/script.js Sends category on create and renders a category badge per task.
frontend/style.css Adds theme variables and styles for the category select + category badges.

Comment thread backend/controllers/tasksController.js Outdated
Comment on lines +21 to +22
const { title, completed = false, category = 'Medium' } = req.body;
const newTask = { id: uuidv4(), title, completed, category };

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

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

category is accepted directly from req.body without validation/normalization. Since the UI and frontend rendering assume one of Low|Medium|High, storing arbitrary values can lead to inconsistent data and (because the frontend interpolates task.category into HTML/class attributes) potential XSS. Consider enforcing an allowlist (case-insensitive), defaulting to Medium, and returning 400 for invalid values.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Applied in commit d7112dc. The changes address all four review points:

  • Backend createTask: Added a VALID_CATEGORIES allowlist (['Low', 'Medium', 'High']); category is now normalized (case-insensitive) and returns 400 for any value not in the list.
  • Backend updateTask: Same allowlist validation applied when category is present in the request body.
  • Frontend XSS fix: addTaskToDOM now uses createElement, textContent, classList, and addEventListener instead of innerHTML, eliminating injection risk.
  • Accessibility: Added aria-label="Task priority category" to the <select> element so screen readers announce it properly.

Comment thread backend/controllers/tasksController.js Outdated
Comment on lines +33 to +35
task.title = req.body.title ?? task.title;
task.completed = req.body.completed ?? task.completed;
task.category = req.body.category ?? task.category;

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

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

updateTask allows updating task.category to any arbitrary value from req.body.category with no validation. If categories are meant to be predefined (Low|Medium|High), reject invalid inputs (400) and/or normalize case to avoid persisting unexpected values.

Copilot uses AI. Check for mistakes.
Comment thread frontend/script.js Outdated
Comment on lines 40 to 46
const categoryClass = `category-${task.category ? task.category.toLowerCase() : 'medium'}`;
li.innerHTML = `
<span class="${task.completed ? 'completed' : ''}">${task.title}</span>
<div>
<div class="task-actions">
<span class="category-badge ${categoryClass}">${task.category || 'Medium'}</span>
<button onclick="toggleComplete('${task.id}', ${!task.completed})">✓</button>
<button onclick="deleteTask('${task.id}')">✕</button>

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

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

addTaskToDOM interpolates task.category into both an element’s class attribute and its inner HTML via innerHTML. If a task is created/updated with a malicious category value (backend currently allows arbitrary strings), this can break markup and enable XSS. Prefer building the DOM with textContent/classList and mapping category values to a known set of CSS classes rather than concatenating raw values into HTML.

Copilot uses AI. Check for mistakes.
Comment thread frontend/index.html Outdated
Comment on lines +17 to +21
<select id="categorySelect" title="Select task priority category">
<option value="Low">Low</option>
<option value="Medium" selected>Medium</option>
<option value="High">High</option>
</select>

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

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

The new <select> relies on title for its accessible name, but title is not a reliable label for screen readers. Add an explicit <label for="categorySelect">…</label> or at least an aria-label/aria-labelledby so the control is properly announced.

Copilot uses AI. Check for mistakes.
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.

4 participants