Compare commits

..

5 Commits

Author SHA1 Message Date
db0963a7db chore(test): remove non-business logic config tests
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 25s
Build & Deploy / 🧪 QA (push) Successful in 1m24s
Build & Deploy / 🏗️ Build (push) Successful in 2m37s
Build & Deploy / 🚀 Deploy (push) Successful in 26s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 49s
Build & Deploy / 🔔 Notify (push) Successful in 3s
2026-08-17 18:31:53 +02:00
aac0529bb6 fix(infra): replace legacy klz fallback references with etib across docker compose and test scripts
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 19s
Build & Deploy / 🧪 QA (push) Successful in 1m25s
Build & Deploy / 🏗️ Build (push) Successful in 2m44s
Build & Deploy / 🚀 Deploy (push) Successful in 24s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 51s
Build & Deploy / 🔔 Notify (push) Successful in 3s
2026-08-17 18:31:29 +02:00
5006163ddf fix(ci): update proxy matcher and traefik public router for image optimizer loopback
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 19s
Build & Deploy / 🧪 QA (push) Successful in 1m31s
Build & Deploy / 🏗️ Build (push) Successful in 2m34s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 50s
Build & Deploy / 🔔 Notify (push) Successful in 3s
2026-08-17 18:22:45 +02:00
35fb31249a fix(content): keep pipe diameter unchanged at 400er Rohr / 400mm pipe
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Successful in 1m19s
Build & Deploy / 🏗️ Build (push) Successful in 2m50s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 49s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-08-13 09:48:45 +02:00
120ba0488c fix(content): update HDD drilling max distance from 250m to 400m in DE and EN kompetenzen
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🧪 QA (push) Has been cancelled
2026-08-13 09:47:36 +02:00
18 changed files with 106 additions and 80 deletions

View File

@@ -104,7 +104,7 @@ layout: "fullBleed"
icon: "hdd", icon: "hdd",
lists: [ lists: [
[ [
"Horizontalspülbohrverfahren (bis 250m)", "Horizontalspülbohrverfahren (bis 400m)",
"Horizontalspülbohrverfahren (bis 400er Rohr)", "Horizontalspülbohrverfahren (bis 400er Rohr)",
"Erdrakete (bis 15m DÖ-Länge)", "Erdrakete (bis 15m DÖ-Länge)",
"Erdrakete (bis 160er Rohr)" "Erdrakete (bis 160er Rohr)"

View File

@@ -104,7 +104,7 @@ layout: "fullBleed"
icon: "hdd", icon: "hdd",
lists: [ lists: [
[ [
"Horizontal directional drilling (up to 250m)", "Horizontal directional drilling (up to 400m)",
"Horizontal directional drilling (up to 400mm pipe)", "Horizontal directional drilling (up to 400mm pipe)",
"Earth rocket (up to 15m crossing length)", "Earth rocket (up to 15m crossing length)",
"Earth rocket (up to 160mm pipe)" "Earth rocket (up to 160mm pipe)"

View File

@@ -57,9 +57,10 @@ services:
sh -c "pnpm install --no-frozen-lockfile && pnpm next dev --webpack --hostname 0.0.0.0 --port 3001" sh -c "pnpm install --no-frozen-lockfile && pnpm next dev --webpack --hostname 0.0.0.0 --port 3001"
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.services.${PROJECT_NAME:-klz}-app-svc.loadbalancer.server.port=3001" - "traefik.http.services.${PROJECT_NAME:-etib}-app-svc.loadbalancer.server.port=3001"
- "traefik.docker.network=infra" - "traefik.docker.network=infra"
networks: networks:
default: default:
name: ${COMPOSE_PROJECT_NAME:-etib}-dev-internal name: ${COMPOSE_PROJECT_NAME:-etib}-dev-internal

View File

@@ -15,46 +15,47 @@ services:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
# HTTP ⇒ HTTPS redirect # HTTP ⇒ HTTPS redirect
- "traefik.http.routers.${PROJECT_NAME:-klz}-web.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}" - "traefik.http.routers.${PROJECT_NAME:-etib}-web.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-web.entrypoints=web" - "traefik.http.routers.${PROJECT_NAME:-etib}-web.entrypoints=web"
- "traefik.http.routers.${PROJECT_NAME:-klz}-web.middlewares=redirect-https" - "traefik.http.routers.${PROJECT_NAME:-etib}-web.middlewares=redirect-https"
# HTTPS router (Standard) # HTTPS router (Standard)
- "traefik.http.routers.${PROJECT_NAME:-klz}.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}" - "traefik.http.routers.${PROJECT_NAME:-etib}.rule=${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}"
- "traefik.http.routers.${PROJECT_NAME:-klz}.entrypoints=${TRAEFIK_ENTRYPOINT:-web}" - "traefik.http.routers.${PROJECT_NAME:-etib}.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz}.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}" - "traefik.http.routers.${PROJECT_NAME:-etib}.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz}.tls=${TRAEFIK_TLS:-false}" - "traefik.http.routers.${PROJECT_NAME:-etib}.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz}.service=${PROJECT_NAME:-klz}-app-svc" - "traefik.http.routers.${PROJECT_NAME:-etib}.service=${PROJECT_NAME:-etib}-app-svc"
- "traefik.http.routers.${PROJECT_NAME:-klz}.middlewares=${AUTH_MIDDLEWARE:-etib-ratelimit,etib-forward,etib-compress}" - "traefik.http.routers.${PROJECT_NAME:-etib}.middlewares=${AUTH_MIDDLEWARE:-etib-ratelimit,etib-forward,etib-compress}"
# Public Router paths that bypass Gatekeeper auth (health, SEO, static assets, OG images) # Public Router paths that bypass Gatekeeper auth (health, SEO, static assets, OG images)
- "traefik.http.routers.${PROJECT_NAME:-klz}-public.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}) && PathRegexp(`^/([a-z]{2}/)?(health|login|gatekeeper|uploads|media|assets|robots\\.txt|manifest\\.webmanifest|sitemap(-[0-9]+)?\\.xml|(.*/)?api/og(/.*)?|(.*/)?opengraph-image.*)`)" - "traefik.http.routers.${PROJECT_NAME:-etib}-public.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}) && PathRegexp(`^/([a-z]{2}/)?(health|login|gatekeeper|uploads|media|assets|_next|robots\\.txt|manifest\\.webmanifest|sitemap(-[0-9]+)?\\.xml|(.*/)?api/og(/.*)?|(.*/)?opengraph-image.*)`)"
- "traefik.http.routers.${PROJECT_NAME:-klz}-public.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-public.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-public.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-public.service=${PROJECT_NAME:-klz}-app-svc"
- "traefik.http.routers.${PROJECT_NAME:-klz}-public.priority=2000"
- "traefik.http.services.${PROJECT_NAME:-klz}-app-svc.loadbalancer.server.port=3000" - "traefik.http.routers.${PROJECT_NAME:-etib}-public.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-etib}-public.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-etib}-public.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-etib}-public.service=${PROJECT_NAME:-etib}-app-svc"
- "traefik.http.routers.${PROJECT_NAME:-etib}-public.priority=2000"
- "traefik.http.services.${PROJECT_NAME:-etib}-app-svc.loadbalancer.server.port=3000"
- "traefik.docker.network=infra" - "traefik.docker.network=infra"
# Middlewares # Middlewares
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-compress.compress=true" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-compress.compress=true"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-ratelimit.ratelimit.average=100" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-ratelimit.ratelimit.burst=50" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-ratelimit.ratelimit.burst=50"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-forward.headers.customrequestheaders.X-Forwarded-Proto=https" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-forward.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-forward.headers.customrequestheaders.X-Forwarded-Ssl=on" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-forward.headers.customrequestheaders.X-Forwarded-Ssl=on"
# Login redirect the app's middleware sends users to /login but login lives at /gatekeeper/login # Login redirect the app's middleware sends users to /login but login lives at /gatekeeper/login
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-loginredirect.redirectregex.regex=^https?://([^/]+)/([a-z]{2}/)?login(.*)" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-loginredirect.redirectregex.regex=^https?://([^/]+)/([a-z]{2}/)?login(.*)"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-loginredirect.redirectregex.replacement=https://$${1}/gatekeeper/login$${3}" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-loginredirect.redirectregex.replacement=https://$${1}/gatekeeper/login$${3}"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-loginredirect.redirectregex.permanent=false" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-loginredirect.redirectregex.permanent=false"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}) && PathRegexp(`^/([a-z]{2}/)?login`)" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}) && PathRegexp(`^/([a-z]{2}/)?login`)"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.entrypoints=${TRAEFIK_ENTRYPOINT:-web}" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.tls=${TRAEFIK_TLS:-false}" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.middlewares=${PROJECT_NAME:-klz}-loginredirect" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.middlewares=${PROJECT_NAME:-etib}-loginredirect"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.service=${PROJECT_NAME:-klz}-app-svc" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.service=${PROJECT_NAME:-etib}-app-svc"
- "traefik.http.routers.${PROJECT_NAME:-klz}-loginredir.priority=2002" - "traefik.http.routers.${PROJECT_NAME:-etib}-loginredir.priority=2002"
etib-gatekeeper: etib-gatekeeper:
profiles: [ "gatekeeper" ] profiles: [ "gatekeeper" ]
@@ -64,7 +65,7 @@ services:
default: default:
infra: infra:
aliases: aliases:
- ${PROJECT_NAME:-klz}-gatekeeper - ${PROJECT_NAME:-etib}-gatekeeper
env_file: env_file:
- ${ENV_FILE:-.env} - ${ENV_FILE:-.env}
environment: environment:
@@ -73,19 +74,20 @@ services:
NODE_ENV: production NODE_ENV: production
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.services.${PROJECT_NAME:-klz}-gatekeeper-svc.loadbalancer.server.port=3000" - "traefik.http.services.${PROJECT_NAME:-etib}-gatekeeper-svc.loadbalancer.server.port=3000"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-auth.forwardauth.address=http://${PROJECT_NAME:-klz}-gatekeeper:3000/gatekeeper/api/verify" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-auth.forwardauth.address=http://${PROJECT_NAME:-etib}-gatekeeper:3000/gatekeeper/api/verify"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-auth.forwardauth.trustForwardHeader=true" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-auth.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.${PROJECT_NAME:-klz}-auth.forwardauth.authResponseHeaders=X-Auth-User" - "traefik.http.middlewares.${PROJECT_NAME:-etib}-auth.forwardauth.authResponseHeaders=X-Auth-User"
- "traefik.docker.network=infra" - "traefik.docker.network=infra"
# Gatekeeper Public Router (Login/Auth UI) — basePath mode on main domain # Gatekeeper Public Router (Login/Auth UI) — basePath mode on main domain
- "traefik.http.routers.${PROJECT_NAME:-klz}-gatekeeper.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}) && PathPrefix(`/gatekeeper`)" - "traefik.http.routers.${PROJECT_NAME:-etib}-gatekeeper.rule=(${TRAEFIK_HOST_RULE:-Host(`${TRAEFIK_HOST:-e-tib.com}`) || Host(`staging.${TRAEFIK_HOST:-e-tib.com}`) || Host(`testing.${TRAEFIK_HOST:-e-tib.com}`)}) && PathPrefix(`/gatekeeper`)"
- "traefik.http.routers.${PROJECT_NAME:-klz}-gatekeeper.entrypoints=${TRAEFIK_ENTRYPOINT:-web}" - "traefik.http.routers.${PROJECT_NAME:-etib}-gatekeeper.entrypoints=${TRAEFIK_ENTRYPOINT:-web}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-gatekeeper.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}" - "traefik.http.routers.${PROJECT_NAME:-etib}-gatekeeper.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-gatekeeper.tls=${TRAEFIK_TLS:-false}" - "traefik.http.routers.${PROJECT_NAME:-etib}-gatekeeper.tls=${TRAEFIK_TLS:-false}"
- "traefik.http.routers.${PROJECT_NAME:-klz}-gatekeeper.service=${PROJECT_NAME:-klz}-gatekeeper-svc" - "traefik.http.routers.${PROJECT_NAME:-etib}-gatekeeper.service=${PROJECT_NAME:-etib}-gatekeeper-svc"
- "traefik.http.routers.${PROJECT_NAME:-klz}-gatekeeper.priority=2001" - "traefik.http.routers.${PROJECT_NAME:-etib}-gatekeeper.priority=2001"
etib-db: etib-db:
image: postgres:15-alpine image: postgres:15-alpine

View File

@@ -1,6 +1,7 @@
{ {
"name": "e-tib-nextjs", "name": "e-tib-nextjs",
"version": "2.4.54", "version": "2.4.58",
"type": "module", "type": "module",
"private": true, "private": true,
"packageManager": "pnpm@10.18.3", "packageManager": "pnpm@10.18.3",

View File

@@ -7,11 +7,12 @@ export default createMiddleware({
}); });
export const config = { export const config = {
// Match all pathnames except for // Match all pathnames except for:
// - /api (API routes) // - /api (API routes)
// - /stats (Analytics proxy) // - /stats (Analytics proxy)
// - /_next (Next.js internals) // - /_next (Next.js internals & image optimizer)
// - /_static (inside /public) // - /assets, /_static (static files in /public)
// - all root files inside /public (e.g. /favicon.ico) // - all files with an extension (e.g. /favicon.ico, .JPG, .png, .webp, .svg)
matcher: ['/((?!api|stats|_next|assets|_static|_vercel|[\\w-]+\\.\\w+).*)'] matcher: ['/((?!api|stats|_next|assets|_static|_vercel|.*\\..*).*)']
}; };

View File

@@ -31,22 +31,23 @@ fi
get_media_path() { get_media_path() {
case "$1" in case "$1" in
local) echo "$LOCAL_MEDIA_DIR" ;; local) echo "$LOCAL_MEDIA_DIR" ;;
testing) echo "/var/lib/docker/volumes/klz-testing_klz_media_data/_data" ;; testing) echo "/var/lib/docker/volumes/etib-testing_etib_media_data/_data" ;;
staging) echo "/var/lib/docker/volumes/klz-staging_klz_media_data/_data" ;; staging) echo "/var/lib/docker/volumes/etib-staging_etib_media_data/_data" ;;
prod|production) echo "/var/lib/docker/volumes/klz-cablescom_klz_media_data/_data" ;; prod|production) echo "/var/lib/docker/volumes/e-tibcom_etib_media_data/_data" ;;
*) echo "❌ Unknown environment: $1"; exit 1 ;; *) echo "❌ Unknown environment: $1"; exit 1 ;;
esac esac
} }
get_app_container() { get_app_container() {
case "$1" in case "$1" in
testing) echo "klz-testing-klz-app-1" ;; testing) echo "etib-testing-etib-app-1" ;;
staging) echo "klz-staging-klz-app-1" ;; staging) echo "etib-staging-etib-app-1" ;;
prod|production) echo "klz-cablescom-klz-app-1" ;; prod|production) echo "e-tibcom-etib-app-1" ;;
*) echo "" ;; *) echo "" ;;
esac esac
} }
SRC_PATH=$(get_media_path "$SOURCE_ENV") SRC_PATH=$(get_media_path "$SOURCE_ENV")
TGT_PATH=$(get_media_path "$TARGET_ENV") TGT_PATH=$(get_media_path "$TARGET_ENV")
TGT_CONTAINER=$(get_app_container "$TARGET_ENV") TGT_CONTAINER=$(get_app_container "$TARGET_ENV")

View File

@@ -15,7 +15,8 @@ export NEXT_PUBLIC_CI=true
export CI=true export CI=true
docker network create infra 2>/dev/null || true docker network create infra 2>/dev/null || true
docker volume create klz_db_data 2>/dev/null || true docker volume create etib_db_data 2>/dev/null || true
# 2. Start infra services (DB, CMS, Gatekeeper) # 2. Start infra services (DB, CMS, Gatekeeper)
echo "📦 Starting infrastructure services..." echo "📦 Starting infrastructure services..."

View File

@@ -7,7 +7,8 @@ const targetUrl =
process.env.NEXT_PUBLIC_BASE_URL || process.env.NEXT_PUBLIC_BASE_URL ||
'http://localhost:3000'; 'http://localhost:3000';
const limit = process.env.ASSET_CHECK_LIMIT ? parseInt(process.env.ASSET_CHECK_LIMIT) : 20; const limit = process.env.ASSET_CHECK_LIMIT ? parseInt(process.env.ASSET_CHECK_LIMIT) : 20;
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
async function main() { async function main() {
console.log(`\n🚀 Starting Strict Asset Integrity Check for: ${targetUrl}`); console.log(`\n🚀 Starting Strict Asset Integrity Check for: ${targetUrl}`);
@@ -20,9 +21,10 @@ async function main() {
try { try {
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`); console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
const response = await axios.get(sitemapUrl, { const response = await axios.get(sitemapUrl, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
}); });
const $ = cheerio.load(response.data, { xmlMode: true }); const $ = cheerio.load(response.data, { xmlMode: true });
urls = $('url loc') urls = $('url loc')
.map((i, el) => $(el).text()) .map((i, el) => $(el).text())
@@ -64,7 +66,7 @@ async function main() {
// Inject Gatekeeper session bypassing auth screens // Inject Gatekeeper session bypassing auth screens
await page.setCookie({ await page.setCookie({
name: 'klz_gatekeeper_session', name: authCookieName,
value: gatekeeperPassword, value: gatekeeperPassword,
domain: new URL(targetUrl).hostname, domain: new URL(targetUrl).hostname,
path: '/', path: '/',

View File

@@ -3,7 +3,8 @@ import axios from 'axios';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
// Utility for hardcoded delays // Utility for hardcoded delays
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -20,7 +21,7 @@ async function main() {
while (Date.now() - startTime < maxWaitMs) { while (Date.now() - startTime < maxWaitMs) {
try { try {
const resp = await axios.get(targetUrl, { const resp = await axios.get(targetUrl, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
timeout: 5000, timeout: 5000,
validateStatus: (s) => s === 200, validateStatus: (s) => s === 200,
}); });
@@ -50,7 +51,7 @@ async function main() {
try { try {
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`); console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
const response = await axios.get(sitemapUrl, { const response = await axios.get(sitemapUrl, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
}); });
const $ = cheerio.load(response.data, { xmlMode: true }); const $ = cheerio.load(response.data, { xmlMode: true });

View File

@@ -5,7 +5,8 @@ import * as path from 'path';
import { execSync } from 'child_process'; import { execSync } from 'child_process';
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
async function main() { async function main() {
console.log(`\n🚀 Starting HTML Validation for: ${targetUrl}`); console.log(`\n🚀 Starting HTML Validation for: ${targetUrl}`);
@@ -16,10 +17,11 @@ async function main() {
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`); console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
const response = await axios.get(sitemapUrl, { const response = await axios.get(sitemapUrl, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
validateStatus: (status) => status < 400, validateStatus: (status) => status < 400,
}); });
const $ = cheerio.load(response.data, { xmlMode: true }); const $ = cheerio.load(response.data, { xmlMode: true });
let urls = $('url loc') let urls = $('url loc')
.map((i, el) => $(el).text()) .map((i, el) => $(el).text())
@@ -47,10 +49,11 @@ async function main() {
const u = urls[i]; const u = urls[i];
try { try {
const res = await axios.get(u, { const res = await axios.get(u, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
validateStatus: (status) => status < 400, validateStatus: (status) => status < 400,
}); });
// Generate a safe filename that retains URL information // Generate a safe filename that retains URL information
const urlStr = new URL(u); const urlStr = new URL(u);
const safePath = (urlStr.pathname + urlStr.search).replace(/[^a-zA-Z0-9]/g, '_'); const safePath = (urlStr.pathname + urlStr.search).replace(/[^a-zA-Z0-9]/g, '_');

View File

@@ -2,7 +2,8 @@ import axios from 'axios';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
async function main() { async function main() {
console.log(`\n🚀 Starting HTTP Sitemap Validation for: ${targetUrl}\n`); console.log(`\n🚀 Starting HTTP Sitemap Validation for: ${targetUrl}\n`);
@@ -12,10 +13,11 @@ async function main() {
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`); console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
const response = await axios.get(sitemapUrl, { const response = await axios.get(sitemapUrl, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
validateStatus: (status) => status < 400, validateStatus: (status) => status < 400,
}); });
const $ = cheerio.load(response.data, { xmlMode: true }); const $ = cheerio.load(response.data, { xmlMode: true });
let urls = $('url loc') let urls = $('url loc')
.map((i, el) => $(el).text()) .map((i, el) => $(el).text())
@@ -42,10 +44,11 @@ async function main() {
const u = urls[i]; const u = urls[i];
try { try {
const res = await axios.get(u, { const res = await axios.get(u, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
validateStatus: null, // Don't throw on error status validateStatus: null, // Don't throw on error status
}); });
if (res.status >= 400) { if (res.status >= 400) {
console.error(`❌ ERROR ${res.status}: ${res.statusText} -> ${u}`); console.error(`❌ ERROR ${res.status}: ${res.statusText} -> ${u}`);
hasErrors = true; hasErrors = true;

View File

@@ -12,7 +12,8 @@ import * as cheerio from 'cheerio';
*/ */
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
// Expected slug translations: German key → English value // Expected slug translations: German key → English value
const SLUG_MAP: Record<string, string> = { const SLUG_MAP: Record<string, string> = {
@@ -32,7 +33,8 @@ const REVERSE_SLUG_MAP: Record<string, string> = Object.fromEntries(
Object.entries(SLUG_MAP).map(([de, en]) => [en, de]), Object.entries(SLUG_MAP).map(([de, en]) => [en, de]),
); );
const headers = { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }; const headers = { Cookie: `${authCookieName}=${gatekeeperPassword}` };
function getExpectedTranslation( function getExpectedTranslation(
sourcePath: string, sourcePath: string,

View File

@@ -1,7 +1,8 @@
import axios from 'axios'; import axios from 'axios';
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
const requiredHeaders = [ const requiredHeaders = [
'strict-transport-security', 'strict-transport-security',
@@ -15,10 +16,11 @@ async function main() {
console.log(`\n🛡 Starting Security Headers Scan for: ${targetUrl}\n`); console.log(`\n🛡 Starting Security Headers Scan for: ${targetUrl}\n`);
try { try {
const response = await axios.head(targetUrl, { const response = await axios.head(targetUrl, {
headers: { Cookie: `klz_gatekeeper_session=${gatekeeperPassword}` }, headers: { Cookie: `${authCookieName}=${gatekeeperPassword}` },
validateStatus: () => true, validateStatus: () => true,
}); });
const headers = response.headers; const headers = response.headers;
let allPassed = true; let allPassed = true;

View File

@@ -7,9 +7,10 @@ module.exports = async (browser, context) => {
// Using LHCI_URL or TARGET_URL if available // Using LHCI_URL or TARGET_URL if available
const targetUrl = const targetUrl =
process.env.LHCI_URL || process.env.TARGET_URL || 'https://testing.e-tib.com'; process.env.LHCI_URL || process.env.TARGET_URL || 'https://testing.e-tib.com';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session'; const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
console.log(`🔑 LHCI Auth: Setting gatekeeper cookie (${authCookieName}) for ${new URL(targetUrl).hostname}...`); console.log(`🔑 LHCI Auth: Setting gatekeeper cookie (${authCookieName}) for ${new URL(targetUrl).hostname}...`);
await page.setCookie({ await page.setCookie({

View File

@@ -18,9 +18,10 @@ const targetUrl =
process.env.LHCI_URL || process.env.LHCI_URL ||
'http://localhost:3000'; 'http://localhost:3000';
const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; // Default limit to avoid infinite runs const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; // Default limit to avoid infinite runs
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session'; const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
async function main() { async function main() {
console.log(`\n🚀 Starting PageSpeed test for: ${targetUrl}`); console.log(`\n🚀 Starting PageSpeed test for: ${targetUrl}`);
console.log(`📊 Limit: ${limit} pages\n`); console.log(`📊 Limit: ${limit} pages\n`);

View File

@@ -1,7 +1,8 @@
import puppeteer from 'puppeteer'; import puppeteer from 'puppeteer';
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
async function run() { async function run() {
console.log(`🚀 Smoke Test: ${targetUrl}`); console.log(`🚀 Smoke Test: ${targetUrl}`);

View File

@@ -14,7 +14,8 @@ import * as path from 'path';
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20;
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'etib2026';
const authCookieName = process.env.AUTH_COOKIE_NAME || 'etib_gatekeeper_session';
async function main() { async function main() {
console.log(`\n🚀 Starting WCAG Audit for: ${targetUrl}`); console.log(`\n🚀 Starting WCAG Audit for: ${targetUrl}`);
@@ -27,11 +28,12 @@ async function main() {
const response = await axios.get(sitemapUrl, { const response = await axios.get(sitemapUrl, {
headers: { headers: {
Cookie: `klz_gatekeeper_session=${gatekeeperPassword}`, Cookie: `${authCookieName}=${gatekeeperPassword}`,
}, },
validateStatus: (status) => status < 400, validateStatus: (status) => status < 400,
}); });
const $ = cheerio.load(response.data, { xmlMode: true }); const $ = cheerio.load(response.data, { xmlMode: true });
let urls = $('url loc') let urls = $('url loc')
.map((i, el) => $(el).text()) .map((i, el) => $(el).text())
@@ -92,8 +94,9 @@ async function main() {
], ],
}, },
headers: { headers: {
Cookie: `klz_gatekeeper_session=${gatekeeperPassword}`, Cookie: `${authCookieName}=${gatekeeperPassword}`,
}, },
timeout: 60000, // Increase timeout for slower pages timeout: 60000, // Increase timeout for slower pages
}, },
urls: urls, urls: urls,