shell-mirror 1.5.125 → 1.5.126
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mac-agent/agent.js +71 -7
- package/package.json +1 -1
- package/public/app/terminal.js +16 -1
package/mac-agent/agent.js
CHANGED
|
@@ -807,15 +807,79 @@ async function createPeerConnection(clientId) {
|
|
|
807
807
|
};
|
|
808
808
|
}
|
|
809
809
|
|
|
810
|
-
function cleanup(clientId = null) {
|
|
810
|
+
async function cleanup(clientId = null) {
|
|
811
811
|
// Disconnect client from session manager
|
|
812
812
|
if (clientId) {
|
|
813
813
|
sessionManager.disconnectClient(clientId);
|
|
814
814
|
} else {
|
|
815
|
-
// Full agent shutdown -
|
|
815
|
+
// Full agent shutdown - send final heartbeat with empty sessions BEFORE stopping heartbeat
|
|
816
|
+
logToFile('[AGENT] Sending final heartbeat with empty sessions before shutdown...');
|
|
817
|
+
|
|
818
|
+
if (heartbeatInterval) {
|
|
819
|
+
const finalHeartbeatData = JSON.stringify({
|
|
820
|
+
agentId: AGENT_ID,
|
|
821
|
+
timestamp: Date.now(),
|
|
822
|
+
activeSessions: 0,
|
|
823
|
+
sessions: [], // Empty session list to clear dashboard
|
|
824
|
+
localPort: process.env.LOCAL_PORT || 8080,
|
|
825
|
+
capabilities: ['webrtc', 'direct_websocket'],
|
|
826
|
+
status: 'shutting_down'
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
const options = {
|
|
830
|
+
hostname: 'shellmirror.app',
|
|
831
|
+
port: 443,
|
|
832
|
+
path: '/php-backend/api/agent-heartbeat.php',
|
|
833
|
+
method: 'POST',
|
|
834
|
+
headers: {
|
|
835
|
+
'Content-Type': 'application/json',
|
|
836
|
+
'Content-Length': Buffer.byteLength(finalHeartbeatData),
|
|
837
|
+
'X-Agent-Secret': 'mac-agent-secret-2024',
|
|
838
|
+
'X-Agent-ID': AGENT_ID
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
try {
|
|
843
|
+
await new Promise((resolve, reject) => {
|
|
844
|
+
const req = https.request(options, (res) => {
|
|
845
|
+
let responseData = '';
|
|
846
|
+
res.on('data', (chunk) => {
|
|
847
|
+
responseData += chunk;
|
|
848
|
+
});
|
|
849
|
+
res.on('end', () => {
|
|
850
|
+
if (res.statusCode === 200) {
|
|
851
|
+
logToFile('[AGENT] ✅ Sent final heartbeat with empty sessions');
|
|
852
|
+
resolve();
|
|
853
|
+
} else {
|
|
854
|
+
logToFile(`[AGENT] ⚠️ Final heartbeat HTTP error: ${res.statusCode}`);
|
|
855
|
+
resolve(); // Continue shutdown even if heartbeat fails
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
req.on('error', (error) => {
|
|
861
|
+
logToFile(`[AGENT] ❌ Failed to send final heartbeat: ${error.message}`);
|
|
862
|
+
resolve(); // Continue shutdown even if heartbeat fails
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
req.setTimeout(5000, () => {
|
|
866
|
+
req.destroy();
|
|
867
|
+
logToFile('[AGENT] ⚠️ Final heartbeat timed out after 5s');
|
|
868
|
+
resolve(); // Continue shutdown even if heartbeat times out
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
req.write(finalHeartbeatData);
|
|
872
|
+
req.end();
|
|
873
|
+
});
|
|
874
|
+
} catch (error) {
|
|
875
|
+
logToFile(`[AGENT] ❌ Error sending final heartbeat: ${error.message}`);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// Now stop heartbeat system
|
|
816
880
|
stopHeartbeatSystem();
|
|
817
881
|
}
|
|
818
|
-
|
|
882
|
+
|
|
819
883
|
if (dataChannel) {
|
|
820
884
|
dataChannel.close();
|
|
821
885
|
dataChannel = null;
|
|
@@ -1058,17 +1122,17 @@ function sendMessage(message) {
|
|
|
1058
1122
|
}
|
|
1059
1123
|
|
|
1060
1124
|
// Graceful shutdown handling
|
|
1061
|
-
process.on('SIGINT', () => {
|
|
1125
|
+
process.on('SIGINT', async () => {
|
|
1062
1126
|
console.log('\n[AGENT] Shutting down gracefully...');
|
|
1063
|
-
cleanup();
|
|
1127
|
+
await cleanup();
|
|
1064
1128
|
if (ws) ws.close();
|
|
1065
1129
|
if (localServer) localServer.close();
|
|
1066
1130
|
process.exit(0);
|
|
1067
1131
|
});
|
|
1068
1132
|
|
|
1069
|
-
process.on('SIGTERM', () => {
|
|
1133
|
+
process.on('SIGTERM', async () => {
|
|
1070
1134
|
console.log('\n[AGENT] Received SIGTERM, shutting down...');
|
|
1071
|
-
cleanup();
|
|
1135
|
+
await cleanup();
|
|
1072
1136
|
if (ws) ws.close();
|
|
1073
1137
|
if (localServer) localServer.close();
|
|
1074
1138
|
process.exit(0);
|
package/package.json
CHANGED
package/public/app/terminal.js
CHANGED
|
@@ -189,6 +189,7 @@ function clearConnectionTimeouts() {
|
|
|
189
189
|
if (connectionTimeoutWarning) {
|
|
190
190
|
clearTimeout(connectionTimeoutWarning.timeout10s);
|
|
191
191
|
clearTimeout(connectionTimeoutWarning.timeout30s);
|
|
192
|
+
clearTimeout(connectionTimeoutWarning.timeout60s);
|
|
192
193
|
connectionTimeoutWarning = null;
|
|
193
194
|
console.log('[CLIENT] ✅ Connection timeout warnings cleared');
|
|
194
195
|
}
|
|
@@ -310,8 +311,22 @@ function startConnection() {
|
|
|
310
311
|
}
|
|
311
312
|
}, 30000);
|
|
312
313
|
|
|
314
|
+
const timeout60s = setTimeout(() => {
|
|
315
|
+
if (!currentSession) {
|
|
316
|
+
updateConnectionStatus('disconnected');
|
|
317
|
+
setConnectionMessage('❌ Failed to connect - Agent or session unavailable', false);
|
|
318
|
+
term.write('\r\n\r\n\x1b[31m❌ Connection Failed\x1b[0m\r\n');
|
|
319
|
+
term.write('\x1b[33mThe agent or session you requested is not available.\x1b[0m\r\n');
|
|
320
|
+
term.write('\r\n\x1b[36mPossible reasons:\x1b[0m\r\n');
|
|
321
|
+
term.write(' • Agent is offline or shut down\r\n');
|
|
322
|
+
term.write(' • Session was terminated\r\n');
|
|
323
|
+
term.write(' • Network connectivity issues\r\n');
|
|
324
|
+
term.write('\r\n\x1b[36m💡 Click Dashboard to return and try another session\x1b[0m\r\n');
|
|
325
|
+
}
|
|
326
|
+
}, 60000);
|
|
327
|
+
|
|
313
328
|
// Store timeout IDs so they can be cleared on successful connection
|
|
314
|
-
connectionTimeoutWarning = { timeout10s, timeout30s };
|
|
329
|
+
connectionTimeoutWarning = { timeout10s, timeout30s, timeout60s };
|
|
315
330
|
|
|
316
331
|
initialize();
|
|
317
332
|
}
|