From 5e71ee1be6c9af9885aefada72bbf64bd11d91e6 Mon Sep 17 00:00:00 2001 From: lew Date: Thu, 9 Apr 2026 14:56:40 +0100 Subject: [PATCH] open registration toggle --- module.nix | 7 +++++++ src/config.rs | 4 ++++ src/web.rs | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/module.nix b/module.nix index 10f26a1..7326c7e 100644 --- a/module.nix +++ b/module.nix @@ -69,6 +69,12 @@ in description = "Maximum length for website URLs. 0 for unlimited."; }; + openRegistration = mkOption { + type = types.bool; + default = true; + description = "Allow new guestbook submissions. When false, the form is hidden and submissions are rejected."; + }; + user = mkOption { type = types.str; default = "guestbook"; @@ -108,6 +114,7 @@ in BOOK_MAX_NAME_LENGTH = toString cfg.maxNameLength; BOOK_MAX_MESSAGE_LENGTH = toString cfg.maxMessageLength; BOOK_MAX_WEBSITE_LENGTH = toString cfg.maxWebsiteLength; + BOOK_OPEN_REGISTRATION = if cfg.openRegistration then "true" else "false"; }; serviceConfig = { Type = "simple"; diff --git a/src/config.rs b/src/config.rs index 64f67c7..84a1128 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,7 @@ pub struct Config { pub max_name_length: usize, pub max_message_length: usize, pub max_website_length: usize, + pub open_registration: bool, } impl Config { @@ -52,6 +53,9 @@ impl Config { .unwrap_or_else(|_| "100".into()) .parse() .map_err(|_| "BOOK_MAX_WEBSITE_LENGTH must be a number")?, + open_registration: env::var("BOOK_OPEN_REGISTRATION") + .map(|v| v != "false") + .unwrap_or(true), }) } } diff --git a/src/web.rs b/src/web.rs index 7a53b51..e6b2de7 100644 --- a/src/web.rs +++ b/src/web.rs @@ -39,11 +39,12 @@ pub fn router(state: Arc) -> Router { async fn index(State(state): State>) -> Html { let entries_dir = state.config.data_dir.join("entries"); let entries = entries::read_approved(&entries_dir); + let form = if state.config.open_registration { FORM_HTML } else { "" }; let html = render::render_page( &state.config.site_title, &state.config.site_url, &entries, - FORM_HTML, + form, ); Html(html) } @@ -52,6 +53,10 @@ async fn submit( State(state): State>, Form(form): Form, ) -> Html { + if !state.config.open_registration { + return Html("Submissions are closed.".to_string()); + } + // Honeypot check — silently discard if state.config.honeypot && !form.url.is_empty() { return Html("Thanks! Your message is pending approval.".to_string());