MainViewController+MultiFactor.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright 2019 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file 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. #import "MainViewController+MultiFactor.h"
  17. #import "FirebaseAuth/Sources/Auth/FIRAuth_Internal.h"
  18. #import "FirebaseAuth/Sources/User/FIRUser_Internal.h"
  19. #import <FirebaseAuth/FIRMultiFactorInfo.h>
  20. #import <FirebaseAuth/FIRPhoneAuthProvider.h>
  21. #import <FirebaseAuth/FIRTOTPMultiFactorGenerator.h>
  22. #import <FirebaseAuth/FIRTOTPMultiFactorAssertion.h>
  23. #import "MainViewController+Internal.h"
  24. #import <FirebaseCore/FIRApp.h>
  25. NS_ASSUME_NONNULL_BEGIN
  26. @implementation MainViewController (MultiFactor)
  27. - (StaticContentTableViewSection *)multiFactorSection {
  28. __weak typeof(self) weakSelf = self;
  29. return [StaticContentTableViewSection sectionWithTitle:@"Multi Factor" cells:@[
  30. [StaticContentTableViewCell cellWithTitle:@"Phone Enroll"
  31. action:^{ [weakSelf phoneEnroll]; }],
  32. [StaticContentTableViewCell cellWithTitle:@"TOTP Enroll"
  33. action:^{ [weakSelf TOTPEnroll]; }],
  34. [StaticContentTableViewCell cellWithTitle:@"MultiFactor Unenroll"
  35. action:^{ [weakSelf mfaUnenroll]; }],
  36. ]];
  37. }
  38. - (void)phoneEnroll {
  39. FIRUser *user = FIRAuth.auth.currentUser;
  40. if (!user) {
  41. [self logFailure:@"Please sign in first." error:nil];
  42. return;
  43. }
  44. [self showTextInputPromptWithMessage:@"Phone Number"
  45. completionBlock:^(BOOL userPressedOK, NSString *_Nullable phoneNumber) {
  46. [user.multiFactor
  47. getSessionWithCompletion:^(FIRMultiFactorSession *_Nullable session, NSError *_Nullable error) {
  48. // this is the step verfication code has been send to the phone number along with validating the number
  49. [FIRPhoneAuthProvider.provider verifyPhoneNumber:phoneNumber
  50. UIDelegate:nil
  51. multiFactorSession:session
  52. completion:^(NSString * _Nullable verificationID,
  53. NSError * _Nullable error) {
  54. if (error) {
  55. [self logFailure:@"Multi factor start enroll failed." error:error];
  56. } else {
  57. [self showTextInputPromptWithMessage:@"Verification code"
  58. completionBlock:^(BOOL userPressedOK,
  59. NSString *_Nullable verificationCode) {
  60. FIRPhoneAuthCredential *credential =
  61. [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
  62. verificationCode:verificationCode];
  63. FIRMultiFactorAssertion *assertion =
  64. [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
  65. [self showTextInputPromptWithMessage:@"Display name"
  66. completionBlock:^(BOOL userPressedOK,
  67. NSString *_Nullable displayName) {
  68. [user.multiFactor enrollWithAssertion:assertion
  69. displayName:displayName
  70. completion:^(NSError *_Nullable error) {
  71. if (error) {
  72. [self logFailure:@"Multi factor finalize enroll failed." error:error];
  73. } else {
  74. [self logSuccess:@"Multi factor finalize enroll succeeded."];
  75. }
  76. }];
  77. }];
  78. }];
  79. }
  80. }];
  81. }];
  82. }];
  83. }
  84. - (void)TOTPEnroll {
  85. FIRUser *user = FIRAuth.auth.currentUser;
  86. if (!user) {
  87. [self logFailure:@"Please sign in first." error:nil];
  88. return;
  89. }
  90. [user.multiFactor getSessionWithCompletion:^(FIRMultiFactorSession *_Nullable session, NSError *_Nullable error) {
  91. if (error) {
  92. [self logFailure:@"Error getting multi-factor session." error:error];
  93. return;
  94. }
  95. [FIRTOTPMultiFactorGenerator generateSecretWithMultiFactorSession:session completion:^(FIRTOTPSecret *_Nullable secret, NSError *_Nullable error) {
  96. if (error) {
  97. [self logFailure:@"Error generating TOTP secret." error:error];
  98. return;
  99. }
  100. NSString *accountName = user.email;
  101. NSString *issuer = FIRAuth.auth.app.name;
  102. dispatch_async(dispatch_get_main_queue(), ^{
  103. NSString *url = [secret generateQRCodeURLWithAccountName:accountName issuer:issuer];
  104. if(!url.length) {
  105. [self logFailure: @"Multi factor finalize enroll failed. Could not generate url." error:nil];
  106. return;
  107. }
  108. [secret openInOTPAppWithQRCodeURL:url];
  109. [self showQRCodePromptWithTextInput:@"Scan this QR Code and enter OTP:"
  110. qrCodeString:url
  111. completionBlock:^(BOOL userPressedOK, NSString *_Nullable oneTimePassword) {
  112. FIRTOTPMultiFactorAssertion *assertion = [FIRTOTPMultiFactorGenerator assertionForEnrollmentWithSecret:secret oneTimePassword:oneTimePassword];
  113. [self showTextInputPromptWithMessage:@"Display name"
  114. completionBlock:^(BOOL userPressedOK,
  115. NSString *_Nullable displayName) {
  116. [user.multiFactor enrollWithAssertion:assertion
  117. displayName:displayName
  118. completion:^(NSError *_Nullable error) {
  119. if (error) {
  120. [self logFailure:@"Multi factor finalize enroll failed." error:error];
  121. } else {
  122. [self logSuccess:@"Multi factor finalize enroll succeeded."];
  123. }
  124. }];
  125. }];
  126. }];
  127. });
  128. }];
  129. }];
  130. }
  131. - (void)mfaUnenroll {
  132. NSMutableString *displayNameString = [NSMutableString string];
  133. for (FIRMultiFactorInfo *tmpFactorInfo in FIRAuth.auth.currentUser.multiFactor.enrolledFactors) {
  134. [displayNameString appendString:tmpFactorInfo.displayName];
  135. [displayNameString appendString:@" "];
  136. }
  137. [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Enter multi factor to unenroll\n%@", displayNameString]
  138. completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
  139. FIRMultiFactorInfo *factorInfo;
  140. for (FIRMultiFactorInfo *tmpFactorInfo in FIRAuth.auth.currentUser.multiFactor.enrolledFactors) {
  141. if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
  142. factorInfo = tmpFactorInfo;
  143. }
  144. }
  145. [FIRAuth.auth.currentUser.multiFactor unenrollWithInfo:factorInfo
  146. completion:^(NSError * _Nullable error) {
  147. if (error) {
  148. [self logFailure:@"Multi factor unenroll failed." error:error];
  149. } else {
  150. [self logSuccess:@"Multi factor unenroll succeeded."];
  151. }
  152. }];
  153. }];
  154. }
  155. @end
  156. NS_ASSUME_NONNULL_END