dongdayu il y a 5 ans
Parent
révision
96eb62c576
61 fichiers modifiés avec 1207 ajouts et 2486 suppressions
  1. 162
    166
      README.md
  2. 3
    2
      RNLGeetestSensebot.podspec
  3. 10
    6
      android/build.gradle
  4. BIN
      android/libs/geetest_sensebot_android_v4.0.7_20190311.aar
  5. BIN
      android/libs/geetest_testbutton_android_v3.5.3.aar
  6. 1
    1
      android/proguard-rules.pro
  7. 1
    6
      android/src/main/AndroidManifest.xml
  8. 0
    16
      android/src/main/java/com/rnlib/geetest/sensebot/ReactGSEventType.java
  9. 0
    152
      android/src/main/java/com/rnlib/geetest/sensebot/ReactGeetestSensebotModule.java
  10. 225
    0
      android/src/main/java/com/rnlib/geetestsensebot/RNLGeetestSensebotModule.java
  11. 3
    3
      android/src/main/java/com/rnlib/geetestsensebot/RNLGeetestSensebotPackage.java
  12. 63
    0
      dist/index.d.ts
  13. 137
    0
      dist/index.js
  14. BIN
      doc/images/ios-add-framework-search-paths.png
  15. BIN
      doc/images/ios-add-framework.png
  16. 0
    21
      index.js
  17. 201
    0
      index.ts
  18. 0
    25
      ios/Helper/GSColorHelper.h
  19. 0
    17
      ios/Helper/GSColorHelper.m
  20. 0
    155
      ios/RCTGeetestSensebot.m
  21. 1
    8
      ios/RNLGeetestSensebot.h
  22. 211
    0
      ios/RNLGeetestSensebot.m
  23. 32
    86
      ios/RNLGeetestSensebot.xcodeproj/project.pbxproj
  24. BIN
      ios/SDK/GT3Captcha.bundle/Assets.car
  25. BIN
      ios/SDK/GT3Captcha.bundle/Info.plist
  26. BIN
      ios/SDK/GT3Captcha.bundle/ar.lproj/GT3Captcha.strings
  27. BIN
      ios/SDK/GT3Captcha.bundle/de.lproj/GT3Captcha.strings
  28. BIN
      ios/SDK/GT3Captcha.bundle/en.lproj/GT3Captcha.strings
  29. BIN
      ios/SDK/GT3Captcha.bundle/es.lproj/GT3Captcha.strings
  30. BIN
      ios/SDK/GT3Captcha.bundle/fr.lproj/GT3Captcha.strings
  31. BIN
      ios/SDK/GT3Captcha.bundle/id.lproj/GT3Captcha.strings
  32. BIN
      ios/SDK/GT3Captcha.bundle/ja.lproj/GT3Captcha.strings
  33. BIN
      ios/SDK/GT3Captcha.bundle/ko.lproj/GT3Captcha.strings
  34. BIN
      ios/SDK/GT3Captcha.bundle/pt-PT.lproj/GT3Captcha.strings
  35. 0
    0
      ios/SDK/GT3Captcha.bundle/resource.js
  36. BIN
      ios/SDK/GT3Captcha.bundle/ru.lproj/GT3Captcha.strings
  37. BIN
      ios/SDK/GT3Captcha.bundle/zh-CN.lproj/GT3Captcha.strings
  38. BIN
      ios/SDK/GT3Captcha.bundle/zh-HK.lproj/GT3Captcha.strings
  39. BIN
      ios/SDK/GT3Captcha.bundle/zh-Hans.lproj/GT3Captcha.strings
  40. BIN
      ios/SDK/GT3Captcha.bundle/zh-Hant.lproj/GT3Captcha.strings
  41. BIN
      ios/SDK/GT3Captcha.bundle/zh-TW.lproj/GT3Captcha.strings
  42. BIN
      ios/SDK/GT3Captcha.framework/GT3Captcha
  43. 0
    0
      ios/SDK/GT3Captcha.framework/Headers/GT3Captcha.h
  44. 1
    1
      ios/SDK/GT3Captcha.framework/Headers/GT3CaptchaButton.h
  45. 12
    3
      ios/SDK/GT3Captcha.framework/Headers/GT3CaptchaManager.h
  46. 0
    0
      ios/SDK/GT3Captcha.framework/Headers/GT3Error.h
  47. 23
    11
      ios/SDK/GT3Captcha.framework/Headers/GT3Utils.h
  48. BIN
      ios/SDK/GT3Captcha.framework/Info.plist
  49. 0
    0
      ios/SDK/GT3Captcha.framework/Modules/module.modulemap
  50. 47
    0
      package-lock.json
  51. 11
    22
      package.json
  52. 0
    40
      scripts/file.js
  53. 0
    22
      scripts/postinstall.js
  54. 0
    21
      scripts/postlink.js
  55. 0
    258
      src/api.js
  56. 0
    10
      src/constant.js
  57. 0
    3
      src/lib/processColor.js
  58. 0
    13
      src/lib/validCaptchaParams.js
  59. 0
    12
      src/lib/validUrl.js
  60. 63
    0
      tsconfig.json
  61. 0
    1406
      yarn.lock

+ 162
- 166
README.md Voir le fichier

@@ -1,206 +1,202 @@
1 1
 # react-native-geetest-sensebot
2 2
 
3
-[GEETEST极验行为验证](https://docs.geetest.com/install/overview/start/) for React Native
3
+[GEETEST极验行为验证](https://docs.geetest.com/install/overview/start/) [![npm version](https://badge.fury.io/js/%40yyyyu%2Freact-native-geetest-sensebot.svg)](https://www.npmjs.com/package/@yyyyu/react-native-geetest-sensebot)
4 4
 
5
-## 安装
5
+**SDK Version**
6
+iOS: v0.11.7_20190314
7
+Android: v4.0.7_20190311
6 8
 
7
-```bash
8
-yarn add @yyyyu/react-native-geetest-sensebot
9
-```
9
+**测试环境**
10
+Xcode 10.2.1
11
+react-native 0.59.5
10 12
 
11
-or
13
+## Getting Started
12 14
 
13 15
 ```bash
14
-npm install --save @yyyyu/react-native-geetest-sensebot
16
+yarn add @yyyyu/react-native-geetest-sensebot
17
+# or
18
+npm i @yyyyu/react-native-geetest-sensebot --save
15 19
 ```
16 20
 
17
-## 配置
18
-
19
-### ios
20
-
21
-#### 1. 自动配置(推荐)
22
-
23 21
 ```bash
24 22
 react-native link @yyyyu/react-native-geetest-sensebot
25 23
 ```
26 24
 
27
-如果项目**使用 Pods 管理依赖**需要在 Podfile 中添加
25
+### iOS 如果没有使用 CocoaPods
28 26
 
29
-```ruby
30
-pod 'React', :path => '../node_modules/react-native', :subspecs => ['Dependency']
31
-pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
32
-```
27
+在 Linked Frameworks and Libraries 中添加 node_modules/@yyyyu/react-native-geetest-sensebot/ios/SDK/GT3Captcha.framework
33 28
 
34
-#### 2. 手动配置
29
+![add framework](doc/images/ios-add-framework.png)
35 30
 
36
-1. 使用 Xcode 打开项目,在项目依赖目录(Libraries)下添加 node_modules 中的 @yyyyu/react-native-geetest-sensebot 项目
37
-2. 在 Linked Frameworks and Libraries 添加 libRCTGeetestSensebot.a
31
+如果编译报错 <span style="color:red;font-weight:bold;">Framework not found GT3Captcha</span>, 在 Framework Search Paths 添加 $(SRCROOT)/../node_modules/@yyyyu/react-native-geetest-sensebot/ios/SDK
38 32
 
39
-#### 额外配置
40
-
41
-**手动配置和非 Pods 管理依赖情况下**需要将 **node_modules/@yyyyu/react-native-geetest-sensebot/ios/SDK/GT3Captcha.framework** 添加到 framework 依赖中
42
-
43
-### android
44
-
45
-#### 1. 自动配置(如果 IOS 已经运行过,不需要重复运行)
46
-
47
-```bash
48
-react-native link @yyyyu/react-native-geetest-sensebot
49
-```
33
+![add framework search path](doc/images/ios-add-framework-search-paths.png)
50 34
 
51
-#### 2. 手动配置
35
+### Android
52 36
 
53
-1. 在 android/settings.gradle 文件中添加
37
+1. android/build.gradle
54 38
 
55
-    ```Groovy
56
-    include ':react-native-geetest-sensebot'
57
-    project(':react-native-geetest-sensebot').projectDir = new File(rootProject.projectDir, '../node_modules/@yyyyu/react-native-geetest-sensebot/android')
58
-    ```
59
-
60
-2. 在 android/app/build.gradle 文件中依赖部分添加
61
-
62
-    ```Groovy
63
-    dependencies {
64
-        // other dependencies
65
-        compile project(':react-native-geetest-sensebot')
66
-    }
67
-    ```
68
-
69
-3. 在 MainApplication.java 文件中添加
70
-
71
-    ```Java
72
-    import com.rnlib.geetest.sensebot.ReactGeetestSensebotPackage;
73
-
74
-    @Override
75
-    protected List<ReactPackage> getPackages() {
76
-        return Arrays.<ReactPackage>asList(
77
-            // other packages
78
-            new ReactGeetestSensebotPackage()
79
-        );
80
-    }
81
-    ```
82
-
83
-#### 额外配置
84
-
85
-1. 在 android/build.gradle 文件中添加
86
-    ```Groovy
87
-    allprojects {
88
-        repositories {
89
-            // ...other
90
-            flatDir {
91
-                dirs project(':react-native-geetest-sensebot').file('libs')
92
-            }
39
+```Groovy
40
+allprojects {
41
+    repositories {
42
+        // ...
43
+        // 与 android/app/build.gradle 中名称一致
44
+        flatDir {
45
+            dirs project(':@yyyyu_react-native-geetest-sensebot').file('libs')
93 46
         }
94 47
     }
95
-    ```
96
-
97
-2. android/app/build.gradle 中修改构建工具版本大于 25 (buildToolsVersion >= 25)
98
-
99
-3. AndroidManifest.xml
100
-    ```xml
101
-    // 如果存在 android:allowBackup="false" 则添加 tools:replace="android:allowBackup"
102
-    <manifest xmlns:tools="http://schemas.android.com/tools">
103
-        <application
104
-          android:allowBackup="false"
105
-            tools:replace="android:allowBackup">
106
-
107
-        </application>
108
-    </manifest>
109
-    ```
110
-
111
-## JS API
112
-
113
-```javascript
114
-import GeetestSensebot from '@yyyyu/react-native-geetest-sensebot'
115
-
116
-const api1 = 'http://www.geetest.com/demo/gt/register-test'
117
-const api2 = 'http://www.geetest.com/demo/gt/validate-test'
118
-
119
-GeetestSensebot.configApi(api1, api2)
120
-GeetestSensebot.captcha()
121
-```
122
-
123
-#### configApi 配置 api 请求地址
124
-
125
-```javascript
126
-GeetestSensebot.configApi('api1 address', 'api2 address')
48
+}
127 49
 ```
128 50
 
129
-#### captcha 进行行为认证
51
+2. AndroidManifest.xml 中添加权限
130 52
 
131
-```javascript
132
-GeetestSensebot.captcha({
133
-  api1ReqReplacer: (DefaultApi1Req) => { return ModifyApi1Req },
134
-  api1RespHandler: (Api1Resq) => { return { success: number, gt: string, challenge: string } },
135
-  api2ReqReplacer: (DefaultApi2Req) => { return ModifyApi2Req },
136
-  api2RespHandler: (Api2Resq) => { // do anything }
137
-})
53
+```xml
54
+// ...
55
+<uses-permission android:name="android.permission.INTERNET" />
56
+<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
57
+<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
58
+<uses-permission android:name="android.permission.READ_PHONE_STATE" />
138 59
 ```
139 60
 
140
-因为 api1、api2 由使用者自行配置,所以接口的请求及返回处理方式不一定按照官方实例的方式进行,所以这里提供了 4 个可选方法,用于替换 Request 以及处理 Response,关于创建 Request 及处理 Response 参考 [MDN Request](https://developer.mozilla.org/en-US/docs/Web/API/Request)、[MDN Response](https://developer.mozilla.org/en-US/docs/Web/API/Response),同时这 4 个方法均为可选参数,不传会使用默认的方式,函数支持使用 es7 async
61
+## Example
141 62
 
142
-关于 **api1RespHandler** 特别说明,由于行为验证需要将 api1 的结果数据传递到 sdk 组件中,所以需要规定一个格式才能流程正常进行下去,api1RespHandler 返回值格式必须为
143
-```json
144
-{
145
-  "success": number,
146
-  "gt": string,
147
-  "challenge": string
148
-}
149
-```
150
-
151
-错误处理方式
152 63
 ```javascript
153
-import GeetestSensebot, { GSError, ERROR_TYPE } from '@yyyyu/react-native-geetest-sensebot'
154
-try {
155
-  // await GeetestSensebot.captcha() ...
156
-} catch (e) {
157
-  if (e instanceof GSError) {
158
-    const { errCode, errMsg } = e
159
-    if (errCode === ERROR_TYPE.API1) {
160
-    	// api1 出现错误
161
-    }
162
-    if (errCode === ERROR_TYPE.API2) {
163
-    	// api2 出现错误
64
+import React, { Component } from 'react'
65
+import { View, Button } from 'react-native'
66
+import RNGeetestSensebot from '@yyyyu/react-native-geetest-sensebot'
67
+
68
+export default class App extends Component {
69
+  geetest = async () => {
70
+    let api1Result
71
+    try {
72
+      const api1Response = await fetch('http://www.geetest.com/demo/gt/register-test')
73
+      api1Result = await api1Response.json()
74
+    } catch (e) {
75
+      return console.log('API1 request failed, message: %s.', e.message)
164 76
     }
165
-    if (errCode === ERROR_TYPE.CAPTCHA) {
166
-    	// 行为认证过程出现错误
167
-    }
168
-    console.error(errMsg)
169
-    // 由于这个过程涉及多个接口,出错情况多种多样,所以报错使用过程来区分
170
-    // 原 SDK IOS 有错误代码及描述信息,Android 只有错误代码
171
-    // errCode 是自己定义的,errMsg IOS 使用描述信息 Android 使用错误代码
172
-    // errMsg 参数只适用于开发,如果显示给用户建议自行定义错误描述
173
-  }
174
-}
175
-```
176 77
 
177
-官方 API
178
-- API1 [http://www.geetest.com/demo/gt/register-test](http://www.geetest.com/demo/gt/register-test) GET 请求 无参数 返回 json 对象格式为
179
-    ```json
180
-    {
181
-      "success": number,
182
-      "challenge": string,
183
-      "gt": string,
184
-      "new_captcha": boolean
78
+    let geetestResult
79
+    try {
80
+      geetestResult = await RNGeetestSensebot.start({
81
+        api1Result,
82
+        // optional default false
83
+        debug: true,
84
+        // optional default 10s
85
+        loadTimeout: 10000,
86
+        // optional default 10s
87
+        reqTimeout: 10000,
88
+        // optional default system
89
+        lang: RNGeetestSensebot.Lang.System,
90
+        // optional default false
91
+        enableBackgroundCancel: true,
92
+        // optional default transparent
93
+        backgroundColorIOS: 'red',
94
+        // optional default none
95
+        backgroundBlurEffectIOS: RNGeetestSensebot.BackgroundBlurEffectIOS.Regular,
96
+        // optional
97
+        onEvent: (code, data) => {
98
+          if (code === RNGeetestSensebot.Event.FAILED) {
99
+            console.log('Validate failed, reason: %s', data[0])
100
+          } else {
101
+            console.log(RNGeetestSensebot.Event[code], data)
102
+          }
103
+        }
104
+      })
105
+    } catch (e) {
106
+      return console.log('Error, code: %d, message: %s.', e.code, e.message)
185 107
     }
186
-    ```
187
-- API2 [http://www.geetest.com/demo/gt/validate-test](http://www.geetest.com/demo/gt/validate-test) POST 请求 请求参数包含
188
-    ```json
189
-    {
190
-      "geetest_challenge": string,
191
-      "geetest_seccode": string,
192
-      "geetest_validate": string
108
+
109
+    let api2Result
110
+    try {
111
+      const api2Response = await fetch('http://www.geetest.com/demo/gt/validate-test', {
112
+        method: 'POST',
113
+        headers: { 'Content-Type': 'application/json;charset=UTF-8' },
114
+        body: JSON.stringify(geetestResult)
115
+      })
116
+      api2Result = await api2Response.json()
117
+    } catch (e) {
118
+      return console.log('API2 request failed, message: %s.', e.message)
193 119
     }
194
-    ```
195 120
 
196
-#### setMaskColor 设置认证页面背景颜色 iosOnly
121
+    console.log('Validate result: %o.', api2Result)
122
+  }
197 123
 
198
-```javascript
199
-GeetestSensebot.setMaskColor('color string')
124
+  render() {
125
+    return (
126
+      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
127
+        <Button title='StartGeetest' onPress={this.geetest} color='#26c6aa' />
128
+      </View>
129
+    )
130
+  }
131
+}
200 132
 ```
201 133
 
202
-#### enableDebug 设置是否输出调试信息 iosOnly
134
+## Option
203 135
 
204 136
 ```javascript
205
-GeetestSensebot.enableDebug(true)
137
+interface Option {
138
+  // API1
139
+  api1Result: API1Result;
140
+  // debug
141
+  debug?: boolean;
142
+  // view 加载超时时间,默认10000
143
+  loadTimeout?: number;
144
+  // 第二步向极验服务器发送请求超时时间,默认10000
145
+  reqTimeout?: number;
146
+  // 语言,如果为null则使用系统默认语言
147
+  lang?: Lang;
148
+  // 点击背景是否可以取消验证
149
+  enableBackgroundCancel?: boolean;
150
+  // 背景色 IOS Only
151
+  backgroundColorIOS?: any;
152
+  // 背景模糊类型 IOS Only
153
+  backgroundBlurEffectIOS?: BackgroundBlurEffectIOS;
154
+  // 事件监听
155
+  onEvent?: (code: Event, data?: Array<number | string>) => void;
156
+}
157
+interface API1Result {
158
+  success: 0 | 1;
159
+  challenge: string;
160
+  gt: string;
161
+  new_captcha: boolean;
162
+}
163
+enum Lang {
164
+  System = "system",
165
+  ZH = "zh",
166
+  ZH_TW = "zh-tw",
167
+  ZH_HK = "zh-hk",
168
+  EN = "en",
169
+  ID = "id",
170
+  JA = "ja",
171
+  KO = "ko",
172
+  RU = "ru",
173
+  AR = "ar",
174
+  ES = "es",
175
+  PT_PT = "pt-pt",
176
+  FR = "fr",
177
+  DE = "de"
178
+}
179
+enum BackgroundBlurEffectIOS {
180
+  None = -1,
181
+  ExtraLight = 0,
182
+  Light = 1,
183
+  Dark = 2,
184
+  Regular = 3,
185
+  Prominent = 4
186
+}
187
+enum Event {
188
+  RESULT = 1,
189
+  CLOSED = 2,
190
+  FAILED = 3,
191
+  ERROR = 0
192
+}
193
+enum Error {
194
+  PARAMETER_PARSE_FAILED = -1,
195
+  ANDROID_ACTIVITY_DESTROYED = -2
196
+}
197
+interface Result {
198
+  geetest_challenge: string;
199
+  geetest_seccode: string;
200
+  geetest_validate: string;
201
+}
206 202
 ```

RNGeetestSensebot.podspec → RNLGeetestSensebot.podspec Voir le fichier

@@ -3,7 +3,7 @@ require 'json'
3 3
 package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4 4
 
5 5
 Pod::Spec.new do |s|
6
-  s.name                = 'RNGeetestSensebot'
6
+  s.name                = 'RNLGeetestSensebot'
7 7
   s.version             = package['version']
8 8
   s.summary             = package['description']
9 9
   s.description         = package['description']
@@ -14,8 +14,9 @@ Pod::Spec.new do |s|
14 14
 
15 15
   s.requires_arc        = true
16 16
   s.platform            = :ios, '8.0'
17
-  s.source_files        = 'ios/RCTGeetestSensebot.{h,m}', 'ios/Helper/*.{h,m}'
17
+  s.source_files        = 'ios/RNLGeetestSensebot.{h,m}'
18 18
   s.vendored_frameworks = 'ios/SDK/GT3Captcha.framework'
19 19
   s.resource            = 'ios/SDK/GT3Captcha.bundle'
20 20
   s.framework           = 'JavaScriptCore', 'WebKit'
21
+  s.pod_target_xcconfig = { 'HEADER_SEARCH_PATHS' => '$(BUILT_PRODUCTS_DIR)/../include' }
21 22
 end

+ 10
- 6
android/build.gradle Voir le fichier

@@ -1,3 +1,7 @@
1
+def safeExtGet(prop, fallback) {
2
+    rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
3
+}
4
+
1 5
 buildscript {
2 6
     repositories {
3 7
         jcenter()
@@ -11,12 +15,12 @@ buildscript {
11 15
 apply plugin: 'com.android.library'
12 16
 
13 17
 android {
14
-    compileSdkVersion 23
15
-    buildToolsVersion "25.0.3"
18
+    compileSdkVersion safeExtGet('compileSdkVersion', 28)
19
+    buildToolsVersion safeExtGet('buildToolsVersion', "28.0.3")
16 20
 
17 21
     defaultConfig {
18
-        minSdkVersion 16
19
-        targetSdkVersion 22
22
+        minSdkVersion safeExtGet('minSdkVersion', 16)
23
+        targetSdkVersion safeExtGet('targetSdkVersion', 28)
20 24
         versionCode 1
21 25
         versionName "1.0"
22 26
     }
@@ -33,6 +37,6 @@ repositories {
33 37
 }
34 38
 
35 39
 dependencies {
36
-    compile 'com.facebook.react:react-native:+'
37
-    compile(name: 'geetest_testbutton_android_v3.5.3', ext: 'aar')
40
+    implementation 'com.facebook.react:react-native:+'
41
+    implementation(name: 'geetest_sensebot_android_v4.0.7_20190311', ext: 'aar')
38 42
 }

BIN
android/libs/geetest_sensebot_android_v4.0.7_20190311.aar Voir le fichier


BIN
android/libs/geetest_testbutton_android_v3.5.3.aar Voir le fichier


+ 1
- 1
android/proguard-rules.pro Voir le fichier

@@ -1,2 +1,2 @@
1 1
 -dontwarn com.geetest.sdk.**
2
--keep class com.geetest.sdk.** { *; }
2
+-keep class com.geetest.sdk.**{*;}

+ 1
- 6
android/src/main/AndroidManifest.xml Voir le fichier

@@ -1,9 +1,4 @@
1 1
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
-    package="com.rnlib.geetest.sensebot">
2
+    package="com.rnlib.geetestsensebot">
3 3
 
4
-    <uses-permission android:name="android.permission.INTERNET" />
5
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
6
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7
-    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
8
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
9 4
 </manifest>

+ 0
- 16
android/src/main/java/com/rnlib/geetest/sensebot/ReactGSEventType.java Voir le fichier

@@ -1,16 +0,0 @@
1
-package com.rnlib.geetest.sensebot;
2
-
3
-public enum ReactGSEventType {
4
-    GS_CAPTCHA(1),
5
-    GS_ERROR(-1);
6
-
7
-    private final int eventType;
8
-
9
-    ReactGSEventType(int eventType) {
10
-        this.eventType = eventType;
11
-    }
12
-
13
-    public int getValue() {
14
-        return eventType;
15
-    }
16
-}

+ 0
- 152
android/src/main/java/com/rnlib/geetest/sensebot/ReactGeetestSensebotModule.java Voir le fichier

@@ -1,152 +0,0 @@
1
-package com.rnlib.geetest.sensebot;
2
-
3
-import com.facebook.react.bridge.Promise;
4
-import com.facebook.react.bridge.ReactApplicationContext;
5
-import com.facebook.react.bridge.ReactContextBaseJavaModule;
6
-import com.facebook.react.bridge.ReactMethod;
7
-import com.facebook.react.bridge.WritableMap;
8
-import com.facebook.react.bridge.WritableNativeMap;
9
-import com.facebook.react.modules.core.DeviceEventManagerModule;
10
-import com.geetest.sdk.Bind.GT3GeetestBindListener;
11
-import com.geetest.sdk.Bind.GT3GeetestUtilsBind;
12
-
13
-import org.json.JSONObject;
14
-
15
-public class ReactGeetestSensebotModule extends ReactContextBaseJavaModule {
16
-    private final ReactApplicationContext mReactContext;
17
-    private static final String ReactGSEventName = "RNGeetestSensebotEvent";
18
-    private static final String urlPlaceHolder = "";
19
-    private GT3GeetestUtilsBind gt3GeetestUtils;
20
-
21
-    public ReactGeetestSensebotModule(ReactApplicationContext reactContext) {
22
-        super(reactContext);
23
-        mReactContext = reactContext;
24
-    }
25
-
26
-    @Override
27
-    public String getName() {
28
-        return "GeetestSensebot";
29
-    }
30
-
31
-    @ReactMethod
32
-    public void initCaptchaMgr(Integer maskColor, Boolean isDebug, Promise promise) {
33
-        gt3GeetestUtils = new GT3GeetestUtilsBind(mReactContext.getCurrentActivity());
34
-        gt3GeetestUtils.setTimeout(5000);
35
-        gt3GeetestUtils.getISonto();
36
-        gt3GeetestUtils.setDialogTouch(true);
37
-
38
-        promise.resolve(true);
39
-    }
40
-
41
-    @ReactMethod
42
-    public void captcha(final Integer success, final String gt, final String challenge, String api2, Promise promise) {
43
-        if (gt3GeetestUtils == null) {
44
-            promise.resolve(false);
45
-            return;
46
-        }
47
-
48
-        // api1 result pass to captcha
49
-        JSONObject captchaParams = new JSONObject();
50
-        try {
51
-            captchaParams.put("success", success.intValue());
52
-            captchaParams.put("gt", gt);
53
-            captchaParams.put("challenge", challenge);
54
-        } catch (Exception ignored) {
55
-        }
56
-        gt3GeetestUtils.gtSetApi1Json(captchaParams);
57
-
58
-        // start captcha
59
-        mReactContext.runOnUiQueueThread(new Runnable() {
60
-            @Override
61
-            public void run() {
62
-                gt3GeetestUtils.getGeetest(mReactContext.getCurrentActivity(), urlPlaceHolder, urlPlaceHolder, null, new GT3GeetestBindListener() {
63
-                    // 行为验证结果
64
-                    @Override
65
-                    public void gt3GetDialogResult(boolean status, String resultString) {
66
-                        if (status) {
67
-                            JSONObject resultJson;
68
-                            try {
69
-                                resultJson = new JSONObject(resultString);
70
-                            } catch (Exception e) {
71
-                                resultJson = new JSONObject();
72
-                            }
73
-                            WritableMap eventBody = new WritableNativeMap();
74
-                            eventBody.putInt("type", ReactGSEventType.GS_CAPTCHA.getValue());
75
-
76
-                            WritableMap eventPayload = new WritableNativeMap();
77
-                            eventPayload.putString("code", "1");
78
-                            eventPayload.putString("message", "Success");
79
-
80
-                            WritableMap eventResult = new WritableNativeMap();
81
-                            try {
82
-                                eventResult.putString("geetest_challenge", resultJson.getString("geetest_challenge"));
83
-                                eventResult.putString("geetest_validate", resultJson.getString("geetest_validate"));
84
-                                eventResult.putString("geetest_seccode", resultJson.getString("geetest_seccode"));
85
-                            } catch (Exception ignored) {
86
-                            }
87
-
88
-                            eventPayload.putMap("result", eventResult);
89
-                            eventBody.putMap("payload", eventPayload);
90
-
91
-                            sendEvent(eventBody);
92
-
93
-                            gt3GeetestUtils.gt3TestFinish();
94
-                        }
95
-                    }
96
-
97
-                    // 没有进行行为验证就关闭了验证码
98
-                    @Override
99
-                    public void gt3CloseDialog(int i) {
100
-                        WritableMap eventBody = new WritableNativeMap();
101
-                        eventBody.putInt("type", ReactGSEventType.GS_CAPTCHA.getValue());
102
-                        eventBody.putString("errCode", "close view");
103
-                        eventBody.putString("errMsg", "user close captcha view.");
104
-
105
-                        sendEvent(eventBody);
106
-                    }
107
-
108
-                    // 自定义 api2
109
-                    @Override
110
-                    public boolean gt3SetIsCustom() {
111
-                        return true;
112
-                    }
113
-
114
-                    // 框架出错
115
-                    @Override
116
-                    public void gt3DialogOnError(String errCode) {
117
-                        WritableMap eventBody = new WritableNativeMap();
118
-                        eventBody.putInt("type", ReactGSEventType.GS_ERROR.getValue());
119
-                        eventBody.putString("errCode", errCode);
120
-                        eventBody.putString("errMsg", errCode);
121
-
122
-                        sendEvent(eventBody);
123
-                    }
124
-                });
125
-            }
126
-        });
127
-
128
-        promise.resolve(true);
129
-    }
130
-
131
-    @ReactMethod
132
-    public void stopCaptcha(Promise promise) {
133
-        if (gt3GeetestUtils != null) {
134
-            mReactContext.runOnUiQueueThread(new Runnable() {
135
-                @Override
136
-                public void run() {
137
-                    gt3GeetestUtils.cancelUtils();
138
-                    gt3GeetestUtils.gt3TestClose();
139
-                    gt3GeetestUtils = null;
140
-                }
141
-            });
142
-        }
143
-
144
-        promise.resolve(true);
145
-    }
146
-
147
-    private void sendEvent(WritableMap mBody) {
148
-        mReactContext
149
-                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
150
-                .emit(ReactGSEventName, mBody);
151
-    }
152
-}

+ 225
- 0
android/src/main/java/com/rnlib/geetestsensebot/RNLGeetestSensebotModule.java Voir le fichier

@@ -0,0 +1,225 @@
1
+package com.rnlib.geetestsensebot;
2
+
3
+import android.app.Activity;
4
+
5
+import com.facebook.react.bridge.Arguments;
6
+import com.facebook.react.bridge.LifecycleEventListener;
7
+import com.facebook.react.bridge.ReactApplicationContext;
8
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
9
+import com.facebook.react.bridge.ReactMethod;
10
+import com.facebook.react.bridge.ReadableMap;
11
+import com.facebook.react.bridge.UiThreadUtil;
12
+import com.facebook.react.bridge.WritableArray;
13
+import com.facebook.react.bridge.WritableMap;
14
+import com.facebook.react.modules.core.DeviceEventManagerModule;
15
+import com.geetest.sdk.GT3ConfigBean;
16
+import com.geetest.sdk.GT3ErrorBean;
17
+import com.geetest.sdk.GT3GeetestUtils;
18
+import com.geetest.sdk.GT3Listener;
19
+
20
+import org.json.JSONObject;
21
+
22
+import javax.annotation.Nonnull;
23
+import javax.annotation.Nullable;
24
+
25
+public class RNLGeetestSensebotModule extends ReactContextBaseJavaModule {
26
+    private static final String NAME = "RNLGeetestSensebot";
27
+    private static final String EVENT_NAME = "RNLGeetestSensebotEvent";
28
+
29
+    private final ReactApplicationContext mReactContext;
30
+    private GT3GeetestUtils mGT3GeetestUtils;
31
+
32
+    RNLGeetestSensebotModule(ReactApplicationContext reactContext) {
33
+        super(reactContext);
34
+        mReactContext = reactContext;
35
+    }
36
+
37
+    @Nonnull
38
+    @Override
39
+    public String getName() {
40
+        return NAME;
41
+    }
42
+
43
+    @ReactMethod
44
+    public void start(final ReadableMap option) {
45
+        GT3ConfigBean mGT3ConfigBean = new GT3ConfigBean();
46
+        mGT3ConfigBean.setPattern(1); // 1 -> bind 自定义按钮
47
+        try {
48
+            // debug
49
+            boolean debug = option.getBoolean("debug");
50
+            mGT3ConfigBean.setDebug(debug);
51
+            // view load timeout
52
+            int timeout = option.getInt("loadTimeout");
53
+            mGT3ConfigBean.setTimeout(timeout);
54
+            // request timeout
55
+            int webviewTimeout = option.getInt("reqTimeout");
56
+            mGT3ConfigBean.setWebviewTimeout(webviewTimeout);
57
+            // lang
58
+            String lang = option.getString("lang");
59
+            if (lang != null && !lang.equals("system")) {
60
+                mGT3ConfigBean.setLang(lang);
61
+            }
62
+            // enable background cancel
63
+            boolean canceledOnTouchOutside = option.getBoolean("enableBackgroundCancel");
64
+            mGT3ConfigBean.setCanceledOnTouchOutside(canceledOnTouchOutside);
65
+            // api1 json result
66
+            mGT3ConfigBean.setApi1Json(new JSONObject(
67
+                    option.getString("api1Result")));
68
+        } catch (Exception e) {
69
+            sendEvent(Event.Error.getCode(),
70
+                    Error.ParameterParseFailed.getCode(), e.getMessage());
71
+            return;
72
+        }
73
+
74
+        mGT3ConfigBean.setListener(new GT3Listener() {
75
+            @Override
76
+            public void onDialogResult(String s) {
77
+                super.onDialogResult(s);
78
+                sendEvent(Event.Result.getCode(), s);
79
+            }
80
+
81
+            @Override
82
+            public void onClosed(int i) {
83
+                sendEvent(Event.Closed.getCode());
84
+            }
85
+
86
+            @Override
87
+            public void onFailed(GT3ErrorBean gt3ErrorBean) {
88
+                WritableMap result = Arguments.createMap();
89
+                result.putString("errorCode", gt3ErrorBean.errorCode);
90
+                result.putString("errorDesc", gt3ErrorBean.errorDesc);
91
+                result.putDouble("duration", gt3ErrorBean.duration);
92
+                result.putString("challenge", gt3ErrorBean.challenge);
93
+                result.putString("type", gt3ErrorBean.type);
94
+                result.putString("sdkVersion", gt3ErrorBean.sdkVersion);
95
+                JSONObject json = new JSONObject(result.toHashMap());
96
+                sendEvent(Event.Failed.getCode(), json.toString());
97
+            }
98
+
99
+            @Override
100
+            public void onButtonClick() {
101
+
102
+            }
103
+
104
+            @Override
105
+            public void onSuccess(String s) {
106
+
107
+            }
108
+
109
+            @Override
110
+            public void onStatistics(String s) {
111
+
112
+            }
113
+        });
114
+
115
+        Activity activity = mReactContext.getCurrentActivity();
116
+        if (activity == null) {
117
+            sendEvent(Event.Error.getCode(),
118
+                    Error.AndroidActivityDestroyed.getCode(), "Activity has been destroyed.");
119
+            return;
120
+        }
121
+        mGT3GeetestUtils = new GT3GeetestUtils(activity);
122
+        mGT3GeetestUtils.init(mGT3ConfigBean);
123
+        mReactContext.addLifecycleEventListener(new LifecycleEventListener() {
124
+            @Override
125
+            public void onHostResume() {
126
+
127
+            }
128
+
129
+            @Override
130
+            public void onHostPause() {
131
+
132
+            }
133
+
134
+            @Override
135
+            public void onHostDestroy() {
136
+                if (mGT3GeetestUtils != null) {
137
+                    mGT3GeetestUtils.destory();
138
+                }
139
+            }
140
+        });
141
+        UiThreadUtil.runOnUiThread(new Runnable() {
142
+            @Override
143
+            public void run() {
144
+                if (mGT3GeetestUtils != null) {
145
+                    mGT3GeetestUtils.startCustomFlow();
146
+                    mGT3GeetestUtils.getGeetest();
147
+                }
148
+            }
149
+        });
150
+    }
151
+
152
+    @ReactMethod
153
+    public void stop() {
154
+        if (mGT3GeetestUtils != null) {
155
+            UiThreadUtil.runOnUiThread(new Runnable() {
156
+                @Override
157
+                public void run() {
158
+                    if (mGT3GeetestUtils != null) {
159
+                        mGT3GeetestUtils.destory();
160
+                        mGT3GeetestUtils = null;
161
+                    }
162
+                }
163
+            });
164
+        }
165
+    }
166
+
167
+    private void sendEvent(int code, @Nullable Object... data) {
168
+        WritableArray event = Arguments.createArray();
169
+        event.pushInt(code);
170
+        if (data != null) {
171
+            for (Object i : data) {
172
+                if (i == null) {
173
+                    event.pushNull();
174
+                } else if (i instanceof Boolean) {
175
+                    event.pushBoolean((boolean) i);
176
+                } else if (i instanceof Double) {
177
+                    event.pushDouble((double) i);
178
+                } else if (i instanceof Integer) {
179
+                    event.pushInt((int) i);
180
+                } else if (i instanceof String) {
181
+                    event.pushString((String) i);
182
+                } else if (i instanceof WritableArray) {
183
+                    event.pushArray((WritableArray) i);
184
+                } else if (i instanceof WritableMap) {
185
+                    event.pushMap((WritableMap) i);
186
+                }
187
+            }
188
+        }
189
+        mReactContext
190
+                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
191
+                .emit(EVENT_NAME, event);
192
+    }
193
+
194
+    private enum Event {
195
+        Result(1),
196
+        Closed(2),
197
+        Failed(3),
198
+        Error(0);
199
+
200
+        private final int code;
201
+
202
+        Event(int code) {
203
+            this.code = code;
204
+        }
205
+
206
+        public int getCode() {
207
+            return this.code;
208
+        }
209
+    }
210
+
211
+    private enum Error {
212
+        ParameterParseFailed(-1),
213
+        AndroidActivityDestroyed(-2);
214
+
215
+        private final int code;
216
+
217
+        Error(int code) {
218
+            this.code = code;
219
+        }
220
+
221
+        public int getCode() {
222
+            return this.code;
223
+        }
224
+    }
225
+}

android/src/main/java/com/rnlib/geetest/sensebot/ReactGeetestSensebotPackage.java → android/src/main/java/com/rnlib/geetestsensebot/RNLGeetestSensebotPackage.java Voir le fichier

@@ -1,4 +1,4 @@
1
-package com.rnlib.geetest.sensebot;
1
+package com.rnlib.geetestsensebot;
2 2
 
3 3
 import com.facebook.react.ReactPackage;
4 4
 import com.facebook.react.bridge.JavaScriptModule;
@@ -10,10 +10,10 @@ import java.util.Arrays;
10 10
 import java.util.Collections;
11 11
 import java.util.List;
12 12
 
13
-public class ReactGeetestSensebotPackage implements ReactPackage {
13
+public class RNLGeetestSensebotPackage implements ReactPackage {
14 14
     @Override
15 15
     public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
16
-        return Arrays.<NativeModule>asList(new ReactGeetestSensebotModule(reactContext));
16
+        return Arrays.<NativeModule>asList(new RNLGeetestSensebotModule(reactContext));
17 17
     }
18 18
 
19 19
     // Deprecated from RN 0.47

+ 63
- 0
dist/index.d.ts Voir le fichier

@@ -0,0 +1,63 @@
1
+declare namespace GeetestSensebot {
2
+    enum Lang {
3
+        System = "system",
4
+        ZH = "zh",
5
+        ZH_TW = "zh-tw",
6
+        ZH_HK = "zh-hk",
7
+        EN = "en",
8
+        ID = "id",
9
+        JA = "ja",
10
+        KO = "ko",
11
+        RU = "ru",
12
+        AR = "ar",
13
+        ES = "es",
14
+        PT_PT = "pt-pt",
15
+        FR = "fr",
16
+        DE = "de"
17
+    }
18
+    enum BackgroundBlurEffectIOS {
19
+        None = -1,
20
+        ExtraLight = 0,
21
+        Light = 1,
22
+        Dark = 2,
23
+        Regular = 3,
24
+        Prominent = 4
25
+    }
26
+    interface Option {
27
+        api1Result: API1Result;
28
+        debug?: boolean;
29
+        loadTimeout?: number;
30
+        reqTimeout?: number;
31
+        lang?: Lang;
32
+        enableBackgroundCancel?: boolean;
33
+        backgroundColorIOS?: any;
34
+        backgroundBlurEffectIOS?: BackgroundBlurEffectIOS;
35
+        onEvent?: (code: Event, data?: Array<number | string>) => void;
36
+    }
37
+    interface API1Result {
38
+        success: 0 | 1;
39
+        challenge: string;
40
+        gt: string;
41
+        new_captcha: boolean;
42
+        [key: string]: any;
43
+    }
44
+    interface Result {
45
+        geetest_challenge: string;
46
+        geetest_seccode: string;
47
+        geetest_validate: string;
48
+        [key: string]: any;
49
+    }
50
+    enum Event {
51
+        RESULT = 1,
52
+        CLOSED = 2,
53
+        FAILED = 3,
54
+        ERROR = 0
55
+    }
56
+    enum Error {
57
+        PARAMETER_PARSE_FAILED = -1,
58
+        ANDROID_ACTIVITY_DESTROYED = -2
59
+    }
60
+    function start(option: Option): Promise<Result>;
61
+    function stop(): void;
62
+}
63
+export default GeetestSensebot;

+ 137
- 0
dist/index.js Voir le fichier

@@ -0,0 +1,137 @@
1
+import { NativeModules, NativeEventEmitter, Platform, processColor } from 'react-native';
2
+const Exception = Error;
3
+var RNLGeetestSensebot;
4
+(function (RNLGeetestSensebot_1) {
5
+    // API
6
+    const RNLGeetestSensebot = NativeModules.RNLGeetestSensebot;
7
+    RNLGeetestSensebot_1.start = RNLGeetestSensebot.start;
8
+    RNLGeetestSensebot_1.stop = RNLGeetestSensebot.stop;
9
+    // Event
10
+    const EventName = 'RNLGeetestSensebotEvent';
11
+    const EventEmitter = new NativeEventEmitter(RNLGeetestSensebot);
12
+    RNLGeetestSensebot_1.addListener = (listener) => EventEmitter.addListener(EventName, listener);
13
+})(RNLGeetestSensebot || (RNLGeetestSensebot = {}));
14
+var GeetestSensebot;
15
+(function (GeetestSensebot) {
16
+    let Lang;
17
+    (function (Lang) {
18
+        Lang["System"] = "system";
19
+        Lang["ZH"] = "zh";
20
+        Lang["ZH_TW"] = "zh-tw";
21
+        Lang["ZH_HK"] = "zh-hk";
22
+        Lang["EN"] = "en";
23
+        Lang["ID"] = "id";
24
+        Lang["JA"] = "ja";
25
+        Lang["KO"] = "ko";
26
+        Lang["RU"] = "ru";
27
+        Lang["AR"] = "ar";
28
+        Lang["ES"] = "es";
29
+        Lang["PT_PT"] = "pt-pt";
30
+        Lang["FR"] = "fr";
31
+        Lang["DE"] = "de";
32
+    })(Lang = GeetestSensebot.Lang || (GeetestSensebot.Lang = {}));
33
+    let BackgroundBlurEffectIOS;
34
+    (function (BackgroundBlurEffectIOS) {
35
+        BackgroundBlurEffectIOS[BackgroundBlurEffectIOS["None"] = -1] = "None";
36
+        BackgroundBlurEffectIOS[BackgroundBlurEffectIOS["ExtraLight"] = 0] = "ExtraLight";
37
+        BackgroundBlurEffectIOS[BackgroundBlurEffectIOS["Light"] = 1] = "Light";
38
+        BackgroundBlurEffectIOS[BackgroundBlurEffectIOS["Dark"] = 2] = "Dark";
39
+        BackgroundBlurEffectIOS[BackgroundBlurEffectIOS["Regular"] = 3] = "Regular";
40
+        BackgroundBlurEffectIOS[BackgroundBlurEffectIOS["Prominent"] = 4] = "Prominent";
41
+    })(BackgroundBlurEffectIOS = GeetestSensebot.BackgroundBlurEffectIOS || (GeetestSensebot.BackgroundBlurEffectIOS = {}));
42
+    let Event;
43
+    (function (Event) {
44
+        // 验证结果
45
+        Event[Event["RESULT"] = 1] = "RESULT";
46
+        // 验证窗口关闭
47
+        Event[Event["CLOSED"] = 2] = "CLOSED";
48
+        // 验证失败
49
+        Event[Event["FAILED"] = 3] = "FAILED";
50
+        // 发生错误
51
+        Event[Event["ERROR"] = 0] = "ERROR";
52
+    })(Event = GeetestSensebot.Event || (GeetestSensebot.Event = {}));
53
+    let Error;
54
+    (function (Error) {
55
+        // 参数解析错误
56
+        Error[Error["PARAMETER_PARSE_FAILED"] = -1] = "PARAMETER_PARSE_FAILED";
57
+        // 安卓 activity 已经销毁
58
+        Error[Error["ANDROID_ACTIVITY_DESTROYED"] = -2] = "ANDROID_ACTIVITY_DESTROYED";
59
+    })(Error = GeetestSensebot.Error || (GeetestSensebot.Error = {}));
60
+    const defaultOption = {
61
+        api1Result: '',
62
+        debug: false,
63
+        loadTimeout: 10000,
64
+        reqTimeout: 10000,
65
+        lang: Lang.System,
66
+        enableBackgroundCancel: false,
67
+        backgroundColorIOS: 0,
68
+        backgroundBlurEffectIOS: BackgroundBlurEffectIOS.None,
69
+    };
70
+    function parseConfig(c) {
71
+        const config = Object.assign({}, defaultOption);
72
+        config.api1Result = JSON.stringify(c.api1Result);
73
+        if (typeof c.debug === 'boolean') {
74
+            config.debug = c.debug;
75
+        }
76
+        if (typeof c.loadTimeout === 'number') {
77
+            config.loadTimeout = c.loadTimeout >> 0;
78
+        }
79
+        if (typeof c.reqTimeout === 'number') {
80
+            config.reqTimeout = c.reqTimeout >> 0;
81
+        }
82
+        if (typeof c.lang === 'string') {
83
+            config.lang = c.lang;
84
+        }
85
+        if (typeof c.enableBackgroundCancel === 'boolean') {
86
+            config.enableBackgroundCancel = c.enableBackgroundCancel;
87
+        }
88
+        if (c.backgroundColorIOS !== undefined) {
89
+            config.backgroundColorIOS = processColor(c.backgroundColorIOS);
90
+        }
91
+        if (typeof c.backgroundBlurEffectIOS === 'number') {
92
+            config.backgroundBlurEffectIOS = c.backgroundBlurEffectIOS;
93
+        }
94
+        return config;
95
+    }
96
+    let eventListener;
97
+    // 进行行为认证
98
+    function start(option) {
99
+        return new Promise((resolve, reject) => {
100
+            eventListener = RNLGeetestSensebot.addListener(([code, ...data]) => {
101
+                switch (code) {
102
+                    case Event.RESULT:
103
+                        stop();
104
+                        resolve(JSON.parse(data[0]));
105
+                        break;
106
+                    case Event.FAILED:
107
+                        // iOS 只要认证错误就会触发, android 多次认证错误最后自动关闭 view 时才会触发
108
+                        if (Platform.OS === 'android') {
109
+                            stop();
110
+                        }
111
+                        break;
112
+                    case Event.ERROR:
113
+                        stop();
114
+                        const error = new Exception(data[1]);
115
+                        Object.defineProperty(error, 'name', { value: 'RNGeetestError', writable: false });
116
+                        Object.defineProperty(error, 'code', { value: data[0], writable: false });
117
+                        reject(error);
118
+                        break;
119
+                }
120
+                if (typeof option.onEvent === 'function') {
121
+                    option.onEvent(code, data);
122
+                }
123
+            });
124
+            RNLGeetestSensebot.start(parseConfig(option));
125
+        });
126
+    }
127
+    GeetestSensebot.start = start;
128
+    // 清理行为认证资源占用
129
+    function stop() {
130
+        if (eventListener && typeof eventListener.remove === 'function') {
131
+            eventListener.remove();
132
+        }
133
+        RNLGeetestSensebot.stop();
134
+    }
135
+    GeetestSensebot.stop = stop;
136
+})(GeetestSensebot || (GeetestSensebot = {}));
137
+export default GeetestSensebot;

BIN
doc/images/ios-add-framework-search-paths.png Voir le fichier


BIN
doc/images/ios-add-framework.png Voir le fichier


+ 0
- 21
index.js Voir le fichier

@@ -1,21 +0,0 @@
1
-import {
2
-  enableDebug,
3
-  configApi,
4
-  setMaskColor,
5
-  captcha,
6
-
7
-  GSError
8
-} from './src/api'
9
-import { ERROR_TYPE } from './src/constant'
10
-
11
-export {
12
-  GSError,
13
-  ERROR_TYPE
14
-}
15
-
16
-export default {
17
-  enableDebug,
18
-  configApi,
19
-  setMaskColor,
20
-  captcha
21
-}

+ 201
- 0
index.ts Voir le fichier

@@ -0,0 +1,201 @@
1
+import {
2
+    NativeModules,
3
+    NativeEventEmitter,
4
+    EmitterSubscription,
5
+    Platform,
6
+    processColor
7
+} from 'react-native'
8
+
9
+const Exception = Error
10
+
11
+namespace RNLGeetestSensebot {
12
+    export type Option = Pick<GeetestSensebot.Option,
13
+        'debug' | 'loadTimeout' | 'reqTimeout' | 'enableBackgroundCancel'> & {
14
+        api1Result: string;
15
+        lang?: string;
16
+        backgroundColorIOS?: number;
17
+        backgroundBlurEffectIOS?: number;
18
+    }
19
+
20
+    // API
21
+    const RNLGeetestSensebot = NativeModules.RNLGeetestSensebot
22
+
23
+    export const start: (obj: Option) => void = RNLGeetestSensebot.start
24
+
25
+    export const stop: () => void = RNLGeetestSensebot.stop
26
+
27
+    // Event
28
+    const EventName = 'RNLGeetestSensebotEvent'
29
+
30
+    const EventEmitter = new NativeEventEmitter(RNLGeetestSensebot)
31
+
32
+    export const addListener = (listener: (data: any) => void) =>
33
+        EventEmitter.addListener(EventName, listener)
34
+}
35
+
36
+namespace GeetestSensebot {
37
+    export enum Lang {
38
+        System = 'system', // 跟随系统
39
+        ZH = 'zh', // 简体中文
40
+        ZH_TW = 'zh-tw', // 繁体中文
41
+        ZH_HK = 'zh-hk', // 繁体中文
42
+        EN = 'en', // 英语
43
+        ID = 'id', // 印尼语
44
+        JA = 'ja', // 日语
45
+        KO = 'ko', // 韩语
46
+        RU = 'ru', // 俄语
47
+        AR = 'ar', // 阿拉伯语
48
+        ES = 'es', // 西班牙语
49
+        PT_PT = 'pt-pt', // 葡萄牙语
50
+        FR = 'fr', // 法语
51
+        DE = 'de', // 德语
52
+    }
53
+
54
+    export enum BackgroundBlurEffectIOS {
55
+        None = -1,
56
+        ExtraLight = 0,
57
+        Light,
58
+        Dark,
59
+        Regular, // NS_ENUM_AVAILABLE_IOS(10_0)
60
+        Prominent, // NS_ENUM_AVAILABLE_IOS(10_0)
61
+    }
62
+
63
+    export interface Option {
64
+        // API1
65
+        api1Result: API1Result;
66
+        // debug
67
+        debug?: boolean;
68
+        // view 加载超时时间,默认10000
69
+        loadTimeout?: number;
70
+        // 第二步向极验服务器发送请求超时时间,默认10000
71
+        reqTimeout?: number;
72
+        // 语言,如果为null则使用系统默认语言
73
+        lang?: Lang;
74
+        // 点击背景是否可以取消验证
75
+        enableBackgroundCancel?: boolean;
76
+        // 背景色 IOS Only
77
+        backgroundColorIOS?: any;
78
+        // 背景模糊类型 IOS Only
79
+        backgroundBlurEffectIOS?: BackgroundBlurEffectIOS;
80
+        // 事件监听
81
+        onEvent?: (code: Event, data?: Array<number | string>) => void;
82
+    }
83
+
84
+    export interface API1Result {
85
+        success: 0 | 1;
86
+        challenge: string;
87
+        gt: string;
88
+        new_captcha: boolean;
89
+        [key: string]: any;
90
+    }
91
+
92
+    export interface Result {
93
+        geetest_challenge: string;
94
+        geetest_seccode: string;
95
+        geetest_validate: string;
96
+        [key: string]: any;
97
+    }
98
+
99
+    export enum Event {
100
+        // 验证结果
101
+        RESULT = 1,
102
+        // 验证窗口关闭
103
+        CLOSED = 2,
104
+        // 验证失败
105
+        FAILED = 3,
106
+        // 发生错误
107
+        ERROR = 0,
108
+    }
109
+
110
+    export enum Error {
111
+        // 参数解析错误
112
+        PARAMETER_PARSE_FAILED = -1,
113
+        // 安卓 activity 已经销毁
114
+        ANDROID_ACTIVITY_DESTROYED = -2,
115
+    }
116
+
117
+    const defaultOption: RNLGeetestSensebot.Option = {
118
+        api1Result: '',
119
+        debug: false,
120
+        loadTimeout: 10000,
121
+        reqTimeout: 10000,
122
+        lang: Lang.System,
123
+        enableBackgroundCancel: false,
124
+        backgroundColorIOS: 0, // processColor('transparent')
125
+        backgroundBlurEffectIOS: BackgroundBlurEffectIOS.None,
126
+    }
127
+
128
+    function parseConfig(c: Option): RNLGeetestSensebot.Option {
129
+        const config = Object.assign({}, defaultOption)
130
+
131
+        config.api1Result = JSON.stringify(c.api1Result)
132
+        if (typeof c.debug === 'boolean') {
133
+            config.debug = c.debug
134
+        }
135
+        if (typeof c.loadTimeout === 'number') {
136
+            config.loadTimeout = c.loadTimeout >> 0
137
+        }
138
+        if (typeof c.reqTimeout === 'number') {
139
+            config.reqTimeout = c.reqTimeout >> 0
140
+        }
141
+        if (typeof c.lang === 'string') {
142
+            config.lang = c.lang
143
+        }
144
+        if (typeof c.enableBackgroundCancel === 'boolean') {
145
+            config.enableBackgroundCancel = c.enableBackgroundCancel
146
+        }
147
+        if (c.backgroundColorIOS !== undefined) {
148
+            config.backgroundColorIOS = processColor(c.backgroundColorIOS)
149
+        }
150
+        if (typeof c.backgroundBlurEffectIOS === 'number') {
151
+            config.backgroundBlurEffectIOS = c.backgroundBlurEffectIOS
152
+        }
153
+
154
+        return config
155
+    }
156
+
157
+    let eventListener: EmitterSubscription
158
+
159
+    // 进行行为认证
160
+    export function start(option: Option): Promise<Result> {
161
+        return new Promise((resolve, reject) => {
162
+            eventListener = RNLGeetestSensebot.addListener(([code, ...data]) => {
163
+                switch (code) {
164
+                    case Event.RESULT:
165
+                        stop()
166
+                        resolve(JSON.parse(data[0]))
167
+                        break
168
+                    case Event.FAILED:
169
+                        // iOS 只要认证错误就会触发, android 多次认证错误最后自动关闭 view 时才会触发
170
+                        if (Platform.OS === 'android') {
171
+                            stop()
172
+                        }
173
+                        break
174
+                    case Event.ERROR:
175
+                        stop()
176
+                        const error = new Exception(data[1])
177
+                        Object.defineProperty(error, 'name',
178
+                            { value: 'RNGeetestError', writable: false })
179
+                        Object.defineProperty(error, 'code',
180
+                            { value: data[0], writable: false })
181
+                        reject(error)
182
+                        break
183
+                }
184
+                if (typeof option.onEvent === 'function') {
185
+                    option.onEvent(code, data)
186
+                }
187
+            })
188
+            RNLGeetestSensebot.start(parseConfig(option))
189
+        })
190
+    }
191
+
192
+    // 清理行为认证资源占用
193
+    export function stop () {
194
+        if (eventListener && typeof eventListener.remove === 'function') {
195
+            eventListener.remove()
196
+        }
197
+        RNLGeetestSensebot.stop()
198
+    }
199
+}
200
+
201
+export default GeetestSensebot

+ 0
- 25
ios/Helper/GSColorHelper.h Voir le fichier

@@ -1,25 +0,0 @@
1
-//
2
-//  GSColorHelper.h
3
-//  RNGeetestSensebot
4
-//
5
-//  Created by dayu dong on 2018/5/24.
6
-//
7
-
8
-#ifndef GSColorHelper_h
9
-#define GSColorHelper_h
10
-
11
-#import <UIKit/UIKit.h>
12
-
13
-#if __has_include(<React/RCTConvert.h>)
14
-#import <React/RCTConvert.h>
15
-#else
16
-#import "RCTConvert.h"
17
-#endif
18
-
19
-@interface GSColorHelper : NSObject
20
-
21
-+ (UIColor *)parseColor:(NSNumber *)aColorNumber;
22
-
23
-@end
24
-
25
-#endif /* GSColorHelper_h */

+ 0
- 17
ios/Helper/GSColorHelper.m Voir le fichier

@@ -1,17 +0,0 @@
1
-//
2
-//  GSColorHelper.m
3
-//  RNGeetestSensebot
4
-//
5
-//  Created by dayu dong on 2018/5/24.
6
-//
7
-
8
-#import "GSColorHelper.h"
9
-
10
-@implementation GSColorHelper
11
-
12
-+ (UIColor *)parseColor:(NSNumber *)aColorNumber
13
-{
14
-    return [RCTConvert UIColor:aColorNumber];
15
-}
16
-
17
-@end

+ 0
- 155
ios/RCTGeetestSensebot.m Voir le fichier

@@ -1,155 +0,0 @@
1
-#import "RCTGeetestSensebot.h"
2
-#import "GSColorHelper.h"
3
-
4
-#define GSResolveEvent(event) [NSNumber numberWithInteger:event]
5
-#define GSResolveBool(bool) [NSNumber numberWithBool:bool]
6
-
7
-static NSString* RCTGSEventName = @"RNGeetestSensebotEvent";
8
-
9
-typedef NS_ENUM(NSInteger, RCTGSEventType) {
10
-    GS_CAPTCHA = 1,
11
-    GS_ERROR = -1
12
-};
13
-
14
-@implementation RCTGeetestSensebot {
15
-    GT3CaptchaManager *_captchaManager;
16
-}
17
-
18
-+ (BOOL)requiresMainQueueSetup
19
-{
20
-    return YES;
21
-}
22
-
23
-- (dispatch_queue_t)methodQueue
24
-{
25
-    return dispatch_get_main_queue();
26
-}
27
-
28
-RCT_EXPORT_MODULE()
29
-
30
-
31
-#pragma export methods
32
-
33
-RCT_REMAP_METHOD(initCaptchaMgr,
34
-               maskColorNum:(nonnull NSNumber *)aMaskColorNum
35
-                    isDebug:(BOOL)isDebug
36
-                   resolver:(RCTPromiseResolveBlock)resolve
37
-                   rejecter:(RCTPromiseRejectBlock)reject)
38
-{
39
-    // 初始化 captcha manager
40
-    _captchaManager = [[GT3CaptchaManager alloc] initWithAPI1:nil API2:nil timeout:5.0];
41
-    _captchaManager.delegate = self;
42
-
43
-    UIColor *aMaskColor = [GSColorHelper parseColor:aMaskColorNum];
44
-    _captchaManager.maskColor = aMaskColor;
45
-    [_captchaManager enableDebugMode:isDebug];
46
-
47
-    resolve(GSResolveBool(YES));
48
-}
49
-
50
-RCT_REMAP_METHOD(captcha,
51
-     captchaWithSuccess:(nonnull NSNumber *)success
52
-                     gt:(NSString *)gt
53
-              challenge:(NSString *)challenge
54
-                   api2:(NSString *)api2
55
-               resolver:(RCTPromiseResolveBlock)resolve
56
-               rejecter:(RCTPromiseRejectBlock)reject)
57
-{
58
-    if (!_captchaManager) {
59
-        resolve(GSResolveBool(NO));
60
-        return;
61
-    }
62
-    // 行为验证
63
-    [_captchaManager configureGTest:gt challenge:challenge success:success withAPI2:api2];
64
-    [_captchaManager startGTCaptchaWithAnimated:YES];
65
-
66
-    resolve(GSResolveBool(YES));
67
-}
68
-
69
-RCT_REMAP_METHOD(stopCaptcha,
70
-         stopCaptchaResolver:(RCTPromiseResolveBlock)resolve
71
-                    rejecter:(RCTPromiseRejectBlock)reject)
72
-{
73
-    [self stopCaptchaAndClean];
74
-
75
-    resolve(GSResolveBool(YES));
76
-}
77
-
78
-
79
-#pragma other methods
80
-
81
-- (void)stopCaptchaAndClean
82
-{
83
-    if (_captchaManager) {
84
-        [_captchaManager stopGTCaptcha];
85
-        [_captchaManager closeGTViewIfIsOpen];
86
-        _captchaManager = nil;
87
-    }
88
-}
89
-
90
-
91
-#pragma gt3 delegate
92
-
93
-// disable sdk request api1
94
-- (BOOL)shouldUseDefaultRegisterAPI:(GT3CaptchaManager *)manager
95
-{
96
-    return NO;
97
-}
98
-
99
-// get captcha result
100
-- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveCaptchaCode:(NSString *)code result:(NSDictionary *)result message:(NSString *)message
101
-{
102
-    [self sendEvent:@{
103
-                      @"type": GSResolveEvent(GS_CAPTCHA),
104
-                      @"payload": @{
105
-                              @"code": code,
106
-                              @"message": message,
107
-                              @"result": result
108
-                              }
109
-                      }];
110
-}
111
-
112
-// send user close view event to js
113
-- (void)gtCaptchaUserDidCloseGTView:(GT3CaptchaManager *)manager
114
-{
115
-    [self sendEvent:@{
116
-                      @"type": GSResolveEvent(GS_CAPTCHA),
117
-                      @"errCode": @"close view",
118
-                      @"errMsg": @"user close captcha view."
119
-                      }];
120
-}
121
-
122
-// disable sdk request api2
123
-- (BOOL)shouldUseDefaultSecondaryValidate:(GT3CaptchaManager *)manager
124
-{
125
-    return NO;
126
-}
127
-
128
-- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveSecondaryCaptchaData:(NSData *)data response:(NSURLResponse *)response error:(GT3Error *)error decisionHandler:(void (^)(GT3SecondaryCaptchaPolicy))decisionHandler
129
-{
130
-    // no use
131
-}
132
-
133
-// manager error
134
-- (void)gtCaptcha:(GT3CaptchaManager *)manager errorHandler:(GT3Error *)error
135
-{
136
-    [self sendEvent:@{
137
-                      @"type": GSResolveEvent(GS_ERROR),
138
-                      @"errCode": error.error_code,
139
-                      @"errMsg": error.gtDescription
140
-                      }];
141
-}
142
-
143
-
144
-#pragma event
145
-
146
-- (NSArray<NSString *> *)supportedEvents
147
-{
148
-    return @[RCTGSEventName];
149
-}
150
-
151
-- (void)sendEvent:(id)body {
152
-    [self sendEventWithName:RCTGSEventName body:body];
153
-}
154
-
155
-@end

ios/RCTGeetestSensebot.h → ios/RNLGeetestSensebot.h Voir le fichier

@@ -9,12 +9,5 @@
9 9
 #import "RCTEventEmitter.h"
10 10
 #endif
11 11
 
12
-#if __has_include(<GT3Captcha/GT3Captcha.h>)
13
-#import <GT3Captcha/GT3Captcha.h>
14
-#else
15
-#import "GT3Captcha.h"
16
-#endif
17
-
18
-@interface RCTGeetestSensebot : RCTEventEmitter <RCTBridgeModule, GT3CaptchaManagerDelegate, GT3CaptchaManagerViewDelegate>
19
-
12
+@interface RNLGeetestSensebot : RCTEventEmitter <RCTBridgeModule>
20 13
 @end

+ 211
- 0
ios/RNLGeetestSensebot.m Voir le fichier

@@ -0,0 +1,211 @@
1
+#if __has_include(<React/RCTConvert.h>)
2
+#import <React/RCTConvert.h>
3
+#else
4
+#import "RCTConvert.h"
5
+#endif
6
+#if __has_include(<React/RCTUtils.h>)
7
+#import <React/RCTUtils.h>
8
+#else
9
+#import "RCTUtils.h"
10
+#endif
11
+#import <GT3Captcha/GT3Captcha.h>
12
+
13
+#import "RNLGeetestSensebot.h"
14
+
15
+static NSString* EventName = @"RNLGeetestSensebotEvent";
16
+
17
+typedef NS_ENUM(NSUInteger, RNLGSEvent) {
18
+    RNLGSResultEvent = 1,
19
+    RNLGSClosedEvent = 2,
20
+    RNLGSFailedEvent = 3,
21
+    RNLGSErrorEvent = 0,
22
+};
23
+
24
+static NSNumber* RNLGSGetEventCode(RNLGSEvent event) {
25
+    return [NSNumber numberWithUnsignedInteger:event];
26
+}
27
+
28
+typedef NS_ENUM(NSInteger, RNLGSError) {
29
+    RNLGSParameterParseError = -1,
30
+};
31
+
32
+static NSNumber* RNLGSGetErrorCode(RNLGSError event) {
33
+    return [NSNumber numberWithInteger:event];
34
+}
35
+
36
+@interface RNLGeetestSensebot () <GT3CaptchaManagerDelegate, GT3CaptchaManagerViewDelegate>
37
+@end
38
+
39
+@implementation RNLGeetestSensebot {
40
+    GT3CaptchaManager *_manager;
41
+}
42
+
43
+RCT_EXPORT_METHOD(start:(NSDictionary *)option)
44
+{
45
+    @try {
46
+        // view load timeout
47
+        NSTimeInterval timeout = [RCTConvert double:option[@"loadTimeout"]] / 1000.0;
48
+        // init manager
49
+        _manager = [[GT3CaptchaManager alloc] initWithAPI1:nil API2:nil timeout:timeout];
50
+        _manager.delegate = self;
51
+        _manager.viewDelegate = self;
52
+        // debug
53
+        BOOL enableDebugMode = [RCTConvert BOOL:option[@"debug"]];
54
+        [_manager enableDebugMode: enableDebugMode];
55
+        // request timeout
56
+        NSTimeInterval gtViewTimeout = [RCTConvert double:option[@"reqTimeout"]] / 1000.0;
57
+        [_manager useGTViewWithTimeout:gtViewTimeout];
58
+        // lang
59
+        GT3LanguageType lang = [RNLGeetestSensebot parseLanguag:
60
+                                [RCTConvert NSString:option[@"lang"]]];
61
+        [_manager useLanguage:lang];
62
+        // enable background cancel
63
+        BOOL disableBackgroundUserInteraction = ![RCTConvert BOOL:option[@"enableBackgroundCancel"]];
64
+        [_manager disableBackgroundUserInteraction:disableBackgroundUserInteraction];
65
+        // background color
66
+        UIColor *maskColor = [RCTConvert UIColor:option[@"backgroundColorIOS"]];
67
+        if (maskColor != nil) {
68
+            _manager.maskColor = maskColor;
69
+        }
70
+        // background blur effect
71
+        NSInteger blurEffectStyle = [RCTConvert NSInteger:option[@"backgroundBlurEffectIOS"]];
72
+        if (blurEffectStyle >= UIBlurEffectStyleExtraLight && blurEffectStyle <= UIBlurEffectStyleProminent) {
73
+            // enum bound
74
+            [_manager useVisualViewWithEffect:
75
+             [UIBlurEffect effectWithStyle:(UIBlurEffectStyle)blurEffectStyle]];
76
+        }
77
+        // api1 json result
78
+        NSDictionary *api1JSON = RCTJSONParse([RCTConvert NSString:option[@"api1Result"]], nil);
79
+        [_manager configureGTest:[api1JSON objectForKey:@"gt"]
80
+                       challenge:[api1JSON objectForKey:@"challenge"]
81
+                         success:[api1JSON objectForKey:@"success"]
82
+                        withAPI2:nil];
83
+        // registe and start validate
84
+        [_manager registerCaptcha:nil];
85
+        [_manager startGTCaptchaWithAnimated:YES];
86
+    } @catch (NSException *e) {
87
+        NSMutableString *errorMessage = [NSMutableString new];
88
+        [errorMessage appendString:[e name]];
89
+        if ([e reason] != nil) {
90
+            [errorMessage appendFormat:@", %@", [e reason]];
91
+        }
92
+        if ([e userInfo] != nil) {
93
+            [errorMessage appendFormat:@", %@", [e userInfo]];
94
+        }
95
+        [self sendEvent:@[
96
+                          RNLGSGetEventCode(RNLGSErrorEvent),
97
+                          RNLGSGetErrorCode(RNLGSParameterParseError),
98
+                          errorMessage]];
99
+    }
100
+}
101
+
102
+RCT_EXPORT_METHOD(stop)
103
+{
104
+    if (_manager != nil) {
105
+        [_manager stopGTCaptcha];
106
+        _manager = nil;
107
+    }
108
+}
109
+
110
++(GT3LanguageType)parseLanguag:(NSString *)lang
111
+{
112
+    if ([lang isEqualToString:@"system"]) {
113
+        return GT3LANGTYPE_AUTO;
114
+    } else if ([lang isEqualToString:@"zh"]) {
115
+        return GT3LANGTYPE_ZH_CN;
116
+    } else if ([lang isEqualToString:@"zh-tw"]) {
117
+        return GT3LANGTYPE_ZH_TW;
118
+    } else if ([lang isEqualToString:@"zh-hk"]) {
119
+        return GT3LANGTYPE_ZH_HK;
120
+    } else if ([lang isEqualToString:@"en"]) {
121
+        return GT3LANGTYPE_EN;
122
+    } else if ([lang isEqualToString:@"id"]) {
123
+        return GT3LANGTYPE_ID;
124
+    } else if ([lang isEqualToString:@"ja"]) {
125
+        return GT3LANGTYPE_JA_JP;
126
+    } else if ([lang isEqualToString:@"ko"]) {
127
+        return GT3LANGTYPE_KO_KR;
128
+    } else if ([lang isEqualToString:@"ru"]) {
129
+        return GT3LANGTYPE_RU;
130
+    } else if ([lang isEqualToString:@"ar"]) {
131
+        return GT3LANGTYPE_AR;
132
+    } else if ([lang isEqualToString:@"es"]) {
133
+        return GT3LANGTYPE_ES;
134
+    } else if ([lang isEqualToString:@"pt-pt"]) {
135
+        return GT3LANGTYPE_PT_PT;
136
+    } else if ([lang isEqualToString:@"fr"]) {
137
+        return GT3LANGTYPE_FR;
138
+    } else if ([lang isEqualToString:@"de"]) {
139
+        return GT3LANGTYPE_DE;
140
+    }
141
+    return GT3LANGTYPE_AUTO;
142
+}
143
+
144
+#pragma GT3 Delegate
145
+
146
+- (void)gtCaptcha:(GT3CaptchaManager *)manager errorHandler:(GT3Error *)error
147
+{
148
+    NSMutableString *errorMessage = [NSMutableString new];
149
+    [errorMessage appendString:[error error_code]];
150
+    [errorMessage appendFormat:@", %@", [error gtDescription]];
151
+
152
+    [self sendEvent:@[RNLGSGetEventCode(RNLGSFailedEvent),
153
+                      errorMessage]];
154
+}
155
+
156
+- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveCaptchaCode:(NSString *)code result:(NSDictionary *)result message:(NSString *)message
157
+{
158
+    if ([code isEqualToString:@"0"]) {
159
+        [self sendEvent:@[RNLGSGetEventCode(RNLGSFailedEvent),
160
+                          RCTJSONStringify(result, nil)]];
161
+    } else if ([code isEqualToString:@"1"]) {
162
+        [self sendEvent:@[RNLGSGetEventCode(RNLGSResultEvent),
163
+                          RCTJSONStringify(result, nil)]];
164
+    }
165
+}
166
+
167
+- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveSecondaryCaptchaData:(NSData *)data response:(NSURLResponse *)response error:(GT3Error *)error decisionHandler:(void (^)(GT3SecondaryCaptchaPolicy))decisionHandler
168
+{
169
+
170
+}
171
+
172
+- (void)gtCaptchaUserDidCloseGTView:(GT3CaptchaManager *)manager
173
+{
174
+    [self sendEvent:@[RNLGSGetEventCode(RNLGSClosedEvent)]];
175
+}
176
+
177
+- (BOOL)shouldUseDefaultRegisterAPI:(GT3CaptchaManager *)manager
178
+{
179
+    return NO;
180
+}
181
+
182
+- (BOOL)shouldUseDefaultSecondaryValidate:(GT3CaptchaManager *)manager
183
+{
184
+    return NO;
185
+}
186
+
187
+#pragma react native bridge
188
+
189
+- (NSArray<NSString *> *)supportedEvents
190
+{
191
+    return @[EventName];
192
+}
193
+
194
+- (void)sendEvent:(id)body
195
+{
196
+    [self sendEventWithName:EventName body:body];
197
+}
198
+
199
+RCT_EXPORT_MODULE()
200
+
201
++ (BOOL)requiresMainQueueSetup
202
+{
203
+    return YES;
204
+}
205
+
206
+- (dispatch_queue_t)methodQueue
207
+{
208
+    return dispatch_get_main_queue();
209
+}
210
+
211
+@end

ios/RCTGeetestSensebot.xcodeproj/project.pbxproj → ios/RNLGeetestSensebot.xcodeproj/project.pbxproj Voir le fichier

@@ -7,107 +7,63 @@
7 7
 	objects = {
8 8
 
9 9
 /* Begin PBXBuildFile section */
10
-		3643C27A20B64B8E00A0B890 /* GSColorHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3643C27920B64B8E00A0B890 /* GSColorHelper.m */; };
11
-		36AF50B120D2408400F82592 /* GT3Captcha.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 36AF50B020D2408400F82592 /* GT3Captcha.bundle */; };
12
-		B3E7B58A1CC2AC0600A0062D /* RCTGeetestSensebot.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RCTGeetestSensebot.m */; };
10
+		363F8FBF226ED46600C89882 /* GT3Captcha.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 363F8FBD226ED42100C89882 /* GT3Captcha.bundle */; };
11
+		B3E7B58A1CC2AC0600A0062D /* RNLGeetestSensebot.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNLGeetestSensebot.m */; };
13 12
 /* End PBXBuildFile section */
14 13
 
15
-/* Begin PBXCopyFilesBuildPhase section */
16
-		58B511D91A9E6C8500147676 /* Copy Files */ = {
17
-			isa = PBXCopyFilesBuildPhase;
18
-			buildActionMask = 2147483647;
19
-			dstPath = "include/$(PRODUCT_NAME)";
20
-			dstSubfolderSpec = 16;
21
-			files = (
22
-			);
23
-			name = "Copy Files";
24
-			runOnlyForDeploymentPostprocessing = 0;
25
-		};
26
-/* End PBXCopyFilesBuildPhase section */
27
-
28 14
 /* Begin PBXFileReference section */
29
-		134814201AA4EA6300B7C361 /* libRCTGeetestSensebot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTGeetestSensebot.a; sourceTree = BUILT_PRODUCTS_DIR; };
30
-		3643C27820B64B2F00A0B890 /* GSColorHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GSColorHelper.h; sourceTree = "<group>"; };
31
-		3643C27920B64B8E00A0B890 /* GSColorHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GSColorHelper.m; sourceTree = "<group>"; };
32
-		36AF50B020D2408400F82592 /* GT3Captcha.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = GT3Captcha.bundle; path = SDK/GT3Captcha.bundle; sourceTree = "<group>"; };
33
-		B3E7B5881CC2AC0600A0062D /* RCTGeetestSensebot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTGeetestSensebot.h; sourceTree = "<group>"; };
34
-		B3E7B5891CC2AC0600A0062D /* RCTGeetestSensebot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGeetestSensebot.m; sourceTree = "<group>"; };
15
+		134814201AA4EA6300B7C361 /* libRNLGeetestSensebot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNLGeetestSensebot.a; sourceTree = BUILT_PRODUCTS_DIR; };
16
+		363F8FBD226ED42100C89882 /* GT3Captcha.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = GT3Captcha.bundle; sourceTree = "<group>"; };
17
+		363F8FBE226ED45600C89882 /* GT3Captcha.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GT3Captcha.framework; path = SDK/GT3Captcha.framework; sourceTree = "<group>"; };
18
+		B3E7B5881CC2AC0600A0062D /* RNLGeetestSensebot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNLGeetestSensebot.h; sourceTree = "<group>"; };
19
+		B3E7B5891CC2AC0600A0062D /* RNLGeetestSensebot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNLGeetestSensebot.m; sourceTree = "<group>"; };
35 20
 /* End PBXFileReference section */
36 21
 
37
-/* Begin PBXFrameworksBuildPhase section */
38
-		58B511D81A9E6C8500147676 /* Frameworks */ = {
39
-			isa = PBXFrameworksBuildPhase;
40
-			buildActionMask = 2147483647;
41
-			files = (
42
-			);
43
-			runOnlyForDeploymentPostprocessing = 0;
44
-		};
45
-/* End PBXFrameworksBuildPhase section */
46
-
47 22
 /* Begin PBXGroup section */
48 23
 		134814211AA4EA7D00B7C361 /* Products */ = {
49 24
 			isa = PBXGroup;
50 25
 			children = (
51
-				134814201AA4EA6300B7C361 /* libRCTGeetestSensebot.a */,
26
+				134814201AA4EA6300B7C361 /* libRNLGeetestSensebot.a */,
52 27
 			);
53 28
 			name = Products;
54 29
 			sourceTree = "<group>";
55 30
 		};
56
-		3643C27620B64ADF00A0B890 /* Helper */ = {
57
-			isa = PBXGroup;
58
-			children = (
59
-				3643C27820B64B2F00A0B890 /* GSColorHelper.h */,
60
-				3643C27920B64B8E00A0B890 /* GSColorHelper.m */,
61
-			);
62
-			path = Helper;
63
-			sourceTree = "<group>";
64
-		};
65
-		36AF50AF20D2407800F82592 /* Resources */ = {
31
+		363F8FBC226ED41C00C89882 /* SDK */ = {
66 32
 			isa = PBXGroup;
67 33
 			children = (
68
-				36AF50B020D2408400F82592 /* GT3Captcha.bundle */,
34
+				363F8FBE226ED45600C89882 /* GT3Captcha.framework */,
35
+				363F8FBD226ED42100C89882 /* GT3Captcha.bundle */,
69 36
 			);
70
-			name = Resources;
71
-			sourceTree = "<group>";
72
-		};
73
-		36CD983820B80C0500647AC8 /* Frameworks */ = {
74
-			isa = PBXGroup;
75
-			children = (
76
-			);
77
-			name = Frameworks;
37
+			name = SDK;
78 38
 			sourceTree = "<group>";
79 39
 		};
80 40
 		58B511D21A9E6C8500147676 = {
81 41
 			isa = PBXGroup;
82 42
 			children = (
83
-				B3E7B5881CC2AC0600A0062D /* RCTGeetestSensebot.h */,
84
-				B3E7B5891CC2AC0600A0062D /* RCTGeetestSensebot.m */,
85
-				3643C27620B64ADF00A0B890 /* Helper */,
86
-				36AF50AF20D2407800F82592 /* Resources */,
43
+				B3E7B5881CC2AC0600A0062D /* RNLGeetestSensebot.h */,
44
+				B3E7B5891CC2AC0600A0062D /* RNLGeetestSensebot.m */,
45
+				363F8FBC226ED41C00C89882 /* SDK */,
87 46
 				134814211AA4EA7D00B7C361 /* Products */,
88
-				36CD983820B80C0500647AC8 /* Frameworks */,
89 47
 			);
90 48
 			sourceTree = "<group>";
91 49
 		};
92 50
 /* End PBXGroup section */
93 51
 
94 52
 /* Begin PBXNativeTarget section */
95
-		58B511DA1A9E6C8500147676 /* RCTGeetestSensebot */ = {
53
+		58B511DA1A9E6C8500147676 /* RNLGeetestSensebot */ = {
96 54
 			isa = PBXNativeTarget;
97
-			buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTGeetestSensebot" */;
55
+			buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNLGeetestSensebot" */;
98 56
 			buildPhases = (
99 57
 				58B511D71A9E6C8500147676 /* Sources */,
100
-				58B511D81A9E6C8500147676 /* Frameworks */,
101
-				58B511D91A9E6C8500147676 /* Copy Files */,
102
-				36AF50AD20D2404900F82592 /* Resources */,
58
+				363F8F8C226ED25100C89882 /* Resources */,
103 59
 			);
104 60
 			buildRules = (
105 61
 			);
106 62
 			dependencies = (
107 63
 			);
108
-			name = RCTGeetestSensebot;
64
+			name = RNLGeetestSensebot;
109 65
 			productName = RCTDataManager;
110
-			productReference = 134814201AA4EA6300B7C361 /* libRCTGeetestSensebot.a */;
66
+			productReference = 134814201AA4EA6300B7C361 /* libRNLGeetestSensebot.a */;
111 67
 			productType = "com.apple.product-type.library.static";
112 68
 		};
113 69
 /* End PBXNativeTarget section */
@@ -124,11 +80,12 @@
124 80
 					};
125 81
 				};
126 82
 			};
127
-			buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTGeetestSensebot" */;
83
+			buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNLGeetestSensebot" */;
128 84
 			compatibilityVersion = "Xcode 3.2";
129 85
 			developmentRegion = English;
130 86
 			hasScannedForEncodings = 0;
131 87
 			knownRegions = (
88
+				English,
132 89
 				en,
133 90
 			);
134 91
 			mainGroup = 58B511D21A9E6C8500147676;
@@ -136,17 +93,17 @@
136 93
 			projectDirPath = "";
137 94
 			projectRoot = "";
138 95
 			targets = (
139
-				58B511DA1A9E6C8500147676 /* RCTGeetestSensebot */,
96
+				58B511DA1A9E6C8500147676 /* RNLGeetestSensebot */,
140 97
 			);
141 98
 		};
142 99
 /* End PBXProject section */
143 100
 
144 101
 /* Begin PBXResourcesBuildPhase section */
145
-		36AF50AD20D2404900F82592 /* Resources */ = {
102
+		363F8F8C226ED25100C89882 /* Resources */ = {
146 103
 			isa = PBXResourcesBuildPhase;
147 104
 			buildActionMask = 2147483647;
148 105
 			files = (
149
-				36AF50B120D2408400F82592 /* GT3Captcha.bundle in Resources */,
106
+				363F8FBF226ED46600C89882 /* GT3Captcha.bundle in Resources */,
150 107
 			);
151 108
 			runOnlyForDeploymentPostprocessing = 0;
152 109
 		};
@@ -157,8 +114,7 @@
157 114
 			isa = PBXSourcesBuildPhase;
158 115
 			buildActionMask = 2147483647;
159 116
 			files = (
160
-				B3E7B58A1CC2AC0600A0062D /* RCTGeetestSensebot.m in Sources */,
161
-				3643C27A20B64B8E00A0B890 /* GSColorHelper.m in Sources */,
117
+				B3E7B58A1CC2AC0600A0062D /* RNLGeetestSensebot.m in Sources */,
162 118
 			);
163 119
 			runOnlyForDeploymentPostprocessing = 0;
164 120
 		};
@@ -249,14 +205,9 @@
249 205
 		58B511F01A9E6C8500147676 /* Debug */ = {
250 206
 			isa = XCBuildConfiguration;
251 207
 			buildSettings = {
252
-				FRAMEWORK_SEARCH_PATHS = (
253
-					"$(inherited)",
254
-					"$(PROJECT_DIR)/SDK",
255
-				);
256
-				HEADER_SEARCH_PATHS = "$(inherited)";
257
-				LIBRARY_SEARCH_PATHS = "$(inherited)";
208
+				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/SDK";
258 209
 				OTHER_LDFLAGS = "-ObjC";
259
-				PRODUCT_NAME = RCTGeetestSensebot;
210
+				PRODUCT_NAME = RNLGeetestSensebot;
260 211
 				SKIP_INSTALL = YES;
261 212
 			};
262 213
 			name = Debug;
@@ -264,14 +215,9 @@
264 215
 		58B511F11A9E6C8500147676 /* Release */ = {
265 216
 			isa = XCBuildConfiguration;
266 217
 			buildSettings = {
267
-				FRAMEWORK_SEARCH_PATHS = (
268
-					"$(inherited)",
269
-					"$(PROJECT_DIR)/SDK",
270
-				);
271
-				HEADER_SEARCH_PATHS = "$(inherited)";
272
-				LIBRARY_SEARCH_PATHS = "$(inherited)";
218
+				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/SDK";
273 219
 				OTHER_LDFLAGS = "-ObjC";
274
-				PRODUCT_NAME = RCTGeetestSensebot;
220
+				PRODUCT_NAME = RNLGeetestSensebot;
275 221
 				SKIP_INSTALL = YES;
276 222
 			};
277 223
 			name = Release;
@@ -279,7 +225,7 @@
279 225
 /* End XCBuildConfiguration section */
280 226
 
281 227
 /* Begin XCConfigurationList section */
282
-		58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTGeetestSensebot" */ = {
228
+		58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNLGeetestSensebot" */ = {
283 229
 			isa = XCConfigurationList;
284 230
 			buildConfigurations = (
285 231
 				58B511ED1A9E6C8500147676 /* Debug */,
@@ -288,7 +234,7 @@
288 234
 			defaultConfigurationIsVisible = 0;
289 235
 			defaultConfigurationName = Release;
290 236
 		};
291
-		58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTGeetestSensebot" */ = {
237
+		58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNLGeetestSensebot" */ = {
292 238
 			isa = XCConfigurationList;
293 239
 			buildConfigurations = (
294 240
 				58B511F01A9E6C8500147676 /* Debug */,

BIN
ios/SDK/GT3Captcha.bundle/Assets.car Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/Info.plist Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/ar.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/de.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/en.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/es.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/fr.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/id.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/ja.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/ko.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/pt-PT.lproj/GT3Captcha.strings Voir le fichier


+ 0
- 0
ios/SDK/GT3Captcha.bundle/resource.js Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/ru.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/zh-CN.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/zh-HK.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/zh-Hans.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/zh-Hant.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.bundle/zh-TW.lproj/GT3Captcha.strings Voir le fichier


BIN
ios/SDK/GT3Captcha.framework/GT3Captcha Voir le fichier


+ 0
- 0
ios/SDK/GT3Captcha.framework/Headers/GT3Captcha.h Voir le fichier


+ 1
- 1
ios/SDK/GT3Captcha.framework/Headers/GT3CaptchaButton.h Voir le fichier

@@ -53,7 +53,7 @@
53 53
  *  Captcha Button `layer.borderColor`. Defaults 
54 54
  *  to 0xcccccc. Animatable.
55 55
  */
56
-@property (nonatomic, assign) CGColorRef borderColor;
56
+@property (nonatomic, strong) UIColor *borderColor;
57 57
 
58 58
 /**
59 59
  *  Captcha Button `layer.borderWidth` Defaults to

+ 12
- 3
ios/SDK/GT3Captcha.framework/Headers/GT3CaptchaManager.h Voir le fichier

@@ -10,7 +10,7 @@
10 10
 #import "GT3Utils.h"
11 11
 #import "GT3Error.h"
12 12
 
13
-@protocol GT3CaptchaManagerDelegate, GT3CaptchaManagerViewDelegate, GT3CaptchaManagerStatisticDelegate;
13
+@protocol GT3CaptchaManagerDelegate, GT3CaptchaNetworkDelegate, GT3CaptchaManagerViewDelegate, GT3CaptchaManagerStatisticDelegate;
14 14
 
15 15
 @interface GT3CaptchaManager : NSObject
16 16
 
@@ -19,6 +19,8 @@
19 19
 
20 20
 /** 验证管理代理 */
21 21
 @property (nonatomic, weak) id<GT3CaptchaManagerDelegate> delegate;
22
+/** 验证网络代理 */
23
+@property (nonatomic, weak) id<GT3CaptchaNetworkDelegate> networkDelegate;
22 24
 /** 验证视图代理 */
23 25
 @property (nonatomic, weak) id<GT3CaptchaManagerViewDelegate> viewDelegate;
24 26
 /** 验证统计代理 */
@@ -190,9 +192,9 @@
190 192
  *  @discussion
191 193
  *  默认中文
192 194
  *
193
- *  @param Type 语言类型
195
+ *  @param type 语言类型
194 196
  */
195
-- (void)useLanguage:(GT3LanguageType)Type;
197
+- (void)useLanguage:(GT3LanguageType)type;
196 198
 
197 199
 /**
198 200
  *  @abstract 完全使用HTTPS协议请求验证
@@ -356,6 +358,13 @@
356 358
 
357 359
 @end
358 360
 
361
+@protocol GT3CaptchaNetworkDelegate <NSObject>
362
+
363
+- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
364
+ completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * credential))completionHandler;
365
+
366
+@end
367
+
359 368
 @protocol GT3CaptchaManagerViewDelegate <NSObject>
360 369
 
361 370
 @optional

+ 0
- 0
ios/SDK/GT3Captcha.framework/Headers/GT3Error.h Voir le fichier


+ 23
- 11
ios/SDK/GT3Captcha.framework/Headers/GT3Utils.h Voir le fichier

@@ -65,22 +65,34 @@ typedef NS_ENUM(NSInteger, GT3SecondaryCaptchaPolicy) {
65 65
  *  图形验证的语言选项
66 66
  */
67 67
 typedef NS_ENUM(NSInteger, GT3LanguageType) {
68
-    /** Simplified Chinese */
68
+    /** Simplified Chinese 简体中文 */
69 69
     GT3LANGTYPE_ZH_CN = 0,
70
-    /** Traditional Chinese */
70
+    /** Traditional Chinese 繁体中文 */
71 71
     GT3LANGTYPE_ZH_TW,
72
-    /** Traditional Chinese */
72
+    /** Traditional Chinese 繁体中文 */
73 73
     GT3LANGTYPE_ZH_HK,
74
-    /** Korean */
75
-    GT3LANGTYPE_KO_KR,// 暂不支持
76
-    /** Japenese */
74
+    /** Korean 韩语 */
75
+    GT3LANGTYPE_KO_KR,
76
+    /** Japenese 日语 */
77 77
     GT3LANGTYPE_JA_JP,
78
-    /** English */
79
-    GT3LANGTYPE_EN_US,
80
-    /** Indonesian */
78
+    /** English 英语 */
79
+    GT3LANGTYPE_EN,
80
+    /** Indonesian 印度尼西亚语 */
81 81
     GT3LANGTYPE_ID,
82
-    /** System language*/
83
-    GT3LANGTYPE_AUTO
82
+    /** Arabic 阿拉伯语 */
83
+    GT3LANGTYPE_AR,
84
+    /** German 德语 */
85
+    GT3LANGTYPE_DE,
86
+    /** Spanish 西班牙语 */
87
+    GT3LANGTYPE_ES,
88
+    /** French 法语 */
89
+    GT3LANGTYPE_FR,
90
+    /** Portuguese 葡萄牙语 */
91
+    GT3LANGTYPE_PT_PT,
92
+    /** Russian 俄语 */
93
+    GT3LANGTYPE_RU,
94
+    /** System language 跟随系统语言*/
95
+    GT3LANGTYPE_AUTO = 999
84 96
 };
85 97
 
86 98
 /**

BIN
ios/SDK/GT3Captcha.framework/Info.plist Voir le fichier


+ 0
- 0
ios/SDK/GT3Captcha.framework/Modules/module.modulemap Voir le fichier


+ 47
- 0
package-lock.json Voir le fichier

@@ -0,0 +1,47 @@
1
+{
2
+  "name": "@yyyyu/react-native-geetest-sensebot",
3
+  "version": "2.0.0",
4
+  "lockfileVersion": 1,
5
+  "requires": true,
6
+  "dependencies": {
7
+    "@types/invariant": {
8
+      "version": "2.2.29",
9
+      "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.29.tgz",
10
+      "integrity": "sha512-lRVw09gOvgviOfeUrKc/pmTiRZ7g7oDOU6OAutyuSHpm1/o2RaBQvRhgK8QEdu+FFuw/wnWb29A/iuxv9i8OpQ=="
11
+    },
12
+    "@types/prop-types": {
13
+      "version": "15.7.1",
14
+      "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
15
+      "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg=="
16
+    },
17
+    "@types/react": {
18
+      "version": "16.8.13",
19
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.13.tgz",
20
+      "integrity": "sha512-otJ4ntMuHGrvm67CdDJMAls4WqotmAmW0g3HmWi9LCjSWXrxoXY/nHXrtmMfvPEEmGFNm6NdgMsJmnfH820Qaw==",
21
+      "requires": {
22
+        "@types/prop-types": "*",
23
+        "csstype": "^2.2.0"
24
+      }
25
+    },
26
+    "@types/react-native": {
27
+      "version": "0.57.45",
28
+      "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.57.45.tgz",
29
+      "integrity": "sha512-XHo3buFjgCs5WmycCBoc71QAa+mayQgDf+igRKgt3rle8rxW/fKtQny6quSabR+YcT55PsOE2qBQ4S5ra9ds2g==",
30
+      "requires": {
31
+        "@types/prop-types": "*",
32
+        "@types/react": "*"
33
+      }
34
+    },
35
+    "csstype": {
36
+      "version": "2.6.4",
37
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.4.tgz",
38
+      "integrity": "sha512-lAJUJP3M6HxFXbqtGRc0iZrdyeN+WzOWeY0q/VnFzI+kqVrYIzC7bWlKqCW7oCIdzoPkvfp82EVvrTlQ8zsWQg=="
39
+    },
40
+    "typescript": {
41
+      "version": "3.4.3",
42
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz",
43
+      "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==",
44
+      "dev": true
45
+    }
46
+  }
47
+}

+ 11
- 22
package.json Voir le fichier

@@ -1,42 +1,31 @@
1 1
 {
2 2
   "name": "@yyyyu/react-native-geetest-sensebot",
3 3
   "author": "yyyyu <g592842897@gmail.com>",
4
-  "version": "1.0.4",
4
+  "version": "2.0.0",
5 5
   "keywords": [
6 6
     "react-native",
7
-    "geetest"
7
+    "geetest sensebot"
8 8
   ],
9
-  "description": "react native for geetest sensebot.",
9
+  "description": "geetest sensebot for react native.",
10 10
   "license": "MIT",
11 11
   "homepage": "https://github.com/yyyyu/react-native-geetest-sensebot",
12 12
   "repository": {
13 13
     "type": "git",
14 14
     "url": "git@github.com:yyyyu/react-native-geetest-sensebot.git"
15 15
   },
16
-  "main": "index.js",
16
+  "main": "dist/index.js",
17
+  "types": "dist/index.d.js",
17 18
   "scripts": {
18
-    "postinstall": "node scripts/postinstall"
19
-  },
20
-  "rnpm": {
21
-    "commands": {
22
-      "postlink": "node node_modules/@yyyyu/react-native-geetest-sensebot/scripts/postlink"
23
-    }
24
-  },
25
-  "dependencies": {
26
-    "invariant": "^2.2.4"
19
+    "build": "tsc"
27 20
   },
28 21
   "peerDependencies": {
29
-    "react-native": ">0.50.0"
22
+    "react-native": "^0.59.5"
30 23
   },
31 24
   "devDependencies": {
32
-    "babel-eslint": "^8.2.3",
33
-    "standard": "^11.0.1"
25
+    "typescript": "^3.4.3"
34 26
   },
35
-  "standard": {
36
-    "parser": "babel-eslint",
37
-    "globals": [
38
-      "fetch",
39
-      "Request"
40
-    ]
27
+  "dependencies": {
28
+    "@types/invariant": "^2.2.29",
29
+    "@types/react-native": "^0.57.45"
41 30
   }
42 31
 }

+ 0
- 40
scripts/file.js Voir le fichier

@@ -1,40 +0,0 @@
1
-const fs = require('fs')
2
-
3
-function fileInsert (path, insStr, insSign, avoidDupSign) {
4
-  fileReadAndWrite(path, function (data) {
5
-    if (avoidDupSign && data.indexOf(avoidDupSign) !== -1) return
6
-    const position = data.indexOf(insSign)
7
-    return data.slice(0, position) + insStr + data.slice(position)
8
-  })
9
-}
10
-
11
-function fileReplace (path, search, replace) {
12
-  fileReadAndWrite(path, function (data) {
13
-    return data.replace(new RegExp(search, 'g'), replace)
14
-  })
15
-}
16
-
17
-function fileReadAndWrite (path, callback) {
18
-  if (!fs.existsSync(path)) return
19
-  const encoding = 'utf8'
20
-  let data = null
21
-
22
-  try {
23
-    data = fs.readFileSync(path, encoding)
24
-  } catch (e) {
25
-    return console.error(e)
26
-  }
27
-
28
-  const result = callback(data)
29
-
30
-  try {
31
-    fs.writeFileSync(path, result, encoding)
32
-  } catch (e) {
33
-    console.error(e)
34
-  }
35
-}
36
-
37
-module.exports = {
38
-  fileInsert,
39
-  fileReplace
40
-}

+ 0
- 22
scripts/postinstall.js Voir le fichier

@@ -1,22 +0,0 @@
1
-const path = require('path')
2
-const file = require('./file')
3
-
4
-const postinstall = () => {
5
-  const nodeModuleDir = path.dirname(__filename) + '/../../..'
6
-
7
-  const modifies = {
8
-    get reactSpec () {
9
-      const avoidDupSign = '# Dependency'
10
-      return [
11
-        nodeModuleDir + '/react-native/React.podspec',
12
-        avoidDupSign + '\n  s.subspec "Dependency" do |ss|\n    ss.source_files         = "React/**/*.h"\n  end\n\n  ',
13
-        's.subspec "Core" do |ss|',
14
-        avoidDupSign
15
-      ]
16
-    }
17
-  }
18
-
19
-  file.fileInsert(...modifies.reactSpec)
20
-}
21
-
22
-postinstall()

+ 0
- 21
scripts/postlink.js Voir le fichier

@@ -1,21 +0,0 @@
1
-const path = require('path')
2
-const file = require('./file')
3
-
4
-const postlink = () => {
5
-  const projectDir = path.dirname(__filename) + '/../../../..'
6
-
7
-  file.fileReplace(
8
-    projectDir + '/android/settings.gradle',
9
-    ':@yyyyu/react-native-geetest-sensebot',
10
-    ':react-native-geetest-sensebot'
11
-  )
12
-  file.fileReplace(
13
-    projectDir + '/android/app/build.gradle',
14
-    ':@yyyyu/react-native-geetest-sensebot',
15
-    ':react-native-geetest-sensebot'
16
-  )
17
-
18
-  console.log('\nLink finished, hit <Enter> to continue')
19
-}
20
-
21
-postlink()

+ 0
- 258
src/api.js Voir le fichier

@@ -1,258 +0,0 @@
1
-import { NativeEventEmitter, NativeModules, Platform } from 'react-native'
2
-import processColor from './lib/processColor'
3
-import validUrl from './lib/validUrl'
4
-import validCaptchaParams from './lib/validCaptchaParams'
5
-import invariant from 'invariant'
6
-import { EVENT_TYPE, ERROR_TYPE } from './constant'
7
-
8
-const { GeetestSensebot } = NativeModules
9
-
10
-const GSConfig = {
11
-  api1: null,
12
-  api2: null,
13
-  maskColor: processColor('transparent'),
14
-  isDebug: false
15
-}
16
-
17
-/**
18
- * configApi 配置 api 地址
19
- * @param  {String} api1
20
- * @param  {String} api2
21
- * @return {void}
22
- */
23
-export const configApi = (api1, api2) => {
24
-  validUrl(api1)
25
-  GSConfig.api1 = api1
26
-  validUrl(api2)
27
-  GSConfig.api2 = api2
28
-}
29
-
30
-/**
31
- * setMaskColor 配置行为验证背景遮罩颜色 iosOnly
32
- * @param  {String} color
33
- * @return {void}
34
- */
35
-export const setMaskColor = color => {
36
-  if (Platform.OS !== 'ios') return // 避免不必要的计算
37
-  GSConfig.maskColor = processColor(color)
38
-}
39
-
40
-/**
41
- * enableDebug 开启调试 iosOnly
42
- * @param  {Boolean} isDebug
43
- * @return {void}
44
- */
45
-export const enableDebug = isDebug => {
46
-  GSConfig.isDebug = !!isDebug
47
-}
48
-
49
-/**
50
- * captcha 行为验证
51
- */
52
-export const captcha = async argument => {
53
-  invariant(
54
-    GSConfig.api1 !== null && GSConfig.api2 !== null,
55
-    'api address must be set, please run configApi function first.'
56
-  )
57
-
58
-  const {
59
-    api1ReqReplacer, api1RespHandler,
60
-    api2ReqReplacer, api2RespHandler
61
-  } = argument || {}
62
-
63
-  let payload = null
64
-  let errCode = null
65
-  let errMsg = null
66
-
67
-  // initial captcha manager
68
-  await GeetestSensebot.initCaptchaMgr(GSConfig.maskColor, GSConfig.isDebug)
69
-
70
-  // api1 request
71
-  let api1Resp = null
72
-  let captchaParams = null
73
-  try {
74
-    let api1Req = new Request(GSConfig.api1, {
75
-      method: 'GET',
76
-      headers: { 'Content-Type': 'application/json' },
77
-      credentials: 'include'
78
-    })
79
-    if (typeof api1ReqReplacer === 'function') {
80
-      api1Req = await api1ReqReplacer(api1Req)
81
-      if (!(api1Req instanceof Request)) {
82
-        throw Error('api1ReqReplacer return value not a valid request object')
83
-      }
84
-    }
85
-    api1Resp = await fetch(api1Req)
86
-  } catch (e) {
87
-    throw new GSError({
88
-      errCode: ERROR_TYPE.API1,
89
-      errMsg: `api1 request failed, ${e.message}`
90
-    })
91
-  }
92
-  // api1 resp handle
93
-  if (typeof api1RespHandler === 'function') {
94
-    captchaParams = await api1RespHandler(api1Resp)
95
-  } else {
96
-    captchaParams = await defaultApi1RespHandler(api1Resp)
97
-  }
98
-
99
-  // captcha
100
-  try {
101
-    validCaptchaParams(captchaParams)
102
-  } catch (e) {
103
-    throw new GSError({
104
-      errCode: ERROR_TYPE.CAPTCHA,
105
-      errMsg: `captcha params error, ${e.message}`
106
-    })
107
-  }
108
-  const capcataStartRes = await GeetestSensebot.captcha(
109
-    captchaParams.success,
110
-    captchaParams.gt,
111
-    captchaParams.challenge,
112
-    GSConfig.api2
113
-  )
114
-  if (!capcataStartRes) {
115
-    throw new GSError({
116
-      errCode: ERROR_TYPE.CAPTCHA,
117
-      errMsg: 'captcha start failed, can\'t find captcha manager.'
118
-    })
119
-  }
120
-  const captchaRes = await rnGSEventListener(EVENT_TYPE.CAPTCHA)
121
-  payload = captchaRes.payload
122
-  errCode = captchaRes.errCode
123
-  errMsg = captchaRes.errMsg
124
-  if (errCode) {
125
-    throw new GSError({ errCode: ERROR_TYPE.CAPTCHA, errMsg })
126
-  }
127
-  // from sdk @param code 验证交互结果, 0失败/1成功
128
-  if (payload.code !== '1') {
129
-    throw new GSError({
130
-      errCode: ERROR_TYPE.CAPTCHA,
131
-      errMsg: `captcha valid failed, ${payload.message}`
132
-    })
133
-  }
134
-
135
-  // api2 request
136
-  // @param { geetest_challenge: "", geetest_seccode: "", geetest_validate: "" }
137
-  const api2ReqParams = payload.result
138
-  let api2Resp = null
139
-  try {
140
-    let api2Req = new Request(GSConfig.api2, {
141
-      method: 'POST',
142
-      headers: { 'Content-Type': 'application/json' },
143
-      credentials: 'include',
144
-      body: JSON.stringify(api2ReqParams)
145
-    })
146
-    if (typeof api2ReqReplacer === 'function') {
147
-      api2Req = await api2ReqReplacer(api2Req)
148
-      if (!(api2Req instanceof Request)) {
149
-        throw Error('second params not a valid request object')
150
-      }
151
-    }
152
-    api2Resp = await fetch(api2Req)
153
-  } catch (e) {
154
-    throw new GSError({
155
-      errCode: EVENT_TYPE.API2,
156
-      errMsg: `api2 request failed, ${e.message}`
157
-    })
158
-  }
159
-  // clean
160
-  stopCaptcha()
161
-
162
-  // api2 resp handle
163
-  if (typeof api2RespHandler === 'function') {
164
-    return api2RespHandler(api2Resp)
165
-  } else {
166
-    return defaultApi2RespHandler(api2Resp)
167
-  }
168
-}
169
-
170
-/**
171
- * stopCaptcha 停止行为验证
172
- */
173
-const stopCaptcha = () => {
174
-  return GeetestSensebot.stopCaptcha()
175
-}
176
-
177
-/* event handle */
178
-const GSEmitter = new NativeEventEmitter(GeetestSensebot)
179
-
180
-const rnGSEventListener = listenEventType => {
181
-  return new Promise(resolve => {
182
-    let subscription = null
183
-    const handleGSEvent = ({ type, ...otherParams }) => {
184
-      if (type === EVENT_TYPE.ERROR) {
185
-        resolve(otherParams)
186
-        return
187
-      }
188
-      if (listenEventType !== type) return
189
-      clearSubscribe()
190
-      resolve(otherParams)
191
-    }
192
-    const clearSubscribe = () => {
193
-      subscription.remove()
194
-    }
195
-
196
-    subscription = GSEmitter.addListener('RNGeetestSensebotEvent', handleGSEvent)
197
-  })
198
-}
199
-/* event handle end */
200
-
201
-/* default captcha funcs */
202
-const defaultApi1RespHandler = async api1Resp => {
203
-  /**
204
-   * api1 官方示例接口
205
-   * http://www.geetest.com/demo/gt/register-test
206
-   */
207
-  if (api1Resp.status !== 200) {
208
-    throw new GSError({
209
-      errCode: ERROR_TYPE.API1,
210
-      errMsg: `api1 request error, ${await api1Resp.text()}`
211
-    })
212
-  }
213
-  try {
214
-    return api1Resp.json()
215
-  } catch (e) {
216
-    throw new GSError({
217
-      errCode: ERROR_TYPE.API1,
218
-      errMsg: `api1 request error, response result need json format, but get ${await api1Resp.text()}`
219
-    })
220
-  }
221
-}
222
-
223
-const defaultApi2RespHandler = async api2Resp => {
224
-  /**
225
-   * api2 官方示例接口
226
-   * http://www.geetest.com/demo/gt/validate-test
227
-   */
228
-  if (api2Resp.status !== 200) {
229
-    throw new GSError({
230
-      errCode: ERROR_TYPE.API2,
231
-      errMsg: `api2 request error, ${await api2Resp.text()}`
232
-    })
233
-  }
234
-  try {
235
-    return api2Resp.json()
236
-  } catch (e) {
237
-    return api2Resp.text()
238
-  }
239
-}
240
-/* default captcha funcs end */
241
-
242
-export class GSError extends Error {
243
-  constructor ({ errCode, errMsg }) {
244
-    super(errMsg)
245
-
246
-    this.name = 'GSError'
247
-    this.errCode = errCode
248
-    this.errMsg = errMsg
249
-
250
-    if (typeof Object.setPrototypeOf === 'function') {
251
-      Object.setPrototypeOf(this, GSError.prototype)
252
-    } else {
253
-      this.__proto__ = GSError.prototype
254
-    }
255
-
256
-    stopCaptcha()
257
-  }
258
-}

+ 0
- 10
src/constant.js Voir le fichier

@@ -1,10 +0,0 @@
1
-export const EVENT_TYPE = {
2
-  CAPTCHA: 1,
3
-  ERROR: -1
4
-}
5
-
6
-export const ERROR_TYPE = {
7
-  API1: 1,
8
-  API2: 2,
9
-  CAPTCHA: 3
10
-}

+ 0
- 3
src/lib/processColor.js Voir le fichier

@@ -1,3 +0,0 @@
1
-import processColor from 'react-native/Libraries/StyleSheet/processColor'
2
-
3
-export default processColor

+ 0
- 13
src/lib/validCaptchaParams.js Voir le fichier

@@ -1,13 +0,0 @@
1
-import invariant from 'invariant'
2
-
3
-export default params => {
4
-  invariant(
5
-    typeof params === 'object' &&
6
-    typeof params.success === 'number' &&
7
-    typeof params.gt === 'string' &&
8
-    typeof params.challenge === 'string',
9
-    'captcha params must be an object have \
10
-      success(Number) gt(String) challenge(String), but get %s',
11
-    JSON.stringify(params)
12
-  )
13
-}

+ 0
- 12
src/lib/validUrl.js Voir le fichier

@@ -1,12 +0,0 @@
1
-import invariant from 'invariant'
2
-
3
-export default arg => {
4
-  invariant(
5
-    typeof arg === 'string',
6
-    'expect url is string type, but get %s', typeof arg
7
-  )
8
-  invariant(
9
-    /^https?:\/\//.test(arg),
10
-    'expect url is valid http address, but get %s', arg
11
-  )
12
-}

+ 63
- 0
tsconfig.json Voir le fichier

@@ -0,0 +1,63 @@
1
+{
2
+  "compilerOptions": {
3
+    /* Basic Options */
4
+    "target": "ES2016",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
5
+    "module": "es2015",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
6
+    // "lib": [],                             /* Specify library files to be included in the compilation. */
7
+    // "allowJs": true,                       /* Allow javascript files to be compiled. */
8
+    // "checkJs": true,                       /* Report errors in .js files. */
9
+    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
10
+    "declaration": true,                   /* Generates corresponding '.d.ts' file. */
11
+    // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
12
+    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
13
+    // "outFile": "./",                       /* Concatenate and emit output to single file. */
14
+    "outDir": "./dist",                        /* Redirect output structure to the directory. */
15
+    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
16
+    // "composite": true,                     /* Enable project compilation */
17
+    // "incremental": true,                   /* Enable incremental compilation */
18
+    // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
19
+    "removeComments": false,                /* Do not emit comments to output. */
20
+    // "noEmit": true,                        /* Do not emit outputs. */
21
+    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
22
+    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
23
+    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
24
+
25
+    /* Strict Type-Checking Options */
26
+    "strict": true,                           /* Enable all strict type-checking options. */
27
+    "skipLibCheck": true,
28
+    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
29
+    // "strictNullChecks": true,              /* Enable strict null checks. */
30
+    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
31
+    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
32
+    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
33
+    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
34
+    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
35
+
36
+    /* Additional Checks */
37
+    // "noUnusedLocals": true,                /* Report errors on unused locals. */
38
+    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
39
+    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
40
+    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
41
+
42
+    /* Module Resolution Options */
43
+    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
44
+    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
45
+    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
46
+    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
47
+    // "typeRoots": [],                       /* List of folders to include type definitions from. */
48
+    // "types": [],                           /* Type declaration files to be included in compilation. */
49
+    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
50
+    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
51
+    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
52
+
53
+    /* Source Map Options */
54
+    // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
55
+    // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
56
+    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
57
+    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
58
+
59
+    /* Experimental Options */
60
+    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
61
+    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
62
+  }
63
+}

+ 0
- 1406
yarn.lock
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier