Skip to content

Commit 8ff4119

Browse files
authored
fix(codewhisperer): popup for access token migration #3123
* fix(codewhisperer): update error popup for access token migration * use different keys for migration warning and error * add flag for token expired and also show erorr popup * refresh the root node after nullify the token
1 parent c9afa97 commit 8ff4119

File tree

3 files changed

+118
-56
lines changed

3 files changed

+118
-56
lines changed

src/codewhisperer/activation.ts

Lines changed: 98 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
showFreeTierLimit,
3535
updateReferenceLog,
3636
showIntroduction,
37+
showAccessTokenErrorLearnMore,
3738
} from './commands/basicCommands'
3839
import { sleep } from '../shared/utilities/timeoutUtils'
3940
import { ReferenceLogViewProvider } from './service/referenceLogViewProvider'
@@ -47,10 +48,10 @@ import { InlineCompletionService, refreshStatusBar } from './service/inlineCompl
4748
import { isInlineCompletionEnabled } from './util/commonUtil'
4849
import { CodeWhispererCodeCoverageTracker } from './tracker/codewhispererCodeCoverageTracker'
4950
import { AuthUtil, isUpgradeableConnection } from './util/authUtil'
50-
import globals from '../shared/extensionGlobals'
5151
import { Auth } from '../credentials/auth'
5252
import { isUserCancelledError } from '../shared/errors'
5353
import { showViewLogsMessage } from '../shared/utilities/messages'
54+
import globals from '../shared/extensionGlobals'
5455

5556
const performance = globalThis.performance ?? require('perf_hooks').performance
5657

@@ -61,6 +62,7 @@ export async function activate(context: ExtContext): Promise<void> {
6162
/**
6263
* Enable essential intellisense default settings for AWS C9 IDE
6364
*/
65+
6466
if (isCloud9()) {
6567
await enableDefaultConfigCloud9()
6668
}
@@ -167,6 +169,8 @@ export async function activate(context: ExtContext): Promise<void> {
167169
showSsoSignIn.register(),
168170
// learn more about CodeWhisperer
169171
showLearnMore.register(),
172+
// learn more about CodeWhisperer access token migration
173+
showAccessTokenErrorLearnMore.register(),
170174
// show free tier limit
171175
showFreeTierLimit.register(),
172176
// update reference log instance
@@ -220,6 +224,9 @@ export async function activate(context: ExtContext): Promise<void> {
220224

221225
async function showAccessTokenMigrationDialogue() {
222226
// TODO: Change the color of the buttons
227+
const accessTokenExpired =
228+
context.extensionContext.globalState.get<boolean>(CodeWhispererConstants.accessTokenExpriedKey) || false
229+
223230
if (AuthUtil.instance.hasAccessToken()) {
224231
await Auth.instance.tryAutoConnect()
225232
const conn = Auth.instance.activeConnection
@@ -240,65 +247,101 @@ export async function activate(context: ExtContext): Promise<void> {
240247

241248
await vscode.commands.executeCommand('aws.codeWhisperer.refreshRootNode')
242249
const t = new Date()
243-
const doNotShowAgain =
244-
context.extensionContext.globalState.get<boolean>(
245-
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainKey
246-
) || false
247-
const notificationLastShown: number =
248-
context.extensionContext.globalState.get<number | undefined>(
249-
CodeWhispererConstants.accessTokenMigrationDoNotShowLastShown
250-
) || 1
251-
252-
//Add 7 days to notificationLastShown to determine whether warn message should show
253-
if (doNotShowAgain || notificationLastShown + 1000 * 60 * 60 * 24 * 7 >= Date.now()) {
254-
return
255-
} else if (t <= CodeWhispererConstants.accessTokenCutOffDate) {
256-
vscode.window
257-
.showWarningMessage(
258-
CodeWhispererConstants.accessTokenMigrationWarningMessage,
259-
CodeWhispererConstants.accessTokenMigrationWarningButtonMessage,
260-
CodeWhispererConstants.accessTokenMigrationDoNotShowAgain
261-
)
262-
.then(async resp => {
263-
if (resp === CodeWhispererConstants.accessTokenMigrationWarningButtonMessage) {
264-
await vscode.commands.executeCommand('aws.codeWhisperer.refresh')
265-
await showSsoSignIn.execute()
266-
} else if (resp === CodeWhispererConstants.accessTokenMigrationDoNotShowAgain) {
267-
await vscode.window.showInformationMessage(
268-
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainInfo,
269-
'OK'
270-
)
271-
await context.extensionContext.globalState.update(
272-
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainKey,
273-
true
274-
)
275-
}
276-
})
277-
context.extensionContext.globalState.update(
278-
CodeWhispererConstants.accessTokenMigrationDoNotShowLastShown,
279-
Date.now()
280-
)
250+
251+
if (t <= CodeWhispererConstants.accessTokenCutOffDate) {
252+
maybeShowTokenMigrationWarning()
281253
} else {
282254
await globals.context.globalState.update(CodeWhispererConstants.accessToken, undefined)
255+
await globals.context.globalState.update(CodeWhispererConstants.accessTokenExpriedKey, true)
283256
await vscode.commands.executeCommand('aws.codeWhisperer.refreshRootNode')
284-
vscode.window
285-
.showErrorMessage(
286-
CodeWhispererConstants.accessTokenMigrationErrorMessage,
287-
CodeWhispererConstants.accessTokenMigrationErrorButtonMessage
288-
)
289-
.then(async resp => {
290-
if (resp === CodeWhispererConstants.accessTokenMigrationErrorButtonMessage) {
291-
await vscode.commands.executeCommand('aws.codeWhisperer.refresh')
292-
await showSsoSignIn.execute()
293-
} else if (resp === CodeWhispererConstants.accessTokenMigrationDoNotShowAgain) {
294-
await context.extensionContext.globalState.update(
295-
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainKey,
296-
true
297-
)
298-
}
299-
})
257+
maybeShowTokenMigrationError()
300258
}
259+
} else if (accessTokenExpired) {
260+
maybeShowTokenMigrationError()
261+
}
262+
}
263+
264+
function maybeShowTokenMigrationWarning() {
265+
const doNotShowAgain =
266+
context.extensionContext.globalState.get<boolean>(
267+
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainKey
268+
) || false
269+
const notificationLastShown: number =
270+
context.extensionContext.globalState.get<number | undefined>(
271+
CodeWhispererConstants.accessTokenMigrationDoNotShowLastShown
272+
) || 1
273+
274+
//Add 7 days to notificationLastShown to determine whether warn message should show
275+
if (doNotShowAgain || notificationLastShown + 1000 * 60 * 60 * 24 * 7 >= Date.now()) {
276+
return
277+
}
278+
279+
vscode.window
280+
.showWarningMessage(
281+
CodeWhispererConstants.accessTokenMigrationWarningMessage,
282+
CodeWhispererConstants.accessTokenMigrationWarningButtonMessage,
283+
CodeWhispererConstants.accessTokenMigrationDoNotShowAgain
284+
)
285+
.then(async resp => {
286+
if (resp === CodeWhispererConstants.accessTokenMigrationWarningButtonMessage) {
287+
await vscode.commands.executeCommand('aws.codeWhisperer.refresh')
288+
await showSsoSignIn.execute()
289+
} else if (resp === CodeWhispererConstants.accessTokenMigrationDoNotShowAgain) {
290+
await vscode.window.showInformationMessage(
291+
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainInfo,
292+
'OK'
293+
)
294+
await context.extensionContext.globalState.update(
295+
CodeWhispererConstants.accessTokenMigrationDoNotShowAgainKey,
296+
true
297+
)
298+
}
299+
})
300+
context.extensionContext.globalState.update(
301+
CodeWhispererConstants.accessTokenMigrationDoNotShowLastShown,
302+
Date.now()
303+
)
304+
}
305+
306+
function maybeShowTokenMigrationError() {
307+
const migrationErrordoNotShowAgain =
308+
context.extensionContext.globalState.get<boolean>(
309+
CodeWhispererConstants.accessTokenExpiredDoNotShowAgainKey
310+
) || false
311+
const migrationErrorLastShown: number =
312+
context.extensionContext.globalState.get<number | undefined>(
313+
CodeWhispererConstants.accessTokenExpiredDoNotShowLastShown
314+
) || 1
315+
316+
//Add 7 days to notificationLastShown to determine whether warn message should show
317+
if (migrationErrordoNotShowAgain || migrationErrorLastShown + 1000 * 60 * 60 * 24 * 7 >= Date.now()) {
318+
return
301319
}
320+
321+
vscode.window
322+
.showErrorMessage(
323+
CodeWhispererConstants.accessTokenMigrationErrorMessage,
324+
CodeWhispererConstants.accessTokenMigrationErrorButtonMessage,
325+
CodeWhispererConstants.accessTokenMigrationLearnMore,
326+
CodeWhispererConstants.accessTokenMigrationDoNotShowAgain
327+
)
328+
.then(async resp => {
329+
if (resp === CodeWhispererConstants.accessTokenMigrationErrorButtonMessage) {
330+
await vscode.commands.executeCommand('aws.codeWhisperer.refresh')
331+
await showSsoSignIn.execute()
332+
} else if (resp === CodeWhispererConstants.accessTokenMigrationDoNotShowAgain) {
333+
await context.extensionContext.globalState.update(
334+
CodeWhispererConstants.accessTokenExpiredDoNotShowAgainKey,
335+
true
336+
)
337+
} else if (resp === CodeWhispererConstants.accessTokenMigrationLearnMore) {
338+
await vscode.commands.executeCommand('aws.codeWhisperer.accessTokenErrorLearnMore')
339+
}
340+
})
341+
context.extensionContext.globalState.update(
342+
CodeWhispererConstants.accessTokenExpiredDoNotShowLastShown,
343+
Date.now()
344+
)
302345
}
303346

304347
function setStatusBarOK() {

src/codewhisperer/commands/basicCommands.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ export const showLearnMore = Commands.declare('aws.codeWhisperer.learnMore', ()
9797
vscode.env.openExternal(vscode.Uri.parse(CodeWhispererConstants.learnMoreUriGeneral))
9898
})
9999

100+
export const showAccessTokenErrorLearnMore = Commands.declare(
101+
'aws.codeWhisperer.accessTokenErrorLearnMore',
102+
() => async () => {
103+
vscode.env.openExternal(vscode.Uri.parse(CodeWhispererConstants.accessTokenMigrationLearnMoreUri))
104+
}
105+
)
106+
100107
// TODO: Use a different URI
101108
export const showFreeTierLimit = Commands.declare('aws.codeWhisperer.freeTierLimit', () => async () => {
102109
vscode.env.openExternal(vscode.Uri.parse(CodeWhispererConstants.learnMoreUri))

src/codewhisperer/models/constants.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ export const learnMoreUriGeneral = 'https://aws.amazon.com/codewhisperer/'
140140

141141
export const learnMoreUri = 'https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/codewhisperer.html'
142142

143+
export const accessTokenMigrationLearnMoreUri =
144+
'https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/codewhisperer-auth.html'
145+
143146
export const identityPoolID = 'us-east-1:70717e99-906f-4add-908c-bd9074a2f5b9'
144147

145148
/**
@@ -215,7 +218,7 @@ export const accessTokenCutOffDate = new Date(2023, 0, 31)
215218

216219
export const accessTokenMigrationWarningMessage = `To continue using CodeWhisperer, you must add an AWS Builder ID or AWS IAM Identity Center connection by January 31, 2023.`
217220

218-
export const accessTokenMigrationErrorMessage = `To continue using CodeWhisperer, you must add an AWS Builder ID or AWS IAM Identity Center connection.`
221+
export const accessTokenMigrationErrorMessage = `Your Preview Access Code has expired. To continue using CodeWhisperer, connect with AWS Builder ID or AWS IAM Identity center.`
219222

220223
export const accessTokenMigrationWarningButtonMessage = `Connect with AWS to Continue`
221224

@@ -238,11 +241,20 @@ export const failedToConnectIamIdentityCenter = `Failed to connect to IAM Identi
238241

239242
export const connectionExpired = `AWS Toolkit: Connection expired. Reauthenticate to continue.`
240243

244+
export const accessTokenMigrationLearnMore = `Learn More`
245+
241246
export const accessTokenMigrationDoNotShowAgain = `Don\'t Show Again`
242247

243248
export const accessTokenMigrationDoNotShowAgainKey = 'CODEWHISPERER_ACCESS_TOKEN_MIGRATION_DO_NOT_SHOW_AGAIN'
244249

250+
export const accessTokenExpiredDoNotShowAgainKey = 'CODEWHISPERER_ACCESS_TOKEN_EXPIRED_DO_NOT_SHOW_AGAIN'
251+
252+
export const accessTokenExpriedKey = 'CODEWHISPERER_ACCESS_TOKEN_EXPIRED'
253+
245254
export const accessTokenMigrationDoNotShowLastShown =
246255
'CODEWHISPERER_ACCESS_TOKEN_MIGRATION_DO_NOT_SHOW_AGAIN_LAST_SHOWN_TIME'
247256

257+
export const accessTokenExpiredDoNotShowLastShown =
258+
'CODEWHISPERER_ACCESS_TOKEN_EXPIRED_DO_NOT_SHOW_AGAIN_LAST_SHOWN_TIME'
259+
248260
export const accessTokenMigrationDoNotShowAgainInfo = `You will not receive this notification again. If you would like to continue using CodeWhisperer after January 31, 2023, you can still connect with AWS. [Learn More](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/codewhisper-setup-general.html).`

0 commit comments

Comments
 (0)