diff --git a/day9/app.js b/day9/app.js index 97a1728..5e90eef 100644 --- a/day9/app.js +++ b/day9/app.js @@ -1,29 +1,33 @@ -var createError = require('http-errors'); -var express = require('express'); -var path = require('path'); -var cookieParser = require('cookie-parser'); -var logger = require('morgan'); +var createError = require("http-errors"); +var express = require("express"); +var path = require("path"); +var cookieParser = require("cookie-parser"); +var logger = require("morgan"); -var indexRouter = require('./routes/index'); -var usersRouter = require('./routes/users'); +var indexRouter = require("./routes/index"); +var usersRouter = require("./routes/users"); const db = require("./models"); var cors = require("cors"); +const maintenanceMiddleware = require("./middleware/Maintenance"); +const roleCheckMiddleware = require("./middleware/RoleCheckMiddleware"); var app = express(); app.set("db", db); // view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); +app.set("views", path.join(__dirname, "views")); +app.set("view engine", "jade"); app.use(cors()); -app.use(logger('dev')); +app.use(logger("dev")); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, "public"))); +app.use(maintenanceMiddleware); +app.use("/api/v1", roleCheckMiddleware); -app.use('/', indexRouter); -app.use('/users', usersRouter); +app.use("/", indexRouter); +app.use("/users", usersRouter); // catch 404 and forward to error handler app.use(function (req, res, next) { @@ -34,11 +38,14 @@ app.use(function (req, res, next) { app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; - res.locals.error = req.app.get('env') === 'development' ? err : {}; + res.locals.error = req.app.get("env") === "development" ? err : {}; - // render the error page + // standardized error response res.status(err.status || 500); - res.render('error'); + res.json({ + success: false, + error: err.message || "Internal Server Error", + }); }); module.exports = app; diff --git a/day9/config.js b/day9/config.js new file mode 100644 index 0000000..14d24b9 --- /dev/null +++ b/day9/config.js @@ -0,0 +1,3 @@ +module.exports = { + maintenance: false, +}; diff --git a/day9/middleware/AuthMiddleware.js b/day9/middleware/AuthMiddleware.js new file mode 100644 index 0000000..45b98ca --- /dev/null +++ b/day9/middleware/AuthMiddleware.js @@ -0,0 +1,23 @@ +const JwtService = require("../services/JwtService"); + +module.exports = function (req, res, next) { + const token = JwtService.getToken(req); + if (!token) { + return res.status(401).json({ + success: false, + error: "Access denied. No token provided.", + }); + } + const payload = JwtService.verifyAccessToken(token); + if (!payload) { + return res.status(401).json({ + success: false, + error: "Invalid or expired token.", + }); + } + req.tokenPayload = payload; + if (payload && payload.user_id) { + req.user_id = payload.user_id; + } + next(); +}; diff --git a/day9/middleware/Maintenance.js b/day9/middleware/Maintenance.js new file mode 100644 index 0000000..e5b874a --- /dev/null +++ b/day9/middleware/Maintenance.js @@ -0,0 +1,11 @@ +const config = require("../config"); + +module.exports = function (req, res, next) { + if (config.maintenance) { + return res.status(503).json({ + success: false, + error: "Service is under maintenance. Please try again later.", + }); + } + next(); +}; diff --git a/day9/middleware/RoleCheckMiddleware.js b/day9/middleware/RoleCheckMiddleware.js new file mode 100644 index 0000000..ca65741 --- /dev/null +++ b/day9/middleware/RoleCheckMiddleware.js @@ -0,0 +1,14 @@ +module.exports = function (req, res, next) { + const match = req.path.match(/^\/api\/v1\/(\w+)\//); + if (match) { + const portal = match[1]; + const userRole = req.tokenPayload && req.tokenPayload.role; + if (userRole !== portal) { + return res.status(403).json({ + success: false, + error: `Access denied. Role '${userRole}' does not match portal '${portal}'.`, + }); + } + } + next(); +}; diff --git a/day9/package.json b/day9/package.json index b96eef4..2021f0d 100644 --- a/day9/package.json +++ b/day9/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "node ./bin/www", + "dev": "node --watch ./bin/www" }, "dependencies": { "cookie-parser": "~1.4.4", diff --git a/day9/routes/users.js b/day9/routes/users.js index 623e430..28fa22a 100644 --- a/day9/routes/users.js +++ b/day9/routes/users.js @@ -1,9 +1,13 @@ -var express = require('express'); +var express = require("express"); var router = express.Router(); +const authMiddleware = require("../middleware/AuthMiddleware"); /* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); +router.get("/", authMiddleware, function (req, res, next) { + res.json({ + success: true, + data: "respond with a resource", + }); }); module.exports = router;