161 lines
5.3 KiB
JavaScript
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 WHERE type != 'dm' 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;
|