#import "@preview/ilm:1.4.1": * #import "@preview/fletcher:0.5.8" as fletcher: diagram, node, edge, shapes #show link: underline #show link: set text(fill: blue) #set text(lang: "en") #show: ilm.with( title: [SchoolBOX WS], author: "Jurn Wubben", date: datetime.today(), abstract: [Websocket comminucation between the SchoolBox device and the associated server.], figure-index: (enabled: false), table-index: (enabled: false), listing-index: (enabled: false) ) = Messages == Heartbeat === Server - ```json {"c": "ping"} ``` - ```json {"e": 0, "info": "Pong missed"} ``` === Device - ```json {"c": "pong"} ``` == Registration === Server - ```json {"c": "reg_pin", "d": {"pin": 1234}} // Pin is a random integer. Length doesn't really matter, as long as it fits on the screen. ``` - ```json {"c": "reg_ok"} ``` === Device - ```json {"c": "reg_start"} ``` == Authentication === Server - ```json {"c": "auth_nonce", "d": {"nonce": "random_string"}} // Should be a long, random generated string. ``` - ```json {"c": "auth_ok"} ``` - ```json {"e": 1, "info": "Invalid packet, wrong ID."} ``` - ```json {"e": 2, "info": "Invalid signature."} // the info doesn't matter ``` - ```json {"e": 3, "info": "Logged in at other place."} // the info doesn't matter ``` === Device - ```json {"c": "auth_start", "d": {"id": "id"}} // Id that is provided with registration. ``` - ```json {"c": "auth_validate", "d": {"signature": "HMAC hash of nonce"}} ``` - The HMAC is a SHA256 with the password as the key, and the nonce as the data. - The returned signature is encoded as hex. - #link("https://git.jsw.tf/jsw/schoolbox-ws/src/commit/6acc935609d5c0de52aa752b69ccbaea84301b87/src/auth.ts#L9-L32")[Example implementation in JS.] == Session === Server - ```json {"c": "session_start", "d": {"text": "Question?"}} ``` - ```json {"c": "session_stop"} ``` === Device - ```json {"c": "session_vote", "d": {"vote": 1}} // Vote is an integer in the range of 1..5 ``` = General flow #let arrLine = (arr) => { for (i, el) in arr.enumerate() { if i == 0 or i == arr.len() { continue } edge(arr.at(i - 1), el, "-|>") } } #let l = link; #align(center, diagram( node-stroke: 1pt, node((1,0), [New connection], corner-radius: 2pt, extrude: (0, 3), name: ), node((3, 0), l()[ping], name: ), node((3, 1), l()[pong], stroke: blue, name: ), node((0,1), l()[reg_start], name: , stroke: blue), node((0,2), l()[reg_pin], name: ), node((0,3), l()[reg_ok], name: ), node((0,4), [Disconnect], name: , corner-radius: 2pt, extrude: (0, 3)), node((2,1), l()[auth_start], name: , stroke: blue), node((1,1), l()[auth error id], name: ), node((2,2), l()[auth_nonce], name: ), node((1,3), l()[auth error signature], name: ), node((2,3), l()[auth_validate], name: , stroke: blue), node((2,4), l()[auth_ok], name: ), node((1,5), [Logged in], corner-radius: 2pt, extrude: (0, 3), name: ), edge(, , "<|-|>", label: [Every 30s]), edge(, "l", , "-|>"), edge(, "r", , "-|>"), edge(, , "-|>"), edge(, , "-|>", bend: 18deg), edge(, , "-|>"), edge(, , "-|>", bend: 23deg), edge(, "d", , "-|>"), arrLine((, , , )), arrLine((, , , )), node((0,6), l()[session_start], name: ), node((0,7), l()[session_vote], name: ), node((0,8), l()[session_stop], name: ), node((2, 6), l()[auth takeover error], corner-radius: 2pt, extrude: (0, 3), name: ), edge(, "l", , "-|>"), edge(, , "-|>"), edge(, , "-|>"), edge((0, 7), (0, 7), "--|>", bend: 300deg, loop-angle: 200deg), edge(, "r", , "-|>"), edge(, "r", , "-|>") ))