akhaliq HF Staff commited on
Commit
a4a6500
·
1 Parent(s): 990c944
Files changed (2) hide show
  1. frontend/src/app/page.tsx +54 -11
  2. frontend/src/lib/api.ts +13 -1
frontend/src/app/page.tsx CHANGED
@@ -1,6 +1,6 @@
1
  'use client';
2
 
3
- import { useState, useEffect } from 'react';
4
  import { flushSync } from 'react-dom';
5
  import Header from '@/components/Header';
6
  import LandingPage from '@/components/LandingPage';
@@ -57,11 +57,39 @@ export default function Home() {
57
  }
58
  }, [messages]);
59
 
 
60
  useEffect(() => {
61
  checkAuth();
62
- // Check auth status every second to catch OAuth redirects
63
- const interval = setInterval(checkAuth, 1000);
64
- return () => clearInterval(interval);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }, []);
66
 
67
  const checkAuth = async () => {
@@ -74,16 +102,31 @@ export default function Home() {
74
  if (token) {
75
  apiClient.setToken(token);
76
 
77
- // Get username from auth status
78
- try {
79
- const authStatus = await apiClient.getAuthStatus();
80
- if (authStatus.username) {
81
- setUsername(authStatus.username);
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
- } catch (error) {
84
- console.error('Failed to get username:', error);
85
  }
86
  }
 
 
 
 
 
87
  }
88
  };
89
 
 
1
  'use client';
2
 
3
+ import { useState, useEffect, useRef } from 'react';
4
  import { flushSync } from 'react-dom';
5
  import Header from '@/components/Header';
6
  import LandingPage from '@/components/LandingPage';
 
57
  }
58
  }, [messages]);
59
 
60
+ // Check auth on mount and handle OAuth callback
61
  useEffect(() => {
62
  checkAuth();
63
+
64
+ // Check for OAuth callback in URL (handles ?session=token)
65
+ // initializeOAuth already handles this, but we call checkAuth to sync state
66
+ const urlParams = new URLSearchParams(window.location.search);
67
+ if (urlParams.get('session')) {
68
+ // OAuth callback - check auth after a brief delay to let initializeOAuth complete
69
+ setTimeout(() => checkAuth(), 100);
70
+ }
71
+ }, []); // Only run once on mount
72
+
73
+ // Listen for storage changes (e.g., logout from another tab)
74
+ useEffect(() => {
75
+ const handleStorageChange = (e: StorageEvent) => {
76
+ if (e.key === 'hf_oauth_token' || e.key === 'hf_user_info') {
77
+ checkAuth();
78
+ }
79
+ };
80
+
81
+ window.addEventListener('storage', handleStorageChange);
82
+ return () => window.removeEventListener('storage', handleStorageChange);
83
+ }, []);
84
+
85
+ // Listen for window focus (user returns to tab after OAuth redirect)
86
+ useEffect(() => {
87
+ const handleFocus = () => {
88
+ checkAuth();
89
+ };
90
+
91
+ window.addEventListener('focus', handleFocus);
92
+ return () => window.removeEventListener('focus', handleFocus);
93
  }, []);
94
 
95
  const checkAuth = async () => {
 
102
  if (token) {
103
  apiClient.setToken(token);
104
 
105
+ // Get username from auth status (only if we don't have it yet)
106
+ // This is a one-time fetch, not polling
107
+ if (!username) {
108
+ try {
109
+ const authStatus = await apiClient.getAuthStatus();
110
+ if (authStatus.username) {
111
+ setUsername(authStatus.username);
112
+ }
113
+ } catch (error: any) {
114
+ // Silently handle connection errors - don't spam console
115
+ // Only log non-connection errors
116
+ if (error.code !== 'ECONNABORTED' &&
117
+ error.code !== 'ECONNRESET' &&
118
+ !error.message?.includes('socket hang up') &&
119
+ !error.message?.includes('timeout')) {
120
+ console.error('Failed to get username:', error);
121
+ }
122
  }
 
 
123
  }
124
  }
125
+ } else {
126
+ // Not authenticated - clear username
127
+ if (username) {
128
+ setUsername(null);
129
+ }
130
  }
131
  };
132
 
frontend/src/lib/api.ts CHANGED
@@ -49,6 +49,7 @@ class ApiClient {
49
  headers: {
50
  'Content-Type': 'application/json',
51
  },
 
52
  });
53
 
54
  // Add auth token to requests if available
@@ -89,9 +90,20 @@ class ApiClient {
89
  try {
90
  const response = await this.client.get<AuthStatus>('/api/auth/status');
91
  return response.data;
92
- } catch (error) {
 
 
 
 
 
 
 
 
 
 
93
  return {
94
  authenticated: false,
 
95
  message: 'Not authenticated',
96
  };
97
  }
 
49
  headers: {
50
  'Content-Type': 'application/json',
51
  },
52
+ timeout: 10000, // 10 second timeout to prevent hanging connections
53
  });
54
 
55
  // Add auth token to requests if available
 
90
  try {
91
  const response = await this.client.get<AuthStatus>('/api/auth/status');
92
  return response.data;
93
+ } catch (error: any) {
94
+ // Silently handle connection errors - don't spam console
95
+ if (error.code === 'ECONNABORTED' || error.code === 'ECONNRESET' || error.message?.includes('socket hang up')) {
96
+ // Connection error - backend may not be ready
97
+ return {
98
+ authenticated: false,
99
+ username: null,
100
+ message: 'Connection error',
101
+ };
102
+ }
103
+ // For other errors, return not authenticated
104
  return {
105
  authenticated: false,
106
+ username: null,
107
  message: 'Not authenticated',
108
  };
109
  }