Skip to content

Commit c674f9d

Browse files
authored
Improve Studio Token Authentication URI Handler (#5049)
1 parent 6f56425 commit c674f9d

File tree

4 files changed

+22
-8
lines changed

4 files changed

+22
-8
lines changed

extension/src/setup/studio.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Event, EventEmitter } from 'vscode'
1+
import { Event, EventEmitter, Disposable as VSCodeDisposable } from 'vscode'
22
import fetch from 'node-fetch'
33
import { STUDIO_URL } from './webview/contract'
44
import { AvailableCommands, InternalCommands } from '../commands/internal'
@@ -27,6 +27,7 @@ export class Studio extends Disposable {
2727
private studioAccessToken: string | undefined = undefined
2828
private studioIsConnected = false
2929
private shareLiveToStudio: boolean | undefined = undefined
30+
private studioAccessTokenUriHandler: VSCodeDisposable | undefined = undefined
3031

3132
constructor(
3233
internalCommands: InternalCommands,
@@ -108,6 +109,8 @@ export class Studio extends Disposable {
108109
}
109110

110111
public async requestStudioTokenAuthentication() {
112+
this.resetAccessTokenUriHandler()
113+
111114
const response = await this.fetchFromStudio(
112115
`${STUDIO_URL}/api/device-login`,
113116
{
@@ -134,9 +137,17 @@ export class Studio extends Disposable {
134137
verificationUrlWithParams.searchParams.append('code', userCode)
135138

136139
await openUrl(verificationUrlWithParams.toString())
137-
void waitForUriResponse('/studio-complete-auth', () => {
138-
void this.requestStudioToken(deviceCode, tokenUri)
139-
})
140+
this.studioAccessTokenUriHandler = waitForUriResponse(
141+
'/studio-complete-auth',
142+
() => {
143+
void this.requestStudioToken(deviceCode, tokenUri)
144+
}
145+
)
146+
}
147+
148+
private resetAccessTokenUriHandler() {
149+
this.studioAccessTokenUriHandler?.dispose()
150+
this.studioAccessTokenUriHandler = undefined
140151
}
141152

142153
private fetchFromStudio(reqUri: string, body: Record<string, unknown>) {
@@ -171,6 +182,7 @@ export class Studio extends Disposable {
171182
}
172183

173184
private requestStudioToken(deviceCode: string, tokenUri: string) {
185+
this.resetAccessTokenUriHandler()
174186
return Toast.showProgress('Connecting to Studio', async progress => {
175187
progress.report({ increment: 0 })
176188
progress.report({ increment: 25, message: 'Fetching token...' })

extension/src/test/suite/setup/index.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ suite('Setup Test Suite', () => {
873873
const mockGetCallbackUrl = stub(ExternalUtil, 'getCallBackUrl')
874874
const mockOpenUrl = stub(ExternalUtil, 'openUrl')
875875
const mockWaitForUriRes = stub(ExternalUtil, 'waitForUriResponse')
876+
const mockUriHandlerDispose = stub()
876877
const mockStudioRes = {
877878
device_code: 'Yi-NPd9ggvNUDBcam5bP8iivbtLhnqVgM_lSSbilqNw',
878879
token_uri: 'https://studio.iterative.ai/api/device-login/token',
@@ -890,6 +891,7 @@ suite('Setup Test Suite', () => {
890891
resolve =>
891892
mockWaitForUriRes.onFirstCall().callsFake((_, onResponse) => {
892893
resolve(onResponse)
894+
return { dispose: mockUriHandlerDispose }
893895
})
894896
)
895897

@@ -942,6 +944,7 @@ suite('Setup Test Suite', () => {
942944

943945
await failedTokenEvent
944946

947+
expect(mockUriHandlerDispose).to.be.calledOnce
945948
expect(mockFetch).to.be.calledTwice
946949
expect(mockFetch).to.be.calledWithExactly(mockStudioRes.token_uri, {
947950
body: JSON.stringify({

extension/src/vscode/external.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('waitForUriResponse', () => {
5656

5757
const uriWithoutPath = Uri.from({
5858
authority: 'iterative.dvc',
59-
path: '/not-correct-path',
59+
path: '/path-but-not-the-right-one',
6060
scheme: mockedUriScheme
6161
})
6262
mockHandleUriResponse(uriWithoutPath)

extension/src/vscode/external.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ export const getCallBackUrl = async (path: string) => {
1010
return uri.toString()
1111
}
1212

13-
export const waitForUriResponse = (path: string, onResponse: () => unknown) => {
13+
export const waitForUriResponse = (path: string, onResponse: () => unknown) =>
1414
window.registerUriHandler({
1515
handleUri(uri: Uri): ProviderResult<void> {
16-
if (uri.path.startsWith(path)) {
16+
if (uri.path === path) {
1717
onResponse()
1818
}
1919
}
2020
})
21-
}

0 commit comments

Comments
 (0)