Skip to content

Instantly share code, notes, and snippets.

@luxzeitlos
Created April 16, 2020 22:45
Show Gist options
  • Save luxzeitlos/8093dc8aa8a19f24828d0fa07f9bf1a3 to your computer and use it in GitHub Desktop.
Save luxzeitlos/8093dc8aa8a19f24828d0fa07f9bf1a3 to your computer and use it in GitHub Desktop.
Ember-G-reCaptcha
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class RegisterForm extends Component {
googleRecaptcha = null;
siteKey = "6LdeLOYUAAAAAK2DmVLyVf0huk0nD3Sdp1WrpQ5P";
@tracked username;
@tracked password;
@tracked confirmPassword;
// Add a new register action to the component to handle the onsubmit method of our
// register-form.
@action
register(ev) {
// Prevent the form's default action.
ev.preventDefault();
// Call the form's onsubmit method and pass in the component's values.
this.args.register({
username: this.username,
password: this.password,
confirmPassword: this.confirmPassword,
reCaptchaResponse: this.reCaptchaResponse, // This returns undefined
googleRecaptcha: this.googleRecaptcha
});
}
// Add a onCaptchaResolved action to the component that will handle the captcha resolved.
// This is called when the reCaptcha has been resolved and we know it is not a bot submitting the register-form.
@action
onCaptchaResolved(reCaptchaResponse) {
// Set the reCaptchaResponse to the value passed in reCaptchaResponse. This can be checked in the
// register.js controller and if the property does not exist or it is null or it is blank we can
// prevent the new client from registering until the recpatcha has been resolved.
this.setProperties({
reCaptchaResponse: reCaptchaResponse
});
}
// When the recaptcha expires any previous recaptcha response should be invalidated so we do not allow old expired
// responses to be used. Set the reCaptchaResponse property to a blank string so the controller will know any
// previous successful recaptcha response is no longer valid.
@action
onCaptchaExpired()
{
this.setProperties({
reCaptchaResponse: ''
});
}
}
import Controller from '@ember/controller';
export default class ApplicationController extends Controller {
appName = 'Ember Twiddle';
}
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class Register extends Controller {
// Inject the needed services.
//@service('ajax') ajaxService;
// Create a register action that will take in the attributes from the register-form component.
@action
register(attrs) {
// Do a quick form input validation.
if(attrs.username == undefined || attrs.username == null || attrs.username == '') {
// Set the errors property. This will allow the errors to be shown in the UI.
this.set('errors', [{
detail: "The user name cannot be blank. Registration was not successful.",
status: 1000,
title: 'Registration Failed'
}]);
// Set the attributes of the model to what was originally passed so they do not need to be filled out again.
this.set('model', attrs);
}
else if(attrs.password == undefined || attrs.password == null || attrs.password == '' ||
attrs.confirmPassword == undefined || attrs.confirmPassword == null || attrs.confirmPassword == '' ||
attrs.password != attrs.confirmPassword)
{
// Set the errors property. This will allow the errors to be shown in the UI.
this.set('errors', [{
detail: "The password and confirm password must be the same and their values and cannot be blank. Registration was not successful.",
status: 1000,
title: 'Registration Failed'
}]);
// Set the attributes of the model to what was originally passed so they do not need to be filled out again.
this.set('model', attrs);
}
else if(attrs.reCaptchaResponse == undefined || attrs.reCaptchaResponse == null || attrs.reCaptchaResponse == '') {
// If this part of the code is reached it means the recaptcha has not been resolved. Create the error and
// notifiy the user. Set the errors property. This will allow the registration errors to be shown in the UI.
this.set('errors', [{
detail: "Please resolve the reCAPTCHA by clicking on the checkbox marked I'm not a robot.",
status: 1000,
title: 'Registration Failed'
}]);
// Set the attributes of the model to what was originally passed so they do not need to be filled out again.
this.set('model', attrs);
}
else {
// If we get this far all is good to register the new client. Make the ajax call to the backend to register the
// new client. We do not go through the store to create a register model in the store and then execute the save()
// method to make a call to the backend API. Rather we make an ajax call because we do not need a register object
// saved in the store.
this.ajaxService.request(this.store.adapterFor('application').get('host') + "/clients/register", {
method: 'POST',
data: JSON.stringify({
data: {
attributes: {
"username" : attrs.username,
"password" : attrs.password,
"confirm-password" : attrs.confirmPassword
},
type: 'registers'
}
}),
headers: {
'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'
}
})
.then(() => {
// Reset the recaptcha.
attrs.googleRecaptcha.resetReCaptcha();
// Transistion to the register-success route.
this.transitionToRoute('clients.register-success');
})
.catch((ex) => {
// Reset the recaptcha.
attrs.googleRecaptcha.resetReCaptcha();
// Set the errors property to the errors held in the ex.payload.errors. This will allow the registration errors
// to be shown in the UI.
this.set('errors', ex.payload.errors);
// Set the attributes of the model to what was originally passed so they do not need to be filled out again.
this.set('model', attrs);
});
}
}
}
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('register');
});
export default Router;
import Route from '@ember/routing/route';
export default class RegisterRoute extends Route {
// Create the model function that will return the username and password and confirm password model for registration.
model() {
// Return a new model.
return {
username: '',
password: '',
confirmPassowrd: ''
};
}
}
<h1>Welcome to {{this.appName}}</h1>
<br>
<LinkTo @route="register">Register</LinkTo>
<br>
{{outlet}}
<br>
<br>
<div class="middle-box text-center loginscreen animated fadeInDown">
<div>
<h3>Registration</h3>
<form class="m-t" role="form" {{on "submit" this.register}}>
{{#each @errors as |error|}}
<div class="error-alert">{{error.detail}}</div>
{{/each}}
<div class="form-group">
<Input @type="email" class="form-control" placeholder="Username" @value={{this.username}} required="true" />
</div>
<div class="form-group">
<Input @type="password" class="form-control" placeholder="Password" @value={{this.password}} required="true" />
</div>
<div class="form-group">
<Input @type="password" class="form-control" placeholder="Confirm Password" @value={{this.confirmPassword}} required="true" />
</div>
<div>
<!--
<GRecaptcha @size="normal" @sitekey={{this.siteKey}} @onSuccess={{action "onCaptchaResolved"}} @onExpired={{action "onCaptchaExpired"}} @ref={{mut this.googleRecaptcha}} />
-->
<GRecaptcha
@size="normal"
@sitekey={{this.siteKey}}
@onSuccess={{action "onCaptchaResolved"}}
@onExpired={{action "onCaptchaExpired"}}
@ref={{mut this.googleRecaptcha}}
/>
<button type="submit" class="btn btn-primary block full-width m-b">Register</button>
</div>
</form>
</div>
</div>
<RegisterForm @clientModel={{this.model}} @register={{action 'register'}} @errors={{this.errors}} />
{
"version": "0.17.0",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.17.0",
"ember-template-compiler": "3.17.0",
"ember-testing": "3.17.0"
},
"addons": {
"@glimmer/component": "1.0.0",
"ember-g-recaptcha": "1.3.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment