Skip to content

Commit b7572db

Browse files
bug: Amazon Q sign in blocked by stale connection (#5379)
Problem: Previously the AWS Toolkit and Amazon Q extensions shared Auth connections. To do this they communicated their Auth connections to each other, with each extension storing this in their auth connection cache. Later we decided to stop sharing the Auth connections between the extensions, instead having each extension create its own connection. The problem is that when we created this separate auth connection change, we had stale connections remaining in Amazon Q. This caused issues like users being unable to sign in to a new connection since the cached connections showed it already existed. Solution: On every startup clear the stale connections. We have existing code that does this, but it only ran in a CodeCatalyst dev environment. But it looks like we always want to run this check as it seems there are other cases where this happens. Signed-off-by: Nikolas Komonen <[email protected]>
1 parent 4294f8d commit b7572db

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,26 @@ describe('AuthUtil', async function () {
278278
assert.strictEqual(authUtil.reformatStartUrl(expected + '/#/'), expected)
279279
assert.strictEqual(authUtil.reformatStartUrl(expected + '####'), expected)
280280
})
281+
282+
it(`clearExtraConnections()`, async function () {
283+
const conn1 = await auth.createConnection(createBuilderIdProfile())
284+
const conn2 = await auth.createConnection(createSsoProfile({ startUrl: enterpriseSsoStartUrl }))
285+
const conn3 = await auth.createConnection(createSsoProfile({ startUrl: enterpriseSsoStartUrl + 1 }))
286+
// validate listConnections shows all connections
287+
assert.deepStrictEqual(
288+
(await authUtil.auth.listConnections()).map((conn) => conn.id).sort((a, b) => a.localeCompare(b)),
289+
[conn1, conn2, conn3].map((conn) => conn.id).sort((a, b) => a.localeCompare(b))
290+
)
291+
await authUtil.secondaryAuth.useNewConnection(conn3)
292+
293+
await authUtil.clearExtraConnections() // method under test
294+
295+
// Only the conn that AuthUtil is using is remaining
296+
assert.deepStrictEqual(
297+
(await authUtil.auth.listConnections()).map((conn) => conn.id),
298+
[conn3.id]
299+
)
300+
})
281301
})
282302

283303
describe('getChatAuthState()', function () {

packages/core/src/codewhisperer/activation.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ import { securityScanLanguageContext } from './util/securityScanLanguageContext'
7070
import { registerWebviewErrorHandler } from '../webviews/server'
7171
import { logAndShowError, logAndShowWebviewError } from '../shared/utilities/logAndShowUtils'
7272
import { openSettings } from '../shared/settings'
73-
import { getCodeCatalystDevEnvId } from '../shared/vscode/env'
7473

7574
let localize: nls.LocalizeFunc
7675

@@ -296,16 +295,7 @@ export async function activate(context: ExtContext): Promise<void> {
296295
)
297296

298297
await auth.restore()
299-
300-
// Amazon Q may have code catalyst only credentials stored because it used to import the credentials stored on disk in the environment.
301-
if (getCodeCatalystDevEnvId() !== undefined) {
302-
for (const conn of await auth.auth.listConnections()) {
303-
if (conn.id !== auth.conn?.id) {
304-
getLogger().debug('forgetting extra amazon q connection in CoCa dev env: %O', conn)
305-
await auth.auth.forgetConnection(conn)
306-
}
307-
}
308-
}
298+
await auth.clearExtraConnections()
309299

310300
if (auth.isConnectionExpired()) {
311301
auth.showReauthenticatePrompt().catch((e) => {

packages/core/src/codewhisperer/util/authUtil.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { indent } from '../../shared/utilities/textUtilities'
3434
import { showReauthenticateMessage } from '../../shared/utilities/messages'
3535
import { showAmazonQWalkthroughOnce } from '../../amazonq/onboardingPage/walkthrough'
3636
import { setContext } from '../../shared/vscode/setContext'
37+
import { isInDevEnv } from '../../shared/vscode/env'
3738

3839
/** Backwards compatibility for connections w pre-chat scopes */
3940
export const codeWhispererCoreScopes = [...scopesCodeWhispererCore]
@@ -409,6 +410,23 @@ export class AuthUtil {
409410

410411
return state
411412
}
413+
414+
/**
415+
* Edge Case: Due to a change in behaviour/functionality, there are potential extra
416+
* auth connections that the Amazon Q extension has cached. We need to remove these
417+
* as they are irrelevant to the Q extension and can cause issues.
418+
*/
419+
public async clearExtraConnections(): Promise<void> {
420+
const currentQConn = this.conn
421+
// Q currently only maintains 1 connection at a time, so we assume everything else is extra.
422+
// IMPORTANT: In the case Q starts to manage multiple connections, this implementation will need to be updated.
423+
const allOtherConnections = (await this.auth.listConnections()).filter((c) => c.id !== currentQConn?.id)
424+
for (const conn of allOtherConnections) {
425+
getLogger().warn(`forgetting extra amazon q connection: %O`, conn)
426+
// in a Dev Env the connection may be used by code catalyst, so we forget instead of fully deleting
427+
isInDevEnv() ? await this.auth.forgetConnection(conn) : await this.auth.deleteConnection(conn)
428+
}
429+
}
412430
}
413431

414432
/**

0 commit comments

Comments
 (0)