@@ -120,21 +120,25 @@ export async function performLogin(deviceInfo: DeviceInfo): Promise<StoredAuth |
120120 authWindow . hide ( ) ;
121121 }
122122
123- // Wait for cookies to settle
124- await new Promise ( ( r ) => setTimeout ( r , 500 ) ) ;
125-
126123 try {
127- const authData = await extractAuthAndRegisterAll ( deviceInfo ) ;
124+ const authData = await extractAuthAndRegisterAll ( portalUrl , deviceInfo ) ;
128125 if ( authData ) {
129126 setAuth ( authData ) ;
130127 log ( `Auth complete: ${ authData . organizations . length } org(s) registered` ) ;
131128 finish ( authData ) ;
132129 } else {
133- log ( 'Auth extraction returned null, closing window' ) ;
130+ // extractAuthAndRegisterAll already showed an error dialog
134131 finish ( null ) ;
135132 }
136133 } catch ( error ) {
137134 log ( `Auth extraction failed: ${ error } ` , 'ERROR' ) ;
135+ dialog . showMessageBoxSync ( {
136+ type : 'error' ,
137+ title : 'Sign-In Failed' ,
138+ message : 'An unexpected error occurred during sign-in.' ,
139+ detail : `${ error } ` ,
140+ buttons : [ 'OK' ] ,
141+ } ) ;
138142 finish ( null ) ;
139143 }
140144 } ;
@@ -157,24 +161,56 @@ export async function performLogin(deviceInfo: DeviceInfo): Promise<StoredAuth |
157161 } ) ;
158162}
159163
164+ /**
165+ * Waits for the session cookie to appear in the Electron session.
166+ * Retries up to maxAttempts times with a delay between attempts.
167+ */
168+ async function waitForSessionCookie (
169+ portalUrl : string ,
170+ maxAttempts = 10 ,
171+ delayMs = 500 ,
172+ ) : Promise < Electron . Cookie | null > {
173+ for ( let attempt = 1 ; attempt <= maxAttempts ; attempt ++ ) {
174+ await new Promise ( ( r ) => setTimeout ( r , delayMs ) ) ;
175+
176+ const cookies = await session . defaultSession . cookies . get ( { url : portalUrl } ) ;
177+ const sessionCookie = cookies . find (
178+ ( c ) =>
179+ c . name === 'better-auth.session_token' || c . name === '__Secure-better-auth.session_token' ,
180+ ) ;
181+
182+ if ( sessionCookie ) {
183+ log ( `Session cookie found on attempt ${ attempt } /${ maxAttempts } ` ) ;
184+ return sessionCookie ;
185+ }
186+
187+ log ( `Session cookie not found yet (attempt ${ attempt } /${ maxAttempts } )` , 'WARN' ) ;
188+ }
189+
190+ return null ;
191+ }
192+
160193/**
161194 * After login, fetches the user's orgs and registers the device for all of them.
162- * Shows an error dialog if the user has no organizations .
195+ * Shows error dialogs on failure so the user knows what went wrong .
163196 */
164197async function extractAuthAndRegisterAll (
198+ portalUrl : string ,
165199 deviceInfo : DeviceInfo ,
166200) : Promise < StoredAuth | null > {
167- const portalUrl = getPortalUrl ( ) ;
168-
169- // 1. Get session cookie
170- const cookies = await session . defaultSession . cookies . get ( { url : portalUrl } ) ;
171- const sessionCookie = cookies . find (
172- ( c ) =>
173- c . name === 'better-auth.session_token' || c . name === '__Secure-better-auth.session_token' ,
174- ) ;
201+ // 1. Wait for session cookie with retries
202+ const sessionCookie = await waitForSessionCookie ( portalUrl ) ;
175203
176204 if ( ! sessionCookie ) {
177- log ( 'No session cookie found after login' , 'WARN' ) ;
205+ log ( 'No session cookie found after login (exhausted retries)' , 'ERROR' ) ;
206+ dialog . showMessageBoxSync ( {
207+ type : 'error' ,
208+ title : 'Sign-In Failed' ,
209+ message : 'Could not complete sign-in.' ,
210+ detail :
211+ 'The session cookie was not set after authentication. Please try again. If the problem persists, restart the app.' ,
212+ buttons : [ 'OK' ] ,
213+ } ) ;
178214 return null ;
179215 }
180216
@@ -188,14 +224,28 @@ async function extractAuthAndRegisterAll(
188224
189225 if ( ! sessionResponse . ok ) {
190226 log ( `Session fetch failed: ${ sessionResponse . status } ` , 'ERROR' ) ;
227+ dialog . showMessageBoxSync ( {
228+ type : 'error' ,
229+ title : 'Sign-In Failed' ,
230+ message : 'Could not verify your session.' ,
231+ detail : `The server returned status ${ sessionResponse . status } . Please try signing in again.` ,
232+ buttons : [ 'OK' ] ,
233+ } ) ;
191234 return null ;
192235 }
193236
194237 const sessionData = await sessionResponse . json ( ) ;
195238 const userId = sessionData ?. user ?. id ;
196239
197240 if ( ! userId ) {
198- log ( 'No userId in session' , 'ERROR' ) ;
241+ log ( 'No userId in session response' , 'ERROR' ) ;
242+ dialog . showMessageBoxSync ( {
243+ type : 'error' ,
244+ title : 'Sign-In Failed' ,
245+ message : 'Could not retrieve your user information.' ,
246+ detail : 'The session is missing user data. Please try signing in again.' ,
247+ buttons : [ 'OK' ] ,
248+ } ) ;
199249 return null ;
200250 }
201251
@@ -208,6 +258,13 @@ async function extractAuthAndRegisterAll(
208258
209259 if ( ! orgsResponse . ok ) {
210260 log ( `Failed to fetch organizations: ${ orgsResponse . status } ` , 'ERROR' ) ;
261+ dialog . showMessageBoxSync ( {
262+ type : 'error' ,
263+ title : 'Sign-In Failed' ,
264+ message : 'Could not fetch your organizations.' ,
265+ detail : `The server returned status ${ orgsResponse . status } . Please try signing in again.` ,
266+ buttons : [ 'OK' ] ,
267+ } ) ;
211268 return null ;
212269 }
213270
0 commit comments