Skip to content

Conversation

@sachin-panayil
Copy link

Issue Queue Pool

Problem

code.gov originally had an issue pool tracker where users can track issues from federal repos that opt in via a specific set of labels.

Solution

This branch tracks the recreation of that tool.

Result

Issue Queue Pool will be back up and running. Below will be a checklist of things that need to be accomplished regarding this task.

Checklist

  • Develop backend scripts
  • Filter by repos that only opt in with code-gov labels
  • Develop frontend to display the data using Dinne's card / filter system

Notes

  • PR is so big because of the addition of the issue-pool.json.
  • We have to get the codegov.json schema correct

Test Plan

Test this locally via web browser and by running scripts using node or GH Actions

Signed-off-by: Sachin Panayil <sachinpanayil01@gmail.com>
return;
}

issuesGrid.innerHTML = filteredIssues.map(createIssueCard).join('');

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 6 months ago

To fix the issue, all dynamic data used in createIssueCard must be sanitized using the escapeHtml function or equivalent contextual escaping. Specifically:

  1. Ensure that typeTags elements are sanitized before being concatenated and injected into the DOM.
  2. Sanitize issue.url before using it in the <a> tag's href attribute.
  3. Replace issuesGrid.innerHTML with safer methods like textContent or appendChild where possible, or ensure all data is sanitized before using innerHTML.
Suggested changeset 1
assets/_common/js/issue-filters.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/assets/_common/js/issue-filters.js b/assets/_common/js/issue-filters.js
--- a/assets/_common/js/issue-filters.js
+++ b/assets/_common/js/issue-filters.js
@@ -170,11 +170,11 @@
       if (issue.isOpen) {
-        typeTags.push('<span class="usa-tag usa-tag--success">Open</span>');
+        typeTags.push(escapeHtml('<span class="usa-tag usa-tag--success">Open</span>'));
       } else {
-        typeTags.push('<span class="usa-tag">Closed</span>');
+        typeTags.push(escapeHtml('<span class="usa-tag">Closed</span>'));
       }
       
-      if (issue.isBug) typeTags.push('<span class="usa-tag usa-tag--error">Bug</span>');
-      if (issue.isFeature) typeTags.push('<span class="usa-tag usa-tag--info">Feature</span>');
-      if (issue.needsHelp) typeTags.push('<span class="usa-tag usa-tag--accent-warm">Help Wanted</span>');
-      if (issue.isBeginner) typeTags.push('<span class="usa-tag usa-tag--accent-cool">Good First Issue</span>');
+      if (issue.isBug) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--error">Bug</span>'));
+      if (issue.isFeature) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--info">Feature</span>'));
+      if (issue.needsHelp) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--accent-warm">Help Wanted</span>'));
+      if (issue.isBeginner) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--accent-cool">Good First Issue</span>'));
   
@@ -184,3 +184,3 @@
             <h3 class="margin-top-0 margin-bottom-1">
-              <a href="${issue.url}" target="_blank" rel="noopener noreferrer" class="usa-link">
+              <a href="${escapeHtml(issue.url)}" target="_blank" rel="noopener noreferrer" class="usa-link">
                 ${escapeHtml(issue.title || 'Untitled Issue')}
@@ -198,3 +198,3 @@
             <div class="font-body-xs text-base-dark">
-              ${issue.commentCount || 0} comments • 
+              ${escapeHtml(issue.commentCount || 0)} comments • 
               Created ${formatDate(issue.createdDate)} • 
EOF
@@ -170,11 +170,11 @@
if (issue.isOpen) {
typeTags.push('<span class="usa-tag usa-tag--success">Open</span>');
typeTags.push(escapeHtml('<span class="usa-tag usa-tag--success">Open</span>'));
} else {
typeTags.push('<span class="usa-tag">Closed</span>');
typeTags.push(escapeHtml('<span class="usa-tag">Closed</span>'));
}

if (issue.isBug) typeTags.push('<span class="usa-tag usa-tag--error">Bug</span>');
if (issue.isFeature) typeTags.push('<span class="usa-tag usa-tag--info">Feature</span>');
if (issue.needsHelp) typeTags.push('<span class="usa-tag usa-tag--accent-warm">Help Wanted</span>');
if (issue.isBeginner) typeTags.push('<span class="usa-tag usa-tag--accent-cool">Good First Issue</span>');
if (issue.isBug) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--error">Bug</span>'));
if (issue.isFeature) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--info">Feature</span>'));
if (issue.needsHelp) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--accent-warm">Help Wanted</span>'));
if (issue.isBeginner) typeTags.push(escapeHtml('<span class="usa-tag usa-tag--accent-cool">Good First Issue</span>'));

@@ -184,3 +184,3 @@
<h3 class="margin-top-0 margin-bottom-1">
<a href="${issue.url}" target="_blank" rel="noopener noreferrer" class="usa-link">
<a href="${escapeHtml(issue.url)}" target="_blank" rel="noopener noreferrer" class="usa-link">
${escapeHtml(issue.title || 'Untitled Issue')}
@@ -198,3 +198,3 @@
<div class="font-body-xs text-base-dark">
${issue.commentCount || 0} comments
${escapeHtml(issue.commentCount || 0)} comments
Created ${formatDate(issue.createdDate)}
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link

@decause-gov decause-gov left a comment

Choose a reason for hiding this comment

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

LGTM +1 🚢

Let's see how it looks!

@sachin-panayil sachin-panayil merged commit 184fca0 into main Jun 25, 2025
6 of 9 checks passed
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.

3 participants