From 34750bcdb1f2347f807da4cb6fde5b99c2130eb8 Mon Sep 17 00:00:00 2001 From: ale Date: Tue, 16 Sep 2025 02:21:07 +0200 Subject: [PATCH] room fix Signed-off-by: ale --- client/src/components/Lobby.jsx | 12 +++++-- client/src/pages/room/[slug].jsx | 60 +++++++++++++++++++++++++++++++- server/index.js | 10 ++++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/client/src/components/Lobby.jsx b/client/src/components/Lobby.jsx index 3494c4e..291d270 100644 --- a/client/src/components/Lobby.jsx +++ b/client/src/components/Lobby.jsx @@ -26,6 +26,13 @@ const LobbyScreen = () => { const handleJoinRoom = useCallback((data) => { const { email, room } = data; + + // Store user session data + if (typeof window !== 'undefined') { + localStorage.setItem('userEmail', email); + localStorage.setItem('currentRoom', room); + } + setIsLoading(false); router.push(`/room/${room}`); }, [router]); @@ -34,6 +41,7 @@ const LobbyScreen = () => { socket.on("room:join", handleJoinRoom); socket.on("error", (error) => { console.error('Socket error:', error); + alert(`Error: ${error.message || 'Failed to join room. Please check your room ID format (letters, numbers, hyphens, underscores only).'}`); setIsLoading(false); }); @@ -121,9 +129,9 @@ const LobbyScreen = () => { required autoComplete="off" value={room} - onChange={(e) => setRoom(e.target.value)} + onChange={(e) => setRoom(e.target.value.replace(/[^a-zA-Z0-9-_]/g, ''))} className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200 bg-white/50 backdrop-blur-sm" - placeholder="Enter room ID" + placeholder="Enter room ID (letters, numbers, -, _)" disabled={isLoading} /> diff --git a/client/src/pages/room/[slug].jsx b/client/src/pages/room/[slug].jsx index fed0fb1..b05148f 100644 --- a/client/src/pages/room/[slug].jsx +++ b/client/src/pages/room/[slug].jsx @@ -20,6 +20,46 @@ const RoomPage = () => { const [callButton, setCallButton] = useState(true); const [isSendButtonVisible, setIsSendButtonVisible] = useState(true); const [isConnecting, setIsConnecting] = useState(false); + const [hasJoinedRoom, setHasJoinedRoom] = useState(false); + + // Check if user came from lobby (has proper session) or direct navigation + useEffect(() => { + // Check if user has a valid session or email stored (you might want to implement proper session management) + const hasValidSession = localStorage.getItem('userEmail') || document.referrer.includes('/'); + + if (!hasValidSession && typeof window !== 'undefined') { + // User navigated directly to room page without going through lobby + console.warn('Direct navigation to room detected, redirecting to lobby'); + router.push('/'); + return; + } + + // If user has a session, mark as joined + setHasJoinedRoom(true); + }, [router]); + + // Store user email when they join from lobby + useEffect(() => { + socket.on("room:join", (data) => { + if (typeof window !== 'undefined') { + localStorage.setItem('userEmail', data.email); + localStorage.setItem('currentRoom', data.room); + } + }); + + // Listen for socket errors and provide user feedback + socket.on("error", (error) => { + console.error('Socket error:', error); + alert(`Connection Error: ${error.message || 'Something went wrong. Please try again.'}`); + // Redirect to lobby on error + router.push('/'); + }); + + return () => { + socket.off("room:join"); + socket.off("error"); + }; + }, [socket, router]); const handleUserJoined = useCallback(({ email, id }) => { console.log(`User ${email} joined the room!`); @@ -225,11 +265,27 @@ const RoomPage = () => { const handleGoBack = () => { handleEndCall(); + + // Clear session data when leaving room + if (typeof window !== 'undefined') { + localStorage.removeItem('userEmail'); + localStorage.removeItem('currentRoom'); + } + router.push('/'); }; return ( -
+ <> + {!hasJoinedRoom ? ( +
+
+
+

Verifying access...

+
+
+ ) : ( +
Room {slug} - VideoPeersJS {/* Background decorative elements */} @@ -385,6 +441,8 @@ const RoomPage = () => { /> )}
+ )} + ) } diff --git a/server/index.js b/server/index.js index 4713fa8..f1893bc 100644 --- a/server/index.js +++ b/server/index.js @@ -62,7 +62,7 @@ const io = new Server(server, { // Validation schemas const roomJoinSchema = Joi.object({ email: Joi.string().email().required(), - room: Joi.string().alphanum().min(3).max(50).required() + room: Joi.string().pattern(/^[a-zA-Z0-9-_]+$/).min(3).max(50).required() }); const callSchema = Joi.object({ @@ -121,7 +121,13 @@ io.on("connection", (socket) => { // Validate input const { error, value } = roomJoinSchema.validate(data); if (error) { - socket.emit("error", { message: "Invalid room join data" }); + let errorMessage = "Invalid room join data"; + if (error.details[0]?.context?.key === 'room') { + errorMessage = "Room ID must contain only letters, numbers, hyphens, and underscores (3-50 characters)"; + } else if (error.details[0]?.context?.key === 'email') { + errorMessage = "Please provide a valid email address"; + } + socket.emit("error", { message: errorMessage }); return; }