finally added session-based authentication and libcurl for https requests. (serverside for right now.)

This commit is contained in:
Matthew Toro 2026-04-03 04:28:52 -04:00
parent e979be42b2
commit 0fa5ae3037
10 changed files with 175 additions and 40 deletions

View file

@ -1,5 +1,23 @@
#include "stdafx.h"
#include "AuthModule.h"
#include "HttpClient.h"
#include "StringHelpers.h"
#include "Common/vendor/nlohmann/json.hpp"
#include <random>
static string narrowStr(const wstring &w)
{
return string(w.begin(), w.end());
}
static wstring generateServerId()
{
static constexpr wchar_t hex[] = L"0123456789abcdef";
static std::mt19937 rng(std::random_device{}());
wstring id(16, L'0');
for (auto &c : id) c = hex[rng() & 0xF];
return id;
}
bool AuthModule::validate(const wstring &uid, const wstring &username)
{
@ -16,38 +34,67 @@ bool AuthModule::extractIdentity(const vector<pair<wstring, wstring>> &fields, w
return validate(outUid, outUsername);
}
ElyByAuthModule::ElyByAuthModule(const wstring &endpoint)
: endpoint(endpoint)
SessionAuthModule::SessionAuthModule()
{
endpoints[L"mojang"] = {L"https://authserver.mojang.com", L"https://sessionserver.mojang.com"};
endpoints[L"elyby"] = {L"https://authserver.ely.by", L"https://authserver.ely.by"};
}
const wchar_t *ElyByAuthModule::schemeName() { return L"mcconsoles:elyby"; }
const wchar_t *SessionAuthModule::schemeName() { return L"mcconsoles:session"; }
vector<wstring> ElyByAuthModule::supportedVariations()
vector<wstring> SessionAuthModule::supportedVariations()
{
return {L"java"};
return {L"mojang", L"elyby"};
}
vector<pair<wstring, wstring>> ElyByAuthModule::getSettings(const wstring &variation)
vector<pair<wstring, wstring>> SessionAuthModule::getSettings(const wstring &variation)
{
return {{L"endpoint", endpoint}};
auto it = endpoints.find(variation);
if (it == endpoints.end()) return {};
activeSessionEndpoint = it->second.sessionEndpoint;
activeServerId = generateServerId();
return {
{L"authEndpoint", it->second.authEndpoint},
{L"sessionEndpoint", it->second.sessionEndpoint},
{L"serverId", activeServerId}
};
}
bool ElyByAuthModule::onAuthData(const vector<pair<wstring, wstring>> &fields, wstring &outUid, wstring &outUsername)
bool SessionAuthModule::onAuthData(const vector<pair<wstring, wstring>> &fields, wstring &outUid, wstring &outUsername)
{
return extractIdentity(fields, outUid, outUsername);
}
wstring username;
for (const auto &[k, v] : fields)
{
if (k == L"username") username = v;
}
MojangAuthModule::MojangAuthModule()
: ElyByAuthModule(L"https://sessionserver.mojang.com")
{
}
if (username.empty() || activeServerId.empty() || activeSessionEndpoint.empty())
return false;
const wchar_t *MojangAuthModule::schemeName() { return L"mcconsoles:mojang"; }
string url = narrowStr(activeSessionEndpoint)
+ "/session/minecraft/hasJoined?username=" + narrowStr(username)
+ "&serverId=" + narrowStr(activeServerId);
vector<wstring> MojangAuthModule::supportedVariations()
{
return {L"java", L"bedrock"};
auto response = HttpClient::get(url);
if (response.statusCode != 200)
return false;
auto json = nlohmann::json::parse(response.body, nullptr, false);
if (json.is_discarded())
return false;
string id = json.value("id", "");
string name = json.value("name", "");
if (id.empty() || name.empty())
return false;
outUid = convStringToWstring(id);
outUsername = convStringToWstring(name);
return validate(outUid, outUsername);
}
const wchar_t *KeypairOfflineAuthModule::schemeName() { return L"mcconsoles:keypair_offline"; }