import { getLegalSettingsValues } from '../routes/legal-settings.js'; /** * Strict whitelist of supported placeholders. * Only these placeholders will be replaced in legal page content. * Unknown placeholders remain unchanged. */ const SUPPORTED_PLACEHOLDERS = new Set([ 'COMPANY_NAME', 'LEGAL_ENTITY_NAME', 'RUC_NUMBER', 'COMPANY_ADDRESS', 'COMPANY_CITY', 'COMPANY_COUNTRY', 'SUPPORT_EMAIL', 'LEGAL_EMAIL', 'GOVERNING_LAW', 'JURISDICTION_CITY', 'CURRENT_YEAR', 'LAST_UPDATED_DATE', ]); /** * Replace legal placeholders in content using strict whitelist mapping. * * Rules: * - Only supported placeholders are replaced * - Unknown placeholders remain unchanged * - Missing values are replaced with empty string * - No code execution or dynamic evaluation * - Replacement is pure string substitution * * @param content - The markdown/text content containing {{PLACEHOLDER}} tokens * @param updatedAt - The page's updated_at timestamp (for LAST_UPDATED_DATE) * @returns Content with placeholders replaced */ export async function replaceLegalPlaceholders( content: string, updatedAt?: string ): Promise { if (!content) return content; // Fetch legal settings values from DB const settingsValues = await getLegalSettingsValues(); // Build the full replacement map const replacements: Record = { ...settingsValues }; // Dynamic values replacements['CURRENT_YEAR'] = new Date().getFullYear().toString(); if (updatedAt) { try { const date = new Date(updatedAt); if (!isNaN(date.getTime())) { replacements['LAST_UPDATED_DATE'] = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', }); } else { replacements['LAST_UPDATED_DATE'] = updatedAt; } } catch { replacements['LAST_UPDATED_DATE'] = updatedAt; } } // Replace only whitelisted placeholders using a single regex pass // Matches {{PLACEHOLDER_NAME}} where PLACEHOLDER_NAME is uppercase letters and underscores return content.replace(/\{\{([A-Z_]+)\}\}/g, (match, placeholderName) => { // Only replace if the placeholder is in the whitelist if (!SUPPORTED_PLACEHOLDERS.has(placeholderName)) { return match; // Unknown placeholder - leave unchanged } // Return the value or empty string if missing return replacements[placeholderName] ?? ''; }); }