Mark-Lasfar commited on
Commit
0effe0c
·
1 Parent(s): 448d967

Update backend and server frontend for OAuth JSON response, client-side navigation, and add .gitignore

Browse files
Files changed (3) hide show
  1. api/auth.py +29 -9
  2. requirements.txt +2 -1
  3. templates/login.html +49 -45
api/auth.py CHANGED
@@ -4,7 +4,7 @@ from httpx_oauth.clients.google import GoogleOAuth2
4
  from httpx_oauth.clients.github import GitHubOAuth2
5
  from fastapi_users.manager import BaseUserManager, IntegerIDMixin
6
  from fastapi import Depends, Request, FastAPI, Response
7
- from fastapi.responses import JSONResponse
8
  from sqlalchemy.ext.asyncio import AsyncSession
9
  from sqlalchemy import select
10
  from fastapi_users.models import UP
@@ -200,6 +200,7 @@ async def custom_oauth_callback(
200
  oauth_client=Depends(lambda: google_oauth_client),
201
  redirect_url: str = GOOGLE_REDIRECT_URL,
202
  response: Response = None,
 
203
  ):
204
  logger.debug(f"Processing Google callback with code: {code}, state: {state}")
205
  try:
@@ -246,10 +247,19 @@ async def custom_oauth_callback(
246
  secure=True,
247
  )
248
 
249
- return JSONResponse(content={
250
- "message": "Google login successful",
251
- "access_token": token
252
- }, status_code=200)
 
 
 
 
 
 
 
 
 
253
  except Exception as e:
254
  logger.error(f"Error in Google OAuth callback: {str(e)}")
255
  return JSONResponse(content={"detail": str(e)}, status_code=400)
@@ -261,6 +271,7 @@ async def custom_github_oauth_callback(
261
  oauth_client=Depends(lambda: github_oauth_client),
262
  redirect_url: str = GITHUB_REDIRECT_URL,
263
  response: Response = None,
 
264
  ):
265
  logger.debug(f"Processing GitHub callback with code: {code}, state: {state}")
266
  try:
@@ -325,10 +336,19 @@ async def custom_github_oauth_callback(
325
  secure=True,
326
  )
327
 
328
- return JSONResponse(content={
329
- "message": "GitHub login successful",
330
- "access_token": token
331
- }, status_code=200)
 
 
 
 
 
 
 
 
 
332
  except Exception as e:
333
  logger.error(f"Error in GitHub OAuth callback: {str(e)}")
334
  return JSONResponse(content={"detail": str(e)}, status_code=400)
 
4
  from httpx_oauth.clients.github import GitHubOAuth2
5
  from fastapi_users.manager import BaseUserManager, IntegerIDMixin
6
  from fastapi import Depends, Request, FastAPI, Response
7
+ from fastapi.responses import JSONResponse, RedirectResponse
8
  from sqlalchemy.ext.asyncio import AsyncSession
9
  from sqlalchemy import select
10
  from fastapi_users.models import UP
 
200
  oauth_client=Depends(lambda: google_oauth_client),
201
  redirect_url: str = GOOGLE_REDIRECT_URL,
202
  response: Response = None,
203
+ request: Request = None,
204
  ):
205
  logger.debug(f"Processing Google callback with code: {code}, state: {state}")
206
  try:
 
247
  secure=True,
248
  )
249
 
250
+ # تحقق إذا كان الطلب من التطبيق (Capacitor) أو الويب
251
+ is_app = request.headers.get("X-Capacitor-App", False)
252
+
253
+ if is_app:
254
+ # للتطبيق: إرجاع JSON مع الـ token
255
+ return JSONResponse(content={
256
+ "message": "Google login successful",
257
+ "access_token": token
258
+ }, status_code=200)
259
+ else:
260
+ # للويب: إرجاع redirect إلى /chat
261
+ return RedirectResponse(url="/chat", status_code=303)
262
+
263
  except Exception as e:
264
  logger.error(f"Error in Google OAuth callback: {str(e)}")
265
  return JSONResponse(content={"detail": str(e)}, status_code=400)
 
271
  oauth_client=Depends(lambda: github_oauth_client),
272
  redirect_url: str = GITHUB_REDIRECT_URL,
273
  response: Response = None,
274
+ request: Request = None,
275
  ):
276
  logger.debug(f"Processing GitHub callback with code: {code}, state: {state}")
277
  try:
 
336
  secure=True,
337
  )
338
 
339
+ # تحقق إذا كان الطلب من التطبيق (Capacitor) أو الويب
340
+ is_app = request.headers.get("X-Capacitor-App", False)
341
+
342
+ if is_app:
343
+ # للتطبيق: إرجاع JSON مع الـ token
344
+ return JSONResponse(content={
345
+ "message": "GitHub login successful",
346
+ "access_token": token
347
+ }, status_code=200)
348
+ else:
349
+ # للويب: إرجاع redirect إلى /chat
350
+ return RedirectResponse(url="/chat", status_code=303)
351
+
352
  except Exception as e:
353
  logger.error(f"Error in GitHub OAuth callback: {str(e)}")
354
  return JSONResponse(content={"detail": str(e)}, status_code=400)
requirements.txt CHANGED
@@ -1,5 +1,6 @@
1
  fastapi==0.95.2
2
- fastapi-users[sqlalchemy,oauth2]==10.4.2
 
3
  pydantic==1.10.13
4
  email-validator==1.3.1
5
  sqlalchemy[asyncio]
 
1
  fastapi==0.95.2
2
+
3
+ fastapi-users[sqlalchemy,oauth2]==12.1.3
4
  pydantic==1.10.13
5
  email-validator==1.3.1
6
  sqlalchemy[asyncio]
templates/login.html CHANGED
@@ -568,58 +568,62 @@
568
 
569
  // Check for OAuth callback on load
570
  window.addEventListener('load', async () => {
571
- console.log('Page loaded, checking for auth status and OAuth callback');
572
- if (!navigator.onLine) {
573
- errorMsg.textContent = 'You are offline. Please connect to the internet and try again.';
574
- errorMsg.classList.remove('hidden');
575
- return;
576
- }
577
- const urlParams = new URLSearchParams(window.location.search);
578
- const code = urlParams.get('code');
579
- const error = urlParams.get('error');
580
- if (error) {
581
- errorMsg.textContent = decodeURIComponent(error);
582
- errorMsg.classList.remove('hidden');
583
- console.error('OAuth error from URL:', error);
584
- } else if (code) {
585
- console.log('OAuth code detected in URL, processing callback');
586
- const provider = window.location.pathname.includes('google') ? 'google' : 'github';
587
- try {
588
- const response = await fetch(window.location.href, {
589
- method: 'GET',
590
- headers: { 'Accept': 'application/json' }
591
- });
592
- if (response.ok) {
593
- const data = await response.json();
594
- if (data.access_token) {
595
- localStorage.setItem('token', data.access_token);
596
- console.log(`${provider} login successful, token saved`);
597
- const isAuthenticated = await checkAuthStatus();
598
- if (isAuthenticated) {
599
- console.log('Redirecting to /chat');
600
- window.location.href = '/chat';
601
- } else {
602
- throw new Error('Authentication failed after receiving token');
603
- }
 
 
 
 
604
  } else {
605
- throw new Error('No access token received');
606
  }
607
  } else {
608
- const errorData = await response.json();
609
- errorMsg.textContent = errorData.detail || `Failed to complete ${provider} login`;
610
- errorMsg.classList.remove('hidden');
611
- console.error(`Failed to complete ${provider} login:`, errorData);
612
  }
613
- } catch (error) {
614
- errorMsg.textContent = `Failed to process ${provider} login. Please try again.`;
 
615
  errorMsg.classList.remove('hidden');
616
- console.error(`Error processing ${provider} callback:`, error);
617
  }
618
- } else {
619
- await checkAuthStatus();
 
 
620
  }
621
- });
622
-
623
  // Handle card details toggle
624
  function showCardDetails(cardId) {
625
  console.log('Showing card details:', cardId);
 
568
 
569
  // Check for OAuth callback on load
570
  window.addEventListener('load', async () => {
571
+ console.log('Page loaded, checking for auth status and OAuth callback');
572
+ if (!navigator.onLine) {
573
+ errorMsg.textContent = 'You are offline. Please connect to the internet and try again.';
574
+ errorMsg.classList.remove('hidden');
575
+ return;
576
+ }
577
+ const isAuthenticated = await checkAuthStatus();
578
+ if (isAuthenticated) {
579
+ console.log('User already authenticated, redirecting to /chat');
580
+ window.location.href = '/chat';
581
+ return;
582
+ }
583
+
584
+ const urlParams = new URLSearchParams(window.location.search);
585
+ const code = urlParams.get('code');
586
+ const error = urlParams.get('error');
587
+ if (error) {
588
+ errorMsg.textContent = decodeURIComponent(error);
589
+ errorMsg.classList.remove('hidden');
590
+ console.error('OAuth error from URL:', error);
591
+ } else if (code) {
592
+ console.log('OAuth code detected in URL, processing callback');
593
+ const provider = window.location.pathname.includes('google') ? 'google' : 'github';
594
+ try {
595
+ const response = await fetch(window.location.href, {
596
+ method: 'GET',
597
+ headers: { 'Accept': 'application/json' }
598
+ });
599
+ if (response.ok) {
600
+ const data = await response.json();
601
+ if (data.access_token) {
602
+ localStorage.setItem('token', data.access_token);
603
+ console.log(`${provider} login successful, token saved`);
604
+ const isAuthenticated = await checkAuthStatus();
605
+ if (isAuthenticated) {
606
+ console.log('Redirecting to /chat');
607
+ window.location.href = '/chat';
608
  } else {
609
+ throw new Error('Authentication failed after receiving token');
610
  }
611
  } else {
612
+ throw new Error('No access token received');
 
 
 
613
  }
614
+ } else {
615
+ const errorData = await response.json();
616
+ errorMsg.textContent = errorData.detail || `Failed to complete ${provider} login`;
617
  errorMsg.classList.remove('hidden');
618
+ console.error(`Failed to complete ${provider} login:`, errorData);
619
  }
620
+ } catch (error) {
621
+ errorMsg.textContent = `Failed to process ${provider} login. Please try again.`;
622
+ errorMsg.classList.remove('hidden');
623
+ console.error(`Error processing ${provider} callback:`, error);
624
  }
625
+ }
626
+ });
627
  // Handle card details toggle
628
  function showCardDetails(cardId) {
629
  console.log('Showing card details:', cardId);