Skip to content

Commit d233b70

Browse files
authored
fix(auth): enforce 5 scopes when reauthing amazon q (#5015)
* fix(auth): enforce 5 scopes when reauthing amazon q Problem: Users can keep an old 3 scope connection if they continue to reauth with the notification once auth expires. Solution: Any call to the amazon q's reauth function enforces 5 scopes, which will fix the reauth notification. - Does NOT update the case where user reauths an amazon q connection via toolkit quickpick. That is more difficult. * update tests
1 parent df73086 commit d233b70

File tree

5 files changed

+35
-30
lines changed

5 files changed

+35
-30
lines changed

packages/core/src/amazonq/auth/controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ export class AuthController {
3131
}
3232

3333
private handleReAuth() {
34-
void reconnect.execute(placeholder, amazonQChatSource, true)
34+
void reconnect.execute(placeholder, amazonQChatSource)
3535
}
3636
}

packages/core/src/codewhisperer/commands/basicCommands.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,7 @@ export const selectCustomizationPrompt = Commands.declare(
139139

140140
export const reconnect = Commands.declare(
141141
{ id: 'aws.amazonq.reconnect', compositeKey: { 1: 'source' } },
142-
() =>
143-
async (_: VsCodeCommandArg, source: CodeWhispererSource, addMissingScopes: boolean = false) => {
144-
if (typeof addMissingScopes !== 'boolean') {
145-
addMissingScopes = false
146-
}
147-
await AuthUtil.instance.reauthenticate(addMissingScopes)
148-
}
142+
() => async (_: VsCodeCommandArg, source: CodeWhispererSource) => await AuthUtil.instance.reauthenticate()
149143
)
150144

151145
/** @deprecated in favor of the `Add Connection` page */

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

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,23 +324,16 @@ export class AuthUtil {
324324
AuthUtil.logIfChanged(logStr)
325325
}
326326

327-
public async reauthenticate(addMissingScopes: boolean = false) {
327+
public async reauthenticate() {
328328
try {
329329
if (this.conn?.type !== 'sso') {
330330
return
331331
}
332332

333-
// Edge Case: With the addition of Amazon Q/Chat scopes we may need to add
334-
// the new scopes to existing pre-chat connections.
335-
if (addMissingScopes) {
336-
if (
337-
(isBuilderIdConnection(this.conn) || isIdcSsoConnection(this.conn)) &&
338-
!isValidAmazonQConnection(this.conn)
339-
) {
340-
const conn = await this.secondaryAuth.addScopes(this.conn, amazonQScopes)
341-
await this.secondaryAuth.useNewConnection(conn)
342-
return
343-
}
333+
if (!isValidAmazonQConnection(this.conn)) {
334+
const conn = await this.secondaryAuth.addScopes(this.conn, amazonQScopes)
335+
await this.secondaryAuth.useNewConnection(conn)
336+
return
344337
}
345338

346339
await this.auth.reauthenticate(this.conn)

packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export class AmazonQLoginWebview extends CommonAuthWebview {
194194
isReAuth: true,
195195
...this.getMetadataForExistingConn(),
196196
})
197-
await AuthUtil.instance.reauthenticate(true)
197+
await AuthUtil.instance.reauthenticate()
198198
})
199199
} finally {
200200
this.isReauthenticating = false

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

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,38 +143,56 @@ describe('AuthUtil', async function () {
143143
assert.strictEqual(auth.getConnectionState(conn), 'valid')
144144
})
145145

146-
it('reauthenticate does NOT add missing CodeWhisperer scopes if not required to', async function () {
147-
const conn = await auth.createConnection(createBuilderIdProfile({ scopes: codeWhispererCoreScopes }))
146+
it('reauthenticates Builder ID connection that already has all scopes', async function () {
147+
const conn = await auth.createInvalidSsoConnection(createBuilderIdProfile({ scopes: amazonQScopes }))
148148
await auth.useConnection(conn)
149149

150+
// method under test
150151
await authUtil.reauthenticate()
151152

152153
assert.strictEqual(authUtil.conn?.type, 'sso')
153-
assert.deepStrictEqual(authUtil.conn?.scopes, codeWhispererCoreScopes)
154+
assert.deepStrictEqual(authUtil.conn?.scopes, amazonQScopes)
155+
assert.strictEqual(auth.getConnectionState(conn), 'valid')
154156
})
155157

156-
it('reauthenticate adds missing Builder ID scopes when explicitly required', async function () {
157-
const conn = await auth.createConnection(createBuilderIdProfile({ scopes: codeWhispererCoreScopes }))
158+
it('reauthenticates IdC connection that already has all scopes', async function () {
159+
const conn = await auth.createInvalidSsoConnection(
160+
createSsoProfile({ startUrl: enterpriseSsoStartUrl, scopes: codeWhispererCoreScopes })
161+
)
158162
await auth.useConnection(conn)
159163

160164
// method under test
161-
await authUtil.reauthenticate(true)
165+
await authUtil.reauthenticate()
162166

163167
assert.strictEqual(authUtil.conn?.type, 'sso')
164168
assert.deepStrictEqual(authUtil.conn?.scopes, amazonQScopes)
169+
assert.strictEqual(auth.getConnectionState(conn), 'valid')
165170
})
166171

167-
it('reauthenticate adds missing Amazon Q IdC scopes when explicitly required', async function () {
168-
const conn = await auth.createConnection(
172+
it('reauthenticate adds missing Builder ID scopes', async function () {
173+
const conn = await auth.createInvalidSsoConnection(createBuilderIdProfile({ scopes: codeWhispererCoreScopes }))
174+
await auth.useConnection(conn)
175+
176+
// method under test
177+
await authUtil.reauthenticate()
178+
179+
assert.strictEqual(authUtil.conn?.type, 'sso')
180+
assert.deepStrictEqual(authUtil.conn?.scopes, amazonQScopes)
181+
assert.strictEqual(auth.getConnectionState(conn), 'valid')
182+
})
183+
184+
it('reauthenticate adds missing Amazon Q IdC scopes', async function () {
185+
const conn = await auth.createInvalidSsoConnection(
169186
createSsoProfile({ startUrl: enterpriseSsoStartUrl, scopes: codeWhispererCoreScopes })
170187
)
171188
await auth.useConnection(conn)
172189

173190
// method under test
174-
await authUtil.reauthenticate(true)
191+
await authUtil.reauthenticate()
175192

176193
assert.strictEqual(authUtil.conn?.type, 'sso')
177194
assert.deepStrictEqual(authUtil.conn?.scopes, amazonQScopes)
195+
assert.strictEqual(auth.getConnectionState(conn), 'valid')
178196
})
179197

180198
it('CodeWhisperer uses fallback connection when switching to an unsupported connection', async function () {

0 commit comments

Comments
 (0)