from database import execute, fetch_one import bcrypt from jose import jwt from datetime import datetime, timedelta from dotenv import load_dotenv import os from fastapi import Depends from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from email_service import create_verification, send_verification_email security = HTTPBearer() load_dotenv() SECRET_KEY = os.getenv("SECRET_KEY") ALGORITHM = "HS256" def create_token(user_id): payload = { "user_id": user_id, "exp": datetime.utcnow() + timedelta(hours=24) } token = jwt.encode( payload, SECRET_KEY, algorithm=ALGORITHM ) return token def create_user(username, password, email): password_hash = bcrypt.hashpw( password.encode(), bcrypt.gensalt() ).decode() user_id = execute( """ INSERT INTO users ( username, password_hash, email, email_verified ) VALUES (?, ?, ?, 0) """, ( username, password_hash, email, ) ) token = create_verification(user_id) send_verification_email( email, token, ) return user_id def verify_user(username, password): user = fetch_one( "SELECT * FROM users WHERE username = ?", (username,) ) if not user: return None if bcrypt.checkpw( password.encode(), user["password_hash"].encode() ): return user["id"] return None def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(security) ): token = credentials.credentials payload = jwt.decode( token, SECRET_KEY, algorithms=[ALGORITHM] ) return payload["user_id"] def get_user(user_id): return fetch_one( """ SELECT id, username, email, email_verified FROM users WHERE id = ? """, (user_id,) ) def change_password(user_id: int, old_password: str, new_password: str): user = fetch_one( """ SELECT password_hash FROM users WHERE id = ? """, (user_id,), ) if user is None: return { "status": "failed", "reason": "user_not_found", } if not bcrypt.checkpw( old_password.encode(), user["password_hash"].encode(), ): return { "status": "failed", "reason": "incorrect_password", } password_hash = bcrypt.hashpw( new_password.encode(), bcrypt.gensalt(), ).decode() execute( """ UPDATE users SET password_hash = ? WHERE id = ? """, ( password_hash, user_id, ), ) return { "status": "updated", }