All files / app/assets/javascripts/captcha captcha_modal_axios_interceptor.js

100% Statements 13/13
100% Branches 4/4
100% Functions 5/5
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 461054x     1949x         1054x     6x     6x     3x 3x 3x                         1078x   3757x     1949x 6x     1943x        
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(
    (response) => {
      return response;
    },
    (err) => {
      if (needsCaptchaResponse(err)) {
        return showCaptchaModalAndResubmit(axios, err.response.data, err.config);
      }
 
      return Promise.reject(err);
    },
  );
}