Skip to content

Add support for new CAPTCHA modal to issue updates

Chad Woolley requested to merge convert-issues-to-new-captcha-modal into master

What does this MR do?

Switch to new modern captcha modal which uses Pajamas modal and handles all CAPTCHA rendering on the client. This introduces new, more decoupled approach of using axios interceptors to handle captcha modal hooks.

The backend now returns a 409 CONFLICT with a spam_log_id and captcha_site_key. On the frontend side we, the aforementioned interceptor detects this error, opens a modal asking the user to solve the captcha. If the captcha is solved successfully, it re-issues the request, attaching the captchaResponse. If it isn't solved, it will throw an UnresolvedCaptchaError instead. The application can choose to gracefully handle this error, or treat it as any other axios request error.

For now the interceptors only support PATCH, POST and PUT. Future iterations might want to switch to using HTTP headers instead, which would mean we could extend the approach to the other HTTP methods as well.

In this commit we are converting the issue update captcha to use this methodology. Before using an axios interceptor we needed to track the state of the captcha in the application and the logic looked something like this:

sequenceDiagram
    participant U as User
    participant V as Vue Application
    participant G as GitLab API
    U->>V: Save issue
    V->>G: Request
    G--xV: Response with Error and Captcha Data
    V->>U: Please solve Captcha
    U->>V: Captcha Solution
    V->>G: Resend Request with solved Captcha Data
    G-->>V: Response with Success

Now we are doing this:

sequenceDiagram
    participant U as User
    participant V as Vue Application
    participant A as Axios Interceptor
    participant G as GitLab API
    U->>V: Save issue
    V->>G: Request
    G--xA: Response with Error and Captcha Data
    A->>U: Please solve Captcha
    U->>A: Captcha Solution
    A->>G: Resend Request with solved Captcha Data
    G-->>A: Response with Success
    A-->>V: Response with Success

This way we have decoupled the Captcha handling from our Vue Application. For all the Vue Application knows, it is just a request that takes a bit longer than usual. This has the benefit that adding captcha support to new Vue endpoints is as easy as:

registerCaptchaModalInterceptor(axios);

Current Status

Tasks

  • Convert to new modal
  • Convert to axios interceptor
  • Closing Captcha modal without solving should still work

Screenshots (strongly suggested)

Screencast before Screencast after (with solving the captcha ) Screencast after (without solving the captcha)
captcha-before captcha-success captcha-fail

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

NOTE: See this section for details on how to test CAPTCHAs in local dev/GDK and review apps: https://gitlab.com/groups/gitlab-org/-/epics/5527#testing-notes

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team
Edited by Lukas 'ai-pi' Eipert

Merge request reports