@react-native-firebase/auth 19.2.2 → 19.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [19.3.0](https://github.com/invertase/react-native-firebase/compare/v19.2.2...v19.3.0) (2024-05-20)
7
+
8
+ ### Features
9
+
10
+ - include phoneNumber from PhoneMultiFactorInfo ([5acdfb3](https://github.com/invertase/react-native-firebase/commit/5acdfb306279560a9fdd31a35c80f3edca4d0d59))
11
+
12
+ ### Bug Fixes
13
+
14
+ - **auth, android:** change error code for invalid multi-factor session to match iOS WIP needs test ([0f15f2d](https://github.com/invertase/react-native-firebase/commit/0f15f2d36cfec807c42b91b53289fa699ffe4f66))
15
+ - **auth, android:** return credential for signin if phone auth has link collision ([#7793](https://github.com/invertase/react-native-firebase/issues/7793)) ([f8916e2](https://github.com/invertase/react-native-firebase/commit/f8916e25371d43db2bd8c22c7f35e8064edc6806))
16
+ - **auth, ios:** reject multi-factor API call if session not found ([3d61e32](https://github.com/invertase/react-native-firebase/commit/3d61e32394d83fae5d136d21ecbea71590a2adb7))
17
+
6
18
  ## [19.2.2](https://github.com/invertase/react-native-firebase/compare/v19.2.1...v19.2.2) (2024-04-13)
7
19
 
8
20
  **Note:** Version bump only for package @react-native-firebase/auth
@@ -49,6 +49,7 @@ import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
49
49
  import com.google.firebase.auth.FirebaseAuthMultiFactorException;
50
50
  import com.google.firebase.auth.FirebaseAuthProvider;
51
51
  import com.google.firebase.auth.FirebaseAuthSettings;
52
+ import com.google.firebase.auth.FirebaseAuthUserCollisionException;
52
53
  import com.google.firebase.auth.FirebaseUser;
53
54
  import com.google.firebase.auth.FirebaseUserMetadata;
54
55
  import com.google.firebase.auth.GetTokenResult;
@@ -107,6 +108,10 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
107
108
  private final HashMap<String, MultiFactorResolver> mCachedResolvers = new HashMap<>();
108
109
  private final HashMap<String, MultiFactorSession> mMultiFactorSessions = new HashMap<>();
109
110
 
111
+ // storage for anonymous phone auth credentials, used for linkWithCredentials
112
+ // https://github.com/invertase/react-native-firebase/issues/4911
113
+ private HashMap<String, AuthCredential> credentials = new HashMap<>();
114
+
110
115
  ReactNativeFirebaseAuthModule(ReactApplicationContext reactContext) {
111
116
  super(reactContext, TAG);
112
117
  }
@@ -914,9 +919,8 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
914
919
  return;
915
920
  }
916
921
 
917
- OAuthProvider.Builder builder = OAuthProvider.newBuilder(
918
- provider.getString("providerId"),
919
- firebaseAuth);
922
+ OAuthProvider.Builder builder =
923
+ OAuthProvider.newBuilder(provider.getString("providerId"), firebaseAuth);
920
924
  // Add scopes if present
921
925
  if (provider.hasKey("scopes")) {
922
926
  ReadableArray scopes = provider.getArray("scopes");
@@ -1184,7 +1188,7 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
1184
1188
  final Promise promise) {
1185
1189
  final MultiFactorSession multiFactorSession = mMultiFactorSessions.get(sessionKey);
1186
1190
  if (multiFactorSession == null) {
1187
- rejectPromiseWithCodeAndMessage(promise, "unknown", "can't find session for provided key");
1191
+ rejectPromiseWithCodeAndMessage(promise, "invalid-multi-factor-session", "can't find session for provided key");
1188
1192
  return;
1189
1193
  }
1190
1194
  FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
@@ -1613,6 +1617,17 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
1613
1617
  promiseWithAuthResult(task.getResult(), promise);
1614
1618
  } else {
1615
1619
  Exception exception = task.getException();
1620
+ if (exception instanceof FirebaseAuthUserCollisionException collEx) {
1621
+ AuthCredential updatedCredential = collEx.getUpdatedCredential();
1622
+ Log.d(TAG, "link:onComplete:collisionFailure", collEx);
1623
+ // If we have a credential in the error, we can return it, otherwise fall
1624
+ // through
1625
+ if (updatedCredential != null) {
1626
+ Log.d(TAG, "link:onComplete:collisionFailure had credential", collEx);
1627
+ promiseRejectLinkAuthException(promise, collEx, updatedCredential);
1628
+ return;
1629
+ }
1630
+ }
1616
1631
  Log.e(TAG, "link:onComplete:failure", exception);
1617
1632
  promiseRejectAuthException(promise, exception);
1618
1633
  }
@@ -1650,9 +1665,8 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
1650
1665
  return;
1651
1666
  }
1652
1667
 
1653
- OAuthProvider.Builder builder = OAuthProvider.newBuilder(
1654
- provider.getString("providerId"),
1655
- firebaseAuth);
1668
+ OAuthProvider.Builder builder =
1669
+ OAuthProvider.newBuilder(provider.getString("providerId"), firebaseAuth);
1656
1670
  // Add scopes if present
1657
1671
  if (provider.hasKey("scopes")) {
1658
1672
  ReadableArray scopes = provider.getArray("scopes");
@@ -1795,9 +1809,8 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
1795
1809
  return;
1796
1810
  }
1797
1811
 
1798
- OAuthProvider.Builder builder = OAuthProvider.newBuilder(
1799
- provider.getString("providerId"),
1800
- firebaseAuth);
1812
+ OAuthProvider.Builder builder =
1813
+ OAuthProvider.newBuilder(provider.getString("providerId"), firebaseAuth);
1801
1814
  // Add scopes if present
1802
1815
  if (provider.hasKey("scopes")) {
1803
1816
  ReadableArray scopes = provider.getArray("scopes");
@@ -1855,6 +1868,9 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
1855
1868
  if (provider.startsWith("oidc.")) {
1856
1869
  return OAuthProvider.newCredentialBuilder(provider).setIdToken(authToken).build();
1857
1870
  }
1871
+ if (credentials.containsKey(authToken) && credentials.get(authToken) != null) {
1872
+ return credentials.get(authToken);
1873
+ }
1858
1874
 
1859
1875
  switch (provider) {
1860
1876
  case "facebook.com":
@@ -2217,6 +2233,36 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
2217
2233
  promise, error.getString("code"), error.getString("message"), resolverAsMap);
2218
2234
  }
2219
2235
 
2236
+ /**
2237
+ * promiseRejectLinkAuthException
2238
+ *
2239
+ * @param promise
2240
+ * @param exception
2241
+ * @param authCredential
2242
+ */
2243
+ private void promiseRejectLinkAuthException(
2244
+ @NonNull Promise promise,
2245
+ @NonNull Exception exception,
2246
+ @NonNull AuthCredential authCredential) {
2247
+ WritableMap error = getJSError(exception);
2248
+ String authHashCode = String.valueOf(authCredential.hashCode());
2249
+
2250
+ WritableMap authCredentialsMap = Arguments.createMap();
2251
+ authCredentialsMap.putString("providerId", authCredential.getProvider());
2252
+ authCredentialsMap.putString("token", authHashCode);
2253
+ authCredentialsMap.putString("secret", null);
2254
+
2255
+ // Temporarily store the non-serializable credential for later
2256
+ credentials.put(authHashCode, authCredential);
2257
+
2258
+ WritableMap userInfoMap = Arguments.createMap();
2259
+ userInfoMap.putString("code", error.getString("code"));
2260
+ userInfoMap.putString("message", error.getString("message"));
2261
+ userInfoMap.putMap("authCredential", authCredentialsMap);
2262
+
2263
+ promise.reject(error.getString("code"), error.getString("message"), userInfoMap);
2264
+ }
2265
+
2220
2266
  /**
2221
2267
  * getJSError
2222
2268
  *
@@ -2507,6 +2553,10 @@ class ReactNativeFirebaseAuthModule extends ReactNativeFirebaseModule {
2507
2553
  hintMap.putString("factorId", hint.getFactorId());
2508
2554
  hintMap.putString("uid", hint.getUid());
2509
2555
 
2556
+ if (hint.getFactorId().equals(PhoneMultiFactorGenerator.FACTOR_ID)) {
2557
+ hintMap.putString("phoneNumber", ((PhoneMultiFactorInfo) hint).getPhoneNumber());
2558
+ }
2559
+
2510
2560
  return hintMap;
2511
2561
  }
2512
2562
 
@@ -578,7 +578,9 @@ RCT_EXPORT_METHOD(signInWithCredential
578
578
  @"has expired or is not currently supported.",
579
579
  }];
580
580
  }
581
- DLog(@"using app SignInWithCredential: %@", firebaseApp.name)[[FIRAuth authWithApp:firebaseApp]
581
+ DLog(@"using app SignInWithCredential: %@", firebaseApp.name);
582
+
583
+ [[FIRAuth authWithApp:firebaseApp]
582
584
  signInWithCredential:credential
583
585
  completion:^(FIRAuthDataResult *authResult, NSError *error) {
584
586
  if (error) {
@@ -820,8 +822,9 @@ RCT_EXPORT_METHOD(signInWithPhoneNumber
820
822
  : (NSString *)phoneNumber
821
823
  : (RCTPromiseResolveBlock)resolve
822
824
  : (RCTPromiseRejectBlock)reject) {
823
- DLog(@"SignInWthPhoneNumber instance: %@",
824
- firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
825
+ DLog(@"SignInWthPhoneNumber instance: %@", firebaseApp.name);
826
+
827
+ [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
825
828
  verifyPhoneNumber:phoneNumber
826
829
  UIDelegate:nil
827
830
  completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) {
@@ -862,8 +865,9 @@ RCT_EXPORT_METHOD(verifyPhoneNumberWithMultiFactorInfo
862
865
  }];
863
866
  return;
864
867
  }
865
- DLog(@"using instance verifyPhoneNumberWithMultiFactorInfo: %@",
866
- firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
868
+ DLog(@"using instance verifyPhoneNumberWithMultiFactorInfo: %@", firebaseApp.name);
869
+
870
+ [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
867
871
  verifyPhoneNumberWithMultiFactorInfo:hint
868
872
  UIDelegate:nil
869
873
  multiFactorSession:session
@@ -884,9 +888,19 @@ RCT_EXPORT_METHOD(verifyPhoneNumberForMultiFactor
884
888
  : (NSString *)sessionId
885
889
  : (RCTPromiseResolveBlock)resolve
886
890
  : (RCTPromiseRejectBlock)reject) {
891
+ DLog(@"verifyPhoneNumberForMultifactor using app: %@", firebaseApp.name);
892
+ DLog(@"verifyPhoneNumberForMultifactor phoneNumber: %@", phoneNumber);
893
+ DLog(@"verifyPhoneNumberForMultifactor sessionId: %@", sessionId);
887
894
  FIRMultiFactorSession *session = cachedSessions[sessionId];
888
- DLog(@"using instance VerifyPhoneNumberForMultifactor: %@",
889
- firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
895
+ if (session == nil) {
896
+ [RNFBSharedUtils rejectPromiseWithUserInfo:reject
897
+ userInfo:(NSMutableDictionary *)@{
898
+ @"code" : @"invalid-multi-factor-session",
899
+ @"message" : @"can't find session for provided key"
900
+ }];
901
+ return;
902
+ }
903
+ [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
890
904
  verifyPhoneNumber:phoneNumber
891
905
  UIDelegate:nil
892
906
  multiFactorSession:session
@@ -907,12 +921,15 @@ RCT_EXPORT_METHOD(resolveMultiFactorSignIn
907
921
  : (NSString *)verificationCode
908
922
  : (RCTPromiseResolveBlock)resolve
909
923
  : (RCTPromiseRejectBlock)reject) {
910
- DLog(@"using instance resolve MultiFactorSignIn: %@", firebaseApp.name)
911
- FIRPhoneAuthCredential *credential =
912
- [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
913
- credentialWithVerificationID:verificationId
914
- verificationCode:verificationCode];
915
- DLog(@"credential: %@", credential) FIRMultiFactorAssertion *assertion =
924
+ DLog(@"using instance resolve MultiFactorSignIn: %@", firebaseApp.name);
925
+
926
+ FIRPhoneAuthCredential *credential =
927
+ [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
928
+ credentialWithVerificationID:verificationId
929
+ verificationCode:verificationCode];
930
+ DLog(@"credential: %@", credential);
931
+
932
+ FIRMultiFactorAssertion *assertion =
916
933
  [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
917
934
 
918
935
  [cachedResolver[sessionKey] resolveSignInWithAssertion:assertion
@@ -955,11 +972,12 @@ RCT_EXPORT_METHOD(finalizeMultiFactorEnrollment
955
972
  : (NSString *_Nullable)displayName
956
973
  : (RCTPromiseResolveBlock)resolve
957
974
  : (RCTPromiseRejectBlock)reject) {
958
- DLog(@"using instance finalizeMultifactorEnrollment: %@", firebaseApp.name)
959
- FIRPhoneAuthCredential *credential =
960
- [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
961
- credentialWithVerificationID:verificationId
962
- verificationCode:verificationCode];
975
+ DLog(@"using instance finalizeMultifactorEnrollment: %@", firebaseApp.name);
976
+
977
+ FIRPhoneAuthCredential *credential =
978
+ [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
979
+ credentialWithVerificationID:verificationId
980
+ verificationCode:verificationCode];
963
981
  FIRMultiFactorAssertion *assertion =
964
982
  [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
965
983
  FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
@@ -980,8 +998,9 @@ RCT_EXPORT_METHOD(verifyPhoneNumber
980
998
  : (FIRApp *)firebaseApp
981
999
  : (NSString *)phoneNumber
982
1000
  : (NSString *)requestKey) {
983
- DLog(@"using instance verifyPhoneNumber: %@",
984
- firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
1001
+ DLog(@"using instance verifyPhoneNumber: %@", firebaseApp.name);
1002
+
1003
+ [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
985
1004
  verifyPhoneNumber:phoneNumber
986
1005
  UIDelegate:nil
987
1006
  completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) {
@@ -1695,6 +1714,8 @@ RCT_EXPORT_METHOD(useEmulator
1695
1714
  @"enrollmentTime" : enrollmentTime,
1696
1715
  // @deprecated enrollmentDate kept for backwards compatibility, please use enrollmentTime
1697
1716
  @"enrollmentDate" : enrollmentTime,
1717
+ // phoneNumber only present on FIRPhoneMultiFactorInfo
1718
+ @"phoneNumber" : hint.phoneNumber == nil ? [NSNull null] : hint.phoneNumber,
1698
1719
  }];
1699
1720
  }
1700
1721
  return enrolledFactors;
package/lib/index.d.ts CHANGED
@@ -472,7 +472,21 @@ export namespace FirebaseAuthTypes {
472
472
  /**
473
473
  * Contains information about a second factor.
474
474
  */
475
- export interface MultiFactorInfo {
475
+ export type MultiFactorInfo = PhoneMultiFactorInfo | TotpMultiFactorInfo;
476
+
477
+ export interface PhoneMultiFactorInfo extends MultiFactorInfoCommon {
478
+ factorId: 'phone';
479
+ /**
480
+ * The phone number used for this factor.
481
+ */
482
+ phoneNumber: string;
483
+ }
484
+
485
+ export interface TotpMultiFactorInfo extends MultiFactorInfoCommon {
486
+ factorId: 'totp';
487
+ }
488
+
489
+ export interface MultiFactorInfoCommon {
476
490
  /**
477
491
  * User friendly name for this factor.
478
492
  */
@@ -481,10 +495,6 @@ export namespace FirebaseAuthTypes {
481
495
  * Time the second factor was enrolled, in UTC.
482
496
  */
483
497
  enrollmentTime: string;
484
- /**
485
- * Type of factor.
486
- */
487
- factorId: FactorId;
488
498
  /**
489
499
  * Unique id for this factor.
490
500
  */
package/lib/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- module.exports = '19.2.2';
2
+ module.exports = '19.3.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-firebase/auth",
3
- "version": "19.2.2",
3
+ "version": "19.3.0",
4
4
  "author": "Invertase <oss@invertase.io> (http://invertase.io)",
5
5
  "description": "React Native Firebase - The authentication module provides an easy-to-use API to integrate an authentication workflow into new and existing applications. React Native Firebase provides access to all Firebase authentication methods and identity providers.",
6
6
  "main": "lib/index.js",
@@ -27,7 +27,7 @@
27
27
  "plist": "^3.1.0"
28
28
  },
29
29
  "peerDependencies": {
30
- "@react-native-firebase/app": "19.2.2",
30
+ "@react-native-firebase/app": "19.3.0",
31
31
  "expo": ">=47.0.0"
32
32
  },
33
33
  "devDependencies": {
@@ -42,5 +42,5 @@
42
42
  "publishConfig": {
43
43
  "access": "public"
44
44
  },
45
- "gitHead": "2c1f48eacba95904c89073dcb391d89d0f966165"
45
+ "gitHead": "edac62269c1b3088cadf74586d48f68214d6e8e4"
46
46
  }