from datetime import datetime, timedelta import secrets from typing import Optional from sqlalchemy.orm import Session from app.core.config import settings from app.models.password_reset import PasswordReset from app.models.user import User from app.services.user import get_user_by_email, get_user_by_id from app.utils.security import create_access_token, create_refresh_token, get_password_hash, verify_password def generate_password_reset_token(db: Session, email: str) -> Optional[str]: """Generate a password reset token for a user.""" user = get_user_by_email(db, email=email) if not user: return None # Generate token token = secrets.token_urlsafe(32) expires_at = datetime.utcnow() + timedelta(hours=settings.PASSWORD_RESET_TOKEN_EXPIRE_HOURS) # Create password reset record password_reset = PasswordReset( user_id=user.id, token=token, expires_at=expires_at, ) db.add(password_reset) db.commit() return token def verify_password_reset_token(db: Session, token: str) -> Optional[User]: """Verify a password reset token.""" password_reset = db.query(PasswordReset).filter( PasswordReset.token == token, PasswordReset.is_used == 0 ).first() if not password_reset: return None # Check if token is expired if password_reset.is_expired(): return None # Get user user = get_user_by_id(db, user_id=password_reset.user_id) if not user: return None return user def reset_password(db: Session, token: str, new_password: str) -> Optional[User]: """Reset a user's password.""" password_reset = db.query(PasswordReset).filter( PasswordReset.token == token, PasswordReset.is_used == 0 ).first() if not password_reset: return None # Check if token is expired if password_reset.is_expired(): return None # Get user user = get_user_by_id(db, user_id=password_reset.user_id) if not user: return None # Update password user.hashed_password = get_password_hash(new_password) user.updated_at = datetime.utcnow() # Mark token as used password_reset.is_used = 1 db.add(user) db.add(password_reset) db.commit() db.refresh(user) return user def authenticate_user(db: Session, email: str, password: str) -> Optional[User]: """Authenticate a user.""" user = get_user_by_email(db, email=email) if not user: return None if not user.is_active: return None if not verify_password(password, user.hashed_password): return None return user def create_tokens_for_user(user_id: int) -> dict: """Create JWT tokens for a user.""" access_token = create_access_token(subject=user_id) refresh_token = create_refresh_token(subject=user_id) return { "access_token": access_token, "refresh_token": refresh_token, "token_type": "bearer" }