1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:28:11 +00:00

Browser+LibWeb+WebContent: Store cookie expiry times in UTC

We are currently converting parsed expiry times to local time, whereas
the RFC dictates we parse them as UTC. When expiring cookies, we must
also use the current UTC time to compare against the cookies' expiry
times.
This commit is contained in:
Timothy Flynn 2023-02-24 11:51:56 -05:00 committed by Tim Flynn
parent 1858163d3c
commit 87c4080d00
8 changed files with 83 additions and 47 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021-2022, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2022, the SerenityOS developers. * Copyright (c) 2022, the SerenityOS developers.
* Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
* *
@ -11,6 +11,7 @@
#include <AK/IPv4Address.h> #include <AK/IPv4Address.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/StringView.h> #include <AK/StringView.h>
#include <AK/Time.h>
#include <AK/URL.h> #include <AK/URL.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibCore/Promise.h> #include <LibCore/Promise.h>
@ -140,9 +141,9 @@ void CookieJar::dump_cookies()
builder.appendff("{}{}{}\n", key_color, cookie.path, no_color); builder.appendff("{}{}{}\n", key_color, cookie.path, no_color);
builder.appendff("\t{}Value{} = {}\n", attribute_color, no_color, cookie.value); builder.appendff("\t{}Value{} = {}\n", attribute_color, no_color, cookie.value);
builder.appendff("\t{}CreationTime{} = {}\n", attribute_color, no_color, cookie.creation_time.to_deprecated_string()); builder.appendff("\t{}CreationTime{} = {}\n", attribute_color, no_color, cookie.creation_time_to_string());
builder.appendff("\t{}LastAccessTime{} = {}\n", attribute_color, no_color, cookie.last_access_time.to_deprecated_string()); builder.appendff("\t{}LastAccessTime{} = {}\n", attribute_color, no_color, cookie.last_access_time_to_string());
builder.appendff("\t{}ExpiryTime{} = {}\n", attribute_color, no_color, cookie.expiry_time.to_deprecated_string()); builder.appendff("\t{}ExpiryTime{} = {}\n", attribute_color, no_color, cookie.expiry_time_to_string());
builder.appendff("\t{}Secure{} = {:s}\n", attribute_color, no_color, cookie.secure); builder.appendff("\t{}Secure{} = {:s}\n", attribute_color, no_color, cookie.secure);
builder.appendff("\t{}HttpOnly{} = {:s}\n", attribute_color, no_color, cookie.http_only); builder.appendff("\t{}HttpOnly{} = {:s}\n", attribute_color, no_color, cookie.http_only);
builder.appendff("\t{}HostOnly{} = {:s}\n", attribute_color, no_color, cookie.host_only); builder.appendff("\t{}HostOnly{} = {:s}\n", attribute_color, no_color, cookie.host_only);
@ -275,7 +276,7 @@ void CookieJar::store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, con
// 2. Create a new cookie with name cookie-name, value cookie-value. Set the creation-time and the last-access-time to the current date and time. // 2. Create a new cookie with name cookie-name, value cookie-value. Set the creation-time and the last-access-time to the current date and time.
Web::Cookie::Cookie cookie { parsed_cookie.name, parsed_cookie.value, parsed_cookie.same_site_attribute }; Web::Cookie::Cookie cookie { parsed_cookie.name, parsed_cookie.value, parsed_cookie.same_site_attribute };
cookie.creation_time = Core::DateTime::now(); cookie.creation_time = Time::now_realtime();
cookie.last_access_time = cookie.creation_time; cookie.last_access_time = cookie.creation_time;
if (parsed_cookie.expiry_time_from_max_age_attribute.has_value()) { if (parsed_cookie.expiry_time_from_max_age_attribute.has_value()) {
@ -289,9 +290,9 @@ void CookieJar::store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, con
cookie.persistent = true; cookie.persistent = true;
cookie.expiry_time = parsed_cookie.expiry_time_from_expires_attribute.value(); cookie.expiry_time = parsed_cookie.expiry_time_from_expires_attribute.value();
} else { } else {
// Set the cookie's persistent-flag to false. Set the cookie's expiry-time to the latest representable gddate. // Set the cookie's persistent-flag to false. Set the cookie's expiry-time to the latest representable date.
cookie.persistent = false; cookie.persistent = false;
cookie.expiry_time = Core::DateTime::create(9999, 12, 31, 23, 59, 59); cookie.expiry_time = Time::max();
} }
// 4. If the cookie-attribute-list contains an attribute with an attribute-name of "Domain": // 4. If the cookie-attribute-list contains an attribute with an attribute-name of "Domain":
@ -396,13 +397,13 @@ Vector<Web::Cookie::Cookie> CookieJar::get_matching_cookies(const URL& url, Depr
// - Cookies with longer paths are listed before cookies with shorter paths. // - Cookies with longer paths are listed before cookies with shorter paths.
// - Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times. // - Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times.
auto cookie_path_length = cookie.path.length(); auto cookie_path_length = cookie.path.length();
auto cookie_creation_time = cookie.creation_time.timestamp(); auto cookie_creation_time = cookie.creation_time;
cookie_list.insert_before_matching(move(cookie), [cookie_path_length, cookie_creation_time](auto const& entry) { cookie_list.insert_before_matching(move(cookie), [cookie_path_length, cookie_creation_time](auto const& entry) {
if (cookie_path_length > entry.path.length()) { if (cookie_path_length > entry.path.length()) {
return true; return true;
} else if (cookie_path_length == entry.path.length()) { } else if (cookie_path_length == entry.path.length()) {
if (cookie_creation_time < entry.creation_time.timestamp()) if (cookie_creation_time < entry.creation_time)
return true; return true;
} }
return false; return false;
@ -410,7 +411,7 @@ Vector<Web::Cookie::Cookie> CookieJar::get_matching_cookies(const URL& url, Depr
}); });
// 3. Update the last-access-time of each cookie in the cookie-list to the current date and time. // 3. Update the last-access-time of each cookie in the cookie-list to the current date and time.
auto now = Core::DateTime::now(); auto now = Time::now_realtime();
for (auto& cookie : cookie_list) { for (auto& cookie : cookie_list) {
cookie.last_access_time = now; cookie.last_access_time = now;
@ -450,8 +451,8 @@ static ErrorOr<Web::Cookie::Cookie> parse_cookie(ReadonlySpan<SQL::Value> row)
if (value.type() != SQL::SQLType::Integer) if (value.type() != SQL::SQLType::Integer)
return Error::from_string_view(name); return Error::from_string_view(name);
auto time = value.to_int<time_t>().value(); auto time = value.to_int<i64>().value();
field = Core::DateTime::from_timestamp(time); field = Time::from_seconds(time);
return {}; return {};
}; };
@ -492,9 +493,9 @@ void CookieJar::insert_cookie_into_database(Web::Cookie::Cookie const& cookie)
cookie.name, cookie.name,
cookie.value, cookie.value,
to_underlying(cookie.same_site), to_underlying(cookie.same_site),
cookie.creation_time.timestamp(), cookie.creation_time.to_seconds(),
cookie.last_access_time.timestamp(), cookie.last_access_time.to_seconds(),
cookie.expiry_time.timestamp(), cookie.expiry_time.to_seconds(),
cookie.domain, cookie.domain,
cookie.path, cookie.path,
cookie.secure, cookie.secure,
@ -509,9 +510,9 @@ void CookieJar::update_cookie_in_database(Web::Cookie::Cookie const& cookie)
m_statements.update_cookie, {}, [this]() { purge_expired_cookies(); }, {}, m_statements.update_cookie, {}, [this]() { purge_expired_cookies(); }, {},
cookie.value, cookie.value,
to_underlying(cookie.same_site), to_underlying(cookie.same_site),
cookie.creation_time.timestamp(), cookie.creation_time.to_seconds(),
cookie.last_access_time.timestamp(), cookie.last_access_time.to_seconds(),
cookie.expiry_time.timestamp(), cookie.expiry_time.to_seconds(),
cookie.secure, cookie.secure,
cookie.http_only, cookie.http_only,
cookie.host_only, cookie.host_only,
@ -581,7 +582,8 @@ void CookieJar::select_all_cookies_from_database(OnSelectAllCookiesResult on_res
void CookieJar::purge_expired_cookies() void CookieJar::purge_expired_cookies()
{ {
auto now = Core::DateTime::now().timestamp(); auto now = Time::now_realtime().to_seconds();
m_database.execute_statement(m_statements.expire_cookie, {}, {}, {}, now); m_database.execute_statement(m_statements.expire_cookie, {}, {}, {}, now);
} }
} }

View file

@ -80,7 +80,7 @@ GUI::Variant CookiesModel::data(GUI::ModelIndex const& index, GUI::ModelRole rol
case Column::Value: case Column::Value:
return cookie.value; return cookie.value;
case Column::ExpiryTime: case Column::ExpiryTime:
return cookie.expiry_time.to_deprecated_string(); return cookie.expiry_time_to_string();
case Column::SameSite: case Column::SameSite:
return Web::Cookie::same_site_to_string(cookie.same_site); return Web::Cookie::same_site_to_string(cookie.same_site);
} }

View file

@ -130,7 +130,7 @@ void StorageWidget::clear_session_storage_entries()
void StorageWidget::delete_cookie(Web::Cookie::Cookie cookie) void StorageWidget::delete_cookie(Web::Cookie::Cookie cookie)
{ {
// Delete cookie by making its expiry time in the past. // Delete cookie by making its expiry time in the past.
cookie.expiry_time = Core::DateTime::from_timestamp(0); cookie.expiry_time = Time::from_seconds(0);
if (on_update_cookie) if (on_update_cookie)
on_update_cookie(move(cookie)); on_update_cookie(move(cookie));
} }

View file

@ -1,15 +1,38 @@
/* /*
* Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include "Cookie.h" #include "Cookie.h"
#include <LibCore/DateTime.h>
#include <LibIPC/Decoder.h> #include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h> #include <LibIPC/Encoder.h>
namespace Web::Cookie { namespace Web::Cookie {
static DeprecatedString time_to_string(Time const& time)
{
auto local_time = Core::DateTime::from_timestamp(time.to_seconds());
return local_time.to_deprecated_string("%Y-%m-%d %H:%M:%S %Z"sv);
}
DeprecatedString Cookie::creation_time_to_string() const
{
return time_to_string(creation_time);
}
DeprecatedString Cookie::last_access_time_to_string() const
{
return time_to_string(last_access_time);
}
DeprecatedString Cookie::expiry_time_to_string() const
{
return time_to_string(expiry_time);
}
StringView same_site_to_string(SameSite same_site) StringView same_site_to_string(SameSite same_site)
{ {
switch (same_site) { switch (same_site) {
@ -64,11 +87,11 @@ ErrorOr<Web::Cookie::Cookie> IPC::decode(Decoder& decoder)
auto value = TRY(decoder.decode<DeprecatedString>()); auto value = TRY(decoder.decode<DeprecatedString>());
auto domain = TRY(decoder.decode<DeprecatedString>()); auto domain = TRY(decoder.decode<DeprecatedString>());
auto path = TRY(decoder.decode<DeprecatedString>()); auto path = TRY(decoder.decode<DeprecatedString>());
auto creation_time = TRY(decoder.decode<Core::DateTime>()); auto creation_time = TRY(decoder.decode<Time>());
auto expiry_time = TRY(decoder.decode<Core::DateTime>()); auto expiry_time = TRY(decoder.decode<Time>());
auto host_only = TRY(decoder.decode<bool>()); auto host_only = TRY(decoder.decode<bool>());
auto http_only = TRY(decoder.decode<bool>()); auto http_only = TRY(decoder.decode<bool>());
auto last_access_time = TRY(decoder.decode<Core::DateTime>()); auto last_access_time = TRY(decoder.decode<Time>());
auto persistent = TRY(decoder.decode<bool>()); auto persistent = TRY(decoder.decode<bool>());
auto secure = TRY(decoder.decode<bool>()); auto secure = TRY(decoder.decode<bool>());
auto same_site = TRY(decoder.decode<Web::Cookie::SameSite>()); auto same_site = TRY(decoder.decode<Web::Cookie::SameSite>());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -7,7 +7,7 @@
#pragma once #pragma once
#include <AK/DeprecatedString.h> #include <AK/DeprecatedString.h>
#include <LibCore/DateTime.h> #include <AK/Time.h>
#include <LibIPC/Forward.h> #include <LibIPC/Forward.h>
namespace Web::Cookie { namespace Web::Cookie {
@ -25,12 +25,16 @@ enum class Source {
}; };
struct Cookie { struct Cookie {
DeprecatedString creation_time_to_string() const;
DeprecatedString last_access_time_to_string() const;
DeprecatedString expiry_time_to_string() const;
DeprecatedString name; DeprecatedString name;
DeprecatedString value; DeprecatedString value;
SameSite same_site; SameSite same_site;
Core::DateTime creation_time {}; Time creation_time {};
Core::DateTime last_access_time {}; Time last_access_time {};
Core::DateTime expiry_time {}; Time expiry_time {};
DeprecatedString domain {}; DeprecatedString domain {};
DeprecatedString path {}; DeprecatedString path {};
bool secure { false }; bool secure { false };

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -8,6 +8,7 @@
#include <AK/DateConstants.h> #include <AK/DateConstants.h>
#include <AK/Function.h> #include <AK/Function.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/Time.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibIPC/Decoder.h> #include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h> #include <LibIPC/Encoder.h>
@ -26,7 +27,7 @@ static void on_path_attribute(ParsedCookie& parsed_cookie, StringView attribute_
static void on_secure_attribute(ParsedCookie& parsed_cookie); static void on_secure_attribute(ParsedCookie& parsed_cookie);
static void on_http_only_attribute(ParsedCookie& parsed_cookie); static void on_http_only_attribute(ParsedCookie& parsed_cookie);
static void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_value); static void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_value);
static Optional<Core::DateTime> parse_date_time(StringView date_string); static Optional<Time> parse_date_time(StringView date_string);
Optional<ParsedCookie> parse_cookie(DeprecatedString const& cookie_string) Optional<ParsedCookie> parse_cookie(DeprecatedString const& cookie_string)
{ {
@ -153,7 +154,7 @@ void on_expires_attribute(ParsedCookie& parsed_cookie, StringView attribute_valu
{ {
// https://tools.ietf.org/html/rfc6265#section-5.2.1 // https://tools.ietf.org/html/rfc6265#section-5.2.1
if (auto expiry_time = parse_date_time(attribute_value); expiry_time.has_value()) if (auto expiry_time = parse_date_time(attribute_value); expiry_time.has_value())
parsed_cookie.expiry_time_from_expires_attribute = move(*expiry_time); parsed_cookie.expiry_time_from_expires_attribute = expiry_time.release_value();
} }
void on_max_age_attribute(ParsedCookie& parsed_cookie, StringView attribute_value) void on_max_age_attribute(ParsedCookie& parsed_cookie, StringView attribute_value)
@ -168,11 +169,10 @@ void on_max_age_attribute(ParsedCookie& parsed_cookie, StringView attribute_valu
if (auto delta_seconds = attribute_value.to_int(); delta_seconds.has_value()) { if (auto delta_seconds = attribute_value.to_int(); delta_seconds.has_value()) {
if (*delta_seconds <= 0) { if (*delta_seconds <= 0) {
// If delta-seconds is less than or equal to zero (0), let expiry-time be the earliest representable date and time. // If delta-seconds is less than or equal to zero (0), let expiry-time be the earliest representable date and time.
parsed_cookie.expiry_time_from_max_age_attribute = Core::DateTime::from_timestamp(0); parsed_cookie.expiry_time_from_max_age_attribute = Time::min();
} else { } else {
// Otherwise, let the expiry-time be the current date and time plus delta-seconds seconds. // Otherwise, let the expiry-time be the current date and time plus delta-seconds seconds.
time_t now = Core::DateTime::now().timestamp(); parsed_cookie.expiry_time_from_max_age_attribute = Time::now_realtime() + Time::from_seconds(*delta_seconds);
parsed_cookie.expiry_time_from_max_age_attribute = Core::DateTime::from_timestamp(now + *delta_seconds);
} }
} }
} }
@ -236,7 +236,7 @@ void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_va
parsed_cookie.same_site_attribute = same_site_from_string(attribute_value); parsed_cookie.same_site_attribute = same_site_from_string(attribute_value);
} }
Optional<Core::DateTime> parse_date_time(StringView date_string) Optional<Time> parse_date_time(StringView date_string)
{ {
// https://tools.ietf.org/html/rfc6265#section-5.1.1 // https://tools.ietf.org/html/rfc6265#section-5.1.1
unsigned hour = 0; unsigned hour = 0;
@ -341,8 +341,14 @@ Optional<Core::DateTime> parse_date_time(StringView date_string)
if (second > 59) if (second > 59)
return {}; return {};
// 6. Let the parsed-cookie-date be the date whose day-of-month, month, year, hour, minute, and second (in UTC) are the
// day-of-month-value, the month-value, the year-value, the hour-value, the minute-value, and the second-value, respectively.
// If no such date exists, abort these steps and fail to parse the cookie-date.
// FIXME: Fail on dates that do not exist. // FIXME: Fail on dates that do not exist.
return Core::DateTime::create(year, month, day_of_month, hour, minute, second); auto parsed_cookie_date = Time::from_timestamp(year, month, day_of_month, hour, minute, second, 0);
// 7. Return the parsed-cookie-date as the result of this algorithm.
return parsed_cookie_date;
} }
} }
@ -368,8 +374,8 @@ ErrorOr<Web::Cookie::ParsedCookie> IPC::decode(Decoder& decoder)
{ {
auto name = TRY(decoder.decode<DeprecatedString>()); auto name = TRY(decoder.decode<DeprecatedString>());
auto value = TRY(decoder.decode<DeprecatedString>()); auto value = TRY(decoder.decode<DeprecatedString>());
auto expiry_time_from_expires_attribute = TRY(decoder.decode<Optional<Core::DateTime>>()); auto expiry_time_from_expires_attribute = TRY(decoder.decode<Optional<Time>>());
auto expiry_time_from_max_age_attribute = TRY(decoder.decode<Optional<Core::DateTime>>()); auto expiry_time_from_max_age_attribute = TRY(decoder.decode<Optional<Time>>());
auto domain = TRY(decoder.decode<Optional<DeprecatedString>>()); auto domain = TRY(decoder.decode<Optional<DeprecatedString>>());
auto path = TRY(decoder.decode<Optional<DeprecatedString>>()); auto path = TRY(decoder.decode<Optional<DeprecatedString>>());
auto secure_attribute_present = TRY(decoder.decode<bool>()); auto secure_attribute_present = TRY(decoder.decode<bool>());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -8,7 +8,7 @@
#include <AK/DeprecatedString.h> #include <AK/DeprecatedString.h>
#include <AK/Optional.h> #include <AK/Optional.h>
#include <LibCore/DateTime.h> #include <AK/Time.h>
#include <LibIPC/Forward.h> #include <LibIPC/Forward.h>
#include <LibWeb/Cookie/Cookie.h> #include <LibWeb/Cookie/Cookie.h>
@ -18,8 +18,8 @@ struct ParsedCookie {
DeprecatedString name; DeprecatedString name;
DeprecatedString value; DeprecatedString value;
SameSite same_site_attribute { SameSite::Default }; SameSite same_site_attribute { SameSite::Default };
Optional<Core::DateTime> expiry_time_from_expires_attribute {}; Optional<Time> expiry_time_from_expires_attribute {};
Optional<Core::DateTime> expiry_time_from_max_age_attribute {}; Optional<Time> expiry_time_from_max_age_attribute {};
Optional<DeprecatedString> domain {}; Optional<DeprecatedString> domain {};
Optional<DeprecatedString> path {}; Optional<DeprecatedString> path {};
bool secure_attribute_present { false }; bool secure_attribute_present { false };

View file

@ -3,13 +3,14 @@
* Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2022-2023, Tim Flynn <trflynn89@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/JsonObject.h> #include <AK/JsonObject.h>
#include <AK/JsonValue.h> #include <AK/JsonValue.h>
#include <AK/Time.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibJS/Runtime/JSONObject.h> #include <LibJS/Runtime/JSONObject.h>
#include <LibJS/Runtime/Value.h> #include <LibJS/Runtime/Value.h>
@ -54,7 +55,7 @@ static JsonValue serialize_cookie(Web::Cookie::Cookie const& cookie)
serialized_cookie.set("domain"sv, cookie.domain); serialized_cookie.set("domain"sv, cookie.domain);
serialized_cookie.set("secure"sv, cookie.secure); serialized_cookie.set("secure"sv, cookie.secure);
serialized_cookie.set("httpOnly"sv, cookie.http_only); serialized_cookie.set("httpOnly"sv, cookie.http_only);
serialized_cookie.set("expiry"sv, cookie.expiry_time.timestamp()); serialized_cookie.set("expiry"sv, cookie.expiry_time.to_seconds());
serialized_cookie.set("sameSite"sv, Web::Cookie::same_site_to_string(cookie.same_site)); serialized_cookie.set("sameSite"sv, Web::Cookie::same_site_to_string(cookie.same_site));
return serialized_cookie; return serialized_cookie;
@ -1593,7 +1594,7 @@ Messages::WebDriverClient::AddCookieResponse WebDriverConnection::add_cookie(Jso
if (data.has("expiry"sv)) { if (data.has("expiry"sv)) {
// NOTE: less than 0 or greater than safe integer are handled by the JSON parser // NOTE: less than 0 or greater than safe integer are handled by the JSON parser
auto expiry = TRY(get_property<u32>(data, "expiry"sv)); auto expiry = TRY(get_property<u32>(data, "expiry"sv));
cookie.expiry_time_from_expires_attribute = Core::DateTime::from_timestamp(expiry); cookie.expiry_time_from_expires_attribute = Time::from_seconds(expiry);
} }
// Cookie same site // Cookie same site
@ -1985,7 +1986,7 @@ void WebDriverConnection::delete_cookies(Optional<StringView> const& name)
// -> name is equal to cookie name // -> name is equal to cookie name
if (!name.has_value() || name.value() == cookie.name) { if (!name.has_value() || name.value() == cookie.name) {
// Set the cookie expiry time to a Unix timestamp in the past. // Set the cookie expiry time to a Unix timestamp in the past.
cookie.expiry_time = Core::DateTime::from_timestamp(0); cookie.expiry_time = Time::from_seconds(0);
m_page_client.page_did_update_cookie(move(cookie)); m_page_client.page_did_update_cookie(move(cookie));
} }
// -> Otherwise // -> Otherwise