diff --git a/frontend/src/components/common/HostKeyDialog.vue b/frontend/src/components/common/HostKeyDialog.vue new file mode 100644 index 0000000..862d7b8 --- /dev/null +++ b/frontend/src/components/common/HostKeyDialog.vue @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + {{ isChanged ? 'HOST KEY HAS CHANGED' : 'Unknown Host Key' }} + + + {{ isChanged ? 'The server key does not match the stored key!' : 'This host has not been seen before.' }} + + + + + + + + WARNING: This could indicate a man-in-the-middle attack. Only accept if you know the host key was recently changed. + + + + + Host: + {{ hostname }} + + + Key type: + {{ keyType }} + + + Fingerprint: + {{ fingerprint }} + + + + + + + + Reject + + + {{ isChanged ? 'Accept Anyway' : 'Accept' }} + + + + + + + + diff --git a/frontend/src/components/sidebar/ConnectionTree.vue b/frontend/src/components/sidebar/ConnectionTree.vue index 734ca11..ba925f8 100644 --- a/frontend/src/components/sidebar/ConnectionTree.vue +++ b/frontend/src/components/sidebar/ConnectionTree.vue @@ -41,6 +41,7 @@ v-for="conn in connectionStore.connectionsByGroup(group.id)" :key="conn.id" class="w-full flex items-center gap-2 pl-8 pr-3 py-1.5 text-xs hover:bg-[var(--wraith-bg-tertiary)] transition-colors cursor-pointer" + @dblclick="handleConnect(conn)" > import { ref } from "vue"; -import { useConnectionStore } from "@/stores/connection.store"; +import { useConnectionStore, type Connection } from "@/stores/connection.store"; +import { useSessionStore } from "@/stores/session.store"; const connectionStore = useConnectionStore(); +const sessionStore = useSessionStore(); // All groups expanded by default const expandedGroups = ref>( @@ -80,4 +83,9 @@ function toggleGroup(groupId: number): void { expandedGroups.value.add(groupId); } } + +/** Double-click a connection to open a new session. */ +function handleConnect(conn: Connection): void { + sessionStore.connect(conn.id); +} diff --git a/frontend/src/stores/session.store.ts b/frontend/src/stores/session.store.ts index 2390e18..6c64b2d 100644 --- a/frontend/src/stores/session.store.ts +++ b/frontend/src/stores/session.store.ts @@ -1,5 +1,6 @@ import { defineStore } from "pinia"; import { ref, computed } from "vue"; +import { useConnectionStore } from "@/stores/connection.store"; export interface Session { id: string; @@ -17,13 +18,9 @@ export interface Session { * For now, mock sessions are used to render the tab bar. */ export const useSessionStore = defineStore("session", () => { - const sessions = ref([ - { id: "s1", connectionId: 1, name: "Asgard", protocol: "ssh", active: true }, - { id: "s2", connectionId: 2, name: "Docker", protocol: "ssh", active: false }, - { id: "s3", connectionId: 4, name: "CLT-VMHOST01", protocol: "rdp", active: false }, - ]); + const sessions = ref([]); - const activeSessionId = ref("s1"); + const activeSessionId = ref(null); const activeSession = computed(() => sessions.value.find((s) => s.id === activeSessionId.value) ?? null, @@ -61,6 +58,31 @@ export const useSessionStore = defineStore("session", () => { activeSessionId.value = id; } + /** + * Connect to a server by connection ID. + * Creates a new session tab and sets it active. + * + * TODO: Replace with Wails binding call — SSHService.Connect(hostname, port, ...) + * For now, creates a mock session using the connection's name. + */ + function connect(connectionId: number): void { + const connectionStore = useConnectionStore(); + const conn = connectionStore.connections.find((c) => c.id === connectionId); + if (!conn) return; + + // Check if there's already an active session for this connection + const existing = sessions.value.find((s) => s.connectionId === connectionId); + if (existing) { + activeSessionId.value = existing.id; + return; + } + + // TODO: Replace with Wails binding call: + // const sessionId = await SSHService.Connect(conn.hostname, conn.port, username, authMethods, cols, rows) + // For now, create a mock session + addSession(connectionId, conn.name, conn.protocol); + } + return { sessions, activeSessionId, @@ -69,5 +91,6 @@ export const useSessionStore = defineStore("session", () => { activateSession, closeSession, addSession, + connect, }; });
+ {{ isChanged ? 'The server key does not match the stored key!' : 'This host has not been seen before.' }} +
+ WARNING: This could indicate a man-in-the-middle attack. Only accept if you know the host key was recently changed. +