fix: skip existing hosts on JSON and SSH config import (#1607)

* fix: skip existing hosts on JSON and SSH config import

Import (skip existing) only loaded existing hosts when overwriting, so
every host was created again. Always load them, and skip a match unless
overwrite is set. A skipped host still resolves as a jump host for the
hosts imported after it.

Fixes #1606

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: use .js extension for test import

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ShadyNabil8andClaude Opus 5.5 authored and GitHub committed 2026-10-14 08:13:20 +08:00
1 parent 2fe7530cd4
commit 8d9c83b0f6
2 files changed
+100 -34

No files matched your search

+41 -32
View File
@@ -568,22 +568,21 @@ export function registerHostBulkRoutes(
);
}
// Loaded for both modes: overwrite updates a match, skip leaves it alone.
let existingHostMap: Map<string, { id: number }> | undefined;
const hostRepository = createCurrentHostRepository();
if (overwrite) {
try {
const allHosts =
await createCurrentHostResolutionRepository().findHostsByUserId(
userId,
);
existingHostMap = new Map();
for (const h of allHosts) {
const key = `${h.ip}:${h.port}:${h.username}`;
existingHostMap.set(key, { id: h.id as number });
}
} catch {
existingHostMap = undefined;
try {
const allHosts =
await createCurrentHostResolutionRepository().findHostsByUserId(
userId,
);
existingHostMap = new Map();
for (const h of allHosts) {
const key = `${h.ip}:${h.port}:${h.username}`;
existingHostMap.set(key, { id: h.id as number });
}
} catch {
existingHostMap = undefined;
}
const knownAuthTypes = listKnownAuthTypes();
@@ -624,6 +623,15 @@ export function registerHostBulkRoutes(
continue;
}
const lookupKey = `${hostData.ip}:${hostData.port}:${hostData.username}`;
const existing = existingHostMap?.get(lookupKey);
if (existing && !overwrite) {
// Hosts that jump through this one still resolve to the kept host.
if (exportId !== undefined) importedIds.set(exportId, existing.id);
results.skipped++;
continue;
}
if (
effectiveConnectionType === "ssh" &&
hostData.authType &&
@@ -769,8 +777,6 @@ export function registerHostBulkRoutes(
hostData.authType === "key" ? hostData.keyType || "auto" : null;
}
const lookupKey = `${hostData.ip}:${hostData.port}:${hostData.username}`;
const existing = existingHostMap?.get(lookupKey);
await withHostDefaults(
userId,
existing?.id ?? null,
@@ -831,7 +837,7 @@ export function registerHostBulkRoutes(
notifyImportedHosts(userId, writtenHostIds);
res.json({
message: `Import completed: ${results.success} created, ${results.updated} updated, ${results.failed} failed`,
message: `Import completed: ${results.success} created, ${results.updated} updated, ${results.skipped} skipped, ${results.failed} failed`,
success: results.success,
updated: results.updated,
skipped: results.skipped,
@@ -931,20 +937,18 @@ export function registerHostBulkRoutes(
let existingHostMap: Map<string, { id: number }> | undefined;
const hostRepository = createCurrentHostRepository();
if (overwrite) {
try {
const allHosts =
await createCurrentHostResolutionRepository().findHostsByUserId(
userId,
);
existingHostMap = new Map();
for (const h of allHosts) {
const key = `${h.ip}:${h.port}:${h.username}`;
existingHostMap.set(key, { id: h.id as number });
}
} catch {
existingHostMap = undefined;
try {
const allHosts =
await createCurrentHostResolutionRepository().findHostsByUserId(
userId,
);
existingHostMap = new Map();
for (const h of allHosts) {
const key = `${h.ip}:${h.port}:${h.username}`;
existingHostMap.set(key, { id: h.id as number });
}
} catch {
existingHostMap = undefined;
}
const writtenHostIds: number[] = [];
@@ -962,6 +966,13 @@ export function registerHostBulkRoutes(
continue;
}
const lookupKey = `${hostData.ip}:${hostData.port}:${hostData.username}`;
const existing = existingHostMap?.get(lookupKey);
if (existing && !overwrite) {
results.skipped++;
continue;
}
const sshDataObj: Record<string, unknown> = {
userId,
connectionType: "ssh",
@@ -999,8 +1010,6 @@ export function registerHostBulkRoutes(
updatedAt: new Date().toISOString(),
};
const lookupKey = `${hostData.ip}:${hostData.port}:${hostData.username}`;
const existing = existingHostMap?.get(lookupKey);
await withHostDefaults(
userId,
existing?.id ?? null,
@@ -1037,7 +1046,7 @@ export function registerHostBulkRoutes(
notifyImportedHosts(userId, writtenHostIds);
res.json({
message: `Import completed: ${results.success} created, ${results.updated} updated, ${results.failed} failed`,
message: `Import completed: ${results.success} created, ${results.updated} updated, ${results.skipped} skipped, ${results.failed} failed`,
success: results.success,
updated: results.updated,
skipped: results.skipped,