48 lines
1.8 KiB
JavaScript
48 lines
1.8 KiB
JavaScript
// NOTE: This module will be used in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52044
|
|
import { memoize } from 'lodash';
|
|
|
|
export const RECAPTCHA_API_URL_PREFIX = 'https://www.google.com/recaptcha/api.js';
|
|
export const RECAPTCHA_ONLOAD_CALLBACK_NAME = 'recaptchaOnloadCallback';
|
|
|
|
/**
|
|
* Adds the Google reCAPTCHA script tag to the head of the document, and
|
|
* returns a promise of the grecaptcha object
|
|
* (https://developers.google.com/recaptcha/docs/display#js_api).
|
|
*
|
|
* It is memoized, so there will only be one instance of the script tag ever
|
|
* added to the document.
|
|
*
|
|
* See the reCAPTCHA documentation for more details:
|
|
*
|
|
* https://developers.google.com/recaptcha/docs/display#explicit_render
|
|
*
|
|
*/
|
|
export const initRecaptchaScript = memoize(() => {
|
|
// Appends the the reCAPTCHA script tag to the head of document
|
|
const appendRecaptchaScript = () => {
|
|
const script = document.createElement('script');
|
|
script.src = `${RECAPTCHA_API_URL_PREFIX}?onload=${RECAPTCHA_ONLOAD_CALLBACK_NAME}&render=explicit`;
|
|
script.classList.add('js-recaptcha-script');
|
|
document.head.appendChild(script);
|
|
};
|
|
|
|
return new Promise((resolve) => {
|
|
// This global callback resolves the Promise and is passed by name to the reCAPTCHA script.
|
|
window[RECAPTCHA_ONLOAD_CALLBACK_NAME] = () => {
|
|
// Let's clean up after ourselves. This is also important for testing, because `window` is NOT cleared between tests.
|
|
// https://github.com/facebook/jest/issues/1224#issuecomment-444586798.
|
|
delete window[RECAPTCHA_ONLOAD_CALLBACK_NAME];
|
|
resolve(window.grecaptcha);
|
|
};
|
|
appendRecaptchaScript();
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Clears the cached memoization of the default manager.
|
|
*
|
|
* This is needed for determinism in tests.
|
|
*/
|
|
export const clearMemoizeCache = () => {
|
|
initRecaptchaScript.cache.clear();
|
|
};
|