From 1fd8b531e07f3474023989fcefb3d8823a423479 Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Sun, 9 Nov 2025 17:54:53 -0500 Subject: [PATCH] refactor: enhance OverteAuth class with additional methods and improved token handling --- src/OverteAuth.hpp | 62 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/OverteAuth.hpp b/src/OverteAuth.hpp index 61166b6..bebb82c 100644 --- a/src/OverteAuth.hpp +++ b/src/OverteAuth.hpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include // Simple OAuth2 authentication for Overte metaverse class OverteAuth { @@ -11,12 +14,21 @@ public: OverteAuth(); ~OverteAuth(); - // Authenticate with username/password - bool login(const std::string& username, const std::string& password, + // Authenticate with username/password (Resource Owner Password Grant) + bool login(const std:string& username, const std::string& password, const std::string& metaverseUrl = "https://mv.overte.org"); + // Authenticate with browser OAuth flow (Authorization Code Grant) - RECOMMENDED + bool loginWithBrowser(const std::string& metaverseUrl = "https://mv.overte.org"); + + // Authenticate with authorization code (after browser callback) + bool loginWithAuthCode(const std::string& authCode, const std::string& redirectUri); + + // Refresh access token + bool refreshAccessToken(); + // Check if we have a valid access token - bool isAuthenticated() const { return !m_accessToken.empty(); } + bool isAuthenticated() const { return !m_accessToken.empty() && !isTokenExpired(); } // Get current access token const std::string& getAccessToken() const { return m_accessToken; } @@ -24,19 +36,55 @@ public: // Get username const std::string& getUsername() const { return m_username; } + // Get last error message + const std::string& getLastError() const { return m_lastError; } + // Logout void logout(); + // Token persistence + bool loadTokenFromFile(); + bool saveTokenToFile(); + private: std::string m_metaverseUrl; std::string m_accessToken; std::string m_refreshToken; std::string m_username; - std::uint64_t m_tokenExpiresAt{0}; // Unix timestamp + std::uint64_t m_tokenExpiresAt{0}; // Unix timestamp in seconds + std::string m_lastError; + std::string m_clientId = "starworld"; + std::string m_clientSecret = ""; // Public client - // libcurl callback for writing response data + // OAuth callback HTTP server + int m_callbackServerFd = -1; + int m_callbackPort = 0; + std::atomic m_callbackRunning{false}; + std::unique_ptr m_callbackThread; + std::string m_receivedAuthCode; + std::string m_authState; // CSRF protection + + // Helper methods + bool isTokenExpired() const; + bool needsRefresh() const; // Returns true if token expires within 1 hour + std::string getTokenFilePath(); + std::string getConfigDir(); + bool parseTokenResponse(const std::string& jsonResponse); + std::string generateRandomState(); + std::string urlEncode(const std::string& value); + bool openBrowser(const std::string& url); + + // HTTP helpers + bool httpPost(const std::string& url, const std::string& postData, std::string& response); static size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp); - - // Parse JSON response (simple key-value extraction) static std::string extractJsonString(const std::string& json, const std::string& key); + static std::uint64_t extractJsonInt(const std::string& json, const std::string& key); + + // OAuth callback server + bool startCallbackServer(); + void stopCallbackServer(); + void callbackServerThread(); + void handleCallbackRequest(int clientFd); + std::string getCallbackURL() const; }; +