@hcaptcha/react-hcaptcha 0.3.4 → 0.3.8
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.
- package/README.md +3 -8
- package/dist/index.js +42 -36
- package/dist/utils.js +4 -12
- package/package.json +10 -2
- package/src/index.js +23 -16
- package/types/index.d.ts +44 -0
- package/.babelrc +0 -6
- package/.gitattributes +0 -1
- package/.github/workflows/ci.yml +0 -12
- package/.github/workflows/codeql-analysis.yml +0 -71
- package/.github/workflows/publish.yml +0 -22
- package/examples/src/index.html +0 -9
- package/examples/src/index.js +0 -89
- package/jest.config.js +0 -15
- package/tests/hcaptcha.mock.js +0 -19
- package/tests/hcaptcha.spec.js +0 -263
- package/tests/utils.test.js +0 -44
- package/webpack.config.js +0 -42
package/README.md
CHANGED
|
@@ -33,13 +33,6 @@ import HCaptcha from '@hcaptcha/react-hcaptcha';
|
|
|
33
33
|
</FormComponent>
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
#### Usage with TypeScript
|
|
37
|
-
Add the types from DefinitelyTyped
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
npm i -D @types/hcaptcha__react-hcaptcha
|
|
41
|
-
```
|
|
42
|
-
|
|
43
36
|
**A note about TypeScript usage:** If you want to reassign the component name, you could consider making a util that imports the component, then re-exports it as a default. Example:
|
|
44
37
|
|
|
45
38
|
```ts
|
|
@@ -78,6 +71,7 @@ In these instances, you'll most likely want to use `ref` to handle the callbacks
|
|
|
78
71
|
|`imghost`|String|No|`-`|See enterprise docs.|
|
|
79
72
|
|`reportapi`|String|No|`-`|See enterprise docs.|
|
|
80
73
|
|`sentry`|String|No|`-`|See enterprise docs.|
|
|
74
|
+
|`custom`|Boolean|No|`-`|See enterprise docs.|
|
|
81
75
|
|
|
82
76
|
### Events
|
|
83
77
|
|
|
@@ -86,12 +80,13 @@ In these instances, you'll most likely want to use `ref` to handle the callbacks
|
|
|
86
80
|
|`onError`|`err`|When an error occurs. Component will reset immediately after an error.|
|
|
87
81
|
|`onVerify`|`token, eKey`|When challenge is completed. The response `token` and an `eKey` (session id) are passed along.|
|
|
88
82
|
|`onExpire`|-|When the current token expires.|
|
|
83
|
+
|`onLoad`|-|When the hCaptcha API loads.|
|
|
89
84
|
|
|
90
85
|
### Methods
|
|
91
86
|
|
|
92
87
|
|Method|Description|
|
|
93
88
|
|---|---|
|
|
94
|
-
|`execute()`|Programmatically trigger a challenge request
|
|
89
|
+
|`execute()`|Programmatically trigger a challenge request. Additionally, this method can be run asynchronously and returns a promise with the `token` and `eKey` when the challenge is completed.|
|
|
95
90
|
|`resetCaptcha()`|Reset the current challenge|
|
|
96
91
|
|
|
97
92
|
|
package/dist/index.js
CHANGED
|
@@ -1,33 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
20
20
|
|
|
21
|
-
function
|
|
21
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
22
22
|
|
|
23
|
-
function
|
|
23
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
24
24
|
|
|
25
|
-
function
|
|
25
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
|
|
26
26
|
|
|
27
27
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
|
28
28
|
|
|
29
|
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
30
|
-
|
|
31
29
|
var React = require('react');
|
|
32
30
|
|
|
33
31
|
var _require = require("./utils.js"),
|
|
@@ -35,12 +33,12 @@ var _require = require("./utils.js"),
|
|
|
35
33
|
|
|
36
34
|
|
|
37
35
|
var onLoadListeners = [];
|
|
38
|
-
var
|
|
36
|
+
var apiScriptRequested = false; // Generate hCaptcha API Script
|
|
39
37
|
|
|
40
|
-
var
|
|
38
|
+
var mountCaptchaScript = function mountCaptchaScript() {
|
|
41
39
|
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
40
|
+
apiScriptRequested = true; // Create global onload callback
|
|
42
41
|
|
|
43
|
-
// Create global onload callback
|
|
44
42
|
window.hcaptchaOnLoad = function () {
|
|
45
43
|
// Iterate over onload listeners, call each listener
|
|
46
44
|
onLoadListeners = onLoadListeners.filter(function (listener) {
|
|
@@ -60,27 +58,25 @@ var CaptchaScript = function CaptchaScript() {
|
|
|
60
58
|
};
|
|
61
59
|
|
|
62
60
|
var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
63
|
-
|
|
61
|
+
(0, _inherits2["default"])(HCaptcha, _React$Component);
|
|
64
62
|
|
|
65
63
|
var _super = _createSuper(HCaptcha);
|
|
66
64
|
|
|
67
65
|
function HCaptcha(props) {
|
|
68
66
|
var _this;
|
|
69
67
|
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
(0, _classCallCheck2["default"])(this, HCaptcha);
|
|
72
69
|
_this = _super.call(this, props); // API Methods
|
|
73
70
|
|
|
74
|
-
_this.renderCaptcha = _this.renderCaptcha.bind(
|
|
75
|
-
_this.resetCaptcha = _this.resetCaptcha.bind(
|
|
76
|
-
_this.removeCaptcha = _this.removeCaptcha.bind(
|
|
71
|
+
_this.renderCaptcha = _this.renderCaptcha.bind((0, _assertThisInitialized2["default"])(_this));
|
|
72
|
+
_this.resetCaptcha = _this.resetCaptcha.bind((0, _assertThisInitialized2["default"])(_this));
|
|
73
|
+
_this.removeCaptcha = _this.removeCaptcha.bind((0, _assertThisInitialized2["default"])(_this)); // Event Handlers
|
|
77
74
|
|
|
78
|
-
_this.handleOnLoad = _this.handleOnLoad.bind(
|
|
79
|
-
_this.handleSubmit = _this.handleSubmit.bind(
|
|
80
|
-
_this.handleExpire = _this.handleExpire.bind(
|
|
81
|
-
_this.handleError = _this.handleError.bind(
|
|
75
|
+
_this.handleOnLoad = _this.handleOnLoad.bind((0, _assertThisInitialized2["default"])(_this));
|
|
76
|
+
_this.handleSubmit = _this.handleSubmit.bind((0, _assertThisInitialized2["default"])(_this));
|
|
77
|
+
_this.handleExpire = _this.handleExpire.bind((0, _assertThisInitialized2["default"])(_this));
|
|
78
|
+
_this.handleError = _this.handleError.bind((0, _assertThisInitialized2["default"])(_this));
|
|
82
79
|
var isApiReady = typeof hcaptcha !== 'undefined';
|
|
83
|
-
if (!isApiReady) captchaScriptCreated = false;
|
|
84
80
|
_this.ref = React.createRef();
|
|
85
81
|
_this.state = {
|
|
86
82
|
isApiReady: isApiReady,
|
|
@@ -91,7 +87,7 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
91
87
|
return _this;
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
|
|
90
|
+
(0, _createClass2["default"])(HCaptcha, [{
|
|
95
91
|
key: "componentDidMount",
|
|
96
92
|
value: function componentDidMount() {
|
|
97
93
|
//Once captcha is mounted intialize hCaptcha - hCaptcha
|
|
@@ -104,15 +100,15 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
104
100
|
hl = _this$props.languageOverride,
|
|
105
101
|
reCaptchaCompat = _this$props.reCaptchaCompat,
|
|
106
102
|
reportapi = _this$props.reportapi,
|
|
107
|
-
sentry = _this$props.sentry
|
|
103
|
+
sentry = _this$props.sentry,
|
|
104
|
+
custom = _this$props.custom;
|
|
108
105
|
var isApiReady = this.state.isApiReady;
|
|
109
106
|
|
|
110
107
|
if (!isApiReady) {
|
|
111
108
|
//Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
|
|
112
|
-
if (!
|
|
109
|
+
if (!apiScriptRequested) {
|
|
113
110
|
// Only create the script tag once, use a global variable to track
|
|
114
|
-
|
|
115
|
-
CaptchaScript({
|
|
111
|
+
mountCaptchaScript({
|
|
116
112
|
apihost: apihost,
|
|
117
113
|
assethost: assethost,
|
|
118
114
|
endpoint: endpoint,
|
|
@@ -121,7 +117,8 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
121
117
|
imghost: imghost,
|
|
122
118
|
recaptchacompat: reCaptchaCompat === false ? "off" : null,
|
|
123
119
|
reportapi: reportapi,
|
|
124
|
-
sentry: sentry
|
|
120
|
+
sentry: sentry,
|
|
121
|
+
custom: custom
|
|
125
122
|
});
|
|
126
123
|
} // Add onload callback to global onload listeners
|
|
127
124
|
|
|
@@ -221,6 +218,10 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
221
218
|
this.setState({
|
|
222
219
|
isApiReady: true
|
|
223
220
|
}, function () {
|
|
221
|
+
// trigger onLoad if it exists
|
|
222
|
+
var onLoad = _this3.props.onLoad;
|
|
223
|
+
if (onLoad) onLoad(); // render captcha
|
|
224
|
+
|
|
224
225
|
_this3.renderCaptcha();
|
|
225
226
|
});
|
|
226
227
|
}
|
|
@@ -267,12 +268,18 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
267
268
|
}, {
|
|
268
269
|
key: "execute",
|
|
269
270
|
value: function execute() {
|
|
271
|
+
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
270
272
|
var _this$state7 = this.state,
|
|
271
273
|
isApiReady = _this$state7.isApiReady,
|
|
272
274
|
isRemoved = _this$state7.isRemoved,
|
|
273
275
|
captchaId = _this$state7.captchaId;
|
|
274
276
|
if (!isApiReady || isRemoved) return;
|
|
275
|
-
|
|
277
|
+
|
|
278
|
+
if (opts && (0, _typeof2["default"])(opts) !== "object") {
|
|
279
|
+
opts = null;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return hcaptcha.execute(captchaId, opts);
|
|
276
283
|
}
|
|
277
284
|
}, {
|
|
278
285
|
key: "render",
|
|
@@ -284,7 +291,6 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
284
291
|
});
|
|
285
292
|
}
|
|
286
293
|
}]);
|
|
287
|
-
|
|
288
294
|
return HCaptcha;
|
|
289
295
|
}(React.Component);
|
|
290
296
|
|
package/dist/utils.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
|
-
|
|
9
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
10
|
-
|
|
11
|
-
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
12
|
-
|
|
13
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
5
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
14
6
|
|
|
15
7
|
function generateQuery(params) {
|
|
16
8
|
return Object.entries(params).filter(function (_ref) {
|
|
17
|
-
var _ref2 =
|
|
9
|
+
var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
|
|
18
10
|
key = _ref2[0],
|
|
19
11
|
value = _ref2[1];
|
|
20
12
|
|
|
21
13
|
return value || value === false;
|
|
22
14
|
}).map(function (_ref3) {
|
|
23
|
-
var _ref4 =
|
|
15
|
+
var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
|
|
24
16
|
key = _ref4[0],
|
|
25
17
|
value = _ref4[1];
|
|
26
18
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hcaptcha/react-hcaptcha",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.3.8",
|
|
4
|
+
"types": "types/index.d.ts",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"src",
|
|
8
|
+
"dist",
|
|
9
|
+
"types/index.d.ts"
|
|
10
|
+
],
|
|
11
|
+
"description": "A React library for hCaptcha",
|
|
6
12
|
"scripts": {
|
|
7
13
|
"start": "webpack-dev-server --config ./webpack.config.js --mode development",
|
|
8
14
|
"test": "jest",
|
|
15
|
+
"watch": "babel src -d dist --copy-files --watch",
|
|
9
16
|
"transpile": "babel src -d dist --copy-files",
|
|
10
17
|
"build": "npm run transpile",
|
|
11
18
|
"prepublishOnly": "npm run transpile"
|
|
@@ -25,6 +32,7 @@
|
|
|
25
32
|
"devDependencies": {
|
|
26
33
|
"@babel/cli": "^7.12.10",
|
|
27
34
|
"@babel/core": "^7.12.10",
|
|
35
|
+
"@babel/plugin-transform-runtime": "^7.14.5",
|
|
28
36
|
"@babel/preset-env": "^7.12.11",
|
|
29
37
|
"@babel/preset-react": "^7.12.10",
|
|
30
38
|
"babel-loader": "^8.2.2",
|
package/src/index.js
CHANGED
|
@@ -3,10 +3,11 @@ const { generateQuery } = require("./utils.js");
|
|
|
3
3
|
|
|
4
4
|
// Create script to init hCaptcha
|
|
5
5
|
let onLoadListeners = [];
|
|
6
|
-
let
|
|
6
|
+
let apiScriptRequested = false;
|
|
7
7
|
|
|
8
8
|
// Generate hCaptcha API Script
|
|
9
|
-
const
|
|
9
|
+
const mountCaptchaScript = (params={}) => {
|
|
10
|
+
apiScriptRequested = true;
|
|
10
11
|
// Create global onload callback
|
|
11
12
|
window.hcaptchaOnLoad = () => {
|
|
12
13
|
// Iterate over onload listeners, call each listener
|
|
@@ -47,9 +48,6 @@ class HCaptcha extends React.Component {
|
|
|
47
48
|
|
|
48
49
|
const isApiReady = typeof hcaptcha !== 'undefined';
|
|
49
50
|
|
|
50
|
-
if (!isApiReady)
|
|
51
|
-
captchaScriptCreated = false;
|
|
52
|
-
|
|
53
51
|
this.ref = React.createRef();
|
|
54
52
|
|
|
55
53
|
this.state = {
|
|
@@ -61,15 +59,14 @@ class HCaptcha extends React.Component {
|
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
componentDidMount () { //Once captcha is mounted intialize hCaptcha - hCaptcha
|
|
64
|
-
const { apihost, assethost, endpoint, host, imghost, languageOverride:hl, reCaptchaCompat, reportapi, sentry } = this.props;
|
|
62
|
+
const { apihost, assethost, endpoint, host, imghost, languageOverride:hl, reCaptchaCompat, reportapi, sentry, custom } = this.props;
|
|
65
63
|
const { isApiReady } = this.state;
|
|
66
64
|
|
|
67
65
|
if (!isApiReady) { //Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
|
|
68
66
|
|
|
69
|
-
if (!
|
|
67
|
+
if (!apiScriptRequested) {
|
|
70
68
|
// Only create the script tag once, use a global variable to track
|
|
71
|
-
|
|
72
|
-
CaptchaScript({
|
|
69
|
+
mountCaptchaScript({
|
|
73
70
|
apihost,
|
|
74
71
|
assethost,
|
|
75
72
|
endpoint,
|
|
@@ -78,7 +75,8 @@ class HCaptcha extends React.Component {
|
|
|
78
75
|
imghost,
|
|
79
76
|
recaptchacompat: reCaptchaCompat === false? "off" : null,
|
|
80
77
|
reportapi,
|
|
81
|
-
sentry
|
|
78
|
+
sentry,
|
|
79
|
+
custom
|
|
82
80
|
});
|
|
83
81
|
}
|
|
84
82
|
|
|
@@ -129,9 +127,9 @@ class HCaptcha extends React.Component {
|
|
|
129
127
|
const captchaId = hcaptcha.render(this.ref.current,
|
|
130
128
|
{
|
|
131
129
|
...this.props,
|
|
132
|
-
"error-callback"
|
|
133
|
-
"expired-callback": this.handleExpire,
|
|
134
|
-
"callback"
|
|
130
|
+
"error-callback" : this.handleError,
|
|
131
|
+
"expired-callback" : this.handleExpire,
|
|
132
|
+
"callback" : this.handleSubmit,
|
|
135
133
|
});
|
|
136
134
|
|
|
137
135
|
this.setState({ isRemoved: false, captchaId });
|
|
@@ -158,6 +156,11 @@ class HCaptcha extends React.Component {
|
|
|
158
156
|
|
|
159
157
|
handleOnLoad () {
|
|
160
158
|
this.setState({ isApiReady: true }, () => {
|
|
159
|
+
// trigger onLoad if it exists
|
|
160
|
+
const { onLoad } = this.props;
|
|
161
|
+
if (onLoad) onLoad();
|
|
162
|
+
|
|
163
|
+
// render captcha
|
|
161
164
|
this.renderCaptcha();
|
|
162
165
|
});
|
|
163
166
|
}
|
|
@@ -193,12 +196,16 @@ class HCaptcha extends React.Component {
|
|
|
193
196
|
if (onError) onError(event);
|
|
194
197
|
}
|
|
195
198
|
|
|
196
|
-
execute () {
|
|
199
|
+
execute (opts = null) {
|
|
197
200
|
const { isApiReady, isRemoved, captchaId } = this.state;
|
|
198
201
|
|
|
199
|
-
if (!isApiReady || isRemoved) return
|
|
202
|
+
if (!isApiReady || isRemoved) return;
|
|
203
|
+
|
|
204
|
+
if (opts && typeof opts !== "object") {
|
|
205
|
+
opts = null;
|
|
206
|
+
}
|
|
200
207
|
|
|
201
|
-
hcaptcha.execute(captchaId)
|
|
208
|
+
return hcaptcha.execute(captchaId, opts);
|
|
202
209
|
}
|
|
203
210
|
|
|
204
211
|
render () {
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Type definitions for @hcaptcha/react-hcaptcha 0.1
|
|
2
|
+
// Project: https://github.com/hCaptcha/react-hcaptcha
|
|
3
|
+
// Definitions by: Matt Sutkowski <https://github.com/msutkowski>
|
|
4
|
+
// Original Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
|
5
|
+
// TypeScript Version: 2.8
|
|
6
|
+
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
|
|
9
|
+
interface HCaptchaState {
|
|
10
|
+
isApiReady: boolean;
|
|
11
|
+
isRemoved: boolean;
|
|
12
|
+
elementId: string;
|
|
13
|
+
captchaId: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface HCaptchaProps {
|
|
17
|
+
onExpire?: () => any;
|
|
18
|
+
onError?: (event: string) => any;
|
|
19
|
+
onVerify?: (token: string) => any;
|
|
20
|
+
onLoad?: () => any;
|
|
21
|
+
languageOverride?: string;
|
|
22
|
+
sitekey: string;
|
|
23
|
+
size?: "normal" | "compact" | "invisible";
|
|
24
|
+
theme?: "light" | "dark";
|
|
25
|
+
tabIndex?: number;
|
|
26
|
+
id?: string;
|
|
27
|
+
reCaptchaCompat?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface ExecuteResponse {
|
|
31
|
+
response: string;
|
|
32
|
+
key: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
declare class HCaptcha extends React.Component<HCaptchaProps, HCaptchaState> {
|
|
36
|
+
resetCaptcha(): void;
|
|
37
|
+
renderCaptcha(): void;
|
|
38
|
+
removeCaptcha(): void;
|
|
39
|
+
execute(opts: { async: true }): Promise<ExecuteResponse>
|
|
40
|
+
execute(opts?: { async: false }): void;
|
|
41
|
+
execute(opts?: { async: boolean }): Promise<ExecuteResponse> | void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export = HCaptcha;
|
package/.babelrc
DELETED
package/.gitattributes
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
* text=auto
|
package/.github/workflows/ci.yml
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
-
# to commit it to your repository.
|
|
3
|
-
#
|
|
4
|
-
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
-
# or to provide custom queries or build logic.
|
|
6
|
-
name: "CodeQL"
|
|
7
|
-
|
|
8
|
-
on:
|
|
9
|
-
push:
|
|
10
|
-
branches: [master]
|
|
11
|
-
pull_request:
|
|
12
|
-
# The branches below must be a subset of the branches above
|
|
13
|
-
branches: [master]
|
|
14
|
-
schedule:
|
|
15
|
-
- cron: '0 20 * * 3'
|
|
16
|
-
|
|
17
|
-
jobs:
|
|
18
|
-
analyze:
|
|
19
|
-
name: Analyze
|
|
20
|
-
runs-on: ubuntu-latest
|
|
21
|
-
|
|
22
|
-
strategy:
|
|
23
|
-
fail-fast: false
|
|
24
|
-
matrix:
|
|
25
|
-
# Override automatic language detection by changing the below list
|
|
26
|
-
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
|
27
|
-
language: ['javascript']
|
|
28
|
-
# Learn more...
|
|
29
|
-
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
|
30
|
-
|
|
31
|
-
steps:
|
|
32
|
-
- name: Checkout repository
|
|
33
|
-
uses: actions/checkout@v2
|
|
34
|
-
with:
|
|
35
|
-
# We must fetch at least the immediate parents so that if this is
|
|
36
|
-
# a pull request then we can checkout the head.
|
|
37
|
-
fetch-depth: 2
|
|
38
|
-
|
|
39
|
-
# If this run was triggered by a pull request event, then checkout
|
|
40
|
-
# the head of the pull request instead of the merge commit.
|
|
41
|
-
- run: git checkout HEAD^2
|
|
42
|
-
if: ${{ github.event_name == 'pull_request' }}
|
|
43
|
-
|
|
44
|
-
# Initializes the CodeQL tools for scanning.
|
|
45
|
-
- name: Initialize CodeQL
|
|
46
|
-
uses: github/codeql-action/init@v1
|
|
47
|
-
with:
|
|
48
|
-
languages: ${{ matrix.language }}
|
|
49
|
-
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
50
|
-
# By default, queries listed here will override any specified in a config file.
|
|
51
|
-
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
52
|
-
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
|
53
|
-
|
|
54
|
-
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
55
|
-
# If this step fails, then you should remove it and run the build manually (see below)
|
|
56
|
-
- name: Autobuild
|
|
57
|
-
uses: github/codeql-action/autobuild@v1
|
|
58
|
-
|
|
59
|
-
# ℹ️ Command-line programs to run using the OS shell.
|
|
60
|
-
# 📚 https://git.io/JvXDl
|
|
61
|
-
|
|
62
|
-
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
|
63
|
-
# and modify them (or add more) to build your code if your project
|
|
64
|
-
# uses a compiled language
|
|
65
|
-
|
|
66
|
-
#- run: |
|
|
67
|
-
# make bootstrap
|
|
68
|
-
# make release
|
|
69
|
-
|
|
70
|
-
- name: Perform CodeQL Analysis
|
|
71
|
-
uses: github/codeql-action/analyze@v1
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
name: Publish NPM
|
|
2
|
-
on:
|
|
3
|
-
release:
|
|
4
|
-
types: [ created ]
|
|
5
|
-
jobs:
|
|
6
|
-
build:
|
|
7
|
-
name: Build & Test & Publish
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
steps:
|
|
10
|
-
- name: Checkout code
|
|
11
|
-
uses: actions/checkout@v2
|
|
12
|
-
# Setup .npmrc file to publish to npm
|
|
13
|
-
- uses: actions/setup-node@v1
|
|
14
|
-
with:
|
|
15
|
-
node-version: '12.x'
|
|
16
|
-
registry-url: 'https://registry.npmjs.org'
|
|
17
|
-
- run: npm ci
|
|
18
|
-
- run: npm run transpile
|
|
19
|
-
- run: npm run test
|
|
20
|
-
- run: npm publish
|
|
21
|
-
env:
|
|
22
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
|
package/examples/src/index.html
DELETED
package/examples/src/index.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const React = require('react');
|
|
2
|
-
const {render} = require('react-dom');
|
|
3
|
-
const HCaptcha = require('../../dist/');
|
|
4
|
-
|
|
5
|
-
class ReactDemo extends React.Component {
|
|
6
|
-
|
|
7
|
-
constructor(props) {
|
|
8
|
-
super(props);
|
|
9
|
-
|
|
10
|
-
this.state = {isVerified: false};
|
|
11
|
-
this.captcha = React.createRef();
|
|
12
|
-
|
|
13
|
-
this.handleChange = this.handleChange.bind(this);
|
|
14
|
-
this.handleReset = this.handleReset.bind(this);
|
|
15
|
-
this.onVerifyCaptcha = this.onVerifyCaptcha.bind(this);
|
|
16
|
-
// Leave languageOverride unset or null for browser autodetection.
|
|
17
|
-
// To force a language, use the code: https://hcaptcha.com/docs/languages
|
|
18
|
-
this.languageOverride = null; // "fr";
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
handleChange(event) {
|
|
22
|
-
this.setState({isVerified: true});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
onVerifyCaptcha (token) {
|
|
26
|
-
console.log("Verified: " + token);
|
|
27
|
-
this.setState({isVerified: true})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
handleSubmit(event) {
|
|
31
|
-
event.preventDefault()
|
|
32
|
-
this.child.execute()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
handleReset(event) {
|
|
36
|
-
event.preventDefault()
|
|
37
|
-
this.captcha.current.resetCaptcha()
|
|
38
|
-
this.setState({isVerified: false})
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
render() {
|
|
42
|
-
const { isVerified } = this.state;
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<div>
|
|
46
|
-
<p>
|
|
47
|
-
Set your sitekey and onVerify callback as props, and drop into your form. From here, we'll take care of the rest.
|
|
48
|
-
</p>
|
|
49
|
-
<div>
|
|
50
|
-
<HCaptcha ref={this.captcha} onVerify={this.onVerifyCaptcha} languageOverride={this.languageOverride}
|
|
51
|
-
sitekey="917ba1eb-0b37-486e-9c90-39f3cb7b2579"
|
|
52
|
-
theme="light"
|
|
53
|
-
/>
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<div>
|
|
57
|
-
<HCaptcha ref={this.captcha} onVerify={this.onVerifyCaptcha} languageOverride={this.languageOverride}
|
|
58
|
-
sitekey="917ba1eb-0b37-486e-9c90-39f3cb7b2579"
|
|
59
|
-
theme="dark"
|
|
60
|
-
/>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<div>
|
|
64
|
-
<HCaptcha ref={this.captcha} onVerify={this.onVerifyCaptcha} languageOverride={this.languageOverride}
|
|
65
|
-
sitekey="917ba1eb-0b37-486e-9c90-39f3cb7b2579"
|
|
66
|
-
size="compact"
|
|
67
|
-
theme="dark"
|
|
68
|
-
/>
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
{isVerified &&
|
|
72
|
-
<div>
|
|
73
|
-
<p>Open your console to see the Verified response.</p>
|
|
74
|
-
<button onClick={this.handleReset}>Reset Captcha</button>
|
|
75
|
-
</div>
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
render(
|
|
84
|
-
<div>
|
|
85
|
-
<h1>HCaptcha React Demo</h1>
|
|
86
|
-
<ReactDemo/>
|
|
87
|
-
</div>,
|
|
88
|
-
document.getElementById('app')
|
|
89
|
-
);
|
package/jest.config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
// For a detailed explanation regarding each configuration property, visit:
|
|
4
|
-
// https://jestjs.io/docs/en/configuration.html
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
// Automatically clear mock calls and instances between every test
|
|
8
|
-
clearMocks: true,
|
|
9
|
-
|
|
10
|
-
// The glob patterns Jest uses to detect test files
|
|
11
|
-
testMatch: ["**/?(*.)+(spec|test).js?(x)"],
|
|
12
|
-
|
|
13
|
-
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
|
|
14
|
-
testPathIgnorePatterns: ["/node_modules/", "webpack.config.test.js"],
|
|
15
|
-
};
|
package/tests/hcaptcha.mock.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export const MOCK_WIDGET_ID = 'mock-widget-id';
|
|
2
|
-
export const MOCK_TOKEN = 'mock-token';
|
|
3
|
-
export const MOCK_EKEY = 'mock-ekey';
|
|
4
|
-
|
|
5
|
-
/*global jest*/
|
|
6
|
-
|
|
7
|
-
export function getMockedHcaptcha() {
|
|
8
|
-
return {
|
|
9
|
-
// eslint-disable-next-line no-unused-vars
|
|
10
|
-
setData: jest.fn((id, data) => {}),
|
|
11
|
-
// eslint-disable-next-line no-unused-vars
|
|
12
|
-
render: jest.fn((container, opt) => MOCK_WIDGET_ID),
|
|
13
|
-
getResponse: jest.fn(() => MOCK_TOKEN),
|
|
14
|
-
getRespKey: jest.fn(() => MOCK_EKEY),
|
|
15
|
-
reset: jest.fn(),
|
|
16
|
-
execute: jest.fn(),
|
|
17
|
-
remove: jest.fn(),
|
|
18
|
-
};
|
|
19
|
-
}
|
package/tests/hcaptcha.spec.js
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import ReactDOM from "react-dom";
|
|
3
|
-
import ReactTestUtils, { act } from "react-dom/test-utils";
|
|
4
|
-
import HCaptcha from "../src/index";
|
|
5
|
-
import {getMockedHcaptcha, MOCK_EKEY, MOCK_TOKEN, MOCK_WIDGET_ID} from "./hcaptcha.mock";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const TEST_PROPS = {
|
|
9
|
-
sitekey: "10000000-ffff-ffff-ffff-000000000001",
|
|
10
|
-
theme: "light",
|
|
11
|
-
size: "invisible",
|
|
12
|
-
tabindex: 0,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
describe("hCaptcha", () => {
|
|
16
|
-
let instance;
|
|
17
|
-
let mockFns;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
mockFns = {
|
|
21
|
-
onChange: jest.fn(),
|
|
22
|
-
onVerify: jest.fn(),
|
|
23
|
-
onError: jest.fn(),
|
|
24
|
-
onExpire: jest.fn(),
|
|
25
|
-
};
|
|
26
|
-
window.hcaptcha = getMockedHcaptcha();
|
|
27
|
-
instance = ReactTestUtils.renderIntoDocument(
|
|
28
|
-
<HCaptcha
|
|
29
|
-
sitekey={TEST_PROPS.sitekey}
|
|
30
|
-
theme={TEST_PROPS.theme}
|
|
31
|
-
size={TEST_PROPS.size}
|
|
32
|
-
tabindex={TEST_PROPS.tabindex}
|
|
33
|
-
onChange={mockFns.onChange}
|
|
34
|
-
onVerify={mockFns.onVerify}
|
|
35
|
-
onError={mockFns.onError}
|
|
36
|
-
onExpire={mockFns.onExpire}
|
|
37
|
-
/>,
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("renders into a div", () => {
|
|
42
|
-
expect(ReactDOM.findDOMNode(instance).nodeName).toBe("DIV");
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("has functions", () => {
|
|
46
|
-
expect(typeof instance.execute).toBe("function");
|
|
47
|
-
expect(typeof instance.resetCaptcha).toBe("function");
|
|
48
|
-
expect(instance.execute).toBeDefined();
|
|
49
|
-
expect(instance.resetCaptcha).toBeDefined();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("can execute", () => {
|
|
53
|
-
expect(window.hcaptcha.execute.mock.calls.length).toBe(0);
|
|
54
|
-
instance.execute();
|
|
55
|
-
expect(window.hcaptcha.execute.mock.calls.length).toBe(1);
|
|
56
|
-
expect(window.hcaptcha.execute.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("can reset", () => {
|
|
60
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(0);
|
|
61
|
-
instance.resetCaptcha();
|
|
62
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(1);
|
|
63
|
-
expect(window.hcaptcha.reset.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("can remove", () => {
|
|
67
|
-
expect(window.hcaptcha.remove.mock.calls.length).toBe(0);
|
|
68
|
-
instance.removeCaptcha();
|
|
69
|
-
expect(window.hcaptcha.remove.mock.calls.length).toBe(1);
|
|
70
|
-
expect(window.hcaptcha.remove.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("emits verify with token and eKey", () => {
|
|
74
|
-
expect(mockFns.onVerify.mock.calls.length).toBe(0);
|
|
75
|
-
instance.handleSubmit();
|
|
76
|
-
expect(mockFns.onVerify.mock.calls.length).toBe(1);
|
|
77
|
-
expect(mockFns.onVerify.mock.calls[0][0]).toBe(MOCK_TOKEN);
|
|
78
|
-
expect(mockFns.onVerify.mock.calls[0][1]).toBe(MOCK_EKEY);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("emits error and calls reset", () => {
|
|
82
|
-
expect(mockFns.onError.mock.calls.length).toBe(0);
|
|
83
|
-
const error = "invalid-input-response";
|
|
84
|
-
instance.handleError(error);
|
|
85
|
-
expect(mockFns.onError.mock.calls.length).toBe(1);
|
|
86
|
-
expect(mockFns.onError.mock.calls[0][0]).toBe(error);
|
|
87
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(1);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("emits expire and calls reset", () => {
|
|
91
|
-
expect(mockFns.onExpire.mock.calls.length).toBe(0);
|
|
92
|
-
instance.handleExpire();
|
|
93
|
-
expect(mockFns.onExpire.mock.calls.length).toBe(1);
|
|
94
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(1);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("el renders after api loads and a widget id is set", () => {
|
|
98
|
-
expect(instance.state.captchaId).toBe(MOCK_WIDGET_ID);
|
|
99
|
-
expect(window.hcaptcha.render.mock.calls.length).toBe(1);
|
|
100
|
-
expect(window.hcaptcha.render.mock.calls[0][1]).toMatchObject({
|
|
101
|
-
sitekey: TEST_PROPS.sitekey,
|
|
102
|
-
theme: TEST_PROPS.theme,
|
|
103
|
-
size: TEST_PROPS.size,
|
|
104
|
-
tabindex: TEST_PROPS.tabindex
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it("should set id if id prop is passed", () => {
|
|
109
|
-
instance = ReactTestUtils.renderIntoDocument(
|
|
110
|
-
<HCaptcha
|
|
111
|
-
sitekey={TEST_PROPS.sitekey}
|
|
112
|
-
id="test-id-1"
|
|
113
|
-
/>,
|
|
114
|
-
);
|
|
115
|
-
const node = ReactDOM.findDOMNode(instance);
|
|
116
|
-
expect(node.getAttribute("id")).toBe("test-id-1");
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("should not set id if no id prop is passed", () => {
|
|
120
|
-
process.env.NODE_ENV = "development";
|
|
121
|
-
instance = ReactTestUtils.renderIntoDocument(
|
|
122
|
-
<HCaptcha
|
|
123
|
-
sitekey={TEST_PROPS.sitekey}
|
|
124
|
-
/>,
|
|
125
|
-
);
|
|
126
|
-
const node = ReactDOM.findDOMNode(instance);
|
|
127
|
-
expect(node.getAttribute("id")).toBe(null);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe("Query parameter", () => {
|
|
131
|
-
|
|
132
|
-
beforeEach(() => {
|
|
133
|
-
// Setup hCaptcha as undefined to load script
|
|
134
|
-
window.hcaptcha = undefined;
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
afterEach(() => {
|
|
138
|
-
// Clean up created script tag
|
|
139
|
-
document.querySelectorAll("head > script")
|
|
140
|
-
.forEach(script => document.head.removeChild(script));
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it("validate src without", () => {
|
|
144
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
145
|
-
sitekey={TEST_PROPS.sitekey}
|
|
146
|
-
/>);
|
|
147
|
-
|
|
148
|
-
const script = document.querySelector("head > script");
|
|
149
|
-
expect(script.src).toEqual("https://hcaptcha.com/1/api.js?render=explicit&onload=hcaptchaOnLoad");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("apihost should change script src, but not be added as query", () => {
|
|
153
|
-
const ExpectHost = "https://test.com";
|
|
154
|
-
|
|
155
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
156
|
-
apihost={ExpectHost}
|
|
157
|
-
sitekey={TEST_PROPS.sitekey}
|
|
158
|
-
/>);
|
|
159
|
-
|
|
160
|
-
const script = document.querySelector("head > script");
|
|
161
|
-
expect(script.src).toContain(ExpectHost);
|
|
162
|
-
expect(script.src).not.toContain(`apihost=${encodeURIComponent(ExpectHost)}`);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("assethost should be found when prop is set", () => {
|
|
166
|
-
const ExpectHost = "https://test.com";
|
|
167
|
-
|
|
168
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
169
|
-
assethost={ExpectHost}
|
|
170
|
-
sitekey={TEST_PROPS.sitekey}
|
|
171
|
-
/>);
|
|
172
|
-
|
|
173
|
-
const script = document.querySelector("head > script");
|
|
174
|
-
expect(script.src).toContain(`assethost=${encodeURIComponent(ExpectHost)}`);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it("endpoint should be found when prop is set", () => {
|
|
178
|
-
const ExpectHost = "https://test.com";
|
|
179
|
-
|
|
180
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
181
|
-
endpoint={ExpectHost}
|
|
182
|
-
sitekey={TEST_PROPS.sitekey}
|
|
183
|
-
/>);
|
|
184
|
-
|
|
185
|
-
const script = document.querySelector("head > script");
|
|
186
|
-
expect(script.src).toContain(`endpoint=${encodeURIComponent(ExpectHost)}`);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it("imghost should be found when prop is set", () => {
|
|
190
|
-
const ExpectHost = "https://test.com";
|
|
191
|
-
|
|
192
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
193
|
-
imghost={ExpectHost}
|
|
194
|
-
sitekey={TEST_PROPS.sitekey}
|
|
195
|
-
/>);
|
|
196
|
-
|
|
197
|
-
const script = document.querySelector("head > script");
|
|
198
|
-
expect(script.src).toContain(`imghost=${encodeURIComponent(ExpectHost)}`);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("reportapi should be found when prop is set", () => {
|
|
202
|
-
const ExpectHost = "https://test.com";
|
|
203
|
-
|
|
204
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
205
|
-
reportapi={ExpectHost}
|
|
206
|
-
sitekey={TEST_PROPS.sitekey}
|
|
207
|
-
/>);
|
|
208
|
-
|
|
209
|
-
const script = document.querySelector("head > script");
|
|
210
|
-
expect(script.src).toContain(`reportapi=${encodeURIComponent(ExpectHost)}`);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it("hl should be found when prop languageOverride is set", () => {
|
|
214
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
215
|
-
languageOverride="fr"
|
|
216
|
-
sitekey={TEST_PROPS.sitekey}
|
|
217
|
-
/>);
|
|
218
|
-
|
|
219
|
-
const script = document.querySelector("head > script");
|
|
220
|
-
expect(script.src).toContain("hl=fr");
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it("reCaptchaCompat should be found when prop is set to false", () => {
|
|
224
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
225
|
-
reCaptchaCompat={false}
|
|
226
|
-
sitekey={TEST_PROPS.sitekey}
|
|
227
|
-
/>);
|
|
228
|
-
|
|
229
|
-
const script = document.querySelector("head > script");
|
|
230
|
-
expect(script.src).toContain("recaptchacompat=off");
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it("reCaptchaCompat should not be found when prop is set to anything except false", () => {
|
|
234
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
235
|
-
reCaptchaCompat={true}
|
|
236
|
-
sitekey={TEST_PROPS.sitekey}
|
|
237
|
-
/>);
|
|
238
|
-
|
|
239
|
-
const script = document.querySelector("head > script");
|
|
240
|
-
expect(script.src).not.toContain("recaptchacompat");
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it("sentry should be found when prop is set", () => {
|
|
244
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
245
|
-
sentry={true}
|
|
246
|
-
sitekey={TEST_PROPS.sitekey}
|
|
247
|
-
/>);
|
|
248
|
-
|
|
249
|
-
const script = document.querySelector("head > script");
|
|
250
|
-
expect(script.src).toContain("sentry=true");
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
it("host should be found when prop is set", () => {
|
|
254
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
255
|
-
host="test.com"
|
|
256
|
-
sitekey={TEST_PROPS.sitekey}
|
|
257
|
-
/>);
|
|
258
|
-
|
|
259
|
-
const script = document.querySelector("head > script");
|
|
260
|
-
expect(script.src).toContain("host=test.com");
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
});
|
package/tests/utils.test.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { generateQuery } from "../src/utils.js";
|
|
2
|
-
|
|
3
|
-
describe("Encode query", () => {
|
|
4
|
-
|
|
5
|
-
it("Property foo to equal bar as string foo=bar:", () => {
|
|
6
|
-
const params = {
|
|
7
|
-
foo: "bar"
|
|
8
|
-
};
|
|
9
|
-
expect(generateQuery(params)).toBe("foo=bar");
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it("Spaces to be encoded with %20", () => {
|
|
13
|
-
const params = {
|
|
14
|
-
foo: "bar baz bah"
|
|
15
|
-
};
|
|
16
|
-
expect(generateQuery(params)).toBe("foo=bar%20baz%20bah");
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("Chain multiple parameters", () => {
|
|
20
|
-
const params = {
|
|
21
|
-
foo: "bar",
|
|
22
|
-
baz: true
|
|
23
|
-
};
|
|
24
|
-
expect(generateQuery(params)).toBe("foo=bar&baz=true");
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("false should be a valid query value", () => {
|
|
28
|
-
const params = {
|
|
29
|
-
foo: false
|
|
30
|
-
};
|
|
31
|
-
expect(generateQuery(params)).toBe("foo=false");
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("Null, undefined, and empty string values should be removed", () => {
|
|
35
|
-
const params = {
|
|
36
|
-
foo: "",
|
|
37
|
-
bar: null,
|
|
38
|
-
baz: undefined,
|
|
39
|
-
bah: true
|
|
40
|
-
};
|
|
41
|
-
expect(generateQuery(params)).toBe("bah=true");
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
});
|
package/webpack.config.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// NPM Modules
|
|
2
|
-
const Webpack = require('webpack');
|
|
3
|
-
const Path = require('path');
|
|
4
|
-
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
|
5
|
-
|
|
6
|
-
// Webpack Plugins
|
|
7
|
-
const htmlPlugin = new HtmlWebpackPlugin({
|
|
8
|
-
template: Path.join(__dirname, "./examples/src/index.html"),
|
|
9
|
-
filename: "./index.html"
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
module.exports = {
|
|
13
|
-
entry: Path.join(__dirname, "./examples/src/index.js"),
|
|
14
|
-
|
|
15
|
-
module: {
|
|
16
|
-
rules: [
|
|
17
|
-
{
|
|
18
|
-
test: /\.(js|jsx)$/,
|
|
19
|
-
exclude: /node_modules/,
|
|
20
|
-
use: ['babel-loader']
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
resolve: {
|
|
26
|
-
extensions: ['*', '.js', '.jsx']
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
output: {
|
|
30
|
-
path: __dirname + '/dist',
|
|
31
|
-
publicPath: '/',
|
|
32
|
-
filename: 'bundle.js'
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
plugins: [
|
|
36
|
-
htmlPlugin
|
|
37
|
-
],
|
|
38
|
-
|
|
39
|
-
devServer: {
|
|
40
|
-
port: 9000
|
|
41
|
-
}
|
|
42
|
-
};
|