diff --git a/client/src/bindings/WebView.cpp b/client/src/bindings/WebView.cpp index 768441a2..86b3521a 100644 --- a/client/src/bindings/WebView.cpp +++ b/client/src/bindings/WebView.cpp @@ -137,7 +137,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK(values.has_value(), "Params are empty"); V8_CHECK(!values->empty(), "Params are empty"); - std::unordered_map headers; + alt::WebViewHeaders headers; + std::vector cookies; int posX = 0; int posY = 0; int sizeX = 0; @@ -189,17 +190,82 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK(headers_opt.has_value(), "headers object is empty"); headers = std::move(headers_opt).value(); } + if (values->contains("cookies")) + { + V8_TO_ARRAY(values->at("cookies"), v8cookies); + auto cookies_opt = V8Helpers::CppValue>(v8cookies); + V8_CHECK(cookies_opt.has_value(), "cookies array is empty"); + for (auto& cookie: cookies_opt.value()) + { + + V8_TO_OBJECT(cookie, v8cookie); + auto cookie_opt = V8Helpers::CppValue>(v8cookie); + V8_CHECK(cookie_opt.has_value(), "cookie object is empty"); + + V8_OBJECT_GET_STRING(v8cookie, "url", cookie_url); + V8_OBJECT_GET_STRING(v8cookie, "name", cookie_name); + V8_OBJECT_GET_STRING(v8cookie, "value", cookie_value); + + V8_CHECK(cookie_name.find("__altv_") == 0, "Cookie name should start with '__altv_'"); + WebViewCookie new_cookie {}; + new_cookie.url = std::move(cookie_url); + new_cookie.name = std::move(cookie_name); + new_cookie.value = std::move(cookie_value); + if (cookie_opt->contains("httpOnly")) + { + V8_TO_BOOLEAN(cookie_opt->at("httpOnly"), v8http_only); + new_cookie.httpOnly = v8http_only; + } + if (cookie_opt->contains("secure")) + { + V8_TO_BOOLEAN(cookie_opt->at("secure"), v8secure); + new_cookie.secure = v8secure; + } + if (cookie_opt->contains("domain")) + { + V8_TO_STRING(cookie_opt->at("domain"), v8domain); + new_cookie.domain = std::move(v8domain); + } + if (cookie_opt->contains("path")) + { + V8_TO_STRING(cookie_opt->at("path"), v8path); + new_cookie.path = std::move(v8path); + } + if (cookie_opt->contains("sameSite")) + { + V8_TO_STRING(cookie_opt->at("sameSite"), v8same_site); + V8_CHECK(v8same_site == "NO_RESTRICTION" || v8same_site == "LAX_MODE" || v8same_site == "STRICT_MODE", + "sameSite value should be one of ['NO_RESTRICTION', 'LAX_MODE', 'STRICT_MODE']"); + new_cookie.sameSite = std::move(v8same_site); + } + if (cookie_opt->contains("priority")) + { + V8_TO_STRING(cookie_opt->at("priority"), v8priority); + V8_CHECK(v8priority == "LOW" || v8priority == "MEDIUM" || v8priority == "HIGH", "priority value should be one of ['LOW', 'MEDIUM', 'HIGH']"); + new_cookie.priority = std::move(v8priority); + } + if (cookie_opt->contains("expires")) + { + V8_TO_INTEGER(cookie_opt->at("expires"), v8expires); + new_cookie.expires = v8expires; + } + + V8_CHECK(!(new_cookie.httpOnly && new_cookie.secure), "HTTP only and secure cannot be combined"); + + cookies.emplace_back(std::move(new_cookie)); + } + } if (onTextureView) { auto texture = alt::ICore::Instance().GetTextureFromDrawable(drawableHash, targetTextureStr); V8_CHECK(texture != nullptr, "Texture not found"); - view = alt::ICore::Instance().CreateWebView(url, (uint32_t)drawableHash, targetTextureStr, altres, headers); + view = alt::ICore::Instance().CreateWebView(url, (uint32_t)drawableHash, targetTextureStr, altres, headers, cookies); V8_CHECK(view, "Interactive WebView cannot be created"); } else { - view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, isOverlay, altres, headers); + view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, isOverlay, altres, headers, cookies); } } else { @@ -279,6 +345,68 @@ static void SetExtraHeader(const v8::FunctionCallbackInfo& info) view->SetExtraHeader(name, value); } +static void SetCookie(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + + V8_GET_THIS_BASE_OBJECT(view, alt::IWebView); + + V8_CHECK_ARGS_LEN(1); + V8_ARG_TO_OBJECT(1, cookie); + + auto cookie_opt = V8Helpers::CppValue>(cookie); + V8_CHECK(cookie_opt.has_value(), "cookie object is empty"); + + V8_OBJECT_GET_STRING(cookie, "url", cookie_url); + V8_OBJECT_GET_STRING(cookie, "name", cookie_name); + V8_OBJECT_GET_STRING(cookie, "value", cookie_value); + + V8_CHECK(cookie_name.find("__altv_") == 0, "Cookie name should start with '__altv_'"); + WebViewCookie new_cookie {}; + new_cookie.url = std::move(cookie_url); + new_cookie.name = std::move(cookie_name); + new_cookie.value = std::move(cookie_value); + if (cookie_opt->contains("httpOnly")) + { + V8_TO_BOOLEAN(cookie_opt->at("httpOnly"), v8http_only); + new_cookie.httpOnly = v8http_only; + } + if (cookie_opt->contains("secure")) + { + V8_TO_BOOLEAN(cookie_opt->at("secure"), v8secure); + new_cookie.secure = v8secure; + } + if (cookie_opt->contains("domain")) + { + V8_TO_STRING(cookie_opt->at("domain"), v8domain); + new_cookie.domain = std::move(v8domain); + } + if (cookie_opt->contains("path")) + { + V8_TO_STRING(cookie_opt->at("path"), v8path); + new_cookie.path = std::move(v8path); + } + if (cookie_opt->contains("sameSite")) + { + V8_TO_STRING(cookie_opt->at("sameSite"), v8same_site); + new_cookie.sameSite = std::move(v8same_site); + } + if (cookie_opt->contains("priority")) + { + V8_TO_STRING(cookie_opt->at("priority"), v8priority); + new_cookie.priority = std::move(v8priority); + } + if (cookie_opt->contains("expires")) + { + V8_TO_INTEGER(cookie_opt->at("expires"), v8expires); + new_cookie.expires = v8expires; + } + + V8_CHECK(!(new_cookie.httpOnly && new_cookie.secure), "HTTP only and secure cannot be combined"); + + view->SetCookie(new_cookie); +} + static void SetZoomLevel(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); @@ -419,6 +547,7 @@ extern V8Class v8WebView("WebView", V8Helpers::SetMethod(isolate, tpl, "unfocus"); V8Helpers::SetMethod(isolate, tpl, "setExtraHeader", &SetExtraHeader); + V8Helpers::SetMethod(isolate, tpl, "setCookie", &SetCookie); V8Helpers::SetMethod(isolate, tpl, "setZoomLevel", &SetZoomLevel); V8Helpers::SetMethod(isolate, tpl, "reload", &Reload); diff --git a/shared/helpers/Macros.h b/shared/helpers/Macros.h index 68d21e3e..2f67a2d3 100644 --- a/shared/helpers/Macros.h +++ b/shared/helpers/Macros.h @@ -126,6 +126,10 @@ v8::Local val; \ V8_CHECK(V8Helpers::SafeToObject((v8Val), ctx, val), "Failed to convert value to object") +#define V8_TO_ARRAY(v8Val, val) \ + v8::Local val; \ + V8_CHECK(V8Helpers::SafeToArray((v8Val), ctx, val), "Failed to convert value to array") + #define V8_TO_VECTOR3(v8Val, val) \ alt::Vector3f val; \ V8_CHECK(V8Helpers::SafeToVector3((v8Val), ctx, val), "Failed to convert value to Vector3")