Skip to content

Commit 7a7d3d2

Browse files
authored
fix: unexpected configuration was selected in the recent profiles (#10817)
1 parent 4f14e92 commit 7a7d3d2

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

tabby-electron/src/sshImporters.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as fs from 'fs/promises'
22
import * as fsSync from 'fs'
33
import * as path from 'path'
44
import * as glob from 'glob'
5-
import slugify from 'slugify'
65
import * as yaml from 'js-yaml'
76
import { Injectable } from '@angular/core'
87
import { PartialProfile } from 'tabby-core'
@@ -145,15 +144,24 @@ async function parseSSHConfigFile (
145144
return merged
146145
}
147146

147+
// Function to convert an SSH Profile name into a sha256 hash-based ID
148+
async function hashSSHProfileName (name: string) {
149+
const textEncoder = new TextEncoder()
150+
const encoded = textEncoder.encode(name)
151+
const hash = await crypto.subtle.digest('SHA-256', encoded)
152+
const hashArray = Array.from(new Uint8Array(hash))
153+
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
154+
}
155+
148156
// Function to take an ssh-config entry and convert it into an SSHProfile
149-
function convertHostToSSHProfile (host: string, settings: Record<string, string | string[] | object[] >): PartialProfile<SSHProfile> {
157+
async function convertHostToSSHProfile (host: string, settings: Record<string, string | string[] | object[] >): Promise<PartialProfile<SSHProfile>> {
150158

151159
// inline function to generate an id for this profile
152-
const deriveID = (name: string) => 'openssh-config:' + slugify(name)
160+
const deriveID = async (name: string) => 'openssh-config:' + await hashSSHProfileName(name)
153161

154162
// Start point of the profile, with an ID, name, type and group
155163
const thisProfile: PartialProfile<SSHProfile> = {
156-
id: deriveID(host),
164+
id: await deriveID(host),
157165
name: `${host} (.ssh/config)`,
158166
type: 'ssh',
159167
group: 'Imported from .ssh/config',
@@ -194,7 +202,7 @@ function convertHostToSSHProfile (host: string, settings: Record<string, string
194202
const basicString = settings[key]
195203
if (typeof basicString === 'string') {
196204
if (targetName === SSHProfilePropertyNames.JumpHost) {
197-
options[targetName] = deriveID(basicString)
205+
options[targetName] = await deriveID(basicString)
198206
} else {
199207
options[targetName] = basicString
200208
}
@@ -295,7 +303,7 @@ function convertHostToSSHProfile (host: string, settings: Record<string, string
295303
return thisProfile
296304
}
297305

298-
function convertToSSHProfiles (config: SSHConfig): PartialProfile<SSHProfile>[] {
306+
async function convertToSSHProfiles (config: SSHConfig): Promise<PartialProfile<SSHProfile>[]> {
299307
const myMap = new Map<string, PartialProfile<SSHProfile>>()
300308

301309
function noWildCardsInName (name: string) {
@@ -333,7 +341,7 @@ function convertToSSHProfiles (config: SSHConfig): PartialProfile<SSHProfile>[]
333341
// NOTE: SSHConfig.compute() lies about the return types
334342
const configuration: Record<string, string | string[] | object[]> = config.compute(host)
335343
if (Object.keys(configuration).map(key => key.toLowerCase()).includes('hostname')) {
336-
myMap[host] = convertHostToSSHProfile(host, configuration)
344+
myMap[host] = await convertHostToSSHProfile(host, configuration)
337345
}
338346
}
339347
}
@@ -354,7 +362,7 @@ export class OpenSSHImporter extends SSHProfileImporter {
354362

355363
try {
356364
const config: SSHConfig = await parseSSHConfigFile(configPath)
357-
return convertToSSHProfiles(config)
365+
return await convertToSSHProfiles(config)
358366
} catch (e) {
359367
if (e.code === 'ENOENT') {
360368
return []
@@ -376,7 +384,7 @@ export class StaticFileImporter extends SSHProfileImporter {
376384
}
377385

378386
async getProfiles (): Promise<PartialProfile<SSHProfile>[]> {
379-
const deriveID = name => 'file-config:' + slugify(name)
387+
const deriveID = async name => 'file-config:' + await hashSSHProfileName(name)
380388

381389
if (!fsSync.existsSync(this.configPath)) {
382390
return []
@@ -387,11 +395,11 @@ export class StaticFileImporter extends SSHProfileImporter {
387395
return []
388396
}
389397

390-
return (yaml.load(content) as PartialProfile<SSHProfile>[]).map(item => ({
398+
return Promise.all((yaml.load(content) as PartialProfile<SSHProfile>[]).map(async item => ({
391399
...item,
392-
id: deriveID(item.name),
400+
id: await deriveID(item.name),
393401
type: 'ssh',
394-
}))
402+
})))
395403
}
396404
}
397405

0 commit comments

Comments
 (0)