import { serveFile } from "@std/http/file-server"; import { WSHeartbeat } from "./heartbeat.ts"; import { Registration } from "./registration.ts"; import { parseCommand } from "./commandbuilder.ts"; import { Authentication } from "./auth.ts"; import { Device } from "./device.ts"; // deno-lint-ignore no-explicit-any async function wsStartHandler(this: WebSocket, msg: MessageEvent) { const data = parseCommand(msg.data); if (data === null) return; switch (data.c as string) { case "reg_start": { new Registration(this); this.removeEventListener("message", wsStartHandler); break; } case "auth_start": { await new Authentication(this).authenticate(data); this.removeEventListener("message", wsStartHandler); break; } default: break; } } function handlePrompt(prompt: string) { let tokens = prompt.match(/(?:[^\s"]+|"[^"]*")+/g) || [] as string[]; tokens = tokens.map((v) => v.replaceAll(/"([^"]*)"+/g, "$1")); if (tokens.length === 0) return; switch (tokens[0]) { case "pin": { const pin = +tokens[1]; if (pin === 0 || isNaN(pin)) return; console.log(Registration.validate(pin) ? "great success" : "invalid pin"); break; } case "devices": { console.debug(Device.devices); break; } case "startsession": { if (tokens.length < 3) return; if (!(tokens[1] in Device.devices)) { console.log("invalid uuid"); return; } const device = Device.devices[tokens[1]]; if (!device.connected) { console.log("Device not connected."); return; } device.startSession(tokens[2]); console.log("great success"); break; } case "stopsession": { if (tokens.length < 2) return; if (!(tokens[1] in Device.devices)) { console.log("invalid uuid"); return; } const device = Device.devices[tokens[1]]; if (!device.connected) { console.log("Device not connected."); return; } device.stopSession(); console.log("great success"); break; } case "votes": { if (tokens.length < 2) return; if (!(tokens[1] in Device.devices)) { console.log("invalid uuid"); return; } const device = Device.devices[tokens[1]]; if (!device.connected) { console.log("Device not connected."); return; } console.log(device.latestVotes); } } } const WS_ROUTE = new URLPattern({ pathname: "/ws" }); Deno.serve((req) => { if (WS_ROUTE.exec(req.url) === null) { return serveFile(req, "./static/index.html"); } if (req.headers.get("upgrade") != "websocket") { return new Response(null, { status: 426 }); } const { socket, response } = Deno.upgradeWebSocket(req); new WSHeartbeat(socket); socket.addEventListener("message", wsStartHandler); return response; }); const decoder = new TextDecoder(); console.info(` Commands: - pin used to activate device. - devices list devices - startsession "" starts a voting session - stopsession stops a voting session - votes grabs the latest votes. `); Deno.stdout.write(Uint8Array.from([62, 32])); // '> ' while (true) { // ja dit is scuffed, nee het werkt niet goed, nee ik ga er niks aan doen. for await (const chunk of Deno.stdin.readable) { const prompt = decoder.decode(chunk).trim(); if (prompt !== "") handlePrompt(prompt); Deno.stdout.write(Uint8Array.from([62, 32])); // '> ' } }