Scaffold and Phase 1
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import type { Server } from "socket.io";
|
||||
import type {
|
||||
ServerToClientEvents,
|
||||
ClientToServerEvents,
|
||||
InterServerEvents,
|
||||
SocketData,
|
||||
} from "@storybid/shared";
|
||||
|
||||
import { registerLiveAuctionHandlers } from "./live-auction.js";
|
||||
import { registerSilentAuctionHandlers } from "./silent-auction.js";
|
||||
import { verifyToken } from "../lib/jwt.js";
|
||||
|
||||
type IO = Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>;
|
||||
|
||||
export function registerSocketHandlers(io: IO): void {
|
||||
// Auth middleware – validate JWT on handshake
|
||||
io.use((socket, next) => {
|
||||
const token =
|
||||
(socket.handshake.auth["token"] as string | undefined) ??
|
||||
(socket.handshake.headers["authorization"] as string | undefined)?.replace("Bearer ", "");
|
||||
|
||||
if (!token) {
|
||||
// Allow unauthenticated connections for display board / public catalog
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
const payload = verifyToken(token);
|
||||
socket.data.bidderId = payload.role === "bidder" ? payload.sub : undefined;
|
||||
socket.data.staffId = payload.role !== "bidder" ? payload.sub : undefined;
|
||||
socket.data.role = payload.role;
|
||||
socket.data.deviceId = payload.deviceId;
|
||||
} catch {
|
||||
return next(new Error("Invalid token"));
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log(`[socket] connected ${socket.id} role=${socket.data.role ?? "guest"}`);
|
||||
|
||||
// Auto-join personal room for outbid / checkout notifications
|
||||
if (socket.data.bidderId) {
|
||||
void socket.join(`bidder:${socket.data.bidderId}`);
|
||||
}
|
||||
|
||||
// Room join/leave for event-scoped broadcasts
|
||||
socket.on("join_event", (eventId) => {
|
||||
void socket.join(`event:${eventId}`);
|
||||
});
|
||||
|
||||
socket.on("leave_event", (eventId) => {
|
||||
void socket.leave(`event:${eventId}`);
|
||||
});
|
||||
|
||||
registerLiveAuctionHandlers(io, socket);
|
||||
registerSilentAuctionHandlers(io, socket);
|
||||
|
||||
socket.on("disconnect", (reason) => {
|
||||
console.log(`[socket] disconnected ${socket.id} reason=${reason}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user