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

RecaptchaVerifier error when used together with AppCheck #6133

Closed
faizanabidnaqvi opened this issue Apr 10, 2022 · 17 comments · Fixed by #6421
Closed

RecaptchaVerifier error when used together with AppCheck #6133

faizanabidnaqvi opened this issue Apr 10, 2022 · 17 comments · Fixed by #6421

Comments

@faizanabidnaqvi
Copy link

[REQUIRED] Describe your environment

  • Operating System version: MacOS Monterey 12.3
  • Browser version: Chrome version 100.0.4896.75
  • Firebase SDK version: 9.6.10
  • Firebase Product: auth

[REQUIRED] Describe the problem

When I use the RecaptchaVerifier on my site with AppCheck enabled, I get an error when I call the verify method on the RecaptchaVerifier. The error is as follows:
TypeError: this.getAssertedRecaptcha(...).render is not a function
This only happens when AppCheck is enabled; without AppCheck it behaves normally, that is, the verification goes through. Also, it doesn't happen in development or production when running at localhost with the emulator. Only occurs in the deployed code in firebase hosting.

Screenshot 2022-04-10 at 6 29 34 PM

Steps to reproduce:

  1. Create a react app with firebase app check enabled
  2. Create a simple page with an invisible RecaptchaVerifier and a button that when clicked calls 'RecaptchaVerifier.verify()'
  3. Build the app and deploy to hosting
  4. Notice the error occurs when you press the button that calls the verify function

Relevant Code:

In my root App.tsx file, appcheck is initialized this way

if(!getApps().length){
  const app = initializeApp(firebaseConfig)
  // console.log(`Initializing app check with ${import.meta.env.VITE_RECAPTCHA_KEY}`)
  //if localhost set debug app check token
  //https://firebase.google.com/docs/app-check/web/debug-provider?authuser=0&hl=en
  if (window.location.hostname === "localhost"){
    //this must be set to true to generate a new token and once generated and registered, we need to set the token value in env
    //(self as any).FIREBASE_APPCHECK_DEBUG_TOKEN = true
    (window.self as any).FIREBASE_APPCHECK_DEBUG_TOKEN = import.meta.env.VITE_APP_CHECK_DEBUG_TOKEN
  }

  initializeAppCheck(app, {
    provider: new ReCaptchaEnterpriseProvider(import.meta.env.VITE_RECAPTCHA_KEY),
    isTokenAutoRefreshEnabled: true
  })
}

The RecaptchaVerifier component is as follows

export const FirebaseRecaptcha = ({instructionMessage, onVerificationComplete}: FirebaseRecaptchaProps)=>{

    const [isCaptchaLoading, setCaptchaLoading] = useState(false)
    const [verificationErrored, setVerificationErrored]= useState(false)
  
    let verifier: any = null
    useEffect(()=>{
      console.log("Initializing captcha");
  
      verifier = new RecaptchaVerifier("recaptcha-container", {
        'size': 'invisible',
        'callback': function(response: any) {
          console.log("verification success")
          setCaptchaLoading(false)
          onVerificationComplete(CaptchaVerificationStatus.SUCCESS)
        }
      }, getAuth())
    },[])
  
    const onStartClick = async ()=> {
      if(verifier){
        try {
          setCaptchaLoading(true)
          console.log("About to verify")
          const res = await verifier.verify()
        }catch(e){
          setCaptchaLoading(false)
          console.error(e)
          onVerificationComplete(CaptchaVerificationStatus.FAIL)
        }
      }
    }
  
    // <Button variant="contained" color="primary" id={recaptchaButtonId} onClick={()=>onStartClick()} className={`${classes.actionButton} ${classes.bottomMargin}`}>
    //   Start
    // </Button>

    return (
        <>
          <div id="recaptcha-container"></div>
          <Typography variant="h6" gutterBottom sx={{mb: 2}}>
            {instructionMessage ? instructionMessage : getStrings().message_start_page}
          </Typography>
          {isCaptchaLoading ?
            <CircularProgress sx={{mb: 2}} /> :
            <Button variant="contained" color="primary" onClick={()=>onStartClick()} sx={{mb: 2, width: '50%'}}>
              {getStrings().button_start}
            </Button>
          }
        </>
      )
  }
@jbalidiong
Copy link
Contributor

Hi @faizanabidnaqvi, thanks for the report. I was able to reproduce the behavior now. Let me check what we can do for this issue or bring someone here that can provide more context about it. I’ll update this thread if I have any information to share.

@votenex
Copy link

votenex commented May 17, 2022

I am currently experiencing this. Phone signin worked before app check. After app check, getting error "this.getAssertedRecaptcha(...).render is not a function".

I unenforced app check for now since I need my website to require my users to register both email and phone. Hoping for a prompt resolution on this.

@votenex
Copy link

votenex commented May 26, 2022

Is there an update on this?

@VFertak
Copy link

VFertak commented Jun 15, 2022

any update on this issue?

@stjoe4
Copy link

stjoe4 commented Jun 21, 2022

any update?

@stjoe4
Copy link

stjoe4 commented Jun 21, 2022

It works with ReCaptchaV3Provider

@votenex
Copy link

votenex commented Jun 22, 2022

It works with ReCaptchaV3Provider

I used app check ReCaptchaV3Provider with phone signin. I had the same issue. So it worked for you?

@stjoe4
Copy link

stjoe4 commented Jun 23, 2022

Yes it works with ReCaptchaV3Provider, but have the same error with ReCaptchaEnterpriseProvider.

@weixifan
Copy link

Thank you for reporting this issue. We're looking into it. Internal bug filed: b/237289338.

@hsubox76
Copy link
Contributor

hsubox76 commented Jul 6, 2022

I actually haven't been able to reproduce this by using the code in the first post and trying to fill in the blanks. I've tried localhost dev server, localhost prod build, and deployed Firebase hosting, and they all work. Does anyone have a minimal repro I can use? (preferably one that errors in localhost, but if not, just let me know what environment)

@votenex
Copy link

votenex commented Jul 7, 2022

When I had this error, I tried both v3 and enterprise. It doesn't even get to the verify code part.

app check:

const appCheck = initializeAppCheck(firebaseApp, {
    provider: new ReCaptchaV3Provider('***********************'),
    isTokenAutoRefreshEnabled: true
});

phone auth:

setPersistence(auth, browserLocalPersistence)
        .then(() => {
            // Sign in
            signInWithPhoneNumber(auth, usermobile, recaptchaVerifier)
            .then((confirmationResult) => {
                $('#otpcode').show();
                $('#phone-signin-sendcode').hide();
                $('#phone-signin-verifycode').show();

                $('#phone-signin-verifycode').click(async function() {
                    const code = document.getElementById('otpcode').value;
                    window.confirmationResult = confirmationResult;

                    let x = {
                        mobile: usermobile,
                        userid: z,
                        code: code
                    }
                    verifyCode(x)
                })

            }).catch((error) => {
                alert('An error occurred! ' + error.code + " " + error.message);
                window.recaptchaVerifier.render().then(function(widgetId) {
                    grecaptcha.reset(widgetId);
                });
            });
        })
        .catch((error) => {
            alert('An error occurred! ' + error.code + " " + error.message);
        });

even if I used self.FIREBASE_APPCHECK_DEBUG_TOKEN = true; It still didn't work.

a few weeks ago, v3 started working for me. But enterprise still doesn't work.

@hsubox76
Copy link
Contributor

hsubox76 commented Jul 7, 2022

I'm able to reproduce with App Check's ReCaptchaEnterpriseProvider only, and I think I can get a quick fix done for that. If you're experiencing this error with ReCaptchaV3Provider, it would be great if you can provide a reliable minimal repro of it with all the extraneous parts stripped out. Will post a PR for the Enterprise fix soon.

@hsubox76
Copy link
Contributor

hsubox76 commented Jul 7, 2022

Let me keep this open because there's still some uncertainty about if there is a bug with RecaptchaV3.

@ehedaya
Copy link

ehedaya commented Aug 1, 2022

I have this error and it started when I switched from using regular recaptcha to enterprise recaptcha on my firebase project. Seems like there's a difference between the object that gets returned by enterprise vs normal recaptcha, this is the object with the missing method in debug mode
Screen Shot 2022-08-01 at 2 39 12 PM

it seems like it may be a result of both libraries (enterprise and non-, which is i assume what the auth library uses) loading on the same page

@hsubox76
Copy link
Contributor

hsubox76 commented Aug 1, 2022

This should be fixed in 9.9.1, if it's not the case, can you try a fresh reinstall to make sure nothing was left behind? (remove node_modules and yarn.lock and reinstall). If that doesn't work, can you provide a minimal repro? Similar comment from #6485 (comment):

I'm not able to reproduce this, are you sure you are using the latest version? It should have been fixed by #6133. Is it possible something got left over when upgrading from an older version? Can you clean out your node_modules and yarn.lock and try to reinstall firebase? I tried to create a minimal reproduction using this code:

const appCheck = initializeAppCheck(app, { provider: new ReCaptchaEnterpriseProvider('MY_SITE_KEY')});

const verifier = new RecaptchaVerifier('container', { size: 'invisible' }, getAuth(app));

const provider = new PhoneAuthProvider(getAuth(app));
await provider.verifyPhoneNumber('+1-510-555-5555', verifier);

And everything seemed to work. If a fresh install doesn't help, how and when are you initializing App Check? I didn't see it in the sample code.

It sounds like there may still be an issue but I'm unable to reproduce it on my end. I've tried swapping the order of App Check and RecaptchaVerifier and it doesn't seem to break it either.

@ehedaya
Copy link

ehedaya commented Aug 4, 2022

Thanks! That did fix it!

@hsubox76
Copy link
Contributor

I haven't heard back from the other person who reported it in #6485 so I'll close this again, can reopen if someone reports the problem again.

@firebase firebase locked and limited conversation to collaborators Sep 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants