ember-g-recaptcha
Version:
Easily integrate Google's reCaptcha in your app as an Ember Component
145 lines (117 loc) • 3.16 kB
JavaScript
/* globals grecaptcha */
import { action, get } from '@ember/object';
import { cached } from '@glimmer/tracking';
import { getOwner } from '@ember/application';
import { isPresent } from '@ember/utils';
import { guidFor } from '@ember/object/internals';
import Component from '@glimmer/component';
export default class GRecaptchaComponent extends Component {
elementId = guidFor(this);
get config() {
const _config =
getOwner(this).resolveRegistration('config:environment') || {};
return _config['ember-g-recaptcha'] || {};
}
get componentOptions() {
const defaults = [
'sitekey',
'theme',
'size',
'tabindex',
'badge',
'isolated',
'skip',
];
const options = {};
defaults.forEach((option) => {
if (isPresent(get(this.args, option))) {
options[option] = get(this.args, option);
}
});
return options;
}
get options() {
return Object.assign({}, this.config, this.componentOptions);
}
reset() {
if (isPresent(this.widgetId)) {
grecaptcha.reset(this.widgetId);
}
}
_initialize(element) {
const globalName = `__ember_g_recaptcha_${this.elementId}_onload`;
window[globalName] = () => {
this._render(element);
};
let baseUrl = [
`${
this.config['jsUrl'] || 'https://www.google.com/recaptcha/api.js'
}?render=explicit`,
`onload=${globalName}`,
];
if (this.config['hl']) {
baseUrl.push(`hl=${this.config['hl']}`);
}
if (!this.options['skip']) {
this._appendScript(baseUrl.join('&'));
} else {
this._render();
}
}
_destroy() {
window[`__ember_g_recaptcha_${this.elementId}_onload`] = () => {};
}
_appendScript(src) {
let scriptTag = document.createElement('script');
scriptTag.src = src;
scriptTag.async = true;
scriptTag.defer = true;
document.body.appendChild(scriptTag);
}
_render(element) {
const parameters = Object.assign(this.options, {
callback: this._onSuccessCallback.bind(this),
'expired-callback': this._onExpiredCallback.bind(this),
'error-callback': this._onErrorCallback.bind(this),
});
if (this.options['skip']) {
window.grecaptcha = {
execute: () => {
this._onSuccessCallback();
},
getResponse: () => {
return window.btoa(Date.now().toString());
},
reset: () => {
return true;
},
};
} else {
this.widgetId = window.grecaptcha.render(element, parameters);
}
this._onRenderCallback();
}
_onRenderCallback() {
this._invokeCallback('onRender', this);
}
_onSuccessCallback(response) {
this._invokeCallback('onSuccess', response);
}
_onExpiredCallback() {
this._invokeCallback('onExpired');
}
_onErrorCallback(error) {
this._invokeCallback('onError', error);
}
_invokeCallback(callback, value) {
const _callback = this.args[callback];
if (isPresent(_callback) && typeof _callback === 'function') {
_callback(value);
}
}
}