@@ -30,6 +30,8 @@ import { builderIdStartUrl, internalStartUrl } from '../../auth/sso/constants'
30
30
import { VSCODE_EXTENSION_ID } from '../../shared/extensions'
31
31
import { RegionProfileManager } from '../region/regionProfileManager'
32
32
import { AuthFormId } from '../../login/webview/vue/types'
33
+ import { notifySelectDeveloperProfile } from '../region/utils'
34
+ import { once } from '../../shared/utilities/functionUtils'
33
35
34
36
const localize = nls . loadMessageBundle ( )
35
37
@@ -91,9 +93,31 @@ export class AuthUtil implements IAuthProvider {
91
93
return this . session . loginType === LoginTypes . SSO
92
94
}
93
95
96
+ /**
97
+ * HACK: Ideally we'd put {@link notifySelectDeveloperProfile} in to {@link restore}.
98
+ * But because {@link refreshState} is only called if !isConnected, we cannot do it since
99
+ * {@link notifySelectDeveloperProfile} needs {@link refreshState} to run so it can set
100
+ * the Bearer Token in the LSP first.
101
+ */
102
+ didStartSignedIn = false
103
+
94
104
async restore ( ) {
95
105
await this . session . restore ( )
96
- if ( ! this . isConnected ( ) ) {
106
+ this . didStartSignedIn = this . isConnected ( )
107
+
108
+ // HACK: We noticed that if calling `refreshState()` here when the user was already signed in, something broke.
109
+ // So as a solution we only call it if they were not already signed in.
110
+ //
111
+ // But in the case where a user was already signed in, we allow `session.restore()` to trigger `refreshState()` through
112
+ // event emitters.
113
+ // This is unoptimal since `refreshState()` should be able to be called multiple times and still work.
114
+ //
115
+ // Because of this edge case, when `restore()` is called we cannot assume all Auth is setup when this function returns,
116
+ // since we may still be waiting on the event emitter to trigger the expected functions.
117
+ //
118
+ // TODO: Figure out why removing the if statement below causes things to break. Maybe we just need to
119
+ // promisify the call and any subsequent callers will not make a redundant call.
120
+ if ( ! this . didStartSignedIn ) {
97
121
await this . refreshState ( )
98
122
}
99
123
}
@@ -257,20 +281,24 @@ export class AuthUtil implements IAuthProvider {
257
281
258
282
private async refreshState ( state = this . getAuthState ( ) ) {
259
283
if ( state === 'expired' || state === 'notConnected' ) {
284
+ this . lspAuth . deleteBearerToken ( )
260
285
if ( this . isIdcConnection ( ) ) {
261
286
await this . regionProfileManager . invalidateProfile ( this . regionProfileManager . activeRegionProfile ?. arn )
262
287
await this . regionProfileManager . clearCache ( )
263
288
}
264
- this . lspAuth . deleteBearerToken ( )
265
289
}
266
290
if ( state === 'connected' ) {
291
+ const bearerTokenParams = ( await this . session . getToken ( ) ) . updateCredentialsParams
292
+ await this . lspAuth . updateBearerToken ( bearerTokenParams )
293
+
267
294
if ( this . isIdcConnection ( ) ) {
268
295
await this . regionProfileManager . restoreProfileSelection ( )
269
296
}
270
- const bearerTokenParams = ( await this . session . getToken ( ) ) . updateCredentialsParams
271
- await this . lspAuth . updateBearerToken ( bearerTokenParams )
272
297
}
273
298
299
+ // regardless of state, send message at startup if user needs to select a Developer Profile
300
+ void this . tryNotifySelectDeveloperProfile ( )
301
+
274
302
vsCodeState . isFreeTierLimitReached = false
275
303
await this . setVscodeContextProps ( state )
276
304
await Promise . all ( [
@@ -283,6 +311,12 @@ export class AuthUtil implements IAuthProvider {
283
311
}
284
312
}
285
313
314
+ private tryNotifySelectDeveloperProfile = once ( async ( ) => {
315
+ if ( this . regionProfileManager . requireProfileSelection ( ) && this . didStartSignedIn ) {
316
+ await notifySelectDeveloperProfile ( )
317
+ }
318
+ } )
319
+
286
320
async getTelemetryMetadata ( ) : Promise < TelemetryMetadata > {
287
321
if ( ! this . isConnected ( ) ) {
288
322
return {
0 commit comments