Files
DiscordClone/Backend/routes/channels.js

161 lines
5.3 KiB
JavaScript

const express = require('express');
const router = express.Router();
const db = require('../db');
router.get('/', async (req, res) => {
try {
const result = await db.query('SELECT * FROM channels ORDER BY name ASC');
res.json(result.rows);
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Server error' });
}
});
// Create New Channel
router.post('/create', async (req, res) => {
console.log('Creates Channel Body:', req.body);
const { name, type } = req.body;
if (!name) return res.status(400).json({ error: 'Channel name required' });
try {
const result = await db.query(
'INSERT INTO channels (name, type) VALUES ($1, $2) RETURNING *',
[name, type || 'text']
);
const newChannel = result.rows[0];
// DO NOT emit 'new_channel' here. Wait until keys are uploaded.
res.json({ id: newChannel.id });
} catch (err) {
console.error('Error creating channel:', err);
if (err.code === '23505') {
res.status(400).json({ error: 'Channel already exists' });
} else {
res.status(500).json({ error: 'Server error' });
}
}
});
// Notify Channel Creation (Called AFTER keys are uploaded)
router.post('/:id/notify', async (req, res) => {
const { id } = req.params;
try {
const result = await db.query('SELECT * FROM channels WHERE id = $1', [id]);
if (result.rows.length === 0) return res.status(404).json({ error: 'Channel not found' });
const channel = result.rows[0];
if (req.io) req.io.emit('new_channel', channel); // Emit NOW
res.json({ success: true });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Server error' });
}
});
// Upload Channel Keys (for self or others)
// Upload Channel Keys (for self or others) - Supports Batch
router.post('/keys', async (req, res) => {
// Check if body is array
const keysToUpload = Array.isArray(req.body) ? req.body : [req.body];
if (keysToUpload.length === 0) return res.json({ success: true });
try {
await db.query('BEGIN');
for (const keyData of keysToUpload) {
const { channelId, userId, encryptedKeyBundle, keyVersion } = keyData;
if (!channelId || !userId || !encryptedKeyBundle) {
continue;
}
await db.query(
`INSERT INTO channel_keys (channel_id, user_id, encrypted_key_bundle, key_version)
VALUES ($1, $2, $3, $4)
ON CONFLICT (channel_id, user_id) DO UPDATE
SET encrypted_key_bundle = EXCLUDED.encrypted_key_bundle,
key_version = EXCLUDED.key_version`,
[channelId, userId, encryptedKeyBundle, keyVersion || 1]
);
}
await db.query('COMMIT');
res.json({ success: true, count: keysToUpload.length });
} catch (err) {
await db.query('ROLLBACK');
console.error('Error uploading channel keys:', err);
res.status(500).json({ error: 'Server error' });
}
});
// Get User's Channel Keys
router.get('/keys/:userId', async (req, res) => {
const { userId } = req.params;
try {
const result = await db.query(
'SELECT channel_id, encrypted_key_bundle, key_version FROM channel_keys WHERE user_id = $1',
[userId]
);
res.json(result.rows);
} catch (err) {
console.error('Error fetching channel keys:', err);
res.status(500).json({ error: 'Server error' });
}
});
// Update Channel Name
router.put('/:id', async (req, res) => {
const { id } = req.params;
const { name } = req.body;
if (!name) return res.status(400).json({ error: 'Name required' });
try {
const result = await db.query(
'UPDATE channels SET name = $1 WHERE id = $2 RETURNING *',
[name, id]
);
if (result.rows.length === 0) return res.status(404).json({ error: 'Channel not found' });
const updatedChannel = result.rows[0];
if (req.io) req.io.emit('channel_renamed', updatedChannel);
res.json(updatedChannel);
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Server error' });
}
});
// Delete Channel
router.delete('/:id', async (req, res) => {
const { id } = req.params;
try {
await db.query('BEGIN');
// Manual Cascade (since we didn't set FK CASCADE in schema for these yet)
await db.query('DELETE FROM messages WHERE channel_id = $1', [id]);
await db.query('DELETE FROM channel_keys WHERE channel_id = $1', [id]);
const result = await db.query('DELETE FROM channels WHERE id = $1 RETURNING *', [id]);
if (result.rows.length === 0) {
await db.query('ROLLBACK');
return res.status(404).json({ error: 'Channel not found' });
}
await db.query('COMMIT');
if (req.io) req.io.emit('channel_deleted', id);
res.json({ success: true, deletedId: id });
} catch (err) {
await db.query('ROLLBACK');
console.error(err);
res.status(500).json({ error: 'Server error' });
}
});
module.exports = router;