diff --git a/src/backend/utils/user-data-import.ts b/src/backend/utils/user-data-import.ts index da776893..ab161e2c 100644 --- a/src/backend/utils/user-data-import.ts +++ b/src/backend/utils/user-data-import.ts @@ -177,15 +177,33 @@ class UserDataImport { continue; } - const tempId = `import-ssh-${targetUserId}-${Date.now()}-${imported}`; + const existing = await getDb() + .select() + .from(sshData) + .where( + and( + eq(sshData.userId, targetUserId), + eq(sshData.ip, host.ip as string), + eq(sshData.port, host.port as number), + eq(sshData.username, host.username as string), + ), + ); + + if (existing.length > 0 && !options.replaceExisting) { + skipped++; + continue; + } + const newHostData = { ...host, - id: tempId, userId: targetUserId, - createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; + if (existing.length === 0) { + newHostData.createdAt = new Date().toISOString(); + } + let processedHostData = newHostData; if (options.userDataKey) { processedHostData = DataCrypto.encryptRecord( @@ -198,9 +216,18 @@ class UserDataImport { delete processedHostData.id; - await getDb() - .insert(sshData) - .values(processedHostData as unknown as typeof sshData.$inferInsert); + if (existing.length > 0 && options.replaceExisting) { + await getDb() + .update(sshData) + .set(processedHostData as unknown as typeof sshData.$inferInsert) + .where(eq(sshData.id, existing[0].id)); + } else { + await getDb() + .insert(sshData) + .values( + processedHostData as unknown as typeof sshData.$inferInsert, + ); + } imported++; } catch (error) { errors.push( @@ -233,17 +260,33 @@ class UserDataImport { continue; } - const tempCredId = `import-cred-${targetUserId}-${Date.now()}-${imported}`; + const existing = await getDb() + .select() + .from(sshCredentials) + .where( + and( + eq(sshCredentials.userId, targetUserId), + eq(sshCredentials.name, credential.name as string), + ), + ); + + if (existing.length > 0 && !options.replaceExisting) { + skipped++; + continue; + } + const newCredentialData = { ...credential, - id: tempCredId, userId: targetUserId, - usageCount: 0, - lastUsed: null, - createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; + if (existing.length === 0) { + newCredentialData.usageCount = 0; + newCredentialData.lastUsed = null; + newCredentialData.createdAt = new Date().toISOString(); + } + let processedCredentialData = newCredentialData; if (options.userDataKey) { processedCredentialData = DataCrypto.encryptRecord( @@ -256,11 +299,20 @@ class UserDataImport { delete processedCredentialData.id; - await getDb() - .insert(sshCredentials) - .values( - processedCredentialData as unknown as typeof sshCredentials.$inferInsert, - ); + if (existing.length > 0 && options.replaceExisting) { + await getDb() + .update(sshCredentials) + .set( + processedCredentialData as unknown as typeof sshCredentials.$inferInsert, + ) + .where(eq(sshCredentials.id, existing[0].id)); + } else { + await getDb() + .insert(sshCredentials) + .values( + processedCredentialData as unknown as typeof sshCredentials.$inferInsert, + ); + } imported++; } catch (error) { errors.push(