143 lines
5.4 KiB
JavaScript
143 lines
5.4 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const db = require('../../db');
|
|
const { isAuthenticated, hasRole } = require('../../middleware/authMiddleware');
|
|
const { requireModule } = require('../../middleware/licenseMiddleware');
|
|
|
|
// Get all cameras - Protected by Module License
|
|
router.get('/', requireModule('monitoring'), async (req, res) => {
|
|
try {
|
|
const [rows] = await db.query('SELECT * FROM camera_settings ORDER BY display_order ASC, created_at DESC');
|
|
res.json(rows);
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Database error' });
|
|
}
|
|
});
|
|
|
|
// Reorder cameras (Admin only)
|
|
router.put('/reorder', hasRole('admin'), async (req, res) => {
|
|
const { cameras } = req.body; // Array of { id, display_order } or just ordered IDs
|
|
if (!Array.isArray(cameras)) {
|
|
return res.status(400).json({ error: 'Invalid data format' });
|
|
}
|
|
|
|
try {
|
|
// Use a transaction for safety
|
|
await db.query('START TRANSACTION');
|
|
|
|
for (let i = 0; i < cameras.length; i++) {
|
|
const cam = cameras[i];
|
|
// If receiving array of IDs, use index as order
|
|
const id = typeof cam === 'object' ? cam.id : cam;
|
|
const order = i;
|
|
|
|
await db.query('UPDATE camera_settings SET display_order = ? WHERE id = ?', [order, id]);
|
|
}
|
|
|
|
await db.query('COMMIT');
|
|
res.json({ message: 'Cameras reordered' });
|
|
} catch (err) {
|
|
await db.query('ROLLBACK');
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Database error' });
|
|
}
|
|
});
|
|
|
|
// Get single camera
|
|
router.get('/:id', async (req, res) => {
|
|
try {
|
|
const [rows] = await db.query('SELECT * FROM camera_settings WHERE id = ?', [req.params.id]);
|
|
if (rows.length === 0) return res.status(404).json({ error: 'Camera not found' });
|
|
res.json(rows[0]);
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Database error' });
|
|
}
|
|
});
|
|
|
|
// Add camera (Admin only)
|
|
router.post('/', hasRole('admin'), async (req, res) => {
|
|
const { name, ip_address, port, username, password, stream_path, transport_mode, rtsp_encoding, quality } = req.body;
|
|
try {
|
|
const sql = `INSERT INTO camera_settings (name, ip_address, port, username, password, stream_path, transport_mode, rtsp_encoding, quality) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
|
const [result] = await db.query(sql, [name, ip_address, port || 554, username, password, stream_path || '/stream1', transport_mode || 'tcp', rtsp_encoding || false, quality || 'low']);
|
|
res.status(201).json({ message: 'Camera added', id: result.insertId });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Database error' });
|
|
}
|
|
});
|
|
|
|
// Update camera (Admin only)
|
|
router.put('/:id', hasRole('admin'), async (req, res) => {
|
|
const { name, ip_address, port, username, password, stream_path, transport_mode, rtsp_encoding, quality } = req.body;
|
|
try {
|
|
const sql = `UPDATE camera_settings SET name=?, ip_address=?, port=?, username=?, password=?, stream_path=?, transport_mode=?, rtsp_encoding=?, quality=? WHERE id=?`;
|
|
const [result] = await db.query(sql, [name, ip_address, port, username, password, stream_path, transport_mode, rtsp_encoding, quality, req.params.id]);
|
|
if (result.affectedRows === 0) return res.status(404).json({ error: 'Camera not found' });
|
|
|
|
// Force stream reset (kick clients to trigger reconnect)
|
|
const streamRelay = req.app.get('streamRelay');
|
|
if (streamRelay) {
|
|
console.log(`Settings changed for camera ${req.params.id}, resetting stream...`);
|
|
streamRelay.resetStream(req.params.id);
|
|
}
|
|
|
|
res.json({ message: 'Camera updated' });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Database error' });
|
|
}
|
|
});
|
|
|
|
// Delete camera (Admin only)
|
|
router.delete('/:id', hasRole('admin'), async (req, res) => {
|
|
try {
|
|
const [result] = await db.query('DELETE FROM camera_settings WHERE id = ?', [req.params.id]);
|
|
if (result.affectedRows === 0) return res.status(404).json({ error: 'Camera not found' });
|
|
|
|
// Stop stream
|
|
const streamRelay = req.app.get('streamRelay');
|
|
if (streamRelay) {
|
|
streamRelay.stopStream(req.params.id);
|
|
}
|
|
|
|
res.json({ message: 'Camera deleted' });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Database error' });
|
|
}
|
|
});
|
|
|
|
const { exec } = require('child_process');
|
|
|
|
// ... existing routes ...
|
|
|
|
// 7. Ping Test (Troubleshooting)
|
|
router.get('/:id/ping', isAuthenticated, async (req, res) => {
|
|
try {
|
|
const [rows] = await db.query('SELECT ip_address FROM camera_settings WHERE id = ?', [req.params.id]);
|
|
if (rows.length === 0) return res.status(404).json({ error: 'Camera not found' });
|
|
|
|
const ip = rows[0].ip_address;
|
|
|
|
// Simple ping command
|
|
const platform = process.platform;
|
|
const cmd = platform === 'win32' ? `ping -n 1 ${ip}` : `ping -c 1 ${ip}`;
|
|
|
|
exec(cmd, (error, stdout, stderr) => {
|
|
res.json({
|
|
ip,
|
|
success: !error,
|
|
output: stdout,
|
|
error: stderr
|
|
});
|
|
});
|
|
} catch (err) {
|
|
res.status(500).json({ error: 'Ping failed' });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|