UNPKG

@hcaptcha/react-hcaptcha

Version:
409 lines (398 loc) 15.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof3 = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var React = _interopRequireWildcard(require("react")); var _loader = require("@hcaptcha/loader"); var _utils = require("./utils.js"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } var HCaptcha = /*#__PURE__*/function (_React$Component) { (0, _inherits2["default"])(HCaptcha, _React$Component); function HCaptcha(props) { var _this; (0, _classCallCheck2["default"])(this, HCaptcha); _this = _callSuper(this, HCaptcha, [props]); /** * Internal reference to track hCaptcha API * * Required as window is relative to initialization in application * not where the script and iFrames have been loaded. */ _this._hcaptcha = undefined; // API Methods _this.renderCaptcha = _this.renderCaptcha.bind((0, _assertThisInitialized2["default"])(_this)); _this.resetCaptcha = _this.resetCaptcha.bind((0, _assertThisInitialized2["default"])(_this)); _this.removeCaptcha = _this.removeCaptcha.bind((0, _assertThisInitialized2["default"])(_this)); _this.isReady = _this.isReady.bind((0, _assertThisInitialized2["default"])(_this)); _this._onReady = null; // Event Handlers _this.loadCaptcha = _this.loadCaptcha.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleOnLoad = _this.handleOnLoad.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleSubmit = _this.handleSubmit.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleExpire = _this.handleExpire.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleError = _this.handleError.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleOpen = _this.handleOpen.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleClose = _this.handleClose.bind((0, _assertThisInitialized2["default"])(_this)); _this.handleChallengeExpired = _this.handleChallengeExpired.bind((0, _assertThisInitialized2["default"])(_this)); _this.ref = /*#__PURE__*/React.createRef(); _this.apiScriptRequested = false; _this.sentryHub = null; _this.captchaId = ''; _this.state = { isApiReady: false, isRemoved: false, elementId: props.id }; return _this; } (0, _createClass2["default"])(HCaptcha, [{ key: "componentDidMount", value: function componentDidMount() { var _this2 = this; // Once captcha is mounted intialize hCaptcha - hCaptcha var element = (0, _utils.getMountElement)(this.props.scriptLocation); var frame = (0, _utils.getFrame)(element); this._hcaptcha = frame.window.hcaptcha || undefined; var isApiReady = typeof this._hcaptcha !== 'undefined'; /* * Check if hCaptcha has already been loaded, * If Yes, render the captcha * If No, create script tag and wait to render the captcha */ if (isApiReady) { this.setState({ isApiReady: true }, function () { _this2.renderCaptcha(); }); return; } this.loadCaptcha(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { return; } // Reset any stored variables / timers when unmounting hcaptcha.reset(captchaId); hcaptcha.remove(captchaId); } }, { key: "shouldComponentUpdate", value: function shouldComponentUpdate(nextProps, nextState) { // Prevent component re-rendering when these internal state variables are updated if (this.state.isApiReady !== nextState.isApiReady || this.state.isRemoved !== nextState.isRemoved) { return false; } return true; } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var _this3 = this; // Prop Keys that could change var keys = ['sitekey', 'size', 'theme', 'tabindex', 'languageOverride', 'endpoint']; // See if any props changed during component update var match = keys.every(function (key) { return prevProps[key] === _this3.props[key]; }); // If they have changed, remove current captcha and render a new one if (!match) { this.removeCaptcha(function () { _this3.renderCaptcha(); }); } } }, { key: "loadCaptcha", value: function loadCaptcha() { if (this.apiScriptRequested) { return; } var _this$props = this.props, apihost = _this$props.apihost, assethost = _this$props.assethost, endpoint = _this$props.endpoint, host = _this$props.host, imghost = _this$props.imghost, hl = _this$props.languageOverride, reCaptchaCompat = _this$props.reCaptchaCompat, reportapi = _this$props.reportapi, sentry = _this$props.sentry, custom = _this$props.custom, loadAsync = _this$props.loadAsync, scriptLocation = _this$props.scriptLocation, scriptSource = _this$props.scriptSource, secureApi = _this$props.secureApi, _this$props$cleanup = _this$props.cleanup, cleanup = _this$props$cleanup === void 0 ? true : _this$props$cleanup; var mountParams = { render: 'explicit', apihost: apihost, assethost: assethost, endpoint: endpoint, hl: hl, host: host, imghost: imghost, recaptchacompat: reCaptchaCompat === false ? 'off' : null, reportapi: reportapi, sentry: sentry, custom: custom, loadAsync: loadAsync, scriptLocation: scriptLocation, scriptSource: scriptSource, secureApi: secureApi, cleanup: cleanup }; (0, _loader.hCaptchaLoader)(mountParams).then(this.handleOnLoad, this.handleError)["catch"](this.handleError); this.apiScriptRequested = true; } }, { key: "renderCaptcha", value: function renderCaptcha(onRender) { var _this4 = this; var onReady = this.props.onReady; var isApiReady = this.state.isApiReady; var captchaId = this.captchaId; // Prevent calling hCaptcha render on two conditions: // • API is not ready // • Component has already been mounted if (!isApiReady || captchaId) return; var renderParams = Object.assign({ "open-callback": this.handleOpen, "close-callback": this.handleClose, "error-callback": this.handleError, "chalexpired-callback": this.handleChallengeExpired, "expired-callback": this.handleExpire, "callback": this.handleSubmit }, this.props, { hl: this.props.hl || this.props.languageOverride, languageOverride: undefined }); var hcaptcha = this._hcaptcha; //Render hCaptcha widget and provide necessary callbacks - hCaptcha var id = hcaptcha.render(this.ref.current, renderParams); this.captchaId = id; this.setState({ isRemoved: false }, function () { onRender && onRender(); onReady && onReady(); _this4._onReady && _this4._onReady(id); }); } }, { key: "resetCaptcha", value: function resetCaptcha() { var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { return; } // Reset captcha state, removes stored token and unticks checkbox hcaptcha.reset(captchaId); } }, { key: "removeCaptcha", value: function removeCaptcha(callback) { var _this5 = this; var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { return; } this.setState({ isRemoved: true }, function () { _this5.captchaId = ''; hcaptcha.remove(captchaId); callback && callback(); }); } }, { key: "handleOnLoad", value: function handleOnLoad() { var _this6 = this; this.setState({ isApiReady: true }, function () { var element = (0, _utils.getMountElement)(_this6.props.scriptLocation); var frame = (0, _utils.getFrame)(element); _this6._hcaptcha = frame.window.hcaptcha; // render captcha and wait for captcha id _this6.renderCaptcha(function () { // trigger onLoad if it exists var onLoad = _this6.props.onLoad; if (onLoad) onLoad(); }); }); } }, { key: "handleSubmit", value: function handleSubmit(event) { var onVerify = this.props.onVerify; var isRemoved = this.state.isRemoved; var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (typeof hcaptcha === 'undefined' || isRemoved) return; var token = hcaptcha.getResponse(captchaId); //Get response token from hCaptcha widget var ekey = hcaptcha.getRespKey(captchaId); //Get current challenge session id from hCaptcha widget if (onVerify) onVerify(token, ekey); //Dispatch event to verify user response } }, { key: "handleExpire", value: function handleExpire() { var onExpire = this.props.onExpire; var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { return; } hcaptcha.reset(captchaId); // If hCaptcha runs into error, reset captcha - hCaptcha if (onExpire) onExpire(); } }, { key: "handleError", value: function handleError(event) { var onError = this.props.onError; var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (this.isReady()) { // If hCaptcha runs into error, reset captcha - hCaptcha hcaptcha.reset(captchaId); } if (onError) onError(event); } }, { key: "isReady", value: function isReady() { var _this$state = this.state, isApiReady = _this$state.isApiReady, isRemoved = _this$state.isRemoved; return isApiReady && !isRemoved; } }, { key: "handleOpen", value: function handleOpen() { if (!this.isReady() || !this.props.onOpen) { return; } this.props.onOpen(); } }, { key: "handleClose", value: function handleClose() { if (!this.isReady() || !this.props.onClose) { return; } this.props.onClose(); } }, { key: "handleChallengeExpired", value: function handleChallengeExpired() { if (!this.isReady() || !this.props.onChalExpired) { return; } this.props.onChalExpired(); } }, { key: "execute", value: function execute() { var _this7 = this; var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; opts = (0, _typeof2["default"])(opts) === 'object' ? opts : null; try { var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { var _opts; var onReady = new Promise(function (resolve, reject) { _this7._onReady = function (id) { try { var _hcaptcha = _this7._hcaptcha; if (opts && opts.async) { _hcaptcha.execute(id, opts).then(resolve)["catch"](reject); } else { resolve(_hcaptcha.execute(id, opts)); } } catch (e) { reject(e); } }; }); return (_opts = opts) !== null && _opts !== void 0 && _opts.async ? onReady : null; } return hcaptcha.execute(captchaId, opts); } catch (error) { if (opts && opts.async) { return Promise.reject(error); } return null; } } }, { key: "close", value: function close() { var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { return; } return hcaptcha.close(captchaId); } }, { key: "setData", value: function setData(data) { var hcaptcha = this._hcaptcha; var captchaId = this.captchaId; if (!this.isReady()) { return; } if (data && (0, _typeof2["default"])(data) !== "object") { data = null; } hcaptcha.setData(captchaId, data); } }, { key: "getResponse", value: function getResponse() { var hcaptcha = this._hcaptcha; return hcaptcha.getResponse(this.captchaId); } }, { key: "getRespKey", value: function getRespKey() { var hcaptcha = this._hcaptcha; return hcaptcha.getRespKey(this.captchaId); } }, { key: "render", value: function render() { var elementId = this.state.elementId; return /*#__PURE__*/React.createElement("div", { ref: this.ref, id: elementId }); } }]); return HCaptcha; }(React.Component); var _default = exports["default"] = HCaptcha; module.exports = exports.default;