diff --git a/src/connect.ts b/src/connect.ts index 6839a0e..bc90128 100644 --- a/src/connect.ts +++ b/src/connect.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import { getConfigs } from './config'; import type { FileSystemConfig } from './fileSystemConfig'; import { censorConfig, Logging } from './logging'; +import { navigate } from './settings'; import { toPromise } from './toPromise'; // tslint:disable-next-line:variable-name @@ -22,7 +23,37 @@ function replaceVariables(string?: string) { return string.replace(/\$\w+/g, key => process.env[key.substr(1)] || ''); } -export async function calculateActualConfig(config: FileSystemConfig): Promise { +const PROMPT_FIELDS: Partial string, + promptOnEmpty: boolean, password?: boolean]>> = { + host: ['Host', c => `Host for ${c.name}`, true], + username: ['Username', c => `Username for ${c.name}`, true], + password: ['Password', c => `Password for ${c.username}@${c.name}`, false, true], + passphrase: ['Passphrase', c => `Passphrase for provided export/private key for ${c.username}@${c.name}`, false, true], +}; + +async function promptFields(config: FileSystemConfig, ...fields: (keyof FileSystemConfig)[]): Promise { + for (const field of fields) { + const prompt = PROMPT_FIELDS[field]; + if (!prompt) { + Logging.error(`Prompting unexpected field '${field}'`); + continue; + } + const value = config[field]; + if (value && value !== true) continue; // Truthy and not true + if (!value && !prompt[2]) continue; // Falsy but not promptOnEmpty + const result = await vscode.window.showInputBox({ + ignoreFocusOut: true, + password: !!prompt[3], + placeHolder: prompt[0], + prompt: prompt[1](config), + }); + (config[field] as string | undefined) = result; + } +} + +export async function calculateActualConfig(config: FileSystemConfig): Promise { if (config._calculated) return config; const logging = Logging.scope(); // Add the internal _calculated field to cache the actual config for the next calculateActualConfig call @@ -41,6 +72,8 @@ export async function calculateActualConfig(config: FileSystemConfig): Promise c.name === name); if (!config) throw new Error(`No configuration with name '${name}' found`); const actualConfig = await calculateActualConfig(config); + if (!actualConfig) throw new Error('Connection cancelled'); const client = await createSSH(actualConfig); if (!client) throw new Error(`Could not create SSH session for '${name}'`); let timeoutCounter = 0;