mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-26 17:16:11 -05:00
Merge pull request #3276 from picklesrus/captcha-join
Initial work for captcha in new join flow.
This commit is contained in:
commit
73c353ba2c
3 changed files with 74 additions and 4 deletions
|
@ -33,6 +33,11 @@ env:
|
|||
- CLOUDDATA_HOST_VAR=CLOUDDATA_HOST_$TRAVIS_BRANCH
|
||||
- CLOUDDATA_HOST=${!CLOUDDATA_HOST_VAR}
|
||||
- CLOUDDATA_HOST=${CLOUDDATA_HOST:-$CLOUDDATA_HOST_STAGING}
|
||||
- RECAPTCHA_SITE_KEY_master=6LeRbUwUAAAAAFYhKgk3G9OKWqE_OJ7Z-7VTUCbl
|
||||
- RECAPTCHA_SITE_KEY_STAGING=6LfukK4UAAAAAFR44yoZMhv8fj6xh-PMiIxwryG3
|
||||
- RECAPTCHA_SITE=RECAPTCHA_SITE_KEY_$TRAVIS_BRANCH
|
||||
- RECAPTCHA_SITE_KEY=${!RECAPTCHA_SITE_KEY_VAR}
|
||||
- RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY:-$RECAPTCHA_SITE_KEY_STAGING}
|
||||
- ROOT_URL_master=https://scratch.mit.edu
|
||||
- ROOT_URL_STAGING=https://scratch.ly
|
||||
- ROOT_URL_VAR=ROOT_URL_$TRAVIS_BRANCH
|
||||
|
|
|
@ -20,16 +20,59 @@ class EmailStep extends React.Component {
|
|||
'handleSetEmailRef',
|
||||
'handleValidSubmit',
|
||||
'validateEmail',
|
||||
'validateForm'
|
||||
'validateForm',
|
||||
'setCaptchaRef',
|
||||
'captchaSolved',
|
||||
'onCaptchaLoad',
|
||||
'onCaptchaError'
|
||||
]);
|
||||
this.state = {
|
||||
captchaIsLoading: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
// automatically start with focus on username field
|
||||
if (this.emailInput) this.emailInput.focus();
|
||||
|
||||
// If grecaptcha doesn't exist on window, we havent loaded the captcha js yet. Load it.
|
||||
if (!window.grecaptcha) {
|
||||
// ReCaptcha calls a callback when the grecatpcha object is usable. That callback
|
||||
// needs to be global so set it on the window.
|
||||
window.grecaptchaOnLoad = this.onCaptchaLoad;
|
||||
// Load Google ReCaptcha script.
|
||||
const script = document.createElement('script');
|
||||
script.async = true;
|
||||
script.onerror = this.onCaptchaError;
|
||||
script.src = `https://www.recaptcha.net/recaptcha/api.js?onload=grecaptchaOnLoad&render=explicit&hl=${window._locale}`;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
}
|
||||
componentWillUnmount () {
|
||||
window.grecaptchaOnLoad = null;
|
||||
}
|
||||
handleSetEmailRef (emailInputRef) {
|
||||
this.emailInput = emailInputRef;
|
||||
}
|
||||
onCaptchaError () {
|
||||
// TODO send user to error step once we have one.
|
||||
}
|
||||
onCaptchaLoad () {
|
||||
this.setState({captchaIsLoading: false});
|
||||
this.grecaptcha = window.grecaptcha;
|
||||
if (!this.grecaptcha) {
|
||||
// According to the reCaptcha documentation, this callback shouldn't get
|
||||
// called unless window.grecaptcha exists. This is just here to be extra defensive.
|
||||
// TODO: Put up the error screen when we have one.
|
||||
}
|
||||
// TODO: Add in error callback for render once we have an error screen.
|
||||
this.widgetId = this.grecaptcha.render(this.captchaRef,
|
||||
{
|
||||
callback: this.captchaSolved,
|
||||
sitekey: process.env.RECAPTCHA_SITE_KEY
|
||||
},
|
||||
true);
|
||||
}
|
||||
validateEmail (email) {
|
||||
if (!email) return this.props.intl.formatMessage({id: 'general.required'});
|
||||
const isValidLocally = emailValidator.validate(email);
|
||||
|
@ -42,8 +85,21 @@ class EmailStep extends React.Component {
|
|||
return {};
|
||||
}
|
||||
handleValidSubmit (formData, formikBag) {
|
||||
formikBag.setSubmitting(false);
|
||||
this.props.onNextStep(formData);
|
||||
this.formData = formData;
|
||||
this.formikBag = formikBag;
|
||||
// Change set submitting to false so that if the user clicks out of
|
||||
// the captcha, the button is clickable again (instead of a disabled button with a spinner).
|
||||
this.formikBag.setSubmitting(false);
|
||||
this.grecaptcha.execute(this.widgetId);
|
||||
}
|
||||
captchaSolved (token) {
|
||||
// Now thatcaptcha is done, we can tell Formik we're submitting.
|
||||
this.formikBag.setSubmitting(true);
|
||||
this.formData['g-recaptcha-response'] = token;
|
||||
this.props.onNextStep(this.formData);
|
||||
}
|
||||
setCaptchaRef (ref) {
|
||||
this.captchaRef = ref;
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
|
@ -88,7 +144,7 @@ class EmailStep extends React.Component {
|
|||
innerClassName="join-flow-inner-email-step"
|
||||
nextButton={this.props.intl.formatMessage({id: 'registration.createAccount'})}
|
||||
title={this.props.intl.formatMessage({id: 'registration.emailStepTitle'})}
|
||||
waiting={isSubmitting}
|
||||
waiting={isSubmitting || this.state.captchaIsLoading}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<FormikInput
|
||||
|
@ -116,6 +172,13 @@ class EmailStep extends React.Component {
|
|||
name="subscribe"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="g-recaptcha"
|
||||
data-badge="bottomright"
|
||||
data-sitekey={process.env.RECAPTCHA_SITE_KEY}
|
||||
data-size="invisible"
|
||||
ref={this.setCaptchaRef}
|
||||
/>
|
||||
</JoinFlowStep>
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -173,6 +173,8 @@ module.exports = {
|
|||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': '"' + (process.env.NODE_ENV || 'development') + '"',
|
||||
'process.env.API_HOST': '"' + (process.env.API_HOST || 'https://api.scratch.mit.edu') + '"',
|
||||
'process.env.RECAPTCHA_SITE_KEY': '"' +
|
||||
(process.env.RECAPTCHA_SITE_KEY || '6Lf6kK4UAAAAABKTyvdSqgcSVASEnMrCquiAkjVW') + '"',
|
||||
'process.env.ASSET_HOST': '"' + (process.env.ASSET_HOST || 'https://assets.scratch.mit.edu') + '"',
|
||||
'process.env.BACKPACK_HOST': '"' + (process.env.BACKPACK_HOST || 'https://backpack.scratch.mit.edu') + '"',
|
||||
'process.env.CLOUDDATA_HOST': '"' + (process.env.CLOUDDATA_HOST || 'clouddata.scratch.mit.edu') + '"',
|
||||
|
|
Loading…
Reference in a new issue