@@ -2036,33 +2036,43 @@ export default class ConnectionManager {
20362036 private async handleSecurityTokenRequest (
20372037 params : RequestSecurityTokenParams ,
20382038 ) : Promise < RequestSecurityTokenResponse > {
2039- if ( this . _keyVaultTokenCache . has ( JSON . stringify ( params ) ) ) {
2040- const token = this . _keyVaultTokenCache . get ( JSON . stringify ( params ) ) ;
2041- const isExpired = AzureController . isTokenExpired ( token . expiresOn ) ;
2042- if ( ! isExpired ) {
2043- return {
2044- accountKey : token . key ,
2045- token : token . token ,
2046- } ;
2047- } else {
2048- this . _keyVaultTokenCache . delete ( JSON . stringify ( params ) ) ;
2039+ try {
2040+ if ( this . _keyVaultTokenCache . has ( JSON . stringify ( params ) ) ) {
2041+ const token = this . _keyVaultTokenCache . get ( JSON . stringify ( params ) ) ;
2042+ const isExpired = AzureController . isTokenExpired ( token . expiresOn ) ;
2043+ if ( ! isExpired ) {
2044+ return {
2045+ accountKey : token . key ,
2046+ token : token . token ,
2047+ } ;
2048+ } else {
2049+ this . _keyVaultTokenCache . delete ( JSON . stringify ( params ) ) ;
2050+ }
20492051 }
2050- }
2051- const account = await this . selectAccount ( ) ;
2052- const tenant = await this . selectTenantId ( account ) ;
2052+ const account = await this . selectAccount ( ) ;
2053+ const tenant = await this . selectTenantId ( account ) ;
20532054
2054- const token = await this . azureController . getAccountSecurityToken (
2055- account ,
2056- tenant ,
2057- getCloudProviderSettings ( account . key . providerId ) . settings . azureKeyVaultResource ,
2058- ) ;
2055+ const token = await this . azureController . getAccountSecurityToken (
2056+ account ,
2057+ tenant ,
2058+ getCloudProviderSettings ( account . key . providerId ) . settings . azureKeyVaultResource ,
2059+ ) ;
20592060
2060- this . _keyVaultTokenCache . set ( JSON . stringify ( params ) , token ) ;
2061+ this . _keyVaultTokenCache . set ( JSON . stringify ( params ) , token ) ;
20612062
2062- return {
2063- accountKey : token . key ,
2064- token : token . token ,
2065- } ;
2063+ return {
2064+ accountKey : token . key ,
2065+ token : token . token ,
2066+ } ;
2067+ } catch ( error ) {
2068+ this . _logger . error ( `Security token request failed: ${ getErrorMessage ( error ) } ` ) ;
2069+ // Return empty response rather than letting the error propagate
2070+ // to STS as a null reference
2071+ return {
2072+ accountKey : "" ,
2073+ token : "" ,
2074+ } ;
2075+ }
20662076 }
20672077
20682078 private async selectAccount ( ) : Promise < IAccount > {
@@ -2074,6 +2084,16 @@ export default class ConnectionManager {
20742084 const quickPickItems = this . createAccountQuickPickItems ( accounts , currentAccountId ) ;
20752085 const selectedAccount = await this . showAccountQuickPick ( quickPickItems ) ;
20762086
2087+ // eslint-disable-next-line no-restricted-syntax
2088+ if ( selectedAccount === null ) {
2089+ // User selected "Sign in to Azure" — trigger sign-in and use the new account
2090+ const newAccount = await this . addAccount ( ) ;
2091+ if ( ! newAccount ) {
2092+ throw new Error ( LocalizedConstants . Connection . noAccountSelected ) ;
2093+ }
2094+ return newAccount ;
2095+ }
2096+
20772097 if ( ! selectedAccount ) {
20782098 throw new Error ( LocalizedConstants . Connection . noAccountSelected ) ;
20792099 }
@@ -2103,30 +2123,47 @@ export default class ConnectionManager {
21032123 return accountItems ;
21042124 }
21052125
2126+ /*
2127+ * Shows a quick pick to select an account. Returns the selected account, null if "Sign in to Azure" was selected,
2128+ * or undefined if the quick pick was dismissed.
2129+ * @params items The quick pick items to show
2130+ * @returns The selected account, null if "Sign in to Azure" was selected, or undefined if the quick pick was dismissed
2131+ */
21062132 private async showAccountQuickPick (
21072133 items : AccountQuickPickItem [ ] ,
2108- ) : Promise < IAccount | undefined > {
2109- const account = await new Promise < IAccount | undefined > ( ( resolve , reject ) => {
2134+ ) : Promise < IAccount | null | undefined > {
2135+ const account = await new Promise < IAccount | null | undefined > ( ( resolve , reject ) => {
21102136 const quickPick = vscode . window . createQuickPick < AccountQuickPickItem > ( ) ;
21112137 quickPick . items = items ;
21122138 quickPick . placeholder = LocalizedConstants . Connection . SelectAccountForKeyVault ;
2139+ let accepted = false ;
21132140
21142141 quickPick . onDidAccept ( async ( ) => {
21152142 try {
2143+ accepted = true ;
21162144 const selectedItem = quickPick . selectedItems [ 0 ] ;
2145+ quickPick . dispose ( ) ;
21172146 if ( ! selectedItem ) {
21182147 resolve ( undefined ) ;
21192148 return ;
21202149 }
21212150
21222151 const account = selectedItem . account ;
2123- quickPick . dispose ( ) ;
2124- resolve ( account ) ;
2152+ // Return null to signal "sign in" was selected (account is undefined on that item)
2153+ resolve ( account ?? null ) ; // eslint-disable-line no-restricted-syntax
21252154 } catch ( error ) {
21262155 quickPick . dispose ( ) ;
21272156 reject ( error ) ;
21282157 }
21292158 } ) ;
2159+
2160+ quickPick . onDidHide ( ( ) => {
2161+ quickPick . dispose ( ) ;
2162+ if ( ! accepted ) {
2163+ resolve ( undefined ) ;
2164+ }
2165+ } ) ;
2166+
21302167 quickPick . show ( ) ;
21312168 } ) ;
21322169 return account ;
0 commit comments