diff --git a/entrypoint.sh b/entrypoint.sh index 7f7e964..c53c564 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,11 +1,10 @@ #!/bin/sh -set -e DATA_DIR=${SITEFORGE_DATA_DIR:-/app/data} SEED_DIR=/app/data-seed # Ensure the data directory exists (in case the volume was not mounted) -mkdir -p "$DATA_DIR" +mkdir -p "$DATA_DIR" || true # Seed each default JSON file only when missing. # This runs on first boot or a fresh volume, but never overwrites existing data. @@ -18,7 +17,7 @@ if [ -d "$SEED_DIR" ]; then if [ ! -f "$target_file" ]; then echo "[siteforge] No $base_name found. Seeding from image defaults..." - cp "$seed_file" "$target_file" + cp "$seed_file" "$target_file" || echo "[siteforge] Warning: could not seed $base_name — check volume permissions on $DATA_DIR" fi done fi @@ -99,8 +98,8 @@ console.log(`[siteforge] Merged seeded platform links into ${targetFile}`) NODE } -merge_seed_platform_links "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json" -merge_seed_platform_links "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json" +merge_seed_platform_links "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json" || true +merge_seed_platform_links "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json" || true # Backfill missing lesson releasedAt values from seeded defaults on upgrades. # This keeps persistent volumes compatible with release-date access gating. @@ -207,8 +206,8 @@ console.log(`[siteforge] Backfilled missing releasedAt values in ${targetFile}`) NODE } -merge_seed_study_release_dates "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json" -merge_seed_study_release_dates "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json" +merge_seed_study_release_dates "$DATA_DIR/admin-content.json" "$SEED_DIR/admin-content.json" || true +merge_seed_study_release_dates "$DATA_DIR/admin-content-draft.json" "$SEED_DIR/admin-content-draft.json" || true export SITEFORGE_DATA_DIR="$DATA_DIR" exec node server.js diff --git a/package.json b/package.json index 76a209f..ae1a9ee 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "siteforge", "private": true, - "version": "2.0.39", + "version": "2.0.40", "type": "module", "scripts": { "dev": "vite", diff --git a/server/helpers.js b/server/helpers.js index a5b2166..9245900 100644 --- a/server/helpers.js +++ b/server/helpers.js @@ -134,6 +134,11 @@ export function sanitizeFeaturedLinks(value) { .slice(0, 30) : [] + const sanitizeStringArray = (val, limit) => + Array.isArray(val) + ? val.filter(s => typeof s === 'string').map(s => s.trim()).filter(Boolean).slice(0, limit) + : [] + return { id: typeof item.id === 'string' && item.id.trim() ? item.id.trim() : randomUUID(), title: typeof item.title === 'string' ? item.title.trim().slice(0, 140) : '', @@ -142,6 +147,11 @@ export function sanitizeFeaturedLinks(value) { url: sanitizeUrl(item.url), embedUrl: sanitizeUrl(item.embedUrl), showNotes: typeof item.showNotes === 'string' ? item.showNotes.trim().slice(0, 10000) : '', + showNotesSummary: typeof item.showNotesSummary === 'string' ? item.showNotesSummary.trim().slice(0, 1000) : '', + showNotesThemes: sanitizeStringArray(item.showNotesThemes, 20), + showNotesScripture: sanitizeStringArray(item.showNotesScripture, 30), + showNotesQuotes: sanitizeStringArray(item.showNotesQuotes, 20), + showNotesResources: sanitizeStringArray(item.showNotesResources, 30), discussionQuestions, } }) @@ -152,6 +162,11 @@ export function sanitizeFeaturedLinks(value) { item.url || item.embedUrl || item.showNotes || + item.showNotesSummary || + item.showNotesThemes.length > 0 || + item.showNotesScripture.length > 0 || + item.showNotesQuotes.length > 0 || + item.showNotesResources.length > 0 || item.discussionQuestions.length > 0, ) }