@@ -33,80 +33,20 @@ use tokio::sync::oneshot;
3333/// HTML response sent to the browser after successful callback.
3434const SUCCESS_HTML : & str = r#"<!DOCTYPE html>
3535<html>
36- <head>
37- <title>Authentication Successful</title>
38- <style>
39- body {
40- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
41- display: flex;
42- justify-content: center;
43- align-items: center;
44- height: 100vh;
45- margin: 0;
46- background-color: #f5f5f5;
47- }
48- .message {
49- text-align: center;
50- padding: 2rem;
51- background: white;
52- border-radius: 8px;
53- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
54- }
55- h1 {
56- color: #2e7d32;
57- margin: 0 0 1rem 0;
58- }
59- p {
60- color: #666;
61- margin: 0;
62- }
63- </style>
64- </head>
36+ <head><title>Authentication Successful</title></head>
6537<body>
66- <div class="message">
67- <h1>✓ Authentication Successful</h1>
68- <p>You can close this tab and return to your application.</p>
69- </div>
38+ <h1>Authentication Successful</h1>
39+ <p>You can close this tab and return to your application.</p>
7040</body>
7141</html>"# ;
7242
7343/// HTML response sent to the browser when an error occurs.
7444const ERROR_HTML : & str = r#"<!DOCTYPE html>
7545<html>
76- <head>
77- <title>Authentication Error</title>
78- <style>
79- body {
80- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
81- display: flex;
82- justify-content: center;
83- align-items: center;
84- height: 100vh;
85- margin: 0;
86- background-color: #f5f5f5;
87- }
88- .message {
89- text-align: center;
90- padding: 2rem;
91- background: white;
92- border-radius: 8px;
93- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
94- }
95- h1 {
96- color: #c62828;
97- margin: 0 0 1rem 0;
98- }
99- p {
100- color: #666;
101- margin: 0;
102- }
103- </style>
104- </head>
46+ <head><title>Authentication Error</title></head>
10547<body>
106- <div class="message">
107- <h1>✗ Authentication Error</h1>
108- <p>An error occurred during authentication. You can close this tab and try again.</p>
109- </div>
48+ <h1>Authentication Error</h1>
49+ <p>An error occurred during authentication. You can close this tab and try again.</p>
11050</body>
11151</html>"# ;
11252
@@ -157,6 +97,15 @@ pub struct CallbackServer {
15797 server_handle : Option < tokio:: task:: JoinHandle < ( ) > > ,
15898}
15999
100+ impl Drop for CallbackServer {
101+ fn drop ( & mut self ) {
102+ // Abort the server task if it's still running (e.g., wait_for_code was never called)
103+ if let Some ( handle) = self . server_handle . take ( ) {
104+ handle. abort ( ) ;
105+ }
106+ }
107+ }
108+
160109impl CallbackServer {
161110 /// Creates a new callback server listening on the specified port.
162111 ///
@@ -496,7 +445,7 @@ mod tests {
496445
497446 // Read the response
498447 let mut response = vec ! [ 0u8 ; 4096 ] ;
499- stream. read ( & mut response) . await . ok ( ) ;
448+ let _ = stream. read ( & mut response) . await ;
500449 } ) ;
501450
502451 // Wait for callback
@@ -533,7 +482,7 @@ mod tests {
533482 stream. flush ( ) . await . ok ( ) ;
534483
535484 let mut response = vec ! [ 0u8 ; 4096 ] ;
536- stream. read ( & mut response) . await . ok ( ) ;
485+ let _ = stream. read ( & mut response) . await ;
537486 } ) ;
538487
539488 // Wait for callback - should fail due to state mismatch
@@ -668,9 +617,24 @@ mod tests {
668617
669618 #[ tokio:: test]
670619 async fn test_redirect_uri_format ( ) {
671- let server = CallbackServer :: new ( 8020 )
620+ // Use port 0 to let the OS assign an available port, avoiding conflicts
621+ let server = CallbackServer :: new ( 0 )
672622 . await
673623 . expect ( "Failed to create server" ) ;
674- assert_eq ! ( server. redirect_uri( ) , "http://localhost:8020/callback" ) ;
624+ let uri = server. redirect_uri ( ) ;
625+ assert ! (
626+ uri. starts_with( "http://localhost:" ) ,
627+ "Expected URI starting with http://localhost:, got: {}" ,
628+ uri
629+ ) ;
630+ // Verify the port is a valid non-zero number
631+ let port: u16 = uri
632+ . strip_prefix ( "http://localhost:" )
633+ . unwrap ( )
634+ . strip_suffix ( "/callback" )
635+ . unwrap_or_else ( || uri. strip_prefix ( "http://localhost:" ) . unwrap ( ) )
636+ . parse ( )
637+ . unwrap ( ) ;
638+ assert ! ( port > 0 , "Expected a non-zero port, got: {}" , port) ;
675639 }
676640}
0 commit comments