diff --git a/src/controllers/CallsController.ts b/src/controllers/CallsController.ts index 8f78d75..c5a6d94 100644 --- a/src/controllers/CallsController.ts +++ b/src/controllers/CallsController.ts @@ -5,6 +5,7 @@ import { EventsHelper } from "../helpers/EventsHelper"; import * as ws from 'ws' import { WsMessage } from "../entities/WsMessage"; import { conf } from "../helpers/ConfigHelper"; +import { RTCRelayController } from "./RTCRelayController"; /** * Legacy calls controller @@ -104,6 +105,39 @@ export class CallsController { ).map(f => f.userID)) } + /** + * Handles client signal + * + * @param h Request handler + */ + public static async OnClientSignal(h: UserWebSocketRequestsHandler) { + const callID = h.postCallId("callID"); + const peerID = h.postCallPeerID(callID, "peerID"); + const type = h.postString("type"); + const data = h.postJSON("data"); + + if(type !== "SDP" && type !== "CANDIDATE") + h.error(401, "Invalid candidate type"); + + if(type == "SDP" && (!data.hasOwnProperty("type") || data.type !== "offer" || !data.hasOwnProperty("sdp"))) + h.error(401, "Invalid SDP signal!") + + if(type == "CANDIDATE" && (!data.hasOwnProperty("candidate") || !data.hasOwnProperty("sdpMLineIndex") || !data.hasOwnProperty("sdpMid"))) + h.error(401, "Invalid candidate signal!") + + await RTCRelayController.SendMessage({ + title: "signal", + callHash: callID+"-"+peerID, + peerId: String(peerID === h.getUserId() ? 0 : peerID), + data: { + type: type, + data: data + } + }); + + h.success() + } + /** * Make the client leave the call * diff --git a/src/controllers/RTCRelayController.ts b/src/controllers/RTCRelayController.ts index 3881300..c43b97b 100644 --- a/src/controllers/RTCRelayController.ts +++ b/src/controllers/RTCRelayController.ts @@ -102,7 +102,7 @@ export class RTCRelayController { * @param title The title of the message to send * @param content The content of the message */ - private static async SendMessage(msg: RTCSocketMessage) { + public static async SendMessage(msg: RTCSocketMessage) { this.currWs.send(JSON.stringify({ title: msg.title, callHash: msg.callHash, diff --git a/src/controllers/UserWebSocketRoutes.ts b/src/controllers/UserWebSocketRoutes.ts index 868c289..3506918 100644 --- a/src/controllers/UserWebSocketRoutes.ts +++ b/src/controllers/UserWebSocketRoutes.ts @@ -40,4 +40,6 @@ export const UserWebSocketRoutes: UserWebSocketRoute[] = [ {title: "calls/leave", handler: (h) => CallsController.LeaveCall(h)}, {title: "calls/members", handler: (h) => CallsController.GetMembersList(h)}, + + {title: "calls/signal", handler: (h) => CallsController.OnClientSignal(h)}, ] \ No newline at end of file diff --git a/src/entities/WebSocketRequestHandler.ts b/src/entities/WebSocketRequestHandler.ts index 49c9b28..1b9ee55 100644 --- a/src/entities/WebSocketRequestHandler.ts +++ b/src/entities/WebSocketRequestHandler.ts @@ -80,4 +80,20 @@ export class UserWebSocketRequestsHandler extends BaseRequestsHandler { return convID; } + + /** + * Get the ID of a peer of a call included in the WebSocket request + * + * @param callID Target call ID + * @param name The name of the POST field + */ + public postCallPeerID(callID: number, name: string) : number{ + const peerID = this.postInt(name); + + if(peerID != this.getUserId() && UserWebSocketController.active_clients.find( + (e) => e.userID == peerID && e.activeCalls.has(callID)) === undefined) + this.error(401, "This peer is not a member of the call!"); + + return peerID; + } } \ No newline at end of file