function normalizeClientName(value) { return String(value || '').trim(); } function normalizeDeviceId(value) { return String(value || '').trim().replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 128); } function collectLiveConnections(liveConnections) { return Array.isArray(liveConnections) ? liveConnections : []; } async function isClientNameAvailable(pool, clientName, excludeDeviceId, liveConnections) { const normalizedName = normalizeClientName(clientName); if (!normalizedName) { return false; } const normalizedDeviceId = normalizeDeviceId(excludeDeviceId); const live = collectLiveConnections(liveConnections); const lowerName = normalizedName.toLowerCase(); try { if (pool) { const [deviceRows] = await pool.query( `SELECT device_id FROM player_onboarding_devices WHERE client_name IS NOT NULL AND TRIM(client_name) <> '' AND LOWER(TRIM(client_name)) = LOWER(TRIM(?)) AND device_id <> ? LIMIT 1`, [normalizedName, normalizedDeviceId] ); if (deviceRows.length) { return false; } } for (const connection of live) { const existingName = normalizeClientName(connection && connection.clientName ? connection.clientName : ''); if (!existingName || existingName.toLowerCase() !== lowerName) { continue; } const existingDeviceId = normalizeDeviceId(connection && (connection.deviceId || connection.clientId) ? (connection.deviceId || connection.clientId) : ''); if (normalizedDeviceId && existingDeviceId && existingDeviceId === normalizedDeviceId) { continue; } return false; } return true; } catch (_error) { for (const connection of live) { const existingName = normalizeClientName(connection && connection.clientName ? connection.clientName : ''); if (!existingName || existingName.toLowerCase() !== lowerName) { continue; } const existingDeviceId = normalizeDeviceId(connection && (connection.deviceId || connection.clientId) ? (connection.deviceId || connection.clientId) : ''); if (normalizedDeviceId && existingDeviceId && existingDeviceId === normalizedDeviceId) { continue; } return false; } return true; } } module.exports = { normalizeClientName: normalizeClientName, normalizeDeviceId: normalizeDeviceId, collectLiveConnections: collectLiveConnections, isClientNameAvailable: isClientNameAvailable };