/** * HTTP route handlers for SSH Connection Management. * * Routes: * - POST /api/ssh/connect - Connect to SSH host * - POST /api/ssh/disconnect - Disconnect SSH * - GET /api/ssh/state - Get connection state * - POST /api/ssh/test - Test connection * - GET /api/ssh/config-hosts - Get SSH config hosts * - POST /api/ssh/resolve-host - Resolve host config * - POST /api/ssh/save-last-connection - Save last connection * - GET /api/ssh/last-connection - Get last connection */ import { createLogger } from '@shared/utils/logger'; import { ConfigManager } from '../services'; import type { SshConnectionConfig, SshConnectionManager,} from '../services/infrastructure/SshConnectionManager';import type { SshLastConnection } from '@shared/types';import type { FastifyInstance } from 'fastify'; const logger = createLogger('HTTP:ssh'); export function registerSshRoutes( app: FastifyInstance, connectionManager: SshConnectionManager, modeSwitchCallback: (mode: 'local' | 'ssh') => Promise<void>): void { const configManager = ConfigManager.getInstance(); // Connect app.post<{ Body: SshConnectionConfig }>('/api/ssh/connect', async (request) => { try { await connectionManager.connect(request.body); await modeSwitchCallback('ssh'); return { success: true, data: connectionManager.getStatus() }; } catch (err) { const message = err instanceof Error ? err.message : String(err); logger.error('SSH connect failed:', message); return { success: false, error: message }; } }); // Disconnect app.post('/api/ssh/disconnect', async () => { try { connectionManager.disconnect(); await modeSwitchCallback('local'); return { success: true, data: connectionManager.getStatus() }; } catch (err) { const message = err instanceof Error ? err.message : String(err); logger.error('SSH disconnect failed:', message); return { success: false, error: message }; } }); // Get state app.get('/api/ssh/state', async () => { return connectionManager.getStatus(); }); // Test connection app.post<{ Body: SshConnectionConfig }>('/api/ssh/test', async (request) => { try { const result = await connectionManager.testConnection(request.body); return { success: true, data: result }; } catch (err) { const message = err instanceof Error ? err.message : String(err); return { success: false, error: message }; } }); // Get config hosts app.get('/api/ssh/config-hosts', async () => { try { const hosts = await connectionManager.getConfigHosts(); return { success: true, data: hosts }; } catch (err) { const message = err instanceof Error ? err.message : String(err); logger.error('Failed to get SSH config hosts:', message); return { success: true, data: [] }; } }); // Resolve host app.post<{ Body: { alias: string } }>('/api/ssh/resolve-host', async (request) => { try { const entry = await connectionManager.resolveHostConfig(request.body.alias); return { success: true, data: entry }; } catch (err) { const message = err instanceof Error ? err.message : String(err); logger.error(`Failed to resolve SSH host "${request.body.alias}":`, message); return { success: true, data: null }; } }); // Save last connection app.post<{ Body: SshLastConnection }>('/api/ssh/save-last-connection', async (request) => { try { const config = request.body; configManager.updateConfig('ssh', { lastConnection: { host: config.host, port: config.port, username: config.username, authMethod: config.authMethod, privateKeyPath: config.privateKeyPath, }, }); return { success: true }; } catch (err) { const message = err instanceof Error ? err.message : String(err); logger.error('Failed to save SSH connection:', message); return { success: false, error: message }; } }); // Get last connection app.get('/api/ssh/last-connection', async () => { try { const config = configManager.getConfig(); return { success: true, data: config.ssh.lastConnection }; } catch (err) { const message = err instanceof Error ? err.message : String(err); logger.error('Failed to get last SSH connection:', message); return { success: true, data: null }; } });}
/**
* HTTP route handlers for SSH Connection Management.
*
* Routes:
* - POST /api/ssh/connect - Connect to SSH host
* - POST /api/ssh/disconnect - Disconnect SSH
* - GET /api/ssh/state - Get connection state
* - POST /api/ssh/test - Test connection
* - GET /api/ssh/config-hosts - Get SSH config hosts
* - POST /api/ssh/resolve-host - Resolve host config
* - POST /api/ssh/save-last-connection - Save last connection
* - GET /api/ssh/last-connection - Get last connection
*/
import { createLogger } from '@shared/utils/logger';
import { ConfigManager } from '../services';
import type {
SshConnectionConfig,
SshConnectionManager,
} from '../services/infrastructure/SshConnectionManager';
import type { SshLastConnection } from '@shared/types';
import type { FastifyInstance } from 'fastify';
const logger = createLogger('HTTP:ssh');
export function registerSshRoutes(
app: FastifyInstance,
connectionManager: SshConnectionManager,
modeSwitchCallback: (mode: 'local' | 'ssh') => Promise<void>
): void {
const configManager = ConfigManager.getInstance();
// Connect
app.post<{ Body: SshConnectionConfig }>('/api/ssh/connect', async (request) => {
try {
await connectionManager.connect(request.body);
await modeSwitchCallback('ssh');
return { success: true, data: connectionManager.getStatus() };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error('SSH connect failed:', message);
return { success: false, error: message };
}
});
// Disconnect
app.post('/api/ssh/disconnect', async () => {
try {
connectionManager.disconnect();
await modeSwitchCallback('local');
return { success: true, data: connectionManager.getStatus() };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error('SSH disconnect failed:', message);
return { success: false, error: message };
}
});
// Get state
app.get('/api/ssh/state', async () => {
return connectionManager.getStatus();
});
// Test connection
app.post<{ Body: SshConnectionConfig }>('/api/ssh/test', async (request) => {
try {
const result = await connectionManager.testConnection(request.body);
return { success: true, data: result };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
return { success: false, error: message };
}
});
// Get config hosts
app.get('/api/ssh/config-hosts', async () => {
try {
const hosts = await connectionManager.getConfigHosts();
return { success: true, data: hosts };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error('Failed to get SSH config hosts:', message);
return { success: true, data: [] };
}
});
// Resolve host
app.post<{ Body: { alias: string } }>('/api/ssh/resolve-host', async (request) => {
try {
const entry = await connectionManager.resolveHostConfig(request.body.alias);
return { success: true, data: entry };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error(`Failed to resolve SSH host "${request.body.alias}":`, message);
return { success: true, data: null };
}
});
// Save last connection
app.post<{ Body: SshLastConnection }>('/api/ssh/save-last-connection', async (request) => {
try {
const config = request.body;
configManager.updateConfig('ssh', {
lastConnection: {
host: config.host,
port: config.port,
username: config.username,
authMethod: config.authMethod,
privateKeyPath: config.privateKeyPath,
},
});
return { success: true };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error('Failed to save SSH connection:', message);
return { success: false, error: message };
}
});
// Get last connection
app.get('/api/ssh/last-connection', async () => {
try {
const config = configManager.getConfig();
return { success: true, data: config.ssh.lastConnection };
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error('Failed to get last SSH connection:', message);
return { success: true, data: null };
}
});
}