From e5cd348ea961b3d84720fb57024081093560c138 Mon Sep 17 00:00:00 2001 From: Hydren <166227780+hydren-dev@users.noreply.github.com> Date: Fri, 3 Jan 2025 13:21:24 +0000 Subject: [PATCH] a --- routes/api.js | 37 ++++++++++++++++++++++++++++++++++++- views/instance/instance.ejs | 11 +++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/routes/api.js b/routes/api.js index 31debc8..8a4cede 100644 --- a/routes/api.js +++ b/routes/api.js @@ -2,6 +2,7 @@ const express = require('express'); const router = express.Router(); const { v4: uuidv4 } = require('uuid'); const bcrypt = require('bcrypt'); +const WebSocket = require('ws'); const axios = require('axios'); const { v4: uuid } = require('uuid'); const { sendPasswordResetEmail } = require('../handlers/email.js'); @@ -77,7 +78,7 @@ router.post('/api/getUser', validateApiKey, async (req, res) => { router.get('/api/auth/create-user', validateApiKey, async (req, res) => { try { - let { username, email, password, userId, admin } = req.query; // Use 'let' instead of 'const' + let { username, email, password, userId, admin } = req.query; if (!username || !email || !password) { return res.status(400).json({ error: 'Username and password are required' }); @@ -153,6 +154,40 @@ router.get('/api/instances', validateApiKey, async (req, res) => { } }); +router.ws("/api/instance/console/:id", async (ws, req) => { + if (!req.user) return ws.close(1008, "Authorization required"); + + const { id } = req.params; + const instance = await db.get(id + '_instance'); + + if (!instance || !id) return ws.close(1008, "Invalid instance or ID"); + + const node = instance.Node; + const socket = new WebSocket(`ws://${node.address}:${node.port}/exec/${instance.ContainerId}`); + + socket.onopen = () => { + socket.send(JSON.stringify({ "event": "auth", "args": [node.apiKey] })); + }; + + socket.onmessage = msg => { + ws.send(msg.data); + }; + + socket.onerror = (error) => { + ws.send('\x1b[31;1mHydraDaemon instance appears to be down') + }; + + socket.onclose = (event) => {}; + + ws.onmessage = msg => { + socket.send(msg.data); + }; + + ws.on('close', () => { + socket.close(); + }); +}); + router.post('/api/instances/deploy', validateApiKey, async (req, res) => { const { image, imagename, memory, cpu, ports, nodeId, name, user, primary, variables } = req.body; diff --git a/views/instance/instance.ejs b/views/instance/instance.ejs index 7f8d198..302d942 100644 --- a/views/instance/instance.ejs +++ b/views/instance/instance.ejs @@ -360,7 +360,12 @@ const eulaPopupHTML = ` command: '<%= instance.imageData.StopCommand %>' || 'stop', containerId: instanceId // Replace with your actual instanceId variable })); - } else { + } else if (action === 'restart') { + ws.send(JSON.stringify({ + event: `power:restart`, + containerId: instanceId // Replace with your actual instanceId variable + })); + } { ws.send(JSON.stringify({ event: `power:${action}`, containerId: instanceId @@ -494,13 +499,11 @@ const eulaPopupHTML = ` ws.onmessage = handleWebSocketMessage; ws.onclose = () => { console.log('WebSocket connection closed, attempting to reconnect...'); - showAlert('error', 'Connection Lost', 'Unable to Connect to WebSocket Please check your internet') setTimeout(initWebSocket, 1); }; ws.onerror = (error) => { console.log('WebSocket encountered an error:', error, 'Attempting to reconnect...'); - showAlert('error', 'Connection Lost', 'Unable to Connect to WebSocket Please check your internet') - setTimeout(initWebSocket, 5000); + setTimeout(initWebSocket, 1); }; }