const HistoryPage = require("../models/historyPage"); const AUDIT_ACTIONS = require("../constants/auditAction"); const historyConfig = require("../utils/contentEditors/historyConfig"); const createPageContentController = require("./_createPageContentController"); const createRenderSingletonPageView = require("./_renderSingletonPageView"); const { ensureUniqueIds } = require("../utils/contentEditorIds"); function getFrontendUrl(req) { return (process.env.FRONTEND_URL || "http://localhost:3000").replace(/\/$/, ""); } function normalizeInternalHistoryHref(rawHref, req) { const href = String(rawHref || "").trim(); if (!href) { return ""; } if (href.startsWith("#")) { return href; } if (href.startsWith("/")) { return href; } const frontendUrl = getFrontendUrl(req); try { const url = new URL(href); const frontendOrigin = new URL(frontendUrl).origin; if (url.origin !== frontendOrigin) { throw new Error("Highlight link only supports internal anchors or frontend paths."); } return `${url.pathname}${url.search}${url.hash}` || "/"; } catch (error) { if (href.startsWith("http://") || href.startsWith("https://")) { throw new Error("Highlight link only supports internal anchors or frontend paths."); } return href.startsWith("?") ? `/about/history${href}` : `/${href.replace(/^\/+/, "")}`; } } function normalizeHistoryForApi(rawData, req) { const data = JSON.parse(JSON.stringify(rawData || {})); const href = data?.highlight?.href; const frontendUrl = getFrontendUrl(req); const backendUrl = `${req.protocol}://${req.get("host")}`.replace(/\/$/, ""); if (!href || href.startsWith("#")) { return data; } if (/^https?:\/\//i.test(href)) { try { const url = new URL(href); const frontendOrigin = new URL(frontendUrl).origin; const backendOrigin = new URL(backendUrl).origin; if (url.origin === frontendOrigin) { data.highlight.href = `${frontendUrl}${url.pathname}${url.search}${url.hash}`; return data; } if (url.origin === backendOrigin) { data.highlight.href = `${frontendUrl}/about/history${url.hash || ""}`; return data; } } catch { data.highlight.href = `${frontendUrl}/about/history`; return data; } data.highlight.href = `${frontendUrl}/about/history`; return data; } data.highlight.href = `${frontendUrl}${href.startsWith("/") ? href : `/${href}`}`; return data; } const controller = createPageContentController({ model: HistoryPage, modelName: "HistoryPage", auditAction: AUDIT_ACTIONS.UPDATE_HISTORY, editorConfig: historyConfig, preparePayload(rawPayload, { req }) { const payload = JSON.parse(JSON.stringify(rawPayload || {})); if (payload.highlight) { payload.highlight.href = normalizeInternalHistoryHref(payload.highlight.href, req); } if (payload.timeline && Array.isArray(payload.timeline.items)) { payload.timeline.items = ensureUniqueIds( payload.timeline.items, (item) => item.id, (item, index) => item.title || item.year || `milestone-${index + 1}`, "milestone", ); } return payload; }, normalizeForApi: normalizeHistoryForApi, }); controller.index = async function index(req, res) { try { return await createRenderSingletonPageView({ model: HistoryPage, editorConfig: historyConfig, view: "admin/history/index", })(req, res); } catch (error) { console.error("history index error:", error); req.flash("error_msg", "Error loading History Management"); return req.session.save(() => res.redirect("/admin/dashboard")); } }; module.exports = controller;