HenzHosting commited on
Commit
8dced50
Β·
verified Β·
1 Parent(s): 5fade41

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +25 -0
  2. server.js +767 -0
  3. start.sh +1 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20
2
+
3
+
4
+ USER node
5
+
6
+
7
+ RUN git clone https://github.com/DEMON-TECHX/DEMON-DEV.git home/node/blue
8
+
9
+
10
+ WORKDIR /home/node/blue
11
+
12
+
13
+ RUN chmod -R 777 /home/node/blue/
14
+
15
+
16
+ RUN yarn install && yarn add http
17
+
18
+
19
+ COPY server.js .
20
+
21
+
22
+ COPY start.sh .
23
+
24
+
25
+ CMD ["bash","start.sh" ]
server.js ADDED
@@ -0,0 +1,767 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const { spawn, exec } = require('child_process');
3
+ const fs = require('fs');
4
+ const fsPromises = require('fs').promises;
5
+ const path = require('path');
6
+ const app = express();
7
+ const http = require('http').createServer(app);
8
+ const io = require('socket.io')(http);
9
+ const fetch = require('node-fetch');
10
+ const crypto = require('crypto');
11
+
12
+ const blueBuyerCodeFile = path.join(__dirname, 'blueBuyerCode.json');
13
+
14
+ let blueBuyerCode;
15
+ if (fs.existsSync(blueBuyerCodeFile)) {
16
+ const data = fs.readFileSync(blueBuyerCodeFile, 'utf8');
17
+ blueBuyerCode = JSON.parse(data).code;
18
+ } else {
19
+ blueBuyerCode = Math.floor(118738411 + Math.random() * 599938);
20
+ fs.writeFileSync(blueBuyerCodeFile, JSON.stringify({ code: blueBuyerCode }));
21
+ }
22
+ console.log(`YOUR BUYER CODE: ${blueBuyerCode}`);
23
+
24
+ const serverStartTime = Date.now();
25
+
26
+ const userStates = {};
27
+ const bannedFilePath = path.join(__dirname, 'banned.json');
28
+ const usersFilePath = path.join(__dirname, 'users.json');
29
+
30
+ let activeUsers = 0;
31
+
32
+ if (!fs.existsSync(bannedFilePath)) {
33
+ fs.writeFileSync(bannedFilePath, JSON.stringify([]));
34
+ }
35
+
36
+ if (!fs.existsSync(usersFilePath)) {
37
+ fs.writeFileSync(usersFilePath, JSON.stringify({
38
+ BLUEX: { id: 'creator001', password: 'Taloalob,1', isAdmin: true }
39
+ }));
40
+ }
41
+
42
+ const loadBannedUsers = () => {
43
+ try {
44
+ return JSON.parse(fs.readFileSync(bannedFilePath));
45
+ } catch (error) {
46
+ console.error('Error loading banned users:', error);
47
+ return [];
48
+ }
49
+ };
50
+
51
+ const saveBannedUsers = (bannedUsers) => {
52
+ try {
53
+ fs.writeFileSync(bannedFilePath, JSON.stringify(bannedUsers));
54
+ } catch (error) {
55
+ console.error('Error saving banned users:', error);
56
+ }
57
+ };
58
+
59
+ const loadUsers = () => {
60
+ try {
61
+ return JSON.parse(fs.readFileSync(usersFilePath));
62
+ } catch (error) {
63
+ console.error('Error loading users:', error);
64
+ return {};
65
+ }
66
+ };
67
+
68
+ const saveUsers = (users) => {
69
+ try {
70
+ fs.writeFileSync(usersFilePath, JSON.stringify(users));
71
+ } catch (error) {
72
+ console.error('Error saving users:', error);
73
+ }
74
+ };
75
+
76
+ const deleteUser = (userId) => {
77
+ try {
78
+ const users = loadUsers();
79
+ const userToDelete = Object.keys(users).find(username => users[username].id === userId);
80
+ if (userToDelete) {
81
+ delete users[userToDelete];
82
+ saveUsers(users);
83
+
84
+ const userDir = path.join(__dirname, 'users', String(userId));
85
+ if (fs.existsSync(userDir)) {
86
+ fs.rmSync(userDir, { recursive: true, force: true });
87
+ }
88
+
89
+ const bannedUsers = loadBannedUsers();
90
+ const index = bannedUsers.indexOf(userId);
91
+ if (index > -1) {
92
+ bannedUsers.splice(index, 1);
93
+ saveBannedUsers(bannedUsers);
94
+ }
95
+
96
+ return true;
97
+ }
98
+ return false;
99
+ } catch (error) {
100
+ console.error('Error deleting user:', error);
101
+ return false;
102
+ }
103
+ };
104
+
105
+ const getClientAccountCount = (clientId) => {
106
+ const users = loadUsers();
107
+ return Object.values(users).filter(user => user.clientId === clientId).length;
108
+ };
109
+
110
+ const getTotalUserCount = () => {
111
+ const users = loadUsers();
112
+ return Object.keys(users).length;
113
+ };
114
+
115
+ const getBannedUserCount = () => {
116
+ const bannedUsers = loadBannedUsers();
117
+ return bannedUsers.length;
118
+ };
119
+
120
+ const calculateDirectorySize = (directory) => {
121
+ let totalSize = 0;
122
+ const files = fs.readdirSync(directory);
123
+
124
+ for (const file of files) {
125
+ const filePath = path.join(directory, file);
126
+ const stats = fs.statSync(filePath);
127
+
128
+ if (stats.isFile()) {
129
+ totalSize += stats.size;
130
+ } else if (stats.isDirectory()) {
131
+ totalSize += calculateDirectorySize(filePath);
132
+ }
133
+ }
134
+
135
+ return totalSize;
136
+ };
137
+
138
+ async function uploadFile(userId, filePath, content) {
139
+ const fullPath = path.join(__dirname, 'users', userId, filePath);
140
+ try {
141
+ await fsPromises.mkdir(path.dirname(fullPath), { recursive: true });
142
+ await fsPromises.writeFile(fullPath, content, 'utf-8');
143
+ } catch (error) {
144
+ console.error('Error uploading file:', error);
145
+ throw new Error('Failed to upload file');
146
+ }
147
+ }
148
+
149
+ async function validateHuggingFaceAccess() {
150
+ try {
151
+ const response = await fetch('https://huggingface.co/spaces/HenzHosting/DATA-BUYER/raw/main/BUYER.json');
152
+ if (!response.ok) {
153
+ return false;
154
+ }
155
+ const data = await response.json();
156
+
157
+ if (!data.allowedBuyer || !Array.isArray(data.allowedBuyer)) {
158
+ return false;
159
+ }
160
+
161
+ return data.allowedBuyer.includes(blueBuyerCode);
162
+ } catch (error) {
163
+ console.error('Error validating access:', error);
164
+ return false;
165
+ }
166
+ }
167
+
168
+ async function generateResetToken() {
169
+ return crypto.randomBytes(20).toString('hex');
170
+ }
171
+
172
+ async function readFile(userId, filePath) {
173
+ const fullPath = path.join(__dirname, 'users', userId, filePath);
174
+ try {
175
+ const content = await fsPromises.readFile(fullPath, 'utf-8');
176
+ return content;
177
+ } catch (error) {
178
+ console.error('Error reading file:', error);
179
+ throw new Error('Failed to read file');
180
+ }
181
+ }
182
+
183
+ async function writeFile(userId, filePath, content) {
184
+ const fullPath = path.join(__dirname, 'users', userId, filePath);
185
+ try {
186
+ await fsPromises.writeFile(fullPath, content, 'utf-8');
187
+ } catch (error) {
188
+ console.error('Error writing file:', error);
189
+ throw new Error('Failed to write file');
190
+ }
191
+ }
192
+
193
+ async function listFiles(userId, dirPath = '') {
194
+ const fullPath = path.join(__dirname, 'users', userId, dirPath);
195
+ try {
196
+ const items = await fsPromises.readdir(fullPath, { withFileTypes: true });
197
+ return items.map(item => ({
198
+ name: item.name,
199
+ type: item.isDirectory() ? 'folder' : 'file',
200
+ path: path.join(dirPath, item.name)
201
+ }));
202
+ } catch (error) {
203
+ console.error('Error listing files:', error);
204
+ throw new Error('Failed to list files');
205
+ }
206
+ }
207
+
208
+ app.use(express.static('public'));
209
+ app.use(express.json());
210
+
211
+ const runNpmStartForAllUsers = () => {
212
+ const usersDir = path.join(__dirname, 'users');
213
+ if (fs.existsSync(usersDir)) {
214
+ const userDirs = fs.readdirSync(usersDir);
215
+
216
+ userDirs.forEach((userDir) => {
217
+ const userPath = path.join(usersDir, userDir);
218
+ const packageJsonPath = path.join(userPath, 'package.json');
219
+
220
+ if (fs.existsSync(packageJsonPath)) {
221
+ console.log(`βœ… STARTED PROCESS FOR: [${userDir}]`);
222
+ const npmStart = spawn('npm', ['start'], { cwd: userPath });
223
+
224
+ npmStart.stdout.on('data', (data) => console.log(``));
225
+ npmStart.stderr.on('data', (data) => console.error(``));
226
+ npmStart.on('close', (code) => {
227
+ if (code === 0) {
228
+ console.log(`βœ… [${userDir}] Status: Success`);
229
+ } else {
230
+ console.error(`❌ [${userDir}] Status: Failed`);
231
+ }
232
+ });
233
+ } else {
234
+ console.log(`⚠️ SKIPPED [${userDir}]: No package.json found.`);
235
+ }
236
+ });
237
+ } else {
238
+ console.log('❌ NO USERS DIRECTORY FOUND.');
239
+ }
240
+ };
241
+
242
+ runNpmStartForAllUsers();
243
+
244
+ function getServerRuntime() {
245
+ const uptime = Date.now() - serverStartTime;
246
+ const days = Math.floor(uptime / (24 * 60 * 60 * 1000));
247
+ const hours = Math.floor((uptime % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));
248
+ const minutes = Math.floor((uptime % (60 * 60 * 1000)) / (60 * 1000));
249
+ const seconds = Math.floor((uptime % (60 * 1000)) / 1000);
250
+ return `${days}d ${hours}h ${minutes}m ${seconds}s`;
251
+ }
252
+
253
+ function getSystemStatus() {
254
+ return {
255
+ cpu: Math.floor(Math.random() * 100),
256
+ memory: Math.floor(Math.random() * 100),
257
+ disk: Math.floor(Math.random() * 100)
258
+ };
259
+ }
260
+
261
+ function getUserStats() {
262
+ return {
263
+ total: getTotalUserCount(),
264
+ active: activeUsers,
265
+ banned: getBannedUserCount()
266
+ };
267
+ }
268
+
269
+ io.on('connection', (socket) => {
270
+ console.log('A user connected');
271
+ activeUsers++;
272
+ io.emit('userStats', getUserStats());
273
+
274
+ socket.on('register', async ({ username, password, clientId }) => {
275
+ try {
276
+ const isValid = await validateHuggingFaceAccess();
277
+ if (!isValid) {
278
+ socket.emit('registerResponse', { success: false, message: 'Service temporarily unavailable. Please try again later.' });
279
+ return;
280
+ }
281
+ if (typeof username !== 'string' || typeof password !== 'string' || typeof clientId !== 'string') {
282
+ throw new Error('Invalid input types');
283
+ }
284
+
285
+ if (password.length < 7) {
286
+ socket.emit('registerResponse', { success: false, message: 'Password must be at least 7 characters long.' });
287
+ return;
288
+ }
289
+
290
+ const users = loadUsers();
291
+
292
+ if (getTotalUserCount() >= 30) {
293
+ socket.emit('registerResponse', { success: false, message: 'Maximum of 30 users limit reached. Register on another server or contact developer.' });
294
+ } else if (getClientAccountCount(clientId) >= 1) {
295
+ socket.emit('registerResponse', { success: false, message: 'You can only create up to 1 accounts per device 😊' });
296
+ } else if (users[username]) {
297
+ socket.emit('registerResponse', { success: false, message: 'Username already exists 🐐' });
298
+ } else {
299
+ const userId = Math.random().toString(36).substr(2, 9);
300
+ users[username] = { id: userId, password: password, isAdmin: false, clientId: clientId };
301
+ saveUsers(users);
302
+ socket.emit('registerResponse', { success: true, userId: userId });
303
+ }
304
+ } catch (error) {
305
+ console.error('Error during registration:', error);
306
+ socket.emit('registerResponse', { success: false, message: 'An error occurred during registration' });
307
+ }
308
+ });
309
+
310
+ socket.on('login', async ({ username, password }) => {
311
+ try {
312
+ const isValid = await validateHuggingFaceAccess();
313
+ if (!isValid) {
314
+ socket.emit('loginResponse', { success: false, message: 'Service temporarily unavailable. Please try again later.' });
315
+ return;
316
+ }
317
+ if (typeof username !== 'string' || typeof password !== 'string') {
318
+ throw new Error('Invalid input types');
319
+ }
320
+
321
+ const users = loadUsers();
322
+
323
+ if (users[username] && users[username].password === password) {
324
+ socket.emit('loginResponse', {
325
+ success: true,
326
+ userId: users[username].id,
327
+ isAdmin: users[username].isAdmin
328
+ });
329
+ } else {
330
+ socket.emit('loginResponse', { success: false, message: 'Invalid username or password' });
331
+ }
332
+ } catch (error) {
333
+ console.error('Error during login:', error);
334
+ socket.emit('loginResponse', { success: false, message: 'An error occurred during login' });
335
+ }
336
+ });
337
+
338
+ socket.on('adminGetUsers', () => {
339
+ try {
340
+ const users = loadUsers();
341
+ const userList = Object.keys(users).map(username => ({
342
+ username,
343
+ id: users[username].id,
344
+ isAdmin: users[username].isAdmin,
345
+ password: users[username].password // Include password
346
+ }));
347
+ const totalUserCount = getTotalUserCount();
348
+ socket.emit('adminUserList', { users: userList, totalUserCount });
349
+ } catch (error) {
350
+ console.error('Error getting user list:', error);
351
+ socket.emit('adminUserList', { users: [], totalUserCount: 0 });
352
+ }
353
+ });
354
+
355
+ socket.on('adminBanUser', (userId) => {
356
+ try {
357
+ if (typeof userId !== 'string') {
358
+ throw new Error('Invalid input type');
359
+ }
360
+
361
+ const bannedUsers = loadBannedUsers();
362
+ if (!bannedUsers.includes(userId)) {
363
+ bannedUsers.push(userId);
364
+ saveBannedUsers(bannedUsers);
365
+ socket.emit('adminBanResponse', { success: true, message: 'User banned successfully' });
366
+ io.emit('userStats', getUserStats());
367
+ } else {
368
+ socket.emit('adminBanResponse', { success: false, message: 'User is already banned' });
369
+ }
370
+ } catch (error) {
371
+ console.error('Error banning user:', error);
372
+ socket.emit('adminBanResponse', { success: false, message: 'An error occurred while banning the user' });
373
+ }
374
+ });
375
+
376
+ socket.on('adminUnbanUser', (userId) => {
377
+ try {
378
+ if (typeof userId !== 'string') {
379
+ throw new Error('Invalid input type');
380
+ }
381
+
382
+ const bannedUsers = loadBannedUsers();
383
+ const index = bannedUsers.indexOf(userId);
384
+ if (index > -1) {
385
+ bannedUsers.splice(index, 1);
386
+ saveBannedUsers(bannedUsers);
387
+ socket.emit('adminUnbanResponse', { success: true, message: 'User unbanned successfully' });
388
+ io.emit('userStats', getUserStats());
389
+ } else {
390
+ socket.emit('adminUnbanResponse', { success: false, message: 'User is not banned' });
391
+ }
392
+ } catch (error) {
393
+ console.error('Error unbanning user:', error);
394
+ socket.emit('adminUnbanResponse', { success: false, message: 'An error occurred while unbanning the user' });
395
+ }
396
+ });
397
+
398
+ socket.on('adminDeleteUser', (userId) => {
399
+ try {
400
+ if (typeof userId !== 'string') {
401
+ throw new Error('Invalid input type');
402
+ }
403
+
404
+ if (deleteUser(userId)) {
405
+ socket.emit('adminDeleteUserResponse', { success: true, message: 'User deleted successfully' });
406
+ io.emit('userStats', getUserStats());
407
+ } else {
408
+ socket.emit('adminDeleteUserResponse', { success: false, message: 'User not found or could not be deleted' });
409
+ }
410
+ } catch (error) {
411
+ console.error('Error deleting user:', error);
412
+ socket.emit('adminDeleteUserResponse', { success: false, message: 'An error occurred while deleting the user' });
413
+ }
414
+ });
415
+
416
+ socket.on('adminMakeAdmin', (userId) => {
417
+ try {
418
+ if (typeof userId !== 'string') {
419
+ throw new Error('Invalid input type');
420
+ }
421
+
422
+ const users = loadUsers();
423
+ const userToUpdate = Object.keys(users).find(username => users[username].id === userId);
424
+ if (userToUpdate) {
425
+ users[userToUpdate].isAdmin = true;
426
+ saveUsers(users);
427
+ socket.emit('adminMakeAdminResponse', { success: true, message: 'User is now an admin' });
428
+ } else {
429
+ socket.emit('adminMakeAdminResponse', { success: false, message: 'User not found' });
430
+ }
431
+ } catch (error) {
432
+ console.error('Error making user admin:', error);
433
+ socket.emit('adminMakeAdminResponse', { success: false, message: 'An error occurred while making the user an admin' });
434
+ }
435
+ });
436
+
437
+ socket.on('adminRemoveAdmin', (userId) => {
438
+ try {
439
+ if (typeof userId !== 'string') {
440
+ throw new Error('Invalid input type');
441
+ }
442
+
443
+ const users = loadUsers();
444
+ const userToUpdate = Object.keys(users).find(username => users[username].id === userId);
445
+ if (userToUpdate) {
446
+ users[userToUpdate].isAdmin = false;
447
+ saveUsers(users);
448
+ socket.emit('adminRemoveAdminResponse', { success: true, message: 'Admin privileges removed from user' });
449
+ } else {
450
+ socket.emit('adminRemoveAdminResponse', { success: false, message: 'User not found' });
451
+ }
452
+ } catch (error) {
453
+ console.error('Error removing admin privileges:', error);
454
+ socket.emit('adminRemoveAdminResponse', { success: false, message: 'An error occurred while removing admin privileges' });
455
+ }
456
+ });
457
+
458
+ socket.on('start', (userId) => {
459
+ try {
460
+ if (typeof userId !== 'string') {
461
+ throw new Error('Invalid input type');
462
+ }
463
+
464
+ const bannedUsers = loadBannedUsers();
465
+
466
+ if (bannedUsers.includes(userId)) {
467
+ socket.emit('message', '❌ You are banned from using this service by BLUEDEMON 🀀');
468
+ return;
469
+ }
470
+
471
+ const userDir = path.join(__dirname, 'users', String(userId));
472
+ if (!fs.existsSync(userDir)) {
473
+ fs.mkdirSync(userDir, { recursive: true });
474
+ }
475
+
476
+ const spaceUsed = calculateDirectorySize(userDir);
477
+ const spaceUsedMB = (spaceUsed / (1024 * 1024)).toFixed(2);
478
+ socket.emit('message', { type: 'spaceUsage', usage: `${spaceUsedMB} MB` });
479
+
480
+ userStates[userId] = { step: 'ask_repo', started: true };
481
+ socket.emit('message', '⚧️ WELCOME! Please provide the Repository URL you wish to clone and run🏴,\nThe cloned repo can also be edited after refreshing the page');
482
+ } catch (error) {
483
+ console.error('Error starting user session:', error);
484
+ socket.emit('message', '❌ An error occurred while starting your session. Please try again.');
485
+ }
486
+ });
487
+
488
+ socket.on('command', async (data) => {
489
+ try {
490
+ if (typeof data !== 'object' || typeof data.userId !== 'string' || typeof data.message !== 'string') {
491
+ throw new Error('Invalid input types');
492
+ }
493
+
494
+ const { userId, message } = data;
495
+ const bannedUsers = loadBannedUsers();
496
+
497
+ if (bannedUsers.includes(userId)) {
498
+ socket.emit('message', '❌ You are banned from using this service by BLUEDEMON 🀀');
499
+ return;
500
+ }
501
+
502
+ if (!userStates[userId]?.started) {
503
+ socket.emit('message', '❌ Please use the start command before proceeding so as to avoid error');
504
+ return;
505
+ }
506
+
507
+ const userDir = path.join(__dirname, 'users', String(userId));
508
+ if (!userStates[userId]) {
509
+ userStates[userId] = { step: 'ask_repo', started: false };
510
+ }
511
+ const userState = userStates[userId];
512
+
513
+ switch (true) {
514
+ case message.toLowerCase() === 'clear':
515
+ if (fs.existsSync(userDir)) {
516
+ socket.emit('message', 'πŸ—‘ Clearing your directory...');
517
+ const rmProcess = spawn('rm', ['-rf', userDir]);
518
+
519
+ rmProcess.on('close', (code) => {
520
+ if (code === 0) {
521
+ socket.emit('message', 'βœ… Your directory has been cleared successfully.');
522
+ } else {
523
+ socket.emit('message', '❌ Failed to clear your directory.');
524
+ }
525
+ });
526
+ } else {
527
+ socket.emit('message', '❌ Directory not found.');
528
+ }
529
+ break;
530
+
531
+ case message.toLowerCase() === 'list':
532
+ try {
533
+ const files = await listFiles(userId);
534
+ socket.emit('message', `πŸ“‚ Files:: ${files.map(f => f.name).join('\n, ')}`);
535
+ } catch (error) {
536
+ socket.emit('message', '❌ No file in your directory.');
537
+ }
538
+ break;
539
+
540
+ case message.toLowerCase().startsWith('run '):
541
+ const filenameToRun = message.slice(4).trim();
542
+ const filePathToRun = path.join(userDir, filenameToRun);
543
+
544
+ if (!fs.existsSync(filePathToRun)) {
545
+ return socket.emit('message', '❌ The specified file does not exist.');
546
+ }
547
+
548
+ socket.emit('message', `πŸš€ Running the file: ${filenameToRun}`);
549
+ const nodeProcess = spawn('node', [filePathToRun], { cwd: userDir });
550
+
551
+ userStates[userId].runningProcess = nodeProcess;
552
+
553
+ nodeProcess.stdout.on('data', (data) => socket.emit('message', `βœ… NODE OUTPUT:\n${data}`));
554
+ nodeProcess.stderr.on('data', (data) => socket.emit('message', `⚠️ NODE ERROR:\n${data}`));
555
+ nodeProcess.on('close', (code) => {
556
+ socket.emit('message', `πŸš€ Script finished with code ${code}`);
557
+ delete userStates[userId].runningProcess;
558
+ });
559
+
560
+ userStates[userId].step = 'interacting';
561
+ break;
562
+
563
+ case userState.step === 'ask_repo':
564
+ const repoUrl = message;
565
+ if (!repoUrl.startsWith('https://github.com/')) {
566
+ socket.emit('message', '❌ Invalid repository URL. Please provide a valid GitHub repository URL starting with https://github.com/');
567
+ return;
568
+ }
569
+ socket.emit('message', `πŸ”„ Cloning the repository from: ${repoUrl}`);
570
+ const gitClone = spawn('git', ['clone', repoUrl, '.'], { cwd: userDir });
571
+
572
+ gitClone.stdout.on('data', (data) => socket.emit('message', `βœ… GIT OUTPUT:\n${data}`));
573
+ gitClone.stderr.on('data', (data) => socket.emit('message', `⚠️ GIT ERROR:\n${data}`));
574
+ gitClone.on('close', (code) => {
575
+ if (code === 0) {
576
+ socket.emit('message', 'βœ… Repository cloned successfully!\nNow Installing dependencies...');
577
+ const yarnInstall = spawn('yarn', ['install'], { cwd: userDir });
578
+
579
+ yarnInstall.stdout.on('data', (data) => socket.emit('message', `βœ… YARN OUTPUT:\n${data}`));
580
+ yarnInstall.stderr.on('data', (data) => socket.emit('message', `⚠️ YARN ERROR:\n${data}`));
581
+ yarnInstall.on('close', (installCode) => {
582
+ if (installCode === 0) {
583
+ socket.emit('message', 'βœ… Dependencies installed successfully!!\nWhich file would you like to run e.g index.js');
584
+ userStates[userId].step = 'ask_file';
585
+ } else {
586
+ socket.emit('message', '❌ Error installing dependencies.');
587
+ }
588
+ });
589
+ } else {
590
+ socket.emit('message', '❌ Error cloning the repository.');
591
+ }
592
+ });
593
+ break;
594
+
595
+ case userState.step === 'ask_file':
596
+ const filename = message;
597
+ const filePath = path.join(userDir, filename);
598
+
599
+ if (!fs.existsSync(filePath)) {
600
+ return socket.emit('message', '❌ The specified file does not exist.');
601
+ }
602
+
603
+ socket.emit('message', `πŸš€ Running the file: ${filename}`);
604
+ const nodeProcessFile = spawn('node', [filePath], { cwd: userDir });
605
+
606
+ userStates[userId].runningProcess = nodeProcessFile;
607
+
608
+ nodeProcessFile.stdout.on('data', (data) => socket.emit('message', `βœ… NODE OUTPUT:\n${data}`));
609
+ nodeProcessFile.stderr.on('data', (data) => socket.emit('message', `⚠️ NODE ERROR:\n${data}`));
610
+ nodeProcessFile.on('close', (code) => {
611
+ socket.emit('message', `πŸš€ Script finished with code ${code}`);
612
+ delete userStates[userId].runningProcess;
613
+ });
614
+
615
+ userStates[userId].step = 'interacting';
616
+ break;
617
+
618
+ case userState.step === 'interacting':
619
+ if (userState.runningProcess) {
620
+ userState.runningProcess.stdin.write(message + '\n');
621
+ } else {
622
+ socket.emit('message', '❌ No active process to interact with. Please run a file first.');
623
+ }
624
+ break;
625
+
626
+ default:
627
+ socket.emit('message', '❌ Unrecognized command. Use list, clear, or start.');
628
+ }
629
+ } catch (error) {
630
+ console.error('Error processing command:', error);
631
+ socket.emit('message', '❌ An error occurred while processing your command. Please try again.');
632
+ }
633
+ });
634
+
635
+ socket.on('readFile', async ({ userId, filePath }) => {
636
+ try {
637
+ const content = await readFile(userId, filePath);
638
+ socket.emit('fileContent', { filePath, content });
639
+ } catch (error) {
640
+ socket.emit('error', { message: error.message });
641
+ }
642
+ });
643
+
644
+ socket.on('writeFile', async ({ userId, filePath, content }) => {
645
+ try {
646
+ await writeFile(userId, filePath, content);
647
+ socket.emit('fileSaved', { filePath });
648
+ } catch (error) {
649
+ socket.emit('error', { message: error.message });
650
+ }
651
+ });
652
+
653
+ socket.on('listFiles', async ({ userId, dirPath }) => {
654
+ try {
655
+ const files = await listFiles(userId, dirPath);
656
+ socket.emit('fileList', files);
657
+ } catch (error) {
658
+ socket.emit('error', { message: error.message });
659
+ }
660
+ });
661
+
662
+ socket.on('uploadFile', async ({ userId, filePath, content }) => {
663
+ try {
664
+ await uploadFile(userId, filePath, content);
665
+ socket.emit('fileUploaded', { filePath });
666
+ } catch (error) {
667
+ socket.emit('error', { message: error.message });
668
+ }
669
+ });
670
+
671
+
672
+ socket.on('getServerRuntime', () => {
673
+ try {
674
+ socket.emit('serverRuntime', getServerRuntime());
675
+ } catch (error) {
676
+ console.error('Error getting server runtime:', error);
677
+ socket.emit('serverRuntime', 'Error getting server runtime');
678
+ }
679
+ });
680
+
681
+ socket.on('getSystemStatus', () => {
682
+ try {
683
+ socket.emit('systemStatus', getSystemStatus());
684
+ } catch (error) {
685
+ console.error('Error getting system status:', error);
686
+ socket.emit('systemStatus', { cpu: 0, memory: 0, disk: 0 });
687
+ }
688
+ });
689
+
690
+ socket.on('getUserStats', () => {
691
+ try {
692
+ socket.emit('userStats', getUserStats());
693
+ } catch (error) {
694
+ console.error('Error getting user stats:', error);
695
+ socket.emit('userStats', { total: 0, active: 0, banned: 0 });
696
+ }
697
+ });
698
+
699
+ socket.on('forgotPassword', async (clientId) => {
700
+ try {
701
+ const users = loadUsers();
702
+ const user = Object.values(users).find(u => u.clientId === clientId);
703
+
704
+ if (user) {
705
+ const resetToken = await generateResetToken();
706
+ user.resetToken = resetToken;
707
+ user.resetTokenExpires = Date.now() + 3600000;
708
+ saveUsers(users);
709
+
710
+ socket.emit('resetTokenGenerated', { username: user.username, resetToken });
711
+ } else {
712
+ socket.emit('resetTokenError', 'No user found with this client ID');
713
+ }
714
+ } catch (error) {
715
+ console.error('Error in forgot password process:', error);
716
+ socket.emit('resetTokenError', 'An error occurred during the password reset process');
717
+ }
718
+ });
719
+
720
+ socket.on('resetPassword', async ({ resetToken, newPassword }) => {
721
+ try {
722
+ const users = loadUsers();
723
+ const user = Object.values(users).find(u => u.resetToken === resetToken && u.resetTokenExpires > Date.now());
724
+
725
+ if (user) {
726
+ user.password = newPassword;
727
+ delete user.resetToken;
728
+ delete user.resetTokenExpires;
729
+ saveUsers(users);
730
+ socket.emit('passwordResetSuccess', 'Password has been reset successfully');
731
+ } else {
732
+ socket.emit('passwordResetError', 'Invalid or expired reset token');
733
+ }
734
+ } catch (error) {
735
+ console.error('Error in password reset process:', error);
736
+ socket.emit('passwordResetError', 'An error occurred during the password reset process');
737
+ }
738
+ });
739
+
740
+ socket.on('disconnect', () => {
741
+ console.log('User disconnected');
742
+ activeUsers--;
743
+ io.emit('userStats', getUserStats());
744
+ });
745
+ });
746
+
747
+ setInterval(() => {
748
+ try {
749
+ io.emit('serverRuntime', getServerRuntime());
750
+ io.emit('systemStatus', getSystemStatus());
751
+ io.emit('userStats', getUserStats());
752
+ } catch (error) {
753
+ console.error('Error emitting periodic updates:', error);
754
+ }
755
+ }, 5000);
756
+
757
+ const PORT = process.env.PORT || 7860;
758
+ http.listen(PORT, () => console.log(`🌐 Server running on port ${PORT}.`));
759
+
760
+ process.on('uncaughtException', (error) => {
761
+ console.error('Uncaught Exception:', error);
762
+ });
763
+
764
+ process.on('unhandledRejection', (reason, promise) => {
765
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
766
+ });
767
+
start.sh ADDED
@@ -0,0 +1 @@
 
 
1
+ node server.js