Skip to main content

revolt_database/util/
captcha.rs

1use reqwest::Client;
2use revolt_config::config;
3use revolt_result::Result;
4use std::sync::LazyLock;
5
6static CLIENT: LazyLock<Client> = LazyLock::new(Client::new);
7
8#[derive(Serialize, Deserialize)]
9struct CaptchaResponse {
10    success: bool,
11}
12
13pub async fn check_captcha(token: Option<&str>) -> Result<()> {
14    let config = config().await;
15
16    if !config.api.security.captcha.hcaptcha_key.is_empty() {
17        let Some(token) = token else {
18            return Err(create_error!(CaptchaFailed));
19        };
20
21        let response = CLIENT
22            .post("https://hcaptcha.com/siteverify")
23            .form(&[
24                ("secret", config.api.security.captcha.hcaptcha_key.as_str()),
25                ("response", token),
26            ])
27            .send()
28            .await
29            .map_err(|_| create_error!(CaptchaFailed))?
30            .json::<CaptchaResponse>()
31            .await
32            .map_err(|_| create_error!(CaptchaFailed))?;
33
34        if response.success {
35            Ok(())
36        } else {
37            Err(create_error!(CaptchaFailed))
38        }
39    } else {
40        Ok(())
41    }
42}