feat: implement CORS proxy for Matrix homeservers during development and refactor call handling logic
This commit is contained in:
@@ -10,7 +10,9 @@ import { getActiveCallMembers } from './useRoomCallMembers';
|
||||
* Get room server from room ID (format: !roomid:server.com)
|
||||
*/
|
||||
function getRoomServer(roomId: string): string | undefined {
|
||||
return getMxIdServer(roomId);
|
||||
const server = getMxIdServer(roomId);
|
||||
console.log(`[getRoomServer] Room ID: ${roomId} -> Server: ${server}`);
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,13 +32,20 @@ export function getLiveKitHomeserverPriority(
|
||||
const memberCount = room.getMembers().length;
|
||||
const isDM = memberCount <= 2;
|
||||
|
||||
console.log(`[getLiveKitHomeserverPriority] Room: ${room.roomId}`);
|
||||
console.log(`[getLiveKitHomeserverPriority] Member count: ${memberCount}, isDM: ${isDM}`);
|
||||
console.log(`[getLiveKitHomeserverPriority] User homeserver: ${userHomeserver}`);
|
||||
|
||||
// Check for active call members
|
||||
const activeCallMembers = getActiveCallMembers(room);
|
||||
const hasActiveCall = activeCallMembers.length > 0;
|
||||
|
||||
console.log(`[getLiveKitHomeserverPriority] Active call members: ${activeCallMembers.length}, hasActiveCall: ${hasActiveCall}`);
|
||||
|
||||
if (hasActiveCall) {
|
||||
// Joining existing call - prioritize room's homeserver (where call is hosted)
|
||||
const roomServer = getRoomServer(room.roomId);
|
||||
console.log(`[getLiveKitHomeserverPriority] Room server (active call): ${roomServer}`);
|
||||
if (roomServer) {
|
||||
servers.push(`https://${roomServer}`);
|
||||
}
|
||||
@@ -60,32 +69,39 @@ export function getLiveKitHomeserverPriority(
|
||||
} else {
|
||||
// Starting new call - use original priority logic
|
||||
if (isDM) {
|
||||
console.log(`[getLiveKitHomeserverPriority] DM path - user homeserver first`);
|
||||
// For DMs: user's homeserver first, then other member's homeserver
|
||||
servers.push(userHomeserver);
|
||||
|
||||
const otherUserId = guessDmRoomUserId(room, myUserId);
|
||||
console.log(`[getLiveKitHomeserverPriority] Other user ID: ${otherUserId}`);
|
||||
if (otherUserId && otherUserId !== myUserId) {
|
||||
const otherServer = getMxIdServer(otherUserId);
|
||||
console.log(`[getLiveKitHomeserverPriority] Other user server: ${otherServer}`);
|
||||
const userDomain = userHomeserver.replace('https://', '').replace('http://', '');
|
||||
if (otherServer && otherServer !== userDomain) {
|
||||
servers.push(`https://${otherServer}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`[getLiveKitHomeserverPriority] Channel path - room homeserver first`);
|
||||
// For channels: room's homeserver first, then user's homeserver
|
||||
const roomServer = getRoomServer(room.roomId);
|
||||
console.log(`[getLiveKitHomeserverPriority] Room server from ID: ${roomServer}`);
|
||||
if (roomServer) {
|
||||
servers.push(`https://${roomServer}`);
|
||||
}
|
||||
|
||||
// Fallback to user's homeserver if different
|
||||
const userDomain = userHomeserver.replace('https://', '').replace('http://', '');
|
||||
console.log(`[getLiveKitHomeserverPriority] User domain: ${userDomain}, room server: ${roomServer}`);
|
||||
if (!roomServer || roomServer !== userDomain) {
|
||||
servers.push(userHomeserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[getLiveKitHomeserverPriority] Final server list:`, servers);
|
||||
return servers;
|
||||
}
|
||||
|
||||
@@ -96,11 +112,16 @@ export function getLiveKitHomeserverPriority(
|
||||
*/
|
||||
export function getLiveKitFocus(wellKnown: WellKnownWithRTC): LiveKitFocus | undefined {
|
||||
const rtcFoci = wellKnown['org.matrix.msc4143.rtc_foci'];
|
||||
console.log(`[getLiveKitFocus] rtcFoci from well-known:`, rtcFoci);
|
||||
|
||||
if (!rtcFoci || !Array.isArray(rtcFoci)) {
|
||||
console.log(`[getLiveKitFocus] No rtc_foci found or not an array`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return rtcFoci.find((focus): focus is LiveKitFocus => focus.type === 'livekit');
|
||||
const livekitFocus = rtcFoci.find((focus): focus is LiveKitFocus => focus.type === 'livekit');
|
||||
console.log(`[getLiveKitFocus] Found LiveKit focus:`, livekitFocus);
|
||||
return livekitFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,14 +130,28 @@ export function getLiveKitFocus(wellKnown: WellKnownWithRTC): LiveKitFocus | und
|
||||
* @returns The well-known response with RTC configuration
|
||||
*/
|
||||
export async function fetchWellKnownWithRTC(baseUrl: string): Promise<WellKnownWithRTC> {
|
||||
const wellKnownUrl = `${baseUrl}/.well-known/matrix/client`;
|
||||
// In development mode (localhost), use CORS proxy to avoid CORS issues
|
||||
const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
|
||||
|
||||
let wellKnownUrl: string;
|
||||
if (isDev) {
|
||||
// Extract hostname from baseUrl for proxy
|
||||
const hostname = baseUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
|
||||
wellKnownUrl = `/_matrix-cors-proxy/${hostname}/.well-known/matrix/client`;
|
||||
} else {
|
||||
wellKnownUrl = `${baseUrl}/.well-known/matrix/client`;
|
||||
}
|
||||
|
||||
console.log(`[fetchWellKnownWithRTC] Fetching from: ${wellKnownUrl}`);
|
||||
|
||||
const response = await fetch(wellKnownUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch well-known: ${response.status}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
const data = await response.json();
|
||||
console.log(`[fetchWellKnownWithRTC] Response data:`, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,7 +167,16 @@ export async function requestOpenIdToken(
|
||||
userId: string,
|
||||
accessToken: string
|
||||
): Promise<OpenIdToken> {
|
||||
const url = `${homeserverBaseUrl}/_matrix/client/v3/user/${encodeURIComponent(userId)}/openid/request_token`;
|
||||
// In development mode (localhost), use CORS proxy to avoid CORS issues
|
||||
const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
|
||||
|
||||
let url: string;
|
||||
if (isDev) {
|
||||
const hostname = homeserverBaseUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
|
||||
url = `/_matrix-cors-proxy/${hostname}/_matrix/client/v3/user/${encodeURIComponent(userId)}/openid/request_token`;
|
||||
} else {
|
||||
url = `${homeserverBaseUrl}/_matrix/client/v3/user/${encodeURIComponent(userId)}/openid/request_token`;
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
@@ -175,7 +219,21 @@ export async function fetchLiveKitJWT(
|
||||
// to create the LiveKit room name.
|
||||
const slotId = 'm.call';
|
||||
|
||||
const response = await fetch(livekitServiceUrl, {
|
||||
// In development mode (localhost), use CORS proxy to avoid CORS issues
|
||||
const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
|
||||
|
||||
let url: string;
|
||||
if (isDev) {
|
||||
// Extract hostname and path from livekitServiceUrl
|
||||
const urlObj = new URL(livekitServiceUrl);
|
||||
const hostname = urlObj.hostname;
|
||||
const pathname = urlObj.pathname;
|
||||
url = `/_matrix-cors-proxy/${hostname}${pathname}`;
|
||||
} else {
|
||||
url = livekitServiceUrl;
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -202,7 +260,8 @@ export async function fetchLiveKitJWT(
|
||||
|
||||
/**
|
||||
* Try fetching LiveKit JWT from multiple homeservers in priority order
|
||||
* @param homeservers - Array of homeserver base URLs to try
|
||||
* @param homeservers - Array of homeserver base URLs to check for LiveKit config
|
||||
* @param userHomeserver - The user's own homeserver URL (for OpenID token)
|
||||
* @param roomId - The Matrix room ID
|
||||
* @param userId - The Matrix user ID
|
||||
* @param deviceId - The Matrix device ID
|
||||
@@ -211,6 +270,7 @@ export async function fetchLiveKitJWT(
|
||||
*/
|
||||
export async function fetchLiveKitJWTFromServers(
|
||||
homeservers: string[],
|
||||
userHomeserver: string,
|
||||
roomId: string,
|
||||
userId: string,
|
||||
deviceId: string,
|
||||
@@ -229,8 +289,9 @@ export async function fetchLiveKitJWTFromServers(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get OpenID token from this homeserver
|
||||
const openIdToken = await requestOpenIdToken(homeserver, userId, accessToken);
|
||||
// Always get OpenID token from user's own homeserver
|
||||
// (Can't use access token on remote homeserver)
|
||||
const openIdToken = await requestOpenIdToken(userHomeserver, userId, accessToken);
|
||||
|
||||
// Exchange for LiveKit JWT
|
||||
const jwt = await fetchLiveKitJWT(
|
||||
|
||||
Reference in New Issue
Block a user