diff --git a/Libraries/LibWeb/Internals/Internals.cpp b/Libraries/LibWeb/Internals/Internals.cpp index 339e509c17..1d325944f2 100644 --- a/Libraries/LibWeb/Internals/Internals.cpp +++ b/Libraries/LibWeb/Internals/Internals.cpp @@ -478,6 +478,16 @@ void Internals::expire_cookies_with_time_offset(WebIDL::LongLong seconds) page().client().page_did_expire_cookies_with_time_offset(AK::Duration::from_seconds(seconds)); } +GC::Ref Internals::delete_all_cookies() +{ + auto& realm = this->realm(); + auto promise = WebIDL::create_promise(realm); + auto const& document = as(HTML::relevant_global_object(*this)).associated_document(); + + page().client().page_did_delete_all_cookies(document.url(), promise); + return promise; +} + bool Internals::set_http_memory_cache_enabled(bool enabled) { auto was_enabled = Web::Fetch::Fetching::http_memory_cache_enabled(); diff --git a/Libraries/LibWeb/Internals/Internals.h b/Libraries/LibWeb/Internals/Internals.h index 1aaee21fef..dd65bafc94 100644 --- a/Libraries/LibWeb/Internals/Internals.h +++ b/Libraries/LibWeb/Internals/Internals.h @@ -82,6 +82,7 @@ public: void simulate_drop(double x, double y); void expire_cookies_with_time_offset(WebIDL::LongLong seconds); + GC::Ref delete_all_cookies(); bool set_http_memory_cache_enabled(bool enabled); WebIDL::ExceptionOr set_content_blockers(String const& patterns); diff --git a/Libraries/LibWeb/Internals/Internals.idl b/Libraries/LibWeb/Internals/Internals.idl index 4f8c0e2103..a8e19b0cab 100644 --- a/Libraries/LibWeb/Internals/Internals.idl +++ b/Libraries/LibWeb/Internals/Internals.idl @@ -70,6 +70,7 @@ interface Internals { undefined simulateDrop(double x, double y); undefined expireCookiesWithTimeOffset(long long seconds); + Promise deleteAllCookies(); boolean setHttpMemoryCacheEnabled(boolean enabled); undefined setContentBlockers(DOMString patterns); diff --git a/Libraries/LibWeb/Page/Page.h b/Libraries/LibWeb/Page/Page.h index a18cb2cc32..00d71d3ffa 100644 --- a/Libraries/LibWeb/Page/Page.h +++ b/Libraries/LibWeb/Page/Page.h @@ -481,6 +481,7 @@ public: virtual void page_did_set_cookie(URL::URL const&, HTTP::Cookie::ParsedCookie const&, HTTP::Cookie::Source) { } virtual void page_did_update_cookie(HTTP::Cookie::Cookie const&) { } virtual void page_did_expire_cookies_with_time_offset(AK::Duration) { } + virtual void page_did_delete_all_cookies(URL::URL const&, GC::Ref) { } virtual void page_did_store_hsts_policy(String const&, HTTP::HSTS::ParsedHSTSPolicy const&) { } virtual bool page_did_is_known_hsts_host(String const&) { return false; } virtual Optional page_did_request_storage_item([[maybe_unused]] Web::StorageAPI::StorageEndpointType storage_endpoint, [[maybe_unused]] String const& storage_key, [[maybe_unused]] String const& bottle_key) { return {}; } diff --git a/Libraries/LibWebView/CookieJar.cpp b/Libraries/LibWebView/CookieJar.cpp index 96c9c93dfb..3963bfec65 100644 --- a/Libraries/LibWebView/CookieJar.cpp +++ b/Libraries/LibWebView/CookieJar.cpp @@ -540,6 +540,14 @@ void CookieJar::expire_cookies_with_time_offset(AK::Duration offset) m_transient_storage.purge_expired_cookies(offset); } +void CookieJar::delete_all_cookies(URL::URL const& url) +{ + for (auto& cookie : get_all_cookies_webdriver(url)) { + cookie.expiry_time = UnixDateTime::earliest(); + update_cookie(move(cookie)); + } +} + void CookieJar::expire_cookies_accessed_since(UnixDateTime since) { m_transient_storage.expire_and_purge_cookies_accessed_since(since); diff --git a/Libraries/LibWebView/CookieJar.h b/Libraries/LibWebView/CookieJar.h index b51ac233cc..7d8c5427c4 100644 --- a/Libraries/LibWebView/CookieJar.h +++ b/Libraries/LibWebView/CookieJar.h @@ -48,6 +48,7 @@ public: Vector get_all_cookies_cookiestore(URL::URL const& url); Optional get_named_cookie(URL::URL const& url, StringView name); void expire_cookies_with_time_offset(AK::Duration); + void delete_all_cookies(URL::URL const&); void expire_cookies_accessed_since(UnixDateTime since); Requests::CacheSizes estimate_storage_size_accessed_since(UnixDateTime since) const; diff --git a/Libraries/LibWebView/WebContentClient.cpp b/Libraries/LibWebView/WebContentClient.cpp index d3a6d8d303..95e7c6235f 100644 --- a/Libraries/LibWebView/WebContentClient.cpp +++ b/Libraries/LibWebView/WebContentClient.cpp @@ -982,6 +982,12 @@ void WebContentClient::did_expire_cookies_with_time_offset(AK::Duration offset) Application::cookie_jar().expire_cookies_with_time_offset(offset); } +void WebContentClient::did_request_delete_all_cookies(u64 page_id, u64 request_id, URL::URL url) +{ + Application::cookie_jar().delete_all_cookies(url); + async_did_delete_all_cookies(page_id, request_id); +} + void WebContentClient::did_store_hsts_policy(String domain, HTTP::HSTS::ParsedHSTSPolicy policy) { Application::hsts_store().store_policy(domain, policy); diff --git a/Libraries/LibWebView/WebContentClient.h b/Libraries/LibWebView/WebContentClient.h index 09a255904c..5bb116cbf7 100644 --- a/Libraries/LibWebView/WebContentClient.h +++ b/Libraries/LibWebView/WebContentClient.h @@ -153,6 +153,7 @@ private: virtual void did_set_cookie(URL::URL, HTTP::Cookie::ParsedCookie, HTTP::Cookie::Source) override; virtual void did_update_cookie(HTTP::Cookie::Cookie) override; virtual void did_expire_cookies_with_time_offset(AK::Duration) override; + virtual void did_request_delete_all_cookies(u64 page_id, u64 request_id, URL::URL) override; virtual void did_store_hsts_policy(String, HTTP::HSTS::ParsedHSTSPolicy) override; virtual Messages::WebContentClient::DidIsKnownHstsHostResponse did_is_known_hsts_host(String) override; virtual Messages::WebContentClient::DidRequestStorageItemResponse did_request_storage_item(Web::StorageAPI::StorageEndpointType storage_endpoint, String storage_key, String bottle_key) override; diff --git a/Services/WebContent/ConnectionFromClient.cpp b/Services/WebContent/ConnectionFromClient.cpp index c1f3b5aabf..f7d0ed139f 100644 --- a/Services/WebContent/ConnectionFromClient.cpp +++ b/Services/WebContent/ConnectionFromClient.cpp @@ -2053,6 +2053,12 @@ void ConnectionFromClient::retrieved_clipboard_entries(u64 page_id, u64 request_ page->page().retrieved_clipboard_entries(request_id, move(items)); } +void ConnectionFromClient::did_delete_all_cookies(u64 page_id, u64 request_id) +{ + if (auto page = this->page(page_id); page.has_value()) + page->did_delete_all_cookies(request_id); +} + void ConnectionFromClient::toggle_media_play_state(u64 page_id) { if (auto page = this->page(page_id); page.has_value()) diff --git a/Services/WebContent/ConnectionFromClient.h b/Services/WebContent/ConnectionFromClient.h index 4085d4598e..a63a255381 100644 --- a/Services/WebContent/ConnectionFromClient.h +++ b/Services/WebContent/ConnectionFromClient.h @@ -147,6 +147,7 @@ private: virtual void set_window_size(u64 page_id, Web::DevicePixelSize) override; virtual void did_update_window_rect(u64 page_id) override; virtual void handle_file_return(u64 page_id, i32 error, Optional file, i32 request_id) override; + virtual void did_delete_all_cookies(u64 page_id, u64 request_id) override; virtual void set_system_visibility_state(u64 page_id, Web::HTML::VisibilityState) override; virtual void reset_zoom(u64 page_id) override; diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index 8979c22671..f4e393a966 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -32,11 +32,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -110,6 +112,8 @@ void PageClient::visit_edges(JS::Cell::Visitor& visitor) Base::visit_edges(visitor); visitor.visit(m_page); visitor.visit(m_top_level_document_console_client); + for (auto& promise : m_pending_delete_all_cookies_promises) + visitor.visit(promise.value); m_pending_dom_mutations.for_each([&](auto& pending_mutation) { visitor.visit(pending_mutation.target); }); @@ -634,6 +638,28 @@ void PageClient::page_did_expire_cookies_with_time_offset(AK::Duration offset) document->reset_cookie_version(); } +void PageClient::page_did_delete_all_cookies(URL::URL const& url, GC::Ref promise) +{ + auto request_id = m_next_delete_all_cookies_request_id++; + m_pending_delete_all_cookies_promises.set(request_id, promise); + client().async_did_request_delete_all_cookies(m_id, request_id, url); + + if (auto* document = page().top_level_browsing_context().active_document()) + document->reset_cookie_version(); +} + +void PageClient::did_delete_all_cookies(u64 request_id) +{ + auto maybe_promise = m_pending_delete_all_cookies_promises.take(request_id); + if (!maybe_promise.has_value()) + return; + + auto promise = maybe_promise.release_value(); + auto& realm = promise->promise()->shape().realm(); + Web::HTML::TemporaryExecutionContext execution_context { realm, Web::HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; + Web::WebIDL::resolve_promise(realm, promise); +} + void PageClient::page_did_store_hsts_policy(String const& domain, HTTP::HSTS::ParsedHSTSPolicy const& policy) { client().async_did_store_hsts_policy(domain, policy); diff --git a/Services/WebContent/PageClient.h b/Services/WebContent/PageClient.h index 99196e2799..4eb01d7551 100644 --- a/Services/WebContent/PageClient.h +++ b/Services/WebContent/PageClient.h @@ -112,6 +112,7 @@ public: void queue_screenshot_task(Optional node_id); void send_current_needs_beforeunload_check(); void clear_pending_dom_mutations(); + void did_delete_all_cookies(u64 request_id); private: struct PendingDOMMutation { @@ -179,6 +180,7 @@ private: virtual void page_did_set_cookie(URL::URL const&, HTTP::Cookie::ParsedCookie const&, HTTP::Cookie::Source) override; virtual void page_did_update_cookie(HTTP::Cookie::Cookie const&) override; virtual void page_did_expire_cookies_with_time_offset(AK::Duration) override; + virtual void page_did_delete_all_cookies(URL::URL const&, GC::Ref) override; virtual void page_did_store_hsts_policy(String const&, HTTP::HSTS::ParsedHSTSPolicy const&) override; virtual bool page_did_is_known_hsts_host(String const&) override; virtual Optional page_did_request_storage_item(Web::StorageAPI::StorageEndpointType storage_endpoint, String const& storage_key, String const& bottle_key) override; @@ -235,6 +237,8 @@ private: double m_zoom_level { 1.0 }; double m_maximum_frames_per_second { 60.0 }; u64 m_id { 0 }; + u64 m_next_delete_all_cookies_request_id { 1 }; + HashMap> m_pending_delete_all_cookies_promises; bool m_has_focus { true }; Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto }; diff --git a/Services/WebContent/WebContentClient.ipc b/Services/WebContent/WebContentClient.ipc index f19c497f3c..59419fe280 100644 --- a/Services/WebContent/WebContentClient.ipc +++ b/Services/WebContent/WebContentClient.ipc @@ -96,6 +96,7 @@ endpoint WebContentClient did_set_cookie(URL::URL url, HTTP::Cookie::ParsedCookie cookie, HTTP::Cookie::Source source) => () did_update_cookie(HTTP::Cookie::Cookie cookie) =| did_expire_cookies_with_time_offset(AK::Duration offset) =| + did_request_delete_all_cookies(u64 page_id, u64 request_id, URL::URL url) =| did_store_hsts_policy(String domain, HTTP::HSTS::ParsedHSTSPolicy policy) =| did_is_known_hsts_host(String domain) => (bool result) diff --git a/Services/WebContent/WebContentServer.ipc b/Services/WebContent/WebContentServer.ipc index 11b9036a58..3c43ef68d5 100644 --- a/Services/WebContent/WebContentServer.ipc +++ b/Services/WebContent/WebContentServer.ipc @@ -138,6 +138,7 @@ endpoint WebContentServer reset_zoom(u64 page_id) =| handle_file_return(u64 page_id, i32 error, Optional file, i32 request_id) =| + did_delete_all_cookies(u64 page_id, u64 request_id) =| set_system_visibility_state(u64 page_id, Web::HTML::VisibilityState visibility_state) =| diff --git a/Tests/LibWeb/Text/input/wpt-import/resources/testdriver-vendor.js b/Tests/LibWeb/Text/input/wpt-import/resources/testdriver-vendor.js index 4afab4489a..4bb213f575 100644 --- a/Tests/LibWeb/Text/input/wpt-import/resources/testdriver-vendor.js +++ b/Tests/LibWeb/Text/input/wpt-import/resources/testdriver-vendor.js @@ -21,6 +21,10 @@ window.test_driver_internal.get_computed_role = async function(element) { return await window.internals.getComputedRole(element); }; +window.test_driver_internal.delete_all_cookies = function(context) { + return window.internals.deleteAllCookies(); +}; + window.test_driver_internal.action_sequence = function(actions, context) { // Modifier key codes from WebDriver spec const SHIFT = "\uE008";