capawesome-team / capacitor-firebase

⚡️ Firebase plugins for Capacitor. Supports Android, iOS and the Web.
https://capawesome.io/plugins/firebase/
Apache License 2.0
373 stars 97 forks source link

feat: Enabling multi-factor authentication #346

Open typefox09 opened 1 year ago

typefox09 commented 1 year ago

Is your feature request related to a problem? Please describe: Currently we are using this package to handle sign in on the native layer while also authenticating on the webview layer.

On the web we are using the Firebase JS SDK instead.

Firebase has launched their Authentication with Identity Platform, and with this we are able to add MFA to our original authentication system.

On web the process is clear as we use the Firebase JS SDK there.

However, when on Capacitor, will we be able to use this package's authentication system to handle the first factor of authentication, and then use the Firebase SDK to handle the 2nd form? Or will this need to be handled on the native layer (using the native SDK libraries)?

Documentation link for reference: https://cloud.google.com/identity-platform/docs/web/mfa?hl=en&_ga=2.262969740.-1034451470.1673398115

I've dived in to try it and here are my findings:

When doing this on the web and on Android, everything works as expected. When you try to log in FirebaseAuthentication does return the error to the client 'auth/multi-factor-auth-required' . This means we can proceed to sending an SMS code on the client to verify.

However, when attempting this on iOS: -Attempting to enroll a user in MFA, step 2 (recaptcha) fails and the error "FirebaseError: Firebase: Error (auth/internal-error)." is returned.

After checking the Ionic forum (link below), it appears others are having this same issue. It looks like the web version of the MFA fails to load the Recaptcha on iOS?

My theory: Recaptcha is suppose to authenticate the domain against what's on Firebase's records, I think the ionic:// added to iOS capacitor apps is the cause of this issue.

Describe the solution you'd like: Add the additional functionality to enable Firebase's MFA (for iOS). This would mean using the native iOS MFA Firebase SDK

It actually doesn't seem to be too much work as a lot of the code has been written for the single factor signInWithPhoneNumber method, this would simply add a little bit more and call it slightly differently (while reusing most of your old methods). I would do it but I'm not a native iOS developer 😅

Ionic forum link: https://forum.ionicframework.com/t/ios-firebase-mfa-error/223988

iOS Native SDK for MFA: https://firebase.google.com/docs/auth/ios/multi-factor?authuser=0&hl=en

Code for reference:

           // Sign in with Google for first factor auth

            const result = await FirebaseAuthentication.signInWithGoogle()
            const credential = GoogleAuthProvider.credential(result.credential?.idToken)
            const userCredential = await signInWithCredential(auth, credential)
            const user = userCredential.user

           // Add Recaptcha step to prevent abuse
           const recaptchaVerifier = new RecaptchaVerifier(this.$refs.signInButton, {"size": "invisible"}, auth)

           //Request phone number from user to enroll in MFA.  (THIS FAILS ON iOS due to recaptchaVerifier result being null)
             const multiFactorSession = await multiFactor(user).getSession()
            const phoneInfoOptions = {
                phoneNumber: this.number,
                session: multiFactorSession
                }
             },
             const phoneAuthProvider = new PhoneAuthProvider(auth)
             const verificationId = await phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)

             //Get verification code and enroll
             const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
             const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
             const final = await multiFactor(user).enroll(multiFactorAssertion, "My personal phone number");
VictorienTardif commented 6 months ago

FYI: https://github.com/capawesome-team/capacitor-firebase/issues/38