From 545dfec17ff2c8582cd75007da18bf2fb8b23f88 Mon Sep 17 00:00:00 2001 From: Michael SCHAL Date: Wed, 25 Mar 2026 09:26:43 +0100 Subject: [PATCH] fix: add migration endpoint to convert absolute localhost media URLs to relative Images uploaded between the local storage switch and the relative URL fix have http://hostname/uploads/... stored in DB, which is blocked by CSP. POST /api/media/fix-urls (admin only) updates all affected rows to use relative /uploads/... paths. Co-Authored-By: Claude Sonnet 4.6 --- server/routes.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/server/routes.ts b/server/routes.ts index b90dc18..cf33b69 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -659,6 +659,35 @@ export async function registerRoutes(app: Express): Promise { } }); + // One-time migration: fix absolute localhost URLs → relative paths in media table + app.post("/api/media/fix-urls", requireAuth, async (req, res) => { + try { + const user = req.user as User; + if ((user as any).role !== 'admin') { + return res.status(403).json({ error: "Admin only" }); + } + + // Convert any absolute URL like http(s)://hostname/uploads/... → /uploads/... + const result = await pool.query(` + UPDATE media SET + original_url = regexp_replace(original_url, '^https?://[^/]+(/uploads/)', '\\1'), + facebook_feed_url = regexp_replace(facebook_feed_url, '^https?://[^/]+(/uploads/)', '\\1'), + instagram_feed_url = regexp_replace(instagram_feed_url, '^https?://[^/]+(/uploads/)', '\\1'), + instagram_story_url= regexp_replace(instagram_story_url,'^https?://[^/]+(/uploads/)', '\\1') + WHERE + original_url ~ '^https?://[^/]+/uploads/' + OR facebook_feed_url ~ '^https?://[^/]+/uploads/' + OR instagram_feed_url ~ '^https?://[^/]+/uploads/' + OR instagram_story_url ~ '^https?://[^/]+/uploads/' + `); + + res.json({ updated: result.rowCount }); + } catch (error) { + console.error("Error fixing media URLs:", error); + res.status(500).json({ error: "Migration failed" }); + } + }); + // Get media app.get("/api/media", requireAuth, async (req, res) => { try {