Skip to content

Commit

Permalink
LibWeb: Stub for Credential Management API
Browse files Browse the repository at this point in the history
Stub out basic Credential Management APIs and import IDL tests.

Spec: https://w3c.github.io/webappsec-credential-management/
  • Loading branch information
devgianlu committed Jan 3, 2025
1 parent e71fb46 commit 5985232
Show file tree
Hide file tree
Showing 28 changed files with 11,821 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Libraries/LibWeb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ set(SOURCES
Clipboard/ClipboardItem.cpp
Compression/CompressionStream.cpp
Compression/DecompressionStream.cpp
CredentialManagement/Credential.cpp
CredentialManagement/CredentialsContainer.cpp
CredentialManagement/FederatedCredential.cpp
CredentialManagement/PasswordCredential.cpp
Crypto/Crypto.cpp
Crypto/CryptoAlgorithms.cpp
Crypto/CryptoBindings.cpp
Expand Down
36 changes: 36 additions & 0 deletions Libraries/LibWeb/CredentialManagement/Credential.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2025, Altomani Gianluca <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CredentialManagement/Credential.h>

namespace Web::CredentialManagement {

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> Credential::is_conditional_mediation_available(JS::VM& vm)
{
auto* realm = vm.current_realm();
return WebIDL::create_rejected_promise(*realm, JS::PrimitiveString::create(vm, "Not implemented"sv));
}

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> Credential::will_request_conditional_creation(JS::VM& vm)
{
auto* realm = vm.current_realm();
return WebIDL::create_rejected_promise(*realm, JS::PrimitiveString::create(vm, "Not implemented"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 changes: 47 additions & 0 deletions Libraries/LibWeb/CredentialManagement/Credential.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2025, Altomani Gianluca <[email protected]>
*
* 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 JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> is_conditional_mediation_available(JS::VM&);
static JS::ThrowCompletionOr<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 changes: 24 additions & 0 deletions Libraries/LibWeb/CredentialManagement/Credential.idl
Original file line number Diff line number Diff line change
@@ -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"
};
51 changes: 51 additions & 0 deletions Libraries/LibWeb/CredentialManagement/CredentialsContainer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2025, Altomani Gianluca <[email protected]>
*
* 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() { }

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> CredentialsContainer::get(CredentialRequestOptions const&)
{
return WebIDL::create_rejected_promise(realm(), JS::PrimitiveString::create(realm().vm(), "Not implemented"sv));
}

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> CredentialsContainer::store(Credential const&)
{
return WebIDL::create_rejected_promise(realm(), JS::PrimitiveString::create(realm().vm(), "Not implemented"sv));
}

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> CredentialsContainer::create(CredentialCreationOptions const&)
{
return WebIDL::create_rejected_promise(realm(), JS::PrimitiveString::create(realm().vm(), "Not implemented"sv));
}

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> CredentialsContainer::prevent_silent_access()
{
return WebIDL::create_rejected_promise(realm(), JS::PrimitiveString::create(realm().vm(), "Not implemented"sv));
}

CredentialsContainer::CredentialsContainer(JS::Realm& realm)
: PlatformObject(realm)
{
}

void CredentialsContainer::initialize(JS::Realm& realm)
{
Base::initialize(realm);
WEB_SET_PROTOTYPE_FOR_INTERFACE(CredentialsContainer);
}

}
55 changes: 55 additions & 0 deletions Libraries/LibWeb/CredentialManagement/CredentialsContainer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2025, Altomani Gianluca <[email protected]>
*
* 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;

JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> get(CredentialRequestOptions const& options);
JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> store(Credential const& credential);
JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> create(CredentialCreationOptions const& options);
JS::ThrowCompletionOr<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;
};

}
21 changes: 21 additions & 0 deletions Libraries/LibWeb/CredentialManagement/CredentialsContainer.idl
Original file line number Diff line number Diff line change
@@ -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;
};
39 changes: 39 additions & 0 deletions Libraries/LibWeb/CredentialManagement/FederatedCredential.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2025, Altomani Gianluca <[email protected]>
*
* 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);
}

WebIDL::ExceptionOr<GC::Ref<FederatedCredential>> FederatedCredential::construct_impl(JS::Realm& realm, FederatedCredentialInit const&)
{
return JS::throw_completion(JS::PrimitiveString::create(realm.vm(), "Not implemented"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 changes: 52 additions & 0 deletions Libraries/LibWeb/CredentialManagement/FederatedCredential.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2025, Altomani Gianluca <[email protected]>
*
* 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;
};

}
30 changes: 30 additions & 0 deletions Libraries/LibWeb/CredentialManagement/FederatedCredential.idl
Original file line number Diff line number Diff line change
@@ -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;
};
Loading

0 comments on commit 5985232

Please sign in to comment.