Challenge 1: Add Origin Checking to verifyClient — Possible Solution ==================================================================== const wss = new WebSocketServer({ port: 8080, verifyClient(info, callback) { const allowedOrigins = ["https://example.com"]; // Check origin FIRST — reject cross-origin handshakes before even // looking at the token. if (!allowedOrigins.includes(info.origin)) { return callback(false, 403, "Forbidden origin"); } const token = new URL(info.req.url, "http://x").searchParams.get("token"); if (!isValidToken(token)) { return callback(false, 401, "Unauthorized"); } callback(true); } }); WHY THIS WORKS -------------- - Both checks live inside the SAME verifyClient function, since ws only provides one hook for handshake-time rejection — combining them means either failure prevents the 101 Switching Protocols response from ever being sent, exactly as each check does individually in the chapter. - The origin check runs FIRST, before the token check. This ordering is deliberate: if the request isn't even coming from an allowed origin, there's no reason to spend effort parsing and validating a token for it — reject the cheaper, more fundamental problem first. - Each failure returns its OWN distinct status code — 403 Forbidden for a bad origin (the request is understood, but this origin is not allowed to make it) versus 401 Unauthorized for a bad/missing token (the origin was fine, but the caller hasn't proven who they are). Using the correct specific code for each failure matters for anyone debugging a rejected handshake later — collapsing both into one generic error code would hide which check actually failed. - callback(true) is only reached if BOTH checks pass — there's no path where a request with a bad origin OR a bad token makes it through to a successful handshake.