@react-native-firebase/auth 26.0.0 → 26.1.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 +11 -0
- package/RNFBAuth.podspec +2 -1
- package/android/src/main/java/io/invertase/firebase/auth/NativeRNFBTurboAuth.java +9 -1
- package/android/src/main/java/io/invertase/firebase/auth/generated/java/com/facebook/fbreact/specs/NativeRNFBTurboAuthSpec.java +1 -1
- package/android/src/main/java/io/invertase/firebase/auth/generated/jni/RNFBAuthTurboModules-generated.cpp +2 -2
- package/android/src/main/java/io/invertase/firebase/auth/generated/jni/react/renderer/components/RNFBAuthTurboModules/RNFBAuthTurboModulesJSI-generated.cpp +3 -2
- package/android/src/main/java/io/invertase/firebase/auth/generated/jni/react/renderer/components/RNFBAuthTurboModules/RNFBAuthTurboModulesJSI.h +5 -5
- package/dist/module/credentials/OAuthCredential.js +22 -1
- package/dist/module/credentials/OAuthCredential.js.map +1 -1
- package/dist/module/index.js +6 -1
- package/dist/module/index.js.map +1 -1
- package/dist/module/providers/AppleAuthProvider.js +17 -4
- package/dist/module/providers/AppleAuthProvider.js.map +1 -1
- package/dist/module/providers/OAuthProvider.js +4 -2
- package/dist/module/providers/OAuthProvider.js.map +1 -1
- package/dist/module/types/auth.js +8 -0
- package/dist/module/types/auth.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/web/RNFBAuthModule.js +13 -11
- package/dist/module/web/RNFBAuthModule.js.map +1 -1
- package/dist/typescript/lib/credentials/OAuthCredential.d.ts +6 -0
- package/dist/typescript/lib/credentials/OAuthCredential.d.ts.map +1 -1
- package/dist/typescript/lib/index.d.ts.map +1 -1
- package/dist/typescript/lib/providers/AppleAuthProvider.d.ts +10 -3
- package/dist/typescript/lib/providers/AppleAuthProvider.d.ts.map +1 -1
- package/dist/typescript/lib/providers/OAuthProvider.d.ts.map +1 -1
- package/dist/typescript/lib/types/auth.d.ts +26 -0
- package/dist/typescript/lib/types/auth.d.ts.map +1 -1
- package/dist/typescript/lib/types/internal.d.ts +1 -1
- package/dist/typescript/lib/types/internal.d.ts.map +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/dist/typescript/lib/web/RNFBAuthModule.d.ts +3 -1
- package/dist/typescript/lib/web/RNFBAuthModule.d.ts.map +1 -1
- package/ios/RNFBAuth/RNFBAuthHelper.h +338 -0
- package/ios/RNFBAuth/RNFBAuthHelper.m +2221 -0
- package/ios/RNFBAuth/RNFBAuthModule.h +7 -64
- package/ios/RNFBAuth/RNFBAuthModule.mm +179 -1637
- package/ios/generated/RNFBAuthTurboModules/RNFBAuthTurboModules-generated.mm +2 -2
- package/ios/generated/RNFBAuthTurboModules/RNFBAuthTurboModules.h +1 -0
- package/ios/generated/RNFBAuthTurboModulesJSI-generated.cpp +3 -2
- package/ios/generated/RNFBAuthTurboModulesJSI.h +5 -5
- package/lib/credentials/OAuthCredential.ts +44 -0
- package/lib/index.ts +13 -1
- package/lib/providers/AppleAuthProvider.ts +21 -5
- package/lib/providers/OAuthProvider.ts +2 -0
- package/lib/types/auth.ts +27 -0
- package/lib/types/internal.ts +2 -0
- package/lib/version.ts +1 -1
- package/lib/web/RNFBAuthModule.ts +34 -23
- package/package.json +4 -4
- package/specs/NativeRNFBTurboAuth.ts +2 -0
|
@@ -0,0 +1,2221 @@
|
|
|
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
|
+
#if __has_include(<Firebase/Firebase.h>)
|
|
19
|
+
#import <Firebase/Firebase.h>
|
|
20
|
+
#else
|
|
21
|
+
@import FirebaseCore;
|
|
22
|
+
@import FirebaseAuth;
|
|
23
|
+
// `@import FirebaseAuth` alone only exposes the Swift-generated interop header
|
|
24
|
+
// (the real `FIRAuth`/`FIRUser` classes). The hand-written ObjC compatibility
|
|
25
|
+
// headers under `Public/FirebaseAuth/` (typedefs like
|
|
26
|
+
// `FIRAuthStateDidChangeListenerHandle`, error userInfo key constants, etc.)
|
|
27
|
+
// are vended by the separate `FirebaseAuthInternal` Clang module, which isn't
|
|
28
|
+
// automatically re-exported by `@import FirebaseAuth` -- it must be imported
|
|
29
|
+
// explicitly too, even though it's a direct (not transitive) SPM dependency of
|
|
30
|
+
// `FirebaseAuth`. See okf-bundle/ios-spm-native-imports.md.
|
|
31
|
+
@import FirebaseAuthInternal;
|
|
32
|
+
#endif
|
|
33
|
+
#import <React/RCTConvert.h>
|
|
34
|
+
#import <React/RCTUtils.h>
|
|
35
|
+
|
|
36
|
+
#import "RNFBApp/RCTConvert+FIRApp.h"
|
|
37
|
+
#import "RNFBApp/RNFBAppModule.h"
|
|
38
|
+
#import "RNFBApp/RNFBSharedUtils.h"
|
|
39
|
+
#import "RNFBAuthHelper.h"
|
|
40
|
+
|
|
41
|
+
static void RNFBAuthThrowSyncErrorWithCode(NSString *code, NSString *message) {
|
|
42
|
+
@throw [NSException exceptionWithName:code
|
|
43
|
+
reason:message
|
|
44
|
+
userInfo:@{@"code" : code, @"message" : message}];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static NSString *const keyIOS = @"iOS";
|
|
48
|
+
static NSString *const keyUrl = @"url";
|
|
49
|
+
static NSString *const keyUid = @"uid";
|
|
50
|
+
static NSString *const keyUser = @"user";
|
|
51
|
+
static NSString *const keyEmail = @"email";
|
|
52
|
+
static NSString *const keyAndroid = @"android";
|
|
53
|
+
static NSString *const keyProfile = @"profile";
|
|
54
|
+
static NSString *const keyNewUser = @"isNewUser";
|
|
55
|
+
static NSString *const keyUsername = @"username";
|
|
56
|
+
static NSString *const keyMultiFactor = @"multiFactor";
|
|
57
|
+
static NSString *const keyPhotoUrl = @"photoURL";
|
|
58
|
+
static NSString *const keyBundleId = @"bundleId";
|
|
59
|
+
static NSString *const keyInstallApp = @"installApp";
|
|
60
|
+
static NSString *const keyProviderId = @"providerId";
|
|
61
|
+
static NSString *const keyPhoneNumber = @"phoneNumber";
|
|
62
|
+
static NSString *const keyDisplayName = @"displayName";
|
|
63
|
+
static NSString *const keyPackageName = @"packageName";
|
|
64
|
+
static NSString *const keyMinVersion = @"minimumVersion";
|
|
65
|
+
static NSString *const constAppLanguage = @"APP_LANGUAGE";
|
|
66
|
+
static NSString *const constAppUser = @"APP_USER";
|
|
67
|
+
static NSString *const keyHandleCodeInApp = @"handleCodeInApp";
|
|
68
|
+
static NSString *const keyLinkDomain = @"linkDomain";
|
|
69
|
+
static NSString *const keyAdditionalUserInfo = @"additionalUserInfo";
|
|
70
|
+
static NSString *const AUTH_STATE_CHANGED_EVENT = @"auth_state_changed";
|
|
71
|
+
static NSString *const AUTH_ID_TOKEN_CHANGED_EVENT = @"auth_id_token_changed";
|
|
72
|
+
static NSString *const PHONE_AUTH_STATE_CHANGED_EVENT = @"phone_auth_state_changed";
|
|
73
|
+
|
|
74
|
+
static NSString *const AuthErrorCode_toJSErrorCode[] = {
|
|
75
|
+
[FIRAuthErrorCodeInvalidCustomToken] = @"invalid-custom-token",
|
|
76
|
+
[FIRAuthErrorCodeCustomTokenMismatch] = @"custom-token-mismatch",
|
|
77
|
+
[FIRAuthErrorCodeInvalidCredential] = @"invalid-credential",
|
|
78
|
+
[FIRAuthErrorCodeUserDisabled] = @"user-disabled",
|
|
79
|
+
[FIRAuthErrorCodeOperationNotAllowed] = @"operation-not-allowed",
|
|
80
|
+
[FIRAuthErrorCodeEmailAlreadyInUse] = @"email-already-in-use",
|
|
81
|
+
[FIRAuthErrorCodeInvalidEmail] = @"invalid-email",
|
|
82
|
+
[FIRAuthErrorCodeWrongPassword] = @"wrong-password",
|
|
83
|
+
[FIRAuthErrorCodeTooManyRequests] = @"too-many-requests",
|
|
84
|
+
[FIRAuthErrorCodeUserNotFound] = @"user-not-found",
|
|
85
|
+
[FIRAuthErrorCodeAccountExistsWithDifferentCredential] =
|
|
86
|
+
@"account-exists-with-different-credential",
|
|
87
|
+
[FIRAuthErrorCodeRequiresRecentLogin] = @"requires-recent-login",
|
|
88
|
+
[FIRAuthErrorCodeProviderAlreadyLinked] = @"provider-already-linked",
|
|
89
|
+
[FIRAuthErrorCodeNoSuchProvider] = @"no-such-provider",
|
|
90
|
+
[FIRAuthErrorCodeInvalidUserToken] = @"invalid-user-token",
|
|
91
|
+
[FIRAuthErrorCodeNetworkError] = @"network-request-failed",
|
|
92
|
+
[FIRAuthErrorCodeUserTokenExpired] = @"user-token-expired",
|
|
93
|
+
[FIRAuthErrorCodeInvalidAPIKey] = @"invalid-api-key",
|
|
94
|
+
[FIRAuthErrorCodeUserMismatch] = @"user-mismatch",
|
|
95
|
+
[FIRAuthErrorCodeCredentialAlreadyInUse] = @"credential-already-in-use",
|
|
96
|
+
[FIRAuthErrorCodeWeakPassword] = @"weak-password",
|
|
97
|
+
[FIRAuthErrorCodeAppNotAuthorized] = @"app-not-authorized",
|
|
98
|
+
[FIRAuthErrorCodeExpiredActionCode] = @"expired-action-code",
|
|
99
|
+
[FIRAuthErrorCodeInvalidActionCode] = @"invalid-action-code",
|
|
100
|
+
[FIRAuthErrorCodeInvalidMessagePayload] = @"invalid-message-payload",
|
|
101
|
+
[FIRAuthErrorCodeInvalidSender] = @"invalid-sender",
|
|
102
|
+
[FIRAuthErrorCodeInvalidRecipientEmail] = @"invalid-recipient-email",
|
|
103
|
+
[FIRAuthErrorCodeMissingEmail] = @"invalid-email",
|
|
104
|
+
[FIRAuthErrorCodeMissingIosBundleID] = @"missing-ios-bundle-id",
|
|
105
|
+
[FIRAuthErrorCodeMissingAndroidPackageName] = @"missing-android-pkg-name",
|
|
106
|
+
[FIRAuthErrorCodeUnauthorizedDomain] = @"unauthorized-domain",
|
|
107
|
+
[FIRAuthErrorCodeInvalidContinueURI] = @"invalid-continue-uri",
|
|
108
|
+
[FIRAuthErrorCodeMissingContinueURI] = @"missing-continue-uri",
|
|
109
|
+
[FIRAuthErrorCodeMissingPhoneNumber] = @"missing-phone-number",
|
|
110
|
+
[FIRAuthErrorCodeInvalidPhoneNumber] = @"invalid-phone-number",
|
|
111
|
+
[FIRAuthErrorCodeMissingVerificationCode] = @"missing-verification-code",
|
|
112
|
+
[FIRAuthErrorCodeInvalidVerificationCode] = @"invalid-verification-code",
|
|
113
|
+
[FIRAuthErrorCodeMissingVerificationID] = @"missing-verification-id",
|
|
114
|
+
[FIRAuthErrorCodeInvalidVerificationID] = @"invalid-verification-id",
|
|
115
|
+
[FIRAuthErrorCodeMissingAppCredential] = @"missing-app-credential",
|
|
116
|
+
[FIRAuthErrorCodeInvalidAppCredential] = @"invalid-app-credential",
|
|
117
|
+
[FIRAuthErrorCodeSessionExpired] = @"code-expired",
|
|
118
|
+
[FIRAuthErrorCodeQuotaExceeded] = @"quota-exceeded",
|
|
119
|
+
[FIRAuthErrorCodeMissingAppToken] = @"missing-apns-token",
|
|
120
|
+
[FIRAuthErrorCodeNotificationNotForwarded] = @"notification-not-forwarded",
|
|
121
|
+
[FIRAuthErrorCodeAppNotVerified] = @"app-not-verified",
|
|
122
|
+
[FIRAuthErrorCodeCaptchaCheckFailed] = @"captcha-check-failed",
|
|
123
|
+
[FIRAuthErrorCodeWebContextAlreadyPresented] = @"cancelled-popup-request",
|
|
124
|
+
[FIRAuthErrorCodeWebContextCancelled] = @"popup-closed-by-user",
|
|
125
|
+
[FIRAuthErrorCodeAppVerificationUserInteractionFailure] =
|
|
126
|
+
@"app-verification-user-interaction-failure",
|
|
127
|
+
[FIRAuthErrorCodeInvalidClientID] = @"invalid-oauth-client-id",
|
|
128
|
+
[FIRAuthErrorCodeWebNetworkRequestFailed] = @"network-request-failed",
|
|
129
|
+
[FIRAuthErrorCodeWebInternalError] = @"internal-error",
|
|
130
|
+
[FIRAuthErrorCodeNullUser] = @"null-user",
|
|
131
|
+
[FIRAuthErrorCodeKeychainError] = @"keychain-error",
|
|
132
|
+
[FIRAuthErrorCodeInternalError] = @"internal-error",
|
|
133
|
+
[FIRAuthErrorCodeMalformedJWT] = @"malformed-jwt",
|
|
134
|
+
[FIRAuthErrorCodeSecondFactorRequired] = @"multi-factor-auth-required"};
|
|
135
|
+
|
|
136
|
+
static __strong NSMutableDictionary *authStateHandlers;
|
|
137
|
+
static __strong NSMutableDictionary *idTokenHandlers;
|
|
138
|
+
static __strong NSMutableDictionary *emulatorConfigs;
|
|
139
|
+
// Used for caching credentials between method calls.
|
|
140
|
+
static __strong NSMutableDictionary<NSString *, FIRAuthCredential *> *credentials;
|
|
141
|
+
#if TARGET_OS_IOS
|
|
142
|
+
static __strong NSMutableDictionary<NSString *, FIRMultiFactorResolver *> *cachedResolver;
|
|
143
|
+
static __strong NSMutableDictionary<NSString *, FIRMultiFactorSession *> *cachedSessions;
|
|
144
|
+
static __strong NSMutableDictionary<NSString *, FIRTOTPSecret *> *cachedTotpSecrets;
|
|
145
|
+
#endif
|
|
146
|
+
|
|
147
|
+
@interface RNFBAuthHelper ()
|
|
148
|
+
|
|
149
|
+
+ (NSString *)nonEmptyStringFromDictionary:(NSDictionary *)dictionary key:(NSString *)key;
|
|
150
|
+
+ (NSPersonNameComponents *)personNameComponentsFromDictionary:(NSDictionary *)dictionary;
|
|
151
|
+
|
|
152
|
+
+ (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider
|
|
153
|
+
token:(NSString *)authToken
|
|
154
|
+
secret:(NSString *)authTokenSecret
|
|
155
|
+
firebaseApp:(FIRApp *)firebaseApp;
|
|
156
|
+
|
|
157
|
+
+ (void)reloadAndReturnUser:(FIRUser *)user
|
|
158
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
159
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
160
|
+
firebaseApp:(FIRApp *)firebaseApp;
|
|
161
|
+
|
|
162
|
+
+ (void)promiseNoUser:(RCTPromiseResolveBlock)resolve
|
|
163
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
164
|
+
isError:(BOOL)isError;
|
|
165
|
+
|
|
166
|
+
#if TARGET_OS_IOS
|
|
167
|
+
+ (NSDictionary *)multiFactorResolverToDict:(FIRMultiFactorResolver *)resolver;
|
|
168
|
+
#endif
|
|
169
|
+
|
|
170
|
+
+ (void)promiseRejectAuthException:(RCTPromiseRejectBlock)reject error:(NSError *)error;
|
|
171
|
+
+ (NSDictionary *)getJSError:(NSError *)error;
|
|
172
|
+
|
|
173
|
+
+ (void)promiseWithUser:(RCTPromiseResolveBlock)resolve
|
|
174
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
175
|
+
user:(FIRUser *)user;
|
|
176
|
+
|
|
177
|
+
+ (void)promiseWithAuthResult:(RCTPromiseResolveBlock)resolve
|
|
178
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
179
|
+
authResult:(FIRAuthDataResult *)authResult;
|
|
180
|
+
|
|
181
|
+
+ (NSArray<NSObject *> *)convertProviderData:(NSArray<id<FIRUserInfo>> *)providerData;
|
|
182
|
+
+ (NSDictionary *)firebaseUserToDict:(FIRUser *)user;
|
|
183
|
+
|
|
184
|
+
#if TARGET_OS_IOS
|
|
185
|
+
+ (NSArray<NSMutableDictionary *> *)convertMultiFactorData:(NSArray<FIRMultiFactorInfo *> *)hints;
|
|
186
|
+
#endif
|
|
187
|
+
|
|
188
|
+
+ (NSDictionary *)authCredentialToDict:(FIRAuthCredential *)authCredential;
|
|
189
|
+
+ (FIRActionCodeSettings *)buildActionCodeSettings:(NSDictionary *)actionCodeSettings;
|
|
190
|
+
|
|
191
|
+
+ (void)initializeSharedStateOnce;
|
|
192
|
+
|
|
193
|
+
@end
|
|
194
|
+
|
|
195
|
+
@implementation RNFBAuthHelper
|
|
196
|
+
|
|
197
|
+
#pragma mark -
|
|
198
|
+
#pragma mark Shared state
|
|
199
|
+
|
|
200
|
+
+ (void)initializeSharedStateOnce {
|
|
201
|
+
static dispatch_once_t onceToken;
|
|
202
|
+
dispatch_once(&onceToken, ^{
|
|
203
|
+
authStateHandlers = [[NSMutableDictionary alloc] init];
|
|
204
|
+
idTokenHandlers = [[NSMutableDictionary alloc] init];
|
|
205
|
+
emulatorConfigs = [[NSMutableDictionary alloc] init];
|
|
206
|
+
credentials = [[NSMutableDictionary alloc] init];
|
|
207
|
+
#if TARGET_OS_IOS
|
|
208
|
+
cachedResolver = [[NSMutableDictionary alloc] init];
|
|
209
|
+
cachedSessions = [[NSMutableDictionary alloc] init];
|
|
210
|
+
cachedTotpSecrets = [[NSMutableDictionary alloc] init];
|
|
211
|
+
#endif
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
+ (void)invalidate {
|
|
216
|
+
[self initializeSharedStateOnce];
|
|
217
|
+
|
|
218
|
+
for (NSString *key in authStateHandlers) {
|
|
219
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:key];
|
|
220
|
+
|
|
221
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
222
|
+
removeAuthStateDidChangeListener:[authStateHandlers valueForKey:key]];
|
|
223
|
+
}
|
|
224
|
+
[authStateHandlers removeAllObjects];
|
|
225
|
+
|
|
226
|
+
for (NSString *key in idTokenHandlers) {
|
|
227
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:key];
|
|
228
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
229
|
+
removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:key]];
|
|
230
|
+
}
|
|
231
|
+
[idTokenHandlers removeAllObjects];
|
|
232
|
+
|
|
233
|
+
[credentials removeAllObjects];
|
|
234
|
+
#if TARGET_OS_IOS
|
|
235
|
+
[cachedResolver removeAllObjects];
|
|
236
|
+
[cachedSessions removeAllObjects];
|
|
237
|
+
[cachedTotpSecrets removeAllObjects];
|
|
238
|
+
#endif
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#pragma mark -
|
|
242
|
+
#pragma mark Firebase Auth Methods
|
|
243
|
+
|
|
244
|
+
+ (void)addAuthStateListener:(NSString *)appName {
|
|
245
|
+
[self initializeSharedStateOnce];
|
|
246
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
247
|
+
|
|
248
|
+
if (![authStateHandlers valueForKey:firebaseApp.name]) {
|
|
249
|
+
FIRAuthStateDidChangeListenerHandle newListenerHandle = [[FIRAuth authWithApp:firebaseApp]
|
|
250
|
+
addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) {
|
|
251
|
+
if (user != nil) {
|
|
252
|
+
[RNFBSharedUtils sendJSEventForApp:firebaseApp
|
|
253
|
+
name:AUTH_STATE_CHANGED_EVENT
|
|
254
|
+
body:@{keyUser : [self firebaseUserToDict:user]}];
|
|
255
|
+
} else {
|
|
256
|
+
[RNFBSharedUtils sendJSEventForApp:firebaseApp name:AUTH_STATE_CHANGED_EVENT body:@{}];
|
|
257
|
+
}
|
|
258
|
+
}];
|
|
259
|
+
authStateHandlers[firebaseApp.name] = newListenerHandle;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
+ (void)removeAuthStateListener:(NSString *)appName {
|
|
264
|
+
[self initializeSharedStateOnce];
|
|
265
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
266
|
+
|
|
267
|
+
if ([authStateHandlers valueForKey:firebaseApp.name]) {
|
|
268
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
269
|
+
removeAuthStateDidChangeListener:[authStateHandlers valueForKey:firebaseApp.name]];
|
|
270
|
+
[authStateHandlers removeObjectForKey:firebaseApp.name];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
+ (void)addIdTokenListener:(NSString *)appName {
|
|
275
|
+
[self initializeSharedStateOnce];
|
|
276
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
277
|
+
|
|
278
|
+
if (![idTokenHandlers valueForKey:firebaseApp.name]) {
|
|
279
|
+
FIRIDTokenDidChangeListenerHandle newListenerHandle = [[FIRAuth authWithApp:firebaseApp]
|
|
280
|
+
addIDTokenDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) {
|
|
281
|
+
if (user != nil) {
|
|
282
|
+
[RNFBSharedUtils sendJSEventForApp:firebaseApp
|
|
283
|
+
name:AUTH_ID_TOKEN_CHANGED_EVENT
|
|
284
|
+
body:@{keyUser : [self firebaseUserToDict:user]}];
|
|
285
|
+
} else {
|
|
286
|
+
[RNFBSharedUtils sendJSEventForApp:firebaseApp
|
|
287
|
+
name:AUTH_ID_TOKEN_CHANGED_EVENT
|
|
288
|
+
body:@{}];
|
|
289
|
+
}
|
|
290
|
+
}];
|
|
291
|
+
idTokenHandlers[firebaseApp.name] = newListenerHandle;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
+ (void)removeIdTokenListener:(NSString *)appName {
|
|
296
|
+
[self initializeSharedStateOnce];
|
|
297
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
298
|
+
|
|
299
|
+
if ([idTokenHandlers valueForKey:firebaseApp.name]) {
|
|
300
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
301
|
+
removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:firebaseApp.name]];
|
|
302
|
+
[idTokenHandlers removeObjectForKey:firebaseApp.name];
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
+ (void)configureAuthDomain:(NSString *)appName {
|
|
307
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
308
|
+
|
|
309
|
+
NSString *authDomain = [RNFBAppModule getCustomDomain:firebaseApp.name];
|
|
310
|
+
DLog(@"RNFBAuth app: %@ customAuthDomain: %@", firebaseApp.name, authDomain);
|
|
311
|
+
if (authDomain != nil) {
|
|
312
|
+
[FIRAuth authWithApp:firebaseApp].customAuthDomain = authDomain;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
+ (void)getCustomAuthDomain:(NSString *)appName
|
|
317
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
318
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
319
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
320
|
+
|
|
321
|
+
resolve([FIRAuth authWithApp:firebaseApp].customAuthDomain);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
+ (void)setAppVerificationDisabledForTesting:(NSString *)appName
|
|
325
|
+
disabled:(BOOL)disabled
|
|
326
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
327
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
328
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
329
|
+
|
|
330
|
+
[FIRAuth authWithApp:firebaseApp].settings.appVerificationDisabledForTesting = disabled;
|
|
331
|
+
resolve([NSNull null]);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
+ (void)useUserAccessGroup:(NSString *)appName
|
|
335
|
+
userAccessGroup:(NSString *)userAccessGroup
|
|
336
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
337
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
338
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
339
|
+
|
|
340
|
+
NSError *error;
|
|
341
|
+
[[FIRAuth authWithApp:firebaseApp] useUserAccessGroup:userAccessGroup error:&error];
|
|
342
|
+
|
|
343
|
+
if (!error) {
|
|
344
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
345
|
+
} else {
|
|
346
|
+
[self promiseRejectAuthException:reject error:error];
|
|
347
|
+
}
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
+ (void)signOut:(NSString *)appName
|
|
352
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
353
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
354
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
355
|
+
|
|
356
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
357
|
+
|
|
358
|
+
if (user) {
|
|
359
|
+
NSError *error;
|
|
360
|
+
[[FIRAuth authWithApp:firebaseApp] signOut:&error];
|
|
361
|
+
if (!error) {
|
|
362
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
363
|
+
} else {
|
|
364
|
+
[self promiseRejectAuthException:reject error:error];
|
|
365
|
+
}
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
+ (void)signInAnonymously:(NSString *)appName
|
|
373
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
374
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
375
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
376
|
+
|
|
377
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
378
|
+
signInAnonymouslyWithCompletion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
379
|
+
if (error) {
|
|
380
|
+
[self promiseRejectAuthException:reject error:error];
|
|
381
|
+
} else {
|
|
382
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
383
|
+
}
|
|
384
|
+
}];
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
+ (void)signInWithEmailAndPassword:(NSString *)appName
|
|
388
|
+
email:(NSString *)email
|
|
389
|
+
password:(NSString *)password
|
|
390
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
391
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
392
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
393
|
+
|
|
394
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
395
|
+
signInWithEmail:email
|
|
396
|
+
password:password
|
|
397
|
+
completion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
398
|
+
if (error) {
|
|
399
|
+
[self promiseRejectAuthException:reject error:error];
|
|
400
|
+
} else {
|
|
401
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
402
|
+
}
|
|
403
|
+
}];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
+ (NSNumber *)isSignInWithEmailLink:(NSString *)appName emailLink:(NSString *)emailLink {
|
|
407
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
408
|
+
|
|
409
|
+
return
|
|
410
|
+
@([RCTConvert BOOL:@([[FIRAuth authWithApp:firebaseApp] isSignInWithEmailLink:emailLink])]);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
+ (void)signInWithEmailLink:(NSString *)appName
|
|
414
|
+
email:(NSString *)email
|
|
415
|
+
emailLink:(NSString *)emailLink
|
|
416
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
417
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
418
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
419
|
+
|
|
420
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
421
|
+
signInWithEmail:email
|
|
422
|
+
link:emailLink
|
|
423
|
+
completion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
424
|
+
if (error) {
|
|
425
|
+
[self promiseRejectAuthException:reject error:error];
|
|
426
|
+
} else {
|
|
427
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
428
|
+
}
|
|
429
|
+
}];
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
+ (void)createUserWithEmailAndPassword:(NSString *)appName
|
|
433
|
+
email:(NSString *)email
|
|
434
|
+
password:(NSString *)password
|
|
435
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
436
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
437
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
438
|
+
|
|
439
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
440
|
+
createUserWithEmail:email
|
|
441
|
+
password:password
|
|
442
|
+
completion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
443
|
+
if (error) {
|
|
444
|
+
[self promiseRejectAuthException:reject error:error];
|
|
445
|
+
} else {
|
|
446
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
447
|
+
}
|
|
448
|
+
}];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
+ (void)deleteUser:(NSString *)appName
|
|
452
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
453
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
454
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
455
|
+
|
|
456
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
457
|
+
|
|
458
|
+
if (user) {
|
|
459
|
+
[user deleteWithCompletion:^(NSError *_Nullable error) {
|
|
460
|
+
if (error) {
|
|
461
|
+
[self promiseRejectAuthException:reject error:error];
|
|
462
|
+
} else {
|
|
463
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
464
|
+
}
|
|
465
|
+
}];
|
|
466
|
+
} else {
|
|
467
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
+ (void)reload:(NSString *)appName
|
|
472
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
473
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
474
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
475
|
+
|
|
476
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
477
|
+
if (user) {
|
|
478
|
+
[self reloadAndReturnUser:user resolver:resolve rejecter:reject firebaseApp:firebaseApp];
|
|
479
|
+
} else {
|
|
480
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
+ (void)sendEmailVerification:(NSString *)appName
|
|
485
|
+
actionCodeSettings:(NSDictionary *)actionCodeSettings
|
|
486
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
487
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
488
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
489
|
+
|
|
490
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
491
|
+
if (user) {
|
|
492
|
+
id handler = ^(NSError *_Nullable error) {
|
|
493
|
+
if (error) {
|
|
494
|
+
[self promiseRejectAuthException:reject error:error];
|
|
495
|
+
} else {
|
|
496
|
+
FIRUser *userAfterUpdate = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
497
|
+
[self promiseWithUser:resolve rejecter:reject user:userAfterUpdate];
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
if (actionCodeSettings) {
|
|
501
|
+
FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings];
|
|
502
|
+
[user sendEmailVerificationWithActionCodeSettings:settings completion:handler];
|
|
503
|
+
} else {
|
|
504
|
+
[user sendEmailVerificationWithCompletion:handler];
|
|
505
|
+
}
|
|
506
|
+
} else {
|
|
507
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
+ (void)verifyBeforeUpdateEmail:(NSString *)appName
|
|
512
|
+
email:(NSString *)email
|
|
513
|
+
actionCodeSettings:(NSDictionary *)actionCodeSettings
|
|
514
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
515
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
516
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
517
|
+
|
|
518
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
519
|
+
if (user) {
|
|
520
|
+
id handler = ^(NSError *_Nullable error) {
|
|
521
|
+
if (error) {
|
|
522
|
+
[self promiseRejectAuthException:reject error:error];
|
|
523
|
+
} else {
|
|
524
|
+
FIRUser *userAfterUpdate = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
525
|
+
[self promiseWithUser:resolve rejecter:reject user:userAfterUpdate];
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
if (actionCodeSettings) {
|
|
529
|
+
FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings];
|
|
530
|
+
[user sendEmailVerificationBeforeUpdatingEmail:email
|
|
531
|
+
actionCodeSettings:settings
|
|
532
|
+
completion:handler];
|
|
533
|
+
} else {
|
|
534
|
+
[user sendEmailVerificationBeforeUpdatingEmail:email completion:handler];
|
|
535
|
+
}
|
|
536
|
+
} else {
|
|
537
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
+ (void)updateEmail:(NSString *)appName
|
|
542
|
+
email:(NSString *)email
|
|
543
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
544
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
545
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
546
|
+
|
|
547
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
548
|
+
|
|
549
|
+
if (user) {
|
|
550
|
+
[user updateEmail:email
|
|
551
|
+
completion:^(NSError *_Nullable error) {
|
|
552
|
+
if (error) {
|
|
553
|
+
[self promiseRejectAuthException:reject error:error];
|
|
554
|
+
} else {
|
|
555
|
+
[self reloadAndReturnUser:user
|
|
556
|
+
resolver:resolve
|
|
557
|
+
rejecter:reject
|
|
558
|
+
firebaseApp:firebaseApp];
|
|
559
|
+
}
|
|
560
|
+
}];
|
|
561
|
+
} else {
|
|
562
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
+ (void)updatePassword:(NSString *)appName
|
|
567
|
+
password:(NSString *)password
|
|
568
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
569
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
570
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
571
|
+
|
|
572
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
573
|
+
|
|
574
|
+
if (user) {
|
|
575
|
+
[user updatePassword:password
|
|
576
|
+
completion:^(NSError *_Nullable error) {
|
|
577
|
+
if (error) {
|
|
578
|
+
[self promiseRejectAuthException:reject error:error];
|
|
579
|
+
} else {
|
|
580
|
+
FIRUser *userAfterUpdate = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
581
|
+
[self promiseWithUser:resolve rejecter:reject user:userAfterUpdate];
|
|
582
|
+
}
|
|
583
|
+
}];
|
|
584
|
+
} else {
|
|
585
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
#if TARGET_OS_IOS
|
|
590
|
+
+ (void)updatePhoneNumber:(NSString *)appName
|
|
591
|
+
provider:(NSString *)provider
|
|
592
|
+
authToken:(NSString *)authToken
|
|
593
|
+
authSecret:(NSString *)authSecret
|
|
594
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
595
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
596
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
597
|
+
|
|
598
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
599
|
+
|
|
600
|
+
if (user) {
|
|
601
|
+
FIRPhoneAuthCredential *credential =
|
|
602
|
+
(FIRPhoneAuthCredential *)[self getCredentialForProvider:provider
|
|
603
|
+
token:authToken
|
|
604
|
+
secret:authSecret
|
|
605
|
+
firebaseApp:firebaseApp];
|
|
606
|
+
|
|
607
|
+
if (credential == nil) {
|
|
608
|
+
[RNFBSharedUtils
|
|
609
|
+
rejectPromiseWithUserInfo:reject
|
|
610
|
+
userInfo:(NSMutableDictionary *)@{
|
|
611
|
+
@"code" : @"invalid-credential",
|
|
612
|
+
@"message" : @"The supplied auth credential is malformed, has expired "
|
|
613
|
+
@"or is not currently supported.",
|
|
614
|
+
}];
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
[user updatePhoneNumberCredential:credential
|
|
618
|
+
completion:^(NSError *_Nullable error) {
|
|
619
|
+
if (error) {
|
|
620
|
+
[self promiseRejectAuthException:reject error:error];
|
|
621
|
+
} else {
|
|
622
|
+
FIRUser *userAfterUpdate =
|
|
623
|
+
[FIRAuth authWithApp:firebaseApp].currentUser;
|
|
624
|
+
[self promiseWithUser:resolve rejecter:reject user:userAfterUpdate];
|
|
625
|
+
}
|
|
626
|
+
}];
|
|
627
|
+
} else {
|
|
628
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
#endif
|
|
632
|
+
|
|
633
|
+
+ (void)updateProfile:(NSString *)appName
|
|
634
|
+
props:(NSDictionary *)props
|
|
635
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
636
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
637
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
638
|
+
|
|
639
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
640
|
+
|
|
641
|
+
if (user) {
|
|
642
|
+
FIRUserProfileChangeRequest *changeRequest = [user profileChangeRequest];
|
|
643
|
+
NSMutableArray *allKeys = [[props allKeys] mutableCopy];
|
|
644
|
+
|
|
645
|
+
for (NSString *key in allKeys) {
|
|
646
|
+
@try {
|
|
647
|
+
if ([key isEqualToString:keyPhotoUrl]) {
|
|
648
|
+
NSURL *url = [NSURL URLWithString:[props valueForKey:key]];
|
|
649
|
+
[changeRequest setValue:url forKey:key];
|
|
650
|
+
} else {
|
|
651
|
+
[changeRequest setValue:props[key] forKey:key];
|
|
652
|
+
}
|
|
653
|
+
} @catch (NSException *exception) {
|
|
654
|
+
DLog(@"Exception occurred while configuring: %@", exception);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
[changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) {
|
|
659
|
+
if (error) {
|
|
660
|
+
[self promiseRejectAuthException:reject error:error];
|
|
661
|
+
} else {
|
|
662
|
+
[self reloadAndReturnUser:user resolver:resolve rejecter:reject firebaseApp:firebaseApp];
|
|
663
|
+
}
|
|
664
|
+
}];
|
|
665
|
+
} else {
|
|
666
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
+ (void)getIdToken:(NSString *)appName
|
|
671
|
+
forceRefresh:(BOOL)forceRefresh
|
|
672
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
673
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
674
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
675
|
+
|
|
676
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
677
|
+
|
|
678
|
+
if (user) {
|
|
679
|
+
[user getIDTokenForcingRefresh:(BOOL)forceRefresh
|
|
680
|
+
completion:^(NSString *token, NSError *_Nullable error) {
|
|
681
|
+
if (error) {
|
|
682
|
+
[self promiseRejectAuthException:reject error:error];
|
|
683
|
+
} else {
|
|
684
|
+
resolve(token);
|
|
685
|
+
}
|
|
686
|
+
}];
|
|
687
|
+
} else {
|
|
688
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
+ (void)getIdTokenResult:(NSString *)appName
|
|
693
|
+
forceRefresh:(BOOL)forceRefresh
|
|
694
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
695
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
696
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
697
|
+
|
|
698
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
699
|
+
|
|
700
|
+
if (user) {
|
|
701
|
+
[user
|
|
702
|
+
getIDTokenResultForcingRefresh:(BOOL)forceRefresh
|
|
703
|
+
completion:^(FIRAuthTokenResult *_Nullable tokenResult,
|
|
704
|
+
NSError *_Nullable error) {
|
|
705
|
+
if (error) {
|
|
706
|
+
[self promiseRejectAuthException:reject error:error];
|
|
707
|
+
} else {
|
|
708
|
+
NSMutableDictionary *tokenResultDict =
|
|
709
|
+
[NSMutableDictionary dictionary];
|
|
710
|
+
[tokenResultDict
|
|
711
|
+
setValue:[RNFBSharedUtils getISO8601String:tokenResult.authDate]
|
|
712
|
+
forKey:@"authTime"];
|
|
713
|
+
[tokenResultDict
|
|
714
|
+
setValue:[RNFBSharedUtils
|
|
715
|
+
getISO8601String:tokenResult.issuedAtDate]
|
|
716
|
+
forKey:@"issuedAtTime"];
|
|
717
|
+
[tokenResultDict
|
|
718
|
+
setValue:[RNFBSharedUtils
|
|
719
|
+
getISO8601String:tokenResult.expirationDate]
|
|
720
|
+
forKey:@"expirationTime"];
|
|
721
|
+
|
|
722
|
+
[tokenResultDict setValue:tokenResult.token forKey:@"token"];
|
|
723
|
+
[tokenResultDict setValue:tokenResult.claims forKey:@"claims"];
|
|
724
|
+
|
|
725
|
+
NSString *provider = tokenResult.signInProvider;
|
|
726
|
+
if (!provider) {
|
|
727
|
+
provider = tokenResult.claims[@"firebase"][@"sign_in_provider"];
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
[tokenResultDict setValue:provider forKey:@"signInProvider"];
|
|
731
|
+
resolve(tokenResultDict);
|
|
732
|
+
}
|
|
733
|
+
}];
|
|
734
|
+
} else {
|
|
735
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
+ (void)signInWithCredential:(NSString *)appName
|
|
740
|
+
provider:(NSString *)provider
|
|
741
|
+
authToken:(NSString *)authToken
|
|
742
|
+
authSecret:(NSString *)authSecret
|
|
743
|
+
fullName:(NSDictionary *)fullName
|
|
744
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
745
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
746
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
747
|
+
|
|
748
|
+
FIRAuthCredential *credential = [self getCredentialForProvider:provider
|
|
749
|
+
token:authToken
|
|
750
|
+
secret:authSecret
|
|
751
|
+
firebaseApp:firebaseApp];
|
|
752
|
+
|
|
753
|
+
// Sign in with Apple: if the caller supplied a non-empty fullName (only available on the
|
|
754
|
+
// user's first authorization), rebuild the credential so Firebase can store displayName.
|
|
755
|
+
// See AppleFullPersonName in auth.ts.
|
|
756
|
+
if ([provider compare:@"apple.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
757
|
+
NSPersonNameComponents *personNameComponents =
|
|
758
|
+
[self personNameComponentsFromDictionary:fullName];
|
|
759
|
+
if (personNameComponents != nil) {
|
|
760
|
+
credential = [FIROAuthProvider appleCredentialWithIDToken:authToken
|
|
761
|
+
rawNonce:authSecret
|
|
762
|
+
fullName:personNameComponents];
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (credential == nil) {
|
|
767
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
768
|
+
userInfo:(NSMutableDictionary *)@{
|
|
769
|
+
@"code" : @"invalid-credential",
|
|
770
|
+
@"message" : @"The supplied auth credential is malformed, "
|
|
771
|
+
@"has expired or is not currently supported.",
|
|
772
|
+
}];
|
|
773
|
+
}
|
|
774
|
+
DLog(@"using app SignInWithCredential: %@", firebaseApp.name);
|
|
775
|
+
|
|
776
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
777
|
+
signInWithCredential:credential
|
|
778
|
+
completion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
779
|
+
if (error) {
|
|
780
|
+
[self promiseRejectAuthException:reject error:error];
|
|
781
|
+
} else {
|
|
782
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
783
|
+
}
|
|
784
|
+
}];
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
+ (void)signInWithProvider:(NSString *)appName
|
|
788
|
+
provider:(NSDictionary *)provider
|
|
789
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
790
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
791
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
792
|
+
|
|
793
|
+
NSString *providerId = provider[@"providerId"];
|
|
794
|
+
if (providerId == nil) {
|
|
795
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
796
|
+
userInfo:(NSMutableDictionary *)@{
|
|
797
|
+
@"code" : @"invalid-credential",
|
|
798
|
+
@"message" : @"The supplied auth credential is malformed, "
|
|
799
|
+
@"has expired or is not currently supported.",
|
|
800
|
+
}];
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
__block FIROAuthProvider *builder =
|
|
804
|
+
[FIROAuthProvider providerWithProviderID:providerId auth:[FIRAuth authWithApp:firebaseApp]];
|
|
805
|
+
// Add scopes if present
|
|
806
|
+
if (provider[@"scopes"]) {
|
|
807
|
+
[builder setScopes:provider[@"scopes"]];
|
|
808
|
+
}
|
|
809
|
+
// Add custom parameters if present
|
|
810
|
+
if (provider[@"customParameters"]) {
|
|
811
|
+
[builder setCustomParameters:provider[@"customParameters"]];
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
#if TARGET_OS_IOS
|
|
815
|
+
[builder getCredentialWithUIDelegate:nil
|
|
816
|
+
completion:^(FIRAuthCredential *_Nullable credential,
|
|
817
|
+
NSError *_Nullable error) {
|
|
818
|
+
if (error) {
|
|
819
|
+
[self promiseRejectAuthException:reject error:error];
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
if (credential) {
|
|
823
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
824
|
+
signInWithCredential:credential
|
|
825
|
+
completion:^(FIRAuthDataResult *_Nullable authResult,
|
|
826
|
+
NSError *_Nullable error) {
|
|
827
|
+
if (error) {
|
|
828
|
+
[self promiseRejectAuthException:reject
|
|
829
|
+
error:error];
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
// NOTE: This variable has NO PURPOSE AT ALL, it is
|
|
834
|
+
// only to keep a strong reference to the builder
|
|
835
|
+
// variable so it is not deallocated prematurely by
|
|
836
|
+
// ARC.
|
|
837
|
+
NSString *providerID = builder.providerID;
|
|
838
|
+
|
|
839
|
+
[self promiseWithAuthResult:resolve
|
|
840
|
+
rejecter:reject
|
|
841
|
+
authResult:authResult];
|
|
842
|
+
}];
|
|
843
|
+
}
|
|
844
|
+
}];
|
|
845
|
+
#endif
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
+ (void)confirmPasswordReset:(NSString *)appName
|
|
849
|
+
code:(NSString *)code
|
|
850
|
+
newPassword:(NSString *)newPassword
|
|
851
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
852
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
853
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
854
|
+
|
|
855
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
856
|
+
confirmPasswordResetWithCode:code
|
|
857
|
+
newPassword:newPassword
|
|
858
|
+
completion:^(NSError *_Nullable error) {
|
|
859
|
+
if (error) {
|
|
860
|
+
[self promiseRejectAuthException:reject error:error];
|
|
861
|
+
} else {
|
|
862
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
863
|
+
}
|
|
864
|
+
}];
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
+ (void)applyActionCode:(NSString *)appName
|
|
868
|
+
code:(NSString *)code
|
|
869
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
870
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
871
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
872
|
+
|
|
873
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
874
|
+
applyActionCode:code
|
|
875
|
+
completion:^(NSError *_Nullable error) {
|
|
876
|
+
if (error) {
|
|
877
|
+
[self promiseRejectAuthException:reject error:error];
|
|
878
|
+
} else {
|
|
879
|
+
[self promiseWithUser:resolve
|
|
880
|
+
rejecter:reject
|
|
881
|
+
user:[FIRAuth authWithApp:firebaseApp].currentUser];
|
|
882
|
+
}
|
|
883
|
+
}];
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
+ (void)checkActionCode:(NSString *)appName
|
|
887
|
+
code:(NSString *)code
|
|
888
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
889
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
890
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
891
|
+
|
|
892
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
893
|
+
checkActionCode:code
|
|
894
|
+
completion:^(FIRActionCodeInfo *_Nullable info, NSError *_Nullable error) {
|
|
895
|
+
if (error) {
|
|
896
|
+
[self promiseRejectAuthException:reject error:error];
|
|
897
|
+
} else {
|
|
898
|
+
NSString *actionType = @"ERROR";
|
|
899
|
+
switch (info.operation) {
|
|
900
|
+
case FIRActionCodeOperationPasswordReset:
|
|
901
|
+
actionType = @"PASSWORD_RESET";
|
|
902
|
+
break;
|
|
903
|
+
case FIRActionCodeOperationVerifyEmail:
|
|
904
|
+
actionType = @"VERIFY_EMAIL";
|
|
905
|
+
break;
|
|
906
|
+
case FIRActionCodeOperationUnknown:
|
|
907
|
+
actionType = @"UNKNOWN";
|
|
908
|
+
break;
|
|
909
|
+
case FIRActionCodeOperationRecoverEmail:
|
|
910
|
+
actionType = @"RECOVER_EMAIL";
|
|
911
|
+
break;
|
|
912
|
+
case FIRActionCodeOperationEmailLink:
|
|
913
|
+
actionType = @"EMAIL_SIGNIN";
|
|
914
|
+
break;
|
|
915
|
+
case FIRActionCodeOperationVerifyAndChangeEmail:
|
|
916
|
+
case FIRActionCodeOperationRevertSecondFactorAddition:
|
|
917
|
+
default:
|
|
918
|
+
actionType = @"ERROR";
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
NSMutableDictionary *data = [NSMutableDictionary dictionary];
|
|
923
|
+
|
|
924
|
+
if (info.email != nil) {
|
|
925
|
+
[data setValue:info.email forKey:keyEmail];
|
|
926
|
+
} else {
|
|
927
|
+
[data setValue:[NSNull null] forKey:keyEmail];
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
if (info.previousEmail != nil) {
|
|
931
|
+
[data setValue:info.previousEmail forKey:@"fromEmail"];
|
|
932
|
+
} else {
|
|
933
|
+
[data setValue:[NSNull null] forKey:@"fromEmail"];
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
NSDictionary *result = @{@"data" : data, @"operation" : actionType};
|
|
937
|
+
|
|
938
|
+
resolve(result);
|
|
939
|
+
}
|
|
940
|
+
}];
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
+ (void)revokeToken:(NSString *)appName
|
|
944
|
+
authorizationCode:(NSString *)authorizationCode
|
|
945
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
946
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
947
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
948
|
+
|
|
949
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
950
|
+
revokeTokenWithAuthorizationCode:authorizationCode
|
|
951
|
+
completion:^(NSError *_Nullable error) {
|
|
952
|
+
if (error) {
|
|
953
|
+
[self promiseRejectAuthException:reject error:error];
|
|
954
|
+
} else {
|
|
955
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
956
|
+
}
|
|
957
|
+
}];
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
+ (void)sendPasswordResetEmail:(NSString *)appName
|
|
961
|
+
email:(NSString *)email
|
|
962
|
+
actionCodeSettings:(NSDictionary *)actionCodeSettings
|
|
963
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
964
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
965
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
966
|
+
|
|
967
|
+
id handler = ^(NSError *_Nullable error) {
|
|
968
|
+
if (error) {
|
|
969
|
+
[self promiseRejectAuthException:reject error:error];
|
|
970
|
+
} else {
|
|
971
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
|
|
975
|
+
if (actionCodeSettings) {
|
|
976
|
+
FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings];
|
|
977
|
+
[[FIRAuth authWithApp:firebaseApp] sendPasswordResetWithEmail:email
|
|
978
|
+
actionCodeSettings:settings
|
|
979
|
+
completion:handler];
|
|
980
|
+
} else {
|
|
981
|
+
[[FIRAuth authWithApp:firebaseApp] sendPasswordResetWithEmail:email completion:handler];
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
+ (void)sendSignInLinkToEmail:(NSString *)appName
|
|
986
|
+
email:(NSString *)email
|
|
987
|
+
actionCodeSettings:(NSDictionary *)actionCodeSettings
|
|
988
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
989
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
990
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
991
|
+
|
|
992
|
+
id handler = ^(NSError *_Nullable error) {
|
|
993
|
+
if (error) {
|
|
994
|
+
[self promiseRejectAuthException:reject error:error];
|
|
995
|
+
} else {
|
|
996
|
+
[self promiseNoUser:resolve rejecter:reject isError:NO];
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings];
|
|
1001
|
+
[[FIRAuth authWithApp:firebaseApp] sendSignInLinkToEmail:email
|
|
1002
|
+
actionCodeSettings:settings
|
|
1003
|
+
completion:handler];
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
+ (void)signInWithCustomToken:(NSString *)appName
|
|
1007
|
+
customToken:(NSString *)customToken
|
|
1008
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1009
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1010
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1011
|
+
|
|
1012
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
1013
|
+
signInWithCustomToken:customToken
|
|
1014
|
+
completion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
1015
|
+
if (error) {
|
|
1016
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1017
|
+
} else {
|
|
1018
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
1019
|
+
}
|
|
1020
|
+
}];
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
#if TARGET_OS_IOS
|
|
1024
|
+
+ (void)signInWithPhoneNumber:(NSString *)appName
|
|
1025
|
+
phoneNumber:(NSString *)phoneNumber
|
|
1026
|
+
forceResend:(BOOL)forceResend
|
|
1027
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1028
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1029
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1030
|
+
|
|
1031
|
+
DLog(@"SignInWthPhoneNumber instance: %@", firebaseApp.name);
|
|
1032
|
+
|
|
1033
|
+
(void)forceResend;
|
|
1034
|
+
|
|
1035
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1036
|
+
verifyPhoneNumber:phoneNumber
|
|
1037
|
+
UIDelegate:nil
|
|
1038
|
+
completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) {
|
|
1039
|
+
if (error) {
|
|
1040
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1041
|
+
} else {
|
|
1042
|
+
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
1043
|
+
[defaults setObject:verificationID forKey:@"authVerificationID"];
|
|
1044
|
+
resolve(@{@"verificationId" : verificationID});
|
|
1045
|
+
}
|
|
1046
|
+
}];
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
+ (void)verifyPhoneNumberWithMultiFactorInfo:(NSString *)appName
|
|
1050
|
+
hintUid:(NSString *)hintUid
|
|
1051
|
+
sessionKey:(NSString *)sessionKey
|
|
1052
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1053
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1054
|
+
[self initializeSharedStateOnce];
|
|
1055
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1056
|
+
|
|
1057
|
+
if ([cachedResolver valueForKey:sessionKey] == nil) {
|
|
1058
|
+
[RNFBSharedUtils
|
|
1059
|
+
rejectPromiseWithUserInfo:reject
|
|
1060
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1061
|
+
@"code" : @"invalid-multi-factor-session",
|
|
1062
|
+
@"message" : @"No resolver for session found. Is the session id correct?"
|
|
1063
|
+
}];
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
FIRMultiFactorSession *session = cachedResolver[sessionKey].session;
|
|
1067
|
+
NSPredicate *findByUid = [NSPredicate predicateWithFormat:@"UID == %@", hintUid];
|
|
1068
|
+
FIRMultiFactorInfo *_Nullable hint =
|
|
1069
|
+
[[cachedResolver[sessionKey].hints filteredArrayUsingPredicate:findByUid] firstObject];
|
|
1070
|
+
if (hint == nil) {
|
|
1071
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1072
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1073
|
+
@"code" : @"multi-factor-info-not-found",
|
|
1074
|
+
@"message" : @"The user does not have a second factor "
|
|
1075
|
+
@"matching the identifier provided."
|
|
1076
|
+
}];
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
DLog(@"using instance verifyPhoneNumberWithMultiFactorInfo: %@", firebaseApp.name);
|
|
1080
|
+
|
|
1081
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1082
|
+
verifyPhoneNumberWithMultiFactorInfo:hint
|
|
1083
|
+
UIDelegate:nil
|
|
1084
|
+
multiFactorSession:session
|
|
1085
|
+
completion:^(NSString *_Nullable verificationID,
|
|
1086
|
+
NSError *_Nullable error) {
|
|
1087
|
+
if (error) {
|
|
1088
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1089
|
+
} else {
|
|
1090
|
+
DLog(@"verificationID: %@", verificationID)
|
|
1091
|
+
resolve(verificationID);
|
|
1092
|
+
}
|
|
1093
|
+
}];
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
+ (void)verifyPhoneNumberForMultiFactor:(NSString *)appName
|
|
1097
|
+
phoneNumber:(NSString *)phoneNumber
|
|
1098
|
+
sessionKey:(NSString *)sessionKey
|
|
1099
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1100
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1101
|
+
[self initializeSharedStateOnce];
|
|
1102
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1103
|
+
|
|
1104
|
+
DLog(@"verifyPhoneNumberForMultifactor using app: %@", firebaseApp.name);
|
|
1105
|
+
DLog(@"verifyPhoneNumberForMultifactor phoneNumber: %@", phoneNumber);
|
|
1106
|
+
DLog(@"verifyPhoneNumberForMultifactor sessionKey: %@", sessionKey);
|
|
1107
|
+
FIRMultiFactorSession *session = cachedSessions[sessionKey];
|
|
1108
|
+
if (session == nil) {
|
|
1109
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1110
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1111
|
+
@"code" : @"invalid-multi-factor-session",
|
|
1112
|
+
@"message" : @"can't find session for provided key"
|
|
1113
|
+
}];
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1117
|
+
verifyPhoneNumber:phoneNumber
|
|
1118
|
+
UIDelegate:nil
|
|
1119
|
+
multiFactorSession:session
|
|
1120
|
+
completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) {
|
|
1121
|
+
if (error != nil) {
|
|
1122
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
resolve(verificationID);
|
|
1127
|
+
}];
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
+ (void)resolveMultiFactorSignIn:(NSString *)appName
|
|
1131
|
+
session:(NSString *)session
|
|
1132
|
+
verificationId:(NSString *)verificationId
|
|
1133
|
+
verificationCode:(NSString *)verificationCode
|
|
1134
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1135
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1136
|
+
[self initializeSharedStateOnce];
|
|
1137
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1138
|
+
|
|
1139
|
+
DLog(@"using instance resolve MultiFactorSignIn: %@", firebaseApp.name);
|
|
1140
|
+
|
|
1141
|
+
FIRPhoneAuthCredential *credential =
|
|
1142
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1143
|
+
credentialWithVerificationID:verificationId
|
|
1144
|
+
verificationCode:verificationCode];
|
|
1145
|
+
DLog(@"credential: %@", credential);
|
|
1146
|
+
|
|
1147
|
+
FIRMultiFactorAssertion *assertion =
|
|
1148
|
+
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
|
|
1149
|
+
|
|
1150
|
+
[cachedResolver[session] resolveSignInWithAssertion:assertion
|
|
1151
|
+
completion:^(FIRAuthDataResult *_Nullable authResult,
|
|
1152
|
+
NSError *_Nullable error) {
|
|
1153
|
+
DLog(@"authError: %@", error) if (error) {
|
|
1154
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1155
|
+
}
|
|
1156
|
+
else {
|
|
1157
|
+
[self promiseWithAuthResult:resolve
|
|
1158
|
+
rejecter:reject
|
|
1159
|
+
authResult:authResult];
|
|
1160
|
+
}
|
|
1161
|
+
}];
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
+ (void)resolveTotpSignIn:(NSString *)appName
|
|
1165
|
+
sessionKey:(NSString *)sessionKey
|
|
1166
|
+
uid:(NSString *)uid
|
|
1167
|
+
oneTimePassword:(NSString *)oneTimePassword
|
|
1168
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1169
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1170
|
+
[self initializeSharedStateOnce];
|
|
1171
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1172
|
+
|
|
1173
|
+
DLog(@"using instance resolve TotpSignIn: %@", firebaseApp.name);
|
|
1174
|
+
|
|
1175
|
+
FIRMultiFactorAssertion *assertion =
|
|
1176
|
+
[FIRTOTPMultiFactorGenerator assertionForSignInWithEnrollmentID:uid
|
|
1177
|
+
oneTimePassword:oneTimePassword];
|
|
1178
|
+
[cachedResolver[sessionKey] resolveSignInWithAssertion:assertion
|
|
1179
|
+
completion:^(FIRAuthDataResult *_Nullable authResult,
|
|
1180
|
+
NSError *_Nullable error) {
|
|
1181
|
+
DLog(@"authError: %@", error) if (error) {
|
|
1182
|
+
[self promiseRejectAuthException:reject
|
|
1183
|
+
error:error];
|
|
1184
|
+
}
|
|
1185
|
+
else {
|
|
1186
|
+
[self promiseWithAuthResult:resolve
|
|
1187
|
+
rejecter:reject
|
|
1188
|
+
authResult:authResult];
|
|
1189
|
+
}
|
|
1190
|
+
}];
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
+ (void)generateTotpSecret:(NSString *)appName
|
|
1194
|
+
sessionKey:(NSString *)sessionKey
|
|
1195
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1196
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1197
|
+
[self initializeSharedStateOnce];
|
|
1198
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1199
|
+
|
|
1200
|
+
DLog(@"using instance resolve generateTotpSecret: %@", firebaseApp.name);
|
|
1201
|
+
|
|
1202
|
+
FIRMultiFactorSession *session = cachedSessions[sessionKey];
|
|
1203
|
+
DLog(@"using sessionKey: %@", sessionKey);
|
|
1204
|
+
DLog(@"using session: %@", session);
|
|
1205
|
+
[FIRTOTPMultiFactorGenerator
|
|
1206
|
+
generateSecretWithMultiFactorSession:session
|
|
1207
|
+
completion:^(FIRTOTPSecret *_Nullable totpSecret,
|
|
1208
|
+
NSError *_Nullable error) {
|
|
1209
|
+
DLog(@"authError: %@", error) if (error) {
|
|
1210
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1211
|
+
}
|
|
1212
|
+
else {
|
|
1213
|
+
NSString *secretKey = totpSecret.sharedSecretKey;
|
|
1214
|
+
DLog(@"secretKey generated: %@", secretKey);
|
|
1215
|
+
cachedTotpSecrets[secretKey] = totpSecret;
|
|
1216
|
+
DLog(@"cachedSecret: %@", cachedTotpSecrets[secretKey]);
|
|
1217
|
+
resolve(@{
|
|
1218
|
+
@"secretKey" : secretKey,
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
}];
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
+ (NSString *)generateQrCodeUrl:(NSString *)appName
|
|
1225
|
+
secretKey:(NSString *)secretKey
|
|
1226
|
+
account:(NSString *)account
|
|
1227
|
+
issuer:(NSString *)issuer {
|
|
1228
|
+
[self initializeSharedStateOnce];
|
|
1229
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1230
|
+
|
|
1231
|
+
DLog(@"generateQrCodeUrl using instance resolve generateQrCodeUrl: %@", firebaseApp.name);
|
|
1232
|
+
DLog(@"generateQrCodeUrl using secretKey: %@", secretKey);
|
|
1233
|
+
FIRTOTPSecret *totpSecret = cachedTotpSecrets[secretKey];
|
|
1234
|
+
if (!totpSecret) {
|
|
1235
|
+
RNFBAuthThrowSyncErrorWithCode(@"invalid-multi-factor-secret",
|
|
1236
|
+
@"can't find secret for provided key");
|
|
1237
|
+
}
|
|
1238
|
+
NSString *url = [totpSecret generateQRCodeURLWithAccountName:account issuer:issuer];
|
|
1239
|
+
DLog(@"generateQrCodeUrl got QR Code URL %@", url);
|
|
1240
|
+
return url;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
+ (void)openInOtpApp:(NSString *)appName
|
|
1244
|
+
secretKey:(NSString *)secretKey
|
|
1245
|
+
qrCodeUri:(NSString *)qrCodeUri {
|
|
1246
|
+
[self initializeSharedStateOnce];
|
|
1247
|
+
|
|
1248
|
+
DLog(@"generateQrCodeUrl using secretKey: %@", secretKey);
|
|
1249
|
+
FIRTOTPSecret *totpSecret = cachedTotpSecrets[secretKey];
|
|
1250
|
+
DLog(@"openInOtpApp using qrCodeUri: %@", qrCodeUri);
|
|
1251
|
+
[totpSecret openInOTPAppWithQRCodeURL:qrCodeUri];
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
+ (void)getSession:(NSString *)appName
|
|
1255
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1256
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1257
|
+
[self initializeSharedStateOnce];
|
|
1258
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1259
|
+
|
|
1260
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1261
|
+
[[user multiFactor] getSessionWithCompletion:^(FIRMultiFactorSession *_Nullable session,
|
|
1262
|
+
NSError *_Nullable error) {
|
|
1263
|
+
if (error != nil) {
|
|
1264
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
NSString *sessionId = [NSString stringWithFormat:@"%@", @([session hash])];
|
|
1269
|
+
cachedSessions[sessionId] = session;
|
|
1270
|
+
resolve(sessionId);
|
|
1271
|
+
}];
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
+ (void)unenrollMultiFactor:(NSString *)appName
|
|
1275
|
+
factorUID:(NSString *)factorUID
|
|
1276
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1277
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1278
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1279
|
+
|
|
1280
|
+
DLog(@"using instance unenrollMultiFactor: %@", firebaseApp.name);
|
|
1281
|
+
|
|
1282
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1283
|
+
[user.multiFactor unenrollWithFactorUID:factorUID
|
|
1284
|
+
completion:^(NSError *_Nullable error) {
|
|
1285
|
+
if (error != nil) {
|
|
1286
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
resolve(nil);
|
|
1291
|
+
return;
|
|
1292
|
+
}];
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
+ (void)finalizeMultiFactorEnrollment:(NSString *)appName
|
|
1296
|
+
verificationId:(NSString *)verificationId
|
|
1297
|
+
verificationCode:(NSString *)verificationCode
|
|
1298
|
+
displayName:(NSString *_Nullable)displayName
|
|
1299
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1300
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1301
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1302
|
+
|
|
1303
|
+
DLog(@"using instance finalizeMultifactorEnrollment: %@", firebaseApp.name);
|
|
1304
|
+
|
|
1305
|
+
FIRPhoneAuthCredential *credential =
|
|
1306
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1307
|
+
credentialWithVerificationID:verificationId
|
|
1308
|
+
verificationCode:verificationCode];
|
|
1309
|
+
FIRMultiFactorAssertion *assertion =
|
|
1310
|
+
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
|
|
1311
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1312
|
+
[user.multiFactor enrollWithAssertion:assertion
|
|
1313
|
+
displayName:displayName
|
|
1314
|
+
completion:^(NSError *_Nullable error) {
|
|
1315
|
+
if (error != nil) {
|
|
1316
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
resolve(nil);
|
|
1321
|
+
return;
|
|
1322
|
+
}];
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
+ (void)finalizeTotpEnrollment:(NSString *)appName
|
|
1326
|
+
totpSecret:(NSString *)totpSecret
|
|
1327
|
+
verificationCode:(NSString *)verificationCode
|
|
1328
|
+
displayName:(NSString *_Nullable)displayName
|
|
1329
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1330
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1331
|
+
[self initializeSharedStateOnce];
|
|
1332
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1333
|
+
|
|
1334
|
+
DLog(@"using instance finalizeTotpEnrollment: %@", firebaseApp.name);
|
|
1335
|
+
|
|
1336
|
+
FIRTOTPSecret *cachedTotpSecret = cachedTotpSecrets[totpSecret];
|
|
1337
|
+
DLog(@"using totpSecretKey: %@", totpSecret);
|
|
1338
|
+
DLog(@"using cachedSecret: %@", cachedTotpSecret);
|
|
1339
|
+
FIRTOTPMultiFactorAssertion *assertion =
|
|
1340
|
+
[FIRTOTPMultiFactorGenerator assertionForEnrollmentWithSecret:cachedTotpSecret
|
|
1341
|
+
oneTimePassword:verificationCode];
|
|
1342
|
+
|
|
1343
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1344
|
+
|
|
1345
|
+
[user.multiFactor enrollWithAssertion:assertion
|
|
1346
|
+
displayName:displayName
|
|
1347
|
+
completion:^(NSError *_Nullable error) {
|
|
1348
|
+
if (error != nil) {
|
|
1349
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
resolve(nil);
|
|
1354
|
+
return;
|
|
1355
|
+
}];
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
+ (void)verifyPhoneNumber:(NSString *)appName
|
|
1359
|
+
phoneNumber:(NSString *)phoneNumber
|
|
1360
|
+
requestKey:(NSString *)requestKey
|
|
1361
|
+
timeout:(double)timeout
|
|
1362
|
+
forceResend:(BOOL)forceResend {
|
|
1363
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1364
|
+
|
|
1365
|
+
DLog(@"using instance verifyPhoneNumber: %@", firebaseApp.name);
|
|
1366
|
+
|
|
1367
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1368
|
+
verifyPhoneNumber:phoneNumber
|
|
1369
|
+
UIDelegate:nil
|
|
1370
|
+
completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) {
|
|
1371
|
+
if (error) {
|
|
1372
|
+
NSDictionary *jsError = [self getJSError:error];
|
|
1373
|
+
NSDictionary *body = @{
|
|
1374
|
+
@"type" : @"onVerificationFailed",
|
|
1375
|
+
@"requestKey" : requestKey,
|
|
1376
|
+
@"state" : @{@"error" : jsError},
|
|
1377
|
+
};
|
|
1378
|
+
[RNFBSharedUtils sendJSEventForApp:firebaseApp
|
|
1379
|
+
name:PHONE_AUTH_STATE_CHANGED_EVENT
|
|
1380
|
+
body:body];
|
|
1381
|
+
} else {
|
|
1382
|
+
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
1383
|
+
[defaults setObject:verificationID forKey:@"authVerificationID"];
|
|
1384
|
+
NSDictionary *body = @{
|
|
1385
|
+
@"type" : @"onCodeSent",
|
|
1386
|
+
@"requestKey" : requestKey,
|
|
1387
|
+
@"state" : @{@"verificationId" : verificationID},
|
|
1388
|
+
};
|
|
1389
|
+
[RNFBSharedUtils sendJSEventForApp:firebaseApp
|
|
1390
|
+
name:PHONE_AUTH_STATE_CHANGED_EVENT
|
|
1391
|
+
body:body];
|
|
1392
|
+
}
|
|
1393
|
+
}];
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
+ (void)confirmationResultConfirm:(NSString *)appName
|
|
1397
|
+
verificationCode:(NSString *)verificationCode
|
|
1398
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1399
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1400
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1401
|
+
|
|
1402
|
+
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
1403
|
+
NSString *verificationId = [defaults stringForKey:@"authVerificationID"];
|
|
1404
|
+
|
|
1405
|
+
FIRAuthCredential *credential =
|
|
1406
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1407
|
+
credentialWithVerificationID:verificationId
|
|
1408
|
+
verificationCode:verificationCode];
|
|
1409
|
+
|
|
1410
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
1411
|
+
signInWithCredential:credential
|
|
1412
|
+
completion:^(FIRAuthDataResult *authResult, NSError *error) {
|
|
1413
|
+
DLog(@"auth error: %long", (long)error.code);
|
|
1414
|
+
if (error) {
|
|
1415
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1416
|
+
} else {
|
|
1417
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
1418
|
+
}
|
|
1419
|
+
}];
|
|
1420
|
+
}
|
|
1421
|
+
#endif
|
|
1422
|
+
|
|
1423
|
+
+ (void)linkWithCredential:(NSString *)appName
|
|
1424
|
+
provider:(NSString *)provider
|
|
1425
|
+
authToken:(NSString *)authToken
|
|
1426
|
+
authSecret:(NSString *)authSecret
|
|
1427
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1428
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1429
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1430
|
+
|
|
1431
|
+
FIRAuthCredential *credential = [self getCredentialForProvider:provider
|
|
1432
|
+
token:authToken
|
|
1433
|
+
secret:authSecret
|
|
1434
|
+
firebaseApp:firebaseApp];
|
|
1435
|
+
|
|
1436
|
+
if (credential == nil) {
|
|
1437
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1438
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1439
|
+
@"code" : @"invalid-credential",
|
|
1440
|
+
@"message" : @"The supplied auth credential is malformed, "
|
|
1441
|
+
@"has expired or is not currently supported.",
|
|
1442
|
+
}];
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1446
|
+
if (user) {
|
|
1447
|
+
[user linkWithCredential:credential
|
|
1448
|
+
completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
|
|
1449
|
+
if (error) {
|
|
1450
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1451
|
+
} else {
|
|
1452
|
+
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
|
1453
|
+
}
|
|
1454
|
+
}];
|
|
1455
|
+
} else {
|
|
1456
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
+ (void)linkWithProvider:(NSString *)appName
|
|
1461
|
+
provider:(NSDictionary *)provider
|
|
1462
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1463
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1464
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1465
|
+
|
|
1466
|
+
NSString *providerId = provider[@"providerId"];
|
|
1467
|
+
if (providerId == nil) {
|
|
1468
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1469
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1470
|
+
@"code" : @"invalid-credential",
|
|
1471
|
+
@"message" : @"The supplied auth credential is malformed, "
|
|
1472
|
+
@"has expired or is not currently supported.",
|
|
1473
|
+
}];
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
__block FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1477
|
+
if (user == nil) {
|
|
1478
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
1479
|
+
return;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
__block FIROAuthProvider *builder =
|
|
1483
|
+
[FIROAuthProvider providerWithProviderID:providerId auth:[FIRAuth authWithApp:firebaseApp]];
|
|
1484
|
+
// Add scopes if present
|
|
1485
|
+
if (provider[@"scopes"]) {
|
|
1486
|
+
[builder setScopes:provider[@"scopes"]];
|
|
1487
|
+
}
|
|
1488
|
+
// Add custom parameters if present
|
|
1489
|
+
if (provider[@"parameters"]) {
|
|
1490
|
+
[builder setCustomParameters:provider[@"parameters"]];
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
#if TARGET_OS_IOS
|
|
1494
|
+
[builder getCredentialWithUIDelegate:nil
|
|
1495
|
+
completion:^(FIRAuthCredential *_Nullable credential,
|
|
1496
|
+
NSError *_Nullable error) {
|
|
1497
|
+
if (error) {
|
|
1498
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
if (credential) {
|
|
1502
|
+
[user linkWithCredential:credential
|
|
1503
|
+
completion:^(FIRAuthDataResult *_Nullable authResult,
|
|
1504
|
+
NSError *_Nullable error) {
|
|
1505
|
+
if (error) {
|
|
1506
|
+
[self promiseRejectAuthException:reject
|
|
1507
|
+
error:error];
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// NOTE: This variable has NO PURPOSE AT ALL, it is
|
|
1512
|
+
// only to keep a strong reference to the builder
|
|
1513
|
+
// variable so it is not deallocated prematurely by
|
|
1514
|
+
// ARC.
|
|
1515
|
+
NSString *providerID = builder.providerID;
|
|
1516
|
+
|
|
1517
|
+
[self promiseWithAuthResult:resolve
|
|
1518
|
+
rejecter:reject
|
|
1519
|
+
authResult:authResult];
|
|
1520
|
+
}];
|
|
1521
|
+
}
|
|
1522
|
+
}];
|
|
1523
|
+
#endif
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
+ (void)unlink:(NSString *)appName
|
|
1527
|
+
providerId:(NSString *)providerId
|
|
1528
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1529
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1530
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1531
|
+
|
|
1532
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1533
|
+
|
|
1534
|
+
if (user) {
|
|
1535
|
+
[user unlinkFromProvider:providerId
|
|
1536
|
+
completion:^(FIRUser *_Nullable _user, NSError *_Nullable error) {
|
|
1537
|
+
if (error) {
|
|
1538
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1539
|
+
} else {
|
|
1540
|
+
[self reloadAndReturnUser:user
|
|
1541
|
+
resolver:resolve
|
|
1542
|
+
rejecter:reject
|
|
1543
|
+
firebaseApp:firebaseApp];
|
|
1544
|
+
}
|
|
1545
|
+
}];
|
|
1546
|
+
} else {
|
|
1547
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
+ (void)reauthenticateWithCredential:(NSString *)appName
|
|
1552
|
+
provider:(NSString *)provider
|
|
1553
|
+
authToken:(NSString *)authToken
|
|
1554
|
+
authSecret:(NSString *)authSecret
|
|
1555
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1556
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1557
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1558
|
+
|
|
1559
|
+
FIRAuthCredential *credential = [self getCredentialForProvider:provider
|
|
1560
|
+
token:authToken
|
|
1561
|
+
secret:authSecret
|
|
1562
|
+
firebaseApp:firebaseApp];
|
|
1563
|
+
|
|
1564
|
+
if (credential == nil) {
|
|
1565
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1566
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1567
|
+
@"code" : @"invalid-credential",
|
|
1568
|
+
@"message" : @"The supplied auth credential is malformed, "
|
|
1569
|
+
@"has expired or is not currently supported.",
|
|
1570
|
+
}];
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1574
|
+
|
|
1575
|
+
if (user) {
|
|
1576
|
+
[user reauthenticateWithCredential:credential
|
|
1577
|
+
completion:^(FIRAuthDataResult *_Nullable authResult,
|
|
1578
|
+
NSError *_Nullable error) {
|
|
1579
|
+
if (error) {
|
|
1580
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1581
|
+
} else {
|
|
1582
|
+
[self promiseWithAuthResult:resolve
|
|
1583
|
+
rejecter:reject
|
|
1584
|
+
authResult:authResult];
|
|
1585
|
+
}
|
|
1586
|
+
}];
|
|
1587
|
+
} else {
|
|
1588
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
+ (void)reauthenticateWithProvider:(NSString *)appName
|
|
1593
|
+
provider:(NSDictionary *)provider
|
|
1594
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1595
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1596
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1597
|
+
|
|
1598
|
+
NSString *providerId = provider[@"providerId"];
|
|
1599
|
+
if (providerId == nil) {
|
|
1600
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1601
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1602
|
+
@"code" : @"invalid-credential",
|
|
1603
|
+
@"message" : @"The supplied auth credential is malformed, "
|
|
1604
|
+
@"has expired or is not currently supported.",
|
|
1605
|
+
}];
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
__block FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
1609
|
+
if (user == nil) {
|
|
1610
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
1611
|
+
return;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
__block FIROAuthProvider *builder =
|
|
1615
|
+
[FIROAuthProvider providerWithProviderID:providerId auth:[FIRAuth authWithApp:firebaseApp]];
|
|
1616
|
+
// Add scopes if present
|
|
1617
|
+
if (provider[@"scopes"]) {
|
|
1618
|
+
[builder setScopes:provider[@"scopes"]];
|
|
1619
|
+
}
|
|
1620
|
+
// Add custom parameters if present
|
|
1621
|
+
if (provider[@"parameters"]) {
|
|
1622
|
+
[builder setCustomParameters:provider[@"parameters"]];
|
|
1623
|
+
}
|
|
1624
|
+
#if TARGET_OS_IOS
|
|
1625
|
+
[builder getCredentialWithUIDelegate:nil
|
|
1626
|
+
completion:^(FIRAuthCredential *_Nullable credential,
|
|
1627
|
+
NSError *_Nullable error) {
|
|
1628
|
+
if (error) {
|
|
1629
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1630
|
+
return;
|
|
1631
|
+
}
|
|
1632
|
+
if (credential) {
|
|
1633
|
+
[user reauthenticateWithCredential:credential
|
|
1634
|
+
completion:^(
|
|
1635
|
+
FIRAuthDataResult *_Nullable authResult,
|
|
1636
|
+
NSError *_Nullable error) {
|
|
1637
|
+
if (error) {
|
|
1638
|
+
[self promiseRejectAuthException:reject
|
|
1639
|
+
error:error];
|
|
1640
|
+
return;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// NOTE: This variable has NO PURPOSE AT
|
|
1644
|
+
// ALL, it is only to keep a strong
|
|
1645
|
+
// reference to the builder variable so it
|
|
1646
|
+
// is not deallocated prematurely by ARC.
|
|
1647
|
+
NSString *providerID = builder.providerID;
|
|
1648
|
+
|
|
1649
|
+
[self promiseWithAuthResult:resolve
|
|
1650
|
+
rejecter:reject
|
|
1651
|
+
authResult:authResult];
|
|
1652
|
+
}];
|
|
1653
|
+
}
|
|
1654
|
+
}];
|
|
1655
|
+
#endif
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
+ (void)fetchSignInMethodsForEmail:(NSString *)appName
|
|
1659
|
+
email:(NSString *)email
|
|
1660
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1661
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1662
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1663
|
+
|
|
1664
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
1665
|
+
fetchSignInMethodsForEmail:email
|
|
1666
|
+
completion:^(NSArray<NSString *> *_Nullable providers,
|
|
1667
|
+
NSError *_Nullable error) {
|
|
1668
|
+
if (error) {
|
|
1669
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1670
|
+
} else if (!providers) {
|
|
1671
|
+
NSMutableArray *emptyResponse = [[NSMutableArray alloc] init];
|
|
1672
|
+
resolve(emptyResponse);
|
|
1673
|
+
} else {
|
|
1674
|
+
resolve(providers);
|
|
1675
|
+
}
|
|
1676
|
+
}];
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
+ (void)setLanguageCode:(NSString *)appName code:(NSString *)code {
|
|
1680
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1681
|
+
|
|
1682
|
+
if (code) {
|
|
1683
|
+
[FIRAuth authWithApp:firebaseApp].languageCode = code;
|
|
1684
|
+
} else {
|
|
1685
|
+
[[FIRAuth authWithApp:firebaseApp] useAppLanguage];
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
+ (void)setTenantId:(NSString *)appName
|
|
1690
|
+
tenantId:(NSString *)tenantId
|
|
1691
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1692
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1693
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1694
|
+
|
|
1695
|
+
[FIRAuth authWithApp:firebaseApp].tenantID = tenantId;
|
|
1696
|
+
resolve([NSNull null]);
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
+ (void)useDeviceLanguage:(NSString *)appName {
|
|
1700
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1701
|
+
|
|
1702
|
+
[[FIRAuth authWithApp:firebaseApp] useAppLanguage];
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
+ (void)verifyPasswordResetCode:(NSString *)appName
|
|
1706
|
+
code:(NSString *)code
|
|
1707
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
1708
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
1709
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1710
|
+
|
|
1711
|
+
[[FIRAuth authWithApp:firebaseApp]
|
|
1712
|
+
verifyPasswordResetCode:code
|
|
1713
|
+
completion:^(NSString *_Nullable email, NSError *_Nullable error) {
|
|
1714
|
+
if (error) {
|
|
1715
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1716
|
+
} else {
|
|
1717
|
+
resolve(email);
|
|
1718
|
+
}
|
|
1719
|
+
}];
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
+ (void)useEmulator:(NSString *)appName host:(nonnull NSString *)host port:(double)port {
|
|
1723
|
+
[self initializeSharedStateOnce];
|
|
1724
|
+
FIRApp *firebaseApp = [RCTConvert firAppFromString:appName];
|
|
1725
|
+
|
|
1726
|
+
if (!emulatorConfigs[firebaseApp.name]) {
|
|
1727
|
+
[[FIRAuth authWithApp:firebaseApp] useEmulatorWithHost:host port:(NSInteger)port];
|
|
1728
|
+
emulatorConfigs[firebaseApp.name] = @YES;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
+ (NSString *)nonEmptyStringFromDictionary:(NSDictionary *)dictionary key:(NSString *)key {
|
|
1733
|
+
id value = dictionary[key];
|
|
1734
|
+
if (![value isKindOfClass:[NSString class]]) {
|
|
1735
|
+
return nil;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
NSString *stringValue = (NSString *)value;
|
|
1739
|
+
NSString *trimmed = [stringValue
|
|
1740
|
+
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
1741
|
+
return trimmed.length > 0 ? stringValue : nil;
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
+ (NSPersonNameComponents *)personNameComponentsFromDictionary:(NSDictionary *)dictionary {
|
|
1745
|
+
if (dictionary == nil || (id)dictionary == [NSNull null]) {
|
|
1746
|
+
return nil;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
NSPersonNameComponents *components = [[NSPersonNameComponents alloc] init];
|
|
1750
|
+
BOOL hasAnyComponent = NO;
|
|
1751
|
+
NSString *namePrefix = [self nonEmptyStringFromDictionary:dictionary key:@"namePrefix"];
|
|
1752
|
+
if (namePrefix != nil) {
|
|
1753
|
+
components.namePrefix = namePrefix;
|
|
1754
|
+
hasAnyComponent = YES;
|
|
1755
|
+
}
|
|
1756
|
+
NSString *givenName = [self nonEmptyStringFromDictionary:dictionary key:@"givenName"];
|
|
1757
|
+
if (givenName != nil) {
|
|
1758
|
+
components.givenName = givenName;
|
|
1759
|
+
hasAnyComponent = YES;
|
|
1760
|
+
}
|
|
1761
|
+
NSString *middleName = [self nonEmptyStringFromDictionary:dictionary key:@"middleName"];
|
|
1762
|
+
if (middleName != nil) {
|
|
1763
|
+
components.middleName = middleName;
|
|
1764
|
+
hasAnyComponent = YES;
|
|
1765
|
+
}
|
|
1766
|
+
NSString *familyName = [self nonEmptyStringFromDictionary:dictionary key:@"familyName"];
|
|
1767
|
+
if (familyName != nil) {
|
|
1768
|
+
components.familyName = familyName;
|
|
1769
|
+
hasAnyComponent = YES;
|
|
1770
|
+
}
|
|
1771
|
+
NSString *nameSuffix = [self nonEmptyStringFromDictionary:dictionary key:@"nameSuffix"];
|
|
1772
|
+
if (nameSuffix != nil) {
|
|
1773
|
+
components.nameSuffix = nameSuffix;
|
|
1774
|
+
hasAnyComponent = YES;
|
|
1775
|
+
}
|
|
1776
|
+
NSString *nickname = [self nonEmptyStringFromDictionary:dictionary key:@"nickname"];
|
|
1777
|
+
if (nickname != nil) {
|
|
1778
|
+
components.nickname = nickname;
|
|
1779
|
+
hasAnyComponent = YES;
|
|
1780
|
+
}
|
|
1781
|
+
return hasAnyComponent ? components : nil;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
+ (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider
|
|
1785
|
+
token:(NSString *)authToken
|
|
1786
|
+
secret:(NSString *)authTokenSecret
|
|
1787
|
+
firebaseApp:(FIRApp *)firebaseApp {
|
|
1788
|
+
[self initializeSharedStateOnce];
|
|
1789
|
+
FIRAuthCredential *credential;
|
|
1790
|
+
|
|
1791
|
+
// First check if we cached an authToken
|
|
1792
|
+
if (credentials[authToken] != nil && ![credentials[authToken] isEqual:[NSNull null]]) {
|
|
1793
|
+
credential = credentials[authToken];
|
|
1794
|
+
} else if ([provider compare:@"twitter.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1795
|
+
credential = [FIRTwitterAuthProvider credentialWithToken:authToken secret:authTokenSecret];
|
|
1796
|
+
} else if ([provider compare:@"facebook.com" options:NSCaseInsensitiveSearch] == NSOrderedSame &&
|
|
1797
|
+
![authTokenSecret isEqualToString:@""]) {
|
|
1798
|
+
credential = [FIROAuthProvider credentialWithProviderID:provider
|
|
1799
|
+
IDToken:authToken
|
|
1800
|
+
rawNonce:authTokenSecret];
|
|
1801
|
+
} else if ([provider compare:@"facebook.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1802
|
+
credential = [FIRFacebookAuthProvider credentialWithAccessToken:authToken];
|
|
1803
|
+
} else if ([provider compare:@"google.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1804
|
+
credential = [FIRGoogleAuthProvider credentialWithIDToken:authToken
|
|
1805
|
+
accessToken:authTokenSecret];
|
|
1806
|
+
} else if ([provider compare:@"apple.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1807
|
+
credential = [FIROAuthProvider credentialWithProviderID:provider
|
|
1808
|
+
IDToken:authToken
|
|
1809
|
+
rawNonce:authTokenSecret];
|
|
1810
|
+
} else if ([provider compare:@"password" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1811
|
+
credential = [FIREmailAuthProvider credentialWithEmail:authToken password:authTokenSecret];
|
|
1812
|
+
} else if ([provider compare:@"emailLink" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1813
|
+
credential = [FIREmailAuthProvider credentialWithEmail:authToken link:authTokenSecret];
|
|
1814
|
+
} else if ([provider compare:@"github.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1815
|
+
credential = [FIRGitHubAuthProvider credentialWithToken:authToken];
|
|
1816
|
+
} else if ([provider compare:@"phone" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1817
|
+
#if TARGET_OS_IOS
|
|
1818
|
+
DLog(@"using app credGen: %@", firebaseApp.name) credential =
|
|
1819
|
+
[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]]
|
|
1820
|
+
credentialWithVerificationID:authToken
|
|
1821
|
+
verificationCode:authTokenSecret];
|
|
1822
|
+
#endif
|
|
1823
|
+
} else if ([provider compare:@"oauth" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
|
1824
|
+
NSString *IDToken = authToken.length > 0 ? authToken : nil;
|
|
1825
|
+
NSString *accessToken = authTokenSecret.length > 0 ? authTokenSecret : nil;
|
|
1826
|
+
credential = [FIROAuthProvider credentialWithProviderID:@"oauth"
|
|
1827
|
+
IDToken:IDToken
|
|
1828
|
+
accessToken:accessToken];
|
|
1829
|
+
} else if ([provider hasPrefix:@"oidc."]) {
|
|
1830
|
+
credential = [FIROAuthProvider credentialWithProviderID:provider
|
|
1831
|
+
IDToken:authToken
|
|
1832
|
+
rawNonce:nil];
|
|
1833
|
+
} else {
|
|
1834
|
+
DLog(@"Provider not yet handled: %@", provider);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
return credential;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
// This is here to protect against bugs in the iOS SDK which don't
|
|
1841
|
+
// correctly refresh the user object when performing certain operations
|
|
1842
|
+
+ (void)reloadAndReturnUser:(FIRUser *)user
|
|
1843
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1844
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
1845
|
+
firebaseApp:(FIRApp *)firebaseApp {
|
|
1846
|
+
[user reloadWithCompletion:^(NSError *_Nullable error) {
|
|
1847
|
+
if (error) {
|
|
1848
|
+
[self promiseRejectAuthException:reject error:error];
|
|
1849
|
+
} else {
|
|
1850
|
+
[self promiseWithUser:resolve rejecter:reject user:user];
|
|
1851
|
+
}
|
|
1852
|
+
}];
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
+ (void)promiseNoUser:(RCTPromiseResolveBlock)resolve
|
|
1856
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
1857
|
+
isError:(BOOL)isError {
|
|
1858
|
+
if (isError) {
|
|
1859
|
+
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
|
|
1860
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1861
|
+
@"code" : @"no-current-user",
|
|
1862
|
+
@"message" : @"No user currently signed in.",
|
|
1863
|
+
}];
|
|
1864
|
+
} else {
|
|
1865
|
+
resolve([NSNull null]);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
#if TARGET_OS_IOS
|
|
1870
|
+
+ (NSDictionary *)multiFactorResolverToDict:(FIRMultiFactorResolver *)resolver {
|
|
1871
|
+
// Temporarily store the non-serializable session for later
|
|
1872
|
+
NSString *sessionHash = [NSString stringWithFormat:@"%@", @([resolver.session hash])];
|
|
1873
|
+
|
|
1874
|
+
return @{
|
|
1875
|
+
@"hints" : [self convertMultiFactorData:resolver.hints],
|
|
1876
|
+
@"session" : sessionHash,
|
|
1877
|
+
@"auth" : resolver.auth
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1880
|
+
#endif
|
|
1881
|
+
|
|
1882
|
+
+ (void)promiseRejectAuthException:(RCTPromiseRejectBlock)reject error:(NSError *)error {
|
|
1883
|
+
NSDictionary *jsError = [self getJSError:error];
|
|
1884
|
+
|
|
1885
|
+
[RNFBSharedUtils
|
|
1886
|
+
rejectPromiseWithUserInfo:reject
|
|
1887
|
+
userInfo:(NSMutableDictionary *)@{
|
|
1888
|
+
@"code" : [jsError valueForKey:@"code"],
|
|
1889
|
+
@"message" : [jsError valueForKey:@"message"],
|
|
1890
|
+
@"nativeErrorMessage" : [jsError valueForKey:@"nativeErrorMessage"],
|
|
1891
|
+
@"authCredential" : [jsError valueForKey:@"authCredential"],
|
|
1892
|
+
@"resolver" : [jsError valueForKey:@"resolver"]
|
|
1893
|
+
}];
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
+ (NSDictionary *)getJSError:(NSError *)error {
|
|
1897
|
+
[self initializeSharedStateOnce];
|
|
1898
|
+
NSString *code = AuthErrorCode_toJSErrorCode[error.code];
|
|
1899
|
+
NSString *message = [error localizedDescription];
|
|
1900
|
+
NSString *nativeErrorMessage = [error localizedDescription];
|
|
1901
|
+
|
|
1902
|
+
if (code == nil) code = @"unknown";
|
|
1903
|
+
|
|
1904
|
+
// TODO(Salakar): replace these with a AuthErrorCode_toJSErrorMessage map (like codes now does)
|
|
1905
|
+
switch (error.code) {
|
|
1906
|
+
case FIRAuthErrorCodeInvalidCustomToken:
|
|
1907
|
+
message = @"The custom token format is incorrect. Please check the documentation.";
|
|
1908
|
+
break;
|
|
1909
|
+
case FIRAuthErrorCodeCustomTokenMismatch:
|
|
1910
|
+
message = @"The custom token corresponds to a different audience.";
|
|
1911
|
+
break;
|
|
1912
|
+
case FIRAuthErrorCodeInvalidCredential:
|
|
1913
|
+
message = @"The supplied auth credential is malformed or has expired.";
|
|
1914
|
+
break;
|
|
1915
|
+
case FIRAuthErrorCodeInvalidEmail:
|
|
1916
|
+
message = @"The email address is badly formatted.";
|
|
1917
|
+
break;
|
|
1918
|
+
case FIRAuthErrorCodeWrongPassword:
|
|
1919
|
+
message = @"The password is invalid or the user does not have a password.";
|
|
1920
|
+
break;
|
|
1921
|
+
case FIRAuthErrorCodeUserMismatch:
|
|
1922
|
+
message = @"The supplied credentials do not correspond to the previously signed in user.";
|
|
1923
|
+
break;
|
|
1924
|
+
case FIRAuthErrorCodeRequiresRecentLogin:
|
|
1925
|
+
message = @"This operation is sensitive and requires recent authentication. Log in again "
|
|
1926
|
+
@"before retrying this request.";
|
|
1927
|
+
break;
|
|
1928
|
+
case FIRAuthErrorCodeSecondFactorRequired:
|
|
1929
|
+
message = @"Please complete a second factor challenge to finish signing into this account.";
|
|
1930
|
+
break;
|
|
1931
|
+
case FIRAuthErrorCodeAccountExistsWithDifferentCredential:
|
|
1932
|
+
message = @"An account already exists with the same email address but different sign-in "
|
|
1933
|
+
@"credentials. Sign in using a provider associated with this email address.";
|
|
1934
|
+
break;
|
|
1935
|
+
case FIRAuthErrorCodeEmailAlreadyInUse:
|
|
1936
|
+
message = @"The email address is already in use by another account.";
|
|
1937
|
+
break;
|
|
1938
|
+
case FIRAuthErrorCodeCredentialAlreadyInUse:
|
|
1939
|
+
message = @"This credential is already associated with a different user account.";
|
|
1940
|
+
break;
|
|
1941
|
+
case FIRAuthErrorCodeUserDisabled:
|
|
1942
|
+
message = @"The user account has been disabled by an administrator.";
|
|
1943
|
+
break;
|
|
1944
|
+
case FIRAuthErrorCodeUserTokenExpired:
|
|
1945
|
+
message = @"The user's credential is no longer valid. The user must sign in again.";
|
|
1946
|
+
break;
|
|
1947
|
+
case FIRAuthErrorCodeUserNotFound:
|
|
1948
|
+
message = @"There is no user record corresponding to this identifier. The user may have been "
|
|
1949
|
+
@"deleted.";
|
|
1950
|
+
break;
|
|
1951
|
+
case FIRAuthErrorCodeInvalidUserToken:
|
|
1952
|
+
message = @"The user's credential is no longer valid. The user must sign in again.";
|
|
1953
|
+
break;
|
|
1954
|
+
case FIRAuthErrorCodeWeakPassword:
|
|
1955
|
+
message = @"The given password is invalid.";
|
|
1956
|
+
break;
|
|
1957
|
+
case FIRAuthErrorCodeOperationNotAllowed:
|
|
1958
|
+
message = @"This operation is not allowed. You must enable this service in the console.";
|
|
1959
|
+
break;
|
|
1960
|
+
case FIRAuthErrorCodeNetworkError:
|
|
1961
|
+
message = @"A network error has occurred, please try again.";
|
|
1962
|
+
break;
|
|
1963
|
+
case FIRAuthErrorCodeInternalError:
|
|
1964
|
+
message = @"An internal error has occurred, please try again.";
|
|
1965
|
+
break;
|
|
1966
|
+
case FIRAuthErrorCodeInvalidPhoneNumber:
|
|
1967
|
+
message = @"The format of the phone number provided is incorrect. "
|
|
1968
|
+
@"Please enter the phone number in a format that can be parsed into E.164 format. "
|
|
1969
|
+
@"E.164 phone numbers are written in the format [+][country code][subscriber "
|
|
1970
|
+
@"number including area code].";
|
|
1971
|
+
break;
|
|
1972
|
+
default:
|
|
1973
|
+
break;
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
NSDictionary *authCredentialDict = nil;
|
|
1977
|
+
if ([error userInfo][FIRAuthErrorUserInfoUpdatedCredentialKey] != nil) {
|
|
1978
|
+
FIRAuthCredential *authCredential = [error userInfo][FIRAuthErrorUserInfoUpdatedCredentialKey];
|
|
1979
|
+
authCredentialDict = [self authCredentialToDict:authCredential];
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
NSDictionary *resolverDict = nil;
|
|
1983
|
+
#if TARGET_OS_IOS
|
|
1984
|
+
if ([error userInfo][FIRAuthErrorUserInfoMultiFactorResolverKey] != nil) {
|
|
1985
|
+
FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
|
|
1986
|
+
resolverDict = [self multiFactorResolverToDict:resolver];
|
|
1987
|
+
|
|
1988
|
+
NSString *sessionKey = [NSString stringWithFormat:@"%@", @([resolver.session hash])];
|
|
1989
|
+
cachedResolver[sessionKey] = resolver;
|
|
1990
|
+
}
|
|
1991
|
+
#endif
|
|
1992
|
+
|
|
1993
|
+
return @{
|
|
1994
|
+
@"code" : code,
|
|
1995
|
+
@"message" : message,
|
|
1996
|
+
@"nativeErrorMessage" : nativeErrorMessage,
|
|
1997
|
+
@"authCredential" : authCredentialDict != nil ? (id)authCredentialDict : [NSNull null],
|
|
1998
|
+
@"resolver" : resolverDict != nil ? (id)resolverDict : [NSNull null]
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
+ (void)promiseWithUser:(RCTPromiseResolveBlock)resolve
|
|
2003
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
2004
|
+
user:(FIRUser *)user {
|
|
2005
|
+
if (user) {
|
|
2006
|
+
NSDictionary *userDict = [self firebaseUserToDict:user];
|
|
2007
|
+
resolve(userDict);
|
|
2008
|
+
} else {
|
|
2009
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
+ (void)promiseWithAuthResult:(RCTPromiseResolveBlock)resolve
|
|
2014
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
2015
|
+
authResult:(FIRAuthDataResult *)authResult {
|
|
2016
|
+
if (authResult && authResult.user) {
|
|
2017
|
+
NSMutableDictionary *authResultDict = [NSMutableDictionary dictionary];
|
|
2018
|
+
|
|
2019
|
+
if (authResult.additionalUserInfo) {
|
|
2020
|
+
NSMutableDictionary *additionalUserInfo = [NSMutableDictionary dictionary];
|
|
2021
|
+
|
|
2022
|
+
[additionalUserInfo setValue:@(authResult.additionalUserInfo.isNewUser) forKey:keyNewUser];
|
|
2023
|
+
|
|
2024
|
+
if (authResult.additionalUserInfo.profile) {
|
|
2025
|
+
[additionalUserInfo setValue:authResult.additionalUserInfo.profile forKey:keyProfile];
|
|
2026
|
+
} else {
|
|
2027
|
+
[additionalUserInfo setValue:[NSNull null] forKey:keyProfile];
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
if (authResult.additionalUserInfo.providerID) {
|
|
2031
|
+
[additionalUserInfo setValue:authResult.additionalUserInfo.providerID forKey:keyProviderId];
|
|
2032
|
+
} else {
|
|
2033
|
+
[additionalUserInfo setValue:[NSNull null] forKey:keyProviderId];
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
if (authResult.additionalUserInfo.username) {
|
|
2037
|
+
[additionalUserInfo setValue:authResult.additionalUserInfo.username forKey:keyUsername];
|
|
2038
|
+
} else {
|
|
2039
|
+
[additionalUserInfo setValue:[NSNull null] forKey:keyUsername];
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
[authResultDict setValue:additionalUserInfo forKey:keyAdditionalUserInfo];
|
|
2043
|
+
} else {
|
|
2044
|
+
[authResultDict setValue:[NSNull null] forKey:keyAdditionalUserInfo];
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
[authResultDict setValue:[self firebaseUserToDict:authResult.user] forKey:keyUser];
|
|
2048
|
+
resolve(authResultDict);
|
|
2049
|
+
} else {
|
|
2050
|
+
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
+ (NSArray<NSObject *> *)convertProviderData:(NSArray<id<FIRUserInfo>> *)providerData {
|
|
2055
|
+
NSMutableArray *output = [NSMutableArray array];
|
|
2056
|
+
|
|
2057
|
+
for (id<FIRUserInfo> userInfo in providerData) {
|
|
2058
|
+
NSMutableDictionary *pData = [NSMutableDictionary dictionary];
|
|
2059
|
+
|
|
2060
|
+
if (userInfo.providerID != nil) {
|
|
2061
|
+
[pData setValue:userInfo.providerID forKey:keyProviderId];
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
if (userInfo.uid != nil) {
|
|
2065
|
+
[pData setValue:userInfo.uid forKey:keyUid];
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
if (userInfo.displayName != nil) {
|
|
2069
|
+
[pData setValue:userInfo.displayName forKey:keyDisplayName];
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
if (userInfo.photoURL != nil) {
|
|
2073
|
+
[pData setValue:[userInfo.photoURL absoluteString] forKey:keyPhotoUrl];
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
if (userInfo.email != nil) {
|
|
2077
|
+
[pData setValue:userInfo.email forKey:keyEmail];
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
if (userInfo.phoneNumber != nil) {
|
|
2081
|
+
[pData setValue:userInfo.phoneNumber forKey:keyPhoneNumber];
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
[output addObject:pData];
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
return output;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
+ (NSDictionary *)authConstantsDictionary {
|
|
2091
|
+
NSDictionary *firebaseApps = [FIRApp allApps];
|
|
2092
|
+
NSMutableDictionary *constants = [NSMutableDictionary new];
|
|
2093
|
+
NSMutableDictionary *appLanguage = [NSMutableDictionary new];
|
|
2094
|
+
NSMutableDictionary *appUser = [NSMutableDictionary new];
|
|
2095
|
+
|
|
2096
|
+
for (id key in firebaseApps) {
|
|
2097
|
+
FIRApp *firebaseApp = firebaseApps[key];
|
|
2098
|
+
NSString *appName = firebaseApp.name;
|
|
2099
|
+
FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser;
|
|
2100
|
+
|
|
2101
|
+
if ([appName isEqualToString:@"__FIRAPP_DEFAULT"]) {
|
|
2102
|
+
appName = @"[DEFAULT]";
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
appLanguage[appName] = [FIRAuth authWithApp:firebaseApp].languageCode;
|
|
2106
|
+
|
|
2107
|
+
if (user != nil) {
|
|
2108
|
+
appUser[appName] = [self firebaseUserToDict:user];
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
constants[constAppLanguage] = appLanguage;
|
|
2113
|
+
constants[constAppUser] = appUser;
|
|
2114
|
+
return constants;
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2117
|
+
+ (NSDictionary *)firebaseUserToDict:(FIRUser *)user {
|
|
2118
|
+
return @{
|
|
2119
|
+
keyDisplayName : user.displayName ? (id)user.displayName : [NSNull null],
|
|
2120
|
+
keyEmail : user.email ? (id)user.email : [NSNull null],
|
|
2121
|
+
@"emailVerified" : @(user.emailVerified),
|
|
2122
|
+
@"isAnonymous" : @(user.anonymous),
|
|
2123
|
+
@"metadata" : @{
|
|
2124
|
+
@"creationTime" : user.metadata.creationDate
|
|
2125
|
+
? (id) @(round([user.metadata.creationDate timeIntervalSince1970] * 1000.0))
|
|
2126
|
+
: [NSNull null],
|
|
2127
|
+
@"lastSignInTime" : user.metadata.lastSignInDate
|
|
2128
|
+
? (id) @(round([user.metadata.lastSignInDate timeIntervalSince1970] * 1000.0))
|
|
2129
|
+
: [NSNull null],
|
|
2130
|
+
},
|
|
2131
|
+
keyPhoneNumber : user.phoneNumber ? (id)user.phoneNumber : [NSNull null],
|
|
2132
|
+
keyPhotoUrl : user.photoURL ? (id)[user.photoURL absoluteString] : [NSNull null],
|
|
2133
|
+
@"providerData" : [self convertProviderData:user.providerData],
|
|
2134
|
+
keyProviderId : [user.providerID lowercaseString],
|
|
2135
|
+
@"refreshToken" : user.refreshToken,
|
|
2136
|
+
@"tenantId" : user.tenantID ? (id)user.tenantID : [NSNull null],
|
|
2137
|
+
keyUid : user.uid,
|
|
2138
|
+
#if TARGET_OS_IOS
|
|
2139
|
+
@"multiFactor" :
|
|
2140
|
+
@{@"enrolledFactors" : [self convertMultiFactorData:user.multiFactor.enrolledFactors]}
|
|
2141
|
+
#endif
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
#if TARGET_OS_IOS
|
|
2146
|
+
+ (NSArray<NSMutableDictionary *> *)convertMultiFactorData:(NSArray<FIRMultiFactorInfo *> *)hints {
|
|
2147
|
+
NSMutableArray *enrolledFactors = [NSMutableArray array];
|
|
2148
|
+
|
|
2149
|
+
for (FIRMultiFactorInfo *hint in hints) {
|
|
2150
|
+
NSString *enrollmentTime =
|
|
2151
|
+
[[[NSISO8601DateFormatter alloc] init] stringFromDate:hint.enrollmentDate];
|
|
2152
|
+
|
|
2153
|
+
NSMutableDictionary *factorDict = [@{
|
|
2154
|
+
@"uid" : hint.UID,
|
|
2155
|
+
@"factorId" : hint.factorID,
|
|
2156
|
+
@"displayName" : hint.displayName == nil ? [NSNull null] : hint.displayName,
|
|
2157
|
+
@"enrollmentTime" : enrollmentTime,
|
|
2158
|
+
// @deprecated enrollmentDate kept for backwards compatibility, please use enrollmentTime
|
|
2159
|
+
@"enrollmentDate" : enrollmentTime,
|
|
2160
|
+
} mutableCopy];
|
|
2161
|
+
|
|
2162
|
+
if ([hint isKindOfClass:[FIRPhoneMultiFactorInfo class]]) {
|
|
2163
|
+
FIRPhoneMultiFactorInfo *phoneHint = (FIRPhoneMultiFactorInfo *)hint;
|
|
2164
|
+
factorDict[@"phoneNumber"] = phoneHint.phoneNumber;
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
[enrolledFactors addObject:factorDict];
|
|
2168
|
+
}
|
|
2169
|
+
return enrolledFactors;
|
|
2170
|
+
}
|
|
2171
|
+
#endif
|
|
2172
|
+
|
|
2173
|
+
+ (NSDictionary *)authCredentialToDict:(FIRAuthCredential *)authCredential {
|
|
2174
|
+
[self initializeSharedStateOnce];
|
|
2175
|
+
NSString *authCredentialHash = [NSString stringWithFormat:@"%@", @([authCredential hash])];
|
|
2176
|
+
|
|
2177
|
+
// Temporarily store the non-serializable credential for later
|
|
2178
|
+
credentials[authCredentialHash] = authCredential;
|
|
2179
|
+
|
|
2180
|
+
return @{
|
|
2181
|
+
keyProviderId : authCredential.provider,
|
|
2182
|
+
@"token" : authCredentialHash,
|
|
2183
|
+
@"secret" : [NSNull null],
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
+ (FIRActionCodeSettings *)buildActionCodeSettings:(NSDictionary *)actionCodeSettings {
|
|
2188
|
+
FIRActionCodeSettings *settings = [[FIRActionCodeSettings alloc] init];
|
|
2189
|
+
|
|
2190
|
+
NSString *url = actionCodeSettings[keyUrl];
|
|
2191
|
+
[settings setURL:[NSURL URLWithString:url]];
|
|
2192
|
+
|
|
2193
|
+
if (actionCodeSettings[keyLinkDomain]) {
|
|
2194
|
+
NSString *linkDomain = actionCodeSettings[keyLinkDomain];
|
|
2195
|
+
[settings setLinkDomain:linkDomain];
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
if (actionCodeSettings[keyHandleCodeInApp]) {
|
|
2199
|
+
BOOL handleCodeInApp = [actionCodeSettings[keyHandleCodeInApp] boolValue];
|
|
2200
|
+
[settings setHandleCodeInApp:handleCodeInApp];
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
if (actionCodeSettings[keyAndroid]) {
|
|
2204
|
+
NSDictionary *android = actionCodeSettings[keyAndroid];
|
|
2205
|
+
NSString *packageName = android[keyPackageName];
|
|
2206
|
+
NSString *minimumVersion = android[keyMinVersion];
|
|
2207
|
+
BOOL installApp = [android[keyInstallApp] boolValue];
|
|
2208
|
+
[settings setAndroidPackageName:packageName
|
|
2209
|
+
installIfNotAvailable:installApp
|
|
2210
|
+
minimumVersion:minimumVersion];
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
if (actionCodeSettings[keyIOS]) {
|
|
2214
|
+
NSDictionary *ios = actionCodeSettings[keyIOS];
|
|
2215
|
+
[settings setIOSBundleID:ios[keyBundleId]];
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
return settings;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
@end
|