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 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Sonnet 4.6 committed 2026-03-25 09:26:43 +01:00
1 parent 695d219724
commit 545dfec17f
1 file changed
+29
+29
View File
@@ -659,6 +659,35 @@ export async function registerRoutes(app: Express): Promise<Server> {
}
});
// 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 {