|
|
const express = require('express'); |
|
|
const multer = require('multer'); |
|
|
const path = require('path'); |
|
|
const fs = require('fs'); |
|
|
const mime = require('mime-types'); |
|
|
const router = express.Router(); |
|
|
|
|
|
const uploadDir = path.join(__dirname, '../../uploads'); |
|
|
if (!fs.existsSync(uploadDir)) { |
|
|
fs.mkdirSync(uploadDir, { recursive: true }); |
|
|
} |
|
|
|
|
|
const supportedExtensions = [ |
|
|
'.jpg', '.jpeg', '.png', '.gif', '.webp', |
|
|
'.mp4', '.mov', '.avi', '.mkv', '.webm', |
|
|
'.mp3', '.wav', '.ogg', '.m4a' |
|
|
]; |
|
|
|
|
|
const storage = multer.diskStorage({ |
|
|
destination: (req, file, cb) => { |
|
|
cb(null, uploadDir); |
|
|
}, |
|
|
filename: (req, file, cb) => { |
|
|
const ext = path.extname(file.originalname).toLowerCase(); |
|
|
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); |
|
|
cb(null, 'file-' + uniqueSuffix + ext); |
|
|
} |
|
|
}); |
|
|
|
|
|
const fileFilter = (req, file, cb) => { |
|
|
const ext = path.extname(file.originalname).toLowerCase(); |
|
|
if (supportedExtensions.includes(ext)) { |
|
|
cb(null, true); |
|
|
} else { |
|
|
cb(new Error(`Unsupported file type: ${ext}`), false); |
|
|
} |
|
|
}; |
|
|
|
|
|
const upload = multer({ |
|
|
storage: storage, |
|
|
fileFilter: fileFilter, |
|
|
limits: { |
|
|
fileSize: 100 * 1024 * 1024 |
|
|
} |
|
|
}); |
|
|
|
|
|
router.post('/upload', upload.single('file'), (req, res) => { |
|
|
if (!req.file) { |
|
|
return res.status(400).json({ error: 'No file uploaded or invalid file type' }); |
|
|
} |
|
|
|
|
|
const fileType = mime.lookup(req.file.originalname) || 'application/octet-stream'; |
|
|
const fileCategory = getFileCategory(fileType); |
|
|
const protocol = req.secure || req.headers['x-forwarded-proto'] === 'https' ? 'https' : 'http'; |
|
|
const host = req.headers.host || `${DOMAIN}:${PORT}`; |
|
|
|
|
|
res.json({ |
|
|
message: 'File uploaded successfully', |
|
|
file: { |
|
|
originalName: req.file.originalname, |
|
|
fileName: req.file.filename, |
|
|
size: req.file.size, |
|
|
type: fileType, |
|
|
category: fileCategory, |
|
|
url: `${protocol}://${host}/api/files/${req.file.filename}` |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
router.get('/files/:filename', (req, res) => { |
|
|
const filePath = path.join(uploadDir, req.params.filename); |
|
|
|
|
|
if (!fs.existsSync(filePath)) { |
|
|
return res.status(404).json({ |
|
|
error: 'File not found', |
|
|
message: `The requested file does not exist on the server` |
|
|
}); |
|
|
} |
|
|
|
|
|
const contentType = mime.lookup(filePath) || 'application/octet-stream'; |
|
|
res.setHeader('Content-Type', contentType); |
|
|
res.sendFile(filePath); |
|
|
}); |
|
|
|
|
|
function getFileCategory(mimeType) { |
|
|
if (mimeType.startsWith('image/')) return 'image'; |
|
|
if (mimeType.startsWith('video/')) return 'video'; |
|
|
if (mimeType.startsWith('audio/')) return 'audio'; |
|
|
return 'other'; |
|
|
} |
|
|
|
|
|
module.exports = router; |