Skip to content

Commit

Permalink
Merge pull request #227 from rcowsill/feature/lint-workflow
Browse files Browse the repository at this point in the history
Add lint workflow
  • Loading branch information
lirantal authored Mar 6, 2023
2 parents cdf0f7f + 3d1d9fe commit 8d4c9cc
Show file tree
Hide file tree
Showing 36 changed files with 852 additions and 678 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Lint
on: [push, pull_request]

jobs:
lint:
name: Node.js
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
node-version: ["14.x"]

steps:
- name: Checkout https://github.com/${{ github.repository }}@${{ github.ref }}
uses: actions/checkout@v2
with:
persist-credentials: false

- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Run linter
run: npx --no-install [email protected] .
2 changes: 2 additions & 0 deletions .jshintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
app/assets/vendor/
47 changes: 22 additions & 25 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
"browser": true, // Standard browser globals e.g. `window`, `document`.
"es5": false, // Allow EcmaScript 5 syntax.
"esnext": true, // Allow ES.next specific features such as `const` and `let`.
"esversion": 9, // Allow EcmaScript 9 syntax.
"bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.).
"camelcase": true, // Permit only camelcase for `var` and `object indexes`.
"curly": false, // Require {} for every new block or scope.
"eqeqeq": true, // Require triple equals i.e. `===`.
"immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
"immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`.
"latedef": true, // Prohibit variable use before definition.
"newcap": true, // Require capitalization of all constructor functions e.g. `new F()`.
"noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`.
Expand All @@ -17,26 +16,24 @@
"unused": false, // Warn unused variables.
"strict": true, // Require `use strict` pragma in every file.
"trailing": true, // Prohibit trailing whitespaces.
"smarttabs": false, // Suppresses warnings about mixed tabs and spaces
"globals": { // Globals variables.
},
"predef": [ // Extra globals.
"define",
"require",
"exports",
"module",
"describe",
"before",
"beforeEach",
"after",
"afterEach",
"it",
"$",
"Morris",
"Tour"
],
"indent": 4, // Specify indentation spacing
"maxlen": 120, // Max line lenght
"smarttabs": false, // Suppresses warnings about mixed tabs and spaces.
"indent": 4, // Specify indentation spacing.
"maxlen": 120, // Max line length.
"devel": false, // Allow development statements e.g. `console.log();`.
"noempty": true // Prohibit use of empty blocks.
}
"noempty": true, // Prohibit use of empty blocks.
"overrides": {
"test/e2e/**": {
"globals": {
"cy": false,
"Cypress": false,
"it": false,
"describe": false,
"before": false,
"after": false,
"beforeEach": false,
"afterEach": false,
"expect": false
}
}
}
}
14 changes: 11 additions & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,31 @@

var exec = require("child_process").exec;

var JS_FILES = ["Gruntfile.js", "app/assets/js/**", "config/config.js", "app/data/**/*.js",
"app/routes/**/*.js", "server.js", "test/**/*.js"
var APP_JS_FILES = ["app/assets/js/**/*.js", "config/**/*.js", "app/data/**/*.js",
"app/routes/**/*.js", "server.js"
];

var SUPPORT_JS_FILES = ["Gruntfile.js", "artifacts/**/*.js", "test/**/*.js"];

var JS_FILES = APP_JS_FILES.concat(SUPPORT_JS_FILES);


module.exports = function(grunt) {
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
watch: {
js: {
files: JS_FILES,
files: APP_JS_FILES,
tasks: ["jshint"],
options: {
livereload: true
}
},
support: {
files: SUPPORT_JS_FILES,
tasks: ["jshint"]
},
html: {
files: ["app/views/**"],
options: {
Expand Down
1 change: 1 addition & 0 deletions app/assets/js/chart/chart-data-morris.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* globals $, Morris */
$(function() {

"use strict";
Expand Down
2 changes: 2 additions & 0 deletions app/assets/js/tour/redirects-steps.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* globals $, Tour */

const redirectsTour = new Tour({
name: "redirects"
});
Expand Down
4 changes: 2 additions & 2 deletions app/data/allocations-dao.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const AllocationsDAO = function(db){
return {
userId: parsedUserId
};
}
};

allocationsCol.find(searchCriteria()).toArray((err, allocations) => {
if (err) return callback(err, null);
Expand Down Expand Up @@ -109,6 +109,6 @@ const AllocationsDAO = function(db){
});
};

}
};

module.exports.AllocationsDAO = AllocationsDAO;
4 changes: 2 additions & 2 deletions app/data/research-dao.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ function ResearchDAO(db) {
symbol
};
}
}
}
};
};
}

module.exports = { ResearchDAO };
6 changes: 3 additions & 3 deletions app/data/user-dao.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function UserDAO(db) {
const day = (Math.floor(Math.random() * 10) + today.getDay()) % 29;
const month = (Math.floor(Math.random() * 10) + today.getMonth()) % 12;
const year = Math.ceil(Math.random() * 30) + today.getFullYear();
return `${year}-${("0" + month).slice(-2)}-${("0" + day).slice(-2)}`
return `${year}-${("0" + month).slice(-2)}-${("0" + day).slice(-2)}`;
};

this.validateLogin = (userName, password, callback) => {
Expand All @@ -64,7 +64,7 @@ function UserDAO(db) {
// compares decrypted password stored in this.addUser()
return bcrypt.compareSync(fromDB, fromUser);
*/
}
};

// Callback to pass to MongoDB that validates a user document
const validateUserDoc = (err, user) => {
Expand All @@ -86,7 +86,7 @@ function UserDAO(db) {
noSuchUserError.noSuchUser = true;
callback(noSuchUserError, null);
}
}
};

usersCol.findOne({
userName: userName
Expand Down
2 changes: 1 addition & 1 deletion app/routes/allocations.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function AllocationsHandler(db) {
} = req.params;
const {
threshold
} = req.query
} = req.query;

allocationsDAO.getByUserIdAndThreshold(userId, threshold, (err, allocations) => {
if (err) return next(err);
Expand Down
4 changes: 2 additions & 2 deletions app/routes/contributions.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ function ContributionsHandler(db) {
} = req.session;

//validate contributions
const validations = [isNaN(preTax), isNaN(afterTax), isNaN(roth), preTax < 0, afterTax < 0, roth < 0]
const isInvalid = validations.some(validation => validation)
const validations = [isNaN(preTax), isNaN(afterTax), isNaN(roth), preTax < 0, afterTax < 0, roth < 0];
const isInvalid = validations.some(validation => validation);
if (isInvalid) {
return res.render("contributions", {
updateError: "Invalid contribution percentages",
Expand Down
2 changes: 1 addition & 1 deletion app/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const index = (app, db) => {
app.get("/tutorial/:page", (req, res) => {
const {
page
} = req.params
} = req.params;
return res.render(`tutorial/${page}`, {
environmentalScripts
});
Expand Down
6 changes: 3 additions & 3 deletions app/routes/profile.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const ProfileDAO = require("../data/profile-dao").ProfileDAO;
const ESAPI = require('node-esapi')
const ESAPI = require("node-esapi");
const {
environmentalScripts
} = require("../../config/config");
Expand All @@ -25,7 +25,7 @@ function ProfileHandler(db) {
// while the developer intentions were correct in encoding the user supplied input so it
// doesn't end up as an XSS attack, the context is incorrect as it is encoding the firstname for HTML
// while this same variable is also used in the context of a URL link element
doc.website = ESAPI.encoder().encodeForHTML(doc.website)
doc.website = ESAPI.encoder().encodeForHTML(doc.website);
// fix it by replacing the above with another template variable that is used for
// the context of a URL in a link header
// doc.website = ESAPI.encoder().encodeForURL(doc.website)
Expand Down Expand Up @@ -61,7 +61,7 @@ function ProfileHandler(db) {
const testComplyWithRequirements = regexPattern.test(bankRouting);
// if the regex test fails we do not allow saving
if (testComplyWithRequirements !== true) {
const firstNameSafeString = firstName
const firstNameSafeString = firstName;
return res.render("profile", {
updateError: "Bank Routing number does not comply with requirements for format specified",
firstNameSafeString,
Expand Down
24 changes: 15 additions & 9 deletions app/routes/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ function SessionHandler(db) {

this.isAdminUserMiddleware = (req, res, next) => {
if (req.session.userId) {
return userDAO.getUserById(req.session.userId, (err, user) => user && user.isAdmin ? next() : res.redirect("/login"));
return userDAO.getUserById(req.session.userId, (err, user) => {
return user && user.isAdmin ? next() : res.redirect("/login");
});
}
console.log("redirecting to login");
return res.redirect("/login");
Expand Down Expand Up @@ -52,26 +54,30 @@ function SessionHandler(db) {
const {
userName,
password
} = req.body
} = req.body;
userDAO.validateLogin(userName, password, (err, user) => {
const errorMessage = "Invalid username and/or password";
const invalidUserNameErrorMessage = "Invalid username";
const invalidPasswordErrorMessage = "Invalid password";
if (err) {
if (err.noSuchUser) {
console.log('Error: attempt to login with invalid user: ', userName);
console.log("Error: attempt to login with invalid user: ", userName);

// Fix for A1 - 3 Log Injection - encode/sanitize input for CRLF Injection
// that could result in log forging:
// - Step 1: Require a module that supports encoding
// const ESAPI = require('node-esapi');
// - Step 2: Encode the user input that will be logged in the correct context
// following are a few examples:
// console.log('Error: attempt to login with invalid user: %s', ESAPI.encoder().encodeForHTML(userName));
// console.log('Error: attempt to login with invalid user: %s', ESAPI.encoder().encodeForJavaScript(userName));
// console.log('Error: attempt to login with invalid user: %s', ESAPI.encoder().encodeForURL(userName));
// console.log('Error: attempt to login with invalid user: %s',
// ESAPI.encoder().encodeForHTML(userName));
// console.log('Error: attempt to login with invalid user: %s',
// ESAPI.encoder().encodeForJavaScript(userName));
// console.log('Error: attempt to login with invalid user: %s',
// ESAPI.encoder().encodeForURL(userName));
// or if you know that this is a CRLF vulnerability you can target this specifically as follows:
// console.log('Error: attempt to login with invalid user: %s', userName.replace(/(\r\n|\r|\n)/g, '_'));
// console.log('Error: attempt to login with invalid user: %s',
// userName.replace(/(\r\n|\r|\n)/g, '_'));

return res.render("login", {
userName: userName,
Expand Down Expand Up @@ -108,7 +114,7 @@ function SessionHandler(db) {
// i.e:
// `req.session.regenerate(() => {})`
req.session.userId = user._id;
return res.redirect(user.isAdmin ? "/benefits" : "/dashboard")
return res.redirect(user.isAdmin ? "/benefits" : "/dashboard");
});
};

Expand Down Expand Up @@ -178,7 +184,7 @@ function SessionHandler(db) {
}
}
return true;
}
};

this.handleSignup = (req, res, next) => {

Expand Down
6 changes: 3 additions & 3 deletions artifacts/db-reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const tryDropCollection = (db, name) => {
resolve(undefined);
});
});
}
};

const parseResponse = (err, res, comm) => {
if (err) {
Expand All @@ -56,7 +56,7 @@ const parseResponse = (err, res, comm) => {
}
console.log(comm);
console.log(JSON.stringify(res));
}
};


// Starting here
Expand Down Expand Up @@ -126,7 +126,7 @@ MongoClient.connect(db, (err, db) => {

allocationsCol.insertMany(finalAllocations, (err, data) => {
parseResponse(err, data, "allocations.insertMany");
console.log("Database reset performed successfully")
console.log("Database reset performed successfully");
process.exit(0);
});

Expand Down
12 changes: 6 additions & 6 deletions config/config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
const _ = require("underscore");
const path = require("path");
const util = require('util')
const util = require("util");

const finalEnv = process.env.NODE_ENV || "development";

const allConf = require(path.resolve(__dirname + "/../config/env/all.js"))
const envConf = require(path.resolve(__dirname + "/../config/env/" + finalEnv.toLowerCase() + ".js")) || {}
const allConf = require(path.resolve(__dirname + "/../config/env/all.js"));
const envConf = require(path.resolve(__dirname + "/../config/env/" + finalEnv.toLowerCase() + ".js")) || {};

const config = { ...allConf, ...envConf }
const config = { ...allConf, ...envConf };

console.log(`Current Config:`)
console.log(util.inspect(config, false, null))
console.log(`Current Config:`);
console.log(util.inspect(config, false, null));

module.exports = config;
6 changes: 5 additions & 1 deletion config/env/development.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ module.exports = {
zapApiKey: "v9dn0balpqas1pcc281tn5ood1",
// Required if debugging security regression tests.
zapApiFeedbackSpeed: 5000, // Milliseconds.
environmentalScripts: [`<script>document.write("<script src='http://" + (location.host || "localhost").split(":")[0] + ":35729/livereload.js'></" + "script>");</script>`]
environmentalScripts: [
// jshint -W101
`<script>document.write("<script src='http://" + (location.host || "localhost").split(":")[0] + ":35729/livereload.js'></" + "script>");</script>`
// jshint +W101
]
};
Loading

0 comments on commit 8d4c9cc

Please sign in to comment.