diff options
author | metamuffin <metamuffin@disroot.org> | 2022-09-09 12:45:37 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-09-09 12:45:37 +0200 |
commit | e590ea788aefe0714bb9ce24976303566a648d42 (patch) | |
tree | d6b3d827512af388fe0ea4f2ac1c2f1fc983178a /client-web/source | |
parent | b25bbae82f9bfaf6f37dfb16e07708060dd3df55 (diff) | |
download | keks-meet-e590ea788aefe0714bb9ce24976303566a648d42.tar keks-meet-e590ea788aefe0714bb9ce24976303566a648d42.tar.bz2 keks-meet-e590ea788aefe0714bb9ce24976303566a648d42.tar.zst |
reworked websocket stuff with encryption and new spec
Diffstat (limited to 'client-web/source')
-rw-r--r-- | client-web/source/index.ts | 2 | ||||
-rw-r--r-- | client-web/source/local_user.ts | 4 | ||||
-rw-r--r-- | client-web/source/protocol/mod.ts | 46 | ||||
-rw-r--r-- | client-web/source/remote_user.ts | 12 | ||||
-rw-r--r-- | client-web/source/rnnoise.ts | 2 | ||||
-rw-r--r-- | client-web/source/room.ts | 46 | ||||
-rw-r--r-- | client-web/source/user.ts | 13 |
7 files changed, 79 insertions, 46 deletions
diff --git a/client-web/source/index.ts b/client-web/source/index.ts index 21bf4b8..5695573 100644 --- a/client-web/source/index.ts +++ b/client-web/source/index.ts @@ -19,7 +19,7 @@ export interface User { window.onload = () => main() export async function main() { - document.body.querySelector("p")?.remove() + document.body.querySelectorAll("p").forEach(e => e.remove()) log("*", "starting up") const room_name = window.location.pathname.substring("/".length) const conn = await (new SignalingConnection().connect(room_name)) diff --git a/client-web/source/local_user.ts b/client-web/source/local_user.ts index bb5b779..efedfc2 100644 --- a/client-web/source/local_user.ts +++ b/client-web/source/local_user.ts @@ -12,8 +12,8 @@ export class LocalUser extends User { mic_gain?: GainNode default_gain: number = PREFS.microphone_gain - constructor(room: Room, id: number, name: string) { - super(room, id, name) + constructor(room: Room, id: number) { + super(room, id) this.el.classList.add("local") this.local = true this.create_controls() diff --git a/client-web/source/protocol/mod.ts b/client-web/source/protocol/mod.ts index 4fbd607..53cbb86 100644 --- a/client-web/source/protocol/mod.ts +++ b/client-web/source/protocol/mod.ts @@ -1,5 +1,6 @@ +import { ClientboundPacket, RelayMessage, ServerboundPacket } from "../../../common/packets.d.ts" import { log } from "../logger.ts" -import { crypto_seeded_key, crypt_hash } from "./crypto.ts" +import { crypto_encrypt, crypto_seeded_key, crypt_decrypt, crypt_hash } from "./crypto.ts" export class SignalingConnection { room!: string @@ -7,6 +8,9 @@ export class SignalingConnection { signaling_id!: string key!: CryptoKey + control_handler: (_packet: ClientboundPacket) => void = () => { } + relay_handler: (_sender: number, _message: RelayMessage) => void = () => { } + constructor() { } async connect(room: string): Promise<SignalingConnection> { this.key = await crypto_seeded_key(room) @@ -14,10 +18,48 @@ export class SignalingConnection { log("ws", "connecting…") const ws_url = new URL(`${window.location.protocol.endsWith("s:") ? "wss" : "ws"}://${window.location.host}/signaling/${encodeURIComponent(this.signaling_id)}`) this.websocket = new WebSocket(ws_url) - await new Promise(r => this.websocket!.onopen = r) + this.websocket.onerror = () => this.on_error() + this.websocket.onmessage = e => { + if (typeof e.data == "string") this.on_message(e.data) + } + await new Promise<void>(r => this.websocket!.onopen = () => { + this.on_open() + r() + }) log("ws", "connection opened") return this } + on_close() { + log("ws", "websocket closed"); + setTimeout(() => { + window.location.reload() + }, 1000) + } + on_open() { + log("ws", "websocket opened"); + setInterval(() => this.send_control({ ping: null }), 30000) // stupid workaround for nginx disconnecting inactive connections + } + on_error() { + log("error", "websocket error occurred!") + } + async on_message(data: string) { + const packet: ClientboundPacket = JSON.parse(data) // TODO dont crash if invalid + this.control_handler(packet) + if (packet.message) { + const inner_json = await crypt_decrypt(this.key, packet.message.message) + const inner: RelayMessage = JSON.parse(inner_json) // TODO make sure that protocol spec is met + this.relay_handler(packet.message.sender, inner) + } + } + send_control(data: ServerboundPacket) { + log("ws", `-> ${data.relay?.recipient ?? "*"}`, data) + this.websocket.send(JSON.stringify(data)) + } + async send_relay(data: RelayMessage, recipient?: number | null) { + recipient ??= undefined // null -> undefined + const message = await crypto_encrypt(this.key, JSON.stringify(data)) + this.send_control({ relay: { recipient, message } }) + } } diff --git a/client-web/source/remote_user.ts b/client-web/source/remote_user.ts index 6cc57a5..5283a7b 100644 --- a/client-web/source/remote_user.ts +++ b/client-web/source/remote_user.ts @@ -10,13 +10,13 @@ export class RemoteUser extends User { peer: RTCPeerConnection negotiation_busy = false - constructor(room: Room, id: number, name: string) { - super(room, id, name) - log("usermodel", `added remote user: ${id} ${JSON.stringify(name)}`) + constructor(room: Room, id: number) { + super(room, id) + log("usermodel", `added remote user: ${id}`) this.peer = new RTCPeerConnection(servers) this.peer.onicecandidate = ev => { if (!ev.candidate) return - room.websocket_send({ relay: { recipient: this.id, message: { ice_candidate: ev.candidate.toJSON() } } }) + room.signaling.send_relay({ ice_candidate: ev.candidate.toJSON() }, this.id) } this.peer.ontrack = ev => { const t = ev.track @@ -38,7 +38,7 @@ export class RemoteUser extends User { await this.peer.setLocalDescription(offer_description) const offer = { type: offer_description.type, sdp: offer_description.sdp } log("webrtc", `sent offer: ${this.name}`, { a: offer }) - this.room.websocket_send({ relay: { recipient: this.id, message: { offer } } }) + this.room.signaling.send_relay({ offer }, this.id) } async on_offer(offer: RTCSessionDescriptionInit) { this.negotiation_busy = true @@ -52,7 +52,7 @@ export class RemoteUser extends User { await this.peer.setLocalDescription(answer_description) const answer = { type: answer_description.type, sdp: answer_description.sdp } log("webrtc", `sent answer: ${this.name}`, { a: answer }) - this.room.websocket_send({ relay: { recipient: this.id, message: { answer } } }) + this.room.signaling.send_relay({ answer }, this.id) this.negotiation_busy = false } async on_answer(answer: RTCSessionDescriptionInit) { diff --git a/client-web/source/rnnoise.ts b/client-web/source/rnnoise.ts index d6efb3b..2e0f857 100644 --- a/client-web/source/rnnoise.ts +++ b/client-web/source/rnnoise.ts @@ -23,7 +23,7 @@ export async function get_rnnoise_node(context: AudioContext): Promise<RNNoiseNo if (!RNNoiseNode) { log("rnnoise", "loading wasm...") script = document.createElement("script") - script.src = "/_assets/rnnoise/rnnoise-runtime.js" + script.src = "/assets/rnnoise/rnnoise-runtime.js" script.defer = true document.head.appendChild(script) //@ts-ignore asdfsfad diff --git a/client-web/source/room.ts b/client-web/source/room.ts index 6c9a7ba..9f27230 100644 --- a/client-web/source/room.ts +++ b/client-web/source/room.ts @@ -4,7 +4,7 @@ import { log } from "./logger.ts"; import { RemoteUser } from "./remote_user.ts"; import { User } from "./user.ts"; import { LocalUser } from "./local_user.ts"; -import { ServerboundPacket, ClientboundPacket } from "../../common/packets.d.ts"; +import { ClientboundPacket, RelayMessage } from "../../common/packets.d.ts"; import { SignalingConnection } from "./protocol/mod.ts"; export class Room { @@ -17,14 +17,13 @@ export class Room { constructor(public signaling: SignalingConnection) { this.el = document.createElement("div") this.el.classList.add("room") + this.signaling.control_handler = this.control_handler + this.signaling.relay_handler = this.relay_handler } - websocket_send(data: ServerboundPacket) { - log("ws", `-> ${data.relay?.recipient ?? "*"}`, data) - // this.websocket.send(JSON.stringify(data)) - } - websocket_message(packet: ClientboundPacket) { - log("ws", `<- ${packet.message?.sender ?? "control packet"}: `, packet); + control_handler(packet: ClientboundPacket) { + if (packet.message) return // let the relay handler do that + log("ws", `<- [control packet]: `, packet); if (packet.init) { this.my_id = packet.init.your_id // no need to check compat for now because this is hosted in the same place @@ -33,9 +32,9 @@ export class Room { const p = packet.client_join log("*", `${p.id} joined`); if (p.id == this.my_id) { - this.local_user = new LocalUser(this, p.id, p.name); + this.local_user = new LocalUser(this, p.id); } else { - const ru = new RemoteUser(this, p.id, p.name) + const ru = new RemoteUser(this, p.id) this.local_user.add_initial_to_remote(ru) ru.offer() this.users.set(p.id, ru) @@ -48,26 +47,17 @@ export class Room { this.users.delete(p.id) this.remote_users.delete(p.id) return - } else if (packet.message) { - const p = packet.message; - const sender = this.users.get(p.sender) - if (sender instanceof RemoteUser) { - // if (p.message.ice_candidate) sender.add_ice_candidate(p.message.ice_candidate) - // if (p.message.offer) sender.on_offer(p.message.offer) - // if (p.message.answer) sender.on_answer(p.message.answer) - } else { - console.log("!", p, sender); - } } + } - websocket_close() { - log("ws", "websocket closed"); - setTimeout(() => { - window.location.reload() - }, 1000) - } - websocket_open() { - log("ws", "websocket opened"); - setInterval(() => this.websocket_send({ ping: null }), 30000) // stupid workaround for nginx disconnecting inactive connections + relay_handler(sender_id: number, message: RelayMessage) { + const sender = this.users.get(sender_id) + if (sender instanceof RemoteUser) { + if (message.ice_candidate) sender.add_ice_candidate(message.ice_candidate) + if (message.offer) sender.on_offer(message.offer) + if (message.answer) sender.on_answer(message.answer) + } else { + console.log("!", message, sender); + } } }
\ No newline at end of file diff --git a/client-web/source/user.ts b/client-web/source/user.ts index dbf2862..057cdf4 100644 --- a/client-web/source/user.ts +++ b/client-web/source/user.ts @@ -6,13 +6,12 @@ import { TrackHandle } from "./track_handle.ts"; export abstract class User { - el: HTMLElement - - local = false - + protected el: HTMLElement + public local = false + public name?: string protected tracks: Set<TrackHandle> = new Set() - constructor(public room: Room, public id: number, public name: string) { + constructor(public room: Room, public id: number,) { this.el = document.createElement("div") this.el.classList.add("user") this.room.el.append(this.el) @@ -34,11 +33,13 @@ export abstract class User { }) } + get display_name() { return this.name ?? `guest (${this.id})` } + setup_view() { const info_el = document.createElement("div") info_el.classList.add("info") const name_el = document.createElement("span") - name_el.textContent = this.name + name_el.textContent = this.display_name name_el.classList.add("name") info_el.append(name_el) this.el.append(info_el) |