mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-21 18:00:16 +00:00
LibWeb: Stub for Credential Management API
Stub out basic Credential Management APIs and import IDL tests. Spec: https://w3c.github.io/webappsec-credential-management/
This commit is contained in:
parent
e14511468f
commit
da9eaf8788
Notes:
github-actions[bot]
2025-02-05 20:19:50 +00:00
Author: https://github.com/devgianlu
Commit: da9eaf8788
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3117
Reviewed-by: https://github.com/ADKaster ✅
20 changed files with 534 additions and 0 deletions
38
Libraries/LibWeb/CredentialManagement/Credential.cpp
Normal file
38
Libraries/LibWeb/CredentialManagement/Credential.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CredentialManagement/Credential.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-credential-isconditionalmediationavailable
|
||||
GC::Ref<WebIDL::Promise> Credential::is_conditional_mediation_available(JS::VM& vm)
|
||||
{
|
||||
auto* realm = vm.current_realm();
|
||||
return WebIDL::create_rejected_promise_from_exception(*realm, vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "is conditional mediation available"sv));
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-credential-willrequestconditionalcreation
|
||||
GC::Ref<WebIDL::Promise> Credential::will_request_conditional_creation(JS::VM& vm)
|
||||
{
|
||||
auto* realm = vm.current_realm();
|
||||
return WebIDL::create_rejected_promise_from_exception(*realm, vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "will request conditional creation"sv));
|
||||
}
|
||||
|
||||
Credential::~Credential() { }
|
||||
|
||||
Credential::Credential(JS::Realm& realm)
|
||||
: PlatformObject(realm)
|
||||
{
|
||||
}
|
||||
|
||||
void Credential::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(Credential);
|
||||
}
|
||||
}
|
47
Libraries/LibWeb/CredentialManagement/Credential.h
Normal file
47
Libraries/LibWeb/CredentialManagement/Credential.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Bindings/CredentialPrototype.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
class Credential : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(Credential, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(Credential);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<Credential> create(JS::Realm&);
|
||||
|
||||
static GC::Ref<WebIDL::Promise> is_conditional_mediation_available(JS::VM&);
|
||||
static GC::Ref<WebIDL::Promise> will_request_conditional_creation(JS::VM&);
|
||||
|
||||
virtual ~Credential() override;
|
||||
|
||||
String const& id() { return m_id; }
|
||||
String const& name() { return m_name; }
|
||||
String const& icon_url() { return m_icon_url; }
|
||||
|
||||
virtual String type() = 0;
|
||||
|
||||
protected:
|
||||
explicit Credential(JS::Realm&);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
String m_id;
|
||||
String m_name;
|
||||
String m_icon_url;
|
||||
};
|
||||
|
||||
struct CredentialData {
|
||||
String id;
|
||||
};
|
||||
|
||||
}
|
24
Libraries/LibWeb/CredentialManagement/Credential.idl
Normal file
24
Libraries/LibWeb/CredentialManagement/Credential.idl
Normal file
|
@ -0,0 +1,24 @@
|
|||
[Exposed=Window, SecureContext]
|
||||
interface Credential {
|
||||
readonly attribute USVString id;
|
||||
readonly attribute DOMString type;
|
||||
static Promise<boolean> isConditionalMediationAvailable();
|
||||
static Promise<undefined> willRequestConditionalCreation();
|
||||
};
|
||||
|
||||
[SecureContext]
|
||||
interface mixin CredentialUserData {
|
||||
readonly attribute USVString name;
|
||||
readonly attribute USVString iconURL;
|
||||
};
|
||||
|
||||
dictionary CredentialData {
|
||||
required USVString id;
|
||||
};
|
||||
|
||||
enum CredentialMediationRequirement {
|
||||
"silent",
|
||||
"optional",
|
||||
"conditional",
|
||||
"required"
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(CredentialsContainer);
|
||||
|
||||
GC::Ref<CredentialsContainer> CredentialsContainer::create(JS::Realm& realm)
|
||||
{
|
||||
return realm.create<CredentialsContainer>(realm);
|
||||
}
|
||||
|
||||
CredentialsContainer::~CredentialsContainer() { }
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-get
|
||||
GC::Ref<WebIDL::Promise> CredentialsContainer::get(CredentialRequestOptions const&)
|
||||
{
|
||||
auto* realm = vm().current_realm();
|
||||
return WebIDL::create_rejected_promise_from_exception(*realm, vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "get"sv));
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-store
|
||||
GC::Ref<WebIDL::Promise> CredentialsContainer::store(Credential const&)
|
||||
{
|
||||
auto* realm = vm().current_realm();
|
||||
return WebIDL::create_rejected_promise_from_exception(*realm, vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "store"sv));
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-create
|
||||
GC::Ref<WebIDL::Promise> CredentialsContainer::create(CredentialCreationOptions const&)
|
||||
{
|
||||
auto* realm = vm().current_realm();
|
||||
return WebIDL::create_rejected_promise_from_exception(*realm, vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "create"sv));
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-preventsilentaccess
|
||||
GC::Ref<WebIDL::Promise> CredentialsContainer::prevent_silent_access()
|
||||
{
|
||||
auto* realm = vm().current_realm();
|
||||
return WebIDL::create_rejected_promise_from_exception(*realm, vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "prevent silent access"sv));
|
||||
}
|
||||
|
||||
CredentialsContainer::CredentialsContainer(JS::Realm& realm)
|
||||
: PlatformObject(realm)
|
||||
{
|
||||
}
|
||||
|
||||
void CredentialsContainer::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(CredentialsContainer);
|
||||
}
|
||||
|
||||
}
|
55
Libraries/LibWeb/CredentialManagement/CredentialsContainer.h
Normal file
55
Libraries/LibWeb/CredentialManagement/CredentialsContainer.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Bindings/CredentialsContainerPrototype.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/CredentialManagement/Credential.h>
|
||||
#include <LibWeb/CredentialManagement/FederatedCredential.h>
|
||||
#include <LibWeb/CredentialManagement/PasswordCredential.h>
|
||||
#include <LibWeb/DOM/AbortSignal.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
class CredentialsContainer final : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(CredentialsContainer, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(CredentialsContainer);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<CredentialsContainer> create(JS::Realm&);
|
||||
|
||||
virtual ~CredentialsContainer() override;
|
||||
|
||||
GC::Ref<WebIDL::Promise> get(CredentialRequestOptions const& options);
|
||||
GC::Ref<WebIDL::Promise> store(Credential const& credential);
|
||||
GC::Ref<WebIDL::Promise> create(CredentialCreationOptions const& options);
|
||||
GC::Ref<WebIDL::Promise> prevent_silent_access();
|
||||
|
||||
private:
|
||||
explicit CredentialsContainer(JS::Realm&);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
};
|
||||
|
||||
struct CredentialRequestOptions {
|
||||
Bindings::CredentialMediationRequirement mediation { Bindings::CredentialMediationRequirement::Optional };
|
||||
GC::Ptr<DOM::AbortSignal> signal;
|
||||
|
||||
Optional<bool> password;
|
||||
Optional<FederatedCredentialRequestOptions> federated;
|
||||
};
|
||||
|
||||
struct CredentialCreationOptions {
|
||||
Bindings::CredentialMediationRequirement mediation { Bindings::CredentialMediationRequirement::Optional };
|
||||
GC::Ptr<DOM::AbortSignal> signal;
|
||||
|
||||
Optional<PasswordCredentialInit> password;
|
||||
Optional<FederatedCredentialInit> federated;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#import <CredentialManagement/Credential.idl>
|
||||
#import <CredentialManagement/FederatedCredential.idl>
|
||||
#import <CredentialManagement/PasswordCredential.idl>
|
||||
|
||||
[Exposed=Window, SecureContext]
|
||||
interface CredentialsContainer {
|
||||
Promise<Credential?> get(optional CredentialRequestOptions options = {});
|
||||
Promise<undefined> store(Credential credential);
|
||||
Promise<Credential?> create(optional CredentialCreationOptions options = {});
|
||||
Promise<undefined> preventSilentAccess();
|
||||
};
|
||||
|
||||
dictionary CredentialRequestOptions {
|
||||
CredentialMediationRequirement mediation = "optional";
|
||||
AbortSignal signal;
|
||||
};
|
||||
|
||||
dictionary CredentialCreationOptions {
|
||||
CredentialMediationRequirement mediation = "optional";
|
||||
AbortSignal signal;
|
||||
};
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CredentialManagement/FederatedCredential.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(FederatedCredential);
|
||||
|
||||
GC::Ref<FederatedCredential> FederatedCredential::create(JS::Realm& realm)
|
||||
{
|
||||
return realm.create<FederatedCredential>(realm);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-federatedcredential-federatedcredential
|
||||
WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> FederatedCredential::construct_impl(JS::Realm& realm, FederatedCredentialInit const&)
|
||||
{
|
||||
return realm.vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "construct"sv);
|
||||
}
|
||||
|
||||
FederatedCredential::~FederatedCredential()
|
||||
{
|
||||
}
|
||||
|
||||
FederatedCredential::FederatedCredential(JS::Realm& realm)
|
||||
: Credential(realm)
|
||||
{
|
||||
}
|
||||
|
||||
void FederatedCredential::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(FederatedCredential);
|
||||
}
|
||||
|
||||
}
|
52
Libraries/LibWeb/CredentialManagement/FederatedCredential.h
Normal file
52
Libraries/LibWeb/CredentialManagement/FederatedCredential.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Bindings/FederatedCredentialPrototype.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/CredentialManagement/Credential.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
class FederatedCredential final : public Credential {
|
||||
WEB_PLATFORM_OBJECT(FederatedCredential, Credential);
|
||||
GC_DECLARE_ALLOCATOR(FederatedCredential);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<FederatedCredential> create(JS::Realm&);
|
||||
static WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> construct_impl(JS::Realm&, FederatedCredentialInit const&);
|
||||
|
||||
virtual ~FederatedCredential() override;
|
||||
|
||||
String const& provider() { return m_provider; }
|
||||
Optional<String> const& protocol() { return m_protocol; }
|
||||
|
||||
String type() override { return "federated"_string; }
|
||||
|
||||
private:
|
||||
explicit FederatedCredential(JS::Realm&);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
String m_provider;
|
||||
Optional<String> m_protocol;
|
||||
};
|
||||
|
||||
struct FederatedCredentialRequestOptions {
|
||||
Optional<Vector<String>> providers;
|
||||
Optional<Vector<String>> protocols;
|
||||
};
|
||||
|
||||
struct FederatedCredentialInit : CredentialData {
|
||||
Optional<String> name;
|
||||
Optional<String> icon_url;
|
||||
String origin;
|
||||
String provider;
|
||||
Optional<String> protocol;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#import <CredentialManagement/Credential.idl>
|
||||
|
||||
[Exposed=Window, SecureContext]
|
||||
interface FederatedCredential : Credential {
|
||||
constructor(FederatedCredentialInit data);
|
||||
readonly attribute USVString provider;
|
||||
readonly attribute DOMString? protocol;
|
||||
};
|
||||
FederatedCredential includes CredentialUserData;
|
||||
|
||||
dictionary FederatedCredentialRequestOptions {
|
||||
sequence<USVString> providers;
|
||||
sequence<DOMString> protocols;
|
||||
};
|
||||
|
||||
partial dictionary CredentialRequestOptions {
|
||||
FederatedCredentialRequestOptions federated;
|
||||
};
|
||||
|
||||
dictionary FederatedCredentialInit : CredentialData {
|
||||
USVString name;
|
||||
USVString iconURL;
|
||||
required USVString origin;
|
||||
required USVString provider;
|
||||
DOMString protocol;
|
||||
};
|
||||
|
||||
partial dictionary CredentialCreationOptions {
|
||||
FederatedCredentialInit federated;
|
||||
};
|
45
Libraries/LibWeb/CredentialManagement/PasswordCredential.cpp
Normal file
45
Libraries/LibWeb/CredentialManagement/PasswordCredential.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/CredentialManagement/PasswordCredential.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(PasswordCredential);
|
||||
|
||||
GC::Ref<PasswordCredential> PasswordCredential::create(JS::Realm& realm)
|
||||
{
|
||||
return realm.create<PasswordCredential>(realm);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-passwordcredential-passwordcredential
|
||||
WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> PasswordCredential::construct_impl(JS::Realm& realm, HTML::HTMLFormElement const&)
|
||||
{
|
||||
return realm.vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "construct"sv);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/credential-management-1/#dom-passwordcredential-passwordcredential-data
|
||||
WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> PasswordCredential::construct_impl(JS::Realm& realm, PasswordCredentialData const&)
|
||||
{
|
||||
return realm.vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "construct"sv);
|
||||
}
|
||||
|
||||
PasswordCredential::~PasswordCredential()
|
||||
{
|
||||
}
|
||||
|
||||
PasswordCredential::PasswordCredential(JS::Realm& realm)
|
||||
: Credential(realm)
|
||||
{
|
||||
}
|
||||
|
||||
void PasswordCredential::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(PasswordCredential);
|
||||
}
|
||||
|
||||
}
|
49
Libraries/LibWeb/CredentialManagement/PasswordCredential.h
Normal file
49
Libraries/LibWeb/CredentialManagement/PasswordCredential.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Bindings/PasswordCredentialPrototype.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/CredentialManagement/Credential.h>
|
||||
#include <LibWeb/HTML/HTMLFormElement.h>
|
||||
|
||||
namespace Web::CredentialManagement {
|
||||
|
||||
class PasswordCredential final : public Credential {
|
||||
WEB_PLATFORM_OBJECT(PasswordCredential, Credential);
|
||||
GC_DECLARE_ALLOCATOR(PasswordCredential);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<PasswordCredential> create(JS::Realm&);
|
||||
static WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> construct_impl(JS::Realm&, HTML::HTMLFormElement const&);
|
||||
static WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> construct_impl(JS::Realm&, PasswordCredentialData const&);
|
||||
|
||||
virtual ~PasswordCredential() override;
|
||||
|
||||
String const& password() { return m_password; }
|
||||
|
||||
String type() override { return "password"_string; }
|
||||
|
||||
private:
|
||||
explicit PasswordCredential(JS::Realm&);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
// TODO: Use Core::SecretString when it comes back
|
||||
String m_password;
|
||||
};
|
||||
|
||||
struct PasswordCredentialData : CredentialData {
|
||||
Optional<String> name;
|
||||
Optional<String> icon_url;
|
||||
String origin;
|
||||
String password;
|
||||
};
|
||||
|
||||
using PasswordCredentialInit = Variant<PasswordCredentialData, GC::Root<HTML::HTMLFormElement>>;
|
||||
|
||||
}
|
26
Libraries/LibWeb/CredentialManagement/PasswordCredential.idl
Normal file
26
Libraries/LibWeb/CredentialManagement/PasswordCredential.idl
Normal file
|
@ -0,0 +1,26 @@
|
|||
#import <CredentialManagement/Credential.idl>
|
||||
|
||||
[Exposed=Window, SecureContext]
|
||||
interface PasswordCredential : Credential {
|
||||
constructor(HTMLFormElement form);
|
||||
constructor(PasswordCredentialData data);
|
||||
readonly attribute USVString password;
|
||||
};
|
||||
PasswordCredential includes CredentialUserData;
|
||||
|
||||
partial dictionary CredentialRequestOptions {
|
||||
boolean password = false;
|
||||
};
|
||||
|
||||
dictionary PasswordCredentialData : CredentialData {
|
||||
USVString name;
|
||||
USVString iconURL;
|
||||
required USVString origin;
|
||||
required USVString password;
|
||||
};
|
||||
|
||||
typedef (PasswordCredentialData or HTMLFormElement) PasswordCredentialInit;
|
||||
|
||||
partial dictionary CredentialCreationOptions {
|
||||
PasswordCredentialInit password;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue