GitHub Actions commited on
Commit
1d45897
0 Parent(s):

Initial commit

Browse files
Files changed (6) hide show
  1. .gitignore +4 -0
  2. Dockerfile +29 -0
  3. README.md +10 -0
  4. index.js +204 -0
  5. package.json +17 -0
  6. temp.js +159 -0
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ node_modules/
2
+ dist/
3
+ .env
4
+ *lock.json
Dockerfile ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-slim
2
+
3
+ # Switch to the node user
4
+ USER node
5
+
6
+ # Set environment variables for the user
7
+ ENV HOME=/home/node \
8
+ PATH=/home/node/.local/bin:$PATH
9
+
10
+ # Set the working directory
11
+ WORKDIR $HOME/app
12
+
13
+ # Copy the package.json and package-lock.json files to the working directory
14
+ COPY --chown=node:node package*.json ./
15
+
16
+ # Install Node.js dependencies
17
+ RUN npm install
18
+
19
+ # Copy the application code to the working directory
20
+ COPY --chown=node:node . .
21
+
22
+ # Ensure the ownership of the directory to the node user
23
+ RUN chown -R node:node .
24
+
25
+ # Expose the port the app runs on
26
+ EXPOSE 7860
27
+
28
+ # Command to run the Node.js server
29
+ CMD ["node", "index.js"]
README.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Placemenext
3
+ emoji: 🏢
4
+ colorFrom: purple
5
+ colorTo: indigo
6
+ sdk: docker
7
+ pinned: false
8
+ ---
9
+
10
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.js ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // server.js
3
+
4
+ const express = require('express');
5
+ const http = require('http');
6
+ const WebSocket = require('ws');
7
+ const path = require('path');
8
+
9
+ const app = express();
10
+ const port = 7860;
11
+
12
+ // Serve static files (if any)
13
+ app.use(express.static('public'));
14
+
15
+ // Data structures to store client data
16
+ const clients = {};
17
+
18
+ // HTTP server
19
+ const server = http.createServer(app);
20
+
21
+ // WebSocket server
22
+ const wss = new WebSocket.Server({ server });
23
+
24
+ // Handle new WebSocket connections
25
+ wss.on('connection', (ws) => {
26
+ const clientId = generateId();
27
+ clients[clientId] = {
28
+ ws: ws,
29
+ html: '',
30
+ css: '',
31
+ url: ''
32
+ };
33
+
34
+ console.log(`Client ${clientId} connected`);
35
+
36
+ ws.on('message', (message) => {
37
+ try {
38
+ const data = JSON.parse(message);
39
+
40
+ if (data.type === 'sessionInfo') {
41
+ if(data.sessionId){
42
+ clients[clientId].sessionId = data.sessionId;
43
+ }
44
+ }
45
+
46
+ if (data.type === 'pageContent') {
47
+ clients[clientId].html = data.html;
48
+ clients[clientId].css = data.css;
49
+ clients[clientId].url = data.url;
50
+ } else if (data.type === 'userInteraction') {
51
+ // Handle user interactions if needed
52
+ console.log(`Interaction from ${clientId}:`, data);
53
+ }
54
+ } catch (e) {
55
+ console.error('Error parsing message:', e);
56
+ }
57
+ });
58
+
59
+ ws.on('close', () => {
60
+ console.log(`Client ${clientId} disconnected`);
61
+ delete clients[clientId];
62
+ });
63
+ });
64
+
65
+ // Generate a unique client ID
66
+ function generateId() {
67
+ return Math.random().toString(36).substr(2, 9);
68
+ }
69
+
70
+ // Tailwind Play CDN for including Tailwind CSS
71
+ const tailwindCDN = `<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">`;
72
+
73
+ // Route to list all active clients
74
+ app.get('/', (req, res) => {
75
+ // Get the list of active clients
76
+ const clientKeys = Object.keys(clients);
77
+
78
+ // If no clients are available
79
+ if (clientKeys.length === 0) {
80
+ return res.send(`
81
+ ${tailwindCDN}
82
+ <div class="min-h-screen flex items-center justify-center bg-gray-100">
83
+ <h1 class="text-2xl font-bold text-gray-800">No Active Clients</h1>
84
+ </div>
85
+ `);
86
+ }
87
+
88
+ // Render the list of active clients using Tailwind
89
+ let clientListHTML = `
90
+ ${tailwindCDN}
91
+ <div class="min-h-screen bg-gray-100 py-10 px-4">
92
+ <h1 class="text-4xl font-bold text-center mb-10 text-gray-800">Active Clients</h1>
93
+ <div class="max-w-4xl mx-auto">
94
+ <ul class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
95
+ `;
96
+
97
+ // Loop through each client and create a link for each one
98
+ clientKeys.forEach(clientId => {
99
+ clientListHTML += `
100
+ <li class="bg-white shadow-md rounded-lg p-6 hover:shadow-lg transition duration-300 ease-in-out">
101
+ <a href="/clientCSS/${clientId}" class="block text-lg font-semibold text-blue-600 hover:text-blue-800">
102
+ Client ID: ${clientId}
103
+ Session Name : ${clients[clientId].sessionId ?? "No Session Name"}
104
+ </a>
105
+ </li>
106
+ `;
107
+ });
108
+
109
+ clientListHTML += `
110
+ </ul>
111
+ </div>
112
+ </div>
113
+ `;
114
+
115
+ // Send the rendered HTML response
116
+ res.send(clientListHTML);
117
+ });
118
+
119
+ // Route to render the client's page
120
+ app.get('/client/:id', (req, res) => {
121
+ const client = clients[req.params.id];
122
+ if (client) {
123
+ res.send(client.html);
124
+ } else {
125
+ res.status(404).send('Client not found');
126
+ }
127
+ });
128
+
129
+ app.get('/clientCSS/:id', (req, res) => {
130
+ const client = clients[req.params.id];
131
+ if (client) {
132
+ let htmlContent = client.html;
133
+
134
+ // Inject the CSS into a style tag in the head
135
+ const cssTag = `<style>${client.css}</style>`;
136
+ htmlContent = htmlContent.replace('</head>', `${cssTag}</head>`);
137
+
138
+ //remove all script tags
139
+ htmlContent = htmlContent.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "");
140
+
141
+ //enable copy paste
142
+ htmlContent = htmlContent.replace(/-webkit-user-select: none;/gi, "");
143
+ htmlContent = htmlContent.replace(/user-select: none;/gi, "");
144
+ htmlContent = htmlContent.replace(/-moz-user-select: none;/gi, "");
145
+ htmlContent = htmlContent.replace(/-ms-user-select: none;/gi, "");
146
+ htmlContent = htmlContent.replace(/-o-user-select: none;/gi, "");
147
+
148
+ //enable right click
149
+ htmlContent = htmlContent.replace(/oncontextmenu="return false;"/gi, "");
150
+ htmlContent = htmlContent.replace(/onselectstart="return false;"/gi, "");
151
+ htmlContent = htmlContent.replace(/onselect="return false;"/gi, "");
152
+ htmlContent = htmlContent.replace(/ondragstart="return false;"/gi, "");
153
+ htmlContent = htmlContent.replace(/onmousedown="return false;"/gi, "");
154
+ htmlContent = htmlContent.replace(/onmouseup="return false;"/gi, "");
155
+ htmlContent = htmlContent.replace(/onselectstart="return false;"/gi, "");
156
+ htmlContent = htmlContent.replace(/onselect="return false;"/gi, "");
157
+ htmlContent = htmlContent.replace(/oncopy="return false;"/gi, "");
158
+
159
+ //add css to allow copy paste
160
+
161
+ //add css to allow right click
162
+
163
+ //add custom js code
164
+
165
+
166
+ htmlContent = htmlContent.replace('</body>', `<script>
167
+
168
+
169
+ function addGlobalStyle() {
170
+ const style = document.createElement('style');
171
+ style.innerHTML = ` + `"* { user-select: text !important; -webkit-user-select: text !important; -ms-user-select: text !important; cursor: text !important; }"` + `;
172
+ document.head.appendChild(style);
173
+ }
174
+
175
+ function enableCopyPaste() {
176
+ document.oncopy = null;
177
+ document.onpaste = null;
178
+ document.oncut = null;
179
+ document.oncontextmenu = null;
180
+ document.onselectstart = null;
181
+
182
+ // Also enabling right-click
183
+ document.addEventListener('contextmenu', function(e) {
184
+ e.stopPropagation(); // Stop propagation of right-click blocking
185
+ }, true);
186
+ }
187
+
188
+ // Wait for the page to load before enabling copy-paste
189
+ window.addEventListener('DOMContentLoaded', (event) => {
190
+ enableCopyPaste();
191
+ addGlobalStyle();
192
+ });
193
+ </script></body>`);
194
+
195
+ res.send(htmlContent);
196
+ } else {
197
+ res.status(404).send('Client not found');
198
+ }
199
+ });
200
+
201
+ // Start the server
202
+ server.listen(port, () => {
203
+ console.log(`Server is listening on http://localhost:${port}`);
204
+ });
package.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "node_server",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "node index.js",
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "express": "^4.21.0",
15
+ "ws": "^8.18.0"
16
+ }
17
+ }
temp.js ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const http = require('http');
3
+ const WebSocket = require('ws');
4
+ const path = require('path');
5
+
6
+ const app = express();
7
+ const port = 8080;
8
+
9
+ // Serve static files (if any)
10
+ app.use(express.static('public'));
11
+
12
+ // Data structures to store client data
13
+ const clients = {};
14
+
15
+ // HTTP server
16
+ const server = http.createServer(app);
17
+
18
+ // WebSocket server
19
+ const wss = new WebSocket.Server({ server });
20
+
21
+ // Handle new WebSocket connections
22
+ wss.on('connection', (ws) => {
23
+ let clientId = null;
24
+
25
+ ws.on('message', (message) => {
26
+ try {
27
+ const data = JSON.parse(message);
28
+
29
+ if (!clientId && data.clientId) {
30
+ clientId = data.clientId;
31
+ clients[clientId] = {
32
+ ws: ws,
33
+ html: '',
34
+ css: '',
35
+ url: ''
36
+ };
37
+ console.log(`Client ${clientId} connected`);
38
+ }
39
+
40
+ if (data.type === 'pageContent') {
41
+ clients[clientId].html = data.html;
42
+ clients[clientId].css = data.css;
43
+ clients[clientId].url = data.url;
44
+ } else if (data.type === 'keyboardEvent') {
45
+ // Relay the keyboard event to other clients
46
+ relayKeyboardEvent(data, clientId);
47
+ }
48
+ } catch (e) {
49
+ console.error('Error parsing message:', e);
50
+ }
51
+ });
52
+
53
+ ws.on('close', () => {
54
+ console.log(`Client ${clientId} disconnected`);
55
+ delete clients[clientId];
56
+ });
57
+ });
58
+
59
+ // Function to relay keyboard events to other clients
60
+ function relayKeyboardEvent(data, senderId) {
61
+ // Send the keyboard event to all connected clients except the sender
62
+ for (const [id, client] of Object.entries(clients)) {
63
+ if (id !== senderId) {
64
+ client.ws.send(JSON.stringify(data));
65
+ }
66
+ }
67
+ }
68
+
69
+ // Route to list all active clients
70
+ app.get('/clients', (req, res) => {
71
+ res.json(Object.keys(clients));
72
+ });
73
+
74
+ // Route to render the client's page
75
+ app.get('/client/:id', (req, res) => {
76
+ const client = clients[req.params.id];
77
+ if (client) {
78
+ let htmlContent = client.html;
79
+
80
+ // Inject the CSS into a style tag in the head
81
+ const cssTag = `<style>${client.css}</style>`;
82
+ htmlContent = htmlContent.replace('</head>', `${cssTag}</head>`);
83
+
84
+ // Inject the script to establish WebSocket connection
85
+ const scriptTag = `
86
+ <script>
87
+ (function() {
88
+ const socket = new WebSocket('ws://' + location.host);
89
+
90
+ const clientId = '${req.params.id}-page';
91
+
92
+ socket.addEventListener('open', () => {
93
+ console.log('WebSocket connection opened from rendered page');
94
+ });
95
+
96
+ socket.addEventListener('message', (event) => {
97
+ const data = JSON.parse(event.data);
98
+
99
+ // Ignore messages originating from this client
100
+ if (data.clientId === clientId) return;
101
+
102
+ if (data.type === 'keyboardEvent') {
103
+ simulateKeyboardEvent(data.event);
104
+ }
105
+ });
106
+
107
+ // Send keyboard events to the server
108
+ function sendKeyboardEvent(event) {
109
+ const data = {
110
+ type: 'keyboardEvent',
111
+ event: serializeKeyboardEvent(event),
112
+ clientId: clientId
113
+ };
114
+ socket.send(JSON.stringify(data));
115
+ }
116
+
117
+ // Serialize keyboard event properties
118
+ function serializeKeyboardEvent(event) {
119
+ return {
120
+ type: event.type,
121
+ key: event.key,
122
+ code: event.code,
123
+ keyCode: event.keyCode,
124
+ charCode: event.charCode,
125
+ which: event.which,
126
+ altKey: event.altKey,
127
+ ctrlKey: event.ctrlKey,
128
+ metaKey: event.metaKey,
129
+ shiftKey: event.shiftKey,
130
+ repeat: event.repeat,
131
+ isComposing: event.isComposing,
132
+ };
133
+ }
134
+
135
+ // Simulate keyboard event
136
+ function simulateKeyboardEvent(eventData) {
137
+ const event = new KeyboardEvent(eventData.type, eventData);
138
+ document.activeElement.dispatchEvent(event);
139
+ }
140
+
141
+ // Listen for keyboard events
142
+ ['keydown', 'keypress', 'keyup'].forEach(eventType => {
143
+ document.addEventListener(eventType, sendKeyboardEvent, true);
144
+ });
145
+ })();
146
+ </script>
147
+ `;
148
+ htmlContent = htmlContent.replace('</body>', `${scriptTag}</body>`);
149
+
150
+ res.send(htmlContent);
151
+ } else {
152
+ res.status(404).send('Client not found');
153
+ }
154
+ });
155
+
156
+ // Start the server
157
+ server.listen(port, () => {
158
+ console.log(`Server is listening on http://localhost:${port}`);
159
+ });