revolt_database/util/
captcha.rs1use 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}