Skip to content

Commit ed68ddf

Browse files
committed
feat(logs): fixes #38 - logs via websocket
1 parent cb9ad44 commit ed68ddf

2 files changed

Lines changed: 32 additions & 13 deletions

File tree

vps-monitor-app/api/server.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,31 @@ app.post('/api/container/start', requireAuth, async (req, res) => {
119119

120120
// --- WebSocket : logs en temps réel ---
121121

122+
const wsTokens = new Map();
123+
124+
app.get('/api/ws-token', requireAuth, (_req, res) => {
125+
const token = Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
126+
wsTokens.set(token, Date.now() + 30_000);
127+
res.json({ token });
128+
});
129+
122130
const server = createServer(app);
123131
const wss = new WebSocketServer({ noServer: true });
124132

125133
server.on('upgrade', (req, socket, head) => {
126-
const mockRes = { writeHead: () => {}, end: () => {}, getHeader: () => null, setHeader: () => {} };
127-
sessionMiddleware(req, mockRes, () => {
128-
if (!req.session.authenticated) {
129-
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
130-
socket.destroy();
131-
return;
132-
}
133-
wss.handleUpgrade(req, socket, head, (ws) => {
134-
wss.emit('connection', ws, req);
135-
});
134+
const url = new URL(req.url, 'http://localhost');
135+
const token = url.searchParams.get('token');
136+
const expiry = token && wsTokens.get(token);
137+
138+
if (!expiry || Date.now() > expiry) {
139+
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
140+
socket.destroy();
141+
return;
142+
}
143+
wsTokens.delete(token);
144+
145+
wss.handleUpgrade(req, socket, head, (ws) => {
146+
wss.emit('connection', ws, req);
136147
});
137148
});
138149

vps-monitor-app/public/app.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ async function containerAction(action, name) {
2727

2828
let activeLogSocket = null;
2929

30-
function showLogs(name) {
30+
async function showLogs(name) {
3131
if (activeLogSocket) {
3232
activeLogSocket.close();
3333
activeLogSocket = null;
@@ -37,12 +37,20 @@ function showLogs(name) {
3737
const title = document.getElementById('logs-title');
3838
const content = document.getElementById('logs-content');
3939
title.textContent = `Logs — ${name}`;
40-
content.textContent = '';
40+
content.textContent = 'Connexion…';
4141
modal.classList.remove('hidden');
4242

43+
const tokenRes = await fetch('/api/ws-token');
44+
if (!tokenRes.ok) {
45+
content.textContent = 'Erreur: impossible d\'obtenir un token';
46+
return;
47+
}
48+
const { token } = await tokenRes.json();
49+
4350
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
44-
const ws = new WebSocket(`${proto}//${location.host}/ws/logs?name=${encodeURIComponent(name)}&tail=200`);
51+
const ws = new WebSocket(`${proto}//${location.host}/ws/logs?name=${encodeURIComponent(name)}&tail=200&token=${token}`);
4552
activeLogSocket = ws;
53+
content.textContent = '';
4654

4755
ws.onmessage = (e) => {
4856
content.textContent += e.data;

0 commit comments

Comments
 (0)