Skip to content

login captcha#394

Merged
freedit-dev merged 4 commits intomainfrom
login_captcha
Dec 28, 2025
Merged

login captcha#394
freedit-dev merged 4 commits intomainfrom
login_captcha

Conversation

@freedit-dev
Copy link
Member

@freedit-dev freedit-dev commented Dec 28, 2025

Summary by CodeRabbit

  • New Features

    • Added an optional login CAPTCHA setting in the admin panel; CAPTCHA can be toggled per site.
  • Improvements

    • Sign-in page now shows CAPTCHA only when the site setting is enabled; form handling treats CAPTCHA as optional when disabled.
  • Internationalization

    • Added "login_captcha" translations for English, French, Japanese, Ukrainian, and Simplified Chinese

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 28, 2025

Warning

Rate limit exceeded

@freedit-dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fb95cef and f5596ae.

📒 Files selected for processing (1)
  • src/controller/user.rs
📝 Walkthrough

Walkthrough

Adds a configurable login_captcha flag: new i18n keys, a SiteConfig::login_captcha Option (default None), propagation to PageData, admin UI radio control, conditional CAPTCHA rendering on signin, and optional captcha inputs/validation in the signin handler.

Changes

Cohort / File(s) Summary
Translations
i18n/en.toml, i18n/fr.toml, i18n/ja.toml, i18n/uk.toml, i18n/zh_cn.toml
Added login_captcha entries (EN: "Login Captcha", FR: "Captcha de connexion", JA: "ログインキャプチャ", UK: "Капча входу", ZH: "登录验证码").
SiteConfig definition & default
src/controller/mod.rs, src/controller/admin.rs
Added login_captcha: Option<bool> to SiteConfig with #[validate(skip)]; initialized to None in SiteConfig::default().
Page data propagation
src/controller/meta_handler.rs
Added login_captcha: bool to PageData<'a> and initialize from site_config.login_captcha.unwrap_or(false) in PageData::new.
Signin handler & form
src/controller/user.rs
FormSignin changed captcha_id/captcha_value to Option<String>; handler fetches site_config once and conditionally validates captcha when enabled; error path adjusted (uses WrongPassword for missing user).
Admin template
templates/admin.html
Added login_captcha Yes/No radio form group bound to site_config.login_captcha; appears duplicated in the file.
Signin template
templates/signin.html
CAPTCHA image, input, and hidden ID field are rendered only when page_data.login_captcha is true (conditional rendering).

Sequence Diagram(s)

sequenceDiagram
    participant Admin as Admin UI
    participant Server as Web Server
    participant SiteCfg as SiteConfig
    participant Page as PageData
    participant Browser as User Browser
    rect rgba(82,196,26,0.08)
    Note over Admin,Server: Admin toggles login_captcha
    Admin->>Server: POST update SiteConfig(login_captcha)
    Server->>SiteCfg: persist login_captcha
    end
    rect rgba(20,120,200,0.06)
    Note over Browser,Server: User opens signin page
    Browser->>Server: GET /signin
    Server->>SiteCfg: read site_config
    Server->>Page: construct PageData(login_captcha = site_config.unwrap_or(false))
    Server->>Browser: render signin (captcha shown only if login_captcha true)
    end
    rect rgba(255,180,50,0.06)
    Note over Browser,Server: User submits signin form
    Browser->>Server: POST /signin (captcha fields optional)
    Server->>SiteCfg: read site_config (used to decide validation)
    alt login_captcha enabled
        Server->>Server: validate captcha (if provided)
    else login_captcha disabled
        Server->>Server: skip captcha validation
    end
    Server->>Browser: respond with auth result
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰
I nudge a toggle, tiny and bright,
Captchas sleep or wake at night,
Admin sets the gate with care,
Users hop through here or there,
A happy rabbit, nose in the air.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'login captcha' accurately describes the main change—adding optional CAPTCHA functionality to the login feature across multiple files (translations, configuration, UI, and logic).

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/controller/mod.rs (1)

532-533: Consider adding inline documentation.

Adding a brief comment explaining the purpose of this field would improve code maintainability.

📝 Suggested documentation
+    /// When enabled, requires users to complete a CAPTCHA challenge during login
     #[validate(skip)]
     login_captcha: Option<bool>,
src/controller/user.rs (1)

928-937: Consider more explicit validation of optional captcha fields.

While the current implementation is functionally safe (missing fields result in empty strings that fail lookup), the error handling relies on implicit behavior. Consider explicitly checking for None before validation for clarity and better error messages.

🔎 Suggested refactor for explicit field validation
 let site_config = SiteConfig::get(&DB)?;
 if site_config.login_captcha == Some(true) {
+    let captcha_id = input.captcha_id.as_deref().ok_or(AppError::CaptchaError)?;
+    let captcha_value = input.captcha_value.as_deref().ok_or(AppError::CaptchaError)?;
+    
     let captcha_char = DB
         .open_partition("captcha", Default::default())?
-        .take(&input.captcha_id.unwrap_or_default())?
+        .take(captcha_id)?
         .ok_or(AppError::CaptchaError)?;
-    if captcha_char != input.captcha_value.unwrap_or_default() {
+    if captcha_char != captcha_value {
         return Err(AppError::CaptchaError);
     }
 }

This also addresses the clippy warning about unnecessary borrows.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5275686 and 828c3df.

📒 Files selected for processing (11)
  • i18n/en.toml
  • i18n/fr.toml
  • i18n/ja.toml
  • i18n/uk.toml
  • i18n/zh_cn.toml
  • src/controller/admin.rs
  • src/controller/meta_handler.rs
  • src/controller/mod.rs
  • src/controller/user.rs
  • templates/admin.html
  • templates/signin.html
🧰 Additional context used
🪛 GitHub Check: clippy
src/controller/user.rs

[warning] 932-932:
the borrowed expression implements the required traits


[warning] 932-932:
the borrowed expression implements the required traits

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cargo test, clippy and doc (windows-latest, x86_64-pc-windows-gnu)
  • GitHub Check: Cargo test, clippy and doc (windows-latest, x86_64-pc-windows-msvc)
🔇 Additional comments (12)
src/controller/meta_handler.rs (2)

171-171: LGTM - Field addition is correct.

The new login_captcha field is properly added to the PageData struct with appropriate visibility.


198-198: CAPTCHA validation is properly gated in signin handler.

The signin_post function correctly checks if site_config.login_captcha == Some(true) before validating CAPTCHA fields (lines 929-937 in src/controller/user.rs). The FormSignin struct declares captcha_id and captcha_value as optional fields, and when CAPTCHA is disabled, the entire validation block is skipped with no errors.

i18n/uk.toml (1)

75-75: LGTM - Translation key added correctly.

The Ukrainian translation for "Login Captcha" has been added consistently with other locale files.

i18n/en.toml (1)

74-74: LGTM - English translation added correctly.

The translation key is clear and appropriately positioned in the file.

i18n/fr.toml (1)

74-74: LGTM - French translation added correctly.

The French translation "Captcha de connexion" is appropriate and consistently placed.

i18n/ja.toml (1)

74-74: LGTM - Japanese translation added correctly.

The Japanese translation is appropriate and consistently positioned.

i18n/zh_cn.toml (1)

75-75: LGTM - Chinese translation added correctly.

The Simplified Chinese translation "登录验证码" is appropriate and consistently placed.

src/controller/mod.rs (1)

532-533: LGTM - Field addition is correct.

The new login_captcha: Option<bool> field is properly added to SiteConfig with appropriate validation skip. All three implementation points are confirmed:

  1. SiteConfig::default() correctly initializes this field to None (src/controller/admin.rs:384)
  2. Admin interface template renders radio button controls with proper pattern matching, defaulting to "no" when unset (templates/admin.html:288-300)
  3. Admin handler processes this field correctly as part of the struct

Using Option<bool> ensures backward compatibility with existing configurations.

templates/signin.html (1)

31-43: LGTM - Conditional CAPTCHA rendering and form handling implemented correctly.

The CAPTCHA elements are properly gated behind the page_data.login_captcha flag in the template. The signin form handler in src/controller/user.rs correctly defines captcha_id and captcha_value as Option<String> fields, and the validation logic only executes when site_config.login_captcha == Some(true), ensuring form submissions succeed without CAPTCHA data when the feature is disabled.

src/controller/admin.rs (1)

384-384: LGTM!

The default initialization of login_captcha: None is consistent with other optional configuration fields and correctly disables the login captcha by default.

src/controller/user.rs (1)

880-881: LGTM! Optional captcha fields align with conditional validation.

Making captcha_id and captcha_value optional correctly reflects that these fields are only required when login_captcha is enabled.

templates/admin.html (1)

286-304: No duplicate field exists. The code shows a single login_captcha field with conditional rendering of the checked state. Lines 295-299 are not duplicates but rather two branches of a match expression: when login_captcha is Some(true), the "yes" option is checked; otherwise, the "false" option is checked. This is the correct pattern for managing default radio button state based on config. No changes needed.

@freedit-dev freedit-dev merged commit 59119e9 into main Dec 28, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant