streamflow/backend/routes/favorites.js

137 lines
3.7 KiB
JavaScript
Raw Permalink Normal View History

const express = require('express');
const router = express.Router();
const { db } = require('../database/db');
const { authenticate } = require('../middleware/auth');
const { modifyLimiter, readLimiter } = require('../middleware/rateLimiter');
const logger = require('../utils/logger');
const { validateChannelIdParam } = require('../middleware/inputValidation');
/**
* Get user's favorite channels
*/
router.get('/', authenticate, readLimiter, (req, res) => {
const { isRadio } = req.query;
const userId = req.user.userId;
let query = `
SELECT
c.id, c.name, c.url, COALESCE(c.custom_logo, c.logo) as logo,
c.group_name, c.is_radio, f.created_at as favorited_at
FROM favorites f
JOIN channels c ON f.channel_id = c.id
WHERE f.user_id = ? AND c.is_active = 1
`;
const params = [userId];
// Filter by radio or TV
if (isRadio !== undefined) {
query += ' AND c.is_radio = ?';
params.push(isRadio === 'true' ? 1 : 0);
}
query += ' ORDER BY f.created_at DESC';
db.all(query, params, (err, rows) => {
if (err) {
console.error('Error fetching favorites:', err);
return res.status(500).json({ error: 'Failed to fetch favorites' });
}
res.json(rows || []);
});
});
/**
* Add channel to favorites
*/
router.post('/:channelId', authenticate, modifyLimiter, validateChannelIdParam, (req, res) => {
const { channelId } = req.params;
const userId = req.user.userId;
// Check if channel exists and is active
db.get(
'SELECT id, is_radio FROM channels WHERE id = ? AND is_active = 1',
[channelId],
(err, channel) => {
if (err) {
console.error('Error checking channel:', err);
return res.status(500).json({ error: 'Database error' });
}
if (!channel) {
return res.status(404).json({ error: 'Channel not found' });
}
// Add to favorites
db.run(
`INSERT OR IGNORE INTO favorites (user_id, channel_id) VALUES (?, ?)`,
[userId, channelId],
function(err) {
if (err) {
console.error('Error adding favorite:', err);
return res.status(500).json({ error: 'Failed to add favorite' });
}
if (this.changes === 0) {
return res.status(200).json({ message: 'Already in favorites', alreadyExists: true });
}
res.status(201).json({
message: 'Added to favorites',
channelId: parseInt(channelId),
isRadio: channel.is_radio === 1
});
}
);
}
);
});
/**
* Remove channel from favorites
*/
router.delete('/:channelId', authenticate, modifyLimiter, validateChannelIdParam, (req, res) => {
const { channelId } = req.params;
const userId = req.user.userId;
db.run(
'DELETE FROM favorites WHERE user_id = ? AND channel_id = ?',
[userId, channelId],
function(err) {
if (err) {
console.error('Error removing favorite:', err);
return res.status(500).json({ error: 'Failed to remove favorite' });
}
if (this.changes === 0) {
return res.status(404).json({ error: 'Favorite not found' });
}
res.json({ message: 'Removed from favorites' });
}
);
});
/**
* Check if channel is favorited
*/
router.get('/check/:channelId', authenticate, (req, res) => {
const { channelId } = req.params;
const userId = req.user.userId;
db.get(
'SELECT id FROM favorites WHERE user_id = ? AND channel_id = ?',
[userId, channelId],
(err, row) => {
if (err) {
console.error('Error checking favorite:', err);
return res.status(500).json({ error: 'Database error' });
}
res.json({ isFavorite: !!row });
}
);
});
module.exports = router;