-
Notifications
You must be signed in to change notification settings - Fork 893
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
Catch all recaptcha errors #7203
Conversation
🦋 Changeset detectedLatest commit: 7ff8cb9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Size Report 1Affected Products
Test Logs |
Size Analysis Report 1Affected Products
Test Logs |
6f47b6c
to
bde26c7
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.
LGTM great work on this
provider: new ReCaptchaV3Provider(FAKE_SITE_KEY) | ||
}); | ||
|
||
const reCAPTCHASpy = stubGetRecaptchaToken('', false); |
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.
Should the first parameter here, the token parameter, be related to formatDummyToken(defaultTokenErrorData)
?
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.
No, that's the recaptcha token. The flow in App Check (when using recaptcha, the default attestation provider) is
- The client requests a recaptcha token
- recaptcha returns a recaptcha token
- The client takes the recaptcha token and sends it to the App Check exchange endpoint
- The App Check exchange endpoint returns an App Check token
In this test, step 3 is being interrupted, the recaptcha token was no good (it was ''
as stubbed here), so it won't bother to send anything to the exchange endpoint and will just create a dummy App Check token locally, which is returned by getToken()
(the function that covers the whole exchange logic).
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.
Ahhh. thanks so much for the detailed response!
packages/app-check/src/recaptcha.ts
Outdated
@@ -143,11 +143,19 @@ function renderInvisibleWidget( | |||
grecaptcha: GreCAPTCHA, | |||
container: string | |||
): void { | |||
const state = getStateReference(app); |
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.
Is this needed?
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.
It's referenced in 160. Apparently it used to be under the widgetId block, I should put it back, it's weird here.
We were catching local errors in recaptcha by
catch
ing the result ofgrecaptcha.execute
. It turns out that not all recaptcha errors result inrecaptcha.execute
throwing. Errors can also be caught inerror-callback
params passed togrecaptcha.render
. See https://developers.google.com/recaptcha/docs/invisible for parameters accepted bygrecaptcha.render
.These callbacks will set a boolean variable in our AppCheck state object, which will be checked in provider.getToken() methods for the two reCAPTCHA providers, and provider.getToken() will throw with a RECAPTCHA_ERROR if false. This will prevent the main
getToken()
in internal-api.ts from going on to call the exchange endpoint, since we already know we don't have a usable reCAPTCHA token to send. This will then prevent a 503 error caused by sending a bad token, which will prevent a 1 day backoff being imposed.This means that a device that ran into a reCAPTCHA error while asleep, or in a background tab, or some other temporary reason, won't be locked off from retrying on the next request.
This may help with errors such as:
#7116
and
#6708