Skip to content

Commit f47ba84

Browse files
committed
tmp
1 parent 96c0ad1 commit f47ba84

21 files changed

+1622
-11
lines changed

Libraries/LibWeb/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ set(SOURCES
3636
Clipboard/ClipboardItem.cpp
3737
Compression/CompressionStream.cpp
3838
Compression/DecompressionStream.cpp
39+
CredentialManagement/AuthenticatorResponse.cpp
3940
CredentialManagement/Credential.cpp
4041
CredentialManagement/CredentialsContainer.cpp
4142
CredentialManagement/FederatedCredential.cpp
4243
CredentialManagement/PasswordCredential.cpp
44+
CredentialManagement/PublicKeyCredential.cpp
4345
Crypto/Crypto.cpp
4446
Crypto/CryptoAlgorithms.cpp
4547
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 <[email protected]>
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 <[email protected]>
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
@@ -65,22 +65,22 @@ static Vector<CredentialInterface const*> relevant_credential_interface_objects(
6565
// NOTE: We cannot iterate like the spec says.
6666
// 1. Let credentialInterfaceObject be the Appropriate Interface Object (on settings’ global object) whose Options Member Identifier is optionKey.
6767
// 2. Assert: credentialInterfaceObject’s [[type]] slot equals the Credential Type whose Options Member Identifier is optionKey.
68+
// NOTE: This is not necessary in our implementation.
6869
// 3. Append credentialInterfaceObject to relevant interface objects.
6970

7071
#define APPEND_CREDENTIAL_INTERFACE_OBJECT(key, type_) \
7172
if (options.key.has_value()) { \
7273
auto credential_interface_object = type_##Interface::the(); \
73-
VERIFY(credential_interface_object->options_member_identifier() == #key); \
7474
interfaces.append(credential_interface_object); \
7575
}
7676

7777
// https://w3c.github.io/webappsec-credential-management/#credential-type-registry-appropriate-interface-object
7878
APPEND_CREDENTIAL_INTERFACE_OBJECT(password, PasswordCredential);
7979
APPEND_CREDENTIAL_INTERFACE_OBJECT(federated, FederatedCredential);
80+
APPEND_CREDENTIAL_INTERFACE_OBJECT(public_key, PublicKeyCredential);
8081
// TODO: digital
8182
// TODO: identity
8283
// TODO: otp
83-
// TODO: publicKey
8484

8585
#undef APPEND_CREDENTIAL_INTERFACE_OBJECT
8686

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: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
* SPDX-License-Identifier: BSD-2-Clause
55
*/
66

7+
#include "CredentialsContainer.h"
8+
9+
#include <LibWeb/Bindings/ExceptionOrUtils.h>
710
#include <LibWeb/Bindings/Intrinsics.h>
811
#include <LibWeb/CredentialManagement/FederatedCredential.h>
912

@@ -16,10 +19,45 @@ GC::Ref<FederatedCredential> FederatedCredential::create(JS::Realm& realm)
1619
return realm.create<FederatedCredential>(realm);
1720
}
1821

19-
// https://www.w3.org/TR/credential-management-1/#dom-federatedcredential-federatedcredential
20-
WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> FederatedCredential::construct_impl(JS::Realm& realm, FederatedCredentialInit const&)
22+
// https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-federatedcredential-from-federatedcredentialinit
23+
WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> FederatedCredential::create_from_federated_credential_init(JS::Realm& realm, FederatedCredentialInit const& init)
24+
{
25+
// 1. Let c be a new FederatedCredential object.
26+
auto c = realm.create<FederatedCredential>(realm);
27+
28+
// 2. If any of the following are the empty string, throw a TypeError exception:
29+
// - init.id's value
30+
// - init.provider's value
31+
if (init.id.is_empty() || init.provider.is_empty())
32+
return realm.vm().throw_completion<JS::TypeError>("id and provider must not be empty"sv);
33+
34+
// 3. Set c’s properties as follows:
35+
// id -> init.id's value
36+
c->m_id = init.id;
37+
// provider -> init.provider's value
38+
c->m_provider = init.provider;
39+
// iconURL -> init.iconURL's value
40+
c->m_icon_url = init.icon_url.value_or({});
41+
// name -> init.name's value
42+
c->m_name = init.name.value_or({});
43+
// [[origin]] -> init.origin's value.
44+
c->m_origin = init.origin;
45+
46+
// 4. Return c.
47+
return c;
48+
}
49+
50+
// https://w3c.github.io/webappsec-credential-management/#dom-federatedcredential-federatedcredential
51+
WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> FederatedCredential::construct_impl(JS::Realm& realm, FederatedCredentialInit const& init)
2152
{
22-
return realm.vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "construct"sv);
53+
// 1. Let r be the result of executing Create a FederatedCredential from FederatedCredentialInit on data.
54+
// If that threw an exception, rethrow that exception.
55+
auto r = create_from_federated_credential_init(realm, init);
56+
if (r.is_error())
57+
return r.exception();
58+
59+
// 2. Return r.
60+
return r.value();
2361
}
2462

2563
FederatedCredential::~FederatedCredential()
@@ -37,4 +75,23 @@ void FederatedCredential::initialize(JS::Realm& realm)
3775
WEB_SET_PROTOTYPE_FOR_INTERFACE(FederatedCredential);
3876
}
3977

78+
// // https://w3c.github.io/webappsec-credential-management/#create-federatedcredential
79+
JS::ThrowCompletionOr<Variant<Empty, GC::Ref<Credential>, GC::Ref<CreateCredentialAlgorithm>>> FederatedCredentialInterface::create(JS::Realm& realm, URL::Origin const& origin, CredentialCreationOptions const& options, bool) const
80+
{
81+
// 1. Assert: options["federated"] exists, and sameOriginWithAncestors is unused.
82+
VERIFY(options.federated.has_value());
83+
84+
// 2. Set options["federated"]'s origin member’s value to origin’s value.
85+
auto new_options = options;
86+
new_options.federated->origin = origin.serialize();
87+
88+
// 3. Return the result of executing Create a FederatedCredential from FederatedCredentialInit given options["federated"].
89+
// If that threw an exception, then rethrow that exception.
90+
auto maybe_result = FederatedCredential::create_from_federated_credential_init(realm, *new_options.federated);
91+
if (maybe_result.is_error())
92+
return Bindings::exception_to_throw_completion(realm.vm(), maybe_result.release_error());
93+
94+
return maybe_result.release_value();
95+
}
96+
4097
}

Libraries/LibWeb/CredentialManagement/FederatedCredential.h

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

3437
class FederatedCredential final : public Credential {
@@ -50,10 +53,14 @@ class FederatedCredential final : public Credential {
5053
return FederatedCredentialInterface::the();
5154
}
5255

56+
// https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-federatedcredential-from-federatedcredentialinit
57+
static WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> create_from_federated_credential_init(JS::Realm&, FederatedCredentialInit const&);
58+
5359
private:
5460
explicit FederatedCredential(JS::Realm&);
5561
virtual void initialize(JS::Realm&) override;
5662

63+
String m_origin;
5764
String m_provider;
5865
Optional<String> m_protocol;
5966
};

0 commit comments

Comments
 (0)