#include "authenticator.h" #include namespace scar { Authenticator::Authenticator(std::shared_ptr db, const std::string& jwt_secret) : db_(db), jwt_secret_(jwt_secret) {} std::string Authenticator::authenticate(const std::string& username, const std::string& password) { std::cout << "Authentication attempt for user: '" << username << "'" << std::endl; // Get user from database auto user = db_->getUserByUsername(username); if (!user) { std::cerr << "Authentication failed: user not found" << std::endl; return ""; } std::cout << "User found in database, username: '" << user->username << "'" << std::endl; std::cout << "Stored salt (first 20 chars): " << user->salt.substr(0, 20) << std::endl; std::cout << "Stored hash (first 20 chars): " << user->password_hash.substr(0, 20) << std::endl; // Hash the provided password with the stored salt std::string password_hash = Argon2Wrapper::hashPassword(password, user->salt); std::cout << "Computed hash (first 20 chars): " << password_hash.substr(0, 20) << std::endl; // Verify against stored hash if (password_hash != user->password_hash) { std::cerr << "Authentication failed: incorrect password" << std::endl; std::cerr << " Expected: " << user->password_hash << std::endl; std::cerr << " Got: " << password_hash << std::endl; return ""; } // Generate JWT token std::string token = JWT::generate(username, jwt_secret_); // Store token in database if (!db_->updateUserToken(username, token)) { std::cerr << "Failed to update user token" << std::endl; return ""; } // Update user status and last login db_->updateUserStatus(username, UserStatus::ONLINE); db_->updateLastLogin(username); std::cout << "User '" << username << "' authenticated successfully" << std::endl; return token; } std::string Authenticator::verifyToken(const std::string& token) { // Verify JWT signature and expiration if (!JWT::verify(token, jwt_secret_)) { return ""; } // Extract username std::string username = JWT::extractUsername(token); if (username.empty()) { return ""; } // Verify token matches database std::string db_username = db_->getUsernameByToken(token); if (db_username != username) { return ""; } return username; } bool Authenticator::createUser(const std::string& username, const std::string& password) { // Generate salt std::string salt = Argon2Wrapper::generateSalt(); // Hash password with salt std::string password_hash = Argon2Wrapper::hashPassword(password, salt); // Create user in database bool success = db_->createUser(username, password_hash, salt); if (success) { std::cout << "User '" << username << "' created successfully" << std::endl; } else { std::cerr << "Failed to create user '" << username << "'" << std::endl; } return success; } } // namespace scar