diff --git a/terminus-local/src/index.ts b/terminus-local/src/index.ts index 6c99c356..96a54bd8 100644 --- a/terminus-local/src/index.ts +++ b/terminus-local/src/index.ts @@ -6,6 +6,7 @@ import { ToastrModule } from 'ngx-toastr' import TerminusCorePlugin, { HostAppService, ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, TabContextMenuItemProvider, CLIHandler, ConfigService } from 'terminus-core' import TerminusTerminalModule from 'terminus-terminal' +import TerminusElectronPlugin from 'terminus-electron' import { SettingsTabProvider } from 'terminus-settings' import { TerminalTabComponent } from './components/terminalTab.component' @@ -47,6 +48,7 @@ import { AutoOpenTabCLIHandler, OpenPathCLIHandler, TerminalCLIHandler } from '. NgbModule, ToastrModule, TerminusCorePlugin, + TerminusElectronPlugin, TerminusTerminalModule, ], providers: [ diff --git a/terminus-settings/src/components/settingsTab.component.scss b/terminus-settings/src/components/settingsTab.component.scss index efecaac7..94e9682c 100644 --- a/terminus-settings/src/components/settingsTab.component.scss +++ b/terminus-settings/src/components/settingsTab.component.scss @@ -19,6 +19,7 @@ width: 190px; flex: none; overflow-y: auto; + flex-wrap: nowrap; } > .tab-content { diff --git a/terminus-ssh/src/api.ts b/terminus-ssh/src/api.ts index 7091efd3..270f86ff 100644 --- a/terminus-ssh/src/api.ts +++ b/terminus-ssh/src/api.ts @@ -320,16 +320,23 @@ export class SSHSession extends BaseSession { this.remainingAuthMethods = [{ type: 'none' }] if (!this.connection.auth || this.connection.auth === 'publicKey') { - for (const pk of this.connection.privateKeys ?? []) { - try { - this.remainingAuthMethods.push({ - type: 'publickey', - name: pk, - contents: await this.fileProviders.retrieveFile(pk), - }) - } catch (error) { - this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Could not load private key ${pk}: ${error}`) + if (this.connection.privateKeys?.length) { + for (const pk of this.connection.privateKeys) { + try { + this.remainingAuthMethods.push({ + type: 'publickey', + name: pk, + contents: await this.fileProviders.retrieveFile(pk), + }) + } catch (error) { + this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Could not load private key ${pk}: ${error}`) + } } + } else { + this.remainingAuthMethods.push({ + type: 'publickey', + name: 'auto', + }) } } if (!this.connection.auth || this.connection.auth === 'agent') { @@ -717,7 +724,7 @@ export class SSHSession extends BaseSession { const userKeyPath = path.join(process.env.HOME!, '.ssh', 'id_rsa') if (await fs.exists(userKeyPath)) { this.emitServiceMessage('Using user\'s default private key') - privateKeyContents = fs.readFile(userKeyPath, { encoding: null }) + privateKeyContents = await fs.readFile(userKeyPath, { encoding: null }) } } @@ -740,11 +747,17 @@ export class SSHSession extends BaseSession { async parsePrivateKey (privateKey: string): Promise { const keyHash = crypto.createHash('sha512').update(privateKey).digest('hex') - let passphrase: string|null = await this.passwordStorage.loadPrivateKeyPassword(keyHash) + let triedSavedPassphrase = false + let passphrase: string|null = null while (true) { try { return sshpk.parsePrivateKey(privateKey, 'auto', { passphrase }) } catch (e) { + if (!triedSavedPassphrase) { + passphrase = await this.passwordStorage.loadPrivateKeyPassword(keyHash) + triedSavedPassphrase = true + continue + } if (e instanceof sshpk.KeyEncryptedError || e instanceof sshpk.KeyParseError) { await this.passwordStorage.deletePrivateKeyPassword(keyHash) diff --git a/terminus-ssh/src/components/editConnectionModal.component.ts b/terminus-ssh/src/components/editConnectionModal.component.ts index 9c320342..f5f389e6 100644 --- a/terminus-ssh/src/components/editConnectionModal.component.ts +++ b/terminus-ssh/src/components/editConnectionModal.component.ts @@ -64,6 +64,7 @@ export class EditConnectionModalComponent { ) async ngOnInit () { + this.connection.algorithms = this.connection.algorithms ?? {} for (const k of Object.values(SSHAlgorithmType)) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!this.connection.algorithms[k]) { @@ -76,7 +77,6 @@ export class EditConnectionModalComponent { } } - this.connection.algorithms = this.connection.algorithms ?? {} this.connection.scripts = this.connection.scripts ?? [] this.connection.auth = this.connection.auth ?? null this.connection.privateKeys ??= []