alinamarquardt.com/manage-audio/server.js

101 lines
2.9 KiB
JavaScript

require('dotenv').config();
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const cors = require('cors');
const app = express();
const PORT = 3000;
app.use(cors());
app.use('/audio', express.static('public/audio'));
app.use(express.json());
const AUTH_USER = process.env.AUTH_USER;
const AUTH_PASS = process.env.AUTH_PASS;
function basicAuth(user, pass) {
return (req, res, next) => {
const auth = req.headers.authorization || '';
const [scheme, encoded] = auth.split(' ');
if (scheme !== 'Basic' || !encoded) return unauthorized(res);
const [u, p] = Buffer.from(encoded, 'base64').toString().split(':');
if (u === user && p === pass) return next();
return unauthorized(res);
};
}
function unauthorized(res) {
res.set('WWW-Authenticate', 'Basic realm="Uploader"');
return res.status(401).send('Access denied.');
}
const storage = multer.diskStorage({
destination: 'public/audio/',
filename: (req, file, cb) => {
const unique = Date.now() + '-' + file.originalname.replace(/\s+/g, '_');
cb(null, unique);
}
});
const upload = multer({ storage });
const playlistPath = './playlist.json';
app.get('/upload', (req, res) => {
console.log('Blocked unexpected GET to /upload with query:', req.query);
res.status(204).end(); // No Content
});
app.post('/upload', upload.single('file'), (req, res) => {
console.log('POST');
console.log('Body:', req.body);
const title = req.body.title || req.file.originalname;
const filename = req.file.filename;
let playlist = [];
if (fs.existsSync(playlistPath)) {
playlist = JSON.parse(fs.readFileSync(playlistPath));
}
playlist.push({ title, url: `/audio/${filename}` });
fs.writeFileSync(playlistPath, JSON.stringify(playlist, null, 2));
res.json({ success: true });
});
app.get('/api/playlist', (req, res) => {
const playlist = fs.existsSync(playlistPath)
? JSON.parse(fs.readFileSync(playlistPath))
: [];
res.json(playlist);
});
app.post('/delete', basicAuth(AUTH_USER, AUTH_PASS), (req, res) => {
const { filename } = req.body;
let playlist = fs.existsSync(playlistPath)
? JSON.parse(fs.readFileSync(playlistPath))
: [];
playlist = playlist.filter(track => !track.url.endsWith(filename));
const filepath = path.join(__dirname, 'public/audio', filename);
if (fs.existsSync(filepath)) fs.unlinkSync(filepath);
fs.writeFileSync(playlistPath, JSON.stringify(playlist, null, 2));
res.json({ success: true });
});
app.post('/reorder', basicAuth(AUTH_USER, AUTH_PASS), (req, res) => {
const { playlist } = req.body;
fs.writeFileSync(playlistPath, JSON.stringify(playlist, null, 2));
res.json({ success: true });
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.listen(PORT, () => {
console.log(`Uploader running on http://localhost:${PORT}`);
});