espresss 1.0.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/ETe/EJS/Student-dashboard.ejs +37 -0
- package/ETe/EJS/Student-details.ejs +34 -0
- package/ETe/EJS/dynamic_user.ejs +7 -0
- package/ETe/EJS/error-handling.ejs +19 -0
- package/ETe/EJS/include-header.ejs +29 -0
- package/ETe/EJS/pagination-system.ejs +77 -0
- package/ETe/Express Session/admin panel.js +68 -0
- package/ETe/Express Session/basic authentication.js +83 -0
- package/ETe/Express Session/session expiration.js +42 -0
- package/ETe/Express Session/session persistance.js +83 -0
- package/ETe/JWT/monitoring panel.js +87 -0
- package/ETe/JWT/protected profile.js +66 -0
- package/ETe/JWT/token based.js +68 -0
- package/ETe/JWT/token expiration.js +66 -0
- package/ETe/Multer/ImageUpload.js +55 -0
- package/ETe/Multer/file management api.js +266 -0
- package/ETe/Multer/file size and validation.js +62 -0
- package/ETe/Multer/from data.js +70 -0
- package/ETe/Multer/multiple.js +57 -0
- package/ete 2/mongo db/company-systsem.js +127 -0
- package/ete 2/mongo db/student-management.js +65 -0
- package/ete 2/mongoose/e-commerce.js +217 -0
- package/ete 2/mongoose/employee.js +99 -0
- package/ete 2/mongoose/event-management.js +87 -0
- package/package.json +13 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<h2><%= student.name %></h2>
|
|
2
|
+
<p><%= student.email %></p>
|
|
3
|
+
|
|
4
|
+
<% if (student.role === "admin") { %>
|
|
5
|
+
<span>★ Admin Access</span>
|
|
6
|
+
<% } %>
|
|
7
|
+
|
|
8
|
+
<hr>
|
|
9
|
+
|
|
10
|
+
<h3>Courses</h3>
|
|
11
|
+
|
|
12
|
+
<% if (courses.length === 0) { %>
|
|
13
|
+
<p>No courses enrolled yet</p>
|
|
14
|
+
<% } else { %>
|
|
15
|
+
<ul>
|
|
16
|
+
<% courses.forEach(c => { %>
|
|
17
|
+
<li>
|
|
18
|
+
<%= c.title %> -
|
|
19
|
+
<span style="color:
|
|
20
|
+
<%= c.grade === 'A' ? 'green' :
|
|
21
|
+
(c.grade === 'B' || c.grade === 'C') ? 'blue' : 'red' %>">
|
|
22
|
+
<%= c.grade %>
|
|
23
|
+
</span>
|
|
24
|
+
</li>
|
|
25
|
+
<% }) %>
|
|
26
|
+
</ul>
|
|
27
|
+
<% } %>
|
|
28
|
+
|
|
29
|
+
<hr>
|
|
30
|
+
|
|
31
|
+
<!-- Escaped -->
|
|
32
|
+
<p><%= notice %></p>
|
|
33
|
+
|
|
34
|
+
<!-- Unescaped -->
|
|
35
|
+
<p><%- notice %></p>
|
|
36
|
+
|
|
37
|
+
<%- include('footer') %>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<h1>Student Report</h1>
|
|
2
|
+
|
|
3
|
+
<table border="1">
|
|
4
|
+
<tr>
|
|
5
|
+
<th>Name</th>
|
|
6
|
+
<th>Math</th>
|
|
7
|
+
<th>Science</th>
|
|
8
|
+
<th>English</th>
|
|
9
|
+
</tr>
|
|
10
|
+
|
|
11
|
+
<% if (students && students.length > 0) { %>
|
|
12
|
+
<% students.forEach(function (s) { %>
|
|
13
|
+
<tr>
|
|
14
|
+
<td><%= s.name %></td>
|
|
15
|
+
|
|
16
|
+
<td style="color: <%= s.marks.math < 70 ? 'red' : 'black' %>">
|
|
17
|
+
<%= s.marks.math %>
|
|
18
|
+
</td>
|
|
19
|
+
|
|
20
|
+
<td style="color: <%= s.marks.science < 70 ? 'red' : 'black' %>">
|
|
21
|
+
<%= s.marks.science %>
|
|
22
|
+
</td>
|
|
23
|
+
|
|
24
|
+
<td style="color: <%= s.marks.english < 70 ? 'red' : 'black' %>">
|
|
25
|
+
<%= s.marks.english %>
|
|
26
|
+
</td>
|
|
27
|
+
</tr>
|
|
28
|
+
<% }) %>
|
|
29
|
+
<% } else { %>
|
|
30
|
+
<tr>
|
|
31
|
+
<td colspan="4">No student data available</td>
|
|
32
|
+
</tr>
|
|
33
|
+
<% } %>
|
|
34
|
+
</table>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//EJS - Error Handling with Custom Error Templates
|
|
2
|
+
<h1>Error <%= errorData.statusCode %></h1>
|
|
3
|
+
|
|
4
|
+
<p><strong>Message:</strong> <%= errorData.message %></p>
|
|
5
|
+
<p><strong>Time:</strong> <%= errorData.timestamp %></p>
|
|
6
|
+
<p><strong>URL:</strong> <%= errorData.requestUrl %></p>
|
|
7
|
+
|
|
8
|
+
<% if (errorData.errorType === "NOT_FOUND") { %>
|
|
9
|
+
<h3>Page not found</h3>
|
|
10
|
+
<p>Go back to Home Page</p>
|
|
11
|
+
|
|
12
|
+
<% } else if (errorData.errorType === "SERVER_ERROR") { %>
|
|
13
|
+
<h3>Internal server error</h3>
|
|
14
|
+
<p>Try again later</p>
|
|
15
|
+
|
|
16
|
+
<% } else if (errorData.errorType === "VALIDATION") { %>
|
|
17
|
+
<h3>Please check your form inputs</h3>
|
|
18
|
+
<p>Fix the highlighted form inputs and resubmit</p>
|
|
19
|
+
<% } %>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//EJS - Include Header and Footer Partials
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>My Website</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
|
|
11
|
+
<% /* ===== Header Partial (partials/header.ejs) ===== */ %>
|
|
12
|
+
<header>
|
|
13
|
+
<h1>My Website</h1>
|
|
14
|
+
<hr>
|
|
15
|
+
</header>
|
|
16
|
+
|
|
17
|
+
<% /* ===== Main Content (main.ejs) ===== */ %>
|
|
18
|
+
<main>
|
|
19
|
+
<h2>Welcome to our site!</h2>
|
|
20
|
+
</main>
|
|
21
|
+
|
|
22
|
+
<% /* ===== Footer Partial (partials/footer.ejs) ===== */ %>
|
|
23
|
+
<footer>
|
|
24
|
+
<hr>
|
|
25
|
+
<p>© 2025 My Website</p>
|
|
26
|
+
</footer>
|
|
27
|
+
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ======================================================
|
|
2
|
+
// Language: JavaScript (Node.js + Express + EJS)
|
|
3
|
+
// Code Name: EJS Pagination System (Single File Version)
|
|
4
|
+
// ======================================================
|
|
5
|
+
|
|
6
|
+
// ===================== data.json ======================
|
|
7
|
+
// (Create a separate file named data.json and paste this)
|
|
8
|
+
|
|
9
|
+
[
|
|
10
|
+
{ "id": 1, "name": "Product 1" },
|
|
11
|
+
{ "id": 2, "name": "Product 2" },
|
|
12
|
+
{ "id": 3, "name": "Product 3" },
|
|
13
|
+
{ "id": 4, "name": "Product 4" },
|
|
14
|
+
{ "id": 5, "name": "Product 5" },
|
|
15
|
+
{ "id": 6, "name": "Product 6" },
|
|
16
|
+
{ "id": 7, "name": "Product 7" },
|
|
17
|
+
{ "id": 8, "name": "Product 8" },
|
|
18
|
+
{ "id": 9, "name": "Product 9" },
|
|
19
|
+
{ "id": 10, "name": "Product 10" },
|
|
20
|
+
{ "id": 11, "name": "Product 11" },
|
|
21
|
+
{ "id": 12, "name": "Product 12" },
|
|
22
|
+
{ "id": 13, "name": "Product 13" },
|
|
23
|
+
{ "id": 14, "name": "Product 14" },
|
|
24
|
+
{ "id": 15, "name": "Product 15" },
|
|
25
|
+
{ "id": 16, "name": "Product 16" },
|
|
26
|
+
{ "id": 17, "name": "Product 17" },
|
|
27
|
+
{ "id": 18, "name": "Product 18" },
|
|
28
|
+
{ "id": 19, "name": "Product 19" },
|
|
29
|
+
{ "id": 20, "name": "Product 20" }
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
// ===================== server.js ======================
|
|
33
|
+
// (Create a separate file named server.js and paste this)
|
|
34
|
+
|
|
35
|
+
const express = require("express");
|
|
36
|
+
const fs = require("fs");
|
|
37
|
+
const app = express();
|
|
38
|
+
|
|
39
|
+
app.set("view engine", "ejs");
|
|
40
|
+
|
|
41
|
+
app.get("/", (req, res) => {
|
|
42
|
+
// Read JSON on every request (as required)
|
|
43
|
+
const data = JSON.parse(fs.readFileSync("data.json"));
|
|
44
|
+
|
|
45
|
+
const page = +req.query.page || 1;
|
|
46
|
+
const limit = 5;
|
|
47
|
+
|
|
48
|
+
const totalPages = Math.ceil(data.length / limit);
|
|
49
|
+
const products = data.slice((page - 1) * limit, page * limit);
|
|
50
|
+
|
|
51
|
+
res.render("index", { products, page, totalPages });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
app.listen(3000);
|
|
55
|
+
|
|
56
|
+
// ===================== views/index.ejs ======================
|
|
57
|
+
// (Create views/index.ejs and paste this)
|
|
58
|
+
|
|
59
|
+
<h2>Products</h2>
|
|
60
|
+
|
|
61
|
+
<ul>
|
|
62
|
+
<% products.forEach(p => { %>
|
|
63
|
+
<li><%= p.name %></li>
|
|
64
|
+
<% }) %>
|
|
65
|
+
</ul>
|
|
66
|
+
|
|
67
|
+
<p>Page <%= page %> of <%= totalPages %></p>
|
|
68
|
+
|
|
69
|
+
<a href="/?page=<%= page - 1 %>"
|
|
70
|
+
<%= page === 1 ? 'style="pointer-events:none"' : '' %>>
|
|
71
|
+
Previous
|
|
72
|
+
</a>
|
|
73
|
+
|
|
74
|
+
<a href="/?page=<%= page + 1 %>"
|
|
75
|
+
<%= page === totalPages ? 'style="pointer-events:none"' : '' %>>
|
|
76
|
+
Next
|
|
77
|
+
</a>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//Express Session - Role-Based Concurrent Session Management with Admin Panel - User Story 4
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const session = require('express-session');
|
|
4
|
+
const app = express();
|
|
5
|
+
|
|
6
|
+
const sessionStore = new session.MemoryStore();
|
|
7
|
+
|
|
8
|
+
app.use(session({
|
|
9
|
+
secret: 'your-secret-key',
|
|
10
|
+
resave: false,
|
|
11
|
+
saveUninitialized: false,
|
|
12
|
+
store: sessionStore,
|
|
13
|
+
cookie: {
|
|
14
|
+
maxAge: 30 * 60 * 1000,
|
|
15
|
+
httpOnly: true,
|
|
16
|
+
secure: false
|
|
17
|
+
}
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
function authChecker(role) {
|
|
21
|
+
return (req, res, next) => {
|
|
22
|
+
if (req.session.user && req.session.user.role === role) {
|
|
23
|
+
return next();
|
|
24
|
+
}
|
|
25
|
+
res.status(403).send('Access denied');
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
app.post('/login', (req, res) => {
|
|
30
|
+
const { username, role } = req.query;
|
|
31
|
+
req.session.user = { username, role, loginTime: new Date() };
|
|
32
|
+
res.send('Logged in');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
app.post('/logout', (req, res) => {
|
|
36
|
+
req.session.destroy(() => {
|
|
37
|
+
res.send('Logged out');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
app.get('/dashboard', (req, res) => {
|
|
42
|
+
if (req.session.user) {
|
|
43
|
+
res.send(`Welcome ${req.session.user.username}, role: ${req.session.user.role}`);
|
|
44
|
+
} else {
|
|
45
|
+
res.status(401).send('Unauthorized');
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
app.get('/admin/sessions', authChecker('admin'), (req, res) => {
|
|
50
|
+
const sessions = [];
|
|
51
|
+
sessionStore.all((err, allSessions) => {
|
|
52
|
+
if (err) return res.status(500).send('Error fetching sessions');
|
|
53
|
+
for (let sid in allSessions) {
|
|
54
|
+
const s = allSessions[sid];
|
|
55
|
+
if (s.user) {
|
|
56
|
+
sessions.push({
|
|
57
|
+
username: s.user.username,
|
|
58
|
+
role: s.user.role,
|
|
59
|
+
loginTime: s.user.loginTime,
|
|
60
|
+
expirationTime: new Date(s.cookie.expires)
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
res.json(sessions);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//Express Session - Basic Authentication and Role-based Redirection - User Story 1
|
|
2
|
+
const express = require("express");
|
|
3
|
+
const session = require("express-session");
|
|
4
|
+
const bodyParser = require("body-parser");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
const app = express();
|
|
9
|
+
const PORT = 3000;
|
|
10
|
+
|
|
11
|
+
app.use(bodyParser.urlencoded({ extended: true }));
|
|
12
|
+
app.use(bodyParser.json());
|
|
13
|
+
|
|
14
|
+
app.use(
|
|
15
|
+
session({
|
|
16
|
+
secret: "secretKey",
|
|
17
|
+
resave: false,
|
|
18
|
+
saveUninitialized: true,
|
|
19
|
+
cookie: { maxAge: 60000 },
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const usersPath = path.join(__dirname, "user.json");
|
|
24
|
+
let users = [];
|
|
25
|
+
if (fs.existsSync(usersPath)) {
|
|
26
|
+
users = JSON.parse(fs.readFileSync(usersPath));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
app.get("/login", (req, res) => {
|
|
30
|
+
res.send(`
|
|
31
|
+
<form method="POST" action="/login">
|
|
32
|
+
<input type="text" name="username" placeholder="Username" required />
|
|
33
|
+
<input type="password" name="password" placeholder="Password" required />
|
|
34
|
+
<button type="submit">Login</button>
|
|
35
|
+
</form>
|
|
36
|
+
`);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
app.post("/login", (req, res) => {
|
|
40
|
+
const { username, password } = req.body;
|
|
41
|
+
const user = users.find(
|
|
42
|
+
(u) => u.username === username && u.password === password
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
if (!user) {
|
|
46
|
+
return res.status(401).send("Invalid username or password");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
req.session.user = {
|
|
50
|
+
username: user.username,
|
|
51
|
+
role: user.role,
|
|
52
|
+
loginTime: new Date(),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
if (user.role === "admin") {
|
|
56
|
+
return res.redirect("/adminhome");
|
|
57
|
+
} else {
|
|
58
|
+
return res.redirect("/userhome");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
app.get("/adminhome", (req, res) => {
|
|
63
|
+
if (!req.session.user || req.session.user.role !== "admin") {
|
|
64
|
+
return res.status(403).send("Access denied");
|
|
65
|
+
}
|
|
66
|
+
res.send(`Welcome Admin: ${req.session.user.username}, Logged in at ${req.session.user.loginTime}`);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
app.get("/userhome", (req, res) => {
|
|
70
|
+
if (!req.session.user || req.session.user.role !== "user") {
|
|
71
|
+
return res.status(403).send("Access denied");
|
|
72
|
+
}
|
|
73
|
+
res.send(`Welcome User: ${req.session.user.username}, Logged in at ${req.session.user.loginTime}`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
app.get("/logout", (req, res) => {
|
|
77
|
+
req.session.destroy();
|
|
78
|
+
res.send("Logged out successfully");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
app.listen(PORT, () => {
|
|
82
|
+
console.log(`Server running at http://localhost:${PORT}`);
|
|
83
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//Express Session - Session Expiration and Cleanup - User Story 3
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const session = require('express-session');
|
|
4
|
+
const app = express();
|
|
5
|
+
|
|
6
|
+
app.use(session({
|
|
7
|
+
secret: 'your-secret-key',
|
|
8
|
+
resave: false,
|
|
9
|
+
saveUninitialized: false,
|
|
10
|
+
cookie: {
|
|
11
|
+
maxAge: 30 * 60 * 1000,
|
|
12
|
+
httpOnly: true,
|
|
13
|
+
secure: false
|
|
14
|
+
}
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
function sessionChecker(req, res, next) {
|
|
18
|
+
if (req.session.user) {
|
|
19
|
+
return next();
|
|
20
|
+
} else {
|
|
21
|
+
req.session.destroy(() => {
|
|
22
|
+
res.status(401).send('Your session has expired. Please log in again.');
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
app.get('/dashboard', sessionChecker, (req, res) => {
|
|
28
|
+
res.send(`Welcome back, ${req.session.user.username}`);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
app.post('/login', (req, res) => {
|
|
32
|
+
req.session.user = { username: 'Aryan' };
|
|
33
|
+
res.send('Logged in!');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
app.post('/logout', (req, res) => {
|
|
37
|
+
req.session.destroy(() => {
|
|
38
|
+
res.send('Logged out successfully.');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//Express Session - Session Persistence and Profile Access - User Story 2
|
|
2
|
+
const express = require("express");
|
|
3
|
+
const session = require("express-session");
|
|
4
|
+
const bodyParser = require("body-parser");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
const app = express();
|
|
9
|
+
const PORT = 3000;
|
|
10
|
+
|
|
11
|
+
app.use(bodyParser.urlencoded({ extended: true }));
|
|
12
|
+
app.use(bodyParser.json());
|
|
13
|
+
|
|
14
|
+
app.use(
|
|
15
|
+
session({
|
|
16
|
+
secret: "secretKey",
|
|
17
|
+
resave: false,
|
|
18
|
+
saveUninitialized: true,
|
|
19
|
+
cookie: { maxAge: 600000 },
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const usersPath = path.join(__dirname, "user.json");
|
|
24
|
+
let users = [];
|
|
25
|
+
if (fs.existsSync(usersPath)) {
|
|
26
|
+
users = JSON.parse(fs.readFileSync(usersPath));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
app.get("/login", (req, res) => {
|
|
30
|
+
res.send(`
|
|
31
|
+
<form method="POST" action="/login">
|
|
32
|
+
<input type="text" name="username" placeholder="Username" required />
|
|
33
|
+
<input type="password" name="password" placeholder="Password" required />
|
|
34
|
+
<button type="submit">Login</button>
|
|
35
|
+
</form>
|
|
36
|
+
`);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
app.post("/login", (req, res) => {
|
|
40
|
+
const { username, password } = req.body;
|
|
41
|
+
const user = users.find(
|
|
42
|
+
(u) => u.username === username && u.password === password
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
if (!user) {
|
|
46
|
+
return res.status(401).send("Invalid username or password");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
req.session.user = {
|
|
50
|
+
username: user.username,
|
|
51
|
+
role: user.role,
|
|
52
|
+
loginTime: Date.now(),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
res.redirect("/profile");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
function isAuthenticated(req, res, next) {
|
|
59
|
+
if (req.session.user) {
|
|
60
|
+
return next();
|
|
61
|
+
}
|
|
62
|
+
res.redirect("/login");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
app.get("/profile", isAuthenticated, (req, res) => {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
const timeSinceLogin = Math.floor((now - req.session.user.loginTime) / 1000);
|
|
68
|
+
res.send(`
|
|
69
|
+
<h1>Profile Page</h1>
|
|
70
|
+
<p>Username: ${req.session.user.username}</p>
|
|
71
|
+
<p>Time since login: ${timeSinceLogin} seconds</p>
|
|
72
|
+
<p>Session ID: ${req.sessionID}</p>
|
|
73
|
+
`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
app.get("/logout", (req, res) => {
|
|
77
|
+
req.session.destroy();
|
|
78
|
+
res.send("Logged out successfully");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
app.listen(PORT, () => {
|
|
82
|
+
console.log(`Server running at http://localhost:${PORT}`);
|
|
83
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//JWT - Admin Panel for Monitoring Active User Tokens User Story 4
|
|
2
|
+
// Language: JavaScript (Node.js + Express + JWT)
|
|
3
|
+
// Code Name: JWT Admin Panel for Monitoring Active User Tokens
|
|
4
|
+
|
|
5
|
+
const express = require("express");
|
|
6
|
+
const jwt = require("jsonwebtoken");
|
|
7
|
+
const cookieParser = require("cookie-parser");
|
|
8
|
+
|
|
9
|
+
const app = express();
|
|
10
|
+
app.use(express.json());
|
|
11
|
+
app.use(cookieParser());
|
|
12
|
+
|
|
13
|
+
const SECRET = "secretkey";
|
|
14
|
+
|
|
15
|
+
/* ===== Users ===== */
|
|
16
|
+
const users = [
|
|
17
|
+
{ username: "user@gmail.com", password: "user@123", role: "user" },
|
|
18
|
+
{ username: "admin@gmail.com", password: "admin@123", role: "admin" },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
/* ===== Active Tokens Store ===== */
|
|
22
|
+
const activeTokens = [];
|
|
23
|
+
|
|
24
|
+
/* ===== Login ===== */
|
|
25
|
+
app.post("/login", (req, res) => {
|
|
26
|
+
const { username, password } = req.body;
|
|
27
|
+
|
|
28
|
+
const user = users.find(
|
|
29
|
+
(u) => u.username === username && u.password === password
|
|
30
|
+
);
|
|
31
|
+
if (!user) return res.status(401).send("Invalid credentials");
|
|
32
|
+
|
|
33
|
+
const token = jwt.sign(
|
|
34
|
+
{ username: user.username, role: user.role },
|
|
35
|
+
SECRET,
|
|
36
|
+
{ expiresIn: "30m" }
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const decoded = jwt.decode(token);
|
|
40
|
+
|
|
41
|
+
activeTokens.push({
|
|
42
|
+
username: user.username,
|
|
43
|
+
issuedAt: decoded.iat,
|
|
44
|
+
expiresAt: decoded.exp,
|
|
45
|
+
token,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
res.cookie("token", token);
|
|
49
|
+
res.send("Logged In");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
/* ===== Auth Middleware ===== */
|
|
53
|
+
const auth = (req, res, next) => {
|
|
54
|
+
const token = req.cookies.token;
|
|
55
|
+
if (!token) return res.redirect("/login");
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
req.user = jwt.verify(token, SECRET);
|
|
59
|
+
next();
|
|
60
|
+
} catch {
|
|
61
|
+
res.redirect("/login");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/* ===== Admin Only Middleware ===== */
|
|
66
|
+
const adminOnly = (req, res, next) => {
|
|
67
|
+
if (req.user.role !== "admin") return res.status(403).send("Access Denied");
|
|
68
|
+
next();
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/* ===== Admin Panel ===== */
|
|
72
|
+
app.get("/admin-panel", auth, adminOnly, (req, res) => {
|
|
73
|
+
res.json(
|
|
74
|
+
activeTokens.map((t) => ({
|
|
75
|
+
username: t.username,
|
|
76
|
+
issuedAt: new Date(t.issuedAt * 1000),
|
|
77
|
+
expiresAt: new Date(t.expiresAt * 1000),
|
|
78
|
+
}))
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/* ===== Login Page Placeholder ===== */
|
|
83
|
+
app.get("/login", (req, res) => {
|
|
84
|
+
res.send("Login Page");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
app.listen(3000);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Language: JavaScript (Node.js + Express + JWT)
|
|
2
|
+
// Code Name: JWT Protected Profile Route
|
|
3
|
+
|
|
4
|
+
const express = require("express");
|
|
5
|
+
const jwt = require("jsonwebtoken");
|
|
6
|
+
const cookieParser = require("cookie-parser");
|
|
7
|
+
|
|
8
|
+
const app = express();
|
|
9
|
+
app.use(express.json());
|
|
10
|
+
app.use(cookieParser());
|
|
11
|
+
|
|
12
|
+
const SECRET = "secretkey";
|
|
13
|
+
|
|
14
|
+
/* ===== Users (from user.json as variable) ===== */
|
|
15
|
+
const users = [
|
|
16
|
+
{ username: "user@gmail.com", password: "user@123", role: "user" },
|
|
17
|
+
{ username: "admin@gmail.com", password: "admin@123", role: "admin" },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
/* ===== Login ===== */
|
|
21
|
+
app.post("/login", (req, res) => {
|
|
22
|
+
const { username, password } = req.body;
|
|
23
|
+
|
|
24
|
+
const user = users.find(
|
|
25
|
+
(u) => u.username === username && u.password === password
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (!user) return res.status(401).send("Invalid credentials");
|
|
29
|
+
|
|
30
|
+
const token = jwt.sign(
|
|
31
|
+
{ username: user.username, loginTime: Date.now() },
|
|
32
|
+
SECRET
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
res.cookie("token", token);
|
|
36
|
+
res.send("Logged In");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/* ===== JWT Middleware ===== */
|
|
40
|
+
const auth = (req, res, next) => {
|
|
41
|
+
const token = req.cookies.token;
|
|
42
|
+
if (!token) return res.redirect("/login");
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
req.user = jwt.verify(token, SECRET);
|
|
46
|
+
next();
|
|
47
|
+
} catch {
|
|
48
|
+
res.redirect("/login");
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/* ===== Protected Profile ===== */
|
|
53
|
+
app.get("/profile", auth, (req, res) => {
|
|
54
|
+
res.json({
|
|
55
|
+
username: req.user.username,
|
|
56
|
+
timeSinceLogin: Date.now() - req.user.loginTime,
|
|
57
|
+
token: req.cookies.token,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/* ===== Login Page Placeholder ===== */
|
|
62
|
+
app.get("/login", (req, res) => {
|
|
63
|
+
res.send("Login Page");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
app.listen(3000);
|