placemenext / index.js
GitHub Actions
Initial commit
1d45897
// server.js
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const path = require('path');
const app = express();
const port = 7860;
// Serve static files (if any)
app.use(express.static('public'));
// Data structures to store client data
const clients = {};
// HTTP server
const server = http.createServer(app);
// WebSocket server
const wss = new WebSocket.Server({ server });
// Handle new WebSocket connections
wss.on('connection', (ws) => {
const clientId = generateId();
clients[clientId] = {
ws: ws,
html: '',
css: '',
url: ''
};
console.log(`Client ${clientId} connected`);
ws.on('message', (message) => {
try {
const data = JSON.parse(message);
if (data.type === 'sessionInfo') {
if(data.sessionId){
clients[clientId].sessionId = data.sessionId;
}
}
if (data.type === 'pageContent') {
clients[clientId].html = data.html;
clients[clientId].css = data.css;
clients[clientId].url = data.url;
} else if (data.type === 'userInteraction') {
// Handle user interactions if needed
console.log(`Interaction from ${clientId}:`, data);
}
} catch (e) {
console.error('Error parsing message:', e);
}
});
ws.on('close', () => {
console.log(`Client ${clientId} disconnected`);
delete clients[clientId];
});
});
// Generate a unique client ID
function generateId() {
return Math.random().toString(36).substr(2, 9);
}
// Tailwind Play CDN for including Tailwind CSS
const tailwindCDN = `<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">`;
// Route to list all active clients
app.get('/', (req, res) => {
// Get the list of active clients
const clientKeys = Object.keys(clients);
// If no clients are available
if (clientKeys.length === 0) {
return res.send(`
${tailwindCDN}
<div class="min-h-screen flex items-center justify-center bg-gray-100">
<h1 class="text-2xl font-bold text-gray-800">No Active Clients</h1>
</div>
`);
}
// Render the list of active clients using Tailwind
let clientListHTML = `
${tailwindCDN}
<div class="min-h-screen bg-gray-100 py-10 px-4">
<h1 class="text-4xl font-bold text-center mb-10 text-gray-800">Active Clients</h1>
<div class="max-w-4xl mx-auto">
<ul class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
`;
// Loop through each client and create a link for each one
clientKeys.forEach(clientId => {
clientListHTML += `
<li class="bg-white shadow-md rounded-lg p-6 hover:shadow-lg transition duration-300 ease-in-out">
<a href="/clientCSS/${clientId}" class="block text-lg font-semibold text-blue-600 hover:text-blue-800">
Client ID: ${clientId}
Session Name : ${clients[clientId].sessionId ?? "No Session Name"}
</a>
</li>
`;
});
clientListHTML += `
</ul>
</div>
</div>
`;
// Send the rendered HTML response
res.send(clientListHTML);
});
// Route to render the client's page
app.get('/client/:id', (req, res) => {
const client = clients[req.params.id];
if (client) {
res.send(client.html);
} else {
res.status(404).send('Client not found');
}
});
app.get('/clientCSS/:id', (req, res) => {
const client = clients[req.params.id];
if (client) {
let htmlContent = client.html;
// Inject the CSS into a style tag in the head
const cssTag = `<style>${client.css}</style>`;
htmlContent = htmlContent.replace('</head>', `${cssTag}</head>`);
//remove all script tags
htmlContent = htmlContent.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "");
//enable copy paste
htmlContent = htmlContent.replace(/-webkit-user-select: none;/gi, "");
htmlContent = htmlContent.replace(/user-select: none;/gi, "");
htmlContent = htmlContent.replace(/-moz-user-select: none;/gi, "");
htmlContent = htmlContent.replace(/-ms-user-select: none;/gi, "");
htmlContent = htmlContent.replace(/-o-user-select: none;/gi, "");
//enable right click
htmlContent = htmlContent.replace(/oncontextmenu="return false;"/gi, "");
htmlContent = htmlContent.replace(/onselectstart="return false;"/gi, "");
htmlContent = htmlContent.replace(/onselect="return false;"/gi, "");
htmlContent = htmlContent.replace(/ondragstart="return false;"/gi, "");
htmlContent = htmlContent.replace(/onmousedown="return false;"/gi, "");
htmlContent = htmlContent.replace(/onmouseup="return false;"/gi, "");
htmlContent = htmlContent.replace(/onselectstart="return false;"/gi, "");
htmlContent = htmlContent.replace(/onselect="return false;"/gi, "");
htmlContent = htmlContent.replace(/oncopy="return false;"/gi, "");
//add css to allow copy paste
//add css to allow right click
//add custom js code
htmlContent = htmlContent.replace('</body>', `<script>
function addGlobalStyle() {
const style = document.createElement('style');
style.innerHTML = ` + `"* { user-select: text !important; -webkit-user-select: text !important; -ms-user-select: text !important; cursor: text !important; }"` + `;
document.head.appendChild(style);
}
function enableCopyPaste() {
document.oncopy = null;
document.onpaste = null;
document.oncut = null;
document.oncontextmenu = null;
document.onselectstart = null;
// Also enabling right-click
document.addEventListener('contextmenu', function(e) {
e.stopPropagation(); // Stop propagation of right-click blocking
}, true);
}
// Wait for the page to load before enabling copy-paste
window.addEventListener('DOMContentLoaded', (event) => {
enableCopyPaste();
addGlobalStyle();
});
</script></body>`);
res.send(htmlContent);
} else {
res.status(404).send('Client not found');
}
});
// Start the server
server.listen(port, () => {
console.log(`Server is listening on http://localhost:${port}`);
});