This commit is contained in:
2025-12-13 21:46:18 +01:00
parent 9dc66b02fa
commit aeaf2bfaa3
3 changed files with 62 additions and 18 deletions

View File

@@ -207,7 +207,9 @@ const faviconStorage = multer.diskStorage({
cb(null, UPLOAD_DIR);
},
filename: (req, file, cb) => {
cb(null, 'favicon.png');
// Preserve original file extension (e.g., .ico, .png)
const ext = path.extname(file.originalname) || '.png';
cb(null, `favicon${ext}`);
}
});
const uploadFavicon = multer({ storage: faviconStorage });
@@ -215,20 +217,65 @@ const uploadFavicon = multer({ storage: faviconStorage });
// Upload Favicon
app.post('/api/favicon', uploadFavicon.single('favicon'), (req, res) => {
if (!req.file) return res.status(400).json({ error: 'No file uploaded' });
res.json({ success: true, url: '/uploads/favicon.png' });
// Respond with the stored filename (including extension)
const storedName = req.file.filename;
res.json({ success: true, url: `/uploads/${storedName}` });
});
// Serve Favicon (Dynamic)
app.get('/api/favicon', (req, res) => {
const faviconPath = path.join(UPLOAD_DIR, 'favicon.png');
if (fs.existsSync(faviconPath)) {
// Determine the stored favicon file (any supported extension)
const possibleExts = ['.ico', '.png', '.svg', '.jpg', '.jpeg'];
let faviconPath = null;
for (const ext of possibleExts) {
const candidate = path.join(UPLOAD_DIR, `favicon${ext}`);
if (fs.existsSync(candidate)) {
faviconPath = candidate;
break;
}
}
if (faviconPath) {
// Set appropriate Content-Type based on extension
const mimeMap = {
'.ico': 'image/x-icon',
'.png': 'image/png',
'.svg': 'image/svg+xml',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg'
};
const ext = path.extname(faviconPath).toLowerCase();
res.setHeader('Content-Type', mimeMap[ext] || 'application/octet-stream');
// Prevent caching so updates appear immediately
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
res.sendFile(faviconPath);
} else {
// Fallback to default
// Fallback to default (404)
res.status(404).send('Not found');
}
});
// Fallback for browsers requesting /favicon.ico directly
app.get('/favicon.ico', (req, res) => {
const possibleExts = ['.ico', '.png', '.svg', '.jpg', '.jpeg'];
for (const ext of possibleExts) {
const candidate = path.join(UPLOAD_DIR, `favicon${ext}`);
if (fs.existsSync(candidate)) {
const mimeMap = {
'.ico': 'image/x-icon',
'.png': 'image/png',
'.svg': 'image/svg+xml',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg'
};
const mime = mimeMap[ext] || 'application/octet-stream';
res.setHeader('Content-Type', mime);
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
return res.sendFile(candidate);
}
}
res.status(404).send('Not found');
});
// Serve Frontend (Production)
const DIST_DIR = path.join(__dirname, 'dist');
if (fs.existsSync(DIST_DIR)) {