|
1 | 1 | "use strict" |
| 2 | +importaxiosfrom"axios" |
2 | 3 | import{getAuthenticatedUser}from"coder/site/src/api/api" |
| 4 | +import*ashttpsfrom"https" |
3 | 5 | import*asmodulefrom"module" |
4 | 6 | import*asvscodefrom"vscode" |
5 | 7 | import{Commands}from"./commands" |
| 8 | +import{SelfSignedCertificateError}from"./error" |
6 | 9 | import{Remote}from"./remote" |
7 | 10 | import{Storage}from"./storage" |
8 | 11 | import{WorkspaceQuery,WorkspaceProvider}from"./workspacesProvider" |
9 | 12 |
|
10 | 13 | exportasyncfunctionactivate(ctx:vscode.ExtensionContext):Promise<void>{ |
| 14 | +// The Remote SSH extension's proposed APIs are used to override |
| 15 | +// the SSH host name in VS Code itself. It's visually unappealing |
| 16 | +// having a lengthy name! |
| 17 | +// |
| 18 | +// This is janky, but that's alright since it provides such minimal |
| 19 | +// functionality to the extension. |
| 20 | +constremoteSSHExtension=vscode.extensions.getExtension("ms-vscode-remote.remote-ssh") |
| 21 | +if(!remoteSSHExtension){ |
| 22 | +thrownewError("Remote SSH extension not found") |
| 23 | +} |
| 24 | +// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 25 | +constvscodeProposed:typeofvscode=(moduleasany)._load( |
| 26 | +"vscode", |
| 27 | +{ |
| 28 | +filename:remoteSSHExtension?.extensionPath, |
| 29 | +}, |
| 30 | +false, |
| 31 | +) |
| 32 | + |
| 33 | +// updateInsecure is called on extension activation and when the insecure |
| 34 | +// setting is changed. It updates the https agent to allow self-signed |
| 35 | +// certificates if the insecure setting is true. |
| 36 | +constapplyInsecure=()=>{ |
| 37 | +constinsecure=Boolean(vscode.workspace.getConfiguration().get("coder.insecure")) |
| 38 | + |
| 39 | +axios.defaults.httpsAgent=newhttps.Agent({ |
| 40 | +// rejectUnauthorized defaults to true, so we need to explicitly set it to false |
| 41 | +// if we want to allow self-signed certificates. |
| 42 | +rejectUnauthorized:!insecure, |
| 43 | +}) |
| 44 | +} |
| 45 | + |
| 46 | +axios.interceptors.response.use( |
| 47 | +(r)=>r, |
| 48 | +(err)=>{ |
| 49 | +if(err){ |
| 50 | +constmsg=err.toString()asstring |
| 51 | +if(msg.indexOf("unable to verify the first certificate")!==-1){ |
| 52 | +thrownewSelfSignedCertificateError(msg) |
| 53 | +} |
| 54 | +} |
| 55 | + |
| 56 | +throwerr |
| 57 | +}, |
| 58 | +) |
| 59 | + |
| 60 | +vscode.workspace.onDidChangeConfiguration((e)=>{ |
| 61 | +e.affectsConfiguration("coder.insecure")&&applyInsecure() |
| 62 | +}) |
| 63 | +applyInsecure() |
| 64 | + |
11 | 65 | constoutput=vscode.window.createOutputChannel("Coder") |
12 | 66 | conststorage=newStorage(output,ctx.globalState,ctx.secrets,ctx.globalStorageUri,ctx.logUri) |
13 | 67 | awaitstorage.init() |
@@ -62,25 +116,6 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> { |
62 | 116 | }, |
63 | 117 | }) |
64 | 118 |
|
65 | | -// The Remote SSH extension's proposed APIs are used to override |
66 | | -// the SSH host name in VS Code itself. It's visually unappealing |
67 | | -// having a lengthy name! |
68 | | -// |
69 | | -// This is janky, but that's alright since it provides such minimal |
70 | | -// functionality to the extension. |
71 | | -constremoteSSHExtension=vscode.extensions.getExtension("ms-vscode-remote.remote-ssh") |
72 | | -if(!remoteSSHExtension){ |
73 | | -thrownewError("Remote SSH extension not found") |
74 | | -} |
75 | | -// eslint-disable-next-line @typescript-eslint/no-explicit-any |
76 | | -constvscodeProposed:typeofvscode=(moduleasany)._load( |
77 | | -"vscode", |
78 | | -{ |
79 | | -filename:remoteSSHExtension?.extensionPath, |
80 | | -}, |
81 | | -false, |
82 | | -) |
83 | | - |
84 | 119 | constcommands=newCommands(vscodeProposed,storage) |
85 | 120 |
|
86 | 121 | vscode.commands.registerCommand("coder.login",commands.login.bind(commands)) |
@@ -109,6 +144,27 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> { |
109 | 144 | try{ |
110 | 145 | awaitremote.setup(vscodeProposed.env.remoteAuthority) |
111 | 146 | }catch(ex){ |
| 147 | +if(exinstanceofSelfSignedCertificateError){ |
| 148 | +constprompt=awaitvscodeProposed.window.showErrorMessage( |
| 149 | +"Failed to open workspace", |
| 150 | +{ |
| 151 | +detail:SelfSignedCertificateError.Notification, |
| 152 | +modal:true, |
| 153 | +useCustom:true, |
| 154 | +}, |
| 155 | +SelfSignedCertificateError.ActionAllowInsecure, |
| 156 | +SelfSignedCertificateError.ActionViewMoreDetails, |
| 157 | +) |
| 158 | +if(prompt===SelfSignedCertificateError.ActionAllowInsecure){ |
| 159 | +awaitex.allowInsecure(storage) |
| 160 | +awaitremote.reloadWindow() |
| 161 | +return |
| 162 | +} |
| 163 | +if(prompt===SelfSignedCertificateError.ActionViewMoreDetails){ |
| 164 | +awaitex.viewMoreDetails() |
| 165 | +return |
| 166 | +} |
| 167 | +} |
112 | 168 | awaitvscodeProposed.window.showErrorMessage("Failed to open workspace",{ |
113 | 169 | detail:(exasstring).toString(), |
114 | 170 | modal:true, |
|