1 use crate::{captcha_as_wav_base64, Perform};
2 use actix_web::web::Data;
3 use captcha::{gen, Difficulty};
4 use lemmy_api_common::{
6 person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse},
8 use lemmy_db_schema::source::{
9 captcha_answer::{CaptchaAnswer, CaptchaAnswerForm},
10 local_site::LocalSite,
12 use lemmy_utils::error::LemmyError;
14 #[async_trait::async_trait(?Send)]
15 impl Perform for GetCaptcha {
16 type Response = GetCaptchaResponse;
18 #[tracing::instrument(skip(context))]
19 async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
20 let local_site = LocalSite::read(context.pool()).await?;
22 if !local_site.captcha_enabled {
23 return Ok(GetCaptchaResponse { ok: None });
26 let captcha = gen(match local_site.captcha_difficulty.as_str() {
27 "easy" => Difficulty::Easy,
28 "hard" => Difficulty::Hard,
29 _ => Difficulty::Medium,
32 let answer = captcha.chars_as_string();
34 let png = captcha.as_base64().expect("failed to generate captcha");
36 let wav = captcha_as_wav_base64(&captcha);
38 let captcha_form: CaptchaAnswerForm = CaptchaAnswerForm { answer };
39 // Stores the captcha item in the db
40 let captcha = CaptchaAnswer::insert(context.pool(), &captcha_form).await?;
42 Ok(GetCaptchaResponse {
43 ok: Some(CaptchaResponse {
46 uuid: captcha.uuid.to_string(),