Config editor rename to file manager + fixed up file manager UI

This commit is contained in:
LukeGus
2025-08-17 15:57:46 -05:00
parent 22162e5b9b
commit 880907cc93
33 changed files with 223 additions and 175 deletions

View File

@@ -82,14 +82,14 @@ sqlite.exec(`
enable_terminal INTEGER NOT NULL DEFAULT 1,
enable_tunnel INTEGER NOT NULL DEFAULT 1,
tunnel_connections TEXT,
enable_config_editor INTEGER NOT NULL DEFAULT 1,
enable_file_manager INTEGER NOT NULL DEFAULT 1,
default_path TEXT,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS config_editor_recent (
CREATE TABLE IF NOT EXISTS file_manager_recent (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
host_id INTEGER NOT NULL,
@@ -100,7 +100,7 @@ sqlite.exec(`
FOREIGN KEY (host_id) REFERENCES ssh_data(id)
);
CREATE TABLE IF NOT EXISTS config_editor_pinned (
CREATE TABLE IF NOT EXISTS file_manager_pinned (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
host_id INTEGER NOT NULL,
@@ -111,7 +111,7 @@ sqlite.exec(`
FOREIGN KEY (host_id) REFERENCES ssh_data(id)
);
CREATE TABLE IF NOT EXISTS config_editor_shortcuts (
CREATE TABLE IF NOT EXISTS file_manager_shortcuts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
host_id INTEGER NOT NULL,
@@ -179,14 +179,14 @@ const migrateSchema = () => {
addColumnIfNotExists('ssh_data', 'enable_terminal', 'INTEGER NOT NULL DEFAULT 1');
addColumnIfNotExists('ssh_data', 'enable_tunnel', 'INTEGER NOT NULL DEFAULT 1');
addColumnIfNotExists('ssh_data', 'tunnel_connections', 'TEXT');
addColumnIfNotExists('ssh_data', 'enable_config_editor', 'INTEGER NOT NULL DEFAULT 1');
addColumnIfNotExists('ssh_data', 'enable_file_manager', 'INTEGER NOT NULL DEFAULT 1');
addColumnIfNotExists('ssh_data', 'default_path', 'TEXT');
addColumnIfNotExists('ssh_data', 'created_at', 'TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP');
addColumnIfNotExists('ssh_data', 'updated_at', 'TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP');
addColumnIfNotExists('config_editor_recent', 'host_id', 'INTEGER NOT NULL');
addColumnIfNotExists('config_editor_pinned', 'host_id', 'INTEGER NOT NULL');
addColumnIfNotExists('config_editor_shortcuts', 'host_id', 'INTEGER NOT NULL');
addColumnIfNotExists('file_manager_recent', 'host_id', 'INTEGER NOT NULL');
addColumnIfNotExists('file_manager_pinned', 'host_id', 'INTEGER NOT NULL');
addColumnIfNotExists('file_manager_shortcuts', 'host_id', 'INTEGER NOT NULL');
logger.success('Schema migration completed');
};

View File

@@ -42,13 +42,13 @@ export const sshData = sqliteTable('ssh_data', {
enableTerminal: integer('enable_terminal', {mode: 'boolean'}).notNull().default(true),
enableTunnel: integer('enable_tunnel', {mode: 'boolean'}).notNull().default(true),
tunnelConnections: text('tunnel_connections'),
enableConfigEditor: integer('enable_config_editor', {mode: 'boolean'}).notNull().default(true),
enableConfigEditor: integer('enable_file_manager', {mode: 'boolean'}).notNull().default(true),
defaultPath: text('default_path'),
createdAt: text('created_at').notNull().default(sql`CURRENT_TIMESTAMP`),
updatedAt: text('updated_at').notNull().default(sql`CURRENT_TIMESTAMP`),
});
export const configEditorRecent = sqliteTable('config_editor_recent', {
export const configEditorRecent = sqliteTable('file_manager_recent', {
id: integer('id').primaryKey({autoIncrement: true}),
userId: text('user_id').notNull().references(() => users.id),
hostId: integer('host_id').notNull().references(() => sshData.id),
@@ -57,7 +57,7 @@ export const configEditorRecent = sqliteTable('config_editor_recent', {
lastOpened: text('last_opened').notNull().default(sql`CURRENT_TIMESTAMP`),
});
export const configEditorPinned = sqliteTable('config_editor_pinned', {
export const configEditorPinned = sqliteTable('file_manager_pinned', {
id: integer('id').primaryKey({autoIncrement: true}),
userId: text('user_id').notNull().references(() => users.id),
hostId: integer('host_id').notNull().references(() => sshData.id),
@@ -66,7 +66,7 @@ export const configEditorPinned = sqliteTable('config_editor_pinned', {
pinnedAt: text('pinned_at').notNull().default(sql`CURRENT_TIMESTAMP`),
});
export const configEditorShortcuts = sqliteTable('config_editor_shortcuts', {
export const configEditorShortcuts = sqliteTable('file_manager_shortcuts', {
id: integer('id').primaryKey({autoIncrement: true}),
userId: text('user_id').notNull().references(() => users.id),
hostId: integer('host_id').notNull().references(() => sshData.id),

View File

@@ -406,8 +406,8 @@ router.delete('/db/host/:id', authenticateJWT, async (req: Request, res: Respons
});
// Route: Get recent files (requires JWT)
// GET /ssh/config_editor/recent
router.get('/config_editor/recent', authenticateJWT, async (req: Request, res: Response) => {
// GET /ssh/file_manager/recent
router.get('/file_manager/recent', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const hostId = req.query.hostId ? parseInt(req.query.hostId as string) : null;
@@ -438,8 +438,8 @@ router.get('/config_editor/recent', authenticateJWT, async (req: Request, res: R
});
// Route: Add file to recent (requires JWT)
// POST /ssh/config_editor/recent
router.post('/config_editor/recent', authenticateJWT, async (req: Request, res: Response) => {
// POST /ssh/file_manager/recent
router.post('/file_manager/recent', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const {name, path, hostId} = req.body;
if (!isNonEmptyString(userId) || !name || !path || !hostId) {
@@ -480,8 +480,8 @@ router.post('/config_editor/recent', authenticateJWT, async (req: Request, res:
});
// Route: Remove file from recent (requires JWT)
// DELETE /ssh/config_editor/recent
router.delete('/config_editor/recent', authenticateJWT, async (req: Request, res: Response) => {
// DELETE /ssh/file_manager/recent
router.delete('/file_manager/recent', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const {name, path, hostId} = req.body;
if (!isNonEmptyString(userId) || !name || !path || !hostId) {
@@ -506,8 +506,8 @@ router.delete('/config_editor/recent', authenticateJWT, async (req: Request, res
});
// Route: Get pinned files (requires JWT)
// GET /ssh/config_editor/pinned
router.get('/config_editor/pinned', authenticateJWT, async (req: Request, res: Response) => {
// GET /ssh/file_manager/pinned
router.get('/file_manager/pinned', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const hostId = req.query.hostId ? parseInt(req.query.hostId as string) : null;
@@ -538,8 +538,8 @@ router.get('/config_editor/pinned', authenticateJWT, async (req: Request, res: R
});
// Route: Add file to pinned (requires JWT)
// POST /ssh/config_editor/pinned
router.post('/config_editor/pinned', authenticateJWT, async (req: Request, res: Response) => {
// POST /ssh/file_manager/pinned
router.post('/file_manager/pinned', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const {name, path, hostId} = req.body;
if (!isNonEmptyString(userId) || !name || !path || !hostId) {
@@ -575,8 +575,8 @@ router.post('/config_editor/pinned', authenticateJWT, async (req: Request, res:
});
// Route: Remove file from pinned (requires JWT)
// DELETE /ssh/config_editor/pinned
router.delete('/config_editor/pinned', authenticateJWT, async (req: Request, res: Response) => {
// DELETE /ssh/file_manager/pinned
router.delete('/file_manager/pinned', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const {name, path, hostId} = req.body;
if (!isNonEmptyString(userId) || !name || !path || !hostId) {
@@ -601,8 +601,8 @@ router.delete('/config_editor/pinned', authenticateJWT, async (req: Request, res
});
// Route: Get folder shortcuts (requires JWT)
// GET /ssh/config_editor/shortcuts
router.get('/config_editor/shortcuts', authenticateJWT, async (req: Request, res: Response) => {
// GET /ssh/file_manager/shortcuts
router.get('/file_manager/shortcuts', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const hostId = req.query.hostId ? parseInt(req.query.hostId as string) : null;
@@ -631,8 +631,8 @@ router.get('/config_editor/shortcuts', authenticateJWT, async (req: Request, res
});
// Route: Add folder shortcut (requires JWT)
// POST /ssh/config_editor/shortcuts
router.post('/config_editor/shortcuts', authenticateJWT, async (req: Request, res: Response) => {
// POST /ssh/file_manager/shortcuts
router.post('/file_manager/shortcuts', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const {name, path, hostId} = req.body;
if (!isNonEmptyString(userId) || !name || !path || !hostId) {
@@ -667,8 +667,8 @@ router.post('/config_editor/shortcuts', authenticateJWT, async (req: Request, re
});
// Route: Remove folder shortcut (requires JWT)
// DELETE /ssh/config_editor/shortcuts
router.delete('/config_editor/shortcuts', authenticateJWT, async (req: Request, res: Response) => {
// DELETE /ssh/file_manager/shortcuts
router.delete('/file_manager/shortcuts', authenticateJWT, async (req: Request, res: Response) => {
const userId = (req as any).userId;
const {name, path, hostId} = req.body;
if (!isNonEmptyString(userId) || !name || !path || !hostId) {

View File

@@ -959,9 +959,9 @@ router.delete('/delete-user', authenticateJWT, async (req, res) => {
const targetUserId = targetUser[0].id;
try {
db.$client.prepare('DELETE FROM config_editor_recent WHERE user_id = ?').run(targetUserId);
db.$client.prepare('DELETE FROM config_editor_pinned WHERE user_id = ?').run(targetUserId);
db.$client.prepare('DELETE FROM config_editor_shortcuts WHERE user_id = ?').run(targetUserId);
db.$client.prepare('DELETE FROM file_manager_recent WHERE user_id = ?').run(targetUserId);
db.$client.prepare('DELETE FROM file_manager_pinned WHERE user_id = ?').run(targetUserId);
db.$client.prepare('DELETE FROM file_manager_shortcuts WHERE user_id = ?').run(targetUserId);
db.$client.prepare('DELETE FROM ssh_data WHERE user_id = ?').run(targetUserId);
} catch (cleanupError) {
logger.error(`Cleanup failed for user ${username}:`, cleanupError);

View File

@@ -68,7 +68,7 @@ function scheduleSessionCleanup(sessionId: string) {
}
}
app.post('/ssh/config_editor/ssh/connect', (req, res) => {
app.post('/ssh/file_manager/ssh/connect', (req, res) => {
const {sessionId, ip, port, username, password, sshKey, keyPassword} = req.body;
if (!sessionId || !ip || !username || !port) {
return res.status(400).json({error: 'Missing SSH connection parameters'});
@@ -153,19 +153,19 @@ app.post('/ssh/config_editor/ssh/connect', (req, res) => {
client.connect(config);
});
app.post('/ssh/config_editor/ssh/disconnect', (req, res) => {
app.post('/ssh/file_manager/ssh/disconnect', (req, res) => {
const {sessionId} = req.body;
cleanupSession(sessionId);
res.json({status: 'success', message: 'SSH connection disconnected'});
});
app.get('/ssh/config_editor/ssh/status', (req, res) => {
app.get('/ssh/file_manager/ssh/status', (req, res) => {
const sessionId = req.query.sessionId as string;
const isConnected = !!sshSessions[sessionId]?.isConnected;
res.json({status: 'success', connected: isConnected});
});
app.get('/ssh/config_editor/ssh/listFiles', (req, res) => {
app.get('/ssh/file_manager/ssh/listFiles', (req, res) => {
const sessionId = req.query.sessionId as string;
const sshConn = sshSessions[sessionId];
const sshPath = decodeURIComponent((req.query.path as string) || '/');
@@ -231,7 +231,7 @@ app.get('/ssh/config_editor/ssh/listFiles', (req, res) => {
});
});
app.get('/ssh/config_editor/ssh/readFile', (req, res) => {
app.get('/ssh/file_manager/ssh/readFile', (req, res) => {
const sessionId = req.query.sessionId as string;
const sshConn = sshSessions[sessionId];
const filePath = decodeURIComponent(req.query.path as string);
@@ -280,7 +280,7 @@ app.get('/ssh/config_editor/ssh/readFile', (req, res) => {
});
});
app.post('/ssh/config_editor/ssh/writeFile', (req, res) => {
app.post('/ssh/file_manager/ssh/writeFile', (req, res) => {
const {sessionId, path: filePath, content} = req.body;
const sshConn = sshSessions[sessionId];

View File

@@ -2,9 +2,9 @@
// node ./dist/backend/starter.js
import './database/database.js'
import './ssh/ssh.js';
import './ssh/ssh_tunnel.js';
import './ssh/config_editor.js';
import './ssh/terminal.js';
import './ssh/tunnel.js';
import './ssh/file-manager.ts';
import './ssh/server-stats.js';
import chalk from 'chalk';