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.
@@ -0,0 +1,68 @@
1
+ //JWT - Token-based Authentication and Role-based Redirection User Story 1
2
+ // Language: JavaScript (Node.js + Express + JWT)
3
+ // Code Name: JWT Token-based Authentication with Role-based Redirection
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
+ /*
16
+ ==================== user.json (as variable) ====================
17
+ */
18
+ const users = [
19
+ {
20
+ username: "user@gmail.com",
21
+ password: "user@123",
22
+ role: "user",
23
+ },
24
+ {
25
+ username: "admin@gmail.com",
26
+ password: "admin@123",
27
+ role: "admin",
28
+ },
29
+ ];
30
+ /*
31
+ ===============================================================
32
+ */
33
+
34
+ // Login Route
35
+ app.post("/login", (req, res) => {
36
+ const { username, password } = req.body;
37
+
38
+ const user = users.find(
39
+ (u) => u.username === username && u.password === password
40
+ );
41
+
42
+ if (!user) return res.status(401).send("Invalid credentials");
43
+
44
+ const token = jwt.sign(
45
+ {
46
+ username: user.username,
47
+ role: user.role,
48
+ loginTime: Date.now(),
49
+ },
50
+ SECRET
51
+ );
52
+
53
+ res.cookie("token", token);
54
+
55
+ if (user.role === "admin") res.redirect("/adminhome");
56
+ else res.redirect("/userhome");
57
+ });
58
+
59
+ // Role-based Pages
60
+ app.get("/adminhome", (req, res) => {
61
+ res.send("Admin Home");
62
+ });
63
+
64
+ app.get("/userhome", (req, res) => {
65
+ res.send("User Home");
66
+ });
67
+
68
+ app.listen(3000);
@@ -0,0 +1,66 @@
1
+ //JWT - Token Expiration and Auto Logout User Story 3
2
+ // Language: JavaScript (Node.js + Express + JWT)
3
+ // Code Name: JWT Token Expiration and Auto Logout
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 (mock data) ===== */
16
+ const users = [
17
+ { username: "user@gmail.com", password: "user@123" },
18
+ { username: "admin@gmail.com", password: "admin@123" },
19
+ ];
20
+
21
+ /* ===== Login ===== */
22
+ app.post("/login", (req, res) => {
23
+ const { username, password } = req.body;
24
+
25
+ const user = users.find(
26
+ (u) => u.username === username && u.password === password
27
+ );
28
+
29
+ if (!user) return res.status(401).send("Invalid credentials");
30
+
31
+ const token = jwt.sign(
32
+ { username: user.username },
33
+ SECRET,
34
+ { expiresIn: "30m" } // 30 minutes expiry
35
+ );
36
+
37
+ res.cookie("token", token);
38
+ res.send("Logged In");
39
+ });
40
+
41
+ /* ===== JWT Middleware ===== */
42
+ const auth = (req, res, next) => {
43
+ const token = req.cookies.token;
44
+ if (!token) return res.redirect("/login");
45
+
46
+ jwt.verify(token, SECRET, (err, decoded) => {
47
+ if (err) {
48
+ res.clearCookie("token");
49
+ return res.redirect("/login?msg=Token expired");
50
+ }
51
+ req.user = decoded;
52
+ next();
53
+ });
54
+ };
55
+
56
+ /* ===== Protected Route ===== */
57
+ app.get("/profile", auth, (req, res) => {
58
+ res.send("Welcome " + req.user.username);
59
+ });
60
+
61
+ /* ===== Login Page ===== */
62
+ app.get("/login", (req, res) => {
63
+ res.send(req.query.msg || "Login Page");
64
+ });
65
+
66
+ app.listen(3000);
@@ -0,0 +1,55 @@
1
+ const express = require("express");
2
+ const multer = require("multer");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+
6
+ const app = express();
7
+ const PORT = 3000;
8
+
9
+ const uploadDir = path.join(__dirname, "uploads");
10
+ if (!fs.existsSync(uploadDir)) {
11
+ fs.mkdirSync(uploadDir);
12
+ }
13
+
14
+ const storage = multer.diskStorage({
15
+ destination: (req, file, cb) => {
16
+ cb(null, "uploads/");
17
+ },
18
+ filename: (req, file, cb) => {
19
+ cb(null, Date.now() + path.extname(file.originalname));
20
+ },
21
+ });
22
+
23
+ const fileFilter = (req, file, cb) => {
24
+ const allowedTypes = [".jpg", ".jpeg", ".png"];
25
+ const ext = path.extname(file.originalname).toLowerCase();
26
+ if (allowedTypes.includes(ext)) {
27
+ cb(null, true);
28
+ } else {
29
+ cb(new Error("Invalid file type. Only .jpg and .png allowed!"), false);
30
+ }
31
+ };
32
+
33
+ const upload = multer({ storage: storage, fileFilter: fileFilter });
34
+
35
+ app.post("/upload", upload.single("profilePic"), (req, res) => {
36
+ if (!req.file) {
37
+ return res.status(400).json({ error: "No file uploaded or invalid file type." });
38
+ }
39
+ res.json({
40
+ message: "File uploaded successfully!",
41
+ fileName: req.file.filename,
42
+ filePath: `/uploads/${req.file.filename}`,
43
+ });
44
+ });
45
+
46
+ app.use((err, req, res, next) => {
47
+ if (err instanceof multer.MulterError || err.message.includes("Invalid file type")) {
48
+ return res.status(400).json({ error: err.message });
49
+ }
50
+ next(err);
51
+ });
52
+
53
+ app.listen(PORT, () => {
54
+ console.log(`Server running at http://localhost:${PORT}`);
55
+ });
@@ -0,0 +1,266 @@
1
+ // app.js
2
+ const express = require('express');
3
+ const multer = require('multer');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+
7
+ const app = express();
8
+ const PORT = process.env.PORT || 3000;
9
+
10
+ /**
11
+ * Configuration
12
+ */
13
+ const UPLOAD_ROOT = path.join(__dirname, 'uploads');
14
+ const ALLOWED_EXT = ['.jpg', '.jpeg', '.png', '.pdf', '.docx']; // allowed extensions
15
+ const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB per file (global limit)
16
+
17
+ /**
18
+ * Helper: map fieldname to folder
19
+ */
20
+ function folderForField(fieldname) {
21
+ switch (fieldname) {
22
+ case 'profilePic': return 'profile_pics';
23
+ case 'docs': return 'documents';
24
+ case 'others': return 'others';
25
+ default: return 'others';
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Ensure base upload folders exist
31
+ */
32
+ ['profile_pics', 'documents', 'others'].forEach(sub => {
33
+ const p = path.join(UPLOAD_ROOT, sub);
34
+ if (!fs.existsSync(p)) fs.mkdirSync(p, { recursive: true });
35
+ });
36
+
37
+ /**
38
+ * Multer storage config: dynamic destination using userId param
39
+ */
40
+ const storage = multer.diskStorage({
41
+ destination: (req, file, cb) => {
42
+ // Expect userId in route parameter: /upload/:userId
43
+ const userId = req.params.userId;
44
+ if (!userId) return cb(new Error('Missing userId in params'));
45
+
46
+ const folder = folderForField(file.fieldname);
47
+ const dest = path.join(UPLOAD_ROOT, folder, String(userId));
48
+
49
+ // create directory if not exists
50
+ fs.mkdir(dest, { recursive: true }, (err) => {
51
+ cb(err, dest);
52
+ });
53
+ },
54
+
55
+ filename: (req, file, cb) => {
56
+ const userId = req.params.userId || 'unknown';
57
+ const timestamp = Date.now();
58
+ // sanitize originalname for safety (strip path)
59
+ const orig = path.basename(file.originalname);
60
+ const filename = `${file.fieldname}-${userId}-${timestamp}-${orig}`;
61
+ cb(null, filename);
62
+ }
63
+ });
64
+
65
+ /**
66
+ * File filter: allow only specific extensions/mimetypes.
67
+ * Reject with "Invalid file type".
68
+ */
69
+ function fileFilter(req, file, cb) {
70
+ const ext = path.extname(file.originalname).toLowerCase();
71
+ if (!ALLOWED_EXT.includes(ext)) {
72
+ // Provide an error that will be handled by our multer error handler
73
+ return cb(new multer.MulterError('LIMIT_UNEXPECTED_FILE', 'Invalid file type'));
74
+ }
75
+
76
+ // optional: further mime-type checks (basic)
77
+ const allowedMimes = [
78
+ 'image/jpeg', 'image/png',
79
+ 'application/pdf',
80
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' // .docx
81
+ ];
82
+ if (file.mimetype && !allowedMimes.includes(file.mimetype)) {
83
+ // still allow if extension was allowed (some clients provide different mimetype)
84
+ // but for safety, we will allow based on extension mainly.
85
+ // If you want to strictly check mimetype uncomment below:
86
+ // return cb(new multer.MulterError('LIMIT_UNEXPECTED_FILE', 'Invalid file type'));
87
+ }
88
+
89
+ cb(null, true);
90
+ }
91
+
92
+ /**
93
+ * Multer instance
94
+ * - single global fileSize limit (per-file)
95
+ * - fields: profilePic (1), docs (5), others (10) <-- adjust as needed
96
+ */
97
+ const upload = multer({
98
+ storage,
99
+ fileFilter,
100
+ limits: {
101
+ fileSize: MAX_FILE_SIZE
102
+ }
103
+ });
104
+
105
+ /**
106
+ * Middleware to catch multer errors and format responses
107
+ */
108
+ function multerErrorHandler(err, req, res, next) {
109
+ if (!err) return next();
110
+
111
+ if (err instanceof multer.MulterError) {
112
+ // Known multer errors
113
+ let message = err.message;
114
+
115
+ // Provide friendly messages for common codes:
116
+ if (err.code === 'LIMIT_FILE_SIZE') {
117
+ message = `File too large. Max size is ${MAX_FILE_SIZE} bytes.`;
118
+ } else if (err.code === 'LIMIT_UNEXPECTED_FILE') {
119
+ // We used this code to signal invalid file types too
120
+ if (err.field) {
121
+ message = `Unexpected field: ${err.field}`;
122
+ } else {
123
+ message = 'Invalid file type';
124
+ }
125
+ }
126
+
127
+ return res.status(400).json({ error: message });
128
+ }
129
+
130
+ // Non-multer error
131
+ return res.status(500).json({ error: err.message || 'Server Error' });
132
+ }
133
+
134
+ /**
135
+ * Route: POST /upload/:userId
136
+ * Accepts fields:
137
+ * - profilePic: single file
138
+ * - docs: array of files
139
+ * - others: array of files
140
+ *
141
+ * Responds with uploaded file paths grouped under uploaded.profilePic, docs, others
142
+ */
143
+ app.post(
144
+ '/upload/:userId',
145
+ // multer fields handling
146
+ (req, res, next) => {
147
+ const uploader = upload.fields([
148
+ { name: 'profilePic', maxCount: 1 },
149
+ { name: 'docs', maxCount: 10 },
150
+ { name: 'others', maxCount: 20 }
151
+ ]);
152
+ uploader(req, res, function (err) {
153
+ if (err) return next(err);
154
+ next();
155
+ });
156
+ },
157
+ (req, res) => {
158
+ const userId = req.params.userId;
159
+ const files = req.files || {};
160
+
161
+ // Build response paths relative to project root (so they are browsable under /uploads/)
162
+ const uploaded = {
163
+ profilePic: null,
164
+ docs: [],
165
+ others: []
166
+ };
167
+
168
+ if (files.profilePic && files.profilePic.length > 0) {
169
+ uploaded.profilePic = path.join(
170
+ 'uploads',
171
+ folderForField('profilePic'),
172
+ String(userId),
173
+ files.profilePic[0].filename
174
+ ).replace(/\\/g, '/');
175
+ }
176
+
177
+ if (files.docs && files.docs.length > 0) {
178
+ uploaded.docs = files.docs.map(f => path.join('uploads', folderForField('docs'), String(userId), f.filename).replace(/\\/g, '/'));
179
+ }
180
+
181
+ if (files.others && files.others.length > 0) {
182
+ uploaded.others = files.others.map(f => path.join('uploads', folderForField('others'), String(userId), f.filename).replace(/\\/g, '/'));
183
+ }
184
+
185
+ res.json({
186
+ message: 'Files uploaded successfully!',
187
+ uploaded
188
+ });
189
+ }
190
+ );
191
+
192
+ // Attach multer error handler (must be after the upload route)
193
+ app.use(multerErrorHandler);
194
+
195
+ /**
196
+ * Route: GET /files/:userId
197
+ * Lists all files for a userId across profile_pics, documents, others
198
+ */
199
+ app.get('/files/:userId', (req, res) => {
200
+ const userId = String(req.params.userId);
201
+ const folders = ['profile_pics', 'documents', 'others'];
202
+ const files = [];
203
+
204
+ folders.forEach(folder => {
205
+ const userFolder = path.join(UPLOAD_ROOT, folder, userId);
206
+ if (fs.existsSync(userFolder)) {
207
+ const list = fs.readdirSync(userFolder);
208
+ list.forEach(filename => {
209
+ files.push(path.join('uploads', folder, userId, filename).replace(/\\/g, '/'));
210
+ });
211
+ }
212
+ });
213
+
214
+ res.json({
215
+ userId,
216
+ files
217
+ });
218
+ });
219
+
220
+ /**
221
+ * Route: DELETE /delete/:userId/:filename
222
+ * Deletes the named file in any of the three subfolders for that user
223
+ */
224
+ app.delete('/delete/:userId/:filename', (req, res) => {
225
+ const { userId, filename } = req.params;
226
+ const folders = ['profile_pics', 'documents', 'others'];
227
+
228
+ let foundPath = null;
229
+ for (const folder of folders) {
230
+ const p = path.join(UPLOAD_ROOT, folder, String(userId), filename);
231
+ if (fs.existsSync(p)) {
232
+ foundPath = p;
233
+ break;
234
+ }
235
+ }
236
+
237
+ if (!foundPath) {
238
+ return res.status(404).json({ error: 'File not found' });
239
+ }
240
+
241
+ fs.unlink(foundPath, (err) => {
242
+ if (err) {
243
+ console.error('Error deleting file:', err);
244
+ return res.status(500).json({ error: 'Failed to delete file' });
245
+ }
246
+ return res.json({ message: 'File deleted successfully!' });
247
+ });
248
+ });
249
+
250
+ /**
251
+ * Serve uploaded files statically so they are accessible via browser:
252
+ * e.g. http://localhost:3000/uploads/profile_pics/102/profilePic-102-...png
253
+ */
254
+ app.use('/uploads', express.static(UPLOAD_ROOT));
255
+
256
+ /**
257
+ * Simple health route
258
+ */
259
+ app.get('/', (req, res) => {
260
+ res.send('FileManager API is running. Use POST /upload/:userId, GET /files/:userId, DELETE /delete/:userId/:filename');
261
+ });
262
+
263
+ /**
264
+ * Start
265
+ */
266
+ app.listen(PORT, () => console.log(`FileManager listening on http://localhost:${PORT}`));
@@ -0,0 +1,62 @@
1
+ const express = require("express");
2
+ const multer = require("multer");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+
6
+ const app = express();
7
+ const PORT = 3000;
8
+
9
+ const uploadDir = path.join(__dirname, "uploads/products");
10
+ if (!fs.existsSync(uploadDir)) {
11
+ fs.mkdirSync(uploadDir, { recursive: true });
12
+ }
13
+
14
+ const storage = multer.diskStorage({
15
+ destination: (req, file, cb) => {
16
+ cb(null, "uploads/products/");
17
+ },
18
+ filename: (req, file, cb) => {
19
+ cb(null, Date.now() + path.extname(file.originalname));
20
+ },
21
+ });
22
+
23
+ const fileFilter = (req, file, cb) => {
24
+ const allowedTypes = [".jpg", ".jpeg", ".png"];
25
+ const ext = path.extname(file.originalname).toLowerCase();
26
+ if (allowedTypes.includes(ext)) {
27
+ cb(null, true);
28
+ } else {
29
+ cb(new Error("Invalid file type. Only .jpg and .png allowed!"), false);
30
+ }
31
+ };
32
+
33
+ const upload = multer({
34
+ storage: storage,
35
+ fileFilter: fileFilter,
36
+ limits: { fileSize: 2 * 1024 * 1024 },
37
+ });
38
+
39
+ app.post("/upload-product", upload.single("productImage"), (req, res) => {
40
+ if (!req.file) {
41
+ return res.status(400).json({ error: "No file uploaded or invalid file type." });
42
+ }
43
+ res.json({
44
+ message: "File uploaded successfully!",
45
+ filePath: `/uploads/products/${req.file.filename}`,
46
+ fileSize: `${(req.file.size / 1024).toFixed(2)} KB`,
47
+ });
48
+ });
49
+
50
+ app.use((err, req, res, next) => {
51
+ if (err.code === "LIMIT_FILE_SIZE") {
52
+ return res.status(400).json({ error: "File too large. Max size is 2 MB." });
53
+ }
54
+ if (err instanceof multer.MulterError || err.message.includes("Invalid file type")) {
55
+ return res.status(400).json({ error: err.message });
56
+ }
57
+ next(err);
58
+ });
59
+
60
+ app.listen(PORT, () => {
61
+ console.log(`Server running at http://localhost:${PORT}`);
62
+ });
@@ -0,0 +1,70 @@
1
+ const express = require("express");
2
+ const multer = require("multer");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+
6
+ const app = express();
7
+ const PORT = 3000;
8
+
9
+ app.use(express.urlencoded({ extended: true }));
10
+ app.use(express.json());
11
+
12
+ const uploadDir = path.join(__dirname, "uploads/resumes");
13
+ if (!fs.existsSync(uploadDir)) {
14
+ fs.mkdirSync(uploadDir, { recursive: true });
15
+ }
16
+
17
+ const storage = multer.diskStorage({
18
+ destination: (req, file, cb) => {
19
+ cb(null, "uploads/resumes/");
20
+ },
21
+ filename: (req, file, cb) => {
22
+ cb(null, Date.now() + path.extname(file.originalname));
23
+ },
24
+ });
25
+
26
+ const fileFilter = (req, file, cb) => {
27
+ const ext = path.extname(file.originalname).toLowerCase();
28
+ if (ext === ".pdf") {
29
+ cb(null, true);
30
+ } else {
31
+ cb(new Error("Invalid file type. Only .pdf allowed!"), false);
32
+ }
33
+ };
34
+
35
+ const upload = multer({ storage: storage, fileFilter: fileFilter });
36
+
37
+ app.post("/submit", upload.single("resume"), (req, res) => {
38
+ const { name, email, phone } = req.body;
39
+ if (!req.file) {
40
+ return res.status(400).json({ error: "No resume uploaded or invalid file type." });
41
+ }
42
+ const formData = {
43
+ name,
44
+ email,
45
+ phone,
46
+ resumePath: `/uploads/resumes/${req.file.filename}`,
47
+ };
48
+ const dbPath = path.join(__dirname, "formData.json");
49
+ let existingData = [];
50
+ if (fs.existsSync(dbPath)) {
51
+ existingData = JSON.parse(fs.readFileSync(dbPath));
52
+ }
53
+ existingData.push(formData);
54
+ fs.writeFileSync(dbPath, JSON.stringify(existingData, null, 2));
55
+ res.json({
56
+ message: "Form submitted successfully!",
57
+ data: formData,
58
+ });
59
+ });
60
+
61
+ app.use((err, req, res, next) => {
62
+ if (err instanceof multer.MulterError || err.message.includes("Invalid file type")) {
63
+ return res.status(400).json({ error: err.message });
64
+ }
65
+ next(err);
66
+ });
67
+
68
+ app.listen(PORT, () => {
69
+ console.log(`Server running at http://localhost:${PORT}`);
70
+ });
@@ -0,0 +1,57 @@
1
+ const express = require("express");
2
+ const multer = require("multer");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+
6
+ const app = express();
7
+ const PORT = 3000;
8
+
9
+ const uploadDir = path.join(__dirname, "uploads/gallery");
10
+ if (!fs.existsSync(uploadDir)) {
11
+ fs.mkdirSync(uploadDir, { recursive: true });
12
+ }
13
+
14
+ const storage = multer.diskStorage({
15
+ destination: (req, file, cb) => {
16
+ cb(null, "uploads/gallery/");
17
+ },
18
+ filename: (req, file, cb) => {
19
+ cb(null, Date.now() + path.extname(file.originalname));
20
+ },
21
+ });
22
+
23
+ const fileFilter = (req, file, cb) => {
24
+ const allowedTypes = [".jpg", ".jpeg", ".png"];
25
+ const ext = path.extname(file.originalname).toLowerCase();
26
+ if (allowedTypes.includes(ext)) {
27
+ cb(null, true);
28
+ } else {
29
+ cb(new Error("Invalid file type. Only .jpg, .jpeg, and .png allowed!"), false);
30
+ }
31
+ };
32
+
33
+ const upload = multer({ storage: storage, fileFilter: fileFilter });
34
+
35
+ app.post("/upload-multiple", upload.array("images", 5), (req, res) => {
36
+ if (!req.files || req.files.length === 0) {
37
+ return res.status(400).json({ error: "No files uploaded or invalid file type." });
38
+ }
39
+ if (req.files.length > 5) {
40
+ return res.status(400).json({ error: "You can upload a maximum of 5 files." });
41
+ }
42
+ res.json({
43
+ message: "Files uploaded successfully!",
44
+ fileNames: req.files.map((file) => file.filename),
45
+ });
46
+ });
47
+
48
+ app.use((err, req, res, next) => {
49
+ if (err instanceof multer.MulterError || err.message.includes("Invalid file type")) {
50
+ return res.status(400).json({ error: err.message });
51
+ }
52
+ next(err);
53
+ });
54
+
55
+ app.listen(PORT, () => {
56
+ console.log(`Server running at http://localhost:${PORT}`);
57
+ });