123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /* global grecaptcha */
- import React from "react"
- import FormGroup from "misago/components/form-group"
- export class BaseCaptcha {
- init(context, ajax, include, snackbar) {
- this._context = context
- this._ajax = ajax
- this._include = include
- this._snackbar = snackbar
- }
- }
- export class NoCaptcha extends BaseCaptcha {
- load() {
- return new Promise(function(resolve) {
- // immediately resolve as we don't have anything to validate
- resolve()
- })
- }
- validator() {
- return null
- }
- component() {
- return null
- }
- }
- export class QACaptcha extends BaseCaptcha {
- load() {
- var self = this
- return new Promise((resolve, reject) => {
- self._ajax.get(self._context.get("CAPTCHA_API")).then(
- function(data) {
- self.question = data.question
- self.helpText = data.help_text
- resolve()
- },
- function() {
- self._snackbar.error(gettext("Failed to load CAPTCHA."))
- reject()
- }
- )
- })
- }
- validator() {
- return []
- }
- component(kwargs) {
- return (
- <FormGroup
- label={this.question}
- for="id_captcha"
- labelClass={kwargs.labelClass || ""}
- controlClass={kwargs.controlClass || ""}
- validation={kwargs.form.state.errors.captcha}
- helpText={this.helpText || null}
- >
- <input
- aria-describedby="id_captcha_status"
- className="form-control"
- disabled={kwargs.form.state.isLoading}
- id="id_captcha"
- onChange={kwargs.form.bindInput("captcha")}
- type="text"
- value={kwargs.form.state.captcha}
- />
- </FormGroup>
- )
- }
- }
- export class ReCaptchaComponent extends React.Component {
- componentDidMount() {
- grecaptcha.render("recaptcha", {
- sitekey: this.props.siteKey,
- callback: response => {
- // fire fakey event to binding
- this.props.binding({
- target: {
- value: response
- }
- })
- }
- })
- }
- render() {
- return <div id="recaptcha" />
- }
- }
- export class ReCaptcha extends BaseCaptcha {
- load() {
- this._include.include("https://www.google.com/recaptcha/api.js", true)
- return new Promise(function(resolve) {
- var wait = function() {
- if (typeof grecaptcha === "undefined") {
- window.setTimeout(function() {
- wait()
- }, 200)
- } else {
- resolve()
- }
- }
- wait()
- })
- }
- validator() {
- return []
- }
- component(kwargs) {
- return (
- <FormGroup
- label={gettext("Please solve the quick test")}
- for="id_captcha"
- labelClass={kwargs.labelClass || ""}
- controlClass={kwargs.controlClass || ""}
- validation={kwargs.form.state.errors.captcha}
- helpText={gettext(
- "This test helps us prevent automated spam registrations on our site."
- )}
- >
- <ReCaptchaComponent
- binding={kwargs.form.bindInput("captcha")}
- siteKey={this._context.get("SETTINGS").recaptcha_site_key}
- />
- </FormGroup>
- )
- }
- }
- export class Captcha {
- init(context, ajax, include, snackbar) {
- switch (context.get("SETTINGS").captcha_type) {
- case "no":
- this._captcha = new NoCaptcha()
- break
- case "qa":
- this._captcha = new QACaptcha()
- break
- case "re":
- this._captcha = new ReCaptcha()
- break
- }
- this._captcha.init(context, ajax, include, snackbar)
- }
- // accessors for underlying strategy
- load() {
- return this._captcha.load()
- }
- validator() {
- return this._captcha.validator()
- }
- component(kwargs) {
- return this._captcha.component(kwargs)
- }
- }
- export default new Captcha()
|