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:
parent
99937b3fd7
commit
4cc9c41fe8
@ -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):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user