@hcaptcha/react-hcaptcha 0.3.7 → 1.0.0

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 CHANGED
@@ -47,12 +47,71 @@ import { default as RenamedCaptcha } from '../utils/captcha';
47
47
  </FormComponent>
48
48
  ```
49
49
 
50
+ #### Programmatic Usage
51
+ In the event you want to call the hCaptcha client API directly, you can do so by using the hook `useRef` and waiting for `onLoad` to be called. By waiting for `onLoad` the hCaptcha API will be ready and the hCaptcha client will have been setup. See the following example:
52
+
53
+ ```js
54
+ import { useEffect, useRef, useState } from "react";
55
+ import HCaptcha from "@hcaptcha/react-hcaptcha";
56
+
57
+ export default function Form() {
58
+ const [token, setToken] = useState(null);
59
+ const captchaRef = useRef(null);
60
+
61
+ const onLoad = () => {
62
+ // this reaches out to the hCaptcha JS API and runs the
63
+ // execute function on it. you can use other functions as
64
+ // documented here:
65
+ // https://docs.hcaptcha.com/configuration#jsapi
66
+ captchaRef.current.execute();
67
+ };
68
+
69
+ useEffect(() => {
70
+
71
+ if (token)
72
+ console.log(`hCaptcha Token: ${token}`);
73
+
74
+ }, [token]);
75
+
76
+ return (
77
+ <form>
78
+ <HCaptcha
79
+ sitekey="your-sitekey"
80
+ onLoad={onLoad}
81
+ onVerify={setToken}
82
+ ref={captchaRef}
83
+ />
84
+ </form>
85
+ );
86
+ }
87
+ ```
88
+
50
89
  #### Advanced usage
51
90
 
52
91
  In most real-world implementations, you'll probably be using a form library such as [Formik](https://github.com/jaredpalmer/formik) or [React Hook Form](https://github.com/react-hook-form/react-hook-form).
53
92
 
54
93
  In these instances, you'll most likely want to use `ref` to handle the callbacks as well as handle field-level validation of a `captcha` field. For an example of this, you can view this [CodeSandbox](https://codesandbox.io/s/react-hcaptchaform-example-forked-ngxge?file=/src/Form.jsx). This `ref` will point to an instance of the [hCaptcha API](https://docs.hcaptcha.com/configuration#jsapi) where can you interact directly with it.
55
94
 
95
+ #### Passing in fields like `rqdata` to `execute()`
96
+
97
+ Passing an object into the `execute(yourObj)` call will send it through to the underlying JS API. This enables support for Enterprise features like `rqdata`. A simple example is below:
98
+
99
+ ```
100
+ const {sitekey, rqdata} = props;
101
+ const captchaRef = React.useRef<HCaptcha>(null);
102
+
103
+ const onLoad = () => {
104
+ const executePayload = {};
105
+ if (rqdata) {
106
+ executePayload['rqdata'] = rqdata;
107
+ }
108
+ captchaRef.current?.execute(executePayload);
109
+ };
110
+
111
+ return <HCaptcha ref={captchaRef} onLoad={onLoad} sitekey={sitekey} {...props} />;
112
+ ```
113
+
114
+
56
115
  ### Props
57
116
 
58
117
  |Name|Values/Type|Required|Default|Description|
@@ -86,7 +145,7 @@ In these instances, you'll most likely want to use `ref` to handle the callbacks
86
145
 
87
146
  |Method|Description|
88
147
  |---|---|
89
- |`execute()`|Programmatically trigger a challenge request|
148
+ |`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.|
90
149
  |`resetCaptcha()`|Reset the current challenge|
91
150
 
92
151
 
package/dist/index.js CHANGED
@@ -1,33 +1,25 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
- 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; }
5
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
6
6
 
7
- 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) { _defineProperty(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; }
7
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
8
8
 
9
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
 
11
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11
+ var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
12
12
 
13
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
13
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
14
14
 
15
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
15
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
16
16
 
17
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
17
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
18
18
 
19
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
20
-
21
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22
-
23
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
24
-
25
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
19
+ 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
20
 
27
21
  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
22
 
29
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
30
-
31
23
  var React = require('react');
32
24
 
33
25
  var _require = require("./utils.js"),
@@ -49,7 +41,7 @@ var mountCaptchaScript = function mountCaptchaScript() {
49
41
  });
50
42
  };
51
43
 
52
- var domain = params.apihost || "https://hcaptcha.com";
44
+ var domain = params.apihost || "https://js.hcaptcha.com";
53
45
  delete params.apihost;
54
46
  var script = document.createElement("script");
55
47
  script.src = "".concat(domain, "/1/api.js?render=explicit&onload=hcaptchaOnLoad");
@@ -60,25 +52,24 @@ var mountCaptchaScript = function mountCaptchaScript() {
60
52
  };
61
53
 
62
54
  var HCaptcha = /*#__PURE__*/function (_React$Component) {
63
- _inherits(HCaptcha, _React$Component);
55
+ (0, _inherits2["default"])(HCaptcha, _React$Component);
64
56
 
65
57
  var _super = _createSuper(HCaptcha);
66
58
 
67
59
  function HCaptcha(props) {
68
60
  var _this;
69
61
 
70
- _classCallCheck(this, HCaptcha);
71
-
62
+ (0, _classCallCheck2["default"])(this, HCaptcha);
72
63
  _this = _super.call(this, props); // API Methods
73
64
 
74
- _this.renderCaptcha = _this.renderCaptcha.bind(_assertThisInitialized(_this));
75
- _this.resetCaptcha = _this.resetCaptcha.bind(_assertThisInitialized(_this));
76
- _this.removeCaptcha = _this.removeCaptcha.bind(_assertThisInitialized(_this)); // Event Handlers
65
+ _this.renderCaptcha = _this.renderCaptcha.bind((0, _assertThisInitialized2["default"])(_this));
66
+ _this.resetCaptcha = _this.resetCaptcha.bind((0, _assertThisInitialized2["default"])(_this));
67
+ _this.removeCaptcha = _this.removeCaptcha.bind((0, _assertThisInitialized2["default"])(_this)); // Event Handlers
77
68
 
78
- _this.handleOnLoad = _this.handleOnLoad.bind(_assertThisInitialized(_this));
79
- _this.handleSubmit = _this.handleSubmit.bind(_assertThisInitialized(_this));
80
- _this.handleExpire = _this.handleExpire.bind(_assertThisInitialized(_this));
81
- _this.handleError = _this.handleError.bind(_assertThisInitialized(_this));
69
+ _this.handleOnLoad = _this.handleOnLoad.bind((0, _assertThisInitialized2["default"])(_this));
70
+ _this.handleSubmit = _this.handleSubmit.bind((0, _assertThisInitialized2["default"])(_this));
71
+ _this.handleExpire = _this.handleExpire.bind((0, _assertThisInitialized2["default"])(_this));
72
+ _this.handleError = _this.handleError.bind((0, _assertThisInitialized2["default"])(_this));
82
73
  var isApiReady = typeof hcaptcha !== 'undefined';
83
74
  _this.ref = React.createRef();
84
75
  _this.state = {
@@ -90,7 +81,7 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
90
81
  return _this;
91
82
  }
92
83
 
93
- _createClass(HCaptcha, [{
84
+ (0, _createClass2["default"])(HCaptcha, [{
94
85
  key: "componentDidMount",
95
86
  value: function componentDidMount() {
96
87
  //Once captcha is mounted intialize hCaptcha - hCaptcha
@@ -173,18 +164,24 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
173
164
  }
174
165
  }, {
175
166
  key: "renderCaptcha",
176
- value: function renderCaptcha() {
167
+ value: function renderCaptcha(onReady) {
177
168
  var isApiReady = this.state.isApiReady;
178
- if (!isApiReady) return; //Render hCaptcha widget and provide necessary callbacks - hCaptcha
179
-
180
- var captchaId = hcaptcha.render(this.ref.current, _objectSpread(_objectSpread({}, this.props), {}, {
169
+ if (!isApiReady) return;
170
+ var renderParams = Object.assign({
181
171
  "error-callback": this.handleError,
182
172
  "expired-callback": this.handleExpire,
183
173
  "callback": this.handleSubmit
184
- }));
174
+ }, this.props, {
175
+ hl: this.props.hl || this.props.languageOverride,
176
+ languageOverride: undefined
177
+ }); //Render hCaptcha widget and provide necessary callbacks - hCaptcha
178
+
179
+ var captchaId = hcaptcha.render(this.ref.current, renderParams);
185
180
  this.setState({
186
181
  isRemoved: false,
187
182
  captchaId: captchaId
183
+ }, function () {
184
+ onReady && onReady();
188
185
  });
189
186
  }
190
187
  }, {
@@ -221,11 +218,12 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
221
218
  this.setState({
222
219
  isApiReady: true
223
220
  }, function () {
224
- // trigger onLoad if it exists
225
- var onLoad = _this3.props.onLoad;
226
- if (onLoad) onLoad(); // render captcha
227
-
228
- _this3.renderCaptcha();
221
+ // render captcha and wait for captcha id
222
+ _this3.renderCaptcha(function () {
223
+ // trigger onLoad if it exists
224
+ var onLoad = _this3.props.onLoad;
225
+ if (onLoad) onLoad();
226
+ });
229
227
  });
230
228
  }
231
229
  }, {
@@ -271,12 +269,18 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
271
269
  }, {
272
270
  key: "execute",
273
271
  value: function execute() {
272
+ var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
274
273
  var _this$state7 = this.state,
275
274
  isApiReady = _this$state7.isApiReady,
276
275
  isRemoved = _this$state7.isRemoved,
277
276
  captchaId = _this$state7.captchaId;
278
277
  if (!isApiReady || isRemoved) return;
279
- hcaptcha.execute(captchaId);
278
+
279
+ if (opts && (0, _typeof2["default"])(opts) !== "object") {
280
+ opts = null;
281
+ }
282
+
283
+ return hcaptcha.execute(captchaId, opts);
280
284
  }
281
285
  }, {
282
286
  key: "render",
@@ -288,7 +292,6 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
288
292
  });
289
293
  }
290
294
  }]);
291
-
292
295
  return HCaptcha;
293
296
  }(React.Component);
294
297
 
package/dist/utils.js CHANGED
@@ -1,26 +1,18 @@
1
1
  "use strict";
2
2
 
3
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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 = _slicedToArray(_ref, 2),
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 = _slicedToArray(_ref3, 2),
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@hcaptcha/react-hcaptcha",
3
- "version": "0.3.7",
3
+ "version": "1.0.0",
4
4
  "types": "types/index.d.ts",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -12,6 +12,7 @@
12
12
  "scripts": {
13
13
  "start": "webpack-dev-server --config ./webpack.config.js --mode development",
14
14
  "test": "jest",
15
+ "watch": "babel src -d dist --copy-files --watch",
15
16
  "transpile": "babel src -d dist --copy-files",
16
17
  "build": "npm run transpile",
17
18
  "prepublishOnly": "npm run transpile"
@@ -31,6 +32,7 @@
31
32
  "devDependencies": {
32
33
  "@babel/cli": "^7.12.10",
33
34
  "@babel/core": "^7.12.10",
35
+ "@babel/plugin-transform-runtime": "^7.14.5",
34
36
  "@babel/preset-env": "^7.12.11",
35
37
  "@babel/preset-react": "^7.12.10",
36
38
  "babel-loader": "^8.2.2",
package/src/index.js CHANGED
@@ -17,7 +17,7 @@ const mountCaptchaScript = (params={}) => {
17
17
  });
18
18
  };
19
19
 
20
- const domain = params.apihost || "https://hcaptcha.com";
20
+ const domain = params.apihost || "https://js.hcaptcha.com";
21
21
  delete params.apihost;
22
22
 
23
23
  const script = document.createElement("script");
@@ -119,20 +119,25 @@ class HCaptcha extends React.Component {
119
119
  }
120
120
  }
121
121
 
122
- renderCaptcha() {
122
+ renderCaptcha(onReady) {
123
123
  const { isApiReady } = this.state;
124
124
  if (!isApiReady) return;
125
125
 
126
+ const renderParams = Object.assign({
127
+ "error-callback" : this.handleError,
128
+ "expired-callback" : this.handleExpire,
129
+ "callback" : this.handleSubmit,
130
+ }, this.props, {
131
+ hl: this.props.hl || this.props.languageOverride,
132
+ languageOverride: undefined
133
+ });
134
+
126
135
  //Render hCaptcha widget and provide necessary callbacks - hCaptcha
127
- const captchaId = hcaptcha.render(this.ref.current,
128
- {
129
- ...this.props,
130
- "error-callback" : this.handleError,
131
- "expired-callback": this.handleExpire,
132
- "callback" : this.handleSubmit
133
- });
136
+ const captchaId = hcaptcha.render(this.ref.current, renderParams);
134
137
 
135
- this.setState({ isRemoved: false, captchaId });
138
+ this.setState({ isRemoved: false, captchaId }, () => {
139
+ onReady && onReady();
140
+ });
136
141
  }
137
142
 
138
143
  resetCaptcha() {
@@ -156,12 +161,13 @@ class HCaptcha extends React.Component {
156
161
 
157
162
  handleOnLoad () {
158
163
  this.setState({ isApiReady: true }, () => {
159
- // trigger onLoad if it exists
160
- const { onLoad } = this.props;
161
- if (onLoad) onLoad();
162
164
 
163
- // render captcha
164
- this.renderCaptcha();
165
+ // render captcha and wait for captcha id
166
+ this.renderCaptcha(() => {
167
+ // trigger onLoad if it exists
168
+ const { onLoad } = this.props;
169
+ if (onLoad) onLoad();
170
+ });
165
171
  });
166
172
  }
167
173
 
@@ -196,12 +202,16 @@ class HCaptcha extends React.Component {
196
202
  if (onError) onError(event);
197
203
  }
198
204
 
199
- execute () {
205
+ execute (opts = null) {
200
206
  const { isApiReady, isRemoved, captchaId } = this.state;
201
207
 
202
- if (!isApiReady || isRemoved) return
208
+ if (!isApiReady || isRemoved) return;
209
+
210
+ if (opts && typeof opts !== "object") {
211
+ opts = null;
212
+ }
203
213
 
204
- hcaptcha.execute(captchaId)
214
+ return hcaptcha.execute(captchaId, opts);
205
215
  }
206
216
 
207
217
  render () {
package/types/index.d.ts CHANGED
@@ -27,11 +27,18 @@ interface HCaptchaProps {
27
27
  reCaptchaCompat?: boolean;
28
28
  }
29
29
 
30
+ interface ExecuteResponse {
31
+ response: string;
32
+ key: string;
33
+ }
34
+
30
35
  declare class HCaptcha extends React.Component<HCaptchaProps, HCaptchaState> {
31
36
  resetCaptcha(): void;
32
37
  renderCaptcha(): void;
33
38
  removeCaptcha(): void;
34
- execute(): void;
39
+ execute(opts: { async: true }): Promise<ExecuteResponse>
40
+ execute(opts?: { async: false }): void;
41
+ execute(opts?: { async: boolean }): Promise<ExecuteResponse> | void;
35
42
  }
36
43
 
37
44
  export = HCaptcha;