SPE 2450: Delete cookies after login to prevent remembering login info

Windows only part
This commit is contained in:
David Kocik 2024-08-29 15:17:52 +02:00 committed by Lukas Matena
parent 75aa6ced63
commit 6f3b22de4c
5 changed files with 83 additions and 37 deletions

View File

@ -903,15 +903,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
#endif // SLIC3R_DESKTOP_INTEGRATION #endif // SLIC3R_DESKTOP_INTEGRATION
#endif // __linux__ #endif // __linux__
std::string service; std::string service;
if (evt.GetString().Find("accounts.google.com") != wxString::npos) { if (evt.GetString().Find(L"accounts.google.com") != wxString::npos) {
service = "google"; 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"; service = "apple";
} else if (evt.GetString().Find("facebook.com") != wxString::npos) { } else if (evt.GetString().Find(L"facebook.com") != wxString::npos) {
service = "facebook"; service = "facebook";
} }
wxString url = user_account->get_login_redirect_url(service); 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); 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(); sidebar->update_printer_presets_combobox();
wxGetApp().update_wizard_login_page(); wxGetApp().update_wizard_login_page();
this->show_action_buttons(this->ready_to_slice); 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) { this->q->Bind(EVT_UA_ID_USER_SUCCESS, [this](UserAccountSuccessEvent& evt) {

View File

@ -1459,13 +1459,16 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt)
{ {
wxString url = evt.GetURL(); wxString url = evt.GetURL();
if (url.starts_with(L"prusaslicer")) { 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(); evt.Veto();
m_ret_val = into_u8(url); m_ret_val = into_u8(url);
EndModal(wxID_OK); EndModal(wxID_OK);
} else if (url.Find("accounts.google.com") != wxString::npos } else if (url.Find(L"accounts.google.com") != wxString::npos
|| url.Find("appleid.apple.com") != wxString::npos || url.Find(L"appleid.apple.com") != wxString::npos
|| url.Find("facebook.com") != wxString::npos) || url.Find(L"facebook.com") != wxString::npos) {
{
auto& sc = Utils::ServiceConfig::instance(); auto& sc = Utils::ServiceConfig::instance();
if (!m_evt_sent && !url.starts_with(GUI::from_u8(sc.account_url()))) { if (!m_evt_sent && !url.starts_with(GUI::from_u8(sc.account_url()))) {
wxCommandEvent* evt = new wxCommandEvent(EVT_OPEN_EXTERNAL_LOGIN); 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) void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
{ {
const wxSize &size = wxSize(50 * wxGetApp().em_unit(), 80 * wxGetApp().em_unit()); 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(); Fit();
Refresh(); 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 } // GUI
} // Slic3r } // Slic3r

View File

@ -282,21 +282,12 @@ public:
LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url, wxEvtHandler* evt_handler); LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url, wxEvtHandler* evt_handler);
void on_navigation_request(wxWebViewEvent &evt) override; void on_navigation_request(wxWebViewEvent &evt) override;
void on_dpi_changed(const wxRect &suggested_rect) override; void on_dpi_changed(const wxRect &suggested_rect) override;
private: private:
std::string& m_ret_val; std::string& m_ret_val;
wxEvtHandler* p_evt_handler; wxEvtHandler* p_evt_handler;
bool m_evt_sent{ false }; 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 } // GUI
} // Slic3r } // Slic3r

View File

@ -6,4 +6,6 @@
namespace Slic3r::GUI { namespace Slic3r::GUI {
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password); void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password);
void remove_webview_credentials(wxWebView* web_view); void remove_webview_credentials(wxWebView* web_view);
void delete_cookies(wxWebView* web_view, const wxString& url);
} }

View File

@ -4,7 +4,6 @@
#include "WebView2.h" #include "WebView2.h"
#include <wrl.h> #include <wrl.h>
#include <atlbase.h> #include <atlbase.h>
#include <boost/log/trivial.hpp>
#include <unordered_map> #include <unordered_map>
#include "wx/msw/private/comptr.h" #include "wx/msw/private/comptr.h"
@ -13,6 +12,12 @@
#include "format.hpp" #include "format.hpp"
#include "Mainframe.hpp" #include "Mainframe.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/log/trivial.hpp>
namespace pt = boost::property_tree;
namespace Slic3r::GUI { namespace Slic3r::GUI {
std::unordered_map<ICoreWebView2*,EventRegistrationToken> g_basic_auth_handler_tokens; std::unordered_map<ICoreWebView2*,EventRegistrationToken> g_basic_auth_handler_tokens;
@ -20,6 +25,9 @@ std::unordered_map<ICoreWebView2*,EventRegistrationToken> g_basic_auth_handler_t
void setup_webview_with_credentials(wxWebView* webview, const std::string& username, const std::string& password) void setup_webview_with_credentials(wxWebView* webview, const std::string& username, const std::string& password)
{ {
ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend()); ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend());
if (!webView2) {
return;
}
wxCOMPtr<ICoreWebView2_10> wv2_10; wxCOMPtr<ICoreWebView2_10> wv2_10;
HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10)); HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10));
if (FAILED(hr)) { if (FAILED(hr)) {
@ -59,6 +67,9 @@ void setup_webview_with_credentials(wxWebView* webview, const std::string& usern
void remove_webview_credentials(wxWebView* webview) void remove_webview_credentials(wxWebView* webview)
{ {
ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend()); ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend());
if (!webView2) {
return;
}
wxCOMPtr<ICoreWebView2_10> wv2_10; wxCOMPtr<ICoreWebView2_10> wv2_10;
HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10)); HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10));
if (FAILED(hr)) { 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<ICoreWebView2 *>(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<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
[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<std::string>("name");
std::string domain = cookie.second.get<std::string>("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<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
[](HRESULT errorCode, LPCWSTR resultJson) -> HRESULT { return S_OK; }).Get());
}
}
).Get());
}
} // namespace Slic3r::GUI } // namespace Slic3r::GUI
#endif // WIN32 #endif // WIN32