feat: Add a large collection of emoji and other frontend assets, including a sound file, and a backend package.json.
This commit is contained in:
@@ -12,4 +12,149 @@ router.get('/', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 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;
|
||||
|
||||
Reference in New Issue
Block a user