New federation features
All checks were successful
Build & Push Docker Image / build (push) Successful in 5m58s
All checks were successful
Build & Push Docker Image / build (push) Successful in 5m58s
This commit is contained in:
@@ -2,6 +2,7 @@ import { Router } from 'express';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { getDb } from '../config/database.js';
|
||||
import { authenticateToken } from '../middleware/auth.js';
|
||||
import { sendFederationInviteEmail } from '../config/mailer.js';
|
||||
import {
|
||||
getFederationDomain,
|
||||
isFederationEnabled,
|
||||
@@ -152,7 +153,7 @@ router.post('/receive', async (req, res) => {
|
||||
|
||||
// Look up user by name (case-insensitive)
|
||||
const targetUser = await db.get(
|
||||
'SELECT id FROM users WHERE LOWER(name) = LOWER(?)',
|
||||
'SELECT id, name, email FROM users WHERE LOWER(name) = LOWER(?)',
|
||||
[username]
|
||||
);
|
||||
|
||||
@@ -176,6 +177,19 @@ router.post('/receive', async (req, res) => {
|
||||
[invite_id, from_user, targetUser.id, room_name, message || null, join_url]
|
||||
);
|
||||
|
||||
// Send notification email (fire-and-forget, don't fail the request if mail fails)
|
||||
try {
|
||||
const appUrl = process.env.APP_URL || '';
|
||||
const inboxUrl = `${appUrl}/federation/inbox`;
|
||||
const appName = process.env.APP_NAME || 'Redlight';
|
||||
await sendFederationInviteEmail(
|
||||
targetUser.email, targetUser.name, from_user,
|
||||
room_name, message || null, inboxUrl, appName
|
||||
);
|
||||
} catch (mailErr) {
|
||||
console.warn('Federation invite mail failed (non-fatal):', mailErr.message);
|
||||
}
|
||||
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
console.error('Federation receive error:', err);
|
||||
@@ -233,6 +247,19 @@ router.post('/invitations/:id/accept', authenticateToken, async (req, res) => {
|
||||
[invitation.id]
|
||||
);
|
||||
|
||||
// Upsert into federated_rooms so the room appears in the user's dashboard
|
||||
const existing = await db.get(
|
||||
'SELECT id FROM federated_rooms WHERE invite_id = ? AND user_id = ?',
|
||||
[invitation.invite_id, req.user.id]
|
||||
);
|
||||
if (!existing) {
|
||||
await db.run(
|
||||
`INSERT INTO federated_rooms (user_id, invite_id, room_name, from_user, join_url)
|
||||
VALUES (?, ?, ?, ?, ?)`,
|
||||
[req.user.id, invitation.invite_id, invitation.room_name, invitation.from_user, invitation.join_url]
|
||||
);
|
||||
}
|
||||
|
||||
res.json({ success: true, join_url: invitation.join_url });
|
||||
} catch (err) {
|
||||
console.error('Accept invitation error:', err);
|
||||
@@ -262,4 +289,36 @@ router.delete('/invitations/:id', authenticateToken, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ── GET /api/federation/federated-rooms — List saved federated rooms ────────
|
||||
router.get('/federated-rooms', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
const db = getDb();
|
||||
const rooms = await db.all(
|
||||
`SELECT * FROM federated_rooms WHERE user_id = ? ORDER BY created_at DESC`,
|
||||
[req.user.id]
|
||||
);
|
||||
res.json({ rooms });
|
||||
} catch (err) {
|
||||
console.error('List federated rooms error:', err);
|
||||
res.status(500).json({ error: 'Failed to load federated rooms' });
|
||||
}
|
||||
});
|
||||
|
||||
// ── DELETE /api/federation/federated-rooms/:id — Remove a federated room ────
|
||||
router.delete('/federated-rooms/:id', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
const db = getDb();
|
||||
const room = await db.get(
|
||||
'SELECT * FROM federated_rooms WHERE id = ? AND user_id = ?',
|
||||
[req.params.id, req.user.id]
|
||||
);
|
||||
if (!room) return res.status(404).json({ error: 'Room not found' });
|
||||
await db.run('DELETE FROM federated_rooms WHERE id = ?', [room.id]);
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
console.error('Delete federated room error:', err);
|
||||
res.status(500).json({ error: 'Failed to remove room' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user