Add comprehensive error handling and debugging for signup issues

- Enhanced login endpoint with detailed logging for debugging JWT token issues
- Added explicit is_google_user and email_verified flags during registration
- Added test endpoints for JWT token creation verification
- Added debug endpoint to check user authentication status
- Improved error handling and logging throughout authentication flow
- Better validation for password vs Google OAuth users

Debug endpoints added:
- POST /auth/test-token - Test JWT token creation
- GET /auth/debug/user/{email} - Check user authentication status

This will help identify why JWT tokens are not being returned during signin.
This commit is contained in:
Automated Action 2025-06-25 06:41:11 +00:00
parent 99937b3fd7
commit 4cc9c41fe8

View File

@ -23,6 +23,46 @@ async def test_auth():
} }
@router.post("/test-token")
async def test_token_creation():
"""Test endpoint to verify JWT token creation is working"""
try:
test_token = create_access_token(data={"sub": "test@example.com"})
return {
"message": "Token creation successful",
"token_length": len(test_token),
"token_preview": test_token[:50] + "..." if len(test_token) > 50 else test_token
}
except Exception as e:
logger.error(f"Token creation test failed: {e}")
return {
"message": "Token creation failed",
"error": str(e)
}
@router.get("/debug/user/{email}")
async def debug_user_status(email: str, db: Session = Depends(get_db)):
"""Debug endpoint to check user status - REMOVE IN PRODUCTION"""
try:
db_user = db.query(User).filter(User.email == email).first()
if not db_user:
return {"message": "User not found", "email": email}
return {
"email": db_user.email,
"has_password_hash": db_user.password_hash is not None,
"password_hash_length": len(db_user.password_hash) if db_user.password_hash else 0,
"is_google_user": db_user.is_google_user,
"email_verified": db_user.email_verified,
"can_login_with_password": db_user.can_login_with_password(),
"created_at": str(db_user.created_at),
"google_id": db_user.google_id
}
except Exception as e:
return {"error": str(e)}
class UserCreate(BaseModel): class UserCreate(BaseModel):
email: EmailStr email: EmailStr
password: str password: str
@ -63,15 +103,19 @@ async def register(user: UserCreate, db: Session = Depends(get_db)):
# Hash password and create user # Hash password and create user
hashed_password = get_password_hash(user.password) hashed_password = get_password_hash(user.password)
logger.info(f"Password hashed successfully for user: {user.email}")
db_user = User( db_user = User(
email=user.email, email=user.email,
password_hash=hashed_password password_hash=hashed_password,
is_google_user=False, # Explicitly set for password users
email_verified=False # Email not verified for regular registration
) )
db.add(db_user) db.add(db_user)
db.commit() db.commit()
db.refresh(db_user) db.refresh(db_user)
logger.info(f"User registered successfully: {user.email}") logger.info(f"User registered successfully: {user.email}, can_login_with_password: {db_user.can_login_with_password()}")
return UserResponse( return UserResponse(
id=db_user.id, id=db_user.id,
email=db_user.email, email=db_user.email,
@ -91,35 +135,55 @@ async def register(user: UserCreate, db: Session = Depends(get_db)):
@router.post("/login", response_model=Token) @router.post("/login", response_model=Token)
async def login(user: UserLogin, db: Session = Depends(get_db)): async def login(user: UserLogin, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.email == user.email).first() try:
logger.info(f"Login attempt for email: {user.email}")
# Check if user exists db_user = db.query(User).filter(User.email == user.email).first()
if not db_user:
# Check if user exists
if not db_user:
logger.warning(f"Login failed - user not found: {user.email}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"},
)
logger.info(f"User found: {user.email}, is_google_user: {db_user.is_google_user}, has_password: {db_user.password_hash is not None}")
# Check if user can login with password
if not db_user.can_login_with_password():
logger.warning(f"Login failed - Google user attempted password login: {user.email}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This account uses Google sign-in. Please use Google to login.",
headers={"WWW-Authenticate": "Bearer"},
)
# Verify password
if not verify_password(user.password, db_user.password_hash):
logger.warning(f"Login failed - incorrect password: {user.email}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"},
)
# Create token
access_token = create_access_token(data={"sub": db_user.email})
logger.info(f"Login successful for user: {user.email}")
return {"access_token": access_token, "token_type": "bearer"}
except HTTPException:
raise
except Exception as e:
logger.error(f"Login error for {user.email}: {str(e)}")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Incorrect email or password", detail="Internal server error during login"
headers={"WWW-Authenticate": "Bearer"},
) )
# Check if user can login with password
if not db_user.can_login_with_password():
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This account uses Google sign-in. Please use Google to login.",
headers={"WWW-Authenticate": "Bearer"},
)
# Verify password
if not verify_password(user.password, db_user.password_hash):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token = create_access_token(data={"sub": db_user.email})
return {"access_token": access_token, "token_type": "bearer"}
# Google OAuth Models # Google OAuth Models
class GoogleTokenLogin(BaseModel): class GoogleTokenLogin(BaseModel):