Authorize direct file invitations within paired rooms and parties
This commit is contained in:
38
server/direct-relay.js
Normal file
38
server/direct-relay.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { randomBytes } from 'node:crypto';
|
||||
import protocol from '../frontend/direct-protocol.js';
|
||||
|
||||
// One instance per authenticated room. It has no media endpoint or binary path.
|
||||
export function createDirectRelay({ now = Date.now } = {}) {
|
||||
const transfers = new Map();
|
||||
const rates = new Map();
|
||||
function handle(from, raw, peers, send) {
|
||||
const m = protocol.parse(raw);
|
||||
if (!m || !peers.has(from)) return false;
|
||||
const t = now();
|
||||
for (const [token, x] of transfers) if (x.expires < t || !peers.has(x.from) || !peers.has(x.to)) transfers.delete(token);
|
||||
const rate = rates.get(from);
|
||||
const r = rate && t - rate.start < 60000 ? rate : { start: t, count: 0 };
|
||||
rates.set(from, r);
|
||||
if (++r.count > 240) return false;
|
||||
if (m.action === 'invite') {
|
||||
if (m.to === from || !peers.has(m.to) || transfers.size >= 64) return false;
|
||||
const token = randomBytes(24).toString('base64url');
|
||||
transfers.set(token, { from, to: m.to, file: m.file, accepted: false, expires: t + 60000 });
|
||||
send(peers.get(m.to), { type: 'direct', action: 'invite', from, token, file: m.file });
|
||||
send(peers.get(from), { type: 'direct', action: 'invited', to: m.to, token, file: m.file });
|
||||
return true;
|
||||
}
|
||||
const x = transfers.get(m.token);
|
||||
if (!x || ![x.from, x.to].includes(from)) return false;
|
||||
const target = from === x.from ? x.to : x.from;
|
||||
if (m.action === 'accept') {
|
||||
if (from !== x.to || x.accepted) return false;
|
||||
x.accepted = true;
|
||||
x.expires = t + 30 * 60000;
|
||||
} else if (m.action === 'signal' && !x.accepted) return false;
|
||||
else if (m.action === 'decline' || m.action === 'complete') transfers.delete(m.token);
|
||||
send(peers.get(target), { ...m, from });
|
||||
return true;
|
||||
}
|
||||
return { handle };
|
||||
}
|
||||
Reference in New Issue
Block a user