diff options
Diffstat (limited to 'app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js')
-rw-r--r-- | app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js b/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js index c9eac44eb28..fdab188f6be 100644 --- a/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js +++ b/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js @@ -1,4 +1,33 @@ -const supportedMethods = ['patch', 'post', 'put']; +const SUPPORTED_METHODS = ['patch', 'post', 'put']; + +function needsCaptchaResponse(err) { + return ( + SUPPORTED_METHODS.includes(err?.config?.method) && err?.response?.data?.needs_captcha_response + ); +} + +const showCaptchaModalAndResubmit = async (axios, data, errConfig) => { + // NOTE: We asynchronously import and unbox the module. Since this is included globally, we don't + // do a regular import because that would increase the size of the webpack bundle. + const { waitForCaptchaToBeSolved } = await import('~/captcha/wait_for_captcha_to_be_solved'); + + // show the CAPTCHA modal and wait for it to be solved or closed + const captchaResponse = await waitForCaptchaToBeSolved(data.captcha_site_key); + + // resubmit the original request with the captcha_response and spam_log_id in the headers + const originalData = JSON.parse(errConfig.data); + const originalHeaders = errConfig.headers; + return axios({ + method: errConfig.method, + url: errConfig.url, + headers: { + ...originalHeaders, + 'X-GitLab-Captcha-Response': captchaResponse, + 'X-GitLab-Spam-Log-Id': data.spam_log_id, + }, + data: originalData, + }); +}; export function registerCaptchaModalInterceptor(axios) { return axios.interceptors.response.use( @@ -6,29 +35,8 @@ export function registerCaptchaModalInterceptor(axios) { return response; }, (err) => { - if ( - supportedMethods.includes(err?.config?.method) && - err?.response?.data?.needs_captcha_response - ) { - const { data } = err.response; - const captchaSiteKey = data.captcha_site_key; - const spamLogId = data.spam_log_id; - // eslint-disable-next-line promise/no-promise-in-callback - return import('~/captcha/wait_for_captcha_to_be_solved') - .then(({ waitForCaptchaToBeSolved }) => waitForCaptchaToBeSolved(captchaSiteKey)) - .then((captchaResponse) => { - const errConfig = err.config; - const originalData = JSON.parse(errConfig.data); - return axios({ - method: errConfig.method, - url: errConfig.url, - data: { - ...originalData, - captcha_response: captchaResponse, - spam_log_id: spamLogId, - }, - }); - }); + if (needsCaptchaResponse(err)) { + return showCaptchaModalAndResubmit(axios, err.response.data, err.config); } return Promise.reject(err); |