MainViewController+OOB.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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+OOB.h"
  17. #import "AppManager.h"
  18. #import "MainViewController+Internal.h"
  19. NS_ASSUME_NONNULL_BEGIN
  20. @implementation MainViewController (OOB)
  21. - (StaticContentTableViewSection *)oobSection {
  22. __weak typeof(self) weakSelf = self;
  23. return [StaticContentTableViewSection sectionWithTitle:@"OOB" cells:@[
  24. [StaticContentTableViewCell cellWithTitle:@"Action Type"
  25. value:[self actionCodeRequestTypeString]
  26. action:^{ [weakSelf toggleActionCodeRequestType]; }],
  27. [StaticContentTableViewCell cellWithTitle:@"Continue URL"
  28. value:self.actionCodeContinueURL.absoluteString ?: @"(nil)"
  29. action:^{ [weakSelf changeActionCodeContinueURL]; }],
  30. [StaticContentTableViewCell cellWithTitle:@"Request Verify Email"
  31. action:^{ [weakSelf requestVerifyEmail]; }],
  32. [StaticContentTableViewCell cellWithTitle:@"Request Password Reset"
  33. action:^{ [weakSelf requestPasswordReset]; }],
  34. [StaticContentTableViewCell cellWithTitle:@"Reset Password"
  35. action:^{ [weakSelf resetPassword]; }],
  36. [StaticContentTableViewCell cellWithTitle:@"Check Action Code"
  37. action:^{ [weakSelf checkActionCode]; }],
  38. [StaticContentTableViewCell cellWithTitle:@"Apply Action Code"
  39. action:^{ [weakSelf applyActionCode]; }],
  40. [StaticContentTableViewCell cellWithTitle:@"Verify Password Reset Code"
  41. action:^{ [weakSelf verifyPasswordResetCode]; }],
  42. ]];
  43. }
  44. - (void)toggleActionCodeRequestType {
  45. switch (self.actionCodeRequestType) {
  46. case ActionCodeRequestTypeInApp:
  47. self.actionCodeRequestType = ActionCodeRequestTypeContinue;
  48. break;
  49. case ActionCodeRequestTypeContinue:
  50. self.actionCodeRequestType = ActionCodeRequestTypeEmail;
  51. break;
  52. case ActionCodeRequestTypeEmail:
  53. self.actionCodeRequestType = ActionCodeRequestTypeInApp;
  54. break;
  55. }
  56. [self updateTable];
  57. }
  58. - (NSString *)nameForActionCodeOperation:(FIRActionCodeOperation)operation {
  59. switch (operation) {
  60. case FIRActionCodeOperationVerifyEmail:
  61. return @"Verify Email";
  62. case FIRActionCodeOperationRecoverEmail:
  63. return @"Recover Email";
  64. case FIRActionCodeOperationPasswordReset:
  65. return @"Password Reset";
  66. case FIRActionCodeOperationEmailLink:
  67. return @"Email Sign-In Link";
  68. case FIRActionCodeOperationVerifyAndChangeEmail:
  69. return @"Verify Before Change Email";
  70. case FIRActionCodeOperationRevertSecondFactorAddition:
  71. return @"Revert Second Factor Addition";
  72. case FIRActionCodeOperationUnknown:
  73. return @"Unknown action";
  74. }
  75. }
  76. - (NSString *)actionCodeRequestTypeString {
  77. switch (self.actionCodeRequestType) {
  78. case ActionCodeRequestTypeInApp:
  79. return @"In-App + Continue URL";
  80. case ActionCodeRequestTypeContinue:
  81. return @"Continue URL";
  82. case ActionCodeRequestTypeEmail:
  83. return @"Email Only";
  84. }
  85. }
  86. - (void)changeActionCodeContinueURL {
  87. [self showTextInputPromptWithMessage:@"Continue URL"
  88. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  89. if (userPressedOK) {
  90. self.actionCodeContinueURL = userInput.length ? [NSURL URLWithString:userInput] : nil;
  91. [self updateTable];
  92. }
  93. }];
  94. }
  95. - (void)requestVerifyEmail {
  96. [self showSpinner:^{
  97. void (^sendEmailVerification)(void (^)(NSError *)) = ^(void (^completion)(NSError *)) {
  98. if (self.actionCodeRequestType == ActionCodeRequestTypeEmail) {
  99. [[self user] sendEmailVerificationWithCompletion:completion];
  100. } else {
  101. [[self user] sendEmailVerificationWithActionCodeSettings:[self actionCodeSettings]
  102. completion:completion];
  103. }
  104. };
  105. sendEmailVerification(^(NSError *_Nullable error) {
  106. [self hideSpinner:^{
  107. if (error) {
  108. [self logFailure:@"request verify email failed" error:error];
  109. [self showMessagePrompt:error.localizedDescription];
  110. return;
  111. }
  112. [self logSuccess:@"request verify email succeeded."];
  113. [self showMessagePrompt:@"Sent"];
  114. }];
  115. });
  116. }];
  117. }
  118. - (void)requestPasswordReset {
  119. [self showTextInputPromptWithMessage:@"Email:"
  120. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  121. if (!userPressedOK || !userInput.length) {
  122. return;
  123. }
  124. [self showSpinner:^{
  125. void (^requestPasswordReset)(void (^)(NSError *)) = ^(void (^completion)(NSError *)) {
  126. if (self.actionCodeRequestType == ActionCodeRequestTypeEmail) {
  127. [[AppManager auth] sendPasswordResetWithEmail:userInput completion:completion];
  128. } else {
  129. [[AppManager auth] sendPasswordResetWithEmail:userInput
  130. actionCodeSettings:[self actionCodeSettings]
  131. completion:completion];
  132. }
  133. };
  134. requestPasswordReset(^(NSError *_Nullable error) {
  135. [self hideSpinner:^{
  136. if (error) {
  137. [self logFailure:@"request password reset failed" error:error];
  138. [self showMessagePrompt:error.localizedDescription];
  139. return;
  140. }
  141. [self logSuccess:@"request password reset succeeded."];
  142. [self showMessagePrompt:@"Sent"];
  143. }];
  144. });
  145. }];
  146. }];
  147. }
  148. - (void)resetPassword {
  149. [self showTextInputPromptWithMessage:@"OOB Code:"
  150. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  151. if (!userPressedOK || !userInput.length) {
  152. return;
  153. }
  154. NSString *code = userInput;
  155. [self showTextInputPromptWithMessage:@"New Password:"
  156. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  157. if (!userPressedOK || !userInput.length) {
  158. return;
  159. }
  160. [self showSpinner:^{
  161. [[AppManager auth] confirmPasswordResetWithCode:code
  162. newPassword:userInput
  163. completion:^(NSError *_Nullable error) {
  164. [self hideSpinner:^{
  165. if (error) {
  166. [self logFailure:@"Password reset failed" error:error];
  167. [self showMessagePrompt:error.localizedDescription];
  168. return;
  169. }
  170. [self logSuccess:@"Password reset succeeded."];
  171. [self showMessagePrompt:@"Password reset succeeded."];
  172. }];
  173. }];
  174. }];
  175. }];
  176. }];
  177. }
  178. - (void)checkActionCode {
  179. [self showTextInputPromptWithMessage:@"OOB Code:"
  180. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  181. if (!userPressedOK || !userInput.length) {
  182. return;
  183. }
  184. [self showSpinner:^{
  185. [[AppManager auth] checkActionCode:userInput completion:^(FIRActionCodeInfo *_Nullable info,
  186. NSError *_Nullable error) {
  187. [self hideSpinner:^{
  188. if (error) {
  189. [self logFailure:@"Check action code failed" error:error];
  190. [self showMessagePrompt:error.localizedDescription];
  191. return;
  192. }
  193. [self logSuccess:@"Check action code succeeded."];
  194. NSString *email = info.email;
  195. NSString *previousEmail = info.previousEmail;
  196. NSString *message =
  197. previousEmail ? [NSString stringWithFormat:@"%@ -> %@", previousEmail, email] : email;
  198. NSString *operation = [self nameForActionCodeOperation:info.operation];
  199. [self showMessagePromptWithTitle:operation
  200. message:message
  201. showCancelButton:NO
  202. completion:nil];
  203. }];
  204. }];
  205. }];
  206. }];
  207. }
  208. - (void)applyActionCode {
  209. [self showTextInputPromptWithMessage:@"OOB Code:"
  210. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  211. if (!userPressedOK || !userInput.length) {
  212. return;
  213. }
  214. [self showSpinner:^{
  215. [[AppManager auth] applyActionCode:userInput completion:^(NSError *_Nullable error) {
  216. [self hideSpinner:^{
  217. if (error) {
  218. [self logFailure:@"Apply action code failed" error:error];
  219. [self showMessagePrompt:error.localizedDescription];
  220. return;
  221. }
  222. [self logSuccess:@"Apply action code succeeded."];
  223. [self showMessagePrompt:@"Action code was properly applied."];
  224. }];
  225. }];
  226. }];
  227. }];
  228. }
  229. - (void)verifyPasswordResetCode {
  230. [self showTextInputPromptWithMessage:@"OOB Code:"
  231. completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) {
  232. if (!userPressedOK || !userInput.length) {
  233. return;
  234. }
  235. [self showSpinner:^{
  236. [[AppManager auth] verifyPasswordResetCode:userInput completion:^(NSString *_Nullable email,
  237. NSError *_Nullable error) {
  238. [self hideSpinner:^{
  239. if (error) {
  240. [self logFailure:@"Verify password reset code failed" error:error];
  241. [self showMessagePrompt:error.localizedDescription];
  242. return;
  243. }
  244. [self logSuccess:@"Verify password resest code succeeded."];
  245. NSString *alertMessage =
  246. [[NSString alloc] initWithFormat:@"Code verified for email: %@", email];
  247. [self showMessagePrompt:alertMessage];
  248. }];
  249. }];
  250. }];
  251. }];
  252. }
  253. @end
  254. NS_ASSUME_NONNULL_END