use sqlx::PgPool; use bcrypt::verify; use crate::{ models::{User, LoginRequest, LoginResponse}, error::{Result, ApiError}, auth::create_jwt, sql::users, }; /// Authentication and user management service /// Contains all auth-related business logic, keeping handlers thin and focused on HTTP concerns pub struct AuthService; impl AuthService { /// Authenticate user login pub async fn login(pool: &PgPool, request: LoginRequest, jwt_secret: &str) -> Result { // Get user data from database (including password hash) let user_data = match users::get_user_with_password_by_username(pool, &request.username).await? { Some(user) => user, None => return Err(ApiError::AuthError("User not found".to_string())), }; // Verify password match verify(&request.password, &user_data.password_hash) { Ok(true) => { // Password is correct - create user with complete data let user = User { id: user_data.id, username: user_data.username.clone(), email: user_data.email, name: user_data.name, avatar_url: user_data.avatar_url, role: user_data.role.clone(), verified: user_data.verified, created_at: user_data.created_at, updated_at: user_data.updated_at, }; // Create JWT token let token = create_jwt(&user_data.id, &user_data.username, &user.role.as_ref().unwrap_or(&"admin".to_string()), jwt_secret)?; Ok(LoginResponse { token, user }) }, Ok(false) => Err(ApiError::AuthError("Invalid password".to_string())), Err(e) => Err(ApiError::AuthError(format!("Bcrypt error: {}", e))), } } /// List all users (admin function) pub async fn list_users(pool: &PgPool) -> Result> { users::list_all_users(pool).await } }