diff --git a/packages/core/src/shared/lsp/utils/platform.ts b/packages/core/src/shared/lsp/utils/platform.ts index 39284e8a0ac..30ea5d6ed66 100644 --- a/packages/core/src/shared/lsp/utils/platform.ts +++ b/packages/core/src/shared/lsp/utils/platform.ts @@ -4,10 +4,14 @@ */ import { ToolkitError } from '../../errors' -import { Logger } from '../../logger/logger' +import { Logger, getLogger } from '../../logger/logger' import { ChildProcess } from '../../utilities/processUtils' import { waitUntil } from '../../utilities/timeoutUtils' import { isDebugInstance } from '../../vscode/env' +import { tmpdir } from 'os' +import { join } from 'path' +import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports +import * as vscode from 'vscode' export function getNodeExecutableName(): string { return process.platform === 'win32' ? 'node.exe' : 'node' @@ -81,18 +85,67 @@ export async function validateNodeExe(nodePath: string[], lsp: string, args: str } } +/** + * Gets proxy settings and certificates from VS Code + */ +export async function getVSCodeSettings(): Promise<{ proxyUrl?: string; certificatePath?: string }> { + const result: { proxyUrl?: string; certificatePath?: string } = {} + const logger = getLogger('amazonqLsp') + + try { + // Get proxy settings from VS Code configuration + const httpConfig = vscode.workspace.getConfiguration('http') + const proxy = httpConfig.get('proxy') + if (proxy) { + result.proxyUrl = proxy + logger.info(`Using proxy from VS Code settings: ${proxy}`) + } + } catch (err) { + logger.error(`Failed to get VS Code settings: ${err}`) + return result + } + try { + const tls = await import('tls') + // @ts-ignore Get system certificates + const systemCerts = tls.getCACertificates('system') + // @ts-ignore Get any existing extra certificates + const extraCerts = tls.getCACertificates('extra') + const allCerts = [...systemCerts, ...extraCerts] + if (allCerts && allCerts.length > 0) { + logger.info(`Found ${allCerts.length} certificates in system's trust store`) + + const tempDir = join(tmpdir(), 'aws-toolkit-vscode') + if (!nodefs.existsSync(tempDir)) { + nodefs.mkdirSync(tempDir, { recursive: true }) + } + + const certPath = join(tempDir, 'vscode-ca-certs.pem') + const certContent = allCerts.join('\n') + + nodefs.writeFileSync(certPath, certContent) + result.certificatePath = certPath + logger.info(`Created certificate file at: ${certPath}`) + } + } catch (err) { + logger.error(`Failed to extract certificates: ${err}`) + } + return result +} + export function createServerOptions({ encryptionKey, executable, serverModule, execArgv, warnThresholds, + env, }: { encryptionKey: Buffer executable: string[] serverModule: string execArgv: string[] warnThresholds?: { cpu?: number; memory?: number } + env?: Record }) { return async () => { const bin = executable[0] @@ -100,7 +153,44 @@ export function createServerOptions({ if (isDebugInstance()) { args.unshift('--inspect=6080') } - const lspProcess = new ChildProcess(bin, args, { warnThresholds }) + + // Merge environment variables + const processEnv = { ...process.env } + if (env) { + Object.assign(processEnv, env) + } + + // Get settings from VS Code + const settings = await getVSCodeSettings() + const logger = getLogger('amazonqLsp') + + // Add proxy settings to the Node.js process + if (settings.proxyUrl) { + processEnv.HTTPS_PROXY = settings.proxyUrl + } + + // Add certificate path if available + if (settings.certificatePath) { + processEnv.NODE_EXTRA_CA_CERTS = settings.certificatePath + logger.info(`Using certificate file: ${settings.certificatePath}`) + } + + // Get SSL verification settings + const httpConfig = vscode.workspace.getConfiguration('http') + const strictSSL = httpConfig.get('proxyStrictSSL', true) + + // Handle SSL certificate verification + if (!strictSSL) { + processEnv.NODE_TLS_REJECT_UNAUTHORIZED = '0' + logger.info('SSL verification disabled via VS Code settings') + } + + const lspProcess = new ChildProcess(bin, args, { + warnThresholds, + spawnOptions: { + env: processEnv, + }, + }) // this is a long running process, awaiting it will never resolve void lspProcess.run() diff --git a/packages/webpack.base.config.js b/packages/webpack.base.config.js index 652249e6577..9f281a23cd0 100644 --- a/packages/webpack.base.config.js +++ b/packages/webpack.base.config.js @@ -38,6 +38,7 @@ module.exports = (env = {}, argv = {}) => { externals: { vscode: 'commonjs vscode', vue: 'root Vue', + tls: 'commonjs tls', }, resolve: { extensions: ['.ts', '.js'],