@@ -62,7 +62,14 @@ import { ObjectScriptExplorerProvider } from "./explorer/explorer";
6262import { WorkspaceNode } from "./explorer/models/workspaceNode" ;
6363import { FileSystemProvider } from "./providers/FileSystemPovider/FileSystemProvider" ;
6464import { WorkspaceSymbolProvider } from "./providers/WorkspaceSymbolProvider" ;
65- import { currentWorkspaceFolder , outputChannel , portFromDockerCompose , terminalWithDocker , notNull } from "./utils" ;
65+ import {
66+ connectionTarget ,
67+ currentWorkspaceFolder ,
68+ outputChannel ,
69+ portFromDockerCompose ,
70+ terminalWithDocker ,
71+ notNull ,
72+ } from "./utils" ;
6673import { ObjectScriptDiagnosticProvider } from "./providers/ObjectScriptDiagnosticProvider" ;
6774import { DocumentRangeFormattingEditProvider } from "./providers/DocumentRangeFormattingEditProvider" ;
6875
@@ -96,7 +103,7 @@ export const config = (setting?: string, workspaceFolderName?: string): vscode.W
96103 ) {
97104 workspaceFolderName = vscode . workspace . workspaceFolders [ 0 ] . name ;
98105 }
99- let prefix ;
106+ let prefix : string ;
100107 const workspaceFolder = vscode . workspace . workspaceFolders . find (
101108 ( el ) => el . name . toLowerCase ( ) === workspaceFolderName . toLowerCase ( )
102109 ) ;
@@ -145,17 +152,19 @@ let reporter: TelemetryReporter = null;
145152
146153let connectionSocket : WebSocket ;
147154
148- export const checkConnection = ( clearCookies = false ) : void => {
149- const workspaceFolder = currentWorkspaceFolder ( ) ;
155+ let serverManagerApi : any ;
156+
157+ export function checkConnection ( clearCookies = false , uri ?: vscode . Uri ) : void {
158+ const { apiTarget, configName } = connectionTarget ( uri ) ;
150159 if ( clearCookies ) {
151160 /// clean-up cached values
152- workspaceState . update ( workspaceFolder + ":host" , undefined ) ;
153- workspaceState . update ( workspaceFolder + ":port" , undefined ) ;
154- workspaceState . update ( workspaceFolder + ":password" , undefined ) ;
155- workspaceState . update ( workspaceFolder + ":apiVersion" , undefined ) ;
156- workspaceState . update ( workspaceFolder + ":docker" , undefined ) ;
161+ workspaceState . update ( configName + ":host" , undefined ) ;
162+ workspaceState . update ( configName + ":port" , undefined ) ;
163+ workspaceState . update ( configName + ":password" , undefined ) ;
164+ workspaceState . update ( configName + ":apiVersion" , undefined ) ;
165+ workspaceState . update ( configName + ":docker" , undefined ) ;
157166 }
158- let api = new AtelierAPI ( workspaceFolder ) ;
167+ let api = new AtelierAPI ( apiTarget , false ) ;
159168 const { active, host = "" , port = 0 , ns = "" } = api . config ;
160169 let connInfo = `${ host } :${ port } [${ ns } ]` ;
161170 if ( ! host . length || ! port || ! ns . length ) {
@@ -168,9 +177,9 @@ export const checkConnection = (clearCookies = false): void => {
168177 panel . text = `${ packageJson . displayName } - Disabled` ;
169178 return ;
170179 }
171- if ( ! workspaceState . get ( workspaceFolder + ":port" ) && ! api . externalServer ) {
180+ if ( ! workspaceState . get ( configName + ":port" ) && ! api . externalServer ) {
172181 const { port : dockerPort , docker : withDocker } = portFromDockerCompose ( ) ;
173- workspaceState . update ( workspaceFolder + ":docker" , withDocker ) ;
182+ workspaceState . update ( configName + ":docker" , withDocker ) ;
174183 if ( withDocker ) {
175184 if ( ! dockerPort ) {
176185 outputChannel . appendLine (
@@ -181,8 +190,8 @@ export const checkConnection = (clearCookies = false): void => {
181190 }
182191 terminalWithDocker ( ) ;
183192 if ( dockerPort !== port ) {
184- workspaceState . update ( workspaceFolder + ":host" , "localhost" ) ;
185- workspaceState . update ( workspaceFolder + ":port" , dockerPort ) ;
193+ workspaceState . update ( configName + ":host" , "localhost" ) ;
194+ workspaceState . update ( configName + ":port" , dockerPort ) ;
186195 }
187196 connInfo = `localhost:${ dockerPort } [${ ns } ]` ;
188197 }
@@ -194,10 +203,15 @@ export const checkConnection = (clearCookies = false): void => {
194203 panel . text = `${ connInfo } - Connected` ;
195204 return ;
196205 }
197- api = new AtelierAPI ( workspaceFolder ) ;
206+
207+ // Why must this be recreated here?
208+ api = new AtelierAPI ( apiTarget , false ) ;
209+
198210 if ( ! api . config . host || ! api . config . port || ! api . config . ns ) {
199- outputChannel . appendLine ( "host, port and ns must be specified." ) ;
211+ const message = "host, port and ns must be specified." ;
212+ outputChannel . appendLine ( message ) ;
200213 panel . text = `${ packageJson . displayName } - ERROR` ;
214+ panel . tooltip = message ;
201215 return ;
202216 }
203217 api
@@ -222,32 +236,39 @@ export const checkConnection = (clearCookies = false): void => {
222236 . catch ( ( error ) => {
223237 let message = error . message ;
224238 if ( error instanceof StatusCodeError && error . statusCode === 401 ) {
225- setTimeout (
226- ( ) =>
239+ setTimeout ( ( ) => {
240+ const username = api . config . username ;
241+ if ( username === "" ) {
242+ vscode . window . showErrorMessage ( `Anonymous access rejected by ${ connInfo } .` ) ;
243+ if ( ! api . externalServer ) {
244+ vscode . window . showErrorMessage ( "Connection has been disabled." ) ;
245+ disableConnection ( configName ) ;
246+ }
247+ } else {
227248 vscode . window
228249 . showInputBox ( {
229250 password : true ,
230- placeHolder : "Not Authorized, please enter password to connect to: " + connInfo ,
251+ placeHolder : `Not Authorized. Enter password to connect as user '${ username } ' to ${ connInfo } ` ,
252+ prompt : ! api . externalServer ? "If no password is entered the connection will be disabled." : "" ,
231253 ignoreFocusOut : true ,
232254 } )
233255 . then ( ( password ) => {
234256 if ( password ) {
235- workspaceState . update ( currentWorkspaceFolder ( ) + ":password" , password ) ;
236- checkConnection ( ) ;
237- } else {
238- vscode . workspace . getConfiguration ( ) . update ( "objectscript.conn.active" , false ) ;
257+ workspaceState . update ( configName + ":password" , password ) ;
258+ checkConnection ( false , uri ) ;
259+ } else if ( ! api . externalServer ) {
260+ disableConnection ( configName ) ;
239261 }
240- } ) ,
241- 1000
242- ) ;
262+ } ) ;
263+ }
264+ } , 1000 ) ;
243265 message = "Not Authorized" ;
244266 outputChannel . appendLine (
245- `Authorization error: please check your username/password in the settings,
246- and if you have sufficient privileges on the server.`
267+ `Authorization error: Check your credentials in Settings, and that you have sufficient privileges on the /api/atelier web application on ${ connInfo } `
247268 ) ;
248269 } else {
249- outputChannel . appendLine ( " Error: " + message ) ;
250- outputChannel . appendLine ( "Please check your network settings in the settings." ) ;
270+ outputChannel . appendLine ( ` Error: ${ message } ` ) ;
271+ outputChannel . appendLine ( `Check your server details in Settings ( ${ connInfo } ).` ) ;
251272 }
252273 console . error ( error ) ;
253274 panel . text = `${ connInfo } - ERROR` ;
@@ -257,44 +278,70 @@ export const checkConnection = (clearCookies = false): void => {
257278 . finally ( ( ) => {
258279 explorerProvider . refresh ( ) ;
259280 } ) ;
260- } ;
281+ }
282+
283+ // Set objectscript.conn.active = false at WorkspaceFolder level if objectscript.conn is defined there,
284+ // else set it false at Workspace level
285+ function disableConnection ( configName : string ) {
286+ const connConfig : vscode . WorkspaceConfiguration = config ( "" , configName ) ;
287+ const target : vscode . ConfigurationTarget = connConfig . inspect ( "conn" ) . workspaceFolderValue
288+ ? vscode . ConfigurationTarget . WorkspaceFolder
289+ : vscode . ConfigurationTarget . Workspace ;
290+ const targetConfig : any =
291+ connConfig . inspect ( "conn" ) . workspaceFolderValue || connConfig . inspect ( "conn" ) . workspaceValue ;
292+ return connConfig . update ( "conn" , { ...targetConfig , active : false } , target ) ;
293+ }
261294
262- async function serverManager ( ) : Promise < void > {
295+ // Promise to return the API of the servermanager
296+ async function serverManager ( ) : Promise < any > {
263297 const extId = "intersystems-community.servermanager" ;
298+ let extension = vscode . extensions . getExtension ( extId ) ;
264299 const ignore =
265300 config ( "ignoreInstallServerManager" ) ||
266301 vscode . workspace . getConfiguration ( "intersystems.servers" ) . get ( "/ignore" , false ) ;
267- if ( ignore || vscode . extensions . getExtension ( extId ) ) {
268- return ;
302+ if ( ! extension ) {
303+ if ( ignore ) {
304+ return ;
305+ }
306+ await vscode . window
307+ . showInformationMessage (
308+ "The InterSystems® Server Manager extension is recommended to help you define connections and store passwords securely in your keychain." ,
309+ "Install" ,
310+ "Skip" ,
311+ "Ignore"
312+ )
313+ . then ( async ( action ) => {
314+ switch ( action ) {
315+ case "Install" :
316+ await vscode . commands . executeCommand ( "workbench.extensions.search" , `@tag:"intersystems"` ) ;
317+ await vscode . commands . executeCommand ( "extension.open" , extId ) ;
318+ await vscode . commands . executeCommand ( "workbench.extensions.installExtension" , extId ) ;
319+ extension = vscode . extensions . getExtension ( extId ) ;
320+ break ;
321+ case "Ignore" :
322+ config ( ) . update ( "ignoreInstallServerManager" , true , vscode . ConfigurationTarget . Global ) ;
323+ break ;
324+ case "Skip" :
325+ default :
326+ }
327+ } ) ;
328+ }
329+ if ( extension ) {
330+ if ( ! extension . isActive ) {
331+ await extension . activate ( ) ;
332+ }
333+ return extension . exports ;
269334 }
270- return vscode . window
271- . showInformationMessage (
272- "The InterSystems® Server Manager extension is recommended to help you define connections." ,
273- "Install" ,
274- "Skip" ,
275- "Ignore"
276- )
277- . then ( async ( action ) => {
278- switch ( action ) {
279- case "Install" :
280- await vscode . commands . executeCommand ( "workbench.extensions.search" , `@tag:"intersystems"` ) ;
281- await vscode . commands . executeCommand ( "extension.open" , extId ) ;
282- await vscode . commands . executeCommand ( "workbench.extensions.installExtension" , extId ) ;
283- break ;
284- case "Ignore" :
285- config ( ) . update ( "ignoreInstallServerManager" , true , vscode . ConfigurationTarget . Global ) ;
286- break ;
287- case "Skip" :
288- default :
289- }
290- } ) ;
291335}
292336
293337export async function activate ( context : vscode . ExtensionContext ) : Promise < void > {
294338 if ( ! packageJson . version . includes ( "SNAPSHOT" ) ) {
295339 reporter = new TelemetryReporter ( extensionId , extensionVersion , aiKey ) ;
296340 }
297341
342+ // Get api for servermanager extension, perhaps offering to install it
343+ serverManagerApi = await serverManager ( ) ;
344+
298345 const languages = packageJson . contributes . languages . map ( ( lang ) => lang . id ) ;
299346 workspaceState = context . workspaceState ;
300347 extensionContext = context ;
@@ -305,7 +352,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
305352 fileSystemProvider = new FileSystemProvider ( ) ;
306353
307354 explorerProvider = new ObjectScriptExplorerProvider ( ) ;
308- // vscode.window.registerTreeDataProvider("ObjectScriptExplorer", explorerProvider);
309355 vscode . window . createTreeView ( "ObjectScriptExplorer" , {
310356 treeDataProvider : explorerProvider ,
311357 showCollapseAll : true ,
@@ -322,7 +368,17 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
322368 panel . command = "vscode-objectscript.serverActions" ;
323369 panel . show ( ) ;
324370
325- checkConnection ( true ) ;
371+ // Check once (flushing cookies) each connection used by the workspace(s)
372+ const toCheck = new Map < string , vscode . Uri > ( ) ;
373+ vscode . workspace . workspaceFolders . map ( ( workspaceFolder ) => {
374+ const uri = workspaceFolder . uri ;
375+ const { configName } = connectionTarget ( uri ) ;
376+ toCheck . set ( configName , uri ) ;
377+ } ) ;
378+ toCheck . forEach ( function ( uri ) {
379+ checkConnection ( true , uri ) ;
380+ } ) ;
381+
326382 vscode . workspace . onDidChangeConfiguration ( ( { affectsConfiguration } ) => {
327383 if ( affectsConfiguration ( "objectscript.conn" ) ) {
328384 checkConnection ( true ) ;
@@ -597,9 +653,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
597653 ...proposed
598654 ) ;
599655 reporter && reporter . sendTelemetryEvent ( "extensionActivated" ) ;
600-
601- // offer to install servermanager extension
602- await serverManager ( ) ;
603656}
604657
605658export function deactivate ( ) : void {
0 commit comments