mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 22:55:24 +00:00
feat: finish the ai plugin (B18)
This commit is contained in:
1 parent
6b4d1432ab
commit
21937a6b02
193 files changed
+23429
-4244
No files matched your search
@@ -1,6 +1,5 @@
|
||||
import { authLogger } from "../../utils/logger.js";
|
||||
import {
|
||||
createCurrentAiRepository,
|
||||
createCurrentNotificationChannelRepository,
|
||||
createCurrentApiKeyRepository,
|
||||
createCurrentAuditLogRepository,
|
||||
@@ -73,7 +72,6 @@ export async function deleteUserAndRelatedData(
|
||||
await createCurrentTrustedDeviceRepository().deleteByUserId(userId);
|
||||
|
||||
await createCurrentRoleRepository().removeAllRolesFromUser(userId);
|
||||
await createCurrentAiRepository().deleteByUserId(userId);
|
||||
await createCurrentNotificationChannelRepository().deleteByUserId(userId);
|
||||
await createCurrentAuditLogRepository().anonymizeByUserId(userId);
|
||||
|
||||
|
||||
@@ -288,8 +288,6 @@ export function registerHostBulkRoutes(
|
||||
simpleUpdates.enableTmuxMonitor = updates.enableTmuxMonitor;
|
||||
if (typeof updates.enableTerminalToolbar === "boolean")
|
||||
simpleUpdates.enableTerminalToolbar = updates.enableTerminalToolbar;
|
||||
if (typeof updates.enableAiAssistant === "boolean")
|
||||
simpleUpdates.enableAiAssistant = updates.enableAiAssistant;
|
||||
if (typeof updates.statusCheckEnabled === "boolean")
|
||||
simpleUpdates.statusCheckEnabled = updates.statusCheckEnabled;
|
||||
|
||||
@@ -751,7 +749,6 @@ export function registerHostBulkRoutes(
|
||||
enableFileManager: hostData.enableFileManager !== false,
|
||||
enableTmuxMonitor: hostData.enableTmuxMonitor || false,
|
||||
enableTerminalToolbar: hostData.enableTerminalToolbar !== false,
|
||||
enableAiAssistant: hostData.enableAiAssistant || false,
|
||||
enableCommandHistory: hostData.enableCommandHistory !== false,
|
||||
showTerminalInSidebar: hostData.showTerminalInSidebar ? 1 : 0,
|
||||
showFileManagerInSidebar: hostData.showFileManagerInSidebar ? 1 : 0,
|
||||
@@ -1012,7 +1009,6 @@ export function registerHostBulkRoutes(
|
||||
enableFileManager: true,
|
||||
enableTmuxMonitor: false,
|
||||
enableTerminalToolbar: true,
|
||||
enableAiAssistant: false,
|
||||
showTerminalInSidebar: 0,
|
||||
showFileManagerInSidebar: 0,
|
||||
showTunnelInSidebar: 0,
|
||||
|
||||
@@ -178,7 +178,6 @@ export type NormalizedImportedHost = Record<string, unknown> & {
|
||||
enableProxmox?: unknown;
|
||||
enableTmuxMonitor?: unknown;
|
||||
enableTerminalToolbar?: unknown;
|
||||
enableAiAssistant?: unknown;
|
||||
enableCommandHistory?: unknown;
|
||||
showTerminalInSidebar?: unknown;
|
||||
showFileManagerInSidebar?: unknown;
|
||||
@@ -340,7 +339,6 @@ const CONNECT_LEVEL_FIELDS = new Set([
|
||||
"enableFileManager",
|
||||
"enableTmuxMonitor",
|
||||
"enableTerminalToolbar",
|
||||
"enableAiAssistant",
|
||||
"showTerminalInSidebar",
|
||||
"showFileManagerInSidebar",
|
||||
"showTunnelInSidebar",
|
||||
@@ -436,7 +434,6 @@ export function transformHostResponse(
|
||||
enableFileManager: host.enableFileManager !== false,
|
||||
enableTmuxMonitor: !!host.enableTmuxMonitor,
|
||||
enableTerminalToolbar: host.enableTerminalToolbar !== false,
|
||||
enableAiAssistant: !!host.enableAiAssistant,
|
||||
showTerminalInSidebar: !!host.showTerminalInSidebar,
|
||||
showFileManagerInSidebar: !!host.showFileManagerInSidebar,
|
||||
showTunnelInSidebar: !!host.showTunnelInSidebar,
|
||||
|
||||
@@ -15,17 +15,15 @@ import {
|
||||
pickResolvedUsername,
|
||||
} from "../../hosts/credential-username.js";
|
||||
import { emitInternalEvent } from "../../hosts/internal-events.js";
|
||||
import { deleteOwnedHost } from "../../hosts/delete-host.js";
|
||||
import {
|
||||
createCurrentCredentialRepository,
|
||||
createCurrentOpksshTokenRepository,
|
||||
createCurrentRecentActivityRepository,
|
||||
createCurrentSshCredentialUsageRepository,
|
||||
createCurrentRbacAccessRepository,
|
||||
createCurrentRoleRepository,
|
||||
createCurrentHostResolutionRepository,
|
||||
createCurrentHostRepository,
|
||||
createCurrentUserRepository,
|
||||
createCurrentSyncTombstoneRepository,
|
||||
createCurrentSharedHostAuthOverrideRepository,
|
||||
} from "../repositories/factory.js";
|
||||
import {
|
||||
@@ -202,7 +200,6 @@ router.post(
|
||||
enableProxmox,
|
||||
enableTmuxMonitor,
|
||||
enableTerminalToolbar,
|
||||
enableAiAssistant,
|
||||
showTerminalInSidebar,
|
||||
showFileManagerInSidebar,
|
||||
showTunnelInSidebar,
|
||||
@@ -332,7 +329,6 @@ router.post(
|
||||
scpLegacy: scpLegacy ? 1 : 0,
|
||||
enableTmuxMonitor: enableTmuxMonitor ? 1 : 0,
|
||||
enableTerminalToolbar: enableTerminalToolbar === false ? 0 : 1,
|
||||
enableAiAssistant: enableAiAssistant ? 1 : 0,
|
||||
showTerminalInSidebar: showTerminalInSidebar ? 1 : 0,
|
||||
showFileManagerInSidebar: showFileManagerInSidebar ? 1 : 0,
|
||||
showTunnelInSidebar: showTunnelInSidebar ? 1 : 0,
|
||||
@@ -756,7 +752,6 @@ router.post(
|
||||
enableWebUi: false,
|
||||
enableTmuxMonitor: false,
|
||||
enableTerminalToolbar: true,
|
||||
enableAiAssistant: false,
|
||||
showTerminalInSidebar: true,
|
||||
showFileManagerInSidebar: false,
|
||||
showTunnelInSidebar: false,
|
||||
@@ -886,7 +881,6 @@ router.put(
|
||||
enableProxmox,
|
||||
enableTmuxMonitor,
|
||||
enableTerminalToolbar,
|
||||
enableAiAssistant,
|
||||
showTerminalInSidebar,
|
||||
showFileManagerInSidebar,
|
||||
showTunnelInSidebar,
|
||||
@@ -1017,7 +1011,6 @@ router.put(
|
||||
scpLegacy: scpLegacy ? 1 : 0,
|
||||
enableTmuxMonitor: enableTmuxMonitor ? 1 : 0,
|
||||
enableTerminalToolbar: enableTerminalToolbar === false ? 0 : 1,
|
||||
enableAiAssistant: enableAiAssistant ? 1 : 0,
|
||||
showTerminalInSidebar: showTerminalInSidebar ? 1 : 0,
|
||||
showFileManagerInSidebar: showFileManagerInSidebar ? 1 : 0,
|
||||
showTunnelInSidebar: showTunnelInSidebar ? 1 : 0,
|
||||
@@ -2084,7 +2077,6 @@ router.get(
|
||||
enableProxmoxStats: !!proxmoxSettings?.enableProxmoxStats,
|
||||
enableTmuxMonitor: !!resolvedHost.enableTmuxMonitor,
|
||||
enableTerminalToolbar: resolvedHost.enableTerminalToolbar !== false,
|
||||
enableAiAssistant: !!resolvedHost.enableAiAssistant,
|
||||
showTerminalInSidebar: !!resolvedHost.showTerminalInSidebar,
|
||||
showFileManagerInSidebar: !!resolvedHost.showFileManagerInSidebar,
|
||||
showTunnelInSidebar: !!resolvedHost.showTunnelInSidebar,
|
||||
@@ -2241,7 +2233,6 @@ router.get(
|
||||
enableTmuxMonitor: !!resolvedHost.enableTmuxMonitor,
|
||||
enableTerminalToolbar:
|
||||
resolvedHost.enableTerminalToolbar !== false,
|
||||
enableAiAssistant: !!resolvedHost.enableAiAssistant,
|
||||
showTerminalInSidebar: !!resolvedHost.showTerminalInSidebar,
|
||||
showFileManagerInSidebar: !!resolvedHost.showFileManagerInSidebar,
|
||||
showTunnelInSidebar: !!resolvedHost.showTunnelInSidebar,
|
||||
@@ -2418,13 +2409,9 @@ router.delete(
|
||||
hostId: parseInt(hostId),
|
||||
});
|
||||
try {
|
||||
const hostToDelete =
|
||||
await createCurrentHostResolutionRepository().findHostByIdForUser(
|
||||
Number(hostId),
|
||||
userId,
|
||||
);
|
||||
const deleted = await deleteOwnedHost(userId, Number(hostId));
|
||||
|
||||
if (!hostToDelete) {
|
||||
if (!deleted) {
|
||||
sshLogger.warn("SSH host not found for deletion", {
|
||||
operation: "host_delete",
|
||||
hostId: parseInt(hostId),
|
||||
@@ -2433,34 +2420,6 @@ router.delete(
|
||||
return res.status(404).json({ error: "SSH host not found" });
|
||||
}
|
||||
|
||||
const numericHostId = Number(hostId);
|
||||
|
||||
// file manager recent/pinned/shortcuts, transfer_recent, command
|
||||
// history and session recordings cascade on the host's refHost()
|
||||
// foreign key, as the file-manager, ssh-terminal and
|
||||
// session-recording plugins' adopted tables.
|
||||
|
||||
await createCurrentSshCredentialUsageRepository().deleteByHostId(
|
||||
numericHostId,
|
||||
);
|
||||
|
||||
await createCurrentRecentActivityRepository().deleteByHostId(
|
||||
numericHostId,
|
||||
);
|
||||
|
||||
await createCurrentRbacAccessRepository().deleteHostAccessForHost(
|
||||
numericHostId,
|
||||
);
|
||||
|
||||
await createCurrentHostRepository().deleteForUser(userId, numericHostId);
|
||||
if (hostToDelete.syncId) {
|
||||
await createCurrentSyncTombstoneRepository().record(
|
||||
userId,
|
||||
"hosts",
|
||||
hostToDelete.syncId,
|
||||
);
|
||||
}
|
||||
|
||||
databaseLogger.success("SSH host deleted", {
|
||||
operation: "host_delete_success",
|
||||
userId,
|
||||
@@ -2474,29 +2433,12 @@ router.delete(
|
||||
action: "delete_host",
|
||||
resourceType: "host",
|
||||
resourceId: hostId,
|
||||
resourceName: hostToDelete.name ?? hostToDelete.ip,
|
||||
resourceName: deleted.name,
|
||||
ipAddress: dhIp,
|
||||
userAgent: dhUa,
|
||||
success: true,
|
||||
});
|
||||
|
||||
emitInternalEvent("host_deleted", userId, numericHostId, {
|
||||
name: hostToDelete.name ?? hostToDelete.ip,
|
||||
});
|
||||
|
||||
try {
|
||||
pluginEvents.emit(TOPICS.hostDeleted, {
|
||||
hostId: numericHostId,
|
||||
userId,
|
||||
});
|
||||
} catch (err) {
|
||||
sshLogger.warn("Failed to publish host deletion event", {
|
||||
operation: "host_delete",
|
||||
hostId: numericHostId,
|
||||
error: err instanceof Error ? err.message : String(err),
|
||||
});
|
||||
}
|
||||
|
||||
res.json({ message: "SSH host deleted" });
|
||||
} catch (err) {
|
||||
sshLogger.error("Failed to delete SSH host from database", err, {
|
||||
|
||||
@@ -32,8 +32,6 @@ const pickPreferences = (row?: UserPreferenceRecord | null) => ({
|
||||
disableUpdateCheck: row?.disableUpdateCheck ?? null,
|
||||
confirmTabClose: row?.confirmTabClose ?? null,
|
||||
hiddenRailTabs: row?.hiddenRailTabs ?? null,
|
||||
aiAssistantEnabled: row?.aiAssistantEnabled ?? null,
|
||||
aiReadOnlyCommands: row?.aiReadOnlyCommands ?? null,
|
||||
compactHostView: row?.compactHostView ?? null,
|
||||
statusColorScheme: row?.statusColorScheme ?? null,
|
||||
customThemes: row?.customThemes ?? null,
|
||||
@@ -227,8 +225,6 @@ router.put("/", authenticateJWT, async (req: Request, res: Response) => {
|
||||
disableUpdateCheck,
|
||||
confirmTabClose,
|
||||
hiddenRailTabs,
|
||||
aiAssistantEnabled,
|
||||
aiReadOnlyCommands,
|
||||
customThemes,
|
||||
customKeybindings,
|
||||
terminalDefaults,
|
||||
@@ -249,8 +245,6 @@ router.put("/", authenticateJWT, async (req: Request, res: Response) => {
|
||||
disableUpdateCheck?: boolean | null;
|
||||
confirmTabClose?: boolean | null;
|
||||
hiddenRailTabs?: string | null;
|
||||
aiAssistantEnabled?: boolean | null;
|
||||
aiReadOnlyCommands?: boolean | null;
|
||||
customThemes?: string | null;
|
||||
customKeybindings?: string | null;
|
||||
terminalDefaults?: string | null;
|
||||
@@ -392,8 +386,6 @@ router.put("/", authenticateJWT, async (req: Request, res: Response) => {
|
||||
confirmSnippetExecution,
|
||||
disableUpdateCheck,
|
||||
confirmTabClose,
|
||||
aiAssistantEnabled,
|
||||
aiReadOnlyCommands,
|
||||
};
|
||||
for (const [key, value] of Object.entries(boolFields)) {
|
||||
if (value !== undefined && value !== null && typeof value !== "boolean") {
|
||||
@@ -407,10 +399,6 @@ router.put("/", authenticateJWT, async (req: Request, res: Response) => {
|
||||
if (language !== undefined) updates.language = language;
|
||||
if (storageMode !== undefined) updates.storageMode = storageMode;
|
||||
if (hiddenRailTabs !== undefined) updates.hiddenRailTabs = hiddenRailTabs;
|
||||
if (aiAssistantEnabled !== undefined)
|
||||
updates.aiAssistantEnabled = aiAssistantEnabled;
|
||||
if (aiReadOnlyCommands !== undefined)
|
||||
updates.aiReadOnlyCommands = aiReadOnlyCommands;
|
||||
if (commandAutocomplete !== undefined)
|
||||
updates.commandAutocomplete = commandAutocomplete;
|
||||
if (commandPaletteEnabled !== undefined)
|
||||
|
||||
Reference in new issue
Block a user