Skip to content
This repository has been archived by the owner on Mar 10, 2024. It is now read-only.

Commit

Permalink
fix temporary v1 compatibility issues
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonballinger committed Aug 1, 2023
1 parent c8998ee commit ed3aaad
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 106 deletions.
23 changes: 23 additions & 0 deletions compatibility/v1/chargedUpRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const express = require("express");
const router = express.Router();
const {
getGames,
createGame,
updateGame,
deleteGame,
} = require("../../controllers/chargedUpController");
const fillTeamName = require("../../middleware/fillTeamName");
const { editHistory } = require("../../middleware/editHistory");
const protect = require("./protect.js");

router
.route("/")
.post(protect, fillTeamName, editHistory, createGame)
.get(protect, getGames);
router
.route("/:id")
.get(protect, getGames)
.put(protect, editHistory, updateGame)
.delete(protect, deleteGame);

module.exports = router;
32 changes: 32 additions & 0 deletions compatibility/v1/protect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const jwt = require("jsonwebtoken");
const User = require("../../models/usersDb/userModel");
const asyncHandler = require("express-async-handler");

const protect = asyncHandler(async (req, res, next) => {
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer")
) {
try {
token = req.headers.authorization.split(" ")[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = await User.findById(decoded.id).select("-password");
if (req.user.toObject().isAdmin || req.user.toObject().isVerified) {
next();
} else {
res.status(405).json({
message: "User is not compatible with the v1 API",
});
}
} catch (err) {
console.log(err);
res.status(401).json({ message: "Token failed" });
}
}
if (!token) {
res.status(401).json({ message: "No token" });
}
});

module.exports = protect;
21 changes: 21 additions & 0 deletions compatibility/v1/rapidReactRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const express = require("express");
const router = express.Router();
const {
getGames,
setGame,
updateGame,
deleteGame,
} = require("../../controllers/rapidReactController");
const protect = require("./protect");
const { editHistory } = require("../../middleware/editHistory");

// all routes require user to be verified before making a request
// authorization middleware checks for bearer token in header
router.route("/").post(protect, editHistory, setGame).get(protect, getGames);
router
.route("/:id")
.get(protect, getGames)
.put(protect, editHistory, updateGame)
.delete(protect, deleteGame);

module.exports = router;
28 changes: 10 additions & 18 deletions compatibility/v1/userController.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const login = asyncHandler(async (req, res) => {
res.status(400).json({ message: "Invalid credentials" });
}

const isCompatible = user.isAdmin || user.isVerified;
const isCompatible = user.toObject().isAdmin || user.toObject().isVerified;
if (!isCompatible) {
res.status(405).json({
message: "User is not compatible with the v1 API",
Expand Down Expand Up @@ -59,23 +59,15 @@ const getMe = asyncHandler(async (req, res) => {
const { _id, firstname, lastname, username, email, isAdmin, isVerified } =
await User.findById(req.user.id);

const v1Compatible = user.isAdmin || user.isVerified;

if (v1Compatible) {
res.status(200).json({
id: _id,
firstname,
lastname,
username,
email,
isAdmin,
isVerified,
});
} else {
res.status(405).json({
message: "User is not compatible with the v1 API",
});
}
res.status(200).json({
id: _id,
firstname,
lastname,
username,
email,
isAdmin,
isVerified,
});
});

// generate JHT token
Expand Down
25 changes: 1 addition & 24 deletions compatibility/v1/userRoutes.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,9 @@
const express = require("express");
const router = express.Router();
const { login, checkToken, getMe } = require("./userController");
const jwt = require("jsonwebtoken");
const User = require("../../models/usersDb/userModel");
const asyncHandler = require("express-async-handler");
const protect = require("./protect.js");
const deprecatedRoute = require("../deprecatedRoute");

const protect = asyncHandler(async (req, res, next) => {
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer")
) {
try {
token = req.headers.authorization.split(" ")[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = await User.findById(decoded.id).select("-password");
next();
} catch (err) {
console.log(err);
res.status(401).json({ message: "Token failed" });
}
}
if (!token) {
res.status(401).json({ message: "No token" });
}
});

// handle user signups and logins
router.post("/register", deprecatedRoute);
router.post("/login", login); // only returns if user is backwards compatible
Expand Down
53 changes: 12 additions & 41 deletions controllers/userController.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,48 +109,14 @@ const checkToken = asyncHandler(async (req, res) => {
});

const getMe = asyncHandler(async (req, res) => {
const {
_id,
firstname,
lastname,
username,
email,
phone,
subteam,
roles,
accountType,
accountUpdateVersion,
socials,
children,
spouse,
donationAmounts,
employer,
parents,
attendance,
} = await User.findById(req.user.id);
res.status(200).json({
id: _id,
firstname,
lastname,
username,
email,
phone,
grade,
subteam,
roles,
accountType,
accountUpdateVersion,
socials,
children,
spouse,
donationAmounts,
employer,
parents,
attendance,
});
const userFromDb = await User.findById(req.user.id);
const user = userFromDb.toObject();
// temporary solution while transitioning from v1 to v2
if (user.isAdmin) delete user.isAdmin;
if (user.isVerified) delete user.isVerified;
res.status(200).json(user);
});


const deleteMe = asyncHandler(async (req, res) => {
const user = await User.findById(req.user.id);

Expand All @@ -176,6 +142,11 @@ const updateMe = asyncHandler(async (req, res) => {
new: true,
});

// temporary solution while transitioning from v1 to v2
const updatedUserObj = updatedUser.toObject();
if (updatedUserObj.isAdmin) delete updatedUserObj.isAdmin;
if (updatedUserObj.isVerified) delete updatedUserObj.isVerified;

res.status(200).json(updatedUser);
});

Expand Down Expand Up @@ -264,7 +235,7 @@ module.exports = {
checkToken,
getMe,
updateMe,
deleteMe,
deleteMe,
getUsersDefault,
getUsersAdmin,
getUserByIdDefault,
Expand Down
42 changes: 22 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,7 @@ app.use((req, res, next) => {
next();
});

const games = [
{ name: "rapidReact", minVersion: 1 },
{ name: "chargedUp", minVersion: 1 },
];

const nonGameRoutes = [
const routes = [
// keep 1 route path for each version even if they are the same
{
name: "users",
Expand All @@ -63,30 +58,37 @@ const nonGameRoutes = [
},
{
name: "seasons",
routePath: ["./compatibility/v1/seasonRoutes.js", "./routes/seasonRoutes.js"],
routePath: [
"./compatibility/v1/seasonRoutes.js",
"./routes/seasonRoutes.js",
],
minVersion: 1,
},
{
name: "inpit",
routePath: ["./routes/inPitRoutes.js"],
minVersion: 2,
},
{
name: "rapidReact",
routePath: ["./compatibility/v1/rapidReactRoutes.js", "./routes/rapidReactRoutes.js"],
minVersion: 1,
},
{
name: "chargedUp",
routePath: [
"./compatibility/v1/chargedUpRoutes.js",
"./routes/chargedUpRoutes.js",
],
minVersion: 1,
},
];

for (let i = 0; i < apiVersion; i++) {
for (let j = 0; j < games.length; j++) {
app.use(
`${api}/v${i + 1}/${games[j].name}`,
require(`./routes/${games[j].name}Routes`)
);
}
}

for (let i = 0; i < nonGameRoutes.length; i++) {
for (let j = nonGameRoutes[i].minVersion; j <= apiVersion; j++) {
for (let i = 0; i < routes.length; i++) {
for (let j = routes[i].minVersion; j <= apiVersion; j++) {
app.use(
`${api}/v${j}/${nonGameRoutes[i].name}`,
require(nonGameRoutes[i].routePath[j - nonGameRoutes[i].minVersion])
`${api}/v${j}/${routes[i].name}`,
require(routes[i].routePath[j - routes[i].minVersion])
);
}
}
Expand Down
8 changes: 6 additions & 2 deletions models/usersDb/userModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const userSchema = mongoose.Schema(
accountUpdateVersion: { type: Number, required: true },
forgotPassword: { type: Object, required: false },
// forgotPassword: {
// code: { type: Number },
// expiresAt: { type: Number },
// code: { type: Number },
// expiresAt: { type: Number },
// },
socials: { type: Array, required: false },

Expand All @@ -27,6 +27,10 @@ const userSchema = mongoose.Schema(
spouse: { type: Object, required: false },
donationAmounts: { type: Array, required: false },
employer: { type: Object, required: false },

// temporary while transitioning from v1 to v2
isVerified: { type: Boolean, required: false },
isAdmin: { type: Boolean, required: false },
},
{
timestamps: true,
Expand Down
2 changes: 1 addition & 1 deletion routes/userRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ router
.put(protect(3, updateUser));

// // user actions that can be called by user, requires bearer token
router.route("/me").get(protect, getMe).put(protect, updateMe);
router.route("/me").get(protect(0), getMe).put(protect(0), updateMe);

module.exports = router;

0 comments on commit ed3aaad

Please sign in to comment.