142 lines
3.5 KiB
TypeScript
142 lines
3.5 KiB
TypeScript
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<any>) {
|
|
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 <int>
|
|
used to activate device.
|
|
- devices
|
|
list devices
|
|
- startsession <uuid> "<text>"
|
|
starts a voting session
|
|
- stopsession <uuid>
|
|
stops a voting session
|
|
- votes <uuid>
|
|
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])); // '> '
|
|
}
|
|
}
|