Skip to content

Commit 75851d2

Browse files
committed
tmp
1 parent 234f3bb commit 75851d2

20 files changed

Lines changed: 1440 additions & 2 deletions

Libraries/LibWeb/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,14 @@ set(SOURCES
8484
ContentSecurityPolicy/Violation.cpp
8585
CookieStore/CookieChangeEvent.cpp
8686
CookieStore/CookieStore.cpp
87+
CredentialManagement/AuthenticatorResponse.cpp
8788
CredentialManagement/Credential.cpp
8889
CredentialManagement/CredentialsContainer.cpp
8990
CredentialManagement/FederatedCredential.cpp
9091
CredentialManagement/FederatedCredentialOperations.cpp
9192
CredentialManagement/PasswordCredential.cpp
9293
CredentialManagement/PasswordCredentialOperations.cpp
94+
CredentialManagement/PublicKeyCredential.cpp
9395
Crypto/Crypto.cpp
9496
Crypto/CryptoAlgorithms.cpp
9597
Crypto/CryptoBindings.cpp
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <LibJS/Runtime/ArrayBuffer.h>
8+
#include <LibWeb/Bindings/Intrinsics.h>
9+
#include <LibWeb/CredentialManagement/AuthenticatorResponse.h>
10+
11+
namespace Web::CredentialManagement {
12+
13+
GC_DEFINE_ALLOCATOR(AuthenticatorResponse);
14+
15+
AuthenticatorResponse::~AuthenticatorResponse() { }
16+
17+
GC::Ref<JS::ArrayBuffer> AuthenticatorResponse::client_data_json() const
18+
{
19+
return MUST(JS::ArrayBuffer::create(realm(), static_cast<size_t>(0)));
20+
}
21+
22+
AuthenticatorResponse::AuthenticatorResponse(JS::Realm& realm)
23+
: PlatformObject(realm)
24+
{
25+
}
26+
27+
void AuthenticatorResponse::initialize(JS::Realm& realm)
28+
{
29+
Base::initialize(realm);
30+
WEB_SET_PROTOTYPE_FOR_INTERFACE(AuthenticatorResponse);
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include <LibJS/Forward.h>
10+
#include <LibWeb/Bindings/AuthenticatorResponsePrototype.h>
11+
#include <LibWeb/Bindings/PlatformObject.h>
12+
#include <LibWeb/WebIDL/Promise.h>
13+
14+
namespace Web::CredentialManagement {
15+
16+
class AuthenticatorResponse : public Bindings::PlatformObject {
17+
WEB_PLATFORM_OBJECT(AuthenticatorResponse, Bindings::PlatformObject);
18+
GC_DECLARE_ALLOCATOR(AuthenticatorResponse);
19+
20+
public:
21+
[[nodiscard]] static GC::Ref<AuthenticatorResponse> create(JS::Realm&);
22+
23+
virtual ~AuthenticatorResponse() override;
24+
25+
GC::Ref<JS::ArrayBuffer> client_data_json() const;
26+
27+
protected:
28+
explicit AuthenticatorResponse(JS::Realm&);
29+
virtual void initialize(JS::Realm&) override;
30+
};
31+
32+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[SecureContext, Exposed=Window]
2+
interface AuthenticatorResponse {
3+
[SameObject] readonly attribute ArrayBuffer clientDataJSON;
4+
};

Libraries/LibWeb/CredentialManagement/CredentialsContainer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,22 @@ static Vector<CredentialInterface const*> relevant_credential_interface_objects(
6868
// NOTE: We cannot iterate like the spec says.
6969
// 1. Let credentialInterfaceObject be the Appropriate Interface Object (on settings’ global object) whose Options Member Identifier is optionKey.
7070
// 2. Assert: credentialInterfaceObject’s [[type]] slot equals the Credential Type whose Options Member Identifier is optionKey.
71+
// NOTE: This is not necessary in our implementation.
7172
// 3. Append credentialInterfaceObject to relevant interface objects.
7273

7374
#define APPEND_CREDENTIAL_INTERFACE_OBJECT(key, type_) \
7475
if (options.key.has_value()) { \
7576
auto credential_interface_object = type_##Interface::the(); \
76-
VERIFY(credential_interface_object->options_member_identifier() == #key); \
7777
interfaces.append(credential_interface_object); \
7878
}
7979

8080
// https://w3c.github.io/webappsec-credential-management/#credential-type-registry-appropriate-interface-object
8181
APPEND_CREDENTIAL_INTERFACE_OBJECT(password, PasswordCredential);
8282
APPEND_CREDENTIAL_INTERFACE_OBJECT(federated, FederatedCredential);
83+
APPEND_CREDENTIAL_INTERFACE_OBJECT(public_key, PublicKeyCredential);
8384
// TODO: digital
8485
// TODO: identity
8586
// TODO: otp
86-
// TODO: publicKey
8787

8888
#undef APPEND_CREDENTIAL_INTERFACE_OBJECT
8989

Libraries/LibWeb/CredentialManagement/CredentialsContainer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <LibWeb/CredentialManagement/Credential.h>
1414
#include <LibWeb/CredentialManagement/FederatedCredential.h>
1515
#include <LibWeb/CredentialManagement/PasswordCredential.h>
16+
#include <LibWeb/CredentialManagement/PublicKeyCredential.h>
1617
#include <LibWeb/DOM/AbortSignal.h>
1718

1819
namespace Web::CredentialManagement {
@@ -42,6 +43,7 @@ struct CredentialRequestOptions {
4243

4344
Optional<bool> password;
4445
Optional<FederatedCredentialRequestOptions> federated;
46+
Optional<PublicKeyCredentialRequestOptions> public_key;
4547
};
4648

4749
struct CredentialCreationOptions {
@@ -50,6 +52,7 @@ struct CredentialCreationOptions {
5052

5153
Optional<PasswordCredentialInit> password;
5254
Optional<FederatedCredentialInit> federated;
55+
Optional<PublicKeyCredentialCreationOptions> public_key;
5356
};
5457

5558
}

Libraries/LibWeb/CredentialManagement/CredentialsContainer.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#import <CredentialManagement/Credential.idl>
22
#import <CredentialManagement/FederatedCredential.idl>
33
#import <CredentialManagement/PasswordCredential.idl>
4+
#import <CredentialManagement/PublicKeyCredential.idl>
45

56
[Exposed=Window, SecureContext]
67
interface CredentialsContainer {

Libraries/LibWeb/CredentialManagement/FederatedCredential.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
* SPDX-License-Identifier: BSD-2-Clause
55
*/
66

7+
#include <LibWeb/Bindings/ExceptionOrUtils.h>
78
#include <LibWeb/Bindings/Intrinsics.h>
9+
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
810
#include <LibWeb/CredentialManagement/FederatedCredential.h>
911
#include <LibWeb/CredentialManagement/FederatedCredentialOperations.h>
1012

@@ -25,6 +27,25 @@ FederatedCredential::~FederatedCredential()
2527
{
2628
}
2729

30+
// https://w3c.github.io/webappsec-credential-management/#create-federatedcredential
31+
JS::ThrowCompletionOr<Variant<Empty, GC::Ref<Credential>, GC::Ref<CreateCredentialAlgorithm>>> FederatedCredentialInterface::create(JS::Realm& realm, URL::Origin const& origin, CredentialCreationOptions const& options, bool) const
32+
{
33+
// 1. Assert: options["federated"] exists, and sameOriginWithAncestors is unused.
34+
VERIFY(options.federated.has_value());
35+
36+
// 2. Set options["federated"]'s origin member’s value to origin’s value.
37+
auto new_options = options;
38+
new_options.federated->origin = origin;
39+
40+
// 3. Return the result of executing Create a FederatedCredential from FederatedCredentialInit given options["federated"].
41+
// If that threw an exception, then rethrow that exception.
42+
auto maybe_result = create_federated_credential(realm, *new_options.federated);
43+
if (maybe_result.is_error())
44+
return Bindings::exception_to_throw_completion(realm.vm(), maybe_result.release_error());
45+
46+
return maybe_result.release_value();
47+
}
48+
2849
FederatedCredential::FederatedCredential(JS::Realm& realm, FederatedCredentialInit const& init, URL::Origin origin)
2950
: Credential(realm, init.id)
3051
, CredentialUserData(init.name.value_or(String {}), init.icon_url.value_or(String {}))

Libraries/LibWeb/CredentialManagement/FederatedCredential.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class FederatedCredentialInterface final : public CredentialInterface {
3030
// therefore conditional mediation is not supported.
3131
return false;
3232
}
33+
34+
// https://w3c.github.io/webappsec-credential-management/#create-federatedcredential
35+
virtual JS::ThrowCompletionOr<Variant<Empty, GC::Ref<Credential>, GC::Ref<CreateCredentialAlgorithm>>> create(JS::Realm&, URL::Origin const&, CredentialCreationOptions const&, bool) const override;
3336
};
3437

3538
class FederatedCredential final

Libraries/LibWeb/CredentialManagement/PasswordCredential.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
* SPDX-License-Identifier: BSD-2-Clause
55
*/
66

7+
#include <LibWeb/Bindings/ExceptionOrUtils.h>
8+
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
79
#include <LibWeb/CredentialManagement/PasswordCredential.h>
810
#include <LibWeb/CredentialManagement/PasswordCredentialOperations.h>
11+
#include <LibWeb/HTML/AutocompleteElement.h>
12+
#include <LibWeb/XHR/FormData.h>
913

1014
namespace Web::CredentialManagement {
1115

@@ -51,4 +55,31 @@ void PasswordCredential::initialize(JS::Realm& realm)
5155
Base::initialize(realm);
5256
}
5357

58+
// https://w3c.github.io/webappsec-credential-management/#create-passwordcredential
59+
JS::ThrowCompletionOr<Variant<Empty, GC::Ref<Credential>, GC::Ref<CreateCredentialAlgorithm>>> PasswordCredentialInterface::create(JS::Realm& realm, URL::Origin const& origin, CredentialCreationOptions const& options, bool) const
60+
{
61+
// 1. Assert: options["password"] exists, and sameOriginWithAncestors is unused.
62+
VERIFY(options.password.has_value());
63+
64+
auto maybe_result = options.password->visit(
65+
// 2. If options["password"] is an HTMLFormElement, return the result of executing Create a PasswordCredential
66+
// from an HTMLFormElement given options["password"] and origin. Rethrow any exceptions.
67+
[&](GC::Root<HTML::HTMLFormElement> const& form) {
68+
return create_password_credential(realm, *form, origin);
69+
},
70+
// 3. If options["password"] is a PasswordCredentialData, return the result of executing
71+
// Create a PasswordCredential from PasswordCredentialData given options["password"]. Rethrow any exceptions.
72+
[&](PasswordCredentialData const& data) {
73+
return create_password_credential(realm, data, origin);
74+
},
75+
// 4. Throw a TypeError exception.
76+
[&](auto) {
77+
return realm.vm().throw_completion<JS::TypeError>("options.password must be an HTMLFormElement or a PasswordCredentialData"sv);
78+
});
79+
if (maybe_result.is_error())
80+
return Bindings::exception_to_throw_completion(realm.vm(), maybe_result.release_error());
81+
82+
return maybe_result.release_value();
83+
}
84+
5485
}

0 commit comments

Comments
 (0)