Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibWeb: Credential Management level 1 #2278

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Libraries/LibWeb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ set(SOURCES
Bindings/SyntheticHostDefined.cpp
Clipboard/Clipboard.cpp
Clipboard/ClipboardEvent.cpp
CredentialManagement/Credential.cpp
CredentialManagement/CredentialsContainer.cpp
CredentialManagement/FederatedCredential.cpp
Crypto/Crypto.cpp
Crypto/CryptoAlgorithms.cpp
Crypto/CryptoBindings.cpp
Expand Down
48 changes: 48 additions & 0 deletions Libraries/LibWeb/CredentialManagement/Credential.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2024, Saksham Goyal <[email protected]>.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <LibWeb/Bindings/CredentialPrototype.h>
#include <LibWeb/Bindings/CredentialsContainerPrototype.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CredentialManagement/Credential.h>
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
#include <LibWeb/CredentialManagement/FederatedCredential.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/WebIDL/DOMException.h>

namespace Web::CredentialManagement {
JS_DEFINE_ALLOCATOR(Credential);

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

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

JS::NonnullGCPtr<WebIDL::Promise> Credential::will_request_conditional_creation(JS::VM& vm)
{
auto* realm = vm.current_realm();
auto promise = WebIDL::create_promise(*realm);
WebIDL::reject_promise(*realm, promise, WebIDL::UnknownError::create(*realm, "Function not completed"_string));
return promise;
}

JS::NonnullGCPtr<WebIDL::Promise> Credential::is_conditional_mediation_available(JS::VM& vm)
{

auto* realm = vm.current_realm();
auto promise = WebIDL::create_promise(*realm);
WebIDL::reject_promise(*realm, promise, WebIDL::UnknownError::create(*realm, "Function not completed"_string));
return promise;
}

}
125 changes: 125 additions & 0 deletions Libraries/LibWeb/CredentialManagement/Credential.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2024, Saksham Goyal <[email protected]>.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <LibJS/Heap/GCPtr.h>
#include <LibJS/Runtime/Promise.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
#include <LibWeb/CredentialManagement/FederatedCredential.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
#include <LibWeb/WebIDL/Promise.h>

namespace Web::CredentialManagement {
struct CredentialData {
String id;
};
struct FederatedCredentialRequestOptions {
Vector<String> providers;
Vector<String> protocols;
};

struct FederatedCredentialInit : CredentialData {
// FIXME optional or not?
Optional<String> name;
Optional<String> icon_url;
Optional<String> origin;
Optional<String> provider;
Optional<String> protocol;
};

enum class CredentialMediationRequirement {
Silent,
Optional,
Conditional,
Required,
};

struct CredentialRequestOptions {
CredentialMediationRequirement mediation = CredentialMediationRequirement::Optional;
JS::GCPtr<DOM::AbortSignal> signal;

union {
JS::GCPtr<FederatedCredentialRequestOptions> federated;
};
};
struct CredentialCreationOptions {
CredentialMediationRequirement mediation = CredentialMediationRequirement::Optional;
JS::GCPtr<DOM::AbortSignal> signal;

union {
JS::GCPtr<FederatedCredentialInit> federated;
// PasswordCredentialInit password;
};
};

struct PasswordCredentialData : CredentialData {
String name;
String icon_url;
String origin;
String password;
};

class Credential : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(Credential, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(Credential);

public:
virtual ~Credential() override = default;
static JS::NonnullGCPtr<WebIDL::Promise> is_conditional_mediation_available(JS::VM&);
static JS::NonnullGCPtr<WebIDL::Promise> will_request_conditional_creation(JS::VM&);
String id() const { return m_id; }
String type() const { return m_type; }

protected:
virtual void initialize(JS::Realm& realm) override;
Credential(JS::Realm& realm);

private:
String m_id;
String m_type;
};
}
namespace Web::CredentialManagement {

class FederatedCredential : public Credential {
WEB_PLATFORM_OBJECT(FederatedCredential, Credential);
JS_DECLARE_ALLOCATOR(FederatedCredential);

public:
virtual ~FederatedCredential() override = default;

FederatedCredential(JS::Realm&, FederatedCredentialInit&);
static JS::NonnullGCPtr<FederatedCredential> create(JS::Realm&, FederatedCredentialInit&);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<FederatedCredential>> construct_impl(JS::Realm&, FederatedCredentialInit&);

String id() const { return m_id; }
String type() const { return m_type; }
String name() const { return m_name; }
String provider() const { return m_provider; }
String icon_url() const { return m_icon_url; }
Optional<String> protocol() const { return m_protocol; }

static JS::NonnullGCPtr<WebIDL::Promise> will_request_conditional_creation(JS::VM&);
static JS::NonnullGCPtr<WebIDL::Promise> is_conditional_mediation_available(JS::VM&);

private:
FederatedCredential(JS::Realm& realm);

virtual void initialize(JS::Realm& realm) override;

String m_provider;
Optional<String> m_protocol;
String m_id;
String m_type;

// Mixin CredentialUserData
String m_name;
String m_icon_url;
};
}
46 changes: 46 additions & 0 deletions Libraries/LibWeb/CredentialManagement/Credential.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

[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 CredentialRequestOptions {
CredentialMediationRequirement mediation = "optional";
AbortSignal signal;
};

enum CredentialMediationRequirement {
"silent",
"optional",
"conditional",
"required"
};

dictionary CredentialCreationOptions {
CredentialMediationRequirement mediation = "optional";
AbortSignal signal;
};


dictionary PasswordCredentialData : CredentialData {
USVString name;
USVString iconURL;
required USVString origin;
required USVString password;
};

typedef (PasswordCredentialData or HTMLFormElement) PasswordCredentialInit;

// partial dictionary CredentialCreationOptions {
// PasswordCredentialInit password;
// };
60 changes: 60 additions & 0 deletions Libraries/LibWeb/CredentialManagement/CredentialsContainer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2024, Saksham Goyal <[email protected]>.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <LibWeb/Bindings/CredentialsContainerPrototype.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CredentialManagement/Credential.h>
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
#include <LibWeb/CredentialManagement/FederatedCredential.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/WebIDL/DOMException.h>

namespace Web::CredentialManagement {
JS_DEFINE_ALLOCATOR(CredentialsContainer);

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

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

JS::NonnullGCPtr<WebIDL::Promise> CredentialsContainer::get(CredentialRequestOptions&)
{
auto& realm = this->realm();
auto promise = WebIDL::create_promise(realm);
WebIDL::reject_promise(realm, promise, WebIDL::UnknownError::create(realm, "Function not completed"_string));
return promise;
}
JS::NonnullGCPtr<WebIDL::Promise> CredentialsContainer::store(Credential&)
{
auto& realm = this->realm();
auto promise = WebIDL::create_promise(realm);
WebIDL::reject_promise(realm, promise, WebIDL::UnknownError::create(realm, "Function not completed"_string));
return promise;
}
JS::NonnullGCPtr<WebIDL::Promise> CredentialsContainer::create(CredentialCreationOptions&)
{
auto& realm = this->realm();
auto promise = WebIDL::create_promise(realm);
WebIDL::reject_promise(realm, promise, WebIDL::UnknownError::create(realm, "Function not completed"_string));
return promise;
}
JS::NonnullGCPtr<WebIDL::Promise> CredentialsContainer::prevent_silent_access()
{
auto& realm = this->realm();
auto promise = WebIDL::create_promise(realm);
WebIDL::reject_promise(realm, promise, WebIDL::UnknownError::create(realm, "Function not completed"_string));
WebIDL::resolve_promise(realm, promise, JS::js_undefined());
return promise;
}

}
36 changes: 36 additions & 0 deletions Libraries/LibWeb/CredentialManagement/CredentialsContainer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, Saksham Goyal <[email protected]>.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <LibJS/Forward.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/DOM/AbortController.h>
#include <LibWeb/DOM/AbortSignal.h>
#include <LibWeb/Forward.h>
#include <LibWeb/WebIDL/ExceptionOr.h>

namespace Web::CredentialManagement {

class CredentialsContainer final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(CredentialsContainer, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(CredentialsContainer);

public:
virtual ~CredentialsContainer() override = default;

JS::NonnullGCPtr<WebIDL::Promise> get(CredentialRequestOptions& options);
JS::NonnullGCPtr<WebIDL::Promise> store(Credential& cred);
JS::NonnullGCPtr<WebIDL::Promise> create(CredentialCreationOptions& options);
JS::NonnullGCPtr<WebIDL::Promise> prevent_silent_access();

private:
CredentialsContainer(JS::Realm& realm);

virtual void initialize(JS::Realm& realm) override;
};
}
12 changes: 12 additions & 0 deletions Libraries/LibWeb/CredentialManagement/CredentialsContainer.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#import <CredentialManagement/Credential.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 CredentialData {
required USVString id;
};
44 changes: 44 additions & 0 deletions Libraries/LibWeb/CredentialManagement/FederatedCredential.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024, Saksham Goyal <[email protected]>.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/FederatedCredentialPrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CredentialManagement/Credential.h>
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
#include <LibWeb/CredentialManagement/FederatedCredential.h>
#include <LibWeb/HTML/Window.h>

namespace Web::CredentialManagement {
JS_DEFINE_ALLOCATOR(FederatedCredential);

FederatedCredential::FederatedCredential(JS::Realm& realm)
: Credential(realm)
{
}

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

WebIDL::ExceptionOr<JS::NonnullGCPtr<FederatedCredential>> FederatedCredential::construct_impl(JS::Realm& realm, FederatedCredentialInit& data)
{
// 1. Let r be the result of executing Create a FederatedCredential
// from FederatedCredentialInit on data. If that threw an exception, rethrow that exception.
auto r = realm.heap().allocate<FederatedCredential>(realm, realm, data);

return r;
}

FederatedCredential::FederatedCredential(JS::Realm& realm, FederatedCredentialInit&)
: Credential(realm)
{
// auto r = realm.heap().allocate<FederatedCredential>(realm, realm, data);
}

}
Loading