From dc7b303526f84641c534c82e356bcc87e18401e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emirhan=20Durmu=C5=9F?= Date: Tue, 16 Sep 2025 22:29:10 +0300 Subject: [PATCH] auto change tracking added to agent provision, viewer version upgraded, ws session token extraction and ping/pong logic updated for viewer integration, --- package-lock.json | 20 +++++++-------- package.json | 6 ++--- src/services/agent-service.js | 4 +++ src/websocket/server.js | 47 ++++++++++++++++++++++++++++++++--- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index dafedaa4..0224fbf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@datasance/iofogcontroller", - "version": "3.5.3", + "version": "3.5.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@datasance/iofogcontroller", - "version": "3.5.3", + "version": "3.5.4", "hasInstallScript": true, "license": "EPL-2.0", "dependencies": { - "@datasance/ecn-viewer": "1.1.1", + "@datasance/ecn-viewer": "1.1.2", "@kubernetes/client-node": "^0.22.3", "@msgpack/msgpack": "^3.1.2", "@opentelemetry/api": "^1.9.0", @@ -19,7 +19,7 @@ "@opentelemetry/instrumentation-http": "^0.200.0", "@opentelemetry/resources": "^1.8.0", "@opentelemetry/sdk-node": "^0.200.0", - "axios": "1.11.0", + "axios": "1.12.2", "bignumber.js": "^9.3.0", "body-parser": "^1.20.3", "child_process": "1.0.2", @@ -426,9 +426,9 @@ } }, "node_modules/@datasance/ecn-viewer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@datasance/ecn-viewer/-/ecn-viewer-1.1.1.tgz", - "integrity": "sha512-moXxmZgIxfvwvE1HySLQ5iH32L+4qBoVRv8XyAPOu+2W4lJf6wPmTpVMdoplHEad0SV5Fh9wL7ak+FaZJtXluA==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@datasance/ecn-viewer/-/ecn-viewer-1.1.2.tgz", + "integrity": "sha512-JQTwGyqzhqK+oT1NyA2ngo7ZjWDTaxbBZL+obKHhdNoOXmrYB3VzEIdM/uCmGJvCYp14zgIRzWFS9O4E2/TUyg==" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", @@ -2894,9 +2894,9 @@ "dev": true }, "node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", diff --git a/package.json b/package.json index e24f8999..d37d5a08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@datasance/iofogcontroller", - "version": "3.5.3", + "version": "3.5.4", "description": "ioFog Controller project for Datasance PoT @ datasance.com \\nCopyright (c) 2023 Datasance Teknoloji A.S.", "main": "./src/main.js", "author": "Emirhan Durmus", @@ -55,7 +55,7 @@ "iofog-controller": "src/main.js" }, "dependencies": { - "@datasance/ecn-viewer": "1.1.1", + "@datasance/ecn-viewer": "1.1.2", "@kubernetes/client-node": "^0.22.3", "@msgpack/msgpack": "^3.1.2", "@opentelemetry/api": "^1.9.0", @@ -64,7 +64,7 @@ "@opentelemetry/instrumentation-http": "^0.200.0", "@opentelemetry/resources": "^1.8.0", "@opentelemetry/sdk-node": "^0.200.0", - "axios": "1.11.0", + "axios": "1.12.2", "bignumber.js": "^9.3.0", "body-parser": "^1.20.3", "child_process": "1.0.2", diff --git a/src/services/agent-service.js b/src/services/agent-service.js index 24fb0080..b8bf4512 100644 --- a/src/services/agent-service.js +++ b/src/services/agent-service.js @@ -95,6 +95,10 @@ const agentProvision = async function (provisionData, transaction) { provisionKey: provisionData.key }, transaction) + await ChangeTrackingService.update(fog.uuid, ChangeTrackingService.events.volumeMounts, transaction) + await ChangeTrackingService.update(fog.uuid, ChangeTrackingService.events.registries, transaction) + await ChangeTrackingService.update(fog.uuid, ChangeTrackingService.events.microserviceFull, transaction) + return { uuid: fog.uuid, privateKey: keyPair.privateKey diff --git a/src/websocket/server.js b/src/websocket/server.js index 57aea7ff..a44c8be4 100644 --- a/src/websocket/server.js +++ b/src/websocket/server.js @@ -267,9 +267,23 @@ class WebSocketServer { // Wrap the entire connection handling in a transaction TransactionDecorator.generateTransaction(async (transaction) => { try { - const token = req.headers.authorization + // Check for token in Authorization header first (for agent and CLI connections) + let token = req.headers.authorization + + // If no token in header, check query parameters (for React UI connections) + if (!token) { + logger.debug('Missing authentication token in header, checking query parameters') + const url = new URL(req.url, `http://${req.headers.host}`) + token = url.searchParams.get('token') + + // If token is found in query params, format it as Bearer token + if (token) { + token = `Bearer ${token}` + } + } + if (!token) { - logger.error('WebSocket connection failed: Missing authentication token') + logger.error('WebSocket connection failed: Missing authentication token neither in header nor query parameters') try { ws.close(1008, 'Missing authentication token') } catch (error) { @@ -580,7 +594,7 @@ class WebSocketServer { try { const statusMsg = { type: MESSAGE_TYPES.STDERR, - data: Buffer.from('Waiting for agent connection. Please ensure the microservice agent is running.\n'), + data: Buffer.from('Waiting for agent connection. Please ensure the microservice/agent is running.\n'), microserviceUuid: microserviceUuid, execId: 'pending', // Since we don't have execSessionId anymore timestamp: Date.now() @@ -878,6 +892,33 @@ class WebSocketServer { return } + if (msg.type === MESSAGE_TYPES.CONTROL) { + // Handle keep-alive messages from user + const controlData = msg.data.toString() + if (controlData === 'keepalive') { + // Send keep-alive response back to user + const keepAliveResponse = { + type: MESSAGE_TYPES.CONTROL, + data: Buffer.from('keepalive'), + microserviceUuid: session.microserviceUuid, + execId: execId, + timestamp: Date.now() + } + const encoded = this.encodeMessage(keepAliveResponse) + user.send(encoded, { + binary: true, + compress: false, + mask: false, + fin: true + }) + logger.debug('[RELAY] Sent keep-alive response to user:' + JSON.stringify({ + execId, + microserviceUuid: session.microserviceUuid + })) + return // Don't forward keep-alive to agent + } + } + await this.sendMessageToAgent(agent, msg, execId, session.microserviceUuid) } catch (error) { logger.error('[RELAY] Failed to process binary message:' + JSON.stringify({