streamflow/backend/routes/settings.js

135 lines
3.7 KiB
JavaScript
Raw Normal View History

const express = require('express');
const router = express.Router();
const { authenticate } = require('../middleware/auth');
const { modifyLimiter, readLimiter } = require('../middleware/rateLimiter');
const { db } = require('../database/db');
const { validateSettings } = require('../middleware/inputValidation');
const logger = require('../utils/logger');
const SecurityAuditLogger = require('../utils/securityAudit');
// Get user settings
router.get('/', authenticate, readLimiter, async (req, res) => {
const ip = req.ip || req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const userAgent = req.headers['user-agent'];
db.all(
'SELECT key, value FROM settings WHERE user_id = ?',
[req.user.userId],
async (err, settings) => {
if (err) {
return res.status(500).json({ error: 'Failed to fetch settings' });
}
// CWE-778: Log sensitive data access
await SecurityAuditLogger.logSensitiveDataAccess(req.user.userId, 'settings', {
ip,
userAgent,
recordCount: settings.length,
scope: 'own',
accessMethod: 'view'
});
// Convert array to object
const settingsObj = {};
settings.forEach(s => {
try {
settingsObj[s.key] = JSON.parse(s.value);
} catch {
settingsObj[s.key] = s.value;
}
});
res.json(settingsObj);
}
);
});
// Update setting
router.put('/:key', authenticate, modifyLimiter, validateSettings, (req, res) => {
const { key } = req.params;
const { value } = req.body;
const jsonValue = typeof value === 'string' ? value : JSON.stringify(value);
db.run(
`INSERT INTO settings (user_id, key, value, updated_at)
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
ON CONFLICT(user_id, key)
DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP`,
[req.user.userId, key, jsonValue, jsonValue],
function(err) {
if (err) {
return res.status(500).json({ error: 'Failed to update setting' });
}
res.json({ key, value });
}
);
});
// Get specific setting
router.get('/:key', authenticate, readLimiter, (req, res) => {
const { key } = req.params;
// Validate key format
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
return res.status(400).json({ error: 'Invalid setting key' });
}
// Handle stream_settings specially - return defaults if not found
if (key === 'stream_settings') {
db.get(
'SELECT value FROM settings WHERE user_id = ? AND key = ?',
[req.user.userId, key],
(err, setting) => {
if (err) {
return res.status(500).json({ error: 'Failed to fetch setting' });
}
// Return defaults if not found
if (!setting) {
return res.json({
value: {
hwaccel: 'auto',
hwaccel_device: '/dev/dri/renderD128',
codec: 'h264',
preset: 'veryfast',
buffer_size: '2M',
max_bitrate: '8M'
}
});
}
try {
res.json({ value: JSON.parse(setting.value) });
} catch {
res.json({ value: setting.value });
}
}
);
return;
}
db.get(
'SELECT value FROM settings WHERE user_id = ? AND key = ?',
[req.user.userId, key],
(err, setting) => {
if (err) {
return res.status(500).json({ error: 'Failed to fetch setting' });
}
if (!setting) {
return res.status(404).json({ error: 'Setting not found' });
}
try {
res.json({ value: JSON.parse(setting.value) });
} catch {
res.json({ value: setting.value });
}
}
);
});
module.exports = router;