Implement custom footer code option#385
Conversation
WalkthroughAdds a configurable custom footer: new translation keys, a SiteConfig field, PageData exposure, an admin textarea to edit it, and conditional footer rendering that uses the custom code when present or falls back to the original footer. Changes
Sequence Diagram(s)sequenceDiagram
participant Admin as Admin User
participant AdminForm as Admin Form (templates/admin.html)
participant SiteConfig as SiteConfig (src/controller/mod.rs)
participant Meta as Meta Handler / PageData (src/controller/meta_handler.rs)
participant Template as Layout Template (templates/layout.html)
Admin->>AdminForm: Edit & submit custom_footer_code
AdminForm->>SiteConfig: Persist custom_footer_code
Note over SiteConfig,Meta: On request rendering
SiteConfig->>Meta: Provide site_config
Meta->>Meta: Initialize PageData.custom_footer_code (None or &str)
Template->>Meta: Check custom_footer_code
alt custom_footer_code exists
Template->>Template: Render custom footer code (unsafe HTML)
else no custom_footer_code
Template->>Template: Render default static footer
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/controller/admin.rs (1)
340-360: Critical: Missing sanitization for custom_footer_code.The
admin_postfunction sanitizes other user-controlled fields (lines 351-356) usingclean_html(), butcustom_footer_codeis not sanitized. This creates an XSS vulnerability when the unsanitized content is rendered intemplates/layout.html.🔎 Proposed fix to add sanitization
site_config.site_name = clean_html(&site_config.site_name); site_config.domain = clean_html(&site_config.domain); site_config.description = clean_html(&site_config.description); site_config.captcha_difficulty = clean_html(&site_config.captcha_difficulty); site_config.captcha_name = clean_html(&site_config.captcha_name); site_config.tos_link = clean_html(&site_config.tos_link); + site_config.custom_footer_code = site_config.custom_footer_code.map(|s| clean_html(&s)); set_one_with_key(&DB, "default", "site_config", &site_config)?;
🧹 Nitpick comments (1)
src/controller/mod.rs (1)
530-531: Consider adding length validation for the custom footer code field.While this field is admin-controlled and intentionally allows custom code injection, having no length validation could lead to storage, memory, or page load performance issues if excessively large content is provided. Other string fields in
SiteConfighave maximum length constraints (e.g.,descriptionat 5120,article_max_lengthat 65535).🔎 Suggested improvement
- #[validate(skip)] + #[validate(length(max = 65535))] custom_footer_code: Option<String>,Alternatively, choose a different limit based on expected use cases (analytics scripts, custom HTML, etc.).
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
i18n/en.tomli18n/fr.tomli18n/ja.tomli18n/uk.tomli18n/zh_cn.tomlsrc/controller/admin.rssrc/controller/meta_handler.rssrc/controller/mod.rstemplates/admin.htmltemplates/layout.html
🧰 Additional context used
🧬 Code graph analysis (1)
src/controller/mod.rs (2)
src/controller/inn.rs (1)
FormInn(124-139)src/controller/feed.rs (1)
FormFeedAdd(533-542)
⏰ 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-msvc)
- GitHub Check: Cargo test, clippy and doc (windows-latest, x86_64-pc-windows-gnu)
🔇 Additional comments (6)
i18n/en.toml (1)
22-22: LGTM!English translation is appropriate and consistent with other translation keys.
i18n/uk.toml (1)
22-22: LGTM!Ukrainian translation is properly localized and consistent with other translation keys.
templates/admin.html (1)
235-250: Template implementation looks consistent.The conditional rendering pattern matches the existing
spam_regexfield implementation. However, ensure that server-side sanitization is properly implemented to prevent XSS vulnerabilities.src/controller/admin.rs (1)
383-383: LGTM!Default initialization to
Noneis appropriate for the optional custom footer code field.src/controller/meta_handler.rs (2)
170-170: LGTM!The field declaration is correct with proper lifetime management and visibility.
186-197: LGTM! Clean implementation of the custom footer code feature.The initialization logic correctly:
- Converts
Option<String>toOption<&'a str>usingas_deref()- Filters out empty strings for better UX
- Maintains proper lifetime relationships
The field reordering is a stylistic change with no functional impact.
| comment_max_length = "Longueur maximale du commentaire" | ||
| comments = "Comments" # @TODO | ||
| created = "Créé" | ||
| custom_footer_code = "Custom footer code" # @TODO |
There was a problem hiding this comment.
Incomplete French translation.
The translation value is still in English rather than French. Consider translating to something like "Code de pied de page personnalisé".
🤖 Prompt for AI Agents
In i18n/fr.toml around line 22, the value for custom_footer_code is still in
English; replace the English string with the French translation (e.g., "Code de
pied de page personnalisé") so the key is fully localized.
| comment_max_length = "コメントの最大長" | ||
| comments = "Comments" # @TODO | ||
| created = "作成日時" | ||
| custom_footer_code = "Custom footer code" # @TODO |
There was a problem hiding this comment.
Incomplete Japanese translation.
The translation value is still in English rather than Japanese. Consider translating to something like "カスタムフッターコード".
🤖 Prompt for AI Agents
In i18n/ja.toml around line 22, the value for custom_footer_code is still in
English; replace the English string "Custom footer code" with the appropriate
Japanese translation (e.g., "カスタムフッターコード") ensuring UTF-8 encoding and
preserving the TOML key/value format so localization loads correctly.
| comment_max_length = "评论最大长度" | ||
| comments = "Comments" # @TODO | ||
| created = "创建时间" | ||
| custom_footer_code = "Custom footer code" # @TODO |
There was a problem hiding this comment.
Incomplete Chinese translation.
The translation value is still in English rather than Chinese. Consider translating to something like "自定义页脚代码".
🤖 Prompt for AI Agents
In i18n/zh_cn.toml around line 22, the value for custom_footer_code is still in
English; replace the English string with the appropriate Chinese translation
(e.g., "自定义页脚代码") so the key provides the correct Simplified Chinese
localization; ensure quotes and TOML syntax remain valid.
| {% if let Some(custom_footer_code) = page_data.custom_footer_code %} | ||
| {{custom_footer_code}} | ||
| {% else %} | ||
| <p><a href="https://github.com/freedit-org/freedit">GitHub</a></p> | ||
| <p><small>version: <a href="https://github.com/freedit-org/freedit/releases/tag/v{{ crate::VERSION }}">v{{ crate::VERSION }}</a></small></p> | ||
| <p><small>sha256: {{ crate::CURRENT_SHA256.as_str()|truncate(10) }}</small></p> | ||
| <p><small>commit: <a href="https://github.com/freedit-org/freedit/commit/{{ crate::GIT_COMMIT }}">{{ crate::GIT_COMMIT }}</a></small></p> | ||
| {% endif %} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n templates/layout.html | sed -n '140,160p'Repository: freedit-org/freedit
Length of output: 1026
🏁 Script executed:
rg -A 20 "custom_footer_code" src/controller/admin.rsRepository: freedit-org/freedit
Length of output: 546
🏁 Script executed:
rg -B 5 -A 15 "pub.*async fn admin_post" src/controller/admin.rs | head -100Repository: freedit-org/freedit
Length of output: 779
🏁 Script executed:
rg "clean_html" src/Repository: freedit-org/freedit
Length of output: 2592
🏁 Script executed:
rg -A 50 "pub.*async fn admin_post" src/controller/admin.rsRepository: freedit-org/freedit
Length of output: 1947
🏁 Script executed:
rg -B 5 -A 30 "struct SiteConfig" src/Repository: freedit-org/freedit
Length of output: 1882
🏁 Script executed:
rg "custom_footer_code" src/ -B 3 -A 3Repository: freedit-org/freedit
Length of output: 1561
Critical: Potential XSS vulnerability from unsanitized HTML rendering.
Line 148 renders custom_footer_code directly without escaping, allowing arbitrary HTML/JavaScript injection. While the CSP has script-src 'none' which mitigates inline scripts, this still enables:
- HTML injection and page defacement
- Malicious links and phishing attacks
- Potential CSP bypasses through various techniques
The custom_footer_code field is accepted from admin input but notably excluded from sanitization in the admin_post handler—all other HTML-accepting fields (site_name, domain, description, etc.) are sanitized using clean_html(). Apply the same sanitization to custom_footer_code, or escape the output in the template.
🤖 Prompt for AI Agents
In templates/layout.html around lines 147 to 154, custom_footer_code is rendered
raw which permits stored XSS; ensure custom_footer_code is sanitized like other
admin HTML fields before storage or escaped at render time. Fix by applying the
same clean_html() sanitization in the admin_post handler when saving
custom_footer_code (so only safe HTML is stored) and then render the stored
value as safe HTML in the template, or alternately update the template to escape
output unless the value has been sanitized/stored as clean; make the change
consistent with how site_name/domain/description are handled.
|
Forgot to disable html entities, wait please. |
|
Done. |
#383
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.