diff --git a/package.json b/package.json index b0784628..9f1be006 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,21 @@ "markdownDescription": "An external command that outputs additional HTTP headers added to all requests. The command must output each header as `key=value` on its own line. The following environment variables will be available to the process: `CODER_URL`.", "type": "string", "default": "" + }, + "coder.tlsCertFile": { + "markdownDescription": "Path to file for TLS client cert", + "type": "string", + "default": "" + }, + "coder.tlsKeyFile": { + "markdownDescription": "Path to file for TLS client key", + "type": "string", + "default": "" + }, + "coder.tlsCaFile": { + "markdownDescription": "Path to file for TLS certificate authority", + "type": "string", + "default": "" } } }, diff --git a/src/extension.ts b/src/extension.ts index 7345569b..c5b8ecd3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,7 @@ "use strict" import axios from "axios" import { getAuthenticatedUser } from "coder/site/src/api/api" +import fs from "fs" import * as https from "https" import * as module from "module" import * as vscode from "vscode" @@ -30,13 +31,21 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { false, ) - // updateInsecure is called on extension activation and when the insecure - // setting is changed. It updates the https agent to allow self-signed - // certificates if the insecure setting is true. - const applyInsecure = () => { - const insecure = Boolean(vscode.workspace.getConfiguration().get("coder.insecure")) + // applyHttpProperties is called on extension activation and when the + // insecure or TLS setting are changed. It updates the https agent to allow + // self-signed certificates if the insecure setting is true, as well as + // adding cert/key/ca properties for TLS. + const applyHttpProperties = () => { + const cfg = vscode.workspace.getConfiguration() + const insecure = Boolean(cfg.get("coder.insecure")) + const certFile = String(cfg.get("coder.tlsCertFile")) + const keyFile = String(cfg.get("coder.tlsKeyFile")) + const caFile = String(cfg.get("coder.tlsCaFile")) axios.defaults.httpsAgent = new https.Agent({ + cert: certFile === "" ? undefined : fs.readFileSync(certFile), + key: keyFile === "" ? undefined : fs.readFileSync(keyFile), + ca: caFile === "" ? undefined : fs.readFileSync(caFile), // rejectUnauthorized defaults to true, so we need to explicitly set it to false // if we want to allow self-signed certificates. rejectUnauthorized: !insecure, @@ -51,9 +60,16 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { ) vscode.workspace.onDidChangeConfiguration((e) => { - e.affectsConfiguration("coder.insecure") && applyInsecure() + if ( + e.affectsConfiguration("coder.insecure") || + e.affectsConfiguration("coder.tlsCertFile") || + e.affectsConfiguration("coder.tlsKeyFile") || + e.affectsConfiguration("coder.tlsCaFile") + ) { + applyHttpProperties() + } }) - applyInsecure() + applyHttpProperties() const output = vscode.window.createOutputChannel("Coder") const storage = new Storage(output, ctx.globalState, ctx.secrets, ctx.globalStorageUri, ctx.logUri)