FIRRecaptchaBridge.m 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2024 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import <TargetConditionals.h>
  15. #if TARGET_OS_IOS
  16. #import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRRecaptchaBridge.h"
  17. #import "RecaptchaInterop/RecaptchaInterop.h"
  18. // This is thread safe since it is only called by the AuthRecaptchaVerifier singleton.
  19. static id<RCARecaptchaClientProtocol> recaptchaClient;
  20. static void retrieveToken(NSString *actionString,
  21. NSString *fakeToken,
  22. FIRAuthRecaptchaTokenCallback callback) {
  23. Class RecaptchaActionClass = NSClassFromString(@"RecaptchaAction");
  24. SEL customActionSelector = NSSelectorFromString(@"initWithCustomAction:");
  25. if (RecaptchaActionClass &&
  26. [RecaptchaActionClass instancesRespondToSelector:customActionSelector]) {
  27. // Initialize with a custom action
  28. id (*funcWithCustomAction)(id, SEL, NSString *) = (id(*)(
  29. id, SEL, NSString *))[RecaptchaActionClass instanceMethodForSelector:customActionSelector];
  30. id<RCAActionProtocol> customAction = funcWithCustomAction([[RecaptchaActionClass alloc] init],
  31. customActionSelector, actionString);
  32. if (customAction) {
  33. [recaptchaClient execute:customAction
  34. completion:^(NSString *_Nullable token, NSError *_Nullable error) {
  35. if (!error) {
  36. callback(token, nil, YES, YES);
  37. return;
  38. } else {
  39. callback(fakeToken, nil, YES, YES);
  40. }
  41. }];
  42. } else {
  43. // RecaptchaAction class creation failed.
  44. callback(@"", nil, YES, NO);
  45. }
  46. } else {
  47. // RecaptchaEnterprise not linked.
  48. callback(@"", nil, NO, NO);
  49. }
  50. }
  51. void FIRRecaptchaGetToken(NSString *siteKey,
  52. NSString *actionString,
  53. NSString *fakeToken,
  54. FIRAuthRecaptchaTokenCallback callback) {
  55. if (recaptchaClient != nil) {
  56. retrieveToken(actionString, fakeToken, callback);
  57. return;
  58. }
  59. Class RecaptchaClass = NSClassFromString(@"Recaptcha");
  60. SEL selector = NSSelectorFromString(@"getClientWithSiteKey:completion:");
  61. if (RecaptchaClass && [RecaptchaClass respondsToSelector:selector]) {
  62. void (*funcWithoutTimeout)(id, SEL, NSString *,
  63. void (^)(id<RCARecaptchaClientProtocol> _Nullable recaptchaClient,
  64. NSError *_Nullable error)) =
  65. (void *)[RecaptchaClass methodForSelector:selector];
  66. funcWithoutTimeout(RecaptchaClass, selector, siteKey,
  67. ^(id<RCARecaptchaClientProtocol> _Nonnull client, NSError *_Nullable error) {
  68. if (error) {
  69. callback(@"", error, YES, YES);
  70. } else {
  71. recaptchaClient = client;
  72. retrieveToken(actionString, fakeToken, callback);
  73. }
  74. });
  75. } else {
  76. // RecaptchaEnterprise not linked.
  77. callback(@"", nil, NO, NO);
  78. }
  79. }
  80. #endif