#include "SessionHandler.hpp" #include #include #include "crow/logging.h" using namespace login; // generate random string std::string randomString(size_t length) { static const char charset[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; std::string result; result.resize(length); std::mt19937 rng(std::random_device{}()); std::uniform_int_distribution<> dist(0, sizeof(charset)-2); for (size_t i = 0; i < length; ++i) result[i] = charset[dist(rng)]; return result; } SessionHandler::SessionHandler() : cleanupThread(std::thread(&SessionHandler::cleanupWorker, this)) , stopCleanupThread(false) { } SessionHandler::~SessionHandler() { stopCleanupThread = true; if (cleanupThread.joinable()) cleanupThread.join(); } void SessionHandler::cleanupWorker(){ while (!stopCleanupThread) { std::this_thread::sleep_for(std::chrono::minutes(5)); auto now = std::chrono::steady_clock::now(); { std::lock_guard lock(sessionMutex); for (auto it = sessions.begin(); it != sessions.end();) { if (it->second.isExpired(now)){ CROW_LOG_INFO << "Session " << it->first << " expired for userId: " << it->second.userId(); it = sessions.erase(it); } else { ++it; } } } } } std::optional SessionHandler::createSession(int userId){ std::string sessionId = randomString(Session::SESSION_ID_SIZE); std::lock_guard lock(sessionMutex); if (!sessions.emplace(sessionId, Session(userId)).second){ return {}; } return sessionId; } std::optional SessionHandler::isSessionValid(const std::string& sessionId){ auto now = std::chrono::steady_clock::now(); std::lock_guard lock(sessionMutex); auto it = sessions.find(sessionId); if(it != sessions.end()){ if (it->second.isExpired(now)){ CROW_LOG_INFO << "Session " << it->first << " expired for userId: " << it->second.userId(); it = sessions.erase(it); return {}; } it->second.extend(now); // extend session life time return it->second.userId(); } return {}; }