Trivy flagged nginx 1.28.3-r1 in the frontend image (alerts #371-374):
- CVE-2026-42055 (HIGH) HTTP/2 heap overflow
- CVE-2026-49975 (HIGH) HTTP/2 DoS
- CVE-2026-9256 (HIGH) rewrite_module code exec / DoS
- CVE-2026-48142 (MED) charset_module memory disclosure
All fixed in nginx 1.28.3-r4. The Dockerfile already ran 'apk upgrade
--no-cache', but the pushed image predated the fixed package and the layer
was cached on r1. Add an explicit nginx upgrade to force the layer to rebuild
against the current Alpine repos (which now carry r4).
Repo transferred from the-luap/picpeak → PicPeak/picpeak. Docker images
publish to ghcr.io/picpeak/picpeak/{backend,frontend} (lowercase, per the
GHCR canonical form computed by docker-build.yml's `${GITHUB_REPOSITORY,,}`).
Sweep covers:
- docker-compose.production.yml + Dockerfiles → new image registry path
- README, CONTRIBUTING, SECURITY, SIMPLE_SETUP, scripts/picpeak-setup.sh
→ new GitHub URLs
- Update-check / release-notes services (updateCheckService,
environmentService, updateNotificationService, adminSystem,
UpdateNotification, githubReleaseUrl) → GitHub API + tag URLs use the
canonical PicPeak/picpeak path
- Issue templates + README-DOCKER + workflow README → updated package URLs
- One commit-context comment in migrations/090 + customerAccountsService
CHANGELOG.md is intentionally untouched (historical release entries are
immutable; GitHub auto-redirects the old URLs indefinitely).
CLAUDE.md keeps the bare `(the-luap)` reference — that's the maintainer's
personal handle, not a repo URL.
22 files, 48/48 line swaps (every change is a 1:1 URL replacement).
@Rekoo-PS confirmed the prior #521 fix landed on beta but reported the
preview still shows the default "PicPeak" title — their brand is
"arkan-studio". Root cause: that fix used Vite's build-time
%VITE_DEFAULT_TITLE% substitution. Self-hosters running the pre-built
ghcr.io/the-luap/picpeak/frontend image can't override at build time
without rebuilding, so they were stuck with whatever the upstream
build baked in.
Pivot to runtime substitution: the frontend container now reads
BRAND_TITLE / BRAND_DESCRIPTION env vars on startup and envsubsts
them into index.html. Change the values in .env, restart the frontend
service, done — no rebuild required.
Mechanics:
- frontend/index.html: tokens are now ${BRAND_TITLE} /
${BRAND_DESCRIPTION} (shell expansion syntax, passes through Vite
unchanged into the built dist).
- frontend/Dockerfile: install gettext (provides envsubst), snapshot
/usr/share/nginx/html/index.html → index.html.tpl at build, install
docker-entrypoint.sh, wire ENTRYPOINT to it. The .tpl is the
immutable source — every container start re-renders index.html
from .tpl, so restarts pick up new env values cleanly (no
accidental "first-boot env stuck forever" trap).
- frontend/docker-entrypoint.sh: applies defaults if env unset,
runs envsubst (locked to BRAND_TITLE + BRAND_DESCRIPTION
explicitly so /assets/*.js template literals aren't touched if
anyone ever extends substitution to the bundle), execs nginx.
- frontend/vite.config.ts: drop the htmlTitleDefaults plugin — no
longer needed since substitution is fully runtime.
- frontend/.env.example + .env.production.example: drop the
VITE_DEFAULT_* docs (the vars no longer have effect).
- docker-compose.yml + docker-compose.production.yml: pass
BRAND_TITLE / BRAND_DESCRIPTION env into the frontend service
with sensible defaults so unconfigured installs work unchanged.
- .env.example: add BRAND_TITLE / BRAND_DESCRIPTION with comment
pointing at the social-preview use case.
Verified end-to-end against the built image:
- BRAND_TITLE="Arkan Studio" BRAND_DESCRIPTION="Wedding photographs
by Arkan Studio" → index.html serves <title>Arkan Studio</title>
+ og:title="Arkan Studio" + og:description correctly substituted.
- .tpl preserves ${...} tokens so the next restart can re-substitute.
- Bundle assets unaffected.
- Defaults applied when env unset → <title>PicPeak</title>.
Docs PR in picpeak-docs describes the two new env vars under
"Social link preview fallback" in the environment-variables reference.
Refs: #521
Upgrade npm to latest version in both backend and frontend Dockerfiles
to fix the command injection vulnerability in glob's CLI (CVE-2025-64756).
The vulnerability exists in npm's bundled glob package (< 10.5.0 or < 11.1.0).
Original: feat: enhance security logging and ensure rate limit blocks are properly tracked
- Add comprehensive logging for rate limit blocks with full request details
- IP address (with proper proxy detection), user agent, headers, timestamps
- Rate limit info (current count, limit, remaining, reset time)
- Separate tracking for auth vs general endpoints
- Enhance authentication failure logging
- JWT validation failures with detailed error info
- Admin auth attempts without token
- Failed token validation with user context
- All events include IP, path, method, user agent
- Improve Winston logger configuration for production
- Add automatic log rotation (10MB errors, 50MB combined)
- Create separate security.log for auth/rate limit events
- Ensure logs directory exists automatically
- Add structured JSON format for log aggregation
- Support container logging with LOG_TO_CONSOLE env var
- Create comprehensive documentation
- Security logging guide with examples
- Monitoring recommendations
- Configuration reference
- Add test script to verify logging functionality
All rate limit settings remain configurable via admin panel:
- Window duration, max requests, auth limits
- Skip authenticated requests option
- Public endpoints only option
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>