feat: update security headers and improve content security policy; enhance hero image component and loading states in public news
All checks were successful
Code Analysis and Production Deploy / analyze (push) Successful in 7m31s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Successful in 2m1s

This commit is contained in:
Torsten Schulz (local)
2026-05-31 14:19:15 +02:00
parent 6983186caf
commit bf1caefde4
9 changed files with 99 additions and 31 deletions

View File

@@ -36,6 +36,15 @@ async function fileExists(filePath) {
}
}
function isAllowedVariantKey(key) {
return /^[A-Za-z0-9_-]+$/.test(key)
}
function appendPathSegment(rootDir, segment) {
if (!isAllowedVariantKey(segment)) return null
return `${rootDir}${path.sep}${segment}`
}
async function listHeroVariants(heroRoot) {
const dirEntries = await fs.readdir(heroRoot, { withFileTypes: true })
const variants = []
@@ -44,12 +53,17 @@ async function listHeroVariants(heroRoot) {
if (!entry.isDirectory()) continue
const key = entry.name
const variantDir = path.join(heroRoot, key)
if (!isAllowedVariantKey(key)) continue
const variantDir = appendPathSegment(heroRoot, key)
if (!variantDir) continue
const mobileFile = 'hero_960.webp'
const desktopFile = 'hero_1600.webp'
const mobilePath = path.join(variantDir, mobileFile)
const desktopPath = path.join(variantDir, desktopFile)
const mobilePath = `${variantDir}${path.sep}${mobileFile}`
const desktopPath = `${variantDir}${path.sep}${desktopFile}`
if (!mobilePath || !desktopPath) continue
if (!(await fileExists(mobilePath)) || !(await fileExists(desktopPath))) {
continue
@@ -57,7 +71,8 @@ async function listHeroVariants(heroRoot) {
let fallbackFile = desktopFile
for (const candidate of FALLBACK_FILE_CANDIDATES) {
if (await fileExists(path.join(variantDir, candidate))) {
const fallbackPath = `${variantDir}${path.sep}${candidate}`
if (fallbackPath && await fileExists(fallbackPath)) {
fallbackFile = candidate
break
}