From 6f3b22de4c756646f015e37bb8781fca2cf603f6 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 29 Aug 2024 15:17:52 +0200 Subject: [PATCH 1/4] SPE 2450: Delete cookies after login to prevent remembering login info Windows only part --- src/slic3r/GUI/Plater.cpp | 12 ++-- src/slic3r/GUI/WebViewDialog.cpp | 27 +++----- src/slic3r/GUI/WebViewDialog.hpp | 9 --- src/slic3r/GUI/WebViewPlatformUtils.hpp | 2 + src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp | 70 +++++++++++++++++++- 5 files changed, 83 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3568b153dd..a80064f99a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -903,15 +903,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #endif // SLIC3R_DESKTOP_INTEGRATION #endif // __linux__ std::string service; - if (evt.GetString().Find("accounts.google.com") != wxString::npos) { + if (evt.GetString().Find(L"accounts.google.com") != wxString::npos) { service = "google"; - } else if (evt.GetString().Find("appleid.apple.com") != wxString::npos) { + } else if (evt.GetString().Find(L"appleid.apple.com") != wxString::npos) { service = "apple"; - } else if (evt.GetString().Find("facebook.com") != wxString::npos) { + } else if (evt.GetString().Find(L"facebook.com") != wxString::npos) { service = "facebook"; } wxString url = user_account->get_login_redirect_url(service); - wxGetApp().open_login_browser_with_dialog(into_u8(url), nullptr, false); + wxGetApp().open_login_browser_with_dialog(into_u8(url)); }; this->q->Bind(EVT_OPEN_EXTERNAL_LOGIN_WIZARD, open_external_login); @@ -928,10 +928,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) sidebar->update_printer_presets_combobox(); wxGetApp().update_wizard_login_page(); this->show_action_buttons(this->ready_to_slice); - // Needed only when using internal web browser to login (which is case of config wizard) - LogoutWebViewDialog dlg(this->q); - dlg.ShowModal(); - // }); this->q->Bind(EVT_UA_ID_USER_SUCCESS, [this](UserAccountSuccessEvent& evt) { diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index f1d4825857..cd09f07196 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -1459,13 +1459,16 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt) { wxString url = evt.GetURL(); if (url.starts_with(L"prusaslicer")) { + delete_cookies(m_browser, L"https://account.prusa3d.com"); + delete_cookies(m_browser, L"https://accounts.google.com"); + delete_cookies(m_browser, L"https://appleid.apple.com"); + delete_cookies(m_browser, L"https://facebook.com"); evt.Veto(); m_ret_val = into_u8(url); EndModal(wxID_OK); - } else if (url.Find("accounts.google.com") != wxString::npos - || url.Find("appleid.apple.com") != wxString::npos - || url.Find("facebook.com") != wxString::npos) - { + } else if (url.Find(L"accounts.google.com") != wxString::npos + || url.Find(L"appleid.apple.com") != wxString::npos + || url.Find(L"facebook.com") != wxString::npos) { auto& sc = Utils::ServiceConfig::instance(); if (!m_evt_sent && !url.starts_with(GUI::from_u8(sc.account_url()))) { wxCommandEvent* evt = new wxCommandEvent(EVT_OPEN_EXTERNAL_LOGIN); @@ -1475,6 +1478,7 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt) } } } + void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect) { const wxSize &size = wxSize(50 * wxGetApp().em_unit(), 80 * wxGetApp().em_unit()); @@ -1482,20 +1486,5 @@ void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect) Fit(); Refresh(); } - -LogoutWebViewDialog::LogoutWebViewDialog(wxWindow *parent) - : WebViewDialog(parent - , GUI::from_u8(Utils::ServiceConfig::instance().account_logout_url()) - , _L("Logout dialog") - , wxSize(std::max(parent->GetClientSize().x / 4, 10 * wxGetApp().em_unit()), std::max(parent->GetClientSize().y / 4, 10 * wxGetApp().em_unit())) - , {}) -{ - Centre(); -} - -void LogoutWebViewDialog::on_loaded(wxWebViewEvent &evt) -{ - EndModal(wxID_OK); -} } // GUI } // Slic3r diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index 3cec6cf48e..7bedf86264 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -282,21 +282,12 @@ 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; - private: std::string& m_ret_val; wxEvtHandler* p_evt_handler; bool m_evt_sent{ false }; }; -class LogoutWebViewDialog : public WebViewDialog -{ -public: - LogoutWebViewDialog(wxWindow* parent); - void on_loaded(wxWebViewEvent &evt) override; - void on_dpi_changed(const wxRect &suggested_rect) override {} -}; - } // GUI } // Slic3r diff --git a/src/slic3r/GUI/WebViewPlatformUtils.hpp b/src/slic3r/GUI/WebViewPlatformUtils.hpp index bd39d0bd32..55fc47b1d9 100644 --- a/src/slic3r/GUI/WebViewPlatformUtils.hpp +++ b/src/slic3r/GUI/WebViewPlatformUtils.hpp @@ -6,4 +6,6 @@ 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 wxString& url); } + diff --git a/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp b/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp index 91ea861272..40bf882d8d 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp +++ b/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp @@ -4,7 +4,6 @@ #include "WebView2.h" #include #include -#include #include #include "wx/msw/private/comptr.h" @@ -13,6 +12,12 @@ #include "format.hpp" #include "Mainframe.hpp" +#include +#include +#include + +namespace pt = boost::property_tree; + namespace Slic3r::GUI { std::unordered_map g_basic_auth_handler_tokens; @@ -20,6 +25,9 @@ std::unordered_map g_basic_auth_handler_t void setup_webview_with_credentials(wxWebView* webview, const std::string& username, const std::string& password) { ICoreWebView2 *webView2 = static_cast(webview->GetNativeBackend()); + if (!webView2) { + return; + } wxCOMPtr wv2_10; HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10)); if (FAILED(hr)) { @@ -59,6 +67,9 @@ void setup_webview_with_credentials(wxWebView* webview, const std::string& usern void remove_webview_credentials(wxWebView* webview) { ICoreWebView2 *webView2 = static_cast(webview->GetNativeBackend()); + if (!webView2) { + return; + } wxCOMPtr wv2_10; HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10)); if (FAILED(hr)) { @@ -78,6 +89,63 @@ void remove_webview_credentials(wxWebView* webview) } } +void delete_cookies(wxWebView* webview, const wxString& url) +{ + ICoreWebView2 *webView2 = static_cast(webview->GetNativeBackend()); + if (!webView2) { + 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](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; + } + BOOST_LOG_TRIVIAL(error) << url << " " << ptree.get_child("cookies").size(); + for (const auto& cookie : ptree.get_child("cookies")) { + std::string name = cookie.second.get("name"); + std::string domain = cookie.second.get("domain"); + //BOOST_LOG_TRIVIAL(debug) << "Deleting cookie: " << name << " : " << domain; + // Delete cookie by name and domain + wxString name_and_domain = GUI::format_wxstr(L"{\"name\": \"%1%\", \"domain\": \"%2%\"}", name, domain); + webView2->CallDevToolsProtocolMethod(L"Network.deleteCookies", name_and_domain.c_str(), + Microsoft::WRL::Callback( + [](HRESULT errorCode, LPCWSTR resultJson) -> HRESULT { return S_OK; }).Get()); + } + } + ).Get()); + +} + } // namespace Slic3r::GUI #endif // WIN32 From 1e55aaef62cb3e0a34c6727f7ad6a76330dd3017 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 2 Sep 2024 12:46:23 +0200 Subject: [PATCH 2/4] SPE 2450: Delete cookies Linux part --- src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp | 54 +++++++++++++++++++- src/slic3r/GUI/WebViewPlatformUtilsMac.mm | 5 ++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp b/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp index a3b7c7bea2..96de4d9d71 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp +++ b/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp @@ -5,6 +5,7 @@ #include #include "WebViewPlatformUtils.hpp" +#include namespace Slic3r::GUI { @@ -55,5 +56,56 @@ void remove_webview_credentials(wxWebView* web_view) g_webview_authorize_handlers.erase(it); } } - +namespace { +void delete_cookie_callback (GObject* source_object, GAsyncResult* result, void* user_data) +{ + WebKitCookieManager *cookie_manager = WEBKIT_COOKIE_MANAGER(source_object); + GError* err = nullptr; + gboolean b = webkit_cookie_manager_delete_cookie_finish(cookie_manager, result, &err); + if (err) { + BOOST_LOG_TRIVIAL(error) << "Error deleting cookies: " << err->message; + g_error_free(err); + return; + } +} +void get_cookie_callback (GObject* source_object, GAsyncResult* result, void* user_data) +{ + GError* err = nullptr; + WebKitCookieManager *cookie_manager = WEBKIT_COOKIE_MANAGER(source_object); + GList * cookies = webkit_cookie_manager_get_cookies_finish(cookie_manager, result, &err); + + if (err) { + BOOST_LOG_TRIVIAL(error) << "Error retrieving cookies: " << err->message; + g_error_free(err); + return; + } + for (GList *l = cookies; l != nullptr; l = l->next) { + SoupCookie *cookie = static_cast(l->data); + /* + printf("Cookie Name: %s\n", cookie->name); + printf("Cookie Value: %s\n", cookie->value); + printf("Domain: %s\n", cookie->domain); + printf("Path: %s\n", cookie->path); + printf("Expires: %s\n", soup_date_to_string(cookie->expires, SOUP_DATE_HTTP)); + printf("Secure: %s\n", cookie->secure ? "true" : "false"); + printf("HTTP Only: %s\n", cookie->http_only ? "true" : "false"); + */ + webkit_cookie_manager_delete_cookie(cookie_manager, cookie, nullptr, (GAsyncReadyCallback)Slic3r::GUI::delete_cookie_callback, nullptr); + soup_cookie_free(cookie); + } + g_list_free(cookies); +} +} +void delete_cookies(wxWebView* web_view, const wxString& url) +{ + // Call webkit_cookie_manager_get_cookies + // set its callback to call webkit_cookie_manager_get_cookies_finish + // then for each cookie call webkit_cookie_manager_delete_cookie + // set callback to call webkit_cookie_manager_delete_cookie_finish + const gchar* uri = url.c_str(); + WebKitWebView* native_backend = static_cast(web_view->GetNativeBackend()); + WebKitWebContext* context= webkit_web_view_get_context(native_backend); + WebKitCookieManager* cookieManager = webkit_web_context_get_cookie_manager(context); + webkit_cookie_manager_get_cookies(cookieManager, uri, nullptr, (GAsyncReadyCallback)Slic3r::GUI::get_cookie_callback, nullptr); +} } diff --git a/src/slic3r/GUI/WebViewPlatformUtilsMac.mm b/src/slic3r/GUI/WebViewPlatformUtilsMac.mm index 123c1e21d7..5522c78c6a 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsMac.mm +++ b/src/slic3r/GUI/WebViewPlatformUtilsMac.mm @@ -137,5 +137,10 @@ void remove_webview_credentials(wxWebView* web_view) } } +void delete_cookies(wxWebView* web_view, const wxString& url) +{ + +} + } From 097ee2e85de60796422723aebfb5c380ae07ff1b Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Sep 2024 10:03:26 +0200 Subject: [PATCH 3/4] SPE 2450: Delete cookies Mac part + fixes of other parts --- src/slic3r/GUI/WebViewDialog.cpp | 8 +++---- src/slic3r/GUI/WebViewPlatformUtils.hpp | 2 +- src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp | 2 +- src/slic3r/GUI/WebViewPlatformUtilsMac.mm | 23 ++++++++++++++++---- src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp | 3 +-- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index cd09f07196..2905a7653d 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -1459,10 +1459,10 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt) { wxString url = evt.GetURL(); if (url.starts_with(L"prusaslicer")) { - delete_cookies(m_browser, L"https://account.prusa3d.com"); - delete_cookies(m_browser, L"https://accounts.google.com"); - delete_cookies(m_browser, L"https://appleid.apple.com"); - delete_cookies(m_browser, L"https://facebook.com"); + delete_cookies(m_browser, "https://account.prusa3d.com"); + delete_cookies(m_browser, "https://accounts.google.com"); + delete_cookies(m_browser, "https://appleid.apple.com"); + delete_cookies(m_browser, "https://facebook.com"); evt.Veto(); m_ret_val = into_u8(url); EndModal(wxID_OK); diff --git a/src/slic3r/GUI/WebViewPlatformUtils.hpp b/src/slic3r/GUI/WebViewPlatformUtils.hpp index 55fc47b1d9..2c1429d21a 100644 --- a/src/slic3r/GUI/WebViewPlatformUtils.hpp +++ b/src/slic3r/GUI/WebViewPlatformUtils.hpp @@ -6,6 +6,6 @@ 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 wxString& url); + void delete_cookies(wxWebView* web_view, const std::string& url); } diff --git a/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp b/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp index 96de4d9d71..b14a561ddf 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp +++ b/src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp @@ -96,7 +96,7 @@ void get_cookie_callback (GObject* source_object, GAsyncResult* result, void* us g_list_free(cookies); } } -void delete_cookies(wxWebView* web_view, const wxString& url) +void delete_cookies(wxWebView* web_view, const std::string& url) { // Call webkit_cookie_manager_get_cookies // set its callback to call webkit_cookie_manager_get_cookies_finish diff --git a/src/slic3r/GUI/WebViewPlatformUtilsMac.mm b/src/slic3r/GUI/WebViewPlatformUtilsMac.mm index 5522c78c6a..b09c69f31f 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsMac.mm +++ b/src/slic3r/GUI/WebViewPlatformUtilsMac.mm @@ -2,6 +2,8 @@ #import #import +#import +#import #import #import @@ -114,7 +116,6 @@ } @end - namespace Slic3r::GUI { void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password) { @@ -137,10 +138,24 @@ void remove_webview_credentials(wxWebView* web_view) } } -void delete_cookies(wxWebView* web_view, const wxString& url) +void delete_cookies(wxWebView* web_view, const std::string& url) { - -} + WKWebView* backend = static_cast(web_view->GetNativeBackend()); + NSString *url_string = [NSString stringWithCString:url.c_str() encoding:[NSString defaultCStringEncoding]]; + WKWebsiteDataStore *data_store = backend.configuration.websiteDataStore; + NSSet *website_data_types = [NSSet setWithObject:WKWebsiteDataTypeCookies]; + [data_store fetchDataRecordsOfTypes:website_data_types completionHandler:^(NSArray *records) { + for (WKWebsiteDataRecord *record in records) { + if ([url_string containsString:record.displayName]) { + [data_store removeDataOfTypes:website_data_types + forDataRecords:@[record] + completionHandler:^{ + //NSLog(@"Deleted cookies for domain: %@", record.displayName); + }]; + } + } + }]; } +} diff --git a/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp b/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp index 40bf882d8d..feb18b52e4 100644 --- a/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp +++ b/src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp @@ -89,7 +89,7 @@ void remove_webview_credentials(wxWebView* webview) } } -void delete_cookies(wxWebView* webview, const wxString& url) +void delete_cookies(wxWebView* webview, const std::string& url) { ICoreWebView2 *webView2 = static_cast(webview->GetNativeBackend()); if (!webView2) { @@ -130,7 +130,6 @@ void delete_cookies(wxWebView* webview, const wxString& url) BOOST_LOG_TRIVIAL(error) << "Failed to parse cookies json: " << e.what(); return S_OK; } - BOOST_LOG_TRIVIAL(error) << url << " " << ptree.get_child("cookies").size(); for (const auto& cookie : ptree.get_child("cookies")) { std::string name = cookie.second.get("name"); std::string domain = cookie.second.get("domain"); From 6d00fcad77789eb1deb153ba1d21447d790abc19 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 4 Sep 2024 12:29:29 +0200 Subject: [PATCH 4/4] SPE 2450: Delete cookies in Config wizard login --- src/slic3r/GUI/ConfigWizardWebViewPage.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/ConfigWizardWebViewPage.cpp b/src/slic3r/GUI/ConfigWizardWebViewPage.cpp index 0023707813..c5fca80faf 100644 --- a/src/slic3r/GUI/ConfigWizardWebViewPage.cpp +++ b/src/slic3r/GUI/ConfigWizardWebViewPage.cpp @@ -7,6 +7,8 @@ #include "slic3r/GUI/I18N.hpp" #include "format.hpp" #include "Event.hpp" +#include "slic3r/GUI/WebViewPlatformUtils.hpp" + #include wxDEFINE_EVENT(EVT_OPEN_EXTERNAL_LOGIN_WIZARD, wxCommandEvent); @@ -123,6 +125,10 @@ void ConfigWizardWebViewPage::on_navigation_request(wxWebViewEvent &evt) { wxString url = evt.GetURL(); if (url.starts_with(L"prusaslicer")) { + delete_cookies(m_browser, "https://account.prusa3d.com"); + delete_cookies(m_browser, "https://accounts.google.com"); + delete_cookies(m_browser, "https://appleid.apple.com"); + delete_cookies(m_browser, "https://facebook.com"); evt.Veto(); m_vetoed = true; wxPostEvent(wxGetApp().plater(), Event(EVT_LOGIN_VIA_WIZARD, into_u8(url)));