File size: 6,763 Bytes
1d45897
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

// 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/tailwindcss@2.2.19/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}`);
});