@@ -14,6 +14,8 @@ import {
1414} from "vscode" ;
1515import { ServerManagerAuthenticationSession } from "./authenticationSession" ;
1616import { globalState } from "./extension" ;
17+ import { getServerSpec } from "./api/getServerSpec" ;
18+ import { makeRESTRequest } from "./makeRESTRequest" ;
1719
1820export const AUTHENTICATION_PROVIDER = "intersystems-server-credentials" ;
1921const AUTHENTICATION_PROVIDER_LABEL = "InterSystems Server Credentials" ;
@@ -35,6 +37,7 @@ export class ServerManagerAuthenticationProvider implements AuthenticationProvid
3537 private readonly _secretStorage ;
3638
3739 private _sessions : ServerManagerAuthenticationSession [ ] = [ ] ;
40+ private _checkedSessions : ServerManagerAuthenticationSession [ ] = [ ] ;
3841
3942 private _serverManagerExtension = extensions . getExtension ( "intersystems-community.servermanager" ) ;
4043
@@ -52,7 +55,7 @@ export class ServerManagerAuthenticationProvider implements AuthenticationProvid
5255 this . _initializedDisposable ?. dispose ( ) ;
5356 }
5457
55- // This function is called first when `vscode.authentication.getSessions ` is called.
58+ // This function is called first when `vscode.authentication.getSession ` is called.
5659 public async getSessions ( scopes : string [ ] = [ ] ) : Promise < readonly AuthenticationSession [ ] > {
5760 await this . _ensureInitialized ( ) ;
5861 let sessions = this . _sessions ;
@@ -61,7 +64,11 @@ export class ServerManagerAuthenticationProvider implements AuthenticationProvid
6164 for ( let index = 0 ; index < scopes . length ; index ++ ) {
6265 sessions = sessions . filter ( ( session ) => session . scopes [ index ] === scopes [ index ] . toLowerCase ( ) ) ;
6366 }
64- return sessions ;
67+
68+ if ( sessions . length === 1 ) {
69+ sessions = sessions . filter ( async ( session ) => await this . _isStillValid ( session ) ) ;
70+ }
71+ return sessions || [ ] ;
6572 }
6673
6774 // This function is called after `this.getSessions` is called, and only when:
@@ -104,9 +111,17 @@ export class ServerManagerAuthenticationProvider implements AuthenticationProvid
104111
105112 // Return existing session if found
106113 const sessionId = ServerManagerAuthenticationProvider . sessionId ( serverName , userName ) ;
107- const existingSession = this . _sessions . find ( ( s ) => s . id === sessionId ) ;
114+ let existingSession = this . _sessions . find ( ( s ) => s . id === sessionId ) ;
108115 if ( existingSession ) {
109- return existingSession ;
116+ if ( this . _checkedSessions . find ( ( s ) => s . id === sessionId ) ) {
117+ return existingSession ;
118+ }
119+
120+ // Check if the session is still valid
121+ if ( await this . _isStillValid ( existingSession ) ) {
122+ this . _checkedSessions . push ( existingSession ) ;
123+ return existingSession ;
124+ }
110125 }
111126
112127 let password : string | undefined = "" ;
@@ -190,25 +205,52 @@ export class ServerManagerAuthenticationProvider implements AuthenticationProvid
190205 return session ;
191206 }
192207
208+ private async _isStillValid ( session : ServerManagerAuthenticationSession ) : Promise < boolean > {
209+ if ( this . _checkedSessions . find ( ( s ) => s . id === session . id ) ) {
210+ return true ;
211+ }
212+ const serverSpec = await getServerSpec ( session . serverName ) ;
213+ if ( serverSpec ) {
214+ serverSpec . username = session . userName ;
215+ serverSpec . password = session . accessToken ;
216+ const response = await makeRESTRequest ( "HEAD" , serverSpec ) ;
217+ if ( response ?. status !== 200 ) {
218+ this . _removeSession ( session . id , true ) ;
219+ return false ;
220+ }
221+ }
222+ this . _checkedSessions . push ( session ) ;
223+ return true ;
224+ }
225+
193226 // This function is called when the end user signs out of the account.
194227 public async removeSession ( sessionId : string ) : Promise < void > {
228+ this . _removeSession ( sessionId ) ;
229+ }
230+
231+ private async _removeSession ( sessionId : string , alwaysDeletePassword = false ) : Promise < void > {
195232 const index = this . _sessions . findIndex ( ( item ) => item . id === sessionId ) ;
196233 const session = this . _sessions [ index ] ;
197234
198- let deletePassword = false ;
199235 const credentialKey = ServerManagerAuthenticationProvider . credentialKey ( sessionId ) ;
200- if ( await this . secretStorage . get ( credentialKey ) ) {
201- const passwordOption = workspace . getConfiguration ( "intersystemsServerManager.credentialsProvider" )
202- . get < string > ( "deletePasswordOnSignout" , "ask" ) ;
203- deletePassword = ( passwordOption === "always" ) ;
204- if ( passwordOption === "ask" ) {
205- const choice = await window . showWarningMessage (
206- `Do you want to keep the password or delete it?` ,
207- { detail : `The ${ AUTHENTICATION_PROVIDER_LABEL } account you signed out (${ session . account . label } ) is currently storing its password securely on your workstation.` , modal : true } ,
208- { title : "Keep" , isCloseAffordance : true } ,
209- { title : "Delete" , isCloseAffordance : false } ,
210- ) ;
211- deletePassword = ( choice ?. title === "Delete" ) ;
236+ let deletePassword = false ;
237+ const hasStoredPassword = await this . secretStorage . get ( credentialKey ) !== undefined ;
238+ if ( alwaysDeletePassword ) {
239+ deletePassword = hasStoredPassword ;
240+ } else {
241+ if ( hasStoredPassword ) {
242+ const passwordOption = workspace . getConfiguration ( "intersystemsServerManager.credentialsProvider" )
243+ . get < string > ( "deletePasswordOnSignout" , "ask" ) ;
244+ deletePassword = ( passwordOption === "always" ) ;
245+ if ( passwordOption === "ask" ) {
246+ const choice = await window . showWarningMessage (
247+ `Do you want to keep the password or delete it?` ,
248+ { detail : `The ${ AUTHENTICATION_PROVIDER_LABEL } account you signed out (${ session . account . label } ) is currently storing its password securely on your workstation.` , modal : true } ,
249+ { title : "Keep" , isCloseAffordance : true } ,
250+ { title : "Delete" , isCloseAffordance : false } ,
251+ ) ;
252+ deletePassword = ( choice ?. title === "Delete" ) ;
253+ }
212254 }
213255 }
214256 if ( deletePassword ) {
0 commit comments