fixed rooms with passwd
This commit is contained in:
@@ -42,8 +42,7 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
|||||||
const token = req.query.token;
|
const token = req.query.token;
|
||||||
const guestName = req.query.guestName;
|
const guestName = req.query.guestName;
|
||||||
const password = req.query.password;
|
const password = req.query.password;
|
||||||
|
const clientIP = getClientIP(req);
|
||||||
const clientIP = getClientIP(req); // NUEVO
|
|
||||||
|
|
||||||
let userId: string;
|
let userId: string;
|
||||||
let username: string;
|
let username: string;
|
||||||
@@ -52,46 +51,21 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
|||||||
let realUserId: any;
|
let realUserId: any;
|
||||||
|
|
||||||
const room = roomService.getRoom(roomId);
|
const room = roomService.getRoom(roomId);
|
||||||
|
|
||||||
|
// 1. Validaciones básicas de existencia y Ban
|
||||||
if (!room) {
|
if (!room) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Room not found' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Room not found'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roomService.isIPBanned(roomId, clientIP)) {
|
if (roomService.isIPBanned(roomId, clientIP)) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'You have been banned from this room' }));
|
||||||
type: 'error',
|
|
||||||
message: 'You have been banned from this room'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!room) {
|
// 2. MOVIDO ARRIBA: Autenticar usuario PRIMERO para saber quién es
|
||||||
socket.send(JSON.stringify({
|
|
||||||
type: 'error',
|
|
||||||
message: 'Room not found'
|
|
||||||
}));
|
|
||||||
socket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verificar contraseña si existe
|
|
||||||
if (room.password) {
|
|
||||||
if (!password || !roomService.verifyRoomPassword(roomId, password)) {
|
|
||||||
socket.send(JSON.stringify({
|
|
||||||
type: 'error',
|
|
||||||
message: 'Invalid password'
|
|
||||||
}));
|
|
||||||
socket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Autenticar usuario o crear invitado
|
|
||||||
if (token) {
|
if (token) {
|
||||||
try {
|
try {
|
||||||
const decoded: any = jwt.verify(token, process.env.JWT_SECRET!);
|
const decoded: any = jwt.verify(token, process.env.JWT_SECRET!);
|
||||||
@@ -107,50 +81,41 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
|||||||
throw new Error('User not found');
|
throw new Error('User not found');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Invalid token' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Invalid token'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (guestName && guestName.trim()) {
|
} else if (guestName && guestName.trim()) {
|
||||||
|
// ... (Lógica de Guest se mantiene igual) ...
|
||||||
const nameToCheck = guestName.trim();
|
const nameToCheck = guestName.trim();
|
||||||
|
|
||||||
const isNameTaken = Array.from(room.users.values()).some(
|
const isNameTaken = Array.from(room.users.values()).some(
|
||||||
u => u.username.toLowerCase() === nameToCheck.toLowerCase()
|
u => u.username.toLowerCase() === nameToCheck.toLowerCase()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isNameTaken) {
|
if (isNameTaken) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Username is already taken' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Username is already taken'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
userId = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
userId = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
username = nameToCheck;
|
username = nameToCheck;
|
||||||
isGuest = true;
|
isGuest = true;
|
||||||
} else {
|
} else {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Authentication required' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Authentication required'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Determinar si es Host
|
||||||
const isHost = room.host.userId === realUserId || room.host.id === userId;
|
const isHost = room.host.userId === realUserId || room.host.id === userId;
|
||||||
|
|
||||||
console.log('WebSocket Connection:', {
|
// 4. MOVIDO ABAJO: Validar contraseña SOLO SI NO ES HOST
|
||||||
userId,
|
if (room.password && !isHost) {
|
||||||
realUserId,
|
if (!password || !roomService.verifyRoomPassword(roomId, password)) {
|
||||||
roomHostId: room.host.id,
|
socket.send(JSON.stringify({ type: 'error', message: 'Invalid password' }));
|
||||||
roomHostUserId: room.host.userId,
|
socket.close();
|
||||||
isHost
|
return;
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const userInRoom = {
|
const userInRoom = {
|
||||||
id: userId,
|
id: userId,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const RoomsApp = (function() {
|
|||||||
let modalTotalEpisodes = 0;
|
let modalTotalEpisodes = 0;
|
||||||
const MODAL_EPS_PER_PAGE = 50;
|
const MODAL_EPS_PER_PAGE = 50;
|
||||||
let currentQueue = [];
|
let currentQueue = [];
|
||||||
|
let shouldReconnect = true;
|
||||||
|
|
||||||
let configState = {
|
let configState = {
|
||||||
extension: null,
|
extension: null,
|
||||||
@@ -160,6 +161,7 @@ const RoomsApp = (function() {
|
|||||||
function handleInitialEntry(roomInfo) {
|
function handleInitialEntry(roomInfo) {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
const passwordGroup = document.getElementById('password-group');
|
const passwordGroup = document.getElementById('password-group');
|
||||||
|
const guestNameInput = document.getElementById('guest-name-input');
|
||||||
|
|
||||||
const hostInfoDiv = document.getElementById('join-host-info');
|
const hostInfoDiv = document.getElementById('join-host-info');
|
||||||
const hostAvatar = document.getElementById('join-host-avatar');
|
const hostAvatar = document.getElementById('join-host-avatar');
|
||||||
@@ -176,24 +178,31 @@ const RoomsApp = (function() {
|
|||||||
passwordGroup.dataset.required = roomInfo.hasPassword ? 'true' : 'false';
|
passwordGroup.dataset.required = roomInfo.hasPassword ? 'true' : 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token && guestNameInput) {
|
||||||
|
const parentGroup = guestNameInput.closest('.form-group') || guestNameInput;
|
||||||
|
parentGroup.style.display = 'none';
|
||||||
|
} else if (guestNameInput) {
|
||||||
|
const parentGroup = guestNameInput.closest('.form-group') || guestNameInput;
|
||||||
|
parentGroup.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
window.__roomPublicUrl = roomInfo.publicUrl || null;
|
window.__roomPublicUrl = roomInfo.publicUrl || null;
|
||||||
window.__roomExposed = roomInfo.exposed || false;
|
window.__roomExposed = roomInfo.exposed || false;
|
||||||
|
|
||||||
console.log('Room info loaded:', {
|
|
||||||
exposed: window.__roomExposed,
|
|
||||||
publicUrl: window.__roomPublicUrl
|
|
||||||
});
|
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
connectToRoom(currentRoomId);
|
connectToRoom(currentRoomId);
|
||||||
} else {
|
} else {
|
||||||
console.log('Guest user, showing modal...');
|
|
||||||
if (elements.joinRoomModal) {
|
if (elements.joinRoomModal) {
|
||||||
elements.joinRoomModal.classList.add('show');
|
elements.joinRoomModal.classList.add('show');
|
||||||
const nameInput = document.getElementById('guest-name-input');
|
|
||||||
if (nameInput) {
|
if (roomInfo.hasPassword) {
|
||||||
nameInput.value = '';
|
setTimeout(() => {
|
||||||
setTimeout(() => nameInput.focus(), 100);
|
const passInput = document.getElementById('join-password-input');
|
||||||
|
if(passInput) passInput.focus();
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
if(guestNameInput) guestNameInput.focus();
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -983,6 +992,7 @@ const RoomsApp = (function() {
|
|||||||
closeModal();
|
closeModal();
|
||||||
});
|
});
|
||||||
function connectToRoom(roomId, guestName, password) {
|
function connectToRoom(roomId, guestName, password) {
|
||||||
|
shouldReconnect = true;
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
const isTunnel = window.location.hostname.includes('trycloudflare.com');
|
const isTunnel = window.location.hostname.includes('trycloudflare.com');
|
||||||
@@ -1034,7 +1044,7 @@ const RoomsApp = (function() {
|
|||||||
|
|
||||||
ws.onclose = (event) => {
|
ws.onclose = (event) => {
|
||||||
console.log('WebSocket Disconnected:', event.code, event.reason);
|
console.log('WebSocket Disconnected:', event.code, event.reason);
|
||||||
|
if (!shouldReconnect) return;
|
||||||
if (window.AnimePlayer && typeof window.AnimePlayer.setWebSocket === 'function') {
|
if (window.AnimePlayer && typeof window.AnimePlayer.setWebSocket === 'function') {
|
||||||
window.AnimePlayer.setWebSocket(null);
|
window.AnimePlayer.setWebSocket(null);
|
||||||
}
|
}
|
||||||
@@ -1115,6 +1125,7 @@ const RoomsApp = (function() {
|
|||||||
function handleWebSocketMessage(data) {
|
function handleWebSocketMessage(data) {
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'error':
|
case 'error':
|
||||||
|
shouldReconnect = false;
|
||||||
handleConnectionError(data.message);
|
handleConnectionError(data.message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
|||||||
const token = req.query.token;
|
const token = req.query.token;
|
||||||
const guestName = req.query.guestName;
|
const guestName = req.query.guestName;
|
||||||
const password = req.query.password;
|
const password = req.query.password;
|
||||||
|
const clientIP = getClientIP(req);
|
||||||
const clientIP = getClientIP(req); // NUEVO
|
|
||||||
|
|
||||||
let userId: string;
|
let userId: string;
|
||||||
let username: string;
|
let username: string;
|
||||||
@@ -52,46 +51,21 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
|||||||
let realUserId: any;
|
let realUserId: any;
|
||||||
|
|
||||||
const room = roomService.getRoom(roomId);
|
const room = roomService.getRoom(roomId);
|
||||||
|
|
||||||
|
// 1. Validaciones básicas de existencia y Ban
|
||||||
if (!room) {
|
if (!room) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Room not found' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Room not found'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roomService.isIPBanned(roomId, clientIP)) {
|
if (roomService.isIPBanned(roomId, clientIP)) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'You have been banned from this room' }));
|
||||||
type: 'error',
|
|
||||||
message: 'You have been banned from this room'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!room) {
|
// 2. MOVIDO ARRIBA: Autenticar usuario PRIMERO para saber quién es
|
||||||
socket.send(JSON.stringify({
|
|
||||||
type: 'error',
|
|
||||||
message: 'Room not found'
|
|
||||||
}));
|
|
||||||
socket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verificar contraseña si existe
|
|
||||||
if (room.password) {
|
|
||||||
if (!password || !roomService.verifyRoomPassword(roomId, password)) {
|
|
||||||
socket.send(JSON.stringify({
|
|
||||||
type: 'error',
|
|
||||||
message: 'Invalid password'
|
|
||||||
}));
|
|
||||||
socket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Autenticar usuario o crear invitado
|
|
||||||
if (token) {
|
if (token) {
|
||||||
try {
|
try {
|
||||||
const decoded: any = jwt.verify(token, process.env.JWT_SECRET!);
|
const decoded: any = jwt.verify(token, process.env.JWT_SECRET!);
|
||||||
@@ -107,50 +81,41 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
|||||||
throw new Error('User not found');
|
throw new Error('User not found');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Invalid token' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Invalid token'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (guestName && guestName.trim()) {
|
} else if (guestName && guestName.trim()) {
|
||||||
|
// ... (Lógica de Guest se mantiene igual) ...
|
||||||
const nameToCheck = guestName.trim();
|
const nameToCheck = guestName.trim();
|
||||||
|
|
||||||
const isNameTaken = Array.from(room.users.values()).some(
|
const isNameTaken = Array.from(room.users.values()).some(
|
||||||
u => u.username.toLowerCase() === nameToCheck.toLowerCase()
|
u => u.username.toLowerCase() === nameToCheck.toLowerCase()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isNameTaken) {
|
if (isNameTaken) {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Username is already taken' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Username is already taken'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
userId = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
userId = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
username = nameToCheck;
|
username = nameToCheck;
|
||||||
isGuest = true;
|
isGuest = true;
|
||||||
} else {
|
} else {
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({ type: 'error', message: 'Authentication required' }));
|
||||||
type: 'error',
|
|
||||||
message: 'Authentication required'
|
|
||||||
}));
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Determinar si es Host
|
||||||
const isHost = room.host.userId === realUserId || room.host.id === userId;
|
const isHost = room.host.userId === realUserId || room.host.id === userId;
|
||||||
|
|
||||||
console.log('WebSocket Connection:', {
|
// 4. MOVIDO ABAJO: Validar contraseña SOLO SI NO ES HOST
|
||||||
userId,
|
if (room.password && !isHost) {
|
||||||
realUserId,
|
if (!password || !roomService.verifyRoomPassword(roomId, password)) {
|
||||||
roomHostId: room.host.id,
|
socket.send(JSON.stringify({ type: 'error', message: 'Invalid password' }));
|
||||||
roomHostUserId: room.host.userId,
|
socket.close();
|
||||||
isHost
|
return;
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const userInRoom = {
|
const userInRoom = {
|
||||||
id: userId,
|
id: userId,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const RoomsApp = (function() {
|
|||||||
let modalTotalEpisodes = 0;
|
let modalTotalEpisodes = 0;
|
||||||
const MODAL_EPS_PER_PAGE = 50;
|
const MODAL_EPS_PER_PAGE = 50;
|
||||||
let currentQueue = [];
|
let currentQueue = [];
|
||||||
|
let shouldReconnect = true;
|
||||||
|
|
||||||
let configState = {
|
let configState = {
|
||||||
extension: null,
|
extension: null,
|
||||||
@@ -160,6 +161,7 @@ const RoomsApp = (function() {
|
|||||||
function handleInitialEntry(roomInfo) {
|
function handleInitialEntry(roomInfo) {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
const passwordGroup = document.getElementById('password-group');
|
const passwordGroup = document.getElementById('password-group');
|
||||||
|
const guestNameInput = document.getElementById('guest-name-input');
|
||||||
|
|
||||||
const hostInfoDiv = document.getElementById('join-host-info');
|
const hostInfoDiv = document.getElementById('join-host-info');
|
||||||
const hostAvatar = document.getElementById('join-host-avatar');
|
const hostAvatar = document.getElementById('join-host-avatar');
|
||||||
@@ -176,24 +178,31 @@ const RoomsApp = (function() {
|
|||||||
passwordGroup.dataset.required = roomInfo.hasPassword ? 'true' : 'false';
|
passwordGroup.dataset.required = roomInfo.hasPassword ? 'true' : 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token && guestNameInput) {
|
||||||
|
const parentGroup = guestNameInput.closest('.form-group') || guestNameInput;
|
||||||
|
parentGroup.style.display = 'none';
|
||||||
|
} else if (guestNameInput) {
|
||||||
|
const parentGroup = guestNameInput.closest('.form-group') || guestNameInput;
|
||||||
|
parentGroup.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
window.__roomPublicUrl = roomInfo.publicUrl || null;
|
window.__roomPublicUrl = roomInfo.publicUrl || null;
|
||||||
window.__roomExposed = roomInfo.exposed || false;
|
window.__roomExposed = roomInfo.exposed || false;
|
||||||
|
|
||||||
console.log('Room info loaded:', {
|
|
||||||
exposed: window.__roomExposed,
|
|
||||||
publicUrl: window.__roomPublicUrl
|
|
||||||
});
|
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
connectToRoom(currentRoomId);
|
connectToRoom(currentRoomId);
|
||||||
} else {
|
} else {
|
||||||
console.log('Guest user, showing modal...');
|
|
||||||
if (elements.joinRoomModal) {
|
if (elements.joinRoomModal) {
|
||||||
elements.joinRoomModal.classList.add('show');
|
elements.joinRoomModal.classList.add('show');
|
||||||
const nameInput = document.getElementById('guest-name-input');
|
|
||||||
if (nameInput) {
|
if (roomInfo.hasPassword) {
|
||||||
nameInput.value = '';
|
setTimeout(() => {
|
||||||
setTimeout(() => nameInput.focus(), 100);
|
const passInput = document.getElementById('join-password-input');
|
||||||
|
if(passInput) passInput.focus();
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
if(guestNameInput) guestNameInput.focus();
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -983,6 +992,7 @@ const RoomsApp = (function() {
|
|||||||
closeModal();
|
closeModal();
|
||||||
});
|
});
|
||||||
function connectToRoom(roomId, guestName, password) {
|
function connectToRoom(roomId, guestName, password) {
|
||||||
|
shouldReconnect = true;
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
const isTunnel = window.location.hostname.includes('trycloudflare.com');
|
const isTunnel = window.location.hostname.includes('trycloudflare.com');
|
||||||
@@ -1034,7 +1044,7 @@ const RoomsApp = (function() {
|
|||||||
|
|
||||||
ws.onclose = (event) => {
|
ws.onclose = (event) => {
|
||||||
console.log('WebSocket Disconnected:', event.code, event.reason);
|
console.log('WebSocket Disconnected:', event.code, event.reason);
|
||||||
|
if (!shouldReconnect) return;
|
||||||
if (window.AnimePlayer && typeof window.AnimePlayer.setWebSocket === 'function') {
|
if (window.AnimePlayer && typeof window.AnimePlayer.setWebSocket === 'function') {
|
||||||
window.AnimePlayer.setWebSocket(null);
|
window.AnimePlayer.setWebSocket(null);
|
||||||
}
|
}
|
||||||
@@ -1115,6 +1125,7 @@ const RoomsApp = (function() {
|
|||||||
function handleWebSocketMessage(data) {
|
function handleWebSocketMessage(data) {
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'error':
|
case 'error':
|
||||||
|
shouldReconnect = false;
|
||||||
handleConnectionError(data.message);
|
handleConnectionError(data.message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user