@@ -7,6 +7,8 @@ export class CallbackServer {
77 private server : ReturnType < typeof createServer > | null = null ;
88 private port = 8976 ;
99 private callbackPath = '/oauth/callback' ;
10+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11+ private connections = new Set < any > ( ) ;
1012
1113 /**
1214 * Start the callback server and return a promise that resolves with the OAuth callback result
@@ -36,6 +38,18 @@ export class CallbackServer {
3638 }
3739 } ) ;
3840
41+ // Track connections for proper cleanup
42+ this . server . on ( 'connection' , ( socket ) => {
43+ this . connections . add ( socket ) ;
44+ socket . on ( 'close' , ( ) => {
45+ this . connections . delete ( socket ) ;
46+ } ) ;
47+ } ) ;
48+
49+ // Configure server for quick shutdown
50+ this . server . keepAliveTimeout = 1000 ; // 1 second
51+ this . server . headersTimeout = 2000 ; // 2 seconds
52+
3953 this . server . on ( 'error' , ( error ) => {
4054 clearTimeout ( timeoutId ) ;
4155 reject ( new AuthenticationError (
@@ -57,10 +71,25 @@ export class CallbackServer {
5771 async stop ( ) : Promise < void > {
5872 if ( this . server ) {
5973 return new Promise ( ( resolve ) => {
74+ // First, destroy all active connections
75+ for ( const connection of this . connections ) {
76+ connection . destroy ( ) ;
77+ }
78+ this . connections . clear ( ) ;
79+
80+ // Then close the server
6081 this . server ! . close ( ( ) => {
6182 this . server = null ;
6283 resolve ( ) ;
6384 } ) ;
85+
86+ // Fallback timeout as a safety net
87+ setTimeout ( ( ) => {
88+ if ( this . server ) {
89+ this . server = null ;
90+ resolve ( ) ;
91+ }
92+ } , 2000 ) ; // Reduced to 2 seconds since we're properly managing connections
6493 } ) ;
6594 }
6695 }
0 commit comments