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

feat: Enabling multi-factor authentication #346

Open
typefox09 opened this issue Mar 25, 2023 · 1 comment
Open

feat: Enabling multi-factor authentication #346

typefox09 opened this issue Mar 25, 2023 · 1 comment

Comments

@typefox09
Copy link

typefox09 commented Mar 25, 2023

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
Copy link

FYI: #38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants