Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Upgrading dependencies for compatibility with Node 20 and general maintenance #926

Merged
merged 4 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

strategy:
matrix:
node-version: [14.x]
node-version: [20.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v14
20.10.0
6 changes: 3 additions & 3 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const volunteerRouter = require("./routes/api/volunteer");
const roleRouter = require("./routes/api/role");

const app = express();
Services.db.connect(app);
Services.db.connect();

let corsOptions = {};

Expand Down Expand Up @@ -72,7 +72,7 @@ app.use(
// Cookie Options
maxAge: 48 * 60 * 60 * 1000, //Logged in for 48 hours
sameSite: process.env.COOKIE_SAME_SITE,
secureProxy: true
secureProxy: !Services.env.isTest()
})
);
app.use(passport.initialize());
Expand Down Expand Up @@ -115,7 +115,7 @@ app.use((err, req, res, next) => {
const message = err.message ? err.message : "Internal Server Error";
//Only show bad error when we're not in deployment
let errorContents;
if (status === 500 && Services.env.isProduction) {
if (status === 500 && Services.env.isProduction()) {
errorContents = {};
} else if (err.error) {
errorContents = err.error;
Expand Down
3 changes: 1 addition & 2 deletions constants/role.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Constants = {
const mongoose = require("mongoose");

const accountRole = {
_id: mongoose.Types.ObjectId("00000000e285ec4f6ec7e5c2"),
_id: new mongoose.Types.ObjectId("00000000e285ec4f6ec7e5c2"),
name: "account",
routes: [
Constants.Routes.authRoutes.login,
Expand Down Expand Up @@ -37,7 +37,6 @@ const hackerRole = {
Constants.Routes.hackerRoutes.patchSelfById,
Constants.Routes.hackerRoutes.patchSelfConfirmationById,
Constants.Routes.hackerRoutes.getSelf,
Constants.Routes.hackerRoutes.postDiscord,

Constants.Routes.travelRoutes.getSelf,
Constants.Routes.travelRoutes.getSelfById,
Expand Down
22 changes: 11 additions & 11 deletions constants/testMongoId.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

const mongoose = require("mongoose");

const team1Id = mongoose.Types.ObjectId();
const team2Id = mongoose.Types.ObjectId();
const team3Id = mongoose.Types.ObjectId();
const team1Id = new mongoose.Types.ObjectId();
const team2Id = new mongoose.Types.ObjectId();
const team3Id = new mongoose.Types.ObjectId();

const hackerAId = mongoose.Types.ObjectId();
const hackerBId = mongoose.Types.ObjectId();
const hackerCId = mongoose.Types.ObjectId();
const hackerDId = mongoose.Types.ObjectId();
const hackerEId = mongoose.Types.ObjectId();
const hackerFId = mongoose.Types.ObjectId();
const hackerGId = mongoose.Types.ObjectId();
const hackerHId = mongoose.Types.ObjectId();
const hackerAId = new mongoose.Types.ObjectId();
const hackerBId = new mongoose.Types.ObjectId();
const hackerCId = new mongoose.Types.ObjectId();
const hackerDId = new mongoose.Types.ObjectId();
const hackerEId = new mongoose.Types.ObjectId();
const hackerFId = new mongoose.Types.ObjectId();
const hackerGId = new mongoose.Types.ObjectId();
const hackerHId = new mongoose.Types.ObjectId();

module.exports = {
team1Id: team1Id,
Expand Down
4 changes: 2 additions & 2 deletions controllers/auth.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ const Success = require("../constants/success.constant");
module.exports = {
onSuccessfulLogin: function(req, res) {
return res.status(200).json({
message: Success.LOGIN,
message: Success.AUTH_LOGIN,
data: {}
});
},
logout: function(req, res) {
req.logout();
return res.status(200).json({
message: Success.LOGOUT,
message: Success.AUTH_LOGOUT,
data: {}
});
},
Expand Down
30 changes: 15 additions & 15 deletions docs/standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Things to take note of:
message: string,
error: any
}
```
```
* **Wrapping async functions**: Asynchronous middleware must be wrapped with `Util.asyncMiddleware(...)`. This is so that if a `Promise` is rejected, the reject reason is handled gracefully. To understand how this works, please look at the code for `asyncMiddleware`.
* **Organization of import statements**: We organize our import statements according to their general function. If a file is a `Service` (such as `user.service.js`), then we place it inside of the `Service` object. This is to make code readability better.

Expand Down Expand Up @@ -201,9 +201,9 @@ Things to take note of:
* **`activate` function**: Every route file contains one exported function, called `activate`. This takes as input an `ExpressRouter`, to which we will attach the sub router to. We will also define all of the sub-routes in this function.
* **Chaining middlewares in a route**: We chain middlewares together by placing them one after another as arguments to the http request of the route.
* **Ordering of middleware**:
* If input is expected, validation of that input should be done promptly. Therefore validators are generally the first middlewares.
* If input is expected, validation of that input should be done promptly. Therefore validators are generally the first middlewares.
* The first middleware should be the validator for the inputted data of a route. In this case, we have the validator for a new account.
* The next middleware should be `Middleware.parseBody.middleware` to parse the validated information. This middleware also places the data inside of `req.body`. If validation fails, it fails the request.
* The next middleware should be `Middleware.parseBody.middleware` to parse the validated information. This middleware also places the data inside of `req.body`. If validation fails, it fails the request.
* The following middlewares will depend on what type of route it is. In this case, we are creating a new item in our database, so we want to create a new `Account` object. This is what `Middleware.Account.parseAccount` does.
* Finally, we want to interact with the database. This is done either in the `Controller` function, or in another `middleware` function.
* the last middleware should always be a `Controller` (since we want to respond to the user of the api).
Expand Down Expand Up @@ -233,7 +233,7 @@ function findById(id) {
_id: id
};

return Account.findById(query, logger.queryCallbackFactory(TAG, "account", query));
return logger.logQuery(TAG, "account", query, Account.findById(query));
}
...
module.exports = {
Expand All @@ -242,7 +242,7 @@ module.exports = {
```

Things to take note of:
* **async & await**: When the service call is to a mongoose model, they generally return a mongoose query. These can be handled as a promise, and Mongoose has further documentation on it [here](https://mongoosejs.com/docs/api.html). We handle then by using `await` on the service call. For example, a middleware function that uses `findById` would be:
* **async & await**: When the service call is to a mongoose model, they generally return a mongoose query. These can be handled as a promise, and Mongoose has further documentation on it [here](https://mongoosejs.com/docs/api.html). We handle then by using `await` on the service call. For example, a middleware function that uses `findById` would be:
```javascript
async function getById(req, res, next) {
const acc = await Services.Account.findById(req.body.id);
Expand All @@ -256,14 +256,14 @@ Things to take note of:

req.body.account = acc;
return next();
}
}
```
It's important to:
It's important to:
* Use `await` when calling the service function
* Put `async` in the method head
* Check the output of the service function call for any errors. In the code snippet we need to check for a scenario where the account is not found, which is a 404 error. A full list of the current error messages are in [error.constant.js](../constants/error.constant.js).
More information on asynchronous functions can be found [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function).
* **queryCallbackFactory**: The query callback factory returns a function that uses winston to log the success or failure of the service call. The callback factory is used for mongoose service calls.
* **logQuery**: This function wraps the query's `then` method and uses winston to log the success or failure of the mongoose service call.

### Test files

Expand All @@ -281,7 +281,7 @@ We repopulate the test server before each test to ensure consistency. [setup.spe

##### Motivation

We wanted to have a scalable way to create new entities that properly reference each other. The biggest challenge lied in creating enough accounts that can be properly referenced during specific tests.
We wanted to have a scalable way to create new entities that properly reference each other. The biggest challenge lied in creating enough accounts that can be properly referenced during specific tests.

##### Util.js

Expand Down Expand Up @@ -309,7 +309,7 @@ let hackerAccounts = {
};
```

In this example the `new` accounts are accounts that exist, but the hacker objects have not been created. The `stored.team` accounts are those linked to a hacker object that is in a team. The `stored.noTeam` accounts link to a hacker that is not in a team. The `invalid` accounts are created accounts that are linked to a hacker object that does not fit with the Hacker schema. The invalid accounts are used to test fail cases. The value for each key is an array of account objects.
In this example the `new` accounts are accounts that exist, but the hacker objects have not been created. The `stored.team` accounts are those linked to a hacker object that is in a team. The `stored.noTeam` accounts link to a hacker that is not in a team. The `invalid` accounts are created accounts that are linked to a hacker object that does not fit with the Hacker schema. The invalid accounts are used to test fail cases. The value for each key is an array of account objects.

On the other end of the account-hacker link, [hacker.util.js](../tests/util/hacker.test.util.js) contains the hacker data in the form of hacker objects. These hacker objects have an `accountId` attribute which references an account's `_id`. The matching between the hacker object and the respective account object it needs to link to is also done by nomenclature. For example, a hacker on a team would be called `TeamHackerX` where X is a number. This hacker's account object would be within the array specified by `hackerAccounts.stored.team`. The specific account object is referenced by its index in the array. That index is the same as the value X in the name of the hacker object.

Expand All @@ -335,7 +335,7 @@ function stringValidator(fieldLocation, fieldname, optional = true) {
```
It's important to note the use of `setProperValidationChainBuilder` to parse the input value from the appropriate input location. This is consistent across generic validators. It is also important to create a validator for situations where the input is optional.

A validator example, using generic validator functions.
A validator example, using generic validator functions.
```javascript
"use strict";
const VALIDATOR = require("./validator.helper");
Expand All @@ -358,7 +358,7 @@ module.exports = {
};
```

A route would use a validator in the following manner:
A route would use a validator in the following manner:
```javascript
accountRouter.route("/:id").patch(
...
Expand All @@ -377,8 +377,8 @@ A route would use a validator in the following manner:
{
"A": "foo",
"B": true,
"C": {
"bar": "baz"
"C": {
"bar": "baz"
}
}
```
Expand Down Expand Up @@ -429,4 +429,4 @@ We use apidoc.js to generate documentation for the API. This documentation is fo

For more info on how to write your own documentation, see their docs: <http://apidocjs.com/>.

To update the docs, run: `npm run docs`. Make sure that the version number for each route is correct!
To update the docs, run: `npm run docs`. Make sure that the version number for each route is correct!
2 changes: 1 addition & 1 deletion middlewares/account.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function parsePatch(req, res, next) {
*/
function parseAccount(req, res, next) {
const accountDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
firstName: req.body.firstName,
lastName: req.body.lastName,
pronoun: req.body.pronoun,
Expand Down
12 changes: 4 additions & 8 deletions middlewares/hacker.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function parsePatch(req, res, next) {
*/
function parseHacker(req, res, next) {
const hackerDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
accountId: req.body.accountId,
application: req.body.application,
teamId: req.body.teamId
Expand Down Expand Up @@ -127,17 +127,13 @@ function validateConfirmedStatus(account) {
message: Constants.Error.ACCOUNT_404_MESSAGE,
data: { account: account }
};
}
/*
else if (!account.confirmed) {
} else if (!account.confirmed) {
return {
status: 403,
message: Constants.Error.ACCOUNT_403_MESSAGE,
data: { account: { id: account.id, confirmed: account.confirmed } }
};
}
*/
else if (account.accountType !== Constants.General.HACKER) {
} else if (account.accountType !== Constants.General.HACKER) {
return {
status: 409,
message: Constants.Error.ACCOUNT_TYPE_409_MESSAGE,
Expand Down Expand Up @@ -841,7 +837,7 @@ async function checkDuplicateAccountLinks(req, res, next) {
*/
async function findSelf(req, res, next) {
if (
req.user.accountType != Constants.General.HACKER /*|| !req.user.confirmed*/
req.user.accountType != Constants.General.HACKER|| !req.user.confirmed
) {
return next({
status: 409,
Expand Down
2 changes: 1 addition & 1 deletion middlewares/role.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const Constants = {
*/
function parseRole(req, res, next) {
const roleDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
routes: req.body.routes
};
Expand Down
2 changes: 1 addition & 1 deletion middlewares/sponsor.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function parsePatch(req, res, next) {
*/
function parseSponsor(req, res, next) {
const sponsorDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
accountId: req.body.accountId,
tier: req.body.tier,
company: req.body.company,
Expand Down
4 changes: 2 additions & 2 deletions middlewares/team.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ async function populateMemberAccountsById(req, res, next) {
*/
function parseTeam(req, res, next) {
const teamDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
members: req.body.members,
devpostURL: req.body.devpostURL,
Expand Down Expand Up @@ -492,7 +492,7 @@ function parsePatch(req, res, next) {

async function parseNewTeam(req, res, next) {
const teamDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
members: [],
devpostURL: req.body.devpostURL,
Expand Down
2 changes: 1 addition & 1 deletion middlewares/travel.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function parsePatch(req, res, next) {
*/
function parseTravel(req, res, next) {
const travelDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
accountId: req.body.accountId,
hackerId: req.body.hackerId
};
Expand Down
6 changes: 3 additions & 3 deletions middlewares/validators/validator.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) {
// typeof app.shortAnswer.question2 === "string";
// hasValid.previousHackathons =
// !!app.shortAnswer.previousHackathons &&
// typeof app.shortAnswer.previousHackathons === "number";
// typeof app.shortAnswer.previousHackathons === "number";
// hasValid.team =
// !app.team || mongoose.Types.ObjectId.isValid(app.team);

Expand Down Expand Up @@ -534,7 +534,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) {
);
hasValid.previousHackathons = app.shortAnswer.hasOwnProperty(
"previousHackathons"
);
);
}
hasValid.accommodation = app.hasOwnProperty("accommodation");
if (hasValid.accommodation) {
Expand Down Expand Up @@ -584,7 +584,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) {
// typeof app.shortAnswer.question2 === "string";
// hasValid.previousHackathons =
// !!app.shortAnswer.previousHackathons &&
// typeof app.shortAnswer.previousHackathons === "number";
// typeof app.shortAnswer.previousHackathons === "number";
// hasValid.team =
// !app.team || mongoose.Types.ObjectId.isValid(app.team);
return (
Expand Down
2 changes: 1 addition & 1 deletion middlewares/volunteer.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Constants = {
*/
function parseVolunteer(req, res, next) {
const volunteerDetails = {
_id: mongoose.Types.ObjectId(),
_id: new mongoose.Types.ObjectId(),
accountId: req.body.accountId
};

Expand Down
4 changes: 2 additions & 2 deletions models/account.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ const AccountSchema = new mongoose.Schema({
}
});

AccountSchema.methods.toJSON = function() {
const as = this.toObject();
AccountSchema.methods.toJSON = function(options) {
const as = this.toObject(options);
delete as.__v;
as.id = as._id;
delete as._id;
Expand Down
12 changes: 6 additions & 6 deletions models/accountConfirmationToken.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ const AccountConfirmationSchema = new mongoose.Schema({
}
});

AccountConfirmationSchema.methods.toJSON = function() {
const resetObj = this.toObject();
delete resetObj.__v;
resetObj.id = resetObj._id;
delete resetObj._id;
return resetObj;
AccountConfirmationSchema.methods.toJSON = function(options) {
const acs = this.toObject(options);
delete acs.__v;
acs.id = acs._id;
delete acs._id;
return acs;
};

module.exports = mongoose.model(
Expand Down
4 changes: 2 additions & 2 deletions models/bus.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ const BusSchema = new mongoose.Schema({
}
});

BusSchema.methods.toJSON = function() {
const bs = this.toObject();
BusSchema.methods.toJSON = function(options) {
const bs = this.toObject(options);
delete bs.__v;
bs.id = bs._id;
delete bs._id;
Expand Down
Loading
Loading