Rich-text fields (hero lead, paragraphs, FAQ-style copy, datenschutz sections, etc.) now use a proper toolbar editor - bold/italic/underline buttons plus a per-selection font picker drawn from the same curated font list as the Design tab - instead of typed **markdown** syntax. Content is stored as a small allowlisted HTML subset (strong/em/u/span with a validated data-font/br) and sanitized server-side with sanitize-html on every save (admin/lib/rich-sanitize.js), independent of what the client sends - verified this rejects script tags, event handlers, and made-up font names while preserving legitimate markup, and that re-saving already-sanitized content is a no-op. The Astro site mirrors the same allowlist at render time for defense-in-depth (src/lib/rich-sanitize.ts) and only requests Google Fonts for fonts actually referenced somewhere in content, in addition to the two Design-tab fonts - verified a font used via a data-font span gets its own Google Fonts request and [data-font] CSS rule in the built page, and that unused fonts don't get requested. Migrated the three existing fields that used the old markdown-lite syntax (**bold**/*italic*) to real HTML so they keep rendering correctly under the new system. Also replaces the single long scrolling admin page with a tabbed sidebar (grouped "Inhalte"/"Design") to cut down on clutter, per feedback that the all-in-one-page layout was hard to navigate.
27 lines
1.8 KiB
JavaScript
27 lines
1.8 KiB
JavaScript
/**
|
|
* Curated font list for the "Design" tab's font pickers and the rich-text
|
|
* editor's per-selection font picker. Kept in sync by hand with
|
|
* src/lib/fonts.ts (duplicated because the Astro site is ESM/TS and this
|
|
* backend is CommonJS).
|
|
*/
|
|
const FONT_OPTIONS = [
|
|
{ name: 'Playfair Display', fallback: "Georgia, 'Times New Roman', serif" },
|
|
{ name: 'Lora', fallback: "Georgia, 'Times New Roman', serif" },
|
|
{ name: 'Merriweather', fallback: "Georgia, 'Times New Roman', serif" },
|
|
{ name: 'Libre Baskerville', fallback: "Georgia, 'Times New Roman', serif" },
|
|
{ name: 'DM Serif Display', fallback: "Georgia, 'Times New Roman', serif" },
|
|
{ name: 'Georgia (Systemschrift)', fallback: "Georgia, 'Times New Roman', serif" },
|
|
{ name: 'Inter', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Roboto', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Open Sans', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Poppins', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Montserrat', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Nunito', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Work Sans', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'Source Sans 3', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
{ name: 'System UI (Systemschrift)', fallback: "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" },
|
|
];
|
|
|
|
const FONT_NAMES = FONT_OPTIONS.map((f) => f.name);
|
|
|
|
module.exports = { FONT_OPTIONS, FONT_NAMES };
|