Invite Diagnostics + Cleanup and Reboot

This commit is contained in:
Raven Scott
2025-12-17 21:44:58 -05:00
parent 8a82681054
commit eecd85c066
7 changed files with 413 additions and 77 deletions
@@ -8,7 +8,7 @@ const { trackRequest, trackRequestWithTiming } = require('../../../maintenance/m
const { createErrorResponse } = require('../../../infrastructure/error_handler');
const execAsync = promisify(exec);
const { state } = require('../../../infrastructure/state');
const state = require('../../../infrastructure/state');
async function handleDiagnosticsRoutes(req, res) {
const urlPath = req.urlPath || new URL(req.url, `https://${req.headers.host}`).pathname;
@@ -508,7 +508,7 @@ async function handleDiagnosticsRoutes(req, res) {
try {
if (!state.diagnoseInviteIssues) {
res.writeHead(503, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invite diagnostics not available - system not fully initialized' }));
res.end(JSON.stringify({ error: 'Invite diagnostics not available - system still initializing' }));
trackRequest(urlPath, false);
return true;
}
@@ -515,6 +515,68 @@ async function handleSettingsRoutes(req, res) {
return true;
}
// POST /api/admin/clean-dns-storage - Clean DNS Pass storage and reset initialization
if (method === 'POST' && urlPath === '/api/admin/clean-dns-storage') {
try {
const { logInfo, logWarn, logError } = require('../../../infrastructure/logger');
// Safety check: warn if there are active connections
if (state.connectedPeers && state.connectedPeers.size > 0) {
logWarn('Admin', `Cleaning storage while ${state.connectedPeers.size} peers are connected - this may disrupt the network`);
}
// Safety check: warn if this is a master node with initialized DNS pass
if (state.isMaster && state.dnsPass) {
logWarn('Admin', 'Cleaning storage on a master node that has initialized DNS pass - other nodes may be affected');
}
logWarn('Admin', 'Cleaning DNS Pass storage as requested by user');
// Get storage directory
const storageDir = process.env.STORAGE_DIR || './my-storage';
// Clean the storage directory (same logic as --clean flag)
try {
await fs.rm(storageDir, { recursive: true, force: true });
logInfo('Admin', `Cleaned DNS Pass storage directory: ${storageDir}`);
} catch (err) {
// Ignore if directory doesn't exist
if (err.code !== 'ENOENT') {
throw err;
}
}
// Reset state variables that depend on the storage
state.dnsPass = null;
state.consecutiveInviteFailures = 0; // Reset failure counter
// Note: We don't reset the keypair or other persistent state, only the DNS Pass data
logInfo('Admin', 'DNS Pass storage cleaned and state reset successfully');
// Send success response before shutting down
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
success: true,
message: 'DNS Pass storage cleaned. Shutting down for reinitialization...',
storageDir: storageDir,
shutdownInitiated: true,
restartInstructions: 'Process will shut down. Restart manually with: sudo node p2ns.js' + (state.isMaster ? ' --master' : '')
}));
// Trigger graceful shutdown after sending response
setTimeout(() => {
logInfo('Admin', 'Initiating graceful shutdown after DNS storage cleanup...');
process.emit('SIGTERM');
}, 1000); // Give time for response to be sent
} catch (err) {
logError('Admin', `Failed to clean DNS storage: ${err.message}`);
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: `Failed to clean DNS storage: ${err.message}` }));
}
return true;
}
return false;
}
@@ -13,7 +13,8 @@ async function handleStatusRoutes(req, res) {
const status = {
isMaster: state.isMaster,
isConnected: !!state.dnsPass,
peersCount: state.connectedPeers.size
peersCount: state.connectedPeers.size,
pid: process.pid
};
trackRequest('/api/status', true);
res.writeHead(200, { 'Content-Type': 'application/json' });