akhaliq HF Staff commited on
Commit
5db8e53
·
1 Parent(s): 6840c58
Files changed (2) hide show
  1. backend_api.py +21 -1
  2. frontend/src/lib/api.ts +19 -11
backend_api.py CHANGED
@@ -294,7 +294,27 @@ def get_auth_from_header(authorization: Optional[str] = None):
294
  username = parts[2] if len(parts) > 2 else "user"
295
  return MockAuth(token, username)
296
 
297
- # Regular token (OAuth access token passed directly)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  return MockAuth(token, None)
299
 
300
 
 
294
  username = parts[2] if len(parts) > 2 else "user"
295
  return MockAuth(token, username)
296
 
297
+ # Regular OAuth access token passed directly - try to fetch username from HF
298
+ # This happens when frontend sends OAuth token after OAuth callback
299
+ if token and len(token) > 20:
300
+ try:
301
+ from huggingface_hub import HfApi
302
+ hf_api = HfApi(token=token)
303
+ user_info = hf_api.whoami()
304
+ username = (
305
+ user_info.get("preferred_username") or
306
+ user_info.get("name") or
307
+ user_info.get("sub") or
308
+ "user"
309
+ )
310
+ print(f"[Auth] Fetched username from OAuth token: {username}")
311
+ return MockAuth(token, username)
312
+ except Exception as e:
313
+ print(f"[Auth] Could not fetch username from OAuth token: {e}")
314
+ # Return with token but no username - deployment will try to fetch it
315
+ return MockAuth(token, None)
316
+
317
+ # Fallback: token with no username
318
  return MockAuth(token, None)
319
 
320
 
frontend/src/lib/api.ts CHANGED
@@ -1,7 +1,6 @@
1
  // API client for AnyCoder backend
2
 
3
  import axios, { AxiosInstance } from 'axios';
4
- import { getStoredSessionToken } from './auth'; // NEW: Import session token
5
  import type {
6
  Model,
7
  AuthStatus,
@@ -55,12 +54,8 @@ class ApiClient {
55
 
56
  // Add auth token to requests if available
57
  this.client.interceptors.request.use((config) => {
58
- // Use session token instead of OAuth token for session tracking
59
- const sessionToken = getStoredSessionToken();
60
- if (sessionToken) {
61
- config.headers.Authorization = `Bearer ${sessionToken}`;
62
- } else if (this.token) {
63
- // Fallback to OAuth token if no session token
64
  config.headers.Authorization = `Bearer ${this.token}`;
65
  }
66
  return config;
@@ -71,10 +66,24 @@ class ApiClient {
71
  (response) => response,
72
  (error) => {
73
  // Handle 401 errors (expired/invalid authentication)
 
74
  if (error.response && error.response.status === 401) {
75
- // Clear authentication data
76
- if (typeof window !== 'undefined') {
 
 
 
 
 
 
 
 
 
 
 
 
77
  localStorage.removeItem('hf_oauth_token');
 
78
  localStorage.removeItem('hf_user_info');
79
  this.token = null;
80
 
@@ -280,8 +289,7 @@ class ApiClient {
280
  method: 'POST',
281
  headers: {
282
  'Content-Type': 'application/json',
283
- ...(getStoredSessionToken() ? { 'Authorization': `Bearer ${getStoredSessionToken()}` } :
284
- this.token ? { 'Authorization': `Bearer ${this.token}` } : {}),
285
  },
286
  body: JSON.stringify(request),
287
  signal: abortController.signal,
 
1
  // API client for AnyCoder backend
2
 
3
  import axios, { AxiosInstance } from 'axios';
 
4
  import type {
5
  Model,
6
  AuthStatus,
 
54
 
55
  // Add auth token to requests if available
56
  this.client.interceptors.request.use((config) => {
57
+ // ALWAYS use OAuth token primarily, session token is for backend tracking only
58
+ if (this.token) {
 
 
 
 
59
  config.headers.Authorization = `Bearer ${this.token}`;
60
  }
61
  return config;
 
66
  (response) => response,
67
  (error) => {
68
  // Handle 401 errors (expired/invalid authentication)
69
+ // ONLY log out on specific auth errors, not all 401s
70
  if (error.response && error.response.status === 401) {
71
+ const errorData = error.response.data;
72
+ const errorMessage = errorData?.detail || errorData?.message || '';
73
+
74
+ // Only log out if it's an authentication/session issue
75
+ // Don't log out for permission errors on specific resources
76
+ const shouldLogout =
77
+ errorMessage.includes('Authentication required') ||
78
+ errorMessage.includes('Invalid token') ||
79
+ errorMessage.includes('Token expired') ||
80
+ errorMessage.includes('Session expired') ||
81
+ error.config?.url?.includes('/auth/');
82
+
83
+ if (shouldLogout && typeof window !== 'undefined') {
84
+ // Clear ALL authentication data including session token
85
  localStorage.removeItem('hf_oauth_token');
86
+ localStorage.removeItem('hf_session_token');
87
  localStorage.removeItem('hf_user_info');
88
  this.token = null;
89
 
 
289
  method: 'POST',
290
  headers: {
291
  'Content-Type': 'application/json',
292
+ ...(this.token ? { 'Authorization': `Bearer ${this.token}` } : {}),
 
293
  },
294
  body: JSON.stringify(request),
295
  signal: abortController.signal,