geetest_ruby_sdk 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.rubocop.yml +38 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +96 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/geetest_ruby_sdk.gemspec +28 -0
- data/lib/geetest/encryptor.rb +79 -0
- data/lib/geetest/v3/account.rb +45 -0
- data/lib/geetest/v3/concerns/degraded_mode.rb +35 -0
- data/lib/geetest/v3/register.rb +55 -0
- data/lib/geetest/v3/validator.rb +57 -0
- data/lib/geetest/v4/account.rb +45 -0
- data/lib/geetest.rb +84 -0
- data/lib/geetest_ruby_sdk/version.rb +3 -0
- data/lib/geetest_ruby_sdk.rb +25 -0
- data/vendor/assets/javascripts/gt.js +353 -0
- data/vendor/assets/javascripts/gt4.js +460 -0
- metadata +99 -0
@@ -0,0 +1,460 @@
|
|
1
|
+
"v4.1.0 Geetest Inc.";
|
2
|
+
|
3
|
+
(function (window) {
|
4
|
+
"use strict";
|
5
|
+
if (typeof window === 'undefined') {
|
6
|
+
throw new Error('Geetest requires browser environment');
|
7
|
+
}
|
8
|
+
|
9
|
+
var document = window.document;
|
10
|
+
var Math = window.Math;
|
11
|
+
var head = document.getElementsByTagName("head")[0];
|
12
|
+
var TIMEOUT = 10000;
|
13
|
+
|
14
|
+
function _Object(obj) {
|
15
|
+
this._obj = obj;
|
16
|
+
}
|
17
|
+
|
18
|
+
_Object.prototype = {
|
19
|
+
_each: function (process) {
|
20
|
+
var _obj = this._obj;
|
21
|
+
for (var k in _obj) {
|
22
|
+
if (_obj.hasOwnProperty(k)) {
|
23
|
+
process(k, _obj[k]);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
return this;
|
27
|
+
},
|
28
|
+
_extend: function (obj){
|
29
|
+
var self = this;
|
30
|
+
new _Object(obj)._each(function (key, value){
|
31
|
+
self._obj[key] = value;
|
32
|
+
})
|
33
|
+
}
|
34
|
+
};
|
35
|
+
|
36
|
+
var uuid = function () {
|
37
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
38
|
+
var r = Math.random() * 16 | 0;
|
39
|
+
var v = c === 'x' ? r : (r & 0x3 | 0x8);
|
40
|
+
return v.toString(16);
|
41
|
+
});
|
42
|
+
};
|
43
|
+
|
44
|
+
function Config(config) {
|
45
|
+
var self = this;
|
46
|
+
new _Object(config)._each(function (key, value) {
|
47
|
+
self[key] = value;
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
51
|
+
Config.prototype = {
|
52
|
+
apiServers: ['gcaptcha4.geetest.com','gcaptcha4.geevisit.com'],
|
53
|
+
staticServers: ["static.geetest.com",'static.geevisit.com', "dn-staticdown.qbox.me"],
|
54
|
+
protocol: 'http://',
|
55
|
+
typePath: '/load',
|
56
|
+
fallback_config: {
|
57
|
+
bypass: {
|
58
|
+
staticServers: ["static.geetest.com",'static.geevisit.com', "dn-staticdown.qbox.me"],
|
59
|
+
type: 'bypass',
|
60
|
+
bypass: '/v4/bypass.js'
|
61
|
+
}
|
62
|
+
},
|
63
|
+
_get_fallback_config: function () {
|
64
|
+
var self = this;
|
65
|
+
if (isString(self.type)) {
|
66
|
+
return self.fallback_config[self.type];
|
67
|
+
} else {
|
68
|
+
return self.fallback_config.bypass;
|
69
|
+
}
|
70
|
+
},
|
71
|
+
_extend: function (obj) {
|
72
|
+
var self = this;
|
73
|
+
new _Object(obj)._each(function (key, value) {
|
74
|
+
self[key] = value;
|
75
|
+
})
|
76
|
+
}
|
77
|
+
};
|
78
|
+
var isNumber = function (value) {
|
79
|
+
return (typeof value === 'number');
|
80
|
+
};
|
81
|
+
var isString = function (value) {
|
82
|
+
return (typeof value === 'string');
|
83
|
+
};
|
84
|
+
var isBoolean = function (value) {
|
85
|
+
return (typeof value === 'boolean');
|
86
|
+
};
|
87
|
+
var isObject = function (value) {
|
88
|
+
return (typeof value === 'object' && value !== null);
|
89
|
+
};
|
90
|
+
var isFunction = function (value) {
|
91
|
+
return (typeof value === 'function');
|
92
|
+
};
|
93
|
+
var MOBILE = /Mobi/i.test(navigator.userAgent);
|
94
|
+
|
95
|
+
var callbacks = {};
|
96
|
+
var status = {};
|
97
|
+
|
98
|
+
var random = function () {
|
99
|
+
return parseInt(Math.random() * 10000) + (new Date()).valueOf();
|
100
|
+
};
|
101
|
+
|
102
|
+
// bind 函数polify, ä¸å¸¦new功能的bind
|
103
|
+
|
104
|
+
var bind = function(target,context){
|
105
|
+
if(typeof target !== 'function'){
|
106
|
+
return;
|
107
|
+
}
|
108
|
+
var args = Array.prototype.slice.call(arguments,2);
|
109
|
+
|
110
|
+
if(Function.prototype.bind){
|
111
|
+
return target.bind(context, args);
|
112
|
+
}else {
|
113
|
+
return function(){
|
114
|
+
var _args = Array.prototype.slice.call(arguments);
|
115
|
+
return target.apply(context,args.concat(_args));
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
var toString = Object.prototype.toString;
|
123
|
+
|
124
|
+
var _isFunction = function(obj) {
|
125
|
+
return typeof(obj) === 'function';
|
126
|
+
};
|
127
|
+
var _isObject = function(obj) {
|
128
|
+
return obj === Object(obj);
|
129
|
+
};
|
130
|
+
var _isArray = function(obj) {
|
131
|
+
return toString.call(obj) == '[object Array]';
|
132
|
+
};
|
133
|
+
var _isDate = function(obj) {
|
134
|
+
return toString.call(obj) == '[object Date]';
|
135
|
+
};
|
136
|
+
var _isRegExp = function(obj) {
|
137
|
+
return toString.call(obj) == '[object RegExp]';
|
138
|
+
};
|
139
|
+
var _isBoolean = function(obj) {
|
140
|
+
return toString.call(obj) == '[object Boolean]';
|
141
|
+
};
|
142
|
+
|
143
|
+
|
144
|
+
function resolveKey(input){
|
145
|
+
return input.replace(/(\S)(_([a-zA-Z]))/g, function(match, $1, $2, $3){
|
146
|
+
return $1 + $3.toUpperCase() || "";
|
147
|
+
})
|
148
|
+
}
|
149
|
+
|
150
|
+
function camelizeKeys(input, convert){
|
151
|
+
if(!_isObject(input) || _isDate(input) || _isRegExp(input) || _isBoolean(input) || _isFunction(input)){
|
152
|
+
return convert ? resolveKey(input) : input;
|
153
|
+
}
|
154
|
+
|
155
|
+
if(_isArray(input)){
|
156
|
+
var temp = [];
|
157
|
+
for(var i = 0; i < input.length; i++){
|
158
|
+
temp.push(camelizeKeys(input[i]));
|
159
|
+
}
|
160
|
+
|
161
|
+
}else {
|
162
|
+
var temp = {};
|
163
|
+
for(var prop in input){
|
164
|
+
if(input.hasOwnProperty(prop)){
|
165
|
+
temp[camelizeKeys(prop, true)] = camelizeKeys(input[prop]);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
return temp;
|
170
|
+
}
|
171
|
+
|
172
|
+
var loadScript = function (url, cb, timeout) {
|
173
|
+
var script = document.createElement("script");
|
174
|
+
script.charset = "UTF-8";
|
175
|
+
script.async = true;
|
176
|
+
|
177
|
+
// 对geetestçš„é™æ€èµ„æºæ·»åŠ crossOrigin
|
178
|
+
if ( /static\.geetest\.com/g.test(url)) {
|
179
|
+
script.crossOrigin = "anonymous";
|
180
|
+
}
|
181
|
+
|
182
|
+
script.onerror = function () {
|
183
|
+
cb(true);
|
184
|
+
// 错误触å‘了,超时逻辑就ä¸ç”¨äº†
|
185
|
+
loaded = true;
|
186
|
+
};
|
187
|
+
var loaded = false;
|
188
|
+
script.onload = script.onreadystatechange = function () {
|
189
|
+
if (!loaded &&
|
190
|
+
(!script.readyState ||
|
191
|
+
"loaded" === script.readyState ||
|
192
|
+
"complete" === script.readyState)) {
|
193
|
+
|
194
|
+
loaded = true;
|
195
|
+
setTimeout(function () {
|
196
|
+
cb(false);
|
197
|
+
}, 0);
|
198
|
+
}
|
199
|
+
};
|
200
|
+
script.src = url;
|
201
|
+
head.appendChild(script);
|
202
|
+
|
203
|
+
setTimeout(function () {
|
204
|
+
if (!loaded) {
|
205
|
+
script.onerror = script.onload = null;
|
206
|
+
script.remove && script.remove();
|
207
|
+
cb(true);
|
208
|
+
}
|
209
|
+
}, timeout || TIMEOUT);
|
210
|
+
};
|
211
|
+
|
212
|
+
var normalizeDomain = function (domain) {
|
213
|
+
// special domain: uems.sysu.edu.cn/jwxt/geetest/
|
214
|
+
// return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn
|
215
|
+
return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest
|
216
|
+
};
|
217
|
+
var normalizePath = function (path) {
|
218
|
+
path = path.replace(/\/+/g, '/');
|
219
|
+
if (path.indexOf('/') !== 0) {
|
220
|
+
path = '/' + path;
|
221
|
+
}
|
222
|
+
return path;
|
223
|
+
};
|
224
|
+
var normalizeQuery = function (query) {
|
225
|
+
if (!query) {
|
226
|
+
return '';
|
227
|
+
}
|
228
|
+
var q = '?';
|
229
|
+
new _Object(query)._each(function (key, value) {
|
230
|
+
if (isString(value) || isNumber(value) || isBoolean(value)) {
|
231
|
+
q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
|
232
|
+
}
|
233
|
+
});
|
234
|
+
if (q === '?') {
|
235
|
+
q = '';
|
236
|
+
}
|
237
|
+
return q.replace(/&$/, '');
|
238
|
+
};
|
239
|
+
var makeURL = function (protocol, domain, path, query) {
|
240
|
+
domain = normalizeDomain(domain);
|
241
|
+
|
242
|
+
var url = normalizePath(path) + normalizeQuery(query);
|
243
|
+
if (domain) {
|
244
|
+
url = protocol + domain + url;
|
245
|
+
}
|
246
|
+
|
247
|
+
return url;
|
248
|
+
};
|
249
|
+
|
250
|
+
var load = function (config, protocol, domains, path, query, cb, handleCb) {
|
251
|
+
var tryRequest = function (at) {
|
252
|
+
|
253
|
+
// 处ç†jsonp回调,这里为了ä¿è¯æ¯ä¸ªä¸åŒjsonp都有唯一的回调函数
|
254
|
+
if(handleCb){
|
255
|
+
var cbName = "geetest_" + random();
|
256
|
+
// 需è¦ä¸Žé¢„先定义好cbname傿•°ï¼Œåˆ 除对象
|
257
|
+
window[cbName] = bind(handleCb, null, cbName);
|
258
|
+
query.callback = cbName;
|
259
|
+
}
|
260
|
+
var url = makeURL(protocol, domains[at], path, query);
|
261
|
+
loadScript(url, function (err) {
|
262
|
+
if (err) {
|
263
|
+
// 超时或者出错的时候 移除回调
|
264
|
+
if(cbName){
|
265
|
+
try {
|
266
|
+
window[cbName] = function(){
|
267
|
+
window[cbName] = null;
|
268
|
+
}
|
269
|
+
} catch (e) {}
|
270
|
+
}
|
271
|
+
|
272
|
+
if (at >= domains.length - 1) {
|
273
|
+
cb(true);
|
274
|
+
// report gettype error
|
275
|
+
} else {
|
276
|
+
tryRequest(at + 1);
|
277
|
+
}
|
278
|
+
} else {
|
279
|
+
cb(false);
|
280
|
+
}
|
281
|
+
}, config.timeout);
|
282
|
+
};
|
283
|
+
tryRequest(0);
|
284
|
+
};
|
285
|
+
|
286
|
+
|
287
|
+
var jsonp = function (domains, path, config, callback) {
|
288
|
+
|
289
|
+
var handleCb = function (cbName, data) {
|
290
|
+
|
291
|
+
// ä¿è¯åªæ‰§è¡Œä¸€æ¬¡ï¼Œå…¨éƒ¨è¶…时的情况下ä¸ä¼šå†è§¦å‘;
|
292
|
+
|
293
|
+
if (data.status == 'success') {
|
294
|
+
callback(data.data);
|
295
|
+
} else if (!data.status) {
|
296
|
+
callback(data);
|
297
|
+
} else {
|
298
|
+
//æŽ¥å£æœ‰è¿”回,但是返回了错误状æ€ï¼Œè¿›å…¥æŠ¥é”™é€»è¾‘
|
299
|
+
callback(data);
|
300
|
+
}
|
301
|
+
window[cbName] = undefined;
|
302
|
+
try {
|
303
|
+
delete window[cbName];
|
304
|
+
} catch (e) {
|
305
|
+
}
|
306
|
+
};
|
307
|
+
|
308
|
+
load(config, config.protocol, domains, path, {
|
309
|
+
captcha_id: config.captchaId,
|
310
|
+
challenge: config.challenge || uuid(),
|
311
|
+
client_type: MOBILE? 'h5':'web',
|
312
|
+
risk_type: config.riskType,
|
313
|
+
call_type: config.callType,
|
314
|
+
lang: config.language? config.language : navigator.appName === 'Netscape' ? navigator.language.toLowerCase() : navigator.userLanguage.toLowerCase()
|
315
|
+
}, function (err) {
|
316
|
+
// ç½‘ç»œé—®é¢˜æŽ¥å£æ²¡æœ‰è¿”回,直接使用本地验è¯ç ,走宕机模å¼
|
317
|
+
// 这里å¯ä»¥æ·»åŠ ç”¨æˆ·çš„é€»è¾‘
|
318
|
+
if(err && typeof config.offlineCb === 'function'){
|
319
|
+
// 执行自己的宕机
|
320
|
+
config.offlineCb();
|
321
|
+
return;
|
322
|
+
}
|
323
|
+
|
324
|
+
if(err){
|
325
|
+
callback(config._get_fallback_config());
|
326
|
+
}
|
327
|
+
}, handleCb);
|
328
|
+
};
|
329
|
+
|
330
|
+
var reportError = function (config, url) {
|
331
|
+
load(config, config.protocol, ['monitor.geetest.com'], '/monitor/send', {
|
332
|
+
time: Date.now().getTime(),
|
333
|
+
captcha_id: config.gt,
|
334
|
+
challenge: config.challenge,
|
335
|
+
exception_url: url,
|
336
|
+
error_code: config.error_code
|
337
|
+
}, function (err) {})
|
338
|
+
}
|
339
|
+
|
340
|
+
var throwError = function (errorType, config, errObj) {
|
341
|
+
var errors = {
|
342
|
+
networkError: '网络错误',
|
343
|
+
gtTypeError: 'gtå—æ®µä¸æ˜¯å—符串类型'
|
344
|
+
};
|
345
|
+
if (typeof config.onError === 'function') {
|
346
|
+
config.onError({
|
347
|
+
desc: errObj.desc,
|
348
|
+
msg: errObj.msg,
|
349
|
+
code: errObj.code
|
350
|
+
});
|
351
|
+
} else {
|
352
|
+
throw new Error(errors[errorType]);
|
353
|
+
}
|
354
|
+
};
|
355
|
+
|
356
|
+
var detect = function () {
|
357
|
+
return window.Geetest || document.getElementById("gt_lib");
|
358
|
+
};
|
359
|
+
|
360
|
+
if (detect()) {
|
361
|
+
status.slide = "loaded";
|
362
|
+
}
|
363
|
+
|
364
|
+
window.initGeetest4 = function (userConfig,callback) {
|
365
|
+
|
366
|
+
var config = new Config(userConfig);
|
367
|
+
if (userConfig.https) {
|
368
|
+
config.protocol = 'https://';
|
369
|
+
} else if (!userConfig.protocol) {
|
370
|
+
config.protocol = window.location.protocol + '//';
|
371
|
+
}
|
372
|
+
|
373
|
+
|
374
|
+
if (isObject(userConfig.getType)) {
|
375
|
+
config._extend(userConfig.getType);
|
376
|
+
}
|
377
|
+
|
378
|
+
jsonp(config.apiServers , config.typePath, config, function (newConfig) {
|
379
|
+
|
380
|
+
//错误æ•获,第一个load请求å¯èƒ½ç›´æŽ¥æŠ¥é”™
|
381
|
+
var newConfig = camelizeKeys(newConfig);
|
382
|
+
|
383
|
+
if(newConfig.status === 'error'){
|
384
|
+
return throwError('networkError', config, newConfig);
|
385
|
+
}
|
386
|
+
|
387
|
+
var type = newConfig.type;
|
388
|
+
|
389
|
+
if(config.debug){
|
390
|
+
new _Object(newConfig)._extend(config.debug)
|
391
|
+
}
|
392
|
+
var init = function () {
|
393
|
+
config._extend(newConfig);
|
394
|
+
callback(new window.Geetest4(config));
|
395
|
+
};
|
396
|
+
|
397
|
+
callbacks[type] = callbacks[type] || [];
|
398
|
+
|
399
|
+
var s = status[type] || 'init';
|
400
|
+
if (s === 'init') {
|
401
|
+
|
402
|
+
status[type] = 'loading';
|
403
|
+
|
404
|
+
callbacks[type].push(init);
|
405
|
+
|
406
|
+
if(newConfig.gctPath){
|
407
|
+
load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){
|
408
|
+
if(err){
|
409
|
+
throwError('networkError', config, {
|
410
|
+
code: '60205',
|
411
|
+
msg: 'Network failure',
|
412
|
+
desc: {
|
413
|
+
detail: 'gct resource load timeout'
|
414
|
+
}
|
415
|
+
});
|
416
|
+
}
|
417
|
+
})
|
418
|
+
}
|
419
|
+
|
420
|
+
load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers : newConfig.staticServers || config.staticServers, newConfig.bypass || (newConfig.staticPath + newConfig.js), null, function (err) {
|
421
|
+
if (err) {
|
422
|
+
status[type] = 'fail';
|
423
|
+
throwError('networkError', config, {
|
424
|
+
code: '60204',
|
425
|
+
msg: 'Network failure',
|
426
|
+
desc: {
|
427
|
+
detail: 'js resource load timeout'
|
428
|
+
}
|
429
|
+
});
|
430
|
+
} else {
|
431
|
+
status[type] = 'loaded';
|
432
|
+
var cbs = callbacks[type];
|
433
|
+
for (var i = 0, len = cbs.length; i < len; i = i + 1) {
|
434
|
+
var cb = cbs[i];
|
435
|
+
if (isFunction(cb)) {
|
436
|
+
cb();
|
437
|
+
}
|
438
|
+
}
|
439
|
+
callbacks[type] = [];
|
440
|
+
}
|
441
|
+
});
|
442
|
+
} else if (s === "loaded") {
|
443
|
+
return init();
|
444
|
+
} else if (s === "fail") {
|
445
|
+
throwError('networkError', config), {
|
446
|
+
code: '60204',
|
447
|
+
msg: 'Network failure',
|
448
|
+
desc: {
|
449
|
+
detail: 'js resource load timeout'
|
450
|
+
}
|
451
|
+
};
|
452
|
+
} else if (s === "loading") {
|
453
|
+
callbacks[type].push(init);
|
454
|
+
}
|
455
|
+
});
|
456
|
+
|
457
|
+
};
|
458
|
+
|
459
|
+
|
460
|
+
})(window);
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: geetest_ruby_sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 4.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yuehao Hua
|
8
|
+
- Yii Chou
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2022-09-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
description:
|
43
|
+
email:
|
44
|
+
- huayuehao@jinshuju.net, zhouyi@jinshuju,net
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- ".rspec"
|
51
|
+
- ".rubocop.yml"
|
52
|
+
- ".travis.yml"
|
53
|
+
- CODE_OF_CONDUCT.md
|
54
|
+
- Gemfile
|
55
|
+
- Gemfile.lock
|
56
|
+
- LICENSE.txt
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- bin/console
|
60
|
+
- bin/setup
|
61
|
+
- geetest_ruby_sdk.gemspec
|
62
|
+
- lib/geetest.rb
|
63
|
+
- lib/geetest/encryptor.rb
|
64
|
+
- lib/geetest/v3/account.rb
|
65
|
+
- lib/geetest/v3/concerns/degraded_mode.rb
|
66
|
+
- lib/geetest/v3/register.rb
|
67
|
+
- lib/geetest/v3/validator.rb
|
68
|
+
- lib/geetest/v4/account.rb
|
69
|
+
- lib/geetest_ruby_sdk.rb
|
70
|
+
- lib/geetest_ruby_sdk/version.rb
|
71
|
+
- vendor/assets/javascripts/gt.js
|
72
|
+
- vendor/assets/javascripts/gt4.js
|
73
|
+
homepage: https://github.com/jinshuju/geetest-ruby-sdk
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata:
|
77
|
+
homepage_uri: https://github.com/jinshuju/geetest-ruby-sdk
|
78
|
+
source_code_uri: https://github.com/jinshuju/geetest-ruby-sdk
|
79
|
+
changelog_uri: https://github.com/jinshuju/geetest-ruby-sdk
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.5.0
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubygems_version: 3.1.6
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: Ruby version of Geetest SDK
|
99
|
+
test_files: []
|