project-startup 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/Logics/rbac/controllers/authController.js +52 -0
- package/template/Logics/rbac/controllers/demoController.js +38 -0
- package/template/Logics/rbac/db.js +12 -0
- package/template/Logics/rbac/middleware/authMiddleware.js +28 -0
- package/template/Logics/rbac/routes/authRoutes.js +10 -0
- package/template/Logics/rbac/routes/demoRoutes.js +37 -0
package/package.json
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const bcrypt = require("bcrypt");
|
|
2
|
+
const db = require("../db");
|
|
3
|
+
|
|
4
|
+
exports.login = async (req, res) => {
|
|
5
|
+
const { email, password } = req.body;
|
|
6
|
+
|
|
7
|
+
if (!email || !password) {
|
|
8
|
+
return res.status(400).json({ error: "Email and password are required." });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const [rows] = await db.query(
|
|
12
|
+
"SELECT * FROM users WHERE email = ?", [email]
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
if (rows.length === 0) {
|
|
16
|
+
return res.status(401).json({ error: "Invalid email or password." });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const user = rows[0];
|
|
20
|
+
const match = await bcrypt.compare(password, user.password);
|
|
21
|
+
|
|
22
|
+
if (!match) {
|
|
23
|
+
return res.status(401).json({ error: "Invalid email or password." });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Store only the safe user fields in the session — never the password hash
|
|
27
|
+
req.session.user = {
|
|
28
|
+
id: user.id,
|
|
29
|
+
name: user.name,
|
|
30
|
+
email: user.email,
|
|
31
|
+
role: user.role,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// express-session saves the session and sends the Set-Cookie header
|
|
35
|
+
// automatically — we just respond with the user object for the frontend
|
|
36
|
+
res.json({ user: req.session.user });
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
exports.logout = (req, res) => {
|
|
40
|
+
// Destroys the session row in MySQL and clears the cookie
|
|
41
|
+
req.session.destroy(err => {
|
|
42
|
+
if (err) {
|
|
43
|
+
return res.status(500).json({ error: "Could not log out." });
|
|
44
|
+
}
|
|
45
|
+
res.clearCookie("connect.sid");
|
|
46
|
+
res.json({ message: "Logged out." });
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
exports.me = (req, res) => {
|
|
51
|
+
res.json(req.user);
|
|
52
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// These are demo endpoints that exist purely to show RBAC in action.
|
|
2
|
+
// In a real app you'd replace these with your actual business routes.
|
|
3
|
+
|
|
4
|
+
// GET /api/demo/customer — any logged-in user
|
|
5
|
+
exports.customerArea = (req, res) => {
|
|
6
|
+
res.json({
|
|
7
|
+
message: `Hello ${req.user.name}! You reached the customer area.`,
|
|
8
|
+
access: "all authenticated users",
|
|
9
|
+
you: req.user,
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// GET /api/demo/manager — manager or admin only
|
|
14
|
+
exports.managerArea = (req, res) => {
|
|
15
|
+
res.json({
|
|
16
|
+
message: `Hello ${req.user.name}! You reached the manager area.`,
|
|
17
|
+
access: "manager + admin",
|
|
18
|
+
you: req.user,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// GET /api/demo/admin — admin only
|
|
23
|
+
exports.adminArea = (req, res) => {
|
|
24
|
+
res.json({
|
|
25
|
+
message: `Hello ${req.user.name}! You reached the admin area.`,
|
|
26
|
+
access: "admin only",
|
|
27
|
+
you: req.user,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// GET /api/demo/users — admin only: list all users
|
|
32
|
+
exports.listUsers = async (req, res) => {
|
|
33
|
+
const db = require("../db");
|
|
34
|
+
const [rows] = await db.query(
|
|
35
|
+
"SELECT id, name, email, role, created_at FROM users ORDER BY id"
|
|
36
|
+
);
|
|
37
|
+
res.json(rows);
|
|
38
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const mysql = require("mysql2/promise");
|
|
2
|
+
|
|
3
|
+
const pool = mysql.createPool({
|
|
4
|
+
host: process.env.DB_HOST || "localhost",
|
|
5
|
+
user: process.env.DB_USER || "root",
|
|
6
|
+
password: process.env.DB_PASSWORD || "root",
|
|
7
|
+
database: process.env.DB_NAME || "rbac_db",
|
|
8
|
+
waitForConnections: true,
|
|
9
|
+
connectionLimit: 10,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
module.exports = pool;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// With express-session there is no token to look up.
|
|
2
|
+
// The session middleware already parsed the cookie and populated req.session
|
|
3
|
+
// before this function runs — we just check what's in it.
|
|
4
|
+
|
|
5
|
+
function requireAuth(req, res, next) {
|
|
6
|
+
if (!req.session.user) {
|
|
7
|
+
return res.status(401).json({ error: "Not authenticated. Please log in." });
|
|
8
|
+
}
|
|
9
|
+
// Attach user to req so controllers can use req.user (same API as before)
|
|
10
|
+
req.user = req.session.user;
|
|
11
|
+
next();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Role guard — unchanged, still works exactly the same way
|
|
15
|
+
function requireRole(...roles) {
|
|
16
|
+
return (req, res, next) => {
|
|
17
|
+
if (!roles.includes(req.user.role)) {
|
|
18
|
+
return res.status(403).json({
|
|
19
|
+
error: "Access denied.",
|
|
20
|
+
yourRole: req.user.role,
|
|
21
|
+
required: roles,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
next();
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = { requireAuth, requireRole };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const express = require("express");
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const authController = require("../controllers/authController");
|
|
4
|
+
const { requireAuth } = require("../middleware/authMiddleware");
|
|
5
|
+
|
|
6
|
+
router.post("/login", authController.login);
|
|
7
|
+
router.post("/logout", requireAuth, authController.logout);
|
|
8
|
+
router.get("/me", requireAuth, authController.me);
|
|
9
|
+
|
|
10
|
+
module.exports = router;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const express = require("express");
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const demoController = require("../controllers/demoController");
|
|
4
|
+
const { requireAuth, requireRole } = require("../middleware/authMiddleware");
|
|
5
|
+
|
|
6
|
+
// Any logged-in user
|
|
7
|
+
router.get(
|
|
8
|
+
"/customer",
|
|
9
|
+
requireAuth,
|
|
10
|
+
demoController.customerArea
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
// Manager or Admin
|
|
14
|
+
router.get(
|
|
15
|
+
"/manager",
|
|
16
|
+
requireAuth,
|
|
17
|
+
requireRole("manager", "admin"),
|
|
18
|
+
demoController.managerArea
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Admin only
|
|
22
|
+
router.get(
|
|
23
|
+
"/admin",
|
|
24
|
+
requireAuth,
|
|
25
|
+
requireRole("admin"),
|
|
26
|
+
demoController.adminArea
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
// Admin only — lists all users
|
|
30
|
+
router.get(
|
|
31
|
+
"/users",
|
|
32
|
+
requireAuth,
|
|
33
|
+
requireRole("admin"),
|
|
34
|
+
demoController.listUsers
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
module.exports = router;
|