feat(calls): mint a LiveKit join token into the native VoIP call payload (inc 1)
Increment 1 server side. Move livekitToken() into server/livekit.js (shared by routes.js
and calls.js). calls.js now mints a per-callee LiveKit join token and calls.js/push.js
put {livekitUrl, livekitToken} in the VoIP invite payload, so the native plugin can
connect the LiveKit room immediately on answer — even from a killed state, before the
WebView loads. No behaviour change while CALLKIT_ENABLED=0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+3
-16
@@ -137,22 +137,9 @@ const crypto = require('crypto');
|
||||
const MAX_UPLOAD_MB = parseInt(process.env.MAX_UPLOAD_MB, 10) || 1024; // default 1 GB per chat attachment
|
||||
const MAX_FILE_BYTES = MAX_UPLOAD_MB * 1024 * 1024; // NOTE: also raise Nginx Proxy Manager's client_max_body_size to match (default is 1 MB) or large uploads are rejected at the proxy before reaching here.
|
||||
|
||||
// Mint a LiveKit access token (HS256 JWT signed with the API secret) — same hand-rolled JWT
|
||||
// approach as push.js's FCM/APNs tokens, so no extra dependency. Grants the holder join+publish+
|
||||
// subscribe on exactly one room, as one identity. Secret stays server-side.
|
||||
const _b64u = (buf) => Buffer.from(buf).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
||||
function livekitToken(identity, name, room, metadata) {
|
||||
const nowSec = Math.floor(Date.now() / 1000);
|
||||
const header = _b64u(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
|
||||
const payload = _b64u(JSON.stringify({
|
||||
iss: LIVEKIT_API_KEY, sub: identity, name: name || identity,
|
||||
nbf: nowSec, exp: nowSec + 6 * 3600, // 6h — long enough for any meeting
|
||||
metadata: metadata || '',
|
||||
video: { room, roomJoin: true, canPublish: true, canSubscribe: true, canPublishData: true },
|
||||
}));
|
||||
const sig = _b64u(crypto.createHmac('sha256', LIVEKIT_API_SECRET).update(header + '.' + payload).digest());
|
||||
return header + '.' + payload + '.' + sig;
|
||||
}
|
||||
// LiveKit access-token minting lives in ./livekit (shared with calls.js, which mints a token for the native
|
||||
// VoIP call payload). Same hand-rolled HS256 JWT — grants join+publish+subscribe on one room, one identity.
|
||||
const { livekitToken } = require('./livekit');
|
||||
|
||||
// Issue a refresh token (native clients), store only its hash, return the plaintext once.
|
||||
async function issueRefreshToken(userId) {
|
||||
|
||||
Reference in New Issue
Block a user