blob: fcb31114509a2c7b409d46a3cb20e6151e517ac0 [file] [log] [blame] [edit]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/content/browser/email_verifier_delegate.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/content/browser/content_autofill_driver.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/data_model/addresses/autofill_profile.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/foundations/autofill_client.h"
#include "components/autofill/core/browser/foundations/browser_autofill_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/webid/email_verifier.h"
#include "content/public/common/content_features.h"
namespace autofill {
EmailVerifierDelegate::EmailVerifierDelegate(AutofillClient* client)
: EmailVerifierDelegate(
client,
base::BindRepeating([](AutofillManager& manager) {
ContentAutofillDriver& content_driver =
static_cast<ContentAutofillDriver&>(manager.driver());
content::RenderFrameHost* rfh = content_driver.render_frame_host();
return content::webid::EmailVerifier::GetOrCreateForFrame(rfh);
})) {}
EmailVerifierDelegate::EmailVerifierDelegate(AutofillClient* client,
EmailVerifierBuilder builder)
: email_verifier_builder_(std::move(builder)) {
observation_.Observe(client);
}
EmailVerifierDelegate::~EmailVerifierDelegate() = default;
void EmailVerifierDelegate::OnFillOrPreviewForm(
AutofillManager& manager,
FormGlobalId form_id,
mojom::ActionPersistence action_persistence,
const base::flat_set<FieldGlobalId>& filled_field_ids,
const FillingPayload& filling_payload) {
if (!base::FeatureList::IsEnabled(::features::kFedCmDelegation)) {
return;
}
if (action_persistence != mojom::ActionPersistence::kFill) {
return;
}
const AutofillProfile* const* profile =
std::get_if<const AutofillProfile*>(&filling_payload);
if (!profile) {
return;
}
FormStructure* form = manager.FindCachedFormById(form_id);
if (!form) {
return;
}
const std::vector<std::unique_ptr<AutofillField>>& fields = form->fields();
auto it = std::ranges::find_if(
fields, [&](const std::unique_ptr<AutofillField>& field) {
return !field->nonce().empty() &&
field->autofilled_type() == EMAIL_ADDRESS &&
filled_field_ids.contains(field->global_id());
});
if (it == std::ranges::end(fields)) {
return;
}
const AutofillField& email_field = *it->get();
// TODO(crbug.com/446288895): Use email_field->value() when we fix the
// OnFillOrPreviewForm callback.
std::u16string email = (*profile)->GetRawInfo(EMAIL_ADDRESS);
content::webid::EmailVerifier* verifier =
email_verifier_builder_.Run(manager);
verifier->Verify(
base::UTF16ToUTF8(email), base::UTF16ToUTF8(email_field.nonce()),
base::BindOnce(
[](base::WeakPtr<AutofillManager> manager, FieldGlobalId field_id,
std::optional<std::string> presentation_token) {
if (!manager) {
return;
}
if (!presentation_token) {
return;
}
manager->client().ShowEmailVerifiedToast();
manager->driver().DispatchEmailVerifiedEvent(field_id,
*presentation_token);
},
manager.GetWeakPtr(), email_field.global_id()));
}
} // namespace autofill