Emscripten: Sync session with the website one

Also fix a cursed length-related problem with passing strings from JS to C++.
This commit is contained in:
Tamás Bálint Misius 2023-06-23 21:58:49 +02:00
parent f7bca3b1b1
commit 845e195ba5
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
8 changed files with 90 additions and 36 deletions

View File

@ -0,0 +1,30 @@
#include "Client.h"
#include "prefs/GlobalPrefs.h"
void Client::LoadAuthUser()
{
auto &prefs = GlobalPrefs::Ref();
authUser.UserID = prefs.Get("User.ID", 0);
authUser.Username = prefs.Get("User.Username", ByteString(""));
authUser.SessionID = prefs.Get("User.SessionID", ByteString(""));
authUser.SessionKey = prefs.Get("User.SessionKey", ByteString(""));
authUser.UserElevation = prefs.Get("User.Elevation", User::ElevationNone);
}
void Client::SaveAuthUser()
{
auto &prefs = GlobalPrefs::Ref();
Prefs::DeferWrite dw(prefs);
if (authUser.UserID)
{
prefs.Set("User.ID", authUser.UserID);
prefs.Set("User.SessionID", authUser.SessionID);
prefs.Set("User.SessionKey", authUser.SessionKey);
prefs.Set("User.Username", authUser.Username);
prefs.Set("User.Elevation", authUser.UserElevation);
}
else
{
prefs.Clear("User");
}
}

View File

@ -0,0 +1,42 @@
#include "Client.h"
#include "prefs/GlobalPrefs.h"
#include <emscripten.h>
void Client::LoadAuthUser()
{
std::optional<ByteString> newUsername;
if (EM_ASM_INT({
return document.querySelector("#PowderSessionInfo [name='Username']") ? 1 : 0;
}))
{
newUsername = ByteString(std::unique_ptr<char, decltype(&free)>((char *)EM_ASM_PTR({
return stringToNewUTF8(document.querySelector("#PowderSessionInfo [name='Username']").value);
}), free).get());
}
std::optional<ByteString> newSessionKey;
if (EM_ASM_INT({
return document.querySelector("#PowderSessionInfo [name='SessionKey']") ? 1 : 0;
}))
{
newSessionKey = ByteString(std::unique_ptr<char, decltype(&free)>((char *)EM_ASM_PTR({
return stringToNewUTF8(document.querySelector("#PowderSessionInfo [name='SessionKey']").value);
}), free).get());
}
if (newUsername && newSessionKey)
{
authUser.UserID = -1; // Not quite valid but evaluates to true and that's all that matters for this codebase.
authUser.Username = *newUsername;
authUser.SessionID = "(invalid)";
authUser.SessionKey = *newSessionKey;
authUser.UserElevation = User::ElevationNone; // We don't deal with this in the browser.
}
else
{
authUser.UserID = 0;
}
}
void Client::SaveAuthUser()
{
// Nothing is; the cookie headers in the login and logout responses take care of state management.
}

View File

@ -32,12 +32,8 @@ Client::Client():
updateAvailable(false), updateAvailable(false),
authUser(0, "") authUser(0, "")
{ {
LoadAuthUser();
auto &prefs = GlobalPrefs::Ref(); auto &prefs = GlobalPrefs::Ref();
authUser.UserID = prefs.Get("User.ID", 0);
authUser.Username = prefs.Get("User.Username", ByteString(""));
authUser.SessionID = prefs.Get("User.SessionID", ByteString(""));
authUser.SessionKey = prefs.Get("User.SessionKey", ByteString(""));
authUser.UserElevation = prefs.Get("User.Elevation", User::ElevationNone);
firstRun = !prefs.BackedByFile(); firstRun = !prefs.BackedByFile();
} }
@ -239,22 +235,7 @@ Client::~Client()
void Client::SetAuthUser(User user) void Client::SetAuthUser(User user)
{ {
authUser = user; authUser = user;
{ SaveAuthUser();
auto &prefs = GlobalPrefs::Ref();
Prefs::DeferWrite dw(prefs);
if (authUser.UserID)
{
prefs.Set("User.ID", authUser.UserID);
prefs.Set("User.SessionID", authUser.SessionID);
prefs.Set("User.SessionKey", authUser.SessionKey);
prefs.Set("User.Username", authUser.Username);
prefs.Set("User.Elevation", authUser.UserElevation);
}
else
{
prefs.Clear("User");
}
}
notifyAuthUserChanged(); notifyAuthUserChanged();
} }

View File

@ -53,6 +53,9 @@ private:
void MigrateStampsDef(); void MigrateStampsDef();
void WriteStamps(); void WriteStamps();
void LoadAuthUser();
void SaveAuthUser();
public: public:
std::vector<ClientListener*> listeners; std::vector<ClientListener*> listeners;

View File

@ -21,7 +21,7 @@ namespace http
comments.push_back({ comments.push_back({
comment["Username"].asString(), comment["Username"].asString(),
User::ElevationFromString(comment["Elevation"].asString()), User::ElevationFromString(comment["Elevation"].asString()),
ByteString(comment["UserID"].asString()).ToNumber<int>() == user.UserID, comment["Username"].asString() == user.Username,
comment["IsBanned"].asBool(), comment["IsBanned"].asBool(),
ByteString(comment["Text"].asString()).FromUtf8(), ByteString(comment["Text"].asString()).FromUtf8(),
}); });

View File

@ -60,7 +60,7 @@ namespace http
void Request::AuthHeaders(ByteString ID, ByteString session) void Request::AuthHeaders(ByteString ID, ByteString session)
{ {
assert(handle->state == RequestHandle::ready); assert(handle->state == RequestHandle::ready);
if (ID.size()) if (ID.size() && ID != "-1") // -1 is an emscripten hack, see AuthUserEmscripten.cpp
{ {
if (session.size()) if (session.size())
{ {

View File

@ -252,7 +252,6 @@ namespace http
method: request.fetchMethod, method: request.fetchMethod,
headers: request.fetchHeaders, headers: request.fetchHeaders,
body: request.fetchBody, body: request.fetchBody,
credentials: 'omit',
signal: request.fetchController.signal, signal: request.fetchController.signal,
}).then(response => { }).then(response => {
request.statusEarly = response.status; request.statusEarly = response.status;
@ -344,18 +343,12 @@ namespace http
handle->responseHeaders.resize(headerCount); handle->responseHeaders.resize(headerCount);
for (auto i = 0; i < headerCount; ++i) for (auto i = 0; i < headerCount; ++i)
{ {
handle->responseHeaders[i].name.resize(EM_ASM_INT({ handle->responseHeaders[i].name = ByteString(std::unique_ptr<char, decltype(&free)>((char *)EM_ASM_PTR({
return lengthBytesUTF8(Module.emscriptenRequestManager.requests[$0].responseHeaders[$1].name); return stringToNewUTF8(Module.emscriptenRequestManager.requests[$0].responseHeaders[$1].name);
}, handle->id, i)); }, handle->id, i), free).get());
EM_ASM({ handle->responseHeaders[i].value = ByteString(std::unique_ptr<char, decltype(&free)>((char *)EM_ASM_PTR({
stringToUTF8(Module.emscriptenRequestManager.requests[$0].responseHeaders[$1].name, $2, $3); return stringToNewUTF8(Module.emscriptenRequestManager.requests[$0].responseHeaders[$1].value);
}, handle->id, i, &handle->responseHeaders[i].name[0], handle->responseHeaders[i].name.size()); }, handle->id, i), free).get());
handle->responseHeaders[i].value.resize(EM_ASM_INT({
return lengthBytesUTF8(Module.emscriptenRequestManager.requests[$0].responseHeaders[$1].value);
}, handle->id, i));
EM_ASM({
stringToUTF8(Module.emscriptenRequestManager.requests[$0].responseHeaders[$1].value, $2, $3);
}, handle->id, i, &handle->responseHeaders[i].value[0], handle->responseHeaders[i].value.size());
} }
handle->gotResponse = true; handle->gotResponse = true;
HandleWake(); HandleWake();

View File

@ -7,6 +7,11 @@ client_files = files(
'GameSave.cpp', 'GameSave.cpp',
'User.cpp', 'User.cpp',
) )
if host_platform == 'emscripten'
client_files += files('AuthUserEmscripten.cpp')
else
client_files += files('AuthUserCommon.cpp')
endif
subdir('http') subdir('http')