mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-08-28 05:25:25 +00:00
* feat(web): support GITNEXUS_BACKEND_URL env var for Docker deployments * fix(docker): escape inline script injection to prevent XSS and add server-level integration tests - Add jsonForScriptTag() that escapes <, >, & after JSON.stringify to prevent </script> breakout in inline config script - Sanitize rawBackendUrl in warning log to prevent log injection via newlines - Replace 5 duplicated-helper injection tests with 7 server-level HTTP integration tests that spawn the real docker-server.mjs with GITNEXUS_BACKEND_URL set - Add XSS-specific test: URL containing </script> must produce exactly 1 <script> tag - Add empty-string backendUrl frontend test - Improve Docker Compose Linux guidance with explicit <server-ip> example * fix(docker): harden log sanitization, fix error leak, fix killAndWait race - Broaden log sanitization regex from [\r\n] to [\x00-\x1f\x7f] to strip all C0 control characters including ANSI escape sequences - Replace error.message leak in 500 handler with generic string; log the real error server-side via console.error - Fix killAndWait TOCTOU race by registering exit listener before kill and adding post-kill exitCode guard * fix(docker): handle readFile race to resolve CodeQL file-system-race alert Wrap readFile in try/catch so the TOCTOU between stat() and readFile() is handled gracefully — if the file vanishes between the check and the read, return 404 instead of crashing. * @ fix(docker): eliminate TOCTOU race and format web components Replace the previous try/catch approach with fs.promises.open() to get a file handle, then use handle.stat()/readFile()/createReadStream() from the same fd — properly eliminates the CodeQL "file system race condition" alert by removing the window between stat() and read. Also runs prettier on the 5 web component files that were failing the format CI check. @ * chore(autofix): apply prettier + eslint fixes via /autofix command * chore: trigger CI * @ fix(docker): pass GITNEXUS_BACKEND_URL to the web container The env var was documented but commented out, so docker-server.mjs never received it and the config injection was dead. Uncomment the environment block with a passthrough default so users can set GITNEXUS_BACKEND_URL in .env or their shell for remote/custom deployments. @ * @ fix(docker): eliminate stat() to resolve CodeQL js/file-system-race CodeQL pairs any stat() (FileCheck) with a subsequent open() (FileUse) on an aliased path. The previous approach kept stat() for directory detection, which the analyzer flagged regardless of the fd-based reads. Replace stat() entirely with open() + handle.stat(). On Linux (Docker), open() succeeds for directories, so handle.stat().isDirectory() detects them without a standalone stat() call. This removes the FileCheck node from the data-flow graph, eliminating the alert at its source. @ * @ fix(docker): break CodeQL path alias chain between open() calls CodeQL js/file-system-race pairs two open() calls when their path arguments are data-flow aliased. The previous approach derived the fallback path from the request path (resolve(initialPath, index.html)), creating an alias chain the analyzer could trace. Restructure so the SPA fallback uses a module-level constant (spaFallback = resolve(root, index.html)) with zero data-flow from the request. The two open() calls now have provably independent path arguments, eliminating the FileCheck/FileUse pair. Also simplifies the logic: for an SPA, all non-file requests serve root/index.html — no directory/index.html detection needed since the client-side router handles subroutes. @ --------- Co-authored-by: Test <test@example.com> Co-authored-by: Gergő Magyar <gergomagyar@icloud.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
51 lines
2 KiB
YAML
51 lines
2 KiB
YAML
services:
|
|
gitnexus-server:
|
|
image: ${SERVER_IMAGE:-ghcr.io/abhigyanpatwari/gitnexus:latest}
|
|
container_name: ${SERVER_CONTAINER_NAME:-gitnexus-server}
|
|
# Map the server to the same host port the web UI expects by default
|
|
# (http://localhost:4747). The browser runs on the host, so the UI's
|
|
# built-in default works without any reconfiguration.
|
|
ports:
|
|
- '${SERVER_HOST_PORT:-4747}:4747'
|
|
volumes:
|
|
# Persist the global registry, indexes, and cloned repos across runs.
|
|
- gitnexus-data:/data/gitnexus
|
|
# Optional: mount a host workspace so `gitnexus index <path>` can see
|
|
# repos you already have on disk. The default points at an empty
|
|
# `./workspace/` sibling that compose will create on first start —
|
|
# it intentionally does NOT bind-mount the repo root, which would
|
|
# expose `.git`, `.env`, and CI secrets to the container.
|
|
# Override with `WORKSPACE_DIR=/abs/path/to/your/repos`.
|
|
- ${WORKSPACE_DIR:-./workspace}:/workspace:ro
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ['CMD', 'curl', '-f', 'http://localhost:4747/api/health']
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 15s
|
|
|
|
gitnexus-web:
|
|
image: ${WEB_IMAGE:-ghcr.io/abhigyanpatwari/gitnexus-web:latest}
|
|
container_name: ${WEB_CONTAINER_NAME:-gitnexus-web}
|
|
ports:
|
|
- '${WEB_HOST_PORT:-4173}:4173'
|
|
# Override the backend URL served to the browser. The default
|
|
# (http://localhost:4747) works when both containers run locally.
|
|
# Set GITNEXUS_BACKEND_URL in your .env or shell for remote/custom setups:
|
|
# GITNEXUS_BACKEND_URL=http://<server-ip>:4747
|
|
environment:
|
|
- GITNEXUS_BACKEND_URL=${GITNEXUS_BACKEND_URL:-}
|
|
depends_on:
|
|
gitnexus-server:
|
|
condition: service_healthy
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ['CMD', 'curl', '-f', 'http://localhost:4173/']
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
volumes:
|
|
gitnexus-data:
|