aboutsummaryrefslogtreecommitdiff
path: root/client-web/source/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'client-web/source/protocol')
-rw-r--r--client-web/source/protocol/mod.ts32
1 files changed, 19 insertions, 13 deletions
diff --git a/client-web/source/protocol/mod.ts b/client-web/source/protocol/mod.ts
index 83ee8cb..0db1162 100644
--- a/client-web/source/protocol/mod.ts
+++ b/client-web/source/protocol/mod.ts
@@ -4,23 +4,22 @@
Copyright (C) 2023 metamuffin <metamuffin@disroot.org>
*/
import { ClientboundPacket, RelayMessage, RelayMessageWrapper, ServerboundPacket } from "../../../common/packets.d.ts"
+import { EventEmitter } from "../helper.ts";
import { log } from "../logger.ts"
import { crypto_encrypt, crypto_seeded_key, crypt_decrypt, crypto_hash } from "./crypto.ts"
export class SignalingConnection {
- room!: string
websocket!: WebSocket
- room_hash!: string
- key!: CryptoKey
+ room?: string
+ room_hash?: string
+ key?: CryptoKey
my_id?: number // needed for outgoing relay messages
- control_handler: (_packet: ClientboundPacket) => void = () => { }
- relay_handler: (_sender: number, _message: RelayMessage) => void = () => { }
+ control_handler = new EventEmitter<ClientboundPacket>()
+ relay_handler = new EventEmitter<[number, RelayMessage]>()
constructor() { }
- async connect(room: string): Promise<SignalingConnection> {
- this.key = await crypto_seeded_key(room)
- this.room_hash = await crypto_hash(room)
+ async connect(): Promise<SignalingConnection> {
log("ws", "connecting…")
const ws_url = new URL(`${window.location.protocol.endsWith("s:") ? "wss" : "ws"}://${window.location.host}/signaling`)
this.websocket = new WebSocket(ws_url)
@@ -44,21 +43,28 @@ export class SignalingConnection {
}
on_open() {
log("ws", "websocket opened");
- this.send_control({ join: { hash: this.room_hash } })
setInterval(() => this.send_control({ ping: null }), 30000) // stupid workaround for nginx disconnecting inactive connections
}
+
+ async join(room: string) {
+ this.room = room;
+ this.key = await crypto_seeded_key(room)
+ this.room_hash = await crypto_hash(room)
+ this.send_control({ join: { hash: this.room_hash } })
+ }
+
on_error() {
log({ scope: "ws", error: true }, "websocket error occurred!")
}
async on_message(data: string) {
const packet: ClientboundPacket = JSON.parse(data) // TODO dont crash if invalid
- this.control_handler(packet)
+ this.control_handler.dispatch(packet)
if (packet.init) this.my_id = packet.init.your_id;
if (packet.message) {
- const plain_json = await crypt_decrypt(this.key, packet.message.message)
+ const plain_json = await crypt_decrypt(this.key!, packet.message.message)
const plain: RelayMessageWrapper = JSON.parse(plain_json) // TODO make sure that protocol spec is met
if (plain.sender == packet.message.sender)
- this.relay_handler(packet.message.sender, plain.inner)
+ this.relay_handler.dispatch([packet.message.sender, plain.inner])
else {
log({ scope: "crypto", warn: true }, `message dropped: sender inconsistent (${plain.sender} != ${packet.message.sender})`)
}
@@ -71,7 +77,7 @@ export class SignalingConnection {
async send_relay(data: RelayMessage, recipient?: number | null) {
recipient ??= undefined // null -> undefined
const packet: RelayMessageWrapper = { inner: data, sender: this.my_id! }
- const message = await crypto_encrypt(this.key, JSON.stringify(packet))
+ const message = await crypto_encrypt(this.key!, JSON.stringify(packet))
this.send_control({ relay: { recipient, message } })
}
}