New API for CAPTCHA plugins
The current CAPTCHA (GD::SecurityImage) works for simple cases. But some of our users need more advanced features, such as those offered by proprietary systems, such as CAPTCHAs that do not need any actual interaction in usual conditions.
Currently, users need to do this by:
- Disabling the internal captcha
- Modifying templates
- Creating an extractFormInfo plugin that validates the captcha response.
But this doesn't work in non-login scenarios (registration, mail reset..), and it's hard to do.
We need to provide a more pluggable system that lets users select which captcha they want, or easily write (and share) their own. We could include some commonly used ones (if license allows).
Captcha plugins will need to hook at various points of processing:
- Before request is sent to the browser
- Captcha plugins need to generate a HTML block to be included in templates (replacing captcha.tpl)
- Captcha plugins may also need to add their own JS to the page being generated
- Captcha plugins may need to set Content-Security-Policy headers (see #2514)
- Captcha plugins may need to persist some state (by creating a token), but this is not always necessary
- After response is received
- Captcha plugin may need to extract POST fields from the HTTP response. The name of those fields are usually decided by the captcha vendor's external JS lib, and may be out of our control
- Captcha plugins will either need to validate the extracted post fields by an external HTTP request, or by restoring the state that was saved in the first step (this is what GD::SecurityImage does)
- Captcha plugins may need to declare their own routes, for example to generate new challenges dynamically
We need to preserve the existing API (Lib::Captcha / setCaptcha / validateCaptcha) in case some already existing plugins try to use it
We need to be compatible with existing templates (CAPTCHA_SRC etc) for users who use custom templates. It's fine if non-updated templates do not work with new plugins as long as they continue to work with GD::SecurityImage