mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-09 14:00:03 +00:00
158 lines
5.1 KiB
TypeScript
158 lines
5.1 KiB
TypeScript
import { Injectable, InjectFlags, Injector } from '@angular/core'
|
|
import { ProfileProvider, NewTabParameters, PartialProfile, TranslateService } from 'tabby-core'
|
|
import * as ALGORITHMS from 'ssh2/lib/protocol/constants'
|
|
import { SSHProfileSettingsComponent } from './components/sshProfileSettings.component'
|
|
import { SSHTabComponent } from './components/sshTab.component'
|
|
import { PasswordStorageService } from './services/passwordStorage.service'
|
|
import { ALGORITHM_BLACKLIST, SSHAlgorithmType, SSHProfile } from './api'
|
|
import { SSHProfileImporter } from './api/importer'
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
export class SSHProfilesService extends ProfileProvider<SSHProfile> {
|
|
id = 'ssh'
|
|
name = 'SSH'
|
|
supportsQuickConnect = true
|
|
settingsComponent = SSHProfileSettingsComponent
|
|
configDefaults = {
|
|
options: {
|
|
host: null,
|
|
port: 22,
|
|
user: 'root',
|
|
auth: null,
|
|
password: null,
|
|
privateKeys: [],
|
|
keepaliveInterval: 5000,
|
|
keepaliveCountMax: 10,
|
|
readyTimeout: null,
|
|
x11: false,
|
|
skipBanner: false,
|
|
jumpHost: null,
|
|
agentForward: false,
|
|
warnOnClose: null,
|
|
algorithms: {
|
|
hmac: [],
|
|
kex: [],
|
|
cipher: [],
|
|
serverHostKey: [],
|
|
},
|
|
proxyCommand: null,
|
|
forwardedPorts: [],
|
|
scripts: [],
|
|
socksProxyHost: null,
|
|
socksProxyPort: null,
|
|
httpProxyHost: null,
|
|
httpProxyPort: null,
|
|
reuseSession: true,
|
|
input: { backspace: 'backspace' },
|
|
},
|
|
}
|
|
|
|
constructor (
|
|
private passwordStorage: PasswordStorageService,
|
|
private translate: TranslateService,
|
|
private injector: Injector,
|
|
) {
|
|
super()
|
|
for (const k of Object.values(SSHAlgorithmType)) {
|
|
const defaultAlg = {
|
|
[SSHAlgorithmType.KEX]: 'DEFAULT_KEX',
|
|
[SSHAlgorithmType.HOSTKEY]: 'DEFAULT_SERVER_HOST_KEY',
|
|
[SSHAlgorithmType.CIPHER]: 'DEFAULT_CIPHER',
|
|
[SSHAlgorithmType.HMAC]: 'DEFAULT_MAC',
|
|
}[k]
|
|
this.configDefaults.options.algorithms[k] = ALGORITHMS[defaultAlg].filter(x => !ALGORITHM_BLACKLIST.includes(x))
|
|
this.configDefaults.options.algorithms[k].sort()
|
|
}
|
|
}
|
|
|
|
async getBuiltinProfiles (): Promise<PartialProfile<SSHProfile>[]> {
|
|
const importers = this.injector.get<SSHProfileImporter[]>(SSHProfileImporter as any, [], InjectFlags.Optional)
|
|
let imported: PartialProfile<SSHProfile>[] = []
|
|
for (const importer of importers) {
|
|
try {
|
|
imported = imported.concat(await importer.getProfiles())
|
|
} catch (e) {
|
|
console.warn('Could not import SSH profiles:', e)
|
|
}
|
|
}
|
|
return [
|
|
{
|
|
id: `ssh:template`,
|
|
type: 'ssh',
|
|
name: this.translate.instant('SSH connection'),
|
|
icon: 'fas fa-desktop',
|
|
options: {
|
|
host: '',
|
|
port: 22,
|
|
user: 'root',
|
|
},
|
|
isBuiltin: true,
|
|
isTemplate: true,
|
|
weight: -1,
|
|
},
|
|
...imported.map(p => ({
|
|
...p,
|
|
isBuiltin: true,
|
|
})),
|
|
]
|
|
}
|
|
|
|
async getNewTabParameters (profile: SSHProfile): Promise<NewTabParameters<SSHTabComponent>> {
|
|
return {
|
|
type: SSHTabComponent,
|
|
inputs: { profile },
|
|
}
|
|
}
|
|
|
|
getSuggestedName (profile: SSHProfile): string {
|
|
return `${profile.options.user}@${profile.options.host}:${profile.options.port}`
|
|
}
|
|
|
|
getDescription (profile: PartialProfile<SSHProfile>): string {
|
|
return profile.options?.host ?? ''
|
|
}
|
|
|
|
deleteProfile (profile: SSHProfile): void {
|
|
this.passwordStorage.deletePassword(profile)
|
|
}
|
|
|
|
quickConnect (query: string): PartialProfile<SSHProfile> {
|
|
let user: string|undefined = undefined
|
|
let host = query
|
|
let port = 22
|
|
if (host.includes('@')) {
|
|
const parts = host.split(/@/g)
|
|
host = parts[parts.length - 1]
|
|
user = parts.slice(0, parts.length - 1).join('@')
|
|
}
|
|
if (host.includes('[')) {
|
|
port = parseInt(host.split(']')[1].substring(1))
|
|
host = host.split(']')[0].substring(1)
|
|
} else if (host.includes(':')) {
|
|
port = parseInt(host.split(/:/g)[1])
|
|
host = host.split(':')[0]
|
|
}
|
|
|
|
return {
|
|
name: query,
|
|
type: 'ssh',
|
|
options: {
|
|
host,
|
|
user,
|
|
port,
|
|
},
|
|
}
|
|
}
|
|
|
|
intoQuickConnectString (profile: SSHProfile): string|null {
|
|
let s = profile.options.host
|
|
if (profile.options.user !== 'root') {
|
|
s = `${profile.options.user}@${s}`
|
|
}
|
|
if (profile.options.port !== 22) {
|
|
s = `${s}:${profile.options.port}`
|
|
}
|
|
return s
|
|
}
|
|
}
|