WebAuthenticatorCoordinator.cpp [plain text]
#include "config.h"
#include "WebAuthenticatorCoordinator.h"
#if ENABLE(WEB_AUTHN)
#include "DefaultWebBrowserChecks.h"
#include "FrameInfoData.h"
#include "WebAuthenticatorCoordinatorProxyMessages.h"
#include "WebAuthnConnectionToWebProcess.h"
#include "WebAuthnProcessConnection.h"
#include "WebFrame.h"
#include "WebPage.h"
#include "WebProcess.h"
#include <JavaScriptCore/ConsoleTypes.h>
#include <WebCore/AuthenticatorResponseData.h>
#include <WebCore/Frame.h>
#include <WebCore/PublicKeyCredentialCreationOptions.h>
#include <WebCore/PublicKeyCredentialRequestOptions.h>
#include <WebCore/Quirks.h>
#include <WebCore/RuntimeEnabledFeatures.h>
#include <WebCore/SecurityOrigin.h>
#include <WebCore/UserGestureIndicator.h>
namespace WebKit {
using namespace WebCore;
namespace {
static bool isWebBrowser()
{
if (auto* connection = WebProcess::singleton().parentProcessConnection())
return isParentProcessAFullWebBrowser(connection->getAuditToken());
return false;
}
}
WebAuthenticatorCoordinator::WebAuthenticatorCoordinator(WebPage& webPage)
: m_webPage(webPage)
{
}
void WebAuthenticatorCoordinator::makeCredential(const Frame& frame, const SecurityOrigin&, const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions& options, RequestCompletionHandler&& handler)
{
auto* webFrame = WebFrame::fromCoreFrame(frame);
if (!webFrame)
return;
auto isProcessingUserGesture = processingUserGesture(frame, webFrame->frameID());
if (!RuntimeEnabledFeatures::sharedFeatures().webAuthenticationModernEnabled()) {
m_webPage.sendWithAsyncReply(Messages::WebAuthenticatorCoordinatorProxy::MakeCredential(webFrame->frameID(), webFrame->info(), hash, options, isProcessingUserGesture), WTFMove(handler));
return;
}
if (!isWebBrowser())
return;
WebProcess::singleton().ensureWebAuthnProcessConnection().connection().sendWithAsyncReply(Messages::WebAuthnConnectionToWebProcess::MakeCredential(hash, options, isProcessingUserGesture), WTFMove(handler));
}
void WebAuthenticatorCoordinator::getAssertion(const Frame& frame, const SecurityOrigin&, const Vector<uint8_t>& hash, const PublicKeyCredentialRequestOptions& options, RequestCompletionHandler&& handler)
{
auto* webFrame = WebFrame::fromCoreFrame(frame);
if (!webFrame)
return;
auto isProcessingUserGesture = processingUserGesture(frame, webFrame->frameID());
if (!RuntimeEnabledFeatures::sharedFeatures().webAuthenticationModernEnabled()) {
m_webPage.sendWithAsyncReply(Messages::WebAuthenticatorCoordinatorProxy::GetAssertion(webFrame->frameID(), webFrame->info(), hash, options, isProcessingUserGesture), WTFMove(handler));
return;
}
if (!isWebBrowser())
return;
WebProcess::singleton().ensureWebAuthnProcessConnection().connection().sendWithAsyncReply(Messages::WebAuthnConnectionToWebProcess::GetAssertion(hash, options, isProcessingUserGesture), WTFMove(handler));
}
void WebAuthenticatorCoordinator::isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&& handler)
{
if (!RuntimeEnabledFeatures::sharedFeatures().webAuthenticationModernEnabled()) {
m_webPage.sendWithAsyncReply(Messages::WebAuthenticatorCoordinatorProxy::IsUserVerifyingPlatformAuthenticatorAvailable(), WTFMove(handler));
return;
}
if (!isWebBrowser())
return;
WebProcess::singleton().ensureWebAuthnProcessConnection().connection().sendWithAsyncReply(Messages::WebAuthnConnectionToWebProcess::IsUserVerifyingPlatformAuthenticatorAvailable(), WTFMove(handler));
}
bool WebAuthenticatorCoordinator::processingUserGesture(const Frame& frame, const FrameIdentifier& frameID)
{
bool needsQuirk = frame.document() && frame.document()->quirks().shouldBypassUserGestureRequirementForWebAuthn();
auto processingUserGesture = UserGestureIndicator::processingUserGestureForMedia() || (!m_requireUserGesture && needsQuirk);
if (!processingUserGesture)
m_webPage.addConsoleMessage(frameID, MessageSource::Other, MessageLevel::Warning, "User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events."_s);
m_requireUserGesture = true;
return processingUserGesture;
}
}
#endif // ENABLE(WEB_AUTHN)