@react-native-firebase/auth 26.4.0 → 27.0.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 +18 -0
- package/RNFBAuth.podspec +8 -2
- package/android/build.gradle +3 -0
- package/android/src/main/java/io/invertase/firebase/auth/NativeRNFBTurboAuth.java +1 -3
- package/android/src/main/java/io/invertase/firebase/auth/RNFBAuthCacheRegistry.kt +77 -0
- package/android/src/main/java/io/invertase/firebase/auth/RNFBAuthListenerRegistry.kt +76 -0
- package/android/src/test/java/io/invertase/firebase/auth/RNFBAuthCacheRegistryTest.java +12 -0
- package/dist/module/index.js +1 -2
- package/dist/module/index.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/types/internal.d.ts +2 -3
- package/dist/typescript/lib/types/internal.d.ts.map +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/ios/RNFBAuth/RNFBAuthCacheRegistry.m +27 -8
- package/ios/RNFBAuth/RNFBAuthCacheRegistryStorage.swift +53 -0
- package/ios/RNFBAuth/RNFBAuthErrorCodeMapper.swift +333 -0
- package/ios/RNFBAuth/RNFBAuthHelper.m +24 -154
- package/ios/RNFBAuth/RNFBAuthListenerRegistry.m +26 -26
- package/ios/RNFBAuth/RNFBAuthListenerRegistryStorage.swift +76 -0
- package/ios/RNFBAuth/RNFBAuthNullSentinelDecoder.h +40 -0
- package/ios/RNFBAuth/RNFBAuthNullSentinelDecoder.m +49 -0
- package/ios/RNFBAuth.xcodeproj/project.pbxproj +22 -0
- package/ios/RNFBAuthUnitTests/RNFBAuthCacheRegistryStorageTests.swift +72 -0
- package/ios/RNFBAuthUnitTests/RNFBAuthErrorCodeMapperTests.swift +250 -0
- package/ios/RNFBAuthUnitTests/RNFBAuthListenerRegistryStorageTests.swift +122 -0
- package/ios/RNFBAuthUnitTests/RNFBAuthNullSentinelDecodeTests.m +78 -0
- package/ios/RNFBAuthUnitTests/RNFBAuthUnitTests.xcodeproj/project.pbxproj +50 -0
- package/lib/index.ts +1 -1
- package/lib/types/internal.ts +2 -2
- package/lib/version.ts +1 -1
- package/package.json +4 -4
- package/plugin/build/index.js +4 -0
- package/plugin/build/ios/index.d.ts +2 -1
- package/plugin/build/ios/index.js +3 -1
- package/plugin/build/ios/openUrlFix.js +12 -0
- package/plugin/build/ios/sceneDelegate.d.ts +34 -0
- package/plugin/build/ios/sceneDelegate.js +127 -0
- package/plugin/build/ios/sceneLifecycle.d.ts +32 -0
- package/plugin/build/ios/sceneLifecycle.js +115 -0
- package/plugin/src/index.ts +9 -1
- package/plugin/src/ios/index.ts +2 -1
- package/plugin/src/ios/openUrlFix.ts +15 -0
- package/plugin/src/ios/sceneDelegate.ts +159 -0
- package/plugin/src/ios/sceneLifecycle.ts +134 -0
- package/plugin/tsconfig.tsbuildinfo +1 -1
- package/android/src/main/java/io/invertase/firebase/auth/RNFBAuthCacheRegistry.java +0 -66
- package/android/src/main/java/io/invertase/firebase/auth/RNFBAuthListenerRegistry.java +0 -76
|
@@ -39,6 +39,17 @@
|
|
|
39
39
|
#import "RNFBAuthCacheRegistry.h"
|
|
40
40
|
#import "RNFBAuthHelper.h"
|
|
41
41
|
#import "RNFBAuthListenerRegistry.h"
|
|
42
|
+
#import "RNFBAuthNullSentinelDecoder.h"
|
|
43
|
+
|
|
44
|
+
#if __has_include(<RNFBAuth/RNFBAuth-Swift.h>)
|
|
45
|
+
#import <RNFBAuth/RNFBAuth-Swift.h>
|
|
46
|
+
#elif __has_include("RNFBAuth-Swift.h")
|
|
47
|
+
#import "RNFBAuth-Swift.h"
|
|
48
|
+
#elif __has_include("RNFBHandleMapStorage-Swift.inc")
|
|
49
|
+
#import "RNFBHandleMapStorage-Swift.inc"
|
|
50
|
+
#else
|
|
51
|
+
#error "RNFBAuthErrorCodeMapper Swift interface not found"
|
|
52
|
+
#endif
|
|
42
53
|
|
|
43
54
|
@interface RNFBAuthListenerRemover : NSObject
|
|
44
55
|
@property(nonatomic, copy, nullable) void (^onRemove)(void);
|
|
@@ -88,68 +99,6 @@ static NSString *const AUTH_STATE_CHANGED_EVENT = @"auth_state_changed";
|
|
|
88
99
|
static NSString *const AUTH_ID_TOKEN_CHANGED_EVENT = @"auth_id_token_changed";
|
|
89
100
|
static NSString *const PHONE_AUTH_STATE_CHANGED_EVENT = @"phone_auth_state_changed";
|
|
90
101
|
|
|
91
|
-
static NSString *const AuthErrorCode_toJSErrorCode[] = {
|
|
92
|
-
[FIRAuthErrorCodeInvalidCustomToken] = @"invalid-custom-token",
|
|
93
|
-
[FIRAuthErrorCodeCustomTokenMismatch] = @"custom-token-mismatch",
|
|
94
|
-
[FIRAuthErrorCodeInvalidCredential] = @"invalid-credential",
|
|
95
|
-
[FIRAuthErrorCodeUserDisabled] = @"user-disabled",
|
|
96
|
-
[FIRAuthErrorCodeOperationNotAllowed] = @"operation-not-allowed",
|
|
97
|
-
[FIRAuthErrorCodeEmailAlreadyInUse] = @"email-already-in-use",
|
|
98
|
-
[FIRAuthErrorCodeInvalidEmail] = @"invalid-email",
|
|
99
|
-
[FIRAuthErrorCodeWrongPassword] = @"wrong-password",
|
|
100
|
-
[FIRAuthErrorCodeTooManyRequests] = @"too-many-requests",
|
|
101
|
-
[FIRAuthErrorCodeUserNotFound] = @"user-not-found",
|
|
102
|
-
[FIRAuthErrorCodeAccountExistsWithDifferentCredential] =
|
|
103
|
-
@"account-exists-with-different-credential",
|
|
104
|
-
[FIRAuthErrorCodeRequiresRecentLogin] = @"requires-recent-login",
|
|
105
|
-
[FIRAuthErrorCodeProviderAlreadyLinked] = @"provider-already-linked",
|
|
106
|
-
[FIRAuthErrorCodeNoSuchProvider] = @"no-such-provider",
|
|
107
|
-
[FIRAuthErrorCodeInvalidUserToken] = @"invalid-user-token",
|
|
108
|
-
[FIRAuthErrorCodeNetworkError] = @"network-request-failed",
|
|
109
|
-
[FIRAuthErrorCodeUserTokenExpired] = @"user-token-expired",
|
|
110
|
-
[FIRAuthErrorCodeInvalidAPIKey] = @"invalid-api-key",
|
|
111
|
-
[FIRAuthErrorCodeUserMismatch] = @"user-mismatch",
|
|
112
|
-
[FIRAuthErrorCodeCredentialAlreadyInUse] = @"credential-already-in-use",
|
|
113
|
-
[FIRAuthErrorCodeWeakPassword] = @"weak-password",
|
|
114
|
-
[FIRAuthErrorCodeAppNotAuthorized] = @"app-not-authorized",
|
|
115
|
-
[FIRAuthErrorCodeExpiredActionCode] = @"expired-action-code",
|
|
116
|
-
[FIRAuthErrorCodeInvalidActionCode] = @"invalid-action-code",
|
|
117
|
-
[FIRAuthErrorCodeInvalidMessagePayload] = @"invalid-message-payload",
|
|
118
|
-
[FIRAuthErrorCodeInvalidSender] = @"invalid-sender",
|
|
119
|
-
[FIRAuthErrorCodeInvalidRecipientEmail] = @"invalid-recipient-email",
|
|
120
|
-
[FIRAuthErrorCodeMissingEmail] = @"invalid-email",
|
|
121
|
-
[FIRAuthErrorCodeMissingIosBundleID] = @"missing-ios-bundle-id",
|
|
122
|
-
[FIRAuthErrorCodeMissingAndroidPackageName] = @"missing-android-pkg-name",
|
|
123
|
-
[FIRAuthErrorCodeUnauthorizedDomain] = @"unauthorized-domain",
|
|
124
|
-
[FIRAuthErrorCodeInvalidContinueURI] = @"invalid-continue-uri",
|
|
125
|
-
[FIRAuthErrorCodeMissingContinueURI] = @"missing-continue-uri",
|
|
126
|
-
[FIRAuthErrorCodeMissingPhoneNumber] = @"missing-phone-number",
|
|
127
|
-
[FIRAuthErrorCodeInvalidPhoneNumber] = @"invalid-phone-number",
|
|
128
|
-
[FIRAuthErrorCodeMissingVerificationCode] = @"missing-verification-code",
|
|
129
|
-
[FIRAuthErrorCodeInvalidVerificationCode] = @"invalid-verification-code",
|
|
130
|
-
[FIRAuthErrorCodeMissingVerificationID] = @"missing-verification-id",
|
|
131
|
-
[FIRAuthErrorCodeInvalidVerificationID] = @"invalid-verification-id",
|
|
132
|
-
[FIRAuthErrorCodeMissingAppCredential] = @"missing-app-credential",
|
|
133
|
-
[FIRAuthErrorCodeInvalidAppCredential] = @"invalid-app-credential",
|
|
134
|
-
[FIRAuthErrorCodeSessionExpired] = @"code-expired",
|
|
135
|
-
[FIRAuthErrorCodeQuotaExceeded] = @"quota-exceeded",
|
|
136
|
-
[FIRAuthErrorCodeMissingAppToken] = @"missing-apns-token",
|
|
137
|
-
[FIRAuthErrorCodeNotificationNotForwarded] = @"notification-not-forwarded",
|
|
138
|
-
[FIRAuthErrorCodeAppNotVerified] = @"app-not-verified",
|
|
139
|
-
[FIRAuthErrorCodeCaptchaCheckFailed] = @"captcha-check-failed",
|
|
140
|
-
[FIRAuthErrorCodeWebContextAlreadyPresented] = @"cancelled-popup-request",
|
|
141
|
-
[FIRAuthErrorCodeWebContextCancelled] = @"popup-closed-by-user",
|
|
142
|
-
[FIRAuthErrorCodeAppVerificationUserInteractionFailure] =
|
|
143
|
-
@"app-verification-user-interaction-failure",
|
|
144
|
-
[FIRAuthErrorCodeInvalidClientID] = @"invalid-oauth-client-id",
|
|
145
|
-
[FIRAuthErrorCodeWebNetworkRequestFailed] = @"network-request-failed",
|
|
146
|
-
[FIRAuthErrorCodeWebInternalError] = @"internal-error",
|
|
147
|
-
[FIRAuthErrorCodeNullUser] = @"null-user",
|
|
148
|
-
[FIRAuthErrorCodeKeychainError] = @"keychain-error",
|
|
149
|
-
[FIRAuthErrorCodeInternalError] = @"internal-error",
|
|
150
|
-
[FIRAuthErrorCodeMalformedJWT] = @"malformed-jwt",
|
|
151
|
-
[FIRAuthErrorCodeSecondFactorRequired] = @"multi-factor-auth-required"};
|
|
152
|
-
|
|
153
102
|
static __strong RNFBAuthListenerRegistry *authStateHandlers;
|
|
154
103
|
static __strong RNFBAuthListenerRegistry *idTokenHandlers;
|
|
155
104
|
static __strong NSMutableDictionary *emulatorConfigs;
|
|
@@ -652,15 +601,18 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
652
601
|
|
|
653
602
|
if (user) {
|
|
654
603
|
FIRUserProfileChangeRequest *changeRequest = [user profileChangeRequest];
|
|
655
|
-
|
|
604
|
+
// The decoder omits NSNull keys (subscript → nil). Iterate the original props keys so a
|
|
605
|
+
// cleared displayName/photoURL still reaches setValue:forKey: with nil.
|
|
606
|
+
NSDictionary *decodedProps = [RNFBAuthNullSentinelDecoder decodedProfileProps:props];
|
|
656
607
|
|
|
657
|
-
for (NSString *key in
|
|
608
|
+
for (NSString *key in props) {
|
|
658
609
|
@try {
|
|
610
|
+
id value = decodedProps[key];
|
|
659
611
|
if ([key isEqualToString:keyPhotoUrl]) {
|
|
660
|
-
|
|
661
|
-
|
|
612
|
+
[changeRequest setValue:[RNFBAuthNullSentinelDecoder photoURLFromDecodedValue:value]
|
|
613
|
+
forKey:key];
|
|
662
614
|
} else {
|
|
663
|
-
[changeRequest setValue:
|
|
615
|
+
[changeRequest setValue:value forKey:key];
|
|
664
616
|
}
|
|
665
617
|
} @catch (NSException *exception) {
|
|
666
618
|
DLog(@"Exception occurred while configuring: %@", exception);
|
|
@@ -1100,8 +1052,7 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1100
1052
|
if (error) {
|
|
1101
1053
|
[self promiseRejectAuthException:reject error:error];
|
|
1102
1054
|
} else {
|
|
1103
|
-
|
|
1104
|
-
resolve(verificationID);
|
|
1055
|
+
resolve(verificationID);
|
|
1105
1056
|
}
|
|
1106
1057
|
}];
|
|
1107
1058
|
}
|
|
@@ -1115,8 +1066,6 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1115
1066
|
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1116
1067
|
|
|
1117
1068
|
DLog(@"verifyPhoneNumberForMultifactor using app: %@", firebaseApp.name);
|
|
1118
|
-
DLog(@"verifyPhoneNumberForMultifactor phoneNumber: %@", phoneNumber);
|
|
1119
|
-
DLog(@"verifyPhoneNumberForMultifactor sessionKey: %@", sessionKey);
|
|
1120
1069
|
FIRMultiFactorSession *session = [cachedSessions get:sessionKey];
|
|
1121
1070
|
if (session == nil) {
|
|
1122
1071
|
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
@@ -1155,8 +1104,6 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1155
1104
|
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1156
1105
|
credentialWithVerificationID:verificationId
|
|
1157
1106
|
verificationCode:verificationCode];
|
|
1158
|
-
DLog(@"credential: %@", credential);
|
|
1159
|
-
|
|
1160
1107
|
FIRMultiFactorAssertion *assertion =
|
|
1161
1108
|
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
|
|
1162
1109
|
|
|
@@ -1214,8 +1161,6 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1214
1161
|
DLog(@"using instance resolve generateTotpSecret: %@", firebaseApp.name);
|
|
1215
1162
|
|
|
1216
1163
|
FIRMultiFactorSession *session = [cachedSessions get:sessionKey];
|
|
1217
|
-
DLog(@"using sessionKey: %@", sessionKey);
|
|
1218
|
-
DLog(@"using session: %@", session);
|
|
1219
1164
|
[FIRTOTPMultiFactorGenerator
|
|
1220
1165
|
generateSecretWithMultiFactorSession:session
|
|
1221
1166
|
completion:^(FIRTOTPSecret *_Nullable totpSecret,
|
|
@@ -1225,9 +1170,7 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1225
1170
|
}
|
|
1226
1171
|
else {
|
|
1227
1172
|
NSString *secretKey = totpSecret.sharedSecretKey;
|
|
1228
|
-
DLog(@"secretKey generated: %@", secretKey);
|
|
1229
1173
|
[cachedTotpSecrets putReplacing:secretKey value:totpSecret];
|
|
1230
|
-
DLog(@"cachedSecret: %@", [cachedTotpSecrets get:secretKey]);
|
|
1231
1174
|
resolve(@{
|
|
1232
1175
|
@"secretKey" : secretKey,
|
|
1233
1176
|
});
|
|
@@ -1243,14 +1186,12 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1243
1186
|
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1244
1187
|
|
|
1245
1188
|
DLog(@"generateQrCodeUrl using instance resolve generateQrCodeUrl: %@", firebaseApp.name);
|
|
1246
|
-
DLog(@"generateQrCodeUrl using secretKey: %@", secretKey);
|
|
1247
1189
|
FIRTOTPSecret *totpSecret = [cachedTotpSecrets get:secretKey];
|
|
1248
1190
|
if (!totpSecret) {
|
|
1249
1191
|
RNFBAuthThrowSyncErrorWithCode(@"invalid-multi-factor-secret",
|
|
1250
1192
|
@"can't find secret for provided key");
|
|
1251
1193
|
}
|
|
1252
1194
|
NSString *url = [totpSecret generateQRCodeURLWithAccountName:account issuer:issuer];
|
|
1253
|
-
DLog(@"generateQrCodeUrl got QR Code URL %@", url);
|
|
1254
1195
|
return url;
|
|
1255
1196
|
}
|
|
1256
1197
|
|
|
@@ -1259,9 +1200,7 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1259
1200
|
qrCodeUri:(NSString *)qrCodeUri {
|
|
1260
1201
|
[self initializeSharedStateOnce];
|
|
1261
1202
|
|
|
1262
|
-
DLog(@"generateQrCodeUrl using secretKey: %@", secretKey);
|
|
1263
1203
|
FIRTOTPSecret *totpSecret = [cachedTotpSecrets get:secretKey];
|
|
1264
|
-
DLog(@"openInOtpApp using qrCodeUri: %@", qrCodeUri);
|
|
1265
1204
|
[totpSecret openInOTPAppWithQRCodeURL:qrCodeUri];
|
|
1266
1205
|
}
|
|
1267
1206
|
|
|
@@ -1348,8 +1287,6 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1348
1287
|
DLog(@"using instance finalizeTotpEnrollment: %@", firebaseApp.name);
|
|
1349
1288
|
|
|
1350
1289
|
FIRTOTPSecret *cachedTotpSecret = [cachedTotpSecrets get:totpSecret];
|
|
1351
|
-
DLog(@"using totpSecretKey: %@", totpSecret);
|
|
1352
|
-
DLog(@"using cachedSecret: %@", cachedTotpSecret);
|
|
1353
1290
|
FIRTOTPMultiFactorAssertion *assertion =
|
|
1354
1291
|
[FIRTOTPMultiFactorGenerator assertionForEnrollmentWithSecret:cachedTotpSecret
|
|
1355
1292
|
oneTimePassword:verificationCode];
|
|
@@ -1910,82 +1847,15 @@ static __strong RNFBAuthCacheRegistry *cachedTotpSecrets;
|
|
|
1910
1847
|
|
|
1911
1848
|
+ (NSDictionary *)getJSError:(NSError *)error {
|
|
1912
1849
|
[self initializeSharedStateOnce];
|
|
1913
|
-
NSString *code =
|
|
1850
|
+
NSString *code = [RNFBAuthErrorCodeMapper jsErrorCodeForAuthErrorCode:error.code];
|
|
1914
1851
|
NSString *message = [error localizedDescription];
|
|
1915
1852
|
NSString *nativeErrorMessage = [error localizedDescription];
|
|
1916
1853
|
|
|
1917
1854
|
if (code == nil) code = @"unknown";
|
|
1918
1855
|
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
message = @"The custom token format is incorrect. Please check the documentation.";
|
|
1923
|
-
break;
|
|
1924
|
-
case FIRAuthErrorCodeCustomTokenMismatch:
|
|
1925
|
-
message = @"The custom token corresponds to a different audience.";
|
|
1926
|
-
break;
|
|
1927
|
-
case FIRAuthErrorCodeInvalidCredential:
|
|
1928
|
-
message = @"The supplied auth credential is malformed or has expired.";
|
|
1929
|
-
break;
|
|
1930
|
-
case FIRAuthErrorCodeInvalidEmail:
|
|
1931
|
-
message = @"The email address is badly formatted.";
|
|
1932
|
-
break;
|
|
1933
|
-
case FIRAuthErrorCodeWrongPassword:
|
|
1934
|
-
message = @"The password is invalid or the user does not have a password.";
|
|
1935
|
-
break;
|
|
1936
|
-
case FIRAuthErrorCodeUserMismatch:
|
|
1937
|
-
message = @"The supplied credentials do not correspond to the previously signed in user.";
|
|
1938
|
-
break;
|
|
1939
|
-
case FIRAuthErrorCodeRequiresRecentLogin:
|
|
1940
|
-
message = @"This operation is sensitive and requires recent authentication. Log in again "
|
|
1941
|
-
@"before retrying this request.";
|
|
1942
|
-
break;
|
|
1943
|
-
case FIRAuthErrorCodeSecondFactorRequired:
|
|
1944
|
-
message = @"Please complete a second factor challenge to finish signing into this account.";
|
|
1945
|
-
break;
|
|
1946
|
-
case FIRAuthErrorCodeAccountExistsWithDifferentCredential:
|
|
1947
|
-
message = @"An account already exists with the same email address but different sign-in "
|
|
1948
|
-
@"credentials. Sign in using a provider associated with this email address.";
|
|
1949
|
-
break;
|
|
1950
|
-
case FIRAuthErrorCodeEmailAlreadyInUse:
|
|
1951
|
-
message = @"The email address is already in use by another account.";
|
|
1952
|
-
break;
|
|
1953
|
-
case FIRAuthErrorCodeCredentialAlreadyInUse:
|
|
1954
|
-
message = @"This credential is already associated with a different user account.";
|
|
1955
|
-
break;
|
|
1956
|
-
case FIRAuthErrorCodeUserDisabled:
|
|
1957
|
-
message = @"The user account has been disabled by an administrator.";
|
|
1958
|
-
break;
|
|
1959
|
-
case FIRAuthErrorCodeUserTokenExpired:
|
|
1960
|
-
message = @"The user's credential is no longer valid. The user must sign in again.";
|
|
1961
|
-
break;
|
|
1962
|
-
case FIRAuthErrorCodeUserNotFound:
|
|
1963
|
-
message = @"There is no user record corresponding to this identifier. The user may have been "
|
|
1964
|
-
@"deleted.";
|
|
1965
|
-
break;
|
|
1966
|
-
case FIRAuthErrorCodeInvalidUserToken:
|
|
1967
|
-
message = @"The user's credential is no longer valid. The user must sign in again.";
|
|
1968
|
-
break;
|
|
1969
|
-
case FIRAuthErrorCodeWeakPassword:
|
|
1970
|
-
message = @"The given password is invalid.";
|
|
1971
|
-
break;
|
|
1972
|
-
case FIRAuthErrorCodeOperationNotAllowed:
|
|
1973
|
-
message = @"This operation is not allowed. You must enable this service in the console.";
|
|
1974
|
-
break;
|
|
1975
|
-
case FIRAuthErrorCodeNetworkError:
|
|
1976
|
-
message = @"A network error has occurred, please try again.";
|
|
1977
|
-
break;
|
|
1978
|
-
case FIRAuthErrorCodeInternalError:
|
|
1979
|
-
message = @"An internal error has occurred, please try again.";
|
|
1980
|
-
break;
|
|
1981
|
-
case FIRAuthErrorCodeInvalidPhoneNumber:
|
|
1982
|
-
message = @"The format of the phone number provided is incorrect. "
|
|
1983
|
-
@"Please enter the phone number in a format that can be parsed into E.164 format. "
|
|
1984
|
-
@"E.164 phone numbers are written in the format [+][country code][subscriber "
|
|
1985
|
-
@"number including area code].";
|
|
1986
|
-
break;
|
|
1987
|
-
default:
|
|
1988
|
-
break;
|
|
1856
|
+
NSString *overrideMessage = [RNFBAuthErrorCodeMapper jsErrorMessageForAuthErrorCode:error.code];
|
|
1857
|
+
if (overrideMessage != nil) {
|
|
1858
|
+
message = overrideMessage;
|
|
1989
1859
|
}
|
|
1990
1860
|
|
|
1991
1861
|
NSDictionary *authCredentialDict = nil;
|
|
@@ -23,12 +23,18 @@
|
|
|
23
23
|
#import "RNFBApp/RNFBHandleMap.h"
|
|
24
24
|
#endif
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
26
|
+
#if __has_include(<RNFBAuth/RNFBAuth-Swift.h>)
|
|
27
|
+
#import <RNFBAuth/RNFBAuth-Swift.h>
|
|
28
|
+
#elif __has_include("RNFBAuth-Swift.h")
|
|
29
|
+
#import "RNFBAuth-Swift.h"
|
|
30
|
+
#elif __has_include("RNFBHandleMapStorage-Swift.inc")
|
|
31
|
+
#import "RNFBHandleMapStorage-Swift.inc"
|
|
32
|
+
#else
|
|
33
|
+
#error "RNFBAuthListenerRegistryStorage Swift interface not found"
|
|
34
|
+
#endif
|
|
29
35
|
|
|
30
36
|
@interface RNFBAuthListenerRegistry ()
|
|
31
|
-
@property(nonatomic, strong)
|
|
37
|
+
@property(nonatomic, strong) RNFBAuthListenerRegistryStorage *storage;
|
|
32
38
|
@end
|
|
33
39
|
|
|
34
40
|
@implementation RNFBAuthListenerRegistry
|
|
@@ -36,48 +42,42 @@
|
|
|
36
42
|
- (instancetype)init {
|
|
37
43
|
self = [super init];
|
|
38
44
|
if (self) {
|
|
39
|
-
|
|
45
|
+
_storage = [[RNFBAuthListenerRegistryStorage alloc] init];
|
|
40
46
|
}
|
|
41
47
|
return self;
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
- (void)rnfb_removeHandle:(id)handle {
|
|
45
|
-
if (handle && [handle respondsToSelector:@selector(remove)]) {
|
|
46
|
-
[(id<RNFBAuthRemovable>)handle remove];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
50
|
- (BOOL)put:(id)key value:(id)value error:(NSError **)error {
|
|
51
|
-
|
|
51
|
+
if (![self.storage putIfAbsent:key value:value]) {
|
|
52
|
+
if (error != nil) {
|
|
53
|
+
NSString *message = [NSString stringWithFormat:@"Handle id already registered: %@", key];
|
|
54
|
+
*error = [NSError errorWithDomain:RNFBHandleMapErrorDomain
|
|
55
|
+
code:RNFBHandleMapErrorCollision
|
|
56
|
+
userInfo:@{NSLocalizedDescriptionKey : message}];
|
|
57
|
+
}
|
|
58
|
+
return NO;
|
|
59
|
+
}
|
|
60
|
+
return YES;
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
- (BOOL)putOrDiscard:(id)key value:(id)value {
|
|
55
|
-
|
|
56
|
-
if ([self.map put:key value:value error:&error]) {
|
|
57
|
-
return YES;
|
|
58
|
-
}
|
|
59
|
-
[self rnfb_removeHandle:value];
|
|
60
|
-
return NO;
|
|
64
|
+
return [self.storage putOrDiscard:key value:value];
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
- (id)get:(id)key {
|
|
64
|
-
return [self.
|
|
68
|
+
return [self.storage get:key];
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
- (id)take:(id)key {
|
|
68
|
-
return [self.
|
|
72
|
+
return [self.storage take:key];
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
- (void)takeAndRemove:(id)key {
|
|
72
|
-
|
|
73
|
-
[self rnfb_removeHandle:handle];
|
|
76
|
+
[self.storage takeAndRemove:key];
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
- (void)removeAll {
|
|
77
|
-
|
|
78
|
-
for (id handler in handlers) {
|
|
79
|
-
[self rnfb_removeHandle:handler];
|
|
80
|
-
}
|
|
80
|
+
[self.storage removeAll];
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
@end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
|
|
19
|
+
#if canImport(RNFBApp)
|
|
20
|
+
import RNFBApp
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
/// Auth-state / id-token listener map storage. Composes `RNFBHandleMapStorage`.
|
|
24
|
+
/// `putOrDiscard` is first-wins and calls `remove` on the incoming value on collision.
|
|
25
|
+
/// Unique `put` collision errors stay on the ObjC façade.
|
|
26
|
+
@objc(RNFBAuthListenerRegistryStorage)
|
|
27
|
+
public final class RNFBAuthListenerRegistryStorage: NSObject {
|
|
28
|
+
private static let removeSelector = Selector(("remove"))
|
|
29
|
+
|
|
30
|
+
private let storage = RNFBHandleMapStorage()
|
|
31
|
+
|
|
32
|
+
private func removeHandle(_ handle: AnyObject?) {
|
|
33
|
+
guard let handle = handle, handle.responds(to: Self.removeSelector) else {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
_ = handle.perform(Self.removeSelector)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// First-wins store without discarding the incoming value. Used by façade `put`.
|
|
40
|
+
@objc(putIfAbsent:value:)
|
|
41
|
+
public func putIfAbsent(_ key: AnyObject, value: AnyObject) -> Bool {
|
|
42
|
+
storage.putIfAbsent(key, value: value)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// Unique put. On collision, `remove`s the incoming value and leaves the existing mapping.
|
|
46
|
+
@objc(putOrDiscard:value:)
|
|
47
|
+
public func putOrDiscard(_ key: AnyObject, value: AnyObject) -> Bool {
|
|
48
|
+
if storage.putIfAbsent(key, value: value) {
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
removeHandle(value)
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@objc(get:)
|
|
56
|
+
public func get(_ key: AnyObject) -> AnyObject? {
|
|
57
|
+
storage.get(key)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@objc(take:)
|
|
61
|
+
public func take(_ key: AnyObject) -> AnyObject? {
|
|
62
|
+
storage.take(key)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@objc(takeAndRemove:)
|
|
66
|
+
public func takeAndRemove(_ key: AnyObject) {
|
|
67
|
+
removeHandle(storage.take(key))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@objc
|
|
71
|
+
public func removeAll() {
|
|
72
|
+
for handle in storage.takeAll() {
|
|
73
|
+
removeHandle(handle)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <Foundation/Foundation.h>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Decodes New Architecture null sentinels for updateProfile. Foundation only so unit tests can
|
|
22
|
+
* compile it without the Firebase SDK.
|
|
23
|
+
*/
|
|
24
|
+
@interface RNFBAuthNullSentinelDecoder : NSObject
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Decode sentinels and turn NSNull into nil before profileChangeRequest writes.
|
|
28
|
+
* FIRUserProfileChangeRequest clears a field when the property is set to nil (not the same as
|
|
29
|
+
* leaving it unassigned). NSDictionary cannot store nil, so cleared keys are omitted and
|
|
30
|
+
* subscript returns nil, the same value updateProfile reads.
|
|
31
|
+
* displayName/photoURL null arrive as { __rnfbNull: true } and/or NSNull after decode.
|
|
32
|
+
*/
|
|
33
|
+
+ (NSDictionary *)decodedProfileProps:(NSDictionary *)props;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* photoURL clear arm: omitted/nil decoded value must become nil (not @""), not URLWithString:.
|
|
37
|
+
*/
|
|
38
|
+
+ (NSURL *)photoURLFromDecodedValue:(id)value;
|
|
39
|
+
|
|
40
|
+
@end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import "RNFBAuthNullSentinelDecoder.h"
|
|
19
|
+
|
|
20
|
+
#if __has_include(<RNFBApp/RNFBApp-Swift.h>)
|
|
21
|
+
#import <RNFBApp/RNFBApp-Swift.h>
|
|
22
|
+
#elif __has_include("RNFBApp-Swift.h")
|
|
23
|
+
#import "RNFBApp-Swift.h"
|
|
24
|
+
#elif __has_include("RNFBHandleMapStorage-Swift.inc")
|
|
25
|
+
#import "RNFBHandleMapStorage-Swift.inc"
|
|
26
|
+
#else
|
|
27
|
+
#error "RNFBApp Swift interface not found"
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
@implementation RNFBAuthNullSentinelDecoder
|
|
31
|
+
|
|
32
|
+
+ (NSDictionary *)decodedProfileProps:(NSDictionary *)props {
|
|
33
|
+
NSDictionary *decoded = [RNFBNullSentinelDecoder decodeNullSentinels:props];
|
|
34
|
+
NSMutableDictionary *normalized = [NSMutableDictionary dictionaryWithCapacity:decoded.count];
|
|
35
|
+
for (NSString *key in decoded) {
|
|
36
|
+
id value = decoded[key];
|
|
37
|
+
if (value == [NSNull null]) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
normalized[key] = value;
|
|
41
|
+
}
|
|
42
|
+
return normalized;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
+ (NSURL *)photoURLFromDecodedValue:(id)value {
|
|
46
|
+
return value == nil ? nil : [NSURL URLWithString:value];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@end
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
10
|
2744B98621F45429004F8E3F /* RNFBAuthModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBAuthModule.mm */; };
|
|
11
|
+
RNFBAUTH0000000000000001 /* RNFBAuthCacheRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = RNFBAUTH0000000000000002 /* RNFBAuthCacheRegistry.m */; };
|
|
12
|
+
RNFBAUTH0000000000000003 /* RNFBAuthCacheRegistryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBAUTH0000000000000004 /* RNFBAuthCacheRegistryStorage.swift */; };
|
|
13
|
+
RNFBAUTH0000000000000008 /* RNFBAuthListenerRegistryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBAUTH0000000000000009 /* RNFBAuthListenerRegistryStorage.swift */; };
|
|
14
|
+
RNFBAUTH000000000000000A /* RNFBAuthErrorCodeMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBAUTH000000000000000B /* RNFBAuthErrorCodeMapper.swift */; };
|
|
11
15
|
/* End PBXBuildFile section */
|
|
12
16
|
|
|
13
17
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -26,6 +30,11 @@
|
|
|
26
30
|
2744B98221F45429004F8E3F /* libRNFBAuth.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFBAuth.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
27
31
|
2744B98421F45429004F8E3F /* RNFBAuthModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBAuthModule.h; path = RNFBAuth/RNFBAuthModule.h; sourceTree = SOURCE_ROOT; };
|
|
28
32
|
2744B98521F45429004F8E3F /* RNFBAuthModule.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = RNFBAuthModule.mm; path = RNFBAuth/RNFBAuthModule.mm; sourceTree = SOURCE_ROOT; };
|
|
33
|
+
RNFBAUTH0000000000000005 /* RNFBAuthCacheRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBAuthCacheRegistry.h; path = RNFBAuth/RNFBAuthCacheRegistry.h; sourceTree = SOURCE_ROOT; };
|
|
34
|
+
RNFBAUTH0000000000000002 /* RNFBAuthCacheRegistry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBAuthCacheRegistry.m; path = RNFBAuth/RNFBAuthCacheRegistry.m; sourceTree = SOURCE_ROOT; };
|
|
35
|
+
RNFBAUTH0000000000000004 /* RNFBAuthCacheRegistryStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBAuthCacheRegistryStorage.swift; path = RNFBAuth/RNFBAuthCacheRegistryStorage.swift; sourceTree = SOURCE_ROOT; };
|
|
36
|
+
RNFBAUTH0000000000000009 /* RNFBAuthListenerRegistryStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBAuthListenerRegistryStorage.swift; path = RNFBAuth/RNFBAuthListenerRegistryStorage.swift; sourceTree = SOURCE_ROOT; };
|
|
37
|
+
RNFBAUTH000000000000000B /* RNFBAuthErrorCodeMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBAuthErrorCodeMapper.swift; path = RNFBAuth/RNFBAuthErrorCodeMapper.swift; sourceTree = SOURCE_ROOT; };
|
|
29
38
|
/* End PBXFileReference section */
|
|
30
39
|
|
|
31
40
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -52,6 +61,11 @@
|
|
|
52
61
|
children = (
|
|
53
62
|
2744B9A121F48736004F8E3F /* converters */,
|
|
54
63
|
2744B98C21F45C64004F8E3F /* common */,
|
|
64
|
+
RNFBAUTH0000000000000005 /* RNFBAuthCacheRegistry.h */,
|
|
65
|
+
RNFBAUTH0000000000000002 /* RNFBAuthCacheRegistry.m */,
|
|
66
|
+
RNFBAUTH0000000000000004 /* RNFBAuthCacheRegistryStorage.swift */,
|
|
67
|
+
RNFBAUTH0000000000000009 /* RNFBAuthListenerRegistryStorage.swift */,
|
|
68
|
+
RNFBAUTH000000000000000B /* RNFBAuthErrorCodeMapper.swift */,
|
|
55
69
|
2744B98421F45429004F8E3F /* RNFBAuthModule.h */,
|
|
56
70
|
2744B98521F45429004F8E3F /* RNFBAuthModule.mm */,
|
|
57
71
|
);
|
|
@@ -124,6 +138,10 @@
|
|
|
124
138
|
isa = PBXSourcesBuildPhase;
|
|
125
139
|
buildActionMask = 2147483647;
|
|
126
140
|
files = (
|
|
141
|
+
RNFBAUTH0000000000000003 /* RNFBAuthCacheRegistryStorage.swift in Sources */,
|
|
142
|
+
RNFBAUTH0000000000000001 /* RNFBAuthCacheRegistry.m in Sources */,
|
|
143
|
+
RNFBAUTH0000000000000008 /* RNFBAuthListenerRegistryStorage.swift in Sources */,
|
|
144
|
+
RNFBAUTH000000000000000A /* RNFBAuthErrorCodeMapper.swift in Sources */,
|
|
127
145
|
2744B98621F45429004F8E3F /* RNFBAuthModule.mm in Sources */,
|
|
128
146
|
);
|
|
129
147
|
runOnlyForDeploymentPostprocessing = 0;
|
|
@@ -150,6 +168,7 @@
|
|
|
150
168
|
CODE_SIGN_STYLE = Automatic;
|
|
151
169
|
COPY_PHASE_STRIP = NO;
|
|
152
170
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
171
|
+
DEFINES_MODULE = YES;
|
|
153
172
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
|
154
173
|
GCC_DYNAMIC_NO_PIC = NO;
|
|
155
174
|
GCC_OPTIMIZATION_LEVEL = 0;
|
|
@@ -166,6 +185,7 @@
|
|
|
166
185
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
167
186
|
SDKROOT = iphoneos;
|
|
168
187
|
SKIP_INSTALL = YES;
|
|
188
|
+
SWIFT_VERSION = 5.10;
|
|
169
189
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
170
190
|
};
|
|
171
191
|
name = Debug;
|
|
@@ -189,6 +209,7 @@
|
|
|
189
209
|
CODE_SIGN_STYLE = Automatic;
|
|
190
210
|
COPY_PHASE_STRIP = NO;
|
|
191
211
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
212
|
+
DEFINES_MODULE = YES;
|
|
192
213
|
ENABLE_NS_ASSERTIONS = NO;
|
|
193
214
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
|
194
215
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
@@ -200,6 +221,7 @@
|
|
|
200
221
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
201
222
|
SDKROOT = iphoneos;
|
|
202
223
|
SKIP_INSTALL = YES;
|
|
224
|
+
SWIFT_VERSION = 5.10;
|
|
203
225
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
204
226
|
VALIDATE_PRODUCT = YES;
|
|
205
227
|
};
|