Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ of the notes even if it tried to.
| `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_. |
| `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_SVG` | `""` | SVG to replace the logo, rendered inline so it inherits `currentColor` and scales with CSS like the default logo. Accepts a public URL (`https://…`) or an absolute path to a file mounted into the container. Takes precedence over `THEME_IMAGE`. |
| `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_CUSTOM_CSS_FILE` | `""` | Path to a CSS file inside the container. When set, the file is served at `/custom.css` and loaded by the frontend, allowing full visual customisation via CSS variables or selectors. Mount the file as a volume: `-v ./my-theme.css:/custom.css:ro` and set `THEME_CUSTOM_CSS_FILE=/custom.css`. |
| `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
Expand Down
1 change: 1 addition & 0 deletions packages/backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ ring = "0.17"
bs62 = "0.1"
byte-unit = "4"
dotenv = "0.15"
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
9 changes: 9 additions & 0 deletions packages/backend/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use byte_unit::Byte;
use std::sync::OnceLock;

pub static THEME_SVG_CONTENT: OnceLock<String> = OnceLock::new();

// Internal
lazy_static! {
Expand Down Expand Up @@ -54,6 +57,10 @@ lazy_static! {
.unwrap_or("".to_string())
.parse()
.unwrap();
pub static ref THEME_SVG: String = std::env::var("THEME_SVG")
.unwrap_or("".to_string())
.parse()
.unwrap();
pub static ref THEME_TEXT: String = std::env::var("THEME_TEXT")
.unwrap_or("".to_string())
.parse()
Expand All @@ -74,4 +81,6 @@ lazy_static! {
.unwrap_or("true".to_string())
.parse()
.unwrap();
pub static ref THEME_CUSTOM_CSS_FILE: String = std::env::var("THEME_CUSTOM_CSS_FILE")
.unwrap_or("".to_string());
}
25 changes: 23 additions & 2 deletions packages/backend/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{collections::HashMap, sync::Arc};
use reqwest;

use axum::{
Router, ServiceExt,
Expand Down Expand Up @@ -34,6 +35,22 @@ async fn main() {
locks: Arc::new(Mutex::new(HashMap::new())),
};

let theme_svg = config::THEME_SVG.as_str();
if !theme_svg.is_empty() {
let content = if theme_svg.starts_with("http://") || theme_svg.starts_with("https://") {
reqwest::get(theme_svg)
.await
.unwrap_or_else(|e| panic!("Failed to fetch THEME_SVG from {theme_svg}: {e}"))
.text()
.await
.unwrap_or_else(|e| panic!("Failed to read THEME_SVG response: {e}"))
} else {
std::fs::read_to_string(theme_svg)
.unwrap_or_else(|e| panic!("Cannot read THEME_SVG file {theme_svg}: {e}"))
};
config::THEME_SVG_CONTENT.set(content).unwrap();
}

if !store::can_reach_redis() {
println!("cannot reach redis");
panic!("cannot reach redis");
Expand All @@ -53,8 +70,12 @@ async fn main() {
let index = format!("{}{}", config::FRONTEND_PATH.to_string(), "/index.html");
let serve_dir =
ServeDir::new(config::FRONTEND_PATH.to_string()).not_found_service(ServeFile::new(index));
let app = Router::new()
.nest("/api", api_routes)
let mut app = Router::new()
.nest("/api", api_routes);
if !config::THEME_CUSTOM_CSS_FILE.is_empty() {
app = app.route_service("/custom.css", ServeFile::new(config::THEME_CUSTOM_CSS_FILE.as_str()));
}
let app = app
.fallback_service(serve_dir)
// Disabled for now, as svelte inlines scripts
// .layer(middleware::from_fn(csp::add_csp_header))
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/status/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ pub struct Status {
pub imprint_html: String,
// Theme
pub theme_image: String,
pub theme_svg: String,
pub theme_text: String,
pub theme_page_title: String,
pub theme_favicon: String,
pub theme_new_note_notice: bool,
pub theme_home_link: bool,
pub theme_custom_css: bool,
}

pub async fn get_status() -> (StatusCode, Json<Status>) {
Expand All @@ -35,7 +37,9 @@ pub async fn get_status() -> (StatusCode, Json<Status>) {
imprint_html: config::IMPRINT_HTML.to_string(),
theme_new_note_notice: *config::THEME_NEW_NOTE_NOTICE,
theme_home_link: *config::THEME_HOME_LINK,
theme_custom_css: !config::THEME_CUSTOM_CSS_FILE.is_empty(),
theme_image: config::THEME_IMAGE.to_string(),
theme_svg: config::THEME_SVG_CONTENT.get().cloned().unwrap_or_default(),
theme_text: config::THEME_TEXT.to_string(),
theme_page_title: config::THEME_PAGE_TITLE.to_string(),
theme_favicon: config::THEME_FAVICON.to_string(),
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/shared/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ export type Status = {
imprint_url: string
imprint_html: string
theme_image: string
theme_svg: string
theme_text: string
theme_favicon: string
theme_page_title: string
theme_new_note_notice: boolean
theme_home_link: boolean
theme_custom_css: boolean
}

async function status() {
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend/src/lib/views/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
<a onclick={reset} href="/">
{#if $status === null}
<!-- waiting for status to load to avoid flashing default logo -->
{:else if $status.theme_svg}
{@html $status.theme_svg}
{:else if $status.theme_image}
<img alt="logo" src={$status.theme_image} />
{:else}
Expand Down
3 changes: 3 additions & 0 deletions packages/frontend/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<svelte:head>
<title>{$status?.theme_page_title || 'cryptgeon'}</title>
<link rel="icon" href={$status?.theme_favicon || '/favicon.png'} />
{#if $status?.theme_custom_css}
<link rel="stylesheet" href="/custom.css" />
{/if}
</svelte:head>

{#await waitLocale() then _}
Expand Down