fix: restore PATCH endpoints used by E2E + emergency-token fallback

register PATCH /api/v1/settings and PATCH /api/v1/security/acl (E2E expectations)
add emergency-token-aware shortcut handlers (validate X-Emergency-Token → set admin context → invoke handler)
preserve existing POST handlers and backward compatibility
rebuild & redeploy E2E image, verified backend build success
Why: unblocked failing Playwright E2E tests that returned 404s and were blocking the hotfix release
This commit is contained in:
GitHub Actions
2026-01-27 22:43:33 +00:00
parent 949eaa243d
commit 0da6f7620c
39 changed files with 8428 additions and 180 deletions

View File

@@ -1,20 +1,23 @@
# Playwright E2E Test Environment
# ================================
# This configuration is specifically designed for Playwright E2E testing,
# both for local development and CI/CD pipelines.
# Playwright E2E Test Environment for CI/CD
# ==========================================
# This configuration is specifically designed for GitHub Actions CI/CD pipelines.
# Environment variables are provided via GitHub Secrets and generated dynamically.
#
# Usage:
# # Start basic E2E environment
# docker compose -f .docker/compose/docker-compose.playwright.yml up -d
# DO NOT USE env_file - CI provides variables via $GITHUB_ENV:
# - CHARON_ENCRYPTION_KEY: Generated with openssl rand -base64 32 (ephemeral)
# - CHARON_EMERGENCY_TOKEN: From repository secrets (secure)
#
# Usage in CI:
# export CHARON_ENCRYPTION_KEY=$(openssl rand -base64 32)
# export CHARON_EMERGENCY_TOKEN="${{ secrets.CHARON_EMERGENCY_TOKEN }}"
# docker compose -f .docker/compose/docker-compose.playwright-ci.yml up -d
#
# Profiles:
# # Start with security testing services (CrowdSec)
# docker compose -f .docker/compose/docker-compose.playwright.yml --profile security-tests up -d
# docker compose -f .docker/compose/docker-compose.playwright-ci.yml --profile security-tests up -d
#
# # Start with notification testing services (MailHog)
# docker compose -f .docker/compose/docker-compose.playwright.yml --profile notification-tests up -d
#
# # Start with all optional services
# docker compose -f .docker/compose/docker-compose.playwright.yml --profile security-tests --profile notification-tests up -d
# docker compose -f .docker/compose/docker-compose.playwright-ci.yml --profile notification-tests up -d
#
# The setup API will be available since no users exist in the fresh database.
# The auth.setup.ts fixture will create a test admin user automatically.
@@ -27,6 +30,9 @@ services:
image: ${CHARON_E2E_IMAGE:-charon:e2e-test}
container_name: charon-playwright
restart: "no"
# CI generates CHARON_ENCRYPTION_KEY dynamically in GitHub Actions workflow
# and passes CHARON_EMERGENCY_TOKEN from GitHub Secrets via $GITHUB_ENV.
# No .env file is used in CI as it's gitignored and not available.
ports:
- "8080:8080" # Management UI (Charon)
- "127.0.0.1:2019:2019" # Caddy admin API (IPv4 loopback)

View File

@@ -1,10 +1,14 @@
# Docker Compose for E2E Testing
# Docker Compose for Local E2E Testing
#
# This configuration runs Charon with a fresh, isolated database specifically for
# Playwright E2E tests. Use this to ensure tests start with a clean state.
# Playwright E2E tests during local development. Uses .env file for credentials.
#
# Usage:
# docker compose -f .docker/compose/docker-compose.e2e.yml up -d
# docker compose -f .docker/compose/docker-compose.playwright-local.yml up -d
#
# Prerequisites:
# - Create .env file in project root with CHARON_ENCRYPTION_KEY and CHARON_EMERGENCY_TOKEN
# - Build image: docker build -t charon:local .
#
# The setup API will be available since no users exist in the fresh database.
# The auth.setup.ts fixture will create a test admin user automatically.
@@ -14,6 +18,8 @@ services:
image: charon:local
container_name: charon-e2e
restart: "no"
env_file:
- ../../.env
ports:
- "8080:8080" # Management UI (Charon)
- "127.0.0.1:2019:2019" # Caddy admin API (read-only status; keep loopback only)
@@ -24,12 +30,8 @@ services:
- CHARON_ENV=e2e # Enable lenient rate limiting (50 attempts/min) for E2E tests
- CHARON_DEBUG=0
- TZ=UTC
# Encryption key - MUST be provided via environment variable
# Generate with: export CHARON_ENCRYPTION_KEY=$(openssl rand -base64 32)
- CHARON_ENCRYPTION_KEY=${CHARON_ENCRYPTION_KEY:?CHARON_ENCRYPTION_KEY is required}
# Emergency reset token - for break-glass recovery when locked out by ACL
# Generate with: openssl rand -hex 32
- CHARON_EMERGENCY_TOKEN=${CHARON_EMERGENCY_TOKEN:-test-emergency-token-for-e2e-32chars}
# Encryption key and emergency token loaded from env_file (../../.env)
# DO NOT add them here - env_file takes precedence and explicit entries override with empty values
# Emergency server (Tier 2 break glass) - separate port bypassing all security
- CHARON_EMERGENCY_SERVER_ENABLED=true
- CHARON_EMERGENCY_BIND=0.0.0.0:2020 # Bind to all interfaces in container (avoid Caddy's 2019)