mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-06-23 13:02:25 +00:00
152 lines
4.7 KiB
C++
152 lines
4.7 KiB
C++
/*
|
|
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
|
|
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
|
|
#include "Http.h"
|
|
#include "Options.h"
|
|
#include "Logger.h"
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
namespace fs = std::filesystem;
|
|
std::string PublicKey;
|
|
std::string PrivateKey;
|
|
extern bool LoginAuth;
|
|
extern std::string Username;
|
|
extern std::string UserRole;
|
|
extern int UserID;
|
|
|
|
void UpdateKey(const char* newKey) {
|
|
if (newKey && std::isalnum(newKey[0])) {
|
|
PrivateKey = newKey;
|
|
std::ofstream Key("key");
|
|
if (Key.is_open()) {
|
|
Key << newKey;
|
|
Key.close();
|
|
} else
|
|
fatal("Cannot write to disk!");
|
|
} else if (fs::exists("key")) {
|
|
remove("key");
|
|
}
|
|
}
|
|
|
|
/// "username":"value","password":"value"
|
|
/// "Guest":"Name"
|
|
/// "pk":"private_key"
|
|
|
|
std::string GetFail(const std::string& R) {
|
|
std::string DRet = R"({"success":false,"message":)";
|
|
DRet += "\"" + R + "\"}";
|
|
error(R);
|
|
return DRet;
|
|
}
|
|
|
|
std::string Login(const std::string& fields) {
|
|
if (fields == "LO") {
|
|
Username = "";
|
|
UserRole = "";
|
|
UserID = -1;
|
|
LoginAuth = false;
|
|
UpdateKey(nullptr);
|
|
return "";
|
|
}
|
|
info("Attempting to authenticate...");
|
|
try {
|
|
std::string Buffer = HTTP::Post("https://auth." + Utils::RegionToTopLevelDomain(options.region) + "/userlogin", fields);
|
|
|
|
if (Buffer.empty()) {
|
|
return GetFail("Failed to communicate with the auth system!");
|
|
}
|
|
|
|
nlohmann::json d = nlohmann::json::parse(Buffer, nullptr, false);
|
|
|
|
if (Buffer.at(0) != '{' || d.is_discarded()) {
|
|
error(Buffer);
|
|
return GetFail("Invalid answer from authentication servers, please try again later!");
|
|
}
|
|
if (d.contains("success") && d["success"].get<bool>()) {
|
|
LoginAuth = true;
|
|
if (d.contains("username")) {
|
|
Username = d["username"].get<std::string>();
|
|
}
|
|
if (d.contains("role")) {
|
|
UserRole = d["role"].get<std::string>();
|
|
}
|
|
if (d.contains("id")) {
|
|
UserID = d["id"].get<int>();
|
|
}
|
|
if (d.contains("private_key")) {
|
|
UpdateKey(d["private_key"].get<std::string>().c_str());
|
|
}
|
|
if (d.contains("public_key")) {
|
|
PublicKey = d["public_key"].get<std::string>();
|
|
}
|
|
info("Authentication successful!");
|
|
} else
|
|
info("Authentication failed!");
|
|
if (d.contains("message")) {
|
|
d.erase("private_key");
|
|
d.erase("public_key");
|
|
debug("Authentication result: " + d["message"].get<std::string>());
|
|
return d.dump();
|
|
}
|
|
return GetFail("Invalid message parsing!");
|
|
} catch (const std::exception& e) {
|
|
return GetFail(e.what());
|
|
}
|
|
}
|
|
|
|
void CheckLocalKey() {
|
|
if (fs::exists("key") && fs::file_size("key") < 100) {
|
|
std::ifstream Key("key");
|
|
if (Key.is_open()) {
|
|
auto Size = fs::file_size("key");
|
|
std::string Buffer(Size, 0);
|
|
Key.read(&Buffer[0], Size);
|
|
Key.close();
|
|
|
|
for (char& c : Buffer) {
|
|
if (!std::isalnum(c) && c != '-') {
|
|
UpdateKey(nullptr);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Buffer = HTTP::Post("https://auth." + Utils::RegionToTopLevelDomain(options.region) + "/userlogin", R"({"pk":")" + Buffer + "\"}");
|
|
|
|
nlohmann::json d = nlohmann::json::parse(Buffer, nullptr, false);
|
|
|
|
if (Buffer.empty() || Buffer.at(0) != '{' || d.is_discarded()) {
|
|
error(Buffer);
|
|
info("Invalid answer from authentication servers.");
|
|
UpdateKey(nullptr);
|
|
}
|
|
if (d["success"].get<bool>()) {
|
|
LoginAuth = true;
|
|
UpdateKey(d["private_key"].get<std::string>().c_str());
|
|
PublicKey = d["public_key"].get<std::string>();
|
|
if (d.contains("username")) {
|
|
Username = d["username"].get<std::string>();
|
|
}
|
|
if (d.contains("role")) {
|
|
UserRole = d["role"].get<std::string>();
|
|
}
|
|
if (d.contains("id")) {
|
|
UserID = d["id"].get<int>();
|
|
}
|
|
} else {
|
|
info("Auto-Authentication unsuccessful please re-login!");
|
|
UpdateKey(nullptr);
|
|
}
|
|
} else {
|
|
warn("Could not open saved key!");
|
|
UpdateKey(nullptr);
|
|
}
|
|
} else
|
|
UpdateKey(nullptr);
|
|
}
|