Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
864ddfd
Removed Netlify-cms from dependencies
PrashantKF May 8, 2025
e42eaf9
update contact info on multiple pages
arnayv-47 May 9, 2025
be4d1a4
readd contact to dsfs and cdac
arnayv-47 May 12, 2025
de895cc
update contact
arnayv-47 May 12, 2025
6ff2917
update contact
arnayv-47 May 14, 2025
4bde335
add new data quality framework resource
arnayv-47 May 21, 2025
f6a6e04
change question evaluation and data collection order
arnayv-47 May 21, 2025
3c9d49c
For inline search
kkmoghe-gsa May 25, 2025
15c6b5b
For inline false, to check if pagination is happening
kkmoghe-gsa May 25, 2025
bf5ea1a
For inline true search
kkmoghe-gsa May 28, 2025
42414e9
For pagination of fcsm site, inline
kkmoghe-gsa May 28, 2025
c1adafb
For search changes
kkmoghe-gsa May 30, 2025
1b8e26b
For search
kkmoghe-gsa May 30, 2025
ffaf57f
For search page
kkmoghe-gsa May 30, 2025
bd71d90
For search
kkmoghe-gsa May 30, 2025
3430411
For search.js
kkmoghe-gsa May 30, 2025
64c5dfa
For search.js
kkmoghe-gsa May 30, 2025
cd136d7
script.js ref. is commented in meta.html
kkmoghe-gsa May 30, 2025
810dd16
For index.html
kkmoghe-gsa May 30, 2025
2513c87
For reverting back changes to original one
kkmoghe-gsa May 31, 2025
ac99e99
For commenting search
kkmoghe-gsa May 31, 2025
f6d4594
For search index
kkmoghe-gsa May 31, 2025
8dbd1ec
For index html
kkmoghe-gsa May 31, 2025
45a3dcf
For default search
kkmoghe-gsa May 31, 2025
07ab870
For whole search pages
kkmoghe-gsa May 31, 2025
320b076
For step by step changes
kkmoghe-gsa May 31, 2025
6a85cc5
For index.html, a few more additions
kkmoghe-gsa May 31, 2025
f834969
For index.html, a few more additions 2
kkmoghe-gsa May 31, 2025
5f1e228
For index.html, a few more additions 2
kkmoghe-gsa May 31, 2025
32331b5
For index.html, a few more additions 3
kkmoghe-gsa May 31, 2025
c07c35e
For index.html, a few more additions 4
kkmoghe-gsa May 31, 2025
ab24f1a
For index.html, a few more additions 5
kkmoghe-gsa May 31, 2025
30c513c
For index.html, a few more additions 6
kkmoghe-gsa May 31, 2025
7f5a358
For index.html, a few more additions 7
kkmoghe-gsa May 31, 2025
41f4005
For index.html, searchresults null cond check
kkmoghe-gsa May 31, 2025
b0ba36a
For index.html, searchresults setAttr
kkmoghe-gsa May 31, 2025
739e0a8
For index.html, searchresults setAttr
kkmoghe-gsa May 31, 2025
58d8849
For index.html, searchresults setAttr
kkmoghe-gsa May 31, 2025
66f7f53
For index.html, footer note
kkmoghe-gsa May 31, 2025
fc5d781
For index.html, footer note
kkmoghe-gsa May 31, 2025
141aab0
For index.html, end result notes
kkmoghe-gsa May 31, 2025
153d6fc
For index.html, footer note2
kkmoghe-gsa May 31, 2025
4618d2c
For index.html, footer note3
kkmoghe-gsa Jun 1, 2025
973cfda
For index.html, footer note4
kkmoghe-gsa Jun 1, 2025
5e28206
For css changes
kkmoghe-gsa Jun 2, 2025
410f61f
For assets styles
kkmoghe-gsa Jun 2, 2025
49950fe
For styles to be included
kkmoghe-gsa Jun 3, 2025
881fb5d
For renaming
kkmoghe-gsa Jun 3, 2025
5cb563f
For style to make inline
kkmoghe-gsa Jun 3, 2025
70c914a
For removing console stmts
kkmoghe-gsa Jun 3, 2025
562b46e
For style to be commited
kkmoghe-gsa Jun 5, 2025
c772694
For styles include
kkmoghe-gsa Jun 5, 2025
213799f
For styles
kkmoghe-gsa Jun 5, 2025
0563970
For search.js
kkmoghe-gsa Jun 5, 2025
90fa0fb
For search.js
kkmoghe-gsa Jun 5, 2025
05f134a
For searchgov params
kkmoghe-gsa Jun 5, 2025
f7c3023
For search.js
kkmoghe-gsa Jun 5, 2025
e4b8a5d
For gpgkey
kkmoghe-gsa Jun 11, 2025
e1e088d
Merge branch 'staging' into feature/OGPWEB-17405
kkmoghe-gsa Jun 14, 2025
ec1fe60
Merge pull request #296 from GSA/feature/OGPWEB-17405
PrashantKF Jun 16, 2025
36a79b2
Revert "Ritm1344510"
arnayv-47 Jun 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ searchgov:

# This renders the results within the page instead of sending to user to search.gov.
inline: true
#inline: false

# This allows Search.gov to present relevant type-ahead search suggestions in your website's search box.
# If you do not want to present search suggestions, set this value to false.
Expand Down
2 changes: 1 addition & 1 deletion _includes/meta.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@
<!-- CSS
================================================== -->
<link type="text/css" href="{{site.baseurl}}/assets/css/styles.css" rel="stylesheet" />
</head>
</head>
1 change: 1 addition & 0 deletions _includes/scripts.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</script>
{% endif %}

<script src="https://code.jquery.com/jquery-3.6.0.min.js" type="text/javascript"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.
<script src="{{ site.baseurl }}/assets/js/app.js"></script>
<script src="{{ site.baseurl }}/assets/js/carousel.js"></script>
<script src="{{site.baseurl}}/assets/js/uswds.min.js"></script>
Expand Down
28 changes: 28 additions & 0 deletions assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,35 @@ C:/Program Files/Adobe/Adobe Dreamweaver 2021/ruby/lib/ruby/gems/2.7.0/gems/sass
C:/Program Files/Adobe/Adobe Dreamweaver 2021/ruby/bin/sass:23:in `load'
C:/Program Files/Adobe/Adobe Dreamweaver 2021/ruby/bin/sass:23:in `<main>'
*/

body:before {
white-space: pre;
font-family: monospace;
content: "Error: Invalid CSS after \" }\": expected selector or at-rule, was \"}\"\A on line 4446 of M:\icsp\fcsm\assets\css\style.scss\A \A 4441: height: 100%;\A 4442: z-index: -1;\A 4443: \A 4444: };\A 4445: }\A 4446: }\A 4447: .page-title-content {\A 4448: text-align: center;\A 4449: \A 4450: h2 {\A 4451: color: $white-color;"; }

.pager-button {
display: inline-block;
padding: 8px 12px;
margin: 6px;
border: 2px solid #0004ff; /* blue border color */
border-radius: 4px; /* rounded rectangle */
background-color: transparent; /* no background color */
color: #0004ff; /* blue text color */
text-decoration: none;
cursor: pointer;
}

.pager-button-current {
display: inline-block;
padding: 8px 12px;
margin: 6px;
border: 2px solid #350111; /* blue border color */
border-radius: 4px; /* rounded rectangle */
background-color: transparent; /* no background color */
color: #000000; /* blue text color */
text-decoration: none;
cursor: initial;
}
.pager-button:hover {
background-color: #e2e6ea; /* light gray background color on hover */
}
29 changes: 29 additions & 0 deletions assets/css/styles-2.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

.pager-button {
display: inline-block;
padding: 8px 12px;
margin: 6px;
border: 2px solid #0004ff; /* blue border color */
border-radius: 4px; /* rounded rectangle */
background-color: transparent; /* no background color */
color: #0004ff; /* blue text color */
text-decoration: none;
cursor: pointer;
}

.pager-button-current {
display: inline-block;
padding: 8px 12px;
margin: 6px;
border: 2px solid #350111; /* blue border color */
border-radius: 4px; /* rounded rectangle */
background-color: transparent; /* no background color */
color: #000000; /* blue text color */
text-decoration: none;
cursor: initial;
}
.pager-button:hover {
background-color: #e2e6ea; /* light gray background color on hover */
}


152 changes: 152 additions & 0 deletions assets/js/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
var urlParams = new URLSearchParams(window.location.search);
var page = urlParams.get("page") ?? 1;
var resultsPerPage = 20;
var offset = (page - 1) * resultsPerPage;
var totalResults = 0;

// var searchEndpoint = new URL("{{site.searchgov.endpoint}}/api/v2/search/i14y");
// params = { affiliate: "{{site.searchgov.affiliate}}",
// access_key: "{{site.searchgov.access_key}}",
// query: urlParams.get('query') ,
// offset: offset
// }

var searchgovParams = document.getElementById("searchgov-params");
console.log("searchgovParams is : " + searchgovParams);
var currentURL = new URL(window.location.href);
var searchEndpoint = new URL(
searchgovParams.dataset.endpoint + "/api/v2/search/i14y"
);

params = {
affiliate: searchgovParams.dataset.affiliate,
access_key: searchgovParams.dataset.accessKey,
query: urlParams.get("query"),
offset: offset
};
searchResults.setAttribute("start", offset + 1);

var inputElement = document.getElementById("extended-search-field-small");
inputElement.value = urlParams.get("query");
inputElement.focus();



Object.keys(params).forEach(key => searchEndpoint.searchParams.append(key, params[key]));


fetch(searchEndpoint).then(function(res) {
return res.json()
}).then(function(posts) {
totalResults = posts.web.total;
//console.log("Total results are : " + totalResults);

document.getElementById('search-params').innerHTML = encodeHTML(urlParams.get('query'));
document.getElementById("search-keyword").innerHTML = urlParams.get("query");

Check failure

Code scanning / CodeQL

Client-side cross-site scripting High

Cross-site scripting vulnerability due to
user-provided value
.

Copilot Autofix

AI 5 months ago

To fix the issue, the user-provided value from urlParams.get("query") must be sanitized or encoded before being assigned to innerHTML. The best approach is to use a contextual output encoding function, such as encodeHTML, to ensure that any potentially malicious characters are escaped. This prevents the execution of scripts embedded in the query parameter.

Steps to fix:

  1. Apply the encodeHTML function to sanitize the urlParams.get("query") value before assigning it to innerHTML on line 45.
  2. Ensure that the encodeHTML function is defined and properly escapes HTML special characters.

Suggested changeset 1
assets/js/search.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/js/search.js b/assets/js/search.js
--- a/assets/js/search.js
+++ b/assets/js/search.js
@@ -44,3 +44,3 @@
     document.getElementById('search-params').innerHTML = encodeHTML(urlParams.get('query'));
-    document.getElementById("search-keyword").innerHTML = urlParams.get("query");
+    document.getElementById("search-keyword").innerHTML = encodeHTML(urlParams.get("query"));
     document.getElementById("results-count").innerHTML = totalResults;
EOF
@@ -44,3 +44,3 @@
document.getElementById('search-params').innerHTML = encodeHTML(urlParams.get('query'));
document.getElementById("search-keyword").innerHTML = urlParams.get("query");
document.getElementById("search-keyword").innerHTML = encodeHTML(urlParams.get("query"));
document.getElementById("results-count").innerHTML = totalResults;
Copilot is powered by AI and may make mistakes. Always verify output.
document.getElementById("results-count").innerHTML = totalResults;

if (posts.web.results.length > 0) {
var searchResults = document.getElementById("search-results");
if (searchResults != null){
//console.log("searchResults are not null and offset is : " + offset);

searchResults.setAttribute("start", offset + 1);
}else{
console.log("searchResults are null.");
}
document.getElementById('search-results').classList.remove('display-none');
document.getElementById('no-results').classList.add('display-none');
for (item in posts.web.results){
render_result(`
<li class="padding-bottom-5 margin-top-4 usa-prose border-bottom-05 border-base-lightest">
<b class="title">
<a href="${posts.web.results[item]['url']}">
${posts.web.results[item]['title']
.replace(/\uE000/g, '<span class="bg-yellow">')
.replace(/\uE001/g, '</span>')}</a>
</b>
<div> ${posts.web.results[item]['snippet'].replace(/\uE000/g, '<span class="bg-yellow">').replace(/\uE001/g, '</span>')} </div>
</li>
`, true)

}
}
}).catch(function(ex) {
console.log('parsing failed', ex);
}).finally(function(e){

if(document.getElementById('search-results').childNodes.length == 0){
document.getElementById('search-results').classList.add('display-none');
document.getElementById('no-results').classList.remove('display-none');
document.getElementById("results-header").classList.add("display-none");
document.getElementById("pager").classList.add("display-none");
}
document.getElementById("results-header").classList.remove("display-none");
update_pager();

})


function render_result(content, append = true){
const previous = document.getElementById('search-results').innerHTML;
document.getElementById('search-results').innerHTML = (append == true) ? previous + content : content;
}

function update_pager() {
var page = urlParams.get("page") ?? 1;
var pager = document.getElementById("pager");
var pagerLinks = "";
var totalPages = Math.ceil(totalResults / resultsPerPage);

pager.innerHTML = "";

if (page > 1){
pagerLinks += '<a href="' + getLinkToPage(1) + '" aria-label="First page" class="pager-button">First</a>';
}

if (totalPages > 5 && page > 5) {
pagerLinks += '<span style="font-weight: bold;" class="margin-2">...</span>';
}

var start = Math.max(2, page - 3);
for (var i = start; i < page; i++) {
pagerLinks += '<a href="' + getLinkToPage(i) + '" aria-label="Page ' + i + '" class="pager-button">' + i + '</a>';
}

pagerLinks += '<span class="margin-2, pager-button-current">Page ' + page + " of " + totalPages + "</span>";

var end = Math.min((totalPages - 1), ((1*page) + 3));
for (var j = (1*page) + 1; j <= end; j++) {
pagerLinks += '<a href="' + getLinkToPage(j) + '" aria-label="Page ' + j + '" class="pager-button">' + j + '</a>';
}

if (totalPages > 5 && page < totalPages - 4) {
pagerLinks += '<span style="font-weight: bold;" class="margin-2">...</span>';
}

if( totalPages > 1 && page < totalPages){
pagerLinks += '<a href="' + getLinkToPage(totalPages) + '" aria-label="Last page" class="pager-button">Last</a>';
}

pagerLinks += '<div class="usa-footer__contact-info grid-row grid-gap"><div class="grid-col-auto"><p class="margin-top-0">Powered by <strong>Search.gov</strong></p></div></div>';

pager.innerHTML = pagerLinks;

Check failure

Code scanning / CodeQL

Client-side cross-site scripting High

Cross-site scripting vulnerability due to
user-provided value
.

Copilot Autofix

AI 5 months ago

To fix the issue, we need to ensure that any user-controlled input is properly sanitized or encoded before being inserted into the DOM. The best approach here is to use the encodeHTML function (already defined in the code) to escape special characters in the page parameter and any other user-controlled data before concatenating it into pagerLinks. This will prevent malicious scripts from being executed.

Specifically:

  1. Use encodeHTML to sanitize the page parameter and any other user-controlled values before they are added to pagerLinks.
  2. Replace all instances where page or other user-controlled data is directly concatenated into HTML strings with their sanitized versions.

Suggested changeset 1
assets/js/search.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/js/search.js b/assets/js/search.js
--- a/assets/js/search.js
+++ b/assets/js/search.js
@@ -103,3 +103,3 @@
       if (page > 1){
-          pagerLinks += '<a href="' + getLinkToPage(1) + '" aria-label="First page" class="pager-button">First</a>';
+          pagerLinks += '<a href="' + encodeHTML(getLinkToPage(1)) + '" aria-label="First page" class="pager-button">First</a>';
       }
@@ -112,6 +112,6 @@
       for (var i = start; i < page; i++) {
-          pagerLinks += '<a href="' + getLinkToPage(i) + '" aria-label="Page ' + i + '" class="pager-button">' + i + '</a>';
+          pagerLinks += '<a href="' + encodeHTML(getLinkToPage(i)) + '" aria-label="Page ' + encodeHTML(i.toString()) + '" class="pager-button">' + encodeHTML(i.toString()) + '</a>';
       }
 
-      pagerLinks += '<span class="margin-2, pager-button-current">Page ' + page + " of " + totalPages + "</span>";
+      pagerLinks += '<span class="margin-2, pager-button-current">Page ' + encodeHTML(page.toString()) + " of " + encodeHTML(totalPages.toString()) + "</span>";
       
@@ -119,3 +119,3 @@
       for (var j = (1*page) + 1; j <= end; j++) {
-          pagerLinks += '<a href="' + getLinkToPage(j) + '" aria-label="Page ' + j + '" class="pager-button">' + j + '</a>';
+          pagerLinks += '<a href="' + encodeHTML(getLinkToPage(j)) + '" aria-label="Page ' + encodeHTML(j.toString()) + '" class="pager-button">' + encodeHTML(j.toString()) + '</a>';
       }
@@ -127,3 +127,3 @@
       if( totalPages > 1 && page < totalPages){
-          pagerLinks += '<a href="' + getLinkToPage(totalPages) + '" aria-label="Last page" class="pager-button">Last</a>';
+          pagerLinks += '<a href="' + encodeHTML(getLinkToPage(totalPages)) + '" aria-label="Last page" class="pager-button">Last</a>';
       }		
EOF
@@ -103,3 +103,3 @@
if (page > 1){
pagerLinks += '<a href="' + getLinkToPage(1) + '" aria-label="First page" class="pager-button">First</a>';
pagerLinks += '<a href="' + encodeHTML(getLinkToPage(1)) + '" aria-label="First page" class="pager-button">First</a>';
}
@@ -112,6 +112,6 @@
for (var i = start; i < page; i++) {
pagerLinks += '<a href="' + getLinkToPage(i) + '" aria-label="Page ' + i + '" class="pager-button">' + i + '</a>';
pagerLinks += '<a href="' + encodeHTML(getLinkToPage(i)) + '" aria-label="Page ' + encodeHTML(i.toString()) + '" class="pager-button">' + encodeHTML(i.toString()) + '</a>';
}

pagerLinks += '<span class="margin-2, pager-button-current">Page ' + page + " of " + totalPages + "</span>";
pagerLinks += '<span class="margin-2, pager-button-current">Page ' + encodeHTML(page.toString()) + " of " + encodeHTML(totalPages.toString()) + "</span>";

@@ -119,3 +119,3 @@
for (var j = (1*page) + 1; j <= end; j++) {
pagerLinks += '<a href="' + getLinkToPage(j) + '" aria-label="Page ' + j + '" class="pager-button">' + j + '</a>';
pagerLinks += '<a href="' + encodeHTML(getLinkToPage(j)) + '" aria-label="Page ' + encodeHTML(j.toString()) + '" class="pager-button">' + encodeHTML(j.toString()) + '</a>';
}
@@ -127,3 +127,3 @@
if( totalPages > 1 && page < totalPages){
pagerLinks += '<a href="' + getLinkToPage(totalPages) + '" aria-label="Last page" class="pager-button">Last</a>';
pagerLinks += '<a href="' + encodeHTML(getLinkToPage(totalPages)) + '" aria-label="Last page" class="pager-button">Last</a>';
}
Copilot is powered by AI and may make mistakes. Always verify output.
}

function getLinkToPage(pageNumber) {
var searchParams = currentURL.searchParams;
if (searchParams.has("page")) {
searchParams.set("page", pageNumber);
} else {
searchParams.append("page", pageNumber);
}
return currentURL.toString();
}

function encodeHTML(str) {
return str.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
Loading
Loading