fix(auth+room): bytes-encode password compare; replay reconnect snapshot
Two issues from the first user test pass: 1. POST /admin/login was 500'ing on any password attempt that contained non-ASCII characters (e.g. a smart-quote autofill from the browser password manager). secrets.compare_digest(str, str) requires both sides to be bytes or ASCII-only str; otherwise it raises TypeError. Encoding both sides to UTF-8 bytes before the constant-time compare makes the route degrade cleanly to 401 instead of 500. 2. Reconnecting an instructor while the session is in question_closed left the dashboard stuck on "Reveal pending..." because send_instructor_snapshot only replayed state + lobby_update + full_leaderboard for closed sessions, not the question_open and question_closed payloads needed to render the reveal card. Now we replay question_open + question_closed + full_leaderboard for the question_closed branch, so the SPA renders the full reveal immediately on reconnect without waiting for the next event.
This commit is contained in:
10
app/room.py
10
app/room.py
@@ -279,10 +279,18 @@ class RoomManager:
|
||||
}
|
||||
)
|
||||
await websocket.send_json(await self.lobby_message(sid))
|
||||
# When an instructor reconnects mid-session, replay enough payloads
|
||||
# for the SPA to render the current state without waiting for the
|
||||
# next event. Otherwise the dashboard sits on a "Reveal pending..."
|
||||
# placeholder forever.
|
||||
if session["state"] == "question_open":
|
||||
await websocket.send_json(await self.question_open_message(sid, session["current_question_idx"]))
|
||||
await websocket.send_json(await self.live_histogram_message(sid, session["current_question_idx"]))
|
||||
if session["state"] in {"question_closed", "between_questions", "finished"}:
|
||||
elif session["state"] == "question_closed":
|
||||
await websocket.send_json(await self.question_open_message(sid, session["current_question_idx"]))
|
||||
await websocket.send_json(await self.question_closed_message(sid, session["current_question_idx"]))
|
||||
await websocket.send_json(await self.full_leaderboard_message(sid))
|
||||
elif session["state"] in {"between_questions", "finished"}:
|
||||
await websocket.send_json(await self.full_leaderboard_message(sid))
|
||||
|
||||
async def open_question(self, sid: str, question_idx: int, time_limit: int | None = None) -> None:
|
||||
|
||||
Reference in New Issue
Block a user