From 6b29c6f06972fe69ece0bbb28717a3b1cdf99ea0 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Thu, 25 Jun 2026 21:21:17 +0100 Subject: [PATCH] feat: add REDIS_PREFIX env var for shared Redis instance namespace --- README.md | 6 ++++-- packages/backend/src/config.rs | 4 ++++ packages/backend/src/store.rs | 16 ++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c4a2fa5..31668f5 100644 --- a/README.md +++ b/README.md @@ -80,15 +80,17 @@ of the notes even if it tried to. | `ALLOW_ADVANCED` | `true` | Allow custom configuration. If set to `false` all notes will be one view only. | | `ALLOW_FILES` | `true` | Allow uploading files. If set to `false`, users will only be allowed to create text notes. | | `ID_LENGTH` | `32` | Set the size of the note `id` in bytes. By default this is `32` bytes. This is useful for reducing link size. _This setting does not affect encryption strength_. | +| `REDIS_PREFIX` | `""` | Optional prefix for all Redis keys. Useful when sharing a Redis instance with other apps via ACL namespaces. | | `VERBOSITY` | `warn` | Verbosity level for the backend. [Possible values](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) are: `error`, `warn`, `info`, `debug`, `trace` | | `THEME_IMAGE` | `""` | Custom image for replacing the logo. Must be publicly reachable | | `THEME_TEXT` | `""` | Custom text for replacing the description below the logo | | `THEME_PAGE_TITLE` | `""` | Custom text the page title | | `THEME_FAVICON` | `""` | Custom url for the favicon. Must be publicly reachable | | `THEME_NEW_NOTE_NOTICE` | `true` | Show the message about how notes are stored in the memory and may be evicted after creating a new note. Defaults to `true`. | -| `THEME_HOME_LINK` | `true` | Show the `/home` link in the footer. Defaults to `true`. | +| `THEME_HOME_LINK` | `true` | Show the `/home` link in the footer. Defaults to `true`. | | `IMPRINT_URL` | `""` | Custom url for an Imprint hosted somewhere else. Must be publicly reachable. Takes precedence above `IMPRINT_HTML`. | | `IMPRINT_HTML` | `""` | Alternative to `IMPRINT_URL`, this can be used to specify the HTML code to show on `/imprint`. Only `IMPRINT_HTML` or `IMPRINT_URL` should be specified, not both. | + ## Deployment > ℹ️ `https` is required otherwise browsers will not support the cryptographic functions. @@ -102,7 +104,7 @@ Docker is the easiest way. There is the [official image here](https://hub.docker ```yaml # docker-compose.yml -version: '3.8' +version: "3.8" services: redis: diff --git a/packages/backend/src/config.rs b/packages/backend/src/config.rs index 91ff8cb..9b1d1ec 100644 --- a/packages/backend/src/config.rs +++ b/packages/backend/src/config.rs @@ -34,6 +34,10 @@ pub static ref ID_LENGTH: u32 = std::env::var("ID_LENGTH") .unwrap_or("32".to_string()) .parse() .unwrap(); +pub static ref REDIS_PREFIX: String = std::env::var("REDIS_PREFIX") + .unwrap_or("".to_string()) + .parse() + .unwrap(); pub static ref ALLOW_FILES: bool = std::env::var("ALLOW_FILES") .unwrap_or("true".to_string()) .parse() diff --git a/packages/backend/src/store.rs b/packages/backend/src/store.rs index 53fe82b..af437eb 100644 --- a/packages/backend/src/store.rs +++ b/packages/backend/src/store.rs @@ -1,6 +1,7 @@ use redis; use redis::Commands; +use crate::config; use crate::note::now; use crate::note::Note; @@ -11,6 +12,10 @@ lazy_static! { .unwrap(); } +fn prefixed(id: &String) -> String { + format!("{}{}", config::REDIS_PREFIX.as_str(), id) +} + fn get_connection() -> Result { let client = redis::Client::open(REDIS_CLIENT.to_string()).map_err(|_| "Unable to connect to redis")?; @@ -28,15 +33,16 @@ pub fn can_reach_redis() -> bool { } pub fn set(id: &String, note: &Note) -> Result<(), &'static str> { + let key = prefixed(id); let serialized = serde_json::to_string(¬e.clone()).unwrap(); let mut conn = get_connection()?; - conn.set::<_, _, ()>(id, serialized) + conn.set::<_, _, ()>(key.as_str(), serialized) .map_err(|_| "Unable to set note in redis")?; match note.expiration { Some(e) => { let seconds = e - now(); - conn.expire::<_, ()>(id, seconds as i64) + conn.expire::<_, ()>(key.as_str(), seconds as i64) .map_err(|_| "Unable to set expiration on note")? } None => {} @@ -45,8 +51,9 @@ pub fn set(id: &String, note: &Note) -> Result<(), &'static str> { } pub fn get(id: &String) -> Result, &'static str> { + let key = prefixed(id); let mut conn = get_connection()?; - let value: Option = conn.get(id).map_err(|_| "Could not load note in redis")?; + let value: Option = conn.get(key.as_str()).map_err(|_| "Could not load note in redis")?; match value { None => return Ok(None), Some(s) => { @@ -57,7 +64,8 @@ pub fn get(id: &String) -> Result, &'static str> { } pub fn del(id: &String) -> Result<(), &'static str> { + let key = prefixed(id); let mut conn = get_connection()?; - conn.del::<_, ()>(id).map_err(|_| "Unable to delete note in redis")?; + conn.del::<_, ()>(key.as_str()).map_err(|_| "Unable to delete note in redis")?; Ok(()) }