Skip to content

Commit

Permalink
Support multi-factor authentication with email link sign in (#8705)
Browse files Browse the repository at this point in the history
* Support multi-factor authentication for email link sign in.

* Ran scripts/style.sh

* Add documentation
  • Loading branch information
0x0c authored Sep 29, 2021
1 parent 36dc8a5 commit 706f939
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 6 deletions.
28 changes: 22 additions & 6 deletions FirebaseAuth/Sources/Backend/FIRAuthBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -805,15 +805,31 @@ - (void)verifyPassword:(FIRVerifyPasswordRequest *)request
- (void)emailLinkSignin:(FIREmailLinkSignInRequest *)request
callback:(FIREmailLinkSigninResponseCallback)callback {
FIREmailLinkSignInResponse *response = [[FIREmailLinkSignInResponse alloc] init];
[self postWithRequest:request
response:response
callback:^(NSError *error) {
if (error) {
callback(nil, error);
[self
postWithRequest:request
response:response
callback:^(NSError *error) {
if (error) {
callback(nil, error);
} else {
if (!response.IDToken && response.MFAInfo) {
#if TARGET_OS_IOS
NSMutableArray<FIRMultiFactorInfo *> *multiFactorInfo = [NSMutableArray array];
for (FIRAuthProtoMFAEnrollment *MFAEnrollment in response.MFAInfo) {
FIRPhoneMultiFactorInfo *info =
[[FIRPhoneMultiFactorInfo alloc] initWithProto:MFAEnrollment];
[multiFactorInfo addObject:info];
}
NSError *multiFactorRequiredError = [FIRAuthErrorUtils
secondFactorRequiredErrorWithPendingCredential:response.MFAPendingCredential
hints:multiFactorInfo];
callback(nil, multiFactorRequiredError);
#endif
} else {
callback(response, nil);
}
}];
}
}];
}

- (void)secureToken:(FIRSecureTokenRequest *)request
Expand Down
17 changes: 17 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIREmailLinkSignInResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import <Foundation/Foundation.h>

#import "FirebaseAuth/Sources/Backend/FIRAuthRPCResponse.h"
#import "FirebaseAuth/Sources/Backend/RPC/Proto/FIRAuthProtoMFAEnrollment.h"

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -39,6 +40,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic, strong, readonly, nullable) NSString *refreshToken;

/** @property localID
@brief The Firebase Auth user ID.
*/
@property(nonatomic, strong, readonly, nullable) NSString *localID;

/** @property approximateExpirationDate
@brief The approximate expiration date of the access token.
*/
Expand All @@ -49,6 +55,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic, assign) BOOL isNewUser;

/** @property MFAPendingCredential
@brief An opaque string that functions as proof that the user has successfully passed the first
factor check.
*/
@property(nonatomic, strong, readonly, nullable) NSString *MFAPendingCredential;

/** @property MFAInfo
@brief Info on which multi-factor authentication providers are enabled.
*/
@property(nonatomic, strong, readonly, nullable) NSArray<FIRAuthProtoMFAEnrollment *> *MFAInfo;

@end

NS_ASSUME_NONNULL_END
13 changes: 13 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIREmailLinkSignInResponse.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
@implementation FIREmailLinkSignInResponse

- (BOOL)setWithDictionary:(NSDictionary *)dictionary error:(NSError *_Nullable *_Nullable)error {
_localID = [dictionary[@"localId"] copy];
_email = [dictionary[@"email"] copy];
_IDToken = [dictionary[@"idToken"] copy];
_isNewUser = [dictionary[@"isNewUser"] boolValue];
Expand All @@ -29,6 +30,18 @@ - (BOOL)setWithDictionary:(NSDictionary *)dictionary error:(NSError *_Nullable *
[dictionary[@"expiresIn"] isKindOfClass:[NSString class]]
? [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]]
: nil;
if (dictionary[@"mfaInfo"] != nil) {
NSMutableArray<FIRAuthProtoMFAEnrollment *> *MFAInfo = [NSMutableArray array];
NSArray *MFAInfoDataArray = dictionary[@"mfaInfo"];
for (NSDictionary *MFAInfoData in MFAInfoDataArray) {
FIRAuthProtoMFAEnrollment *MFAEnrollment =
[[FIRAuthProtoMFAEnrollment alloc] initWithDictionary:MFAInfoData];
[MFAInfo addObject:MFAEnrollment];
}
_MFAInfo = MFAInfo;
}
_MFAPendingCredential = [dictionary[@"mfaPendingCredential"] copy];

return YES;
}

Expand Down
7 changes: 7 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRVerifyAssertionResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic, copy, nullable) NSString *pendingToken;

/** @property MFAPendingCredential
@brief An opaque string that functions as proof that the user has successfully passed the first
factor check.
*/
@property(nonatomic, strong, readonly, nullable) NSString *MFAPendingCredential;

/** @property MFAInfo
@brief Info on which multi-factor authentication providers are enabled.
*/
@property(nonatomic, strong, readonly, nullable) NSArray<FIRAuthProtoMFAEnrollment *> *MFAInfo;

@end
Expand Down
7 changes: 7 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRVerifyPasswordResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic, strong, readonly, nullable) NSURL *photoURL;

/** @property MFAPendingCredential
@brief An opaque string that functions as proof that the user has successfully passed the first
factor check.
*/
@property(nonatomic, strong, readonly, nullable) NSString *MFAPendingCredential;

/** @property MFAInfo
@brief Info on which multi-factor authentication providers are enabled.
*/
@property(nonatomic, strong, readonly, nullable) NSArray<FIRAuthProtoMFAEnrollment *> *MFAInfo;

@end
Expand Down

0 comments on commit 706f939

Please sign in to comment.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy