From: PhiTux Date: Sat, 11 Oct 2025 20:00:27 +0000 (+0200) Subject: added subpath-fix X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=2d23dea10e6e949d61f60f158e056ba7dbbeb09a;p=DailyTxT.git added subpath-fix --- diff --git a/README.md b/README.md index 004da26..f345567 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,9 @@ services: # After how many days shall the login-cookie expire? - LOGOUT_AFTER_DAYS=40 + + # Set the BASE_PATH if you are running DailyTxT under a subpath (e.g. /dailytxt). + # - BASE_PATH=/dailytxt ports: # Change the left port to your needs. # You often would only see 8000:80. But this way, port 8000 is publicly accessible (without TLS!). diff --git a/backend/handlers/admin.go b/backend/handlers/admin.go index 897b6ba..0315c0c 100644 --- a/backend/handlers/admin.go +++ b/backend/handlers/admin.go @@ -68,6 +68,7 @@ func validateAdminPasswordInRequest(r *http.Request) bool { // - all users with their disk usage // - free disk space // - migration-info +// - app settings (env-vars) func GetAdminData(w http.ResponseWriter, r *http.Request) { if !validateAdminPasswordInRequest(r) { http.Error(w, "Invalid admin password", http.StatusUnauthorized) diff --git a/backend/utils/helpers.go b/backend/utils/helpers.go index 664cdb5..5f9f031 100644 --- a/backend/utils/helpers.go +++ b/backend/utils/helpers.go @@ -43,6 +43,7 @@ type AppSettings struct { AllowedHosts []string `json:"allowed_hosts"` Indent int `json:"indent"` AllowRegistration bool `json:"allow_registration"` + BasePath string `json:"base_path"` } // Global settings @@ -102,6 +103,7 @@ func InitSettings() error { AllowedHosts: []string{}, Indent: 0, AllowRegistration: false, + BasePath: "/", } fmt.Print("\nDetected the following settings:\n================\n") @@ -160,6 +162,11 @@ func InitSettings() error { } fmt.Printf("Allow Registration: %t\n", Settings.AllowRegistration) + if basePath := os.Getenv("BASE_PATH"); basePath != "" { + Settings.BasePath = basePath + } + fmt.Printf("Base Path: %s\n", Settings.BasePath) + fmt.Print("================\n\n") // Create data directory if it doesn't exist diff --git a/docker-compose.yml b/docker-compose.yml index d4cdb3b..2c1cdb7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,9 @@ services: # After how many days shall the login-cookie expire? - LOGOUT_AFTER_DAYS=40 + + # Set the BASE_PATH if you are running DailyTxT under a subpath (e.g. /dailytxt). + # - BASE_PATH=/dailytxt ports: # Change the left port to your needs. # You often would only see 8000:80. But this way, port 8000 is publicly accessible (without TLS!). diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 68ca972..f53569d 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,18 +1,38 @@ #!/bin/sh set -e -# Start the Go backend in background -# Environment variables consumed by backend (see utils.InitSettings): -# DATA_PATH, DEVELOPMENT, SECRET_TOKEN, LOGOUT_AFTER_DAYS, ALLOWED_HOSTS, INDENT, ALLOW_REGISTRATION, ADMIN_PASSWORD - # Ensure data directory exists mkdir -p "${DATA_PATH:-/data}" -# Run backend +# Run backend in background /usr/local/bin/dailytxt & BACKEND_PID=$! echo "Started backend (PID $BACKEND_PID)" +# Edit some files to make dailytxt work on a subpath provided by BASE_PATH +if [ -n "${BASE_PATH:-}" ]; then + echo "Configuring frontend for BASE_PATH: $BASE_PATH" + + # remove leading and trailing slash if exists + BASE_PATH="${BASE_PATH#/}" + BASE_PATH="${BASE_PATH%/}" + # print the BASE_PATH being used + echo "Using BASE_PATH: '$BASE_PATH'" + + # Update base href in app.html + sed -i "s|href=\"/|href=\"|g" /usr/share/nginx/html/index.html + + # Update base path in app.html + sed -i "s|base: \"|base: \"/$BASE_PATH|g" /usr/share/nginx/html/index.html + + # Update import-paths in app.html + sed -i "s|import(\"|import(\"/$BASE_PATH|g" /usr/share/nginx/html/index.html + + # Update manifest.webmanifest base + sed -i "s|start_url\":\"/|start_url\":\"/$BASE_PATH|g" /usr/share/nginx/html/manifest.webmanifest + sed -i "s|src\":\"|src\":\"/$BASE_PATH|g" /usr/share/nginx/html/manifest.webmanifest +fi + # Start nginx in foreground exec nginx -g 'daemon off;' diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index badf74a..3ab6c52 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -67,7 +67,7 @@ "error_reordering_files": "Error changing the order of files", "error_saving": "Error saving the text!" }, - "written_on": "Written on:" + "written_on": "Posted on:" }, "login": { "alert": { diff --git a/frontend/src/lib/settings/Statistics.svelte b/frontend/src/lib/settings/Statistics.svelte index 2a3463f..3fad114 100644 --- a/frontend/src/lib/settings/Statistics.svelte +++ b/frontend/src/lib/settings/Statistics.svelte @@ -11,6 +11,7 @@ import { goto } from '$app/navigation'; import { selectedDate } from '$lib/calendarStore.js'; import { formatBytes } from '$lib/helpers'; + import { resolve } from '$app/paths'; const { t } = getTranslate(); const tolgee = getTolgee(['language']); @@ -251,7 +252,7 @@ } // Navigate to write page - goto('/write'); + goto(resolve('/write')); } function initTooltips() { diff --git a/frontend/src/routes/(authed)/+layout.svelte b/frontend/src/routes/(authed)/+layout.svelte index 55de698..5f8f83b 100644 --- a/frontend/src/routes/(authed)/+layout.svelte +++ b/frontend/src/routes/(authed)/+layout.svelte @@ -3,6 +3,7 @@ import Fa, { FaLayers } from 'svelte-fa'; import { goto } from '$app/navigation'; import { onDestroy, onMount } from 'svelte'; + import { resolve } from '$app/paths'; import { readingMode, settings, @@ -182,10 +183,10 @@ }); $effect(() => { - if ($readingMode === true && page.url.pathname !== '/read') { - goto('/read'); + if ($readingMode === true && !page.url.pathname.endsWith('/read')) { + goto(resolve('/read')); } else if ($readingMode === false) { - goto('/write'); + goto(resolve('/write')); } }); @@ -200,7 +201,7 @@ if (!$isAuthenticated && needsReauth) { // Save current route for return after reauth localStorage.setItem('returnAfterReauth', window.location.pathname); - goto('/reauth'); + goto(resolve('/reauth')); return; // Stop further initialization } @@ -216,9 +217,9 @@ getVersionInfo(); loadTags(); - if (page.url.pathname === '/read') { + if (page.url.pathname.endsWith('/read')) { $readingMode = true; - } else if (page.url.pathname === '/write') { + } else if (page.url.pathname.endsWith('/write')) { $readingMode = false; } @@ -248,9 +249,9 @@ .then(() => { localStorage.removeItem('user'); if (errorCode) { - goto(`/login?error=${errorCode}`); + goto(resolve(`/login?error=${errorCode}`)); } else { - goto('/login'); + goto(resolve('/login')); } }) .catch((error) => { diff --git a/frontend/src/routes/(authed)/read/+page.js b/frontend/src/routes/(authed)/read/+page.js index 68c6d4d..345f985 100644 --- a/frontend/src/routes/(authed)/read/+page.js +++ b/frontend/src/routes/(authed)/read/+page.js @@ -1,8 +1,9 @@ import {redirect} from '@sveltejs/kit' +import { resolve } from '$app/paths'; export const load = () => { const user = localStorage.getItem('user'); if (!user) { - throw redirect(307, '/login'); + throw redirect(307, resolve('/login')); } } \ No newline at end of file diff --git a/frontend/src/routes/(authed)/read/+page.svelte b/frontend/src/routes/(authed)/read/+page.svelte index 877ecd3..18af7a0 100644 --- a/frontend/src/routes/(authed)/read/+page.svelte +++ b/frontend/src/routes/(authed)/read/+page.svelte @@ -609,8 +609,13 @@ .log { border-radius: 15px; - margin-left: 1rem; - margin-right: 1rem; + } + + @media screen and (min-width: 576px) { + .log { + margin-left: 1rem; + margin-right: 1rem; + } } :global(body[data-bs-theme='dark']) .log { diff --git a/frontend/src/routes/(authed)/write/+page.js b/frontend/src/routes/(authed)/write/+page.js index 68c6d4d..345f985 100644 --- a/frontend/src/routes/(authed)/write/+page.js +++ b/frontend/src/routes/(authed)/write/+page.js @@ -1,8 +1,9 @@ import {redirect} from '@sveltejs/kit' +import { resolve } from '$app/paths'; export const load = () => { const user = localStorage.getItem('user'); if (!user) { - throw redirect(307, '/login'); + throw redirect(307, resolve('/login')); } } \ No newline at end of file diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index d26df27..3809d87 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -12,6 +12,7 @@ import { FormatIcu } from '@tolgee/format-icu'; import { darkMode } from '$lib/settingsStore.js'; import { registerSW } from 'virtual:pwa-register'; + import { resolve } from '$app/paths'; const tolgee = Tolgee() .use(DevTools()) @@ -74,7 +75,7 @@ .get(API_URL + '/users/logout') .then(() => { localStorage.removeItem('user'); - goto(`/login?error=${error.response.status}`); + goto(resolve(`/login?error=${error.response.status}`)); }) .catch((error) => { console.error(error); @@ -103,7 +104,7 @@ calculateResize(); // if on login page, generate neon mesh - if (page.url.pathname === '/login') { + if (page.url.pathname.endsWith('/login')) { generateNeonMesh($darkMode); } @@ -260,7 +261,7 @@ } }); - let routeToFromLoginKey = $derived(page.url.pathname === '/login'); + let routeToFromLoginKey = $derived(page.url.pathname.endsWith('/login'));
diff --git a/frontend/src/routes/+page.js b/frontend/src/routes/+page.js index 0dde40f..71eb4a9 100644 --- a/frontend/src/routes/+page.js +++ b/frontend/src/routes/+page.js @@ -1,6 +1,7 @@ import { redirect } from "@sveltejs/kit"; +import { resolve } from '$app/paths'; export function load() { // Redirect to the /write route - throw redirect(307, "/write"); + throw redirect(307, resolve("/write")); } \ No newline at end of file diff --git a/frontend/src/routes/[...missing]/+page.js b/frontend/src/routes/[...missing]/+page.js index edf1cc9..f487fb0 100644 --- a/frontend/src/routes/[...missing]/+page.js +++ b/frontend/src/routes/[...missing]/+page.js @@ -1,8 +1,9 @@ import { redirect } from '@sveltejs/kit'; +import { resolve } from '$app/paths'; // Catch-all for unknown routes: redirect to /write (primary app surface) // If /write itself handles auth, unauthenticated users will still be bounced to /login there. // Adjust here if you later want a different fallback (e.g. redirect to /login when not authenticated). export function load() { - throw redirect(307, '/write'); + throw redirect(307, resolve('/write')); } diff --git a/frontend/src/routes/login/+page.js b/frontend/src/routes/login/+page.js index 9ad951e..0cad61c 100644 --- a/frontend/src/routes/login/+page.js +++ b/frontend/src/routes/login/+page.js @@ -1,8 +1,9 @@ import {redirect} from '@sveltejs/kit' +import { resolve } from '$app/paths'; export const load = () => { const user = localStorage.getItem('user'); if (user) { - throw redirect(307, '/write'); + throw redirect(307, resolve('/write')); } } \ No newline at end of file diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte index 3ea3496..ebded22 100644 --- a/frontend/src/routes/login/+page.svelte +++ b/frontend/src/routes/login/+page.svelte @@ -8,6 +8,7 @@ import { getTranslate, getTolgee } from '@tolgee/svelte'; import { isAuthenticated, loadFlagEmoji } from '$lib/helpers.js'; import { fade } from 'svelte/transition'; + import { resolve } from '$app/paths'; const { t } = getTranslate(); const tolgee = getTolgee(['language']); @@ -187,7 +188,7 @@ } else { $isAuthenticated = true; localStorage.setItem('user', response.data.username); - goto('/write'); + goto(resolve('/write')); } }) .catch((error) => { diff --git a/frontend/src/routes/reauth/+page.svelte b/frontend/src/routes/reauth/+page.svelte index 59bdb61..e59e5de 100644 --- a/frontend/src/routes/reauth/+page.svelte +++ b/frontend/src/routes/reauth/+page.svelte @@ -6,6 +6,7 @@ import { generateNeonMesh, isAuthenticated } from '$lib/helpers'; import { getTranslate } from '@tolgee/svelte'; import logo from '$lib/assets/locked_heart_with_keyhole.svg'; + import { resolve } from '$app/paths'; const { t } = getTranslate(); @@ -40,7 +41,7 @@ $isAuthenticated = true; // Authentication successful - return to original route - const returnPath = localStorage.getItem('returnAfterReauth') || '/write'; + const returnPath = localStorage.getItem('returnAfterReauth') || resolve('/write'); localStorage.removeItem('returnAfterReauth'); goto(returnPath); } else {