FIRGetOOBConfirmationCodeResponseTests.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. * Copyright 2017 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 <XCTest/XCTest.h>
  17. #import "FIRActionCodeSettings.h"
  18. #import "FIRAuthErrors.h"
  19. #import "FIRAuthBackend.h"
  20. #import "FIRGetOOBConfirmationCodeRequest.h"
  21. #import "FIRGetOOBConfirmationCodeResponse.h"
  22. #import "FIRFakeBackendRPCIssuer.h"
  23. /** @var kTestEmail
  24. @brief Testing user email adadress.
  25. */
  26. static NSString *const kTestEmail = @"test@gmail.com";
  27. /** @var kTestAccessToken
  28. @brief Testing access token.
  29. */
  30. static NSString *const kTestAccessToken = @"ACCESS_TOKEN";
  31. /** @var kTestAPIKey
  32. @brief Fake API key used for testing.
  33. */
  34. static NSString *const kTestAPIKey = @"APIKey";
  35. /** @var kOOBCodeKey
  36. @brief The name of the field in the response JSON for the OOB code.
  37. */
  38. static NSString *const kOOBCodeKey = @"oobCode";
  39. /** @var kTestOOBCode
  40. @brief Fake OOB Code used for testing.
  41. */
  42. static NSString *const kTestOOBCode = @"OOBCode";
  43. /** @var kEmailNotFoundMessage
  44. @brief The value of the "message" field returned for an "email not found" error.
  45. */
  46. static NSString *const kEmailNotFoundMessage = @"EMAIL_NOT_FOUND: fake custom message";
  47. /** @var kInvalidEmailErrorMessage
  48. @brief The error returned by the server if the email is invalid.
  49. */
  50. static NSString *const kInvalidEmailErrorMessage = @"INVALID_EMAIL:";
  51. /** @var kInvalidMessagePayloadErrorMessage
  52. @brief This is the prefix for the error message the server responds with if an invalid message
  53. payload was sent.
  54. */
  55. static NSString *const kInvalidMessagePayloadErrorMessage = @"INVALID_MESSAGE_PAYLOAD";
  56. /** @var kInvalidSenderErrorMessage
  57. @brief This is the prefix for the error message the server responds with if invalid sender is
  58. used to send the email for updating user's email address.
  59. */
  60. static NSString *const kInvalidSenderErrorMessage = @"INVALID_SENDER";
  61. /** @var kMissingIosBundleIDErrorMessage
  62. @brief This is the error message the server will respond with if iOS bundle ID is missing but
  63. the iOS App store ID is provided.
  64. */
  65. static NSString *const kMissingIosBundleIDErrorMessage = @"MISSING_IOS_BUNDLE_ID";
  66. /** @var kMissingAndroidPackageNameErrorMessage
  67. @brief This is the error message the server will respond with if Android Package Name is missing
  68. but the flag indicating the app should be installed is set to true.
  69. */
  70. static NSString *const kMissingAndroidPackageNameErrorMessage = @"MISSING_ANDROID_PACKAGE_NAME";
  71. /** @var kUnauthorizedDomainErrorMessage
  72. @brief This is the error message the server will respond with if the domain of the continue URL
  73. specified is not whitelisted in the firebase console.
  74. */
  75. static NSString *const kUnauthorizedDomainErrorMessage = @"UNAUTHORIZED_DOMAIN";
  76. /** @var kInvalidRecipientEmailErrorMessage
  77. @brief This is the prefix for the error message the server responds with if the recipient email
  78. is invalid.
  79. */
  80. static NSString *const kInvalidRecipientEmailErrorMessage = @"INVALID_RECIPIENT_EMAIL";
  81. /** @var kInvalidContinueURIErrorMessage
  82. @brief This is the error returned by the backend if the continue URL provided in the request
  83. is invalid.
  84. */
  85. static NSString *const kInvalidContinueURIErrorMessage = @"INVALID_CONTINUE_URI";
  86. /** @var kMissingContinueURIErrorMessage
  87. @brief This is the error message the server will respond with if there was no continue URI
  88. present in a request that required one.
  89. */
  90. static NSString *const kMissingContinueURIErrorMessage = @"MISSING_CONTINUE_URI";
  91. /** @var kIosBundleID
  92. @brief Fake iOS bundle ID for testing.
  93. */
  94. static NSString *const kIosBundleID = @"testBundleID";
  95. /** @class FIRGetOOBConfirmationCodeResponseTests
  96. @brief Tests for @c FIRGetOOBConfirmationCodeResponse.
  97. */
  98. @interface FIRGetOOBConfirmationCodeResponseTests : XCTestCase
  99. @end
  100. @implementation FIRGetOOBConfirmationCodeResponseTests {
  101. /** @var _RPCIssuer
  102. @brief This backend RPC issuer is used to fake network responses for each test in the suite.
  103. In the @c setUp method we initialize this and set @c FIRAuthBackend's RPC issuer to it.
  104. */
  105. FIRFakeBackendRPCIssuer *_RPCIssuer;
  106. /** @var _requestConfiguration
  107. @brief This is the request configuration used for testing.
  108. */
  109. FIRAuthRequestConfiguration *_requestConfiguration;
  110. }
  111. - (void)setUp {
  112. [super setUp];
  113. FIRFakeBackendRPCIssuer *RPCIssuer = [[FIRFakeBackendRPCIssuer alloc] init];
  114. [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:RPCIssuer];
  115. _RPCIssuer = RPCIssuer;
  116. _requestConfiguration = [[FIRAuthRequestConfiguration alloc] initWithAPIKey:kTestAPIKey];
  117. }
  118. - (void)tearDown {
  119. _requestConfiguration = nil;
  120. _RPCIssuer = nil;
  121. [FIRAuthBackend setDefaultBackendImplementationWithRPCIssuer:nil];
  122. [super tearDown];
  123. }
  124. /** @fn testSuccessfulPasswordResetResponse
  125. @brief This test simulates a complete password reset response (with OOB Code) and makes sure
  126. it succeeds, and we get the OOB Code decoded correctly.
  127. */
  128. - (void)testSuccessfulPasswordResetResponse {
  129. FIRGetOOBConfirmationCodeRequest *request =
  130. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  131. actionCodeSettings:[self fakeActionCodeSettings]
  132. requestConfiguration:_requestConfiguration];
  133. __block BOOL callbackInvoked;
  134. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  135. __block NSError *RPCError;
  136. [FIRAuthBackend getOOBConfirmationCode:request
  137. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  138. NSError *_Nullable error) {
  139. callbackInvoked = YES;
  140. RPCResponse = response;
  141. RPCError = error;
  142. }];
  143. [_RPCIssuer respondWithJSON:@{
  144. kOOBCodeKey : kTestOOBCode
  145. }];
  146. XCTAssert(callbackInvoked);
  147. XCTAssertNil(RPCError);
  148. XCTAssertNotNil(RPCResponse);
  149. XCTAssertEqualObjects(RPCResponse.OOBCode, kTestOOBCode);
  150. }
  151. /** @fn testSuccessfulPasswordResetResponseWithoutOOBCode
  152. @brief This test simulates a password reset request where we don't receive the optional OOBCode
  153. response value. It should still succeed.
  154. */
  155. - (void)testSuccessfulPasswordResetResponseWithoutOOBCode {
  156. FIRGetOOBConfirmationCodeRequest *request =
  157. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  158. actionCodeSettings:[self fakeActionCodeSettings]
  159. requestConfiguration:_requestConfiguration];
  160. __block BOOL callbackInvoked;
  161. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  162. __block NSError *RPCError;
  163. [FIRAuthBackend getOOBConfirmationCode:request
  164. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  165. NSError *_Nullable error) {
  166. callbackInvoked = YES;
  167. RPCResponse = response;
  168. RPCError = error;
  169. }];
  170. [_RPCIssuer respondWithJSON:@{}];
  171. XCTAssert(callbackInvoked);
  172. XCTAssertNil(RPCError);
  173. XCTAssertNotNil(RPCResponse);
  174. XCTAssertNil(RPCResponse.OOBCode);
  175. }
  176. /** @fn testEmailNotFoundError
  177. @brief This test checks for email not found responses, and makes sure they are decoded to the
  178. correct error response.
  179. */
  180. - (void)testEmailNotFoundError {
  181. FIRGetOOBConfirmationCodeRequest *request =
  182. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  183. actionCodeSettings:[self fakeActionCodeSettings]
  184. requestConfiguration:_requestConfiguration];
  185. __block BOOL callbackInvoked;
  186. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  187. __block NSError *RPCError;
  188. [FIRAuthBackend getOOBConfirmationCode:request
  189. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  190. NSError *_Nullable error) {
  191. callbackInvoked = YES;
  192. RPCResponse = response;
  193. RPCError = error;
  194. }];
  195. [_RPCIssuer respondWithServerErrorMessage:kEmailNotFoundMessage];
  196. XCTAssert(callbackInvoked);
  197. XCTAssertNotNil(RPCError);
  198. XCTAssertEqualObjects(RPCError.domain, FIRAuthErrorDomain);
  199. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeUserNotFound);
  200. XCTAssertNil(RPCResponse);
  201. }
  202. /** @fn testInvalidEmailError
  203. @brief This test checks for the INVALID_EMAIL error message from the backend.
  204. */
  205. - (void)testInvalidEmailError {
  206. FIRGetOOBConfirmationCodeRequest *request =
  207. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  208. actionCodeSettings:[self fakeActionCodeSettings]
  209. requestConfiguration:_requestConfiguration];
  210. __block BOOL callbackInvoked;
  211. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  212. __block NSError *RPCError;
  213. [FIRAuthBackend getOOBConfirmationCode:request
  214. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  215. NSError *_Nullable error) {
  216. callbackInvoked = YES;
  217. RPCResponse = response;
  218. RPCError = error;
  219. }];
  220. [_RPCIssuer respondWithServerErrorMessage:kInvalidEmailErrorMessage];
  221. XCTAssert(callbackInvoked);
  222. XCTAssertNotNil(RPCError);
  223. XCTAssertEqualObjects(RPCError.domain, FIRAuthErrorDomain);
  224. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidEmail);
  225. XCTAssertNil(RPCResponse);
  226. }
  227. /** @fn testInvalidMessagePayloadError
  228. @brief Tests for @c FIRAuthErrorCodeInvalidMessagePayload.
  229. */
  230. - (void)testInvalidMessagePayloadError {
  231. FIRGetOOBConfirmationCodeRequest *request =
  232. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  233. actionCodeSettings:[self fakeActionCodeSettings]
  234. requestConfiguration:_requestConfiguration];
  235. __block BOOL callbackInvoked;
  236. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  237. __block NSError *RPCError;
  238. [FIRAuthBackend getOOBConfirmationCode:request
  239. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  240. NSError *_Nullable error) {
  241. callbackInvoked = YES;
  242. RPCResponse = response;
  243. RPCError = error;
  244. }];
  245. [_RPCIssuer respondWithServerErrorMessage:kInvalidMessagePayloadErrorMessage];
  246. XCTAssert(callbackInvoked);
  247. XCTAssertNil(RPCResponse);
  248. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidMessagePayload);
  249. }
  250. /** @fn testInvalidSenderError
  251. @brief Tests for @c FIRAuthErrorCodeInvalidSender.
  252. */
  253. - (void)testInvalidSenderError {
  254. FIRGetOOBConfirmationCodeRequest *request =
  255. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  256. actionCodeSettings:[self fakeActionCodeSettings]
  257. requestConfiguration:_requestConfiguration];
  258. __block BOOL callbackInvoked;
  259. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  260. __block NSError *RPCError;
  261. [FIRAuthBackend getOOBConfirmationCode:request
  262. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  263. NSError *_Nullable error) {
  264. callbackInvoked = YES;
  265. RPCResponse = response;
  266. RPCError = error;
  267. }];
  268. [_RPCIssuer respondWithServerErrorMessage:kInvalidSenderErrorMessage];
  269. XCTAssert(callbackInvoked);
  270. XCTAssertNil(RPCResponse);
  271. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidSender);
  272. }
  273. /** @fn testMissingIosBundleIDError
  274. @brief Tests for @c FIRAuthErrorCodeMissingIosBundleID.
  275. */
  276. - (void)testMissingIosBundleIDError {
  277. FIRGetOOBConfirmationCodeRequest *request =
  278. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  279. actionCodeSettings:[self fakeActionCodeSettings]
  280. requestConfiguration:_requestConfiguration];
  281. __block BOOL callbackInvoked;
  282. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  283. __block NSError *RPCError;
  284. [FIRAuthBackend getOOBConfirmationCode:request
  285. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  286. NSError *_Nullable error) {
  287. callbackInvoked = YES;
  288. RPCResponse = response;
  289. RPCError = error;
  290. }];
  291. [_RPCIssuer respondWithServerErrorMessage:kMissingIosBundleIDErrorMessage];
  292. XCTAssert(callbackInvoked);
  293. XCTAssertNil(RPCResponse);
  294. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingIosBundleID);
  295. }
  296. /** @fn testMissingAndroidPackageNameError
  297. @brief Tests for @c FIRAuthErrorCodeMissingAndroidPackageName.
  298. */
  299. - (void)testMissingAndroidPackageNameError {
  300. FIRGetOOBConfirmationCodeRequest *request =
  301. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  302. actionCodeSettings:[self fakeActionCodeSettings]
  303. requestConfiguration:_requestConfiguration];
  304. __block BOOL callbackInvoked;
  305. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  306. __block NSError *RPCError;
  307. [FIRAuthBackend getOOBConfirmationCode:request
  308. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  309. NSError *_Nullable error) {
  310. callbackInvoked = YES;
  311. RPCResponse = response;
  312. RPCError = error;
  313. }];
  314. [_RPCIssuer respondWithServerErrorMessage:kMissingAndroidPackageNameErrorMessage];
  315. XCTAssert(callbackInvoked);
  316. XCTAssertNil(RPCResponse);
  317. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingAndroidPackageName);
  318. }
  319. /** @fn testUnauthorizedDomainError
  320. @brief Tests for @c FIRAuthErrorCodeUnauthorizedDomain.
  321. */
  322. - (void)testUnauthorizedDomainError {
  323. FIRGetOOBConfirmationCodeRequest *request =
  324. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  325. actionCodeSettings:[self fakeActionCodeSettings]
  326. requestConfiguration:_requestConfiguration];
  327. __block BOOL callbackInvoked;
  328. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  329. __block NSError *RPCError;
  330. [FIRAuthBackend getOOBConfirmationCode:request
  331. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  332. NSError *_Nullable error) {
  333. callbackInvoked = YES;
  334. RPCResponse = response;
  335. RPCError = error;
  336. }];
  337. [_RPCIssuer respondWithServerErrorMessage:kUnauthorizedDomainErrorMessage];
  338. XCTAssert(callbackInvoked);
  339. XCTAssertNil(RPCResponse);
  340. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeUnauthorizedDomain);
  341. }
  342. /** @fn testInvalidContinueURIError
  343. @brief Tests for @c FIRAuthErrorCodeInvalidContinueAuthURI.
  344. */
  345. - (void)testInvalidContinueURIError {
  346. FIRGetOOBConfirmationCodeRequest *request =
  347. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  348. actionCodeSettings:[self fakeActionCodeSettings]
  349. requestConfiguration:_requestConfiguration];
  350. __block BOOL callbackInvoked;
  351. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  352. __block NSError *RPCError;
  353. [FIRAuthBackend getOOBConfirmationCode:request
  354. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  355. NSError *_Nullable error) {
  356. callbackInvoked = YES;
  357. RPCResponse = response;
  358. RPCError = error;
  359. }];
  360. [_RPCIssuer respondWithServerErrorMessage:kInvalidContinueURIErrorMessage];
  361. XCTAssert(callbackInvoked);
  362. XCTAssertNil(RPCResponse);
  363. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidContinueURI);
  364. }
  365. /** @fn testMissingContinueURIError
  366. @brief Tests for @c FIRAuthErrorCodeMissingContinueURI.
  367. */
  368. - (void)testMissingContinueURIError {
  369. FIRGetOOBConfirmationCodeRequest *request =
  370. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  371. actionCodeSettings:[self fakeActionCodeSettings]
  372. requestConfiguration:_requestConfiguration];
  373. __block BOOL callbackInvoked;
  374. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  375. __block NSError *RPCError;
  376. [FIRAuthBackend getOOBConfirmationCode:request
  377. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  378. NSError *_Nullable error) {
  379. callbackInvoked = YES;
  380. RPCResponse = response;
  381. RPCError = error;
  382. }];
  383. [_RPCIssuer respondWithServerErrorMessage:kMissingContinueURIErrorMessage];
  384. XCTAssert(callbackInvoked);
  385. XCTAssertNil(RPCResponse);
  386. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeMissingContinueURI);
  387. }
  388. /** @fn testInvalidRecipientEmailError
  389. @brief Tests for @c FIRAuthErrorCodeInvalidRecipientEmail.
  390. */
  391. - (void)testInvalidRecipientEmailError {
  392. FIRGetOOBConfirmationCodeRequest *request =
  393. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  394. actionCodeSettings:[self fakeActionCodeSettings]
  395. requestConfiguration:_requestConfiguration];
  396. __block BOOL callbackInvoked;
  397. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  398. __block NSError *RPCError;
  399. [FIRAuthBackend getOOBConfirmationCode:request
  400. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  401. NSError *_Nullable error) {
  402. callbackInvoked = YES;
  403. RPCResponse = response;
  404. RPCError = error;
  405. }];
  406. [_RPCIssuer respondWithServerErrorMessage:kInvalidRecipientEmailErrorMessage];
  407. XCTAssert(callbackInvoked);
  408. XCTAssertNil(RPCResponse);
  409. XCTAssertEqual(RPCError.code, FIRAuthErrorCodeInvalidRecipientEmail);
  410. }
  411. /** @fn testSuccessfulEmailVerificationResponse
  412. @brief This test is really not much different than the original test for password reset. But
  413. it's here for completeness sake.
  414. */
  415. - (void)testSuccessfulEmailVerificationResponse {
  416. FIRGetOOBConfirmationCodeRequest *request =
  417. [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:kTestEmail
  418. actionCodeSettings:[self fakeActionCodeSettings]
  419. requestConfiguration:_requestConfiguration];
  420. __block BOOL callbackInvoked;
  421. __block FIRGetOOBConfirmationCodeResponse *RPCResponse;
  422. __block NSError *RPCError;
  423. [FIRAuthBackend getOOBConfirmationCode:request
  424. callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response,
  425. NSError *_Nullable error) {
  426. callbackInvoked = YES;
  427. RPCResponse = response;
  428. RPCError = error;
  429. }];
  430. [_RPCIssuer respondWithJSON:@{
  431. kOOBCodeKey : kTestOOBCode
  432. }];
  433. XCTAssert(callbackInvoked);
  434. XCTAssertNil(RPCError);
  435. XCTAssertNotNil(RPCResponse);
  436. XCTAssertEqualObjects(RPCResponse.OOBCode, kTestOOBCode);
  437. }
  438. #pragma mark - Helpers
  439. /** @fn fakeActionCodeSettings
  440. @brief Constructs and returns a fake instance of @c FIRActionCodeSettings for testing.
  441. @return An instance of @c FIRActionCodeSettings for testing.
  442. */
  443. - (FIRActionCodeSettings *)fakeActionCodeSettings {
  444. FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
  445. [actionCodeSettings setIOSBundleID:kIosBundleID];
  446. return actionCodeSettings;
  447. }
  448. @end