@@ -10,7 +10,7 @@ import { spawn } from 'child_process'
1010import { URL , URLSearchParams } from 'url'
1111import * as http from 'http'
1212import * as os from 'os'
13- import { Logger , Workspace } from '@aws/language-server-runtimes/server-interface'
13+ import { Logger , Workspace , Lsp } from '@aws/language-server-runtimes/server-interface'
1414
1515interface Token {
1616 access_token : string
@@ -35,10 +35,12 @@ interface Registration {
3535export class OAuthClient {
3636 private static logger : Logger
3737 private static workspace : Workspace
38+ private static lsp : Lsp
3839
39- public static initialize ( ws : Workspace , logger : Logger ) : void {
40+ public static initialize ( ws : Workspace , logger : Logger , lsp : Lsp ) : void {
4041 this . workspace = ws
4142 this . logger = logger
43+ this . lsp = lsp
4244 }
4345
4446 /**
@@ -95,10 +97,11 @@ export class OAuthClient {
9597 const savedReg = await this . read < Registration > ( regPath )
9698 if ( savedReg ) {
9799 const port = Number ( new URL ( savedReg . redirect_uri ) . port )
100+ const normalized = `http://127.0.0.1:${ port } `
98101 server = http . createServer ( )
99102 try {
100- await this . listen ( server , port )
101- redirectUri = savedReg . redirect_uri
103+ await this . listen ( server , port , '127.0.0.1' )
104+ redirectUri = normalized
102105 this . logger . info ( `OAuth: reusing redirect URI ${ redirectUri } ` )
103106 } catch ( e : any ) {
104107 if ( e . code === 'EADDRINUSE' ) {
@@ -182,9 +185,9 @@ export class OAuthClient {
182185 /** Spin up a one‑time HTTP listener on localhost:randomPort */
183186 private static async buildCallbackServer ( ) : Promise < { server : http . Server ; redirectUri : string } > {
184187 const server = http . createServer ( )
185- await this . listen ( server , 0 )
188+ await this . listen ( server , 0 , '127.0.0.1' )
186189 const port = ( server . address ( ) as any ) . port as number
187- return { server, redirectUri : `http://localhost :${ port } ` }
190+ return { server, redirectUri : `http://127.0.0.1 :${ port } ` }
188191 }
189192
190193 /** Discover OAuth endpoints by HEAD/WWW‑Authenticate, well‑known, or fallback */
@@ -334,7 +337,7 @@ export class OAuthClient {
334337 redirectUri : string ,
335338 server : http . Server
336339 ) : Promise < Token > {
337- const DEFAULT_PKCE_TIMEOUT_MS = 20_000
340+ const DEFAULT_PKCE_TIMEOUT_MS = 90_000
338341 // a) generate PKCE params
339342 const verifier = this . b64url ( crypto . randomBytes ( 32 ) )
340343 const challenge = this . b64url ( crypto . createHash ( 'sha256' ) . update ( verifier ) . digest ( ) )
@@ -353,17 +356,7 @@ export class OAuthClient {
353356 state : state ,
354357 } ) . toString ( )
355358
356- const opener =
357- process . platform === 'win32'
358- ? {
359- cmd : 'cmd' ,
360- args : [ '/c' , 'start' , '' , `"${ authz . toString ( ) . replace ( / " / g, '""' ) } "` ] ,
361- }
362- : process . platform === 'darwin'
363- ? { cmd : 'open' , args : [ authz . toString ( ) ] }
364- : { cmd : 'xdg-open' , args : [ authz . toString ( ) ] }
365-
366- void spawn ( opener . cmd , opener . args , { detached : true , stdio : 'ignore' } ) . unref ( )
359+ await this . lsp . window . showDocument ( { uri : authz . toString ( ) , external : true } )
367360
368361 // c) wait for code on our loopback
369362 const waitForFlow = new Promise < { code : string ; rxState : string ; err ?: string ; errDesc ?: string } > ( resolve => {
0 commit comments