Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
62035d5
Create README.md
Zachary-Squires Aug 21, 2025
794d464
Create thing-in-docs-folder
Zachary-Squires Aug 21, 2025
4ea1a46
add a file for team meeting schedule
Andrew-Bonner Aug 26, 2025
aca1a74
Update thing-in-docs-folder
Zachary-Squires Aug 26, 2025
2627f0e
Merge branch 'main' of https://github.com/CS495-Fall2025/Team-5
Zachary-Squires Aug 26, 2025
23bca3d
Adding the commit from 1488 called "fix: resolved PR feedback on sani…
Landon-Wivell Jul 7, 2025
bacc35d
feat(security): centralize DOMPurify sanitizer and patch XSS in succe…
Landon-Wivell May 8, 2025
979c3de
Added the commit from 1488 called "feat(security): centralize DOMPuri…
Zachary-Squires Sep 30, 2025
7cfcb79
fix: resolved PR feedback on sanitizer imports and tests
Landon-Wivell Jul 7, 2025
e642e0e
Ran npm install, should bring jsdom and dompurify
Zachary-Squires Sep 30, 2025
7cb2438
Restore executable permissions on scripts and binaries
Zachary-Squires Oct 7, 2025
2ceee19
Merge pull request #1 from Andrew-Bonner/team_b
Zachary-Squires Oct 7, 2025
c24d3c4
Normalize all line endings to LF
Zachary-Squires Oct 7, 2025
f38a83e
Merge pull request #2 from Andrew-Bonner/team_b
Zachary-Squires Oct 7, 2025
ad31fd0
Change to not allow default postgres or secret token in OED production.
Zachary-Squires Nov 4, 2025
2ba98fc
Merge branch 'OpenEnergyDashboard:development' into team_b
Zachary-Squires Nov 4, 2025
f5d6ce0
Merge branch 'team_b' of https://github.com/Andrew-Bonner/OED into te…
Zachary-Squires Nov 4, 2025
489cc17
Merge pull request #3 from Andrew-Bonner/team_b
Zachary-Squires Nov 4, 2025
3c3b6cc
Fix PR suggestions
Zach-O-Bates Nov 5, 2025
6eb6d29
Revert "Merge pull request #3 from Andrew-Bonner/team_b"
Zachary-Squires Nov 5, 2025
7611ae5
Merge branch 'team_b' into development
Zach-O-Bates Nov 5, 2025
040f138
Simplify test to better align with mentor suggestions
Zach-O-Bates Nov 11, 2025
da2dd00
Update .gitattributes
Zachary-Squires Nov 12, 2025
5a40623
Update docker-compose.yml
Zachary-Squires Nov 12, 2025
9acd4b6
Update jsdom package
Zach-O-Bates Nov 12, 2025
c03723a
Addressing Suggestions for PR 1544
Zachary-Squires Nov 20, 2025
533c588
Mark cron scripts as executable
Zachary-Squires Nov 20, 2025
df29aaa
Mark docker-compose.yml as executable
Zachary-Squires Nov 20, 2025
80382e2
Update docker-compose.yml
Zachary-Squires Nov 20, 2025
fea6028
try to resolve some blank line change issues
huss Nov 24, 2025
2ba9168
Merge remote-tracking branch 'origin/development' into pr/Zachary-Squ…
huss Nov 24, 2025
6ca696c
revert dompurify & jsdom versions
huss Dec 1, 2025
29be1dc
fix so check header ignores new CSV file
huss Dec 1, 2025
e48479f
Add meeting times to team_schedule
Zach-O-Bates Dec 2, 2025
e49ef60
Add final presentation date to team schedule
Zach-O-Bates Dec 2, 2025
a4d4e02
Enhance README with project details and contributors
Zach-O-Bates Dec 2, 2025
139a958
Adjust file structure according to the Github folder document
Zach-O-Bates Dec 2, 2025
92f084b
Delete .DS_Store
Zach-O-Bates Dec 2, 2025
c365ac0
Create the team and client folders for meeting notes
Zach-O-Bates Dec 3, 2025
1978591
Merge branch 'main' of https://github.com/CS495-Fall2025/Team-5
Zach-O-Bates Dec 3, 2025
33adcec
Summarize and organize first client meeting notes
Zach-O-Bates Dec 3, 2025
9751b9f
Add notes from client meeting on September 17, 2025
Zach-O-Bates Dec 4, 2025
f04df81
Rename 9-17-2025-ClientMeeting to 9-17-2025-ClientMeeting.md
Zach-O-Bates Dec 4, 2025
f6d65e3
Rename client meeting document for consistency
Zach-O-Bates Dec 4, 2025
3a8d079
Add notes from the client meeting on September 22, 2025
Zach-O-Bates Dec 4, 2025
37b746d
Update and rename team_schedule to team_schedule.md
Zach-O-Bates Dec 4, 2025
1eb48d5
Fix typo in presentation date heading
Zach-O-Bates Dec 4, 2025
80c2ec2
Add meeting notes for client meeting on 10-01-2025
Zach-O-Bates Dec 4, 2025
baf5dc7
Removed meeting 10-01 from a mistakenly created folder
Zach-O-Bates Dec 4, 2025
c2d1d73
Add client meeting notes for October 8, 2025
Zach-O-Bates Dec 4, 2025
1d8fabe
Add notes for October 15, 2025 Client Meeting
Zach-O-Bates Dec 4, 2025
e9f7466
Adjust folder structure in client meetings
Zach-O-Bates Dec 8, 2025
61c4b30
Added test for the second route in crossSite.js
Zach-O-Bates Dec 9, 2025
ee55196
updated the expected to be a status code 401
Andrew-Bonner Dec 9, 2025
bd0068a
Add files via upload
Andrew-Bonner Dec 11, 2025
7a6554c
Create 10-22-2025-ClientMeeting.md
Andrew-Bonner Dec 11, 2025
cf32365
Create 10-29-2025-ClientMeeting.md
Zach-O-Bates Dec 11, 2025
2b0c4f5
Create 11-5-2025-ClientMeeting.md
Zach-O-Bates Dec 11, 2025
767e1cf
Create 11-12-2025-ClientMeeting.md
Zach-O-Bates Dec 11, 2025
d56f5e5
Create 11-19-2025-ClientMeeting.md
Zach-O-Bates Dec 11, 2025
053867e
Create 11-26-2025-ClientMeeting.md
Zach-O-Bates Dec 11, 2025
fbee51f
Create 12-3-2025-ClientMeeting.md
Zach-O-Bates Dec 11, 2025
745b22c
Update 10-22-2025-ClientMeeting.md
Andrew-Bonner Dec 11, 2025
abd89ad
Update 10-29-2025-ClientMeeting.md
Andrew-Bonner Dec 11, 2025
3e343d4
Update 11-12-2025-ClientMeeting.md
Andrew-Bonner Dec 11, 2025
a51091a
Add notes for 11-5-2025 Client Meeting
Zach-O-Bates Dec 11, 2025
b821692
Revise client meeting notes for 11-5-2025
Zach-O-Bates Dec 11, 2025
d01e164
Add notes for client meeting on November 12, 2025
Zach-O-Bates Dec 11, 2025
319649c
Add meeting notes for client meeting on 12-3-2025
Zach-O-Bates Dec 11, 2025
8fe87d1
Update 11-19-2025-ClientMeeting.md
Andrew-Bonner Dec 11, 2025
05f92eb
Merge branch 'OpenEnergyDashboard:development' into development
Zach-O-Bates Dec 11, 2025
4ce2e1d
Create Meeting-Minutes folder for weekly notes
Oykunle Dec 11, 2025
5f0572f
weekly meeting notes (Weeks 1–9)
Oykunle Dec 11, 2025
e1fecf6
Create risk-log.md
BrianRaymond800 Dec 11, 2025
6040351
Update risk-log.md
BrianRaymond800 Dec 12, 2025
d3e3e86
Move meeting minutes into the team meeting folder and add UML diagrams
Zach-O-Bates Dec 12, 2025
e91c33b
Move risk log into the documents folder
Zach-O-Bates Dec 12, 2025
fa02303
Add communication plan document
Zach-O-Bates Dec 12, 2025
f28e5da
Add meeting notes for 09/01/2026
Oykunle Jan 12, 2026
148d882
Add meeting notes for 09/01/2026
Oykunle Jan 12, 2026
73b39d8
Remove the multiple instances of xss indicators
Zach-O-Bates Jan 13, 2026
45ff19e
Merge remote-tracking branch 'team5/main' into development
Zach-O-Bates Jan 18, 2026
70fd5fa
Revert "Merge remote-tracking branch 'team5/main' into development"
Zach-O-Bates Jan 19, 2026
b3baabe
Merge branch 'OpenEnergyDashboard:development' into development
Andrew-Bonner Jan 20, 2026
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
437 changes: 435 additions & 2 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@
"csv": "~5.3.2",
"csv-stringify": "~5.6.5",
"d3": "~7.8.5",
"dompurify": "~3.2.6",
"dotenv": "~16.4.5",
"escape-html": "~1.0.3",
"express": "~4.19.2",
"express-rate-limit": "~7.2.0",
"history": "~5.3.0",
"ini": "~4.1.3",
"jsdom": "~26.1.0",
"jsonschema": "~1.4.1",
"jsonwebtoken": "~9.0.0",
"lodash": "~4.17.21",
Expand Down
2 changes: 2 additions & 0 deletions src/scripts/checkHeader.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ FILES=$(echo "$FILES" | grep -v "src\/server\/test\/web\/readingsData\/.*")
FILES=$(echo "$FILES" | grep -v ".github\/**")
# Filter out unit test files
FILES=$(echo "$FILES" | grep -v "src\/server\/data\/unit\/.*")
# Filter out crossSite test files
FILES=$(echo "$FILES" | grep -v "src/server/test/crossSite/something.csv")

# Counts the files listed in FILES
NFILES=$(echo $FILES | wc -w)
Expand Down
31 changes: 15 additions & 16 deletions src/server/routes/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,31 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Functions to return a code and comment from an Express request.
// Functions to return a code and comment from an Express request.

const DOMPurify = require('../services/utils/sanitizer');

/**
* Inform the client of a success (200 OK).
*
* @param res The Express response object
* @param comment Any additional data to be returned to the client as a string
* Inform the client of a success (200 OK) with sanitized content.
*
* @param {express.Response} res The Express response object.
* @param {string} comment Any additional data to be returned to the client as a string.
*/
function success(res, comment = '') {
res.status(200) // 200 OK
.send(comment);
function success(res, comment = '') {
const safeComment = DOMPurify.sanitize(comment);
res.status(200).send(safeComment);
}

/**
* Inform the client of a failure with provided code or 500.
*
* @param res The Express response object
* @param code The code number to send back for request
* @param comment Any additional data to be returned to the client as a string
* Inform the client of a failure with provided code or 500, using sanitized content.
*
* @param {express.Response} res The Express response object.
* @param {number} code The code number to send back for the request.
* @param {string} comment Any additional data to be returned to the client as a string.
*/
function failure(res, code = 500, comment = '') {
res.status(code)
.send(comment);

const safeComment = DOMPurify.sanitize(comment);
res.status(code).send(safeComment);
}

module.exports = { success, failure };
28 changes: 13 additions & 15 deletions src/server/services/csvPipeline/success.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,33 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const express = require('express') /* needed to resolve types in JSDoc comments */
const express = require('express');
const DOMPurify = require('../utils/sanitizer');

/**
* Inform the client of a success (200 OK).
* Inform the client of a success (200 OK) with sanitized HTML content.
*
* @param {express.Request} req The Express request object
* @param {express.Response} res The Express response object
* @param {express.Request} req The Express request object.
* @param {express.Response} res The Express response object.
* @param {string} comment Any additional data to be returned to the client.
*
*/
function success(req, res, comment = '') {
res.status(200) // 200 OK
.send(`<h1>SUCCESS</h1>${comment}`);
const safeComment = DOMPurify.sanitize(comment);
res.status(200).send(`<h1>SUCCESS</h1>${safeComment}`);
}

/**
* Inform the client of a failure (400 OK).
* Inform the client of a failure (400 OK) with sanitized HTML content.
*
* @param {express.Request} req The Express request object
* @param {express.Response} res The Express response object
* @param {express.Request} req The Express request object.
* @param {express.Response} res The Express response object.
* @param {string} comment Any additional data to be returned to the client.
*
*/
function failure(req, res, comment = '') {
const safeComment = DOMPurify.sanitize(comment);
// 400 is client error. There is a small chance the insert into the DB failed
// but overlooking that.
res.status(400)
.send(`<h1>FAILURE</h1>${comment}`);

res.status(400).send(`<h1>FAILURE</h1>${safeComment}`);
}

module.exports = { success, failure };
module.exports = { success, failure };
12 changes: 12 additions & 0 deletions src/server/services/utils/sanitizer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const { JSDOM } = require('jsdom');
const createDOMPurify = require('dompurify');

// Create jsdom window application and initialize
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

module.exports = DOMPurify;
59 changes: 59 additions & 0 deletions src/server/test/crossSite/crossSite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* This file tests the functionality of the DOMPurify library. It tests for XSS
vulnerabilities in HTML of user uploaded data.*/

/* Run in OED Docker web container terminal/shell:
npm run testsome src/server/test/crossSite/crossSite.js */
const { chai, mocha, expect, app, testUser } = require('../common');
const xssIndicators = [
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for changing so only one version. How about moving it right below the mocha.describe so it isn't globally scoped?

'onerror',
'alert',
'document.domain',
'<script',
'javascript:',
'onload',
'onclick',
'<iframe'
];

mocha.describe('Cross site', () => {

mocha.it('Test for sanitization of HTML', async () => {
const filePath = 'src/server/test/crossSite/readings.csv';

const res = await chai.request(app).post('/api/csv/readings')
.field('email', testUser.username)
.field('password', testUser.password)
/* This next line should produce:
res.text: <h1>FAILURE</h1>CSVPipelineError:
User Error: Meter with name '<img src="x">' not found.
*/
.field('meterName', '<img src=x onerror="alert(document.domain)">')
.field('gzip', "no")
.attach('csvfile', 'src/server/test/crossSite/something.csv');

expect(res).to.have.status(400);
expect(res.text).to.include('<img src="x">');

xssIndicators.forEach(indicator => {
expect(res.text, `Output should not contain ${indicator}`).to.not.include(indicator);
});
});

mocha.it('Test for sanitization of login HTML in username', async () => {
const res = await chai.request(app)
.post('/api/login')
.send({
username: '<img src=x onerror="alert(1)">',
password: 'password123'
});
expect(res).to.have.status(401);

xssIndicators.forEach(indicator => {
expect(res.text, `Output should not contain ${indicator}`).to.not.include(indicator);
});
});
});
1 change: 1 addition & 0 deletions src/server/test/crossSite/something.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1,2,3
Loading