Initial commit

This commit is contained in:
2026-09-16 17:36:46 +05:30
commit c9f429d123
117 changed files with 14145 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const { errorResponse } = require('../utils/apiResponse');
const protect = async (req, res, next) => {
let token;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
token = req.headers.authorization.split(' ')[1];
}
if (!token) {
return errorResponse(res, 'Not authorized to access this route', [], 401);
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'guitar_ecommerce_super_secret_jwt_key_2026');
req.user = await User.findById(decoded.id).select('-password');
if (!req.user) {
return errorResponse(res, 'User account no longer exists', [], 401);
}
next();
} catch (error) {
return errorResponse(res, 'Not authorized, token failed or expired', [], 401);
}
};
const authorize = (...roles) => {
return (req, res, next) => {
if (!req.user || !roles.includes(req.user.role)) {
return errorResponse(
res,
`User role '${req.user ? req.user.role : 'Guest'}' is not authorized to access this resource`,
[],
403
);
}
next();
};
};
module.exports = { protect, authorize };

View File

@@ -0,0 +1,31 @@
const { errorResponse } = require('../utils/apiResponse');
const errorHandler = (err, req, res, next) => {
let statusCode = err.statusCode || res.statusCode === 200 ? 500 : res.statusCode;
let message = err.message || 'Server Error';
// Mongoose bad ObjectId
if (err.name === 'CastError') {
message = `Resource not found with id ${err.value}`;
statusCode = 404;
}
// Mongoose duplicate key
if (err.code === 11000) {
const field = Object.keys(err.keyValue)[0];
message = `Duplicate field value entered for ${field}. Please use another value.`;
statusCode = 400;
}
// Mongoose validation error
if (err.name === 'ValidationError') {
message = Object.values(err.errors).map(val => val.message).join(', ');
statusCode = 400;
}
console.error('[Error Handler]:', err);
return errorResponse(res, message, err.errors || [], statusCode);
};
module.exports = errorHandler;

View File

@@ -0,0 +1,40 @@
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const uploadDir = path.join(__dirname, '../uploads');
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, uploadDir);
},
filename(req, file, cb) {
cb(null, `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`);
}
});
function checkFileType(file, cb) {
const filetypes = /jpg|jpeg|png|webp|svg|mp4|webm/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (extname && mimetype) {
return cb(null, true);
} else {
cb(new Error('Images and video media only!'));
}
}
const upload = multer({
storage,
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB limit
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
});
module.exports = upload;