Skip to content

Commit bdb7c9a

Browse files
committed
deploy fix 96b9977b: OAuth callback fetch error: SyntaxError: Unexpected token 'I' is not valid JSON
1 parent 9d54377 commit bdb7c9a

File tree

2 files changed

+112
-51
lines changed

2 files changed

+112
-51
lines changed

backend/github_oauth.py

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,68 @@
11
import os
22
import httpx
3-
from fastapi import Request
3+
import logging
4+
from fastapi import Request, HTTPException
5+
6+
logger = logging.getLogger(__name__)
47

58
GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID")
69
GITHUB_CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET")
710

811
if not GITHUB_CLIENT_ID or not GITHUB_CLIENT_SECRET:
12+
logger.error("GitHub OAuth credentials missing!")
13+
logger.error(f"GITHUB_CLIENT_ID: {'present' if GITHUB_CLIENT_ID else 'missing'}")
14+
logger.error(f"GITHUB_CLIENT_SECRET: {'present' if GITHUB_CLIENT_SECRET else 'missing'}")
915
raise ValueError("❌ GitHub OAuth credentials not found")
1016

1117
async def exchange_code_for_token(code: str):
12-
async with httpx.AsyncClient() as client:
13-
response = await client.post(
14-
"https://github.com/login/oauth/access_token",
15-
headers={"Accept": "application/json"},
16-
data={
17-
"client_id": GITHUB_CLIENT_ID,
18-
"client_secret": GITHUB_CLIENT_SECRET,
19-
"code": code
20-
}
21-
)
22-
return response.json()
18+
if not code:
19+
raise HTTPException(status_code=400, detail="GitHub code is required")
20+
21+
try:
22+
async with httpx.AsyncClient() as client:
23+
logger.info(f"Exchanging code for token with GitHub")
24+
response = await client.post(
25+
"https://github.com/login/oauth/access_token",
26+
headers={"Accept": "application/json"},
27+
data={
28+
"client_id": GITHUB_CLIENT_ID,
29+
"client_secret": GITHUB_CLIENT_SECRET,
30+
"code": code
31+
}
32+
)
33+
response.raise_for_status()
34+
data = response.json()
35+
logger.info("Successfully exchanged code for token")
36+
return data
37+
except httpx.HTTPError as e:
38+
logger.error(f"HTTP error during token exchange: {str(e)}")
39+
logger.error(f"Response status: {e.response.status_code if hasattr(e, 'response') else 'unknown'}")
40+
logger.error(f"Response body: {e.response.text if hasattr(e, 'response') else 'unknown'}")
41+
raise HTTPException(status_code=500, detail=f"GitHub API error: {str(e)}")
42+
except Exception as e:
43+
logger.exception("Error exchanging code for token:")
44+
raise HTTPException(status_code=500, detail=str(e))
2345

2446
async def get_user_info(access_token: str):
25-
async with httpx.AsyncClient() as client:
26-
response = await client.get(
27-
"https://api.github.com/user",
28-
headers={"Authorization": f"Bearer {access_token}"}
29-
)
30-
return response.json()
47+
if not access_token:
48+
raise HTTPException(status_code=400, detail="Access token is required")
49+
50+
try:
51+
async with httpx.AsyncClient() as client:
52+
logger.info("Fetching user info from GitHub")
53+
response = await client.get(
54+
"https://api.github.com/user",
55+
headers={"Authorization": f"Bearer {access_token}"}
56+
)
57+
response.raise_for_status()
58+
data = response.json()
59+
logger.info("Successfully fetched user info")
60+
return data
61+
except httpx.HTTPError as e:
62+
logger.error(f"HTTP error fetching user info: {str(e)}")
63+
logger.error(f"Response status: {e.response.status_code if hasattr(e, 'response') else 'unknown'}")
64+
logger.error(f"Response body: {e.response.text if hasattr(e, 'response') else 'unknown'}")
65+
raise HTTPException(status_code=500, detail=f"GitHub API error: {str(e)}")
66+
except Exception as e:
67+
logger.exception("Error fetching user info:")
68+
raise HTTPException(status_code=500, detail=str(e))

backend/routers/auth.py

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,72 @@
66
from database import SessionLocal
77
from sqlalchemy import select
88
from datetime import datetime
9+
import logging
910

1011
auth_router = APIRouter()
12+
logger = logging.getLogger(__name__)
1113

1214
@auth_router.get("/login/github/callback")
1315
async def github_callback(request: Request):
14-
code = request.query_params.get("code")
15-
token_data = await exchange_code_for_token(code)
16-
access_token = token_data.get("access_token")
16+
try:
17+
code = request.query_params.get("code")
18+
logger.info(f"Received GitHub code: {code}")
19+
20+
token_data = await exchange_code_for_token(code)
21+
logger.info(f"GitHub token response: {token_data}")
22+
23+
access_token = token_data.get("access_token")
24+
if not access_token:
25+
logger.error(f"No access token in response: {token_data}")
26+
raise HTTPException(status_code=400, detail="Failed to get GitHub access token")
1727

18-
user_info = await get_user_info(access_token)
19-
github_id = user_info.get("id")
20-
username = user_info.get("login")
28+
user_info = await get_user_info(access_token)
29+
logger.info(f"GitHub user info: {user_info}")
30+
31+
github_id = str(user_info.get("id")) # Convert to string to match model
32+
username = user_info.get("login")
33+
34+
if not github_id or not username:
35+
logger.error(f"Invalid user info: {user_info}")
36+
raise HTTPException(status_code=400, detail="Invalid GitHub user info")
2137

22-
async with SessionLocal() as session:
23-
result = await session.execute(select(User).where(User.github_id == github_id))
24-
user = result.scalar_one_or_none()
38+
async with SessionLocal() as session:
39+
result = await session.execute(select(User).where(User.github_id == github_id))
40+
user = result.scalar_one_or_none()
2541

26-
now = datetime.now()
42+
now = datetime.now()
2743

28-
if not user:
29-
user = User(
30-
github_id=github_id,
31-
username=username,
32-
access_token=access_token,
33-
last_login=now,
34-
last_push=None
35-
)
36-
session.add(user)
37-
else:
38-
user.access_token = access_token
39-
user.last_login = now
40-
await session.commit()
44+
if not user:
45+
logger.info(f"Creating new user: {username}")
46+
user = User(
47+
github_id=github_id,
48+
username=username,
49+
access_token=access_token,
50+
last_login=now,
51+
last_push=None
52+
)
53+
session.add(user)
54+
else:
55+
logger.info(f"Updating existing user: {username}")
56+
user.access_token = access_token
57+
user.last_login = now
58+
await session.commit()
4159

42-
jwt_token = create_access_token({"github_id": github_id})
43-
44-
# chrome URL redirect with JWT
45-
return JSONResponse({
46-
"message": "GitHub login successful",
47-
"token": jwt_token,
48-
"username": username,
49-
"last_push": user.last_push.isoformat() if user.last_push else None,
50-
"last_login": user.last_login.isoformat() if user.last_login else None
51-
})
60+
jwt_token = create_access_token({"github_id": github_id})
61+
62+
response_data = {
63+
"message": "GitHub login successful",
64+
"token": jwt_token,
65+
"username": username,
66+
"last_push": user.last_push.isoformat() if user.last_push else None,
67+
"last_login": user.last_login.isoformat() if user.last_login else None
68+
}
69+
logger.info(f"Login successful for user: {username}")
70+
return JSONResponse(response_data)
71+
72+
except Exception as e:
73+
logger.exception("Error in GitHub callback:")
74+
raise HTTPException(status_code=500, detail=str(e))
5275

5376
async def get_current_user(authorization: str = Header(...)):
5477
token = authorization.replace("Bearer ", "")

0 commit comments

Comments
 (0)