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(auth): Add multi-factor support for the sign-in flow #6593

Merged
merged 9 commits into from
Oct 26, 2022

Conversation

fzuellich
Copy link
Contributor

@fzuellich fzuellich commented Oct 6, 2022

Description

At Kyan Health we are using react-native-firebase for our mobile apps. We plan to roll out multi-factor authentication to our users soon. After implementing the necessary code on the web (using the original Firebase libraries) we were missing multi-factor support for the apps.

I'm aware that there are a few small todos left in the code. Nonetheless I'd appreciate some early feedback from the maintainers to see how we can get the PR merged. :)

Open questions on our side:

  • I'm not sure if I'm supposed to add a license header to new files. Let me know and I'm happy to copy the existing header into the newly created files.
  • I'm running into a lot of trouble with testing the iOS part against the Firebase emulator. I marked these tests with :android:. I have the feeling that this is not properly implemented on Firebase' side. Testing against a real life Firebase project doesn't run into issues with missing multi-factor authentication. I also find it strange the the Firebase emulator prints a different SMS code message for iOS devices (masks the phone number). Any thought or hints how to solve this problem? 😇

Related issues

I'm aware of:

Release Summary

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
    • Yes
  • My change supports the following platforms;
    • Android
    • iOS
  • My change includes tests;
    • e2e tests added or updated in packages/\*\*/e2e
    • jest tests added or updated in packages/\*\*/__tests__
  • I have updated TypeScript types that are affected by my change.
  • This is a breaking change;
    • Yes
    • No

Test Plan

  • e2e tests run
  • I could verify the multi-factor enrollment and sign-in with a real world Firebase project (iOS)
    🔥

@vercel
Copy link

vercel bot commented Oct 6, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated
react-native-firebase ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Oct 24, 2022 at 7:31AM (UTC)
1 Ignored Deployment
Name Status Preview Comments Updated
react-native-firebase-next ⬜️ Ignored (Inspect) Oct 24, 2022 at 7:31AM (UTC)

@CLAassistant
Copy link

CLAassistant commented Oct 6, 2022

CLA assistant check
All committers have signed the CLA.

@fzuellich fzuellich changed the title Add multi-factor support for the sign-in flow feat(auth): Add multi-factor support for the sign-in flow Oct 6, 2022
docs/auth/phone-auth.md Outdated Show resolved Hide resolved
packages/auth/lib/index.js Outdated Show resolved Hide resolved
packages/auth/lib/index.js Outdated Show resolved Hide resolved
docs/auth/mfa-auth.md Outdated Show resolved Hide resolved
@mikehardy
Copy link
Collaborator

I'm really sorry I haven't gotten to this yet - I really want this functionality, I truly appreciate the PR, and I will collaborate with you to get it merged+released. I appreciate the patience

Copy link
Collaborator

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, this looks like excellent work. Finally got a chance to review through it.
I left some mostly-trivial / easy to resolve comments, what do you think?

How is this working for you currently? Does it seem to work? You may not have had a chance to test integrate it yet as the CI runs require approval for first-time PRs so the patch-package patch set is not being generated until I approve.

I just approved a run now which should kick out patches for test integration case that helps

docs/auth/phone-auth.md Show resolved Hide resolved
});

describe('sign-in', function () {
it(':android: requires multi-factor auth when enrolled', async function () {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting - I'm not familiar with this it(':android: <description>' form of exclusion, is this documented somewhere?

Historically we have been doing the if (<Platform conditional here>) { do the test } else { this.skip() } style I believe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running the tests e.g. yarn run tests:android:test it outputs the mocha command which uses a grep option:

mocha --config e2e/.mocharc.js --configuration android.emu.debug --grep :ios: --invert --use-custom-logger true e2e

After a quick Google search I couldn't find Detox documentation describing the feature, just some issues:
wix/Detox#712

And a test covering this behaviour: https://github.com/wix/Detox/blob/master/detox/local-cli/test.test.js#L78

Should I move it to the style you mention?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me see what the output looks like after the e2e runs, as long as there is still evidence in the output that there is a test but it is skipped (and the total test count / skipped test count registers them), that's the real goal for me. How they are skipped isn't so important

Copy link
Collaborator

@mikehardy mikehardy Oct 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not appear to show up in list of skipped tests (it would be an entry with a - like this) so I don't think this works well - it hides them too well. I'd prefer the if-platform/else-skip style

  multi-factor
    ✔ has no multi-factor information if not enrolled
    ✔ can not reuse session after logout (1035ms)
    enroll
      ✔ throws an error for unknown sessions
      ✔ throws an error for unknown verification code

https://github.com/invertase/react-native-firebase/actions/runs/3271818247/jobs/5385708987#step:23:282

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :)

packages/auth/e2e/multiFactor.e2e.js Outdated Show resolved Hide resolved
.auth()
.verifyPhoneNumberForMultiFactor({ phoneNumber: getRandomPhoneNumber(), session });
} catch (e) {
// TODO fix in code to match web
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still an active TODO item?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is one of the TODOs I mentioned. There is at least one more in the Android code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The todos are sovled now :)

packages/auth/e2e/multiFactor.e2e.js Show resolved Hide resolved
@mikehardy mikehardy added the Workflow: Waiting for User Response Blocked waiting for user response. label Oct 17, 2022
@mikehardy
Copy link
Collaborator

Oh - should have written this as nearly the first thing: the test support is absolutely fantastic, really really appreciated. It gives me so much more confidence during review that it does in fact work, knowing it's got e2e tests going with coverage we can see

@mikehardy
Copy link
Collaborator

Interesting jest failure, referencing appCheck package? Is that a transitive dep of MFA? 🤔


  ● Auth › getMultiFactorResolver › should return the resolver object if its found

    You attempted to use "firebase.app('[DEFAULT]').appCheck" but this module could not be found.

    Ensure you have installed and imported the '@react-native-firebase/app-check' package.

Formatting failure can be fixed with

"lint:ios:fix": "clang-format -i --glob=\"packages/**/ios/**/*.{h,cpp,m,mm}\" --style=Google",

(likewise if there is an android one, just run yarn lint:android locally - possibly a few times until it passes, then commit the result, and for javascript yarn lint:js --fix and/or yarn lint:markdown --write I think - I forget exactly, but basically getting those to not just check but also fix things in place, then commit result

@fzuellich
Copy link
Contributor Author

fzuellich commented Oct 18, 2022

Very happy to hear you are happy with the PR! :)

Already resolved some of the more trivial comments. I hope I get a chance to look at the rest today, but can't promise it.

How is this working for you currently? Does it seem to work? You may not have had a chance to test integrate it yet as the CI runs require approval for first-time PRs so the patch-package patch set is not being generated until I approve.

I'm linking the package using yalc and played around with it in the iOS simulator (mostly sign-in) yesterday. I'm running the code using our app and against a real Firebase environment. I can also confirm that the Recaptcha part is working. I have a draft for the enroll part lying around somewhere that I'd like to test today. I need to check the Android part is working as well. I hope I get a chance today.

Open todos:

  • Fix todos in the code
  • Investigate app-check warning
  • Possibly change the platform-specific tests to use if instead of :android:

@codecov
Copy link

codecov bot commented Oct 18, 2022

Codecov Report

Merging #6593 (1ecb350) into main (fe2bebe) will increase coverage by 17.67%.
The diff coverage is 56.58%.

❗ Current head 1ecb350 differs from pull request most recent head ce15f02. Consider uploading reports for the commit ce15f02 to get more accurate results

@@              Coverage Diff              @@
##               main    #6593       +/-   ##
=============================================
+ Coverage     54.53%   72.20%   +17.67%     
=============================================
  Files           209      115       -94     
  Lines         10399     4754     -5645     
  Branches       1650     1064      -586     
=============================================
- Hits           5670     3432     -2238     
+ Misses         4445     1240     -3205     
+ Partials        284       82      -202     

@mikehardy
Copy link
Collaborator

You may want to rebase this against current main - I've just ingested the major releases firebase-ios-sdk v10 and firebase-android-sdk v31, and on android they did fix a multi-factor issue:

https://firebase.google.com/support/release-notes/android#auth_v21-1-0

The releases themselves are otherwise very low impact (in my opinion), with the only actual breaking change that affects react-native-firebase being a higher minimum iOS target (11) now

I enhanced the android e2e stability as well so CI shouldn't be so finicky.

Other than that, I'll stand by until I hear the "all clear" then I can test through this again. No pressure at all of course, but I am excited to see it merged, whenever it is ready. Cheers

@fzuellich
Copy link
Contributor Author

You may want to rebase this against current main - I've just ingested the major releases firebase-ios-sdk v10 and firebase-android-sdk v31, and on android they did fix a multi-factor issue:

https://firebase.google.com/support/release-notes/android#auth_v21-1-0

Awesome, that explains the broken timestamp when using Android! Do you want me to do a rebase and push-force or rather merge main into this branch?

We have some urgent stuff going right now, so I get less done than I would like.

@fzuellich
Copy link
Contributor Author

The latest commits should fix all todos for this PR. I double checked linting 🤞

Currently I'm unable to integrate the latest changes into our app using yalc. Some classpath issues for Android and iOS. I hope this is resolved when I switch to a patch-package.

Please test through this again. :)

@mikehardy
Copy link
Collaborator

Huh - never heard of yalc before, interesting! Either way, CI running now, should be a new patch-package set shortly and since I just released (again) last night the patch set will be clean

to match the error message produced by the Web.
@fzuellich
Copy link
Contributor Author

I did some more testing and discovered two smaller issues with the error handling. I pushed the fixes as two commits. I hope it makes it easier to review the changes.

@mikehardy
Copy link
Collaborator

🤔

❌ /Users/runner/work/react-native-firebase/react-native-firebase/packages/auth/ios/RNFBAuth/RNFBAuthModule.m:786:1: extraneous closing brace ('}')
}

to match the error message produced by the Web.
@fzuellich
Copy link
Contributor Author

Hola @mikehardy, I pushed a fix for that syntax error. If you get a chance can you let the checks run again? :)

@mikehardy mikehardy self-requested a review October 25, 2022 15:10
@mikehardy mikehardy added Workflow: Needs Review Pending feedback or review from a maintainer. and removed Workflow: Waiting for User Response Blocked waiting for user response. labels Oct 25, 2022
@mikehardy
Copy link
Collaborator

Green CI is a beautiful thing - I'll do one more review pass through here but I imagine this is good to go if it is working for you - the patch-set may be useful in verifying same ?

@fzuellich
Copy link
Contributor Author

I'm quite happy with the iOS part so far (using the patch set). Still having trouble with the Android side due to

Duplicate class com.google.firebase.iid.FirebaseInstanceIdReceiver found in modules jetified-firebase-iid-20.0.1-runtime (com.google.firebase:firebase-iid:20.0.1) and jetified-firebase-messaging-23.1.0-runtime (com.google.firebase:firebase-messaging:23.1.0)

So far the internet wasn't too useful to fix this issue and I secretly hope this will magically solve itself once we have a real package. 🙈

@mikehardy
Copy link
Collaborator

That one is a pain!

// temporary workaround: https://github.com/firebase/firebase-android-sdk/issues/4206
implementation 'com.google.firebase:firebase-iid:21.1.0'

firebase/firebase-android-sdk#4206

@fzuellich
Copy link
Contributor Author

Thanks Mike, your suggestion fixed it! I need to improve my Google powers ;)

I walked through the enrollment and sign-in using Android as well. It works for us 🥳

@mikehardy
Copy link
Collaborator

mikehardy commented Oct 26, 2022

Fantastic, so my status understanding is no known issues/ ready for final review+merge release (hopefully) then. Enqueued for me as such

@fzuellich
Copy link
Contributor Author

Sounds good. I'm sure we'll be the first to open a PR if we find a bug. 😇 Do you have an ETA that I can communicate to management?

Copy link
Collaborator

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-scanned it all for final review ✅
Tested e2e locally after pulling current main + rebase (just to be sure)

  • ios ✅
  • android ✅

Merging now, will release in just a moment so should be available as 16.3.0 in a few minutes.

You can communicate to management that the quality of the PR and attention to detail on testing gives me a really high level of confidence, making quick review possible and leading to me shipping it immediately despite the size of the PR, how's that vs an ETA ;-)?. This is a fantastic addition to the module, I really appreciate it and I'm sure others hoping for it will be thrilled as well. Happy to collaborate on any followups as needed if (or when, it's a big feature...) something comes up. Cheers

@mikehardy mikehardy merged commit 3c64bf5 into invertase:main Oct 26, 2022
@mikehardy mikehardy removed the Workflow: Needs Review Pending feedback or review from a maintainer. label Oct 26, 2022
@fzuellich fzuellich deleted the add-multi-factor-support branch October 26, 2022 18:26
@fzuellich
Copy link
Contributor Author

That sounds awesome. Thank you so much for the collaboration!

@mikehardy
Copy link
Collaborator

@fzuellich not sure if this is relevant for you or not, but saw it in the release notes for just-released 10.1.0 of firebase-ios-sdk and thought you might be interested, it just released: firebase/firebase-ios-sdk#10296

I'm releasing the SDK update packaged into a version here shortly so that fix (among others) will be generally available here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hacktoberfest-accepted Let's plant some trees!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants