@hcaptcha/react-hcaptcha 0.3.5 → 0.3.9
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 -31
- package/dist/utils.js +4 -12
- package/package.json +10 -2
- package/src/index.js +24 -11
- 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 -281
- 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"),
|
|
@@ -60,25 +58,24 @@ var mountCaptchaScript = function mountCaptchaScript() {
|
|
|
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
80
|
_this.ref = React.createRef();
|
|
84
81
|
_this.state = {
|
|
@@ -90,7 +87,7 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
90
87
|
return _this;
|
|
91
88
|
}
|
|
92
89
|
|
|
93
|
-
|
|
90
|
+
(0, _createClass2["default"])(HCaptcha, [{
|
|
94
91
|
key: "componentDidMount",
|
|
95
92
|
value: function componentDidMount() {
|
|
96
93
|
//Once captcha is mounted intialize hCaptcha - hCaptcha
|
|
@@ -103,7 +100,8 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
103
100
|
hl = _this$props.languageOverride,
|
|
104
101
|
reCaptchaCompat = _this$props.reCaptchaCompat,
|
|
105
102
|
reportapi = _this$props.reportapi,
|
|
106
|
-
sentry = _this$props.sentry
|
|
103
|
+
sentry = _this$props.sentry,
|
|
104
|
+
custom = _this$props.custom;
|
|
107
105
|
var isApiReady = this.state.isApiReady;
|
|
108
106
|
|
|
109
107
|
if (!isApiReady) {
|
|
@@ -119,7 +117,8 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
119
117
|
imghost: imghost,
|
|
120
118
|
recaptchacompat: reCaptchaCompat === false ? "off" : null,
|
|
121
119
|
reportapi: reportapi,
|
|
122
|
-
sentry: sentry
|
|
120
|
+
sentry: sentry,
|
|
121
|
+
custom: custom
|
|
123
122
|
});
|
|
124
123
|
} // Add onload callback to global onload listeners
|
|
125
124
|
|
|
@@ -171,7 +170,7 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
171
170
|
}
|
|
172
171
|
}, {
|
|
173
172
|
key: "renderCaptcha",
|
|
174
|
-
value: function renderCaptcha() {
|
|
173
|
+
value: function renderCaptcha(onReady) {
|
|
175
174
|
var isApiReady = this.state.isApiReady;
|
|
176
175
|
if (!isApiReady) return; //Render hCaptcha widget and provide necessary callbacks - hCaptcha
|
|
177
176
|
|
|
@@ -183,6 +182,8 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
183
182
|
this.setState({
|
|
184
183
|
isRemoved: false,
|
|
185
184
|
captchaId: captchaId
|
|
185
|
+
}, function () {
|
|
186
|
+
onReady && onReady();
|
|
186
187
|
});
|
|
187
188
|
}
|
|
188
189
|
}, {
|
|
@@ -219,7 +220,12 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
219
220
|
this.setState({
|
|
220
221
|
isApiReady: true
|
|
221
222
|
}, function () {
|
|
222
|
-
|
|
223
|
+
// render captcha and wait for captcha id
|
|
224
|
+
_this3.renderCaptcha(function () {
|
|
225
|
+
// trigger onLoad if it exists
|
|
226
|
+
var onLoad = _this3.props.onLoad;
|
|
227
|
+
if (onLoad) onLoad();
|
|
228
|
+
});
|
|
223
229
|
});
|
|
224
230
|
}
|
|
225
231
|
}, {
|
|
@@ -265,12 +271,18 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
265
271
|
}, {
|
|
266
272
|
key: "execute",
|
|
267
273
|
value: function execute() {
|
|
274
|
+
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
268
275
|
var _this$state7 = this.state,
|
|
269
276
|
isApiReady = _this$state7.isApiReady,
|
|
270
277
|
isRemoved = _this$state7.isRemoved,
|
|
271
278
|
captchaId = _this$state7.captchaId;
|
|
272
279
|
if (!isApiReady || isRemoved) return;
|
|
273
|
-
|
|
280
|
+
|
|
281
|
+
if (opts && (0, _typeof2["default"])(opts) !== "object") {
|
|
282
|
+
opts = null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return hcaptcha.execute(captchaId, opts);
|
|
274
286
|
}
|
|
275
287
|
}, {
|
|
276
288
|
key: "render",
|
|
@@ -282,7 +294,6 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
|
|
|
282
294
|
});
|
|
283
295
|
}
|
|
284
296
|
}]);
|
|
285
|
-
|
|
286
297
|
return HCaptcha;
|
|
287
298
|
}(React.Component);
|
|
288
299
|
|
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.9",
|
|
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
|
@@ -59,7 +59,7 @@ class HCaptcha extends React.Component {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
componentDidMount () { //Once captcha is mounted intialize hCaptcha - hCaptcha
|
|
62
|
-
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;
|
|
63
63
|
const { isApiReady } = this.state;
|
|
64
64
|
|
|
65
65
|
if (!isApiReady) { //Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
|
|
@@ -75,7 +75,8 @@ class HCaptcha extends React.Component {
|
|
|
75
75
|
imghost,
|
|
76
76
|
recaptchacompat: reCaptchaCompat === false? "off" : null,
|
|
77
77
|
reportapi,
|
|
78
|
-
sentry
|
|
78
|
+
sentry,
|
|
79
|
+
custom
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -118,7 +119,7 @@ class HCaptcha extends React.Component {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
renderCaptcha() {
|
|
122
|
+
renderCaptcha(onReady) {
|
|
122
123
|
const { isApiReady } = this.state;
|
|
123
124
|
if (!isApiReady) return;
|
|
124
125
|
|
|
@@ -126,12 +127,14 @@ class HCaptcha extends React.Component {
|
|
|
126
127
|
const captchaId = hcaptcha.render(this.ref.current,
|
|
127
128
|
{
|
|
128
129
|
...this.props,
|
|
129
|
-
"error-callback"
|
|
130
|
-
"expired-callback": this.handleExpire,
|
|
131
|
-
"callback"
|
|
130
|
+
"error-callback" : this.handleError,
|
|
131
|
+
"expired-callback" : this.handleExpire,
|
|
132
|
+
"callback" : this.handleSubmit,
|
|
132
133
|
});
|
|
133
134
|
|
|
134
|
-
this.setState({ isRemoved: false, captchaId })
|
|
135
|
+
this.setState({ isRemoved: false, captchaId }, () => {
|
|
136
|
+
onReady && onReady();
|
|
137
|
+
});
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
resetCaptcha() {
|
|
@@ -155,7 +158,13 @@ class HCaptcha extends React.Component {
|
|
|
155
158
|
|
|
156
159
|
handleOnLoad () {
|
|
157
160
|
this.setState({ isApiReady: true }, () => {
|
|
158
|
-
|
|
161
|
+
|
|
162
|
+
// render captcha and wait for captcha id
|
|
163
|
+
this.renderCaptcha(() => {
|
|
164
|
+
// trigger onLoad if it exists
|
|
165
|
+
const { onLoad } = this.props;
|
|
166
|
+
if (onLoad) onLoad();
|
|
167
|
+
});
|
|
159
168
|
});
|
|
160
169
|
}
|
|
161
170
|
|
|
@@ -190,12 +199,16 @@ class HCaptcha extends React.Component {
|
|
|
190
199
|
if (onError) onError(event);
|
|
191
200
|
}
|
|
192
201
|
|
|
193
|
-
execute () {
|
|
202
|
+
execute (opts = null) {
|
|
194
203
|
const { isApiReady, isRemoved, captchaId } = this.state;
|
|
195
204
|
|
|
196
|
-
if (!isApiReady || isRemoved) return
|
|
205
|
+
if (!isApiReady || isRemoved) return;
|
|
206
|
+
|
|
207
|
+
if (opts && typeof opts !== "object") {
|
|
208
|
+
opts = null;
|
|
209
|
+
}
|
|
197
210
|
|
|
198
|
-
hcaptcha.execute(captchaId)
|
|
211
|
+
return hcaptcha.execute(captchaId, opts);
|
|
199
212
|
}
|
|
200
213
|
|
|
201
214
|
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,281 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import ReactDOM from "react-dom";
|
|
3
|
-
import ReactTestUtils, { act } from "react-dom/test-utils";
|
|
4
|
-
import {getMockedHcaptcha, MOCK_EKEY, MOCK_TOKEN, MOCK_WIDGET_ID} from "./hcaptcha.mock";
|
|
5
|
-
|
|
6
|
-
let HCaptcha;
|
|
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
|
-
jest.isolateModules(() => {
|
|
21
|
-
// Use node's `require` because `jest.isolateModules` cannot be async to use it with `await import()`
|
|
22
|
-
HCaptcha = require('../src/index');
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
mockFns = {
|
|
26
|
-
onChange: jest.fn(),
|
|
27
|
-
onVerify: jest.fn(),
|
|
28
|
-
onError: jest.fn(),
|
|
29
|
-
onExpire: jest.fn(),
|
|
30
|
-
};
|
|
31
|
-
window.hcaptcha = getMockedHcaptcha();
|
|
32
|
-
instance = ReactTestUtils.renderIntoDocument(
|
|
33
|
-
<HCaptcha
|
|
34
|
-
sitekey={TEST_PROPS.sitekey}
|
|
35
|
-
theme={TEST_PROPS.theme}
|
|
36
|
-
size={TEST_PROPS.size}
|
|
37
|
-
tabindex={TEST_PROPS.tabindex}
|
|
38
|
-
onChange={mockFns.onChange}
|
|
39
|
-
onVerify={mockFns.onVerify}
|
|
40
|
-
onError={mockFns.onError}
|
|
41
|
-
onExpire={mockFns.onExpire}
|
|
42
|
-
/>,
|
|
43
|
-
);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("renders into a div", () => {
|
|
47
|
-
expect(ReactDOM.findDOMNode(instance).nodeName).toBe("DIV");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("has functions", () => {
|
|
51
|
-
expect(typeof instance.execute).toBe("function");
|
|
52
|
-
expect(typeof instance.resetCaptcha).toBe("function");
|
|
53
|
-
expect(instance.execute).toBeDefined();
|
|
54
|
-
expect(instance.resetCaptcha).toBeDefined();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("can execute", () => {
|
|
58
|
-
expect(window.hcaptcha.execute.mock.calls.length).toBe(0);
|
|
59
|
-
instance.execute();
|
|
60
|
-
expect(window.hcaptcha.execute.mock.calls.length).toBe(1);
|
|
61
|
-
expect(window.hcaptcha.execute.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("can reset", () => {
|
|
65
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(0);
|
|
66
|
-
instance.resetCaptcha();
|
|
67
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(1);
|
|
68
|
-
expect(window.hcaptcha.reset.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("can remove", () => {
|
|
72
|
-
expect(window.hcaptcha.remove.mock.calls.length).toBe(0);
|
|
73
|
-
instance.removeCaptcha();
|
|
74
|
-
expect(window.hcaptcha.remove.mock.calls.length).toBe(1);
|
|
75
|
-
expect(window.hcaptcha.remove.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("emits verify with token and eKey", () => {
|
|
79
|
-
expect(mockFns.onVerify.mock.calls.length).toBe(0);
|
|
80
|
-
instance.handleSubmit();
|
|
81
|
-
expect(mockFns.onVerify.mock.calls.length).toBe(1);
|
|
82
|
-
expect(mockFns.onVerify.mock.calls[0][0]).toBe(MOCK_TOKEN);
|
|
83
|
-
expect(mockFns.onVerify.mock.calls[0][1]).toBe(MOCK_EKEY);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("emits error and calls reset", () => {
|
|
87
|
-
expect(mockFns.onError.mock.calls.length).toBe(0);
|
|
88
|
-
const error = "invalid-input-response";
|
|
89
|
-
instance.handleError(error);
|
|
90
|
-
expect(mockFns.onError.mock.calls.length).toBe(1);
|
|
91
|
-
expect(mockFns.onError.mock.calls[0][0]).toBe(error);
|
|
92
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(1);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("emits expire and calls reset", () => {
|
|
96
|
-
expect(mockFns.onExpire.mock.calls.length).toBe(0);
|
|
97
|
-
instance.handleExpire();
|
|
98
|
-
expect(mockFns.onExpire.mock.calls.length).toBe(1);
|
|
99
|
-
expect(window.hcaptcha.reset.mock.calls.length).toBe(1);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("el renders after api loads and a widget id is set", () => {
|
|
103
|
-
expect(instance.state.captchaId).toBe(MOCK_WIDGET_ID);
|
|
104
|
-
expect(window.hcaptcha.render.mock.calls.length).toBe(1);
|
|
105
|
-
expect(window.hcaptcha.render.mock.calls[0][1]).toMatchObject({
|
|
106
|
-
sitekey: TEST_PROPS.sitekey,
|
|
107
|
-
theme: TEST_PROPS.theme,
|
|
108
|
-
size: TEST_PROPS.size,
|
|
109
|
-
tabindex: TEST_PROPS.tabindex
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("should set id if id prop is passed", () => {
|
|
114
|
-
instance = ReactTestUtils.renderIntoDocument(
|
|
115
|
-
<HCaptcha
|
|
116
|
-
sitekey={TEST_PROPS.sitekey}
|
|
117
|
-
id="test-id-1"
|
|
118
|
-
/>,
|
|
119
|
-
);
|
|
120
|
-
const node = ReactDOM.findDOMNode(instance);
|
|
121
|
-
expect(node.getAttribute("id")).toBe("test-id-1");
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("should not set id if no id prop is passed", () => {
|
|
125
|
-
process.env.NODE_ENV = "development";
|
|
126
|
-
instance = ReactTestUtils.renderIntoDocument(
|
|
127
|
-
<HCaptcha
|
|
128
|
-
sitekey={TEST_PROPS.sitekey}
|
|
129
|
-
/>,
|
|
130
|
-
);
|
|
131
|
-
const node = ReactDOM.findDOMNode(instance);
|
|
132
|
-
expect(node.getAttribute("id")).toBe(null);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
describe("Query parameter", () => {
|
|
136
|
-
|
|
137
|
-
beforeEach(() => {
|
|
138
|
-
// Setup hCaptcha as undefined to load script
|
|
139
|
-
window.hcaptcha = undefined;
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
afterEach(() => {
|
|
143
|
-
// Clean up created script tag
|
|
144
|
-
document.querySelectorAll("head > script")
|
|
145
|
-
.forEach(script => document.head.removeChild(script));
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("validate src without", () => {
|
|
149
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
150
|
-
sitekey={TEST_PROPS.sitekey}
|
|
151
|
-
/>);
|
|
152
|
-
|
|
153
|
-
const script = document.querySelector("head > script");
|
|
154
|
-
expect(script.src).toEqual("https://hcaptcha.com/1/api.js?render=explicit&onload=hcaptchaOnLoad");
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it("apihost should change script src, but not be added as query", () => {
|
|
158
|
-
const ExpectHost = "https://test.com";
|
|
159
|
-
|
|
160
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
161
|
-
apihost={ExpectHost}
|
|
162
|
-
sitekey={TEST_PROPS.sitekey}
|
|
163
|
-
/>);
|
|
164
|
-
|
|
165
|
-
const script = document.querySelector("head > script");
|
|
166
|
-
expect(script.src).toContain(ExpectHost);
|
|
167
|
-
expect(script.src).not.toContain(`apihost=${encodeURIComponent(ExpectHost)}`);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("assethost should be found when prop is set", () => {
|
|
171
|
-
const ExpectHost = "https://test.com";
|
|
172
|
-
|
|
173
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
174
|
-
assethost={ExpectHost}
|
|
175
|
-
sitekey={TEST_PROPS.sitekey}
|
|
176
|
-
/>);
|
|
177
|
-
|
|
178
|
-
const script = document.querySelector("head > script");
|
|
179
|
-
expect(script.src).toContain(`assethost=${encodeURIComponent(ExpectHost)}`);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("endpoint should be found when prop is set", () => {
|
|
183
|
-
const ExpectHost = "https://test.com";
|
|
184
|
-
|
|
185
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
186
|
-
endpoint={ExpectHost}
|
|
187
|
-
sitekey={TEST_PROPS.sitekey}
|
|
188
|
-
/>);
|
|
189
|
-
|
|
190
|
-
const script = document.querySelector("head > script");
|
|
191
|
-
expect(script.src).toContain(`endpoint=${encodeURIComponent(ExpectHost)}`);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it("imghost should be found when prop is set", () => {
|
|
195
|
-
const ExpectHost = "https://test.com";
|
|
196
|
-
|
|
197
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
198
|
-
imghost={ExpectHost}
|
|
199
|
-
sitekey={TEST_PROPS.sitekey}
|
|
200
|
-
/>);
|
|
201
|
-
|
|
202
|
-
const script = document.querySelector("head > script");
|
|
203
|
-
expect(script.src).toContain(`imghost=${encodeURIComponent(ExpectHost)}`);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it("reportapi should be found when prop is set", () => {
|
|
207
|
-
const ExpectHost = "https://test.com";
|
|
208
|
-
|
|
209
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
210
|
-
reportapi={ExpectHost}
|
|
211
|
-
sitekey={TEST_PROPS.sitekey}
|
|
212
|
-
/>);
|
|
213
|
-
|
|
214
|
-
const script = document.querySelector("head > script");
|
|
215
|
-
expect(script.src).toContain(`reportapi=${encodeURIComponent(ExpectHost)}`);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it("hl should be found when prop languageOverride is set", () => {
|
|
219
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
220
|
-
languageOverride="fr"
|
|
221
|
-
sitekey={TEST_PROPS.sitekey}
|
|
222
|
-
/>);
|
|
223
|
-
|
|
224
|
-
const script = document.querySelector("head > script");
|
|
225
|
-
expect(script.src).toContain("hl=fr");
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it("reCaptchaCompat should be found when prop is set to false", () => {
|
|
229
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
230
|
-
reCaptchaCompat={false}
|
|
231
|
-
sitekey={TEST_PROPS.sitekey}
|
|
232
|
-
/>);
|
|
233
|
-
|
|
234
|
-
const script = document.querySelector("head > script");
|
|
235
|
-
expect(script.src).toContain("recaptchacompat=off");
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it("reCaptchaCompat should not be found when prop is set to anything except false", () => {
|
|
239
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
240
|
-
reCaptchaCompat={true}
|
|
241
|
-
sitekey={TEST_PROPS.sitekey}
|
|
242
|
-
/>);
|
|
243
|
-
|
|
244
|
-
const script = document.querySelector("head > script");
|
|
245
|
-
expect(script.src).not.toContain("recaptchacompat");
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it("sentry should be found when prop is set", () => {
|
|
249
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
250
|
-
sentry={true}
|
|
251
|
-
sitekey={TEST_PROPS.sitekey}
|
|
252
|
-
/>);
|
|
253
|
-
|
|
254
|
-
const script = document.querySelector("head > script");
|
|
255
|
-
expect(script.src).toContain("sentry=true");
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it("host should be found when prop is set", () => {
|
|
259
|
-
instance = ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
260
|
-
host="test.com"
|
|
261
|
-
sitekey={TEST_PROPS.sitekey}
|
|
262
|
-
/>);
|
|
263
|
-
|
|
264
|
-
const script = document.querySelector("head > script");
|
|
265
|
-
expect(script.src).toContain("host=test.com");
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it("shouldn't create multiple scripts for multiple captchas", () => {
|
|
269
|
-
ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
270
|
-
sitekey={TEST_PROPS.sitekey}
|
|
271
|
-
/>);
|
|
272
|
-
ReactTestUtils.renderIntoDocument(<HCaptcha
|
|
273
|
-
sitekey={TEST_PROPS.sitekey}
|
|
274
|
-
/>);
|
|
275
|
-
|
|
276
|
-
const scripts = document.querySelectorAll("head > script");
|
|
277
|
-
|
|
278
|
-
expect(scripts.length).toBe(1);
|
|
279
|
-
})
|
|
280
|
-
});
|
|
281
|
-
});
|
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
|
-
};
|