diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 905c27bb8b..e3cd03cde9 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -693,19 +693,28 @@ LoginWebViewDialog::LoginWebViewDialog(wxWindow *parent, std::string &ret_val, c , m_ret_val(ret_val) , p_evt_handler(evt_handler) { + m_force_quit_timer.SetOwner(this, 0); + Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) + { + m_force_quit = true; + }); Centre(); } void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt) { wxString url = evt.GetURL(); if (url.starts_with(L"prusaslicer")) { - delete_cookies(m_browser, Utils::ServiceConfig::instance().account_url()); - delete_cookies(m_browser, "https://accounts.google.com"); - delete_cookies(m_browser, "https://appleid.apple.com"); - delete_cookies(m_browser, "https://facebook.com"); + m_waiting_for_counters = true; + m_atomic_counter = 0; + m_counter_to_match = 4; + delete_cookies_with_counter(m_browser, Utils::ServiceConfig::instance().account_url(), m_atomic_counter); + delete_cookies_with_counter(m_browser, "https://accounts.google.com", m_atomic_counter); + delete_cookies_with_counter(m_browser, "https://appleid.apple.com", m_atomic_counter); + delete_cookies_with_counter(m_browser, "https://facebook.com", m_atomic_counter); evt.Veto(); m_ret_val = into_u8(url); - EndModal(wxID_OK); + m_force_quit_timer.Start(2000, wxTIMER_ONE_SHOT); + // End modal is moved to on_idle } else if (url.Find(L"accounts.google.com") != wxNOT_FOUND || url.Find(L"appleid.apple.com") != wxNOT_FOUND || url.Find(L"facebook.com") != wxNOT_FOUND) { @@ -726,5 +735,36 @@ void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect) Fit(); Refresh(); } + +void LoginWebViewDialog::on_idle(wxIdleEvent& WXUNUSED(evt)) +{ + if (!m_browser) + return; + if (m_browser->IsBusy()) { + if constexpr (!is_linux) { + wxSetCursor(wxCURSOR_ARROWWAIT); + } + } else { + if constexpr (!is_linux) { + wxSetCursor(wxNullCursor); + } + if (m_load_error_page) { + m_load_error_page = false; + m_browser->LoadURL(GUI::format_wxstr("file://%1%/web/error_no_reload.html", boost::filesystem::path(resources_dir()).generic_string())); + } + if (m_waiting_for_counters && m_atomic_counter == m_counter_to_match) + { + EndModal(wxID_OK); + } + if (m_force_quit) + { + EndModal(wxID_OK); + } + } +#ifdef DEBUG_URL_PANEL + m_button_stop->Enable(m_browser->IsBusy()); +#endif +} + } // GUI } // Slic3r diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index e7d4c529d8..1ed91f666e 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -13,6 +13,8 @@ #include #endif +#include + class wxWebView; class wxWebViewEvent; @@ -30,7 +32,7 @@ public: virtual void on_show(wxShowEvent& evt) {}; virtual void on_script_message(wxWebViewEvent& evt); - void on_idle(wxIdleEvent& evt); + virtual void on_idle(wxIdleEvent& evt); void on_url(wxCommandEvent& evt); void on_back_button(wxCommandEvent& evt); void on_forward_button(wxCommandEvent& evt); @@ -124,7 +126,7 @@ protected: void on_reload_event(const std::string& message_data) override; void run_script_bridge(const wxString &script) override { run_script(script); } void on_connect_action_close_dialog(const std::string& message_data) override; -}; + }; class LoginWebViewDialog : public WebViewDialog { @@ -132,10 +134,17 @@ public: LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url, wxEvtHandler* evt_handler); void on_navigation_request(wxWebViewEvent &evt) override; void on_dpi_changed(const wxRect &suggested_rect) override; + void on_idle(wxIdleEvent& evt) override; private: std::string& m_ret_val; wxEvtHandler* p_evt_handler; bool m_evt_sent{ false }; + + bool m_waiting_for_counters {false}; + std::atomic m_atomic_counter; + size_t m_counter_to_match; + wxTimer m_force_quit_timer; + bool m_force_quit{false}; }; } // GUI diff --git a/src/slic3r/GUI/WebViewPlatformUtils.hpp b/src/slic3r/GUI/WebViewPlatformUtils.hpp index f6d5a8b2ed..b9ff741612 100644 --- a/src/slic3r/GUI/WebViewPlatformUtils.hpp +++ b/src/slic3r/GUI/WebViewPlatformUtils.hpp @@ -2,11 +2,12 @@ #include #include - +#include namespace Slic3r::GUI { void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password); void remove_webview_credentials(wxWebView* web_view); void delete_cookies(wxWebView* web_view, const std::string& url); + void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic& counter); void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token); void remove_request_authorization(wxWebView* web_view); void load_request(wxWebView* web_view, const std::string& address, const std::string& token); diff --git a/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp b/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp index f5ffd8bc62..66ad4fc698 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp +++ b/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp @@ -109,6 +109,12 @@ void delete_cookies(wxWebView* web_view, const std::string& url) webkit_cookie_manager_get_cookies(cookieManager, uri, nullptr, (GAsyncReadyCallback)Slic3r::GUI::get_cookie_callback, nullptr); } +void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic& counter) +{ + delete_cookies(web_view, url); + counter++; +} + void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token) { // unused on Linux diff --git a/src/slic3r/GUI/WebViewPlatformUtilsMac.mm b/src/slic3r/GUI/WebViewPlatformUtilsMac.mm index ad04db60d2..feda9eab3d 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsMac.mm +++ b/src/slic3r/GUI/WebViewPlatformUtilsMac.mm @@ -156,6 +156,13 @@ void delete_cookies(wxWebView* web_view, const std::string& url) } }]; } + +void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic& counter) +{ + delete_cookies(web_view, url); + counter++; +} + void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token) { // unused on MacOS diff --git a/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp b/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp index 08fbedcb72..a03a573965 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp +++ b/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp @@ -150,7 +150,78 @@ void delete_cookies(wxWebView* webview, const std::string& url) ).Get()); } +void delete_cookies_with_counter(wxWebView* webview, const std::string& url, std::atomic& counter) +{ + ICoreWebView2 *webView2 = static_cast(webview->GetNativeBackend()); + if (!webView2) { + BOOST_LOG_TRIVIAL(error) << "delete_cookies Failed: webView2 is null."; + return; + } + /* + "cookies": [{ + "domain": ".google.com", + "expires": 1756464458.304917, + "httpOnly": true, + "name": "__Secure-1PSIDCC", + "path": "/", + "priority": "High", + "sameParty": false, + "secure": true, + "session": false, + "size": 90, + "sourcePort": 443, + "sourceScheme": "Secure", + "value": "AKEyXzUvV_KBqM4aOlsudROI_VZ-ToIH41LRbYJFtFjmKq_rOmx1owoyUGvQHbwr5be380fKuQ" + },...]} + */ + wxString parameters = GUI::format_wxstr(L"{\"urls\": [\"%1%\"]}", url); + webView2->CallDevToolsProtocolMethod(L"Network.getCookies", parameters.c_str(), + Microsoft::WRL::Callback( + [webView2, url, &counter](HRESULT errorCode, LPCWSTR resultJson) -> HRESULT { + if (FAILED(errorCode)) { + return S_OK; + } + // Handle successful call (resultJson contains the list of cookies) + pt::ptree ptree; + try { + std::stringstream ss(GUI::into_u8(resultJson)); + pt::read_json(ss, ptree); + } + catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "Failed to parse cookies json: " << e.what(); + return S_OK; + } + auto& cookies = ptree.get_child("cookies"); + if (cookies.size() == 0) { + counter++; + return S_OK; + } + for (auto it = cookies.begin(); it != cookies.end(); ++it) { + const auto& cookie = *it; + std::string name = cookie.second.get("name"); + std::string domain = cookie.second.get("domain"); + // Delete cookie by name and domain + wxString name_and_domain = GUI::format_wxstr(L"{\"name\": \"%1%\", \"domain\": \"%2%\"}", name, domain); + BOOST_LOG_TRIVIAL(debug) << "Deleting cookie: " << name_and_domain; + bool last = false; + if (std::next(it) == cookies.end()) { + last = true; + } + webView2->CallDevToolsProtocolMethod(L"Network.deleteCookies", name_and_domain.c_str(), + Microsoft::WRL::Callback( + [last, &counter](HRESULT errorCode, LPCWSTR resultJson) -> HRESULT { + if (last) { + counter++; + } + return S_OK; + }).Get()); + } + return S_OK; + } + ).Get()); + +} static EventRegistrationToken m_webResourceRequestedTokenForImageBlocking = {}; static wxString filter_patern; namespace {