-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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: Implement most CredentialsContainer
methods
#3495
base: master
Are you sure you want to change the base?
Conversation
Provide the default implementation for `is_conditional_mediation_available` and `will_request_conditional_creation`.
795803e
to
243df11
Compare
The introduction of the abstract `CredentialInterface` class serves to implement what is mentioned in the spec as "interface objects". It is not possible to implement this perfectly to spec in Ladybird so let's make use of a custom abstraction.
This is probably a spec bug. If the property has a default value it will always be populated in the `CredentialRequestOptions` dictionary making that credential type always active.
243df11
to
483f268
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits: some minor naming suggestions
for (auto& interface : relevant_credential_interface_objects(options)) { | ||
// 1. Let r be the result of executing interface’s [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) | ||
// internal method on origin, options, and sameOriginWithAncestors. If that threw an exception, rethrow that exception. | ||
auto maybe_r = interface->collect_from_credential_store(realm, origin, options, same_origin_with_ancestors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider using possible_result
instead of maybe_r
?
if (maybe_r.is_error()) | ||
return maybe_r.error(); | ||
|
||
auto r = maybe_r.release_value(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider using result
instead of r
?
// TODO: 2. Assert: r is a list of interface objects. | ||
|
||
// 3. For each c in r: | ||
for (auto& c : r) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider using credential
instead of c
?
// If that threw an exception: | ||
if (maybe_result.is_error()) { | ||
// 1. Let e be the thrown exception. | ||
auto e = maybe_result.error_value(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider using exception
instead of e
?
// 9. React to p: | ||
auto on_completion = GC::create_function(realm().heap(), [&settings, &credential](JS::Value) -> WebIDL::ExceptionOr<JS::Value> { | ||
// 1. Remove credential’s [[type]] from settings’ active credential types. | ||
settings.active_credential_types().remove_first_matching([&](auto& v) { return v == credential.type(); }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider using type
instead of v
?
// 1. Let r be the result of executing interfaces[0]'s [[Create]](origin, options, sameOriginWithAncestors) | ||
// internal method on origin, options, and sameOriginWithAncestors. | ||
auto maybe_r = interfaces[0]->create(realm(), origin, options, same_origin_with_ancestors); | ||
// If that threw an exception: | ||
if (maybe_r.is_error()) { | ||
// 1. Let e be the thrown exception. | ||
auto e = maybe_r.error_value(); | ||
// 2. Queue a task on global’s DOM manipulation task source to run the following substeps: | ||
queue_global_task(HTML::Task::Source::DOMManipulation, global, GC::create_function(document.heap(), [&] { | ||
// 1. Reject p with e. | ||
WebIDL::reject_promise(realm(), *promise, e); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above with more descriptive names
return; | ||
} | ||
|
||
auto r = maybe_r.release_value(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
… and also here
483f268
to
94ff908
Compare
Implement `get`, `store`, `create` on `CredentialsContainer`. Some pieces that we don't support yet, like permissions and custom user interactions, are left as TODO. The `rejects when aborted after the promise creation` tests are broken because the spec says to check the aborted signal synchronously.
94ff908
to
3274cf3
Compare
This PR mplements
get
,store
,create
onCredentialsContainer
.Notably, it also introduces the
CredentialInterface
abstract class to deal with credentials internal methods and metadata. It has been implemented as a singleton for each credential type. This is the design that I managed to come up with, any suggestion is appreciated.The spec isn't the best and contains some bugs:
options.signal && options.signal->aborted()
check inget
andcreate
is not deferred therefore fails two WPT testsinterfaces.size() < 1
check increate
is custom and avoids an out of bound access in the next step -> Spec issueCredentialRequestOptions
IDL dictionary has a default value forpassword
which renders the credential type always active. I think we are supposed to reject it when computing the relevant credential interface objects ifpassword
isfalse
, but that's not specifiedI'll create some spec issues and link them here even if the repository has been inactive for the last 6 months.
Lastly, I am unsure how to check
If settings’s relevant global object has no associated Document
so I've left two TODOs.