#include #include #include "utils.hpp" #include #include #include #include std::string hashing::GenerateSetting(unsigned long cost) { // "$y$" is the yescrypt prefix const char* setting = crypt_gensalt("$y$", cost, nullptr, 0); if (!setting) throw std::runtime_error("crypt_gensalt() failed - yescrypt may not be supported"); return setting; } std::string hashing::HashPassword(const std::string& password, const std::string& setting) { crypt_data data{}; const char* hash = crypt_r(password.c_str(), setting.c_str(), &data); if (!hash || hash[0] == '*') throw std::runtime_error("crypt_r() failed"); return hash; } bool hashing::VerifyPassword(const std::string& password, const std::string& stored_hash) { crypt_data data{}; const char* result = crypt_r(password.c_str(), stored_hash.c_str(), &data); if (!result || result[0] == '*') return false; return stored_hash == result; } std::string hashing::generate_token(size_t bytes) { std::random_device rd; std::string token; token.reserve(bytes * 2); std::uniform_int_distribution dist(0, 255); for (size_t i = 0; i < bytes; ++i) { std::ostringstream ss; ss << std::hex << std::setw(2) << std::setfill('0') << (int)dist(rd); token += ss.str(); } return token; } timestamp::Timestamp timestamp::ParseTimestamp(const std::string& ts) { std::tm tm = {}; std::istringstream ss(ts); ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S"); return std::chrono::system_clock::from_time_t(std::mktime(&tm)); } timestamp::Timestamp timestamp::Now() { return std::chrono::system_clock::now(); } std::string timestamp::FormatTimestamp(const timestamp::Timestamp& ts) { return std::format("{:%Y-%m-%d %H:%M:%S}", ts); }