diff --git a/.gitea/workflows/deploy-dev.yml b/.gitea/workflows/deploy-dev.yml index 42029a6..784ef58 100644 --- a/.gitea/workflows/deploy-dev.yml +++ b/.gitea/workflows/deploy-dev.yml @@ -122,6 +122,7 @@ jobs: NODE_OPTIONS: "--max-old-space-size=2048" run: | cd dashboard/frontend + npm config set registry https://registry.npmmirror.com || true if [ "${{ steps.cache-node.outputs.cache-hit }}" = "true" ]; then echo "Restoring from cache $CACHE_KEY..." if cp -a $CACHE_DIR/node_modules . && [ -d node_modules ]; then diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 6e00774..4f0b0f2 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -127,6 +127,7 @@ jobs: NODE_OPTIONS: "--max-old-space-size=2048" run: | cd dashboard/frontend + npm config set registry https://registry.npmmirror.com || true if [ "${{ steps.cache-node.outputs.cache-hit }}" = "true" ]; then echo "Restoring from cache $CACHE_KEY..." if cp -a $CACHE_DIR/node_modules . && [ -d node_modules ]; then diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index c22f7ab..2a091df 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -164,6 +164,8 @@ jobs: NODE_OPTIONS: "--max-old-space-size=2048" run: | cd dashboard/frontend + # Use npmmirror for China accessibility + npm config set registry https://registry.npmmirror.com || true if [ "${{ steps.cache-node.outputs.cache-hit }}" = "true" ]; then echo "Restoring from cache $CACHE_KEY..." if cp -a $CACHE_DIR/node_modules . && [ -d node_modules ]; then diff --git a/.gitignore b/.gitignore index b9fda11..24a9957 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,26 @@ dashboard/ssh/ .claude/ .codex/ security_artifacts/ + +# OS +.DS_Store +Thumbs.db + +# Python +*.pyc +*.pyo +venv/ +.venv/ +*.egg-info/ + +# IDE +.vscode/ +.idea/ + +# Logs +*.log + +# Environment +.env.local +.env.production +dashboard/backend/.vite/ diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..0613544 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,65 @@ +# Gitleaks configuration for NAS Tools +# Whitelist rules for known-safe patterns in tests, docs, and CI configs + +[allowlist] + description = "Known safe patterns in test fixtures and CI configuration" + + # Test secrets / example values used in CI and conftest + [[allowlist.rules]] + id = "generic-api-key" + description = "Test SECRET_KEY in CI env and conftest" + regexes = [ + '''test-secret-key-for-ci-environment''', + '''test-secret-key-for-testing''', + '''os\.environ\.setdefault\(["']SECRET_KEY''', + '''SECRET_KEY: \$\{SECRET_KEY\}''', + '''SECRET_KEY=\$\{SECRET_KEY\}''', + ] + + # Telegram test tokens (empty or placeholder) + [[allowlist.rules]] + id = "telegram-bot-token" + description = "Placeholder Telegram tokens in CI config" + regexes = [ + '''TELEGRAM_BOT_TOKEN:-''', + '''TELEGRAM_BOT_TOKEN=\$\{TELEGRAM_BOT_TOKEN''', + ] + + # Transmission test creds + [[allowlist.rules]] + id = "transmission-credentials" + description = "Test Transmission credentials in conftest" + regexes = [ + '''TRANSMISSION_USER.*test-tx''', + '''TRANSMISSION_PASS.*test-tx''', + ] + + # SMTP test config + [[allowlist.rules]] + id = "smtp-credentials" + description = "SMTP env var references (not actual secrets)" + regexes = [ + '''SMTP_USER\s*=\s*os\.getenv''', + '''SMTP_PASSWORD\s*=\s*os\.getenv''', + '''SMTP_TO\s*=\s*os\.getenv''', + ] + + # Gitea token env var references + [[allowlist.rules]] + id = "gitea-token" + description = "Gitea token env var references" + regexes = [ + '''GITEA_TOKEN\s*=\s*os\.getenv''', + '''GITEA_TOKEN=\$\{GITEA_TOKEN\}''', + '''GITEA_TOKEN: \$\{GITEA_TOKEN\}''', + ] + + # Admin password hash env var reference + [[allowlist.rules]] + id = "admin-password-hash" + description = "Admin password hash env var references" + regexes = [ + '''ADMIN_PASSWORD_HASH\s*=\s*os\.getenv''', + '''ADMIN_PASSWORD_HASH=\$\{ADMIN_PASSWORD_HASH\}''', + '''ADMIN_PASSWORD_HASH: \$\{ADMIN_PASSWORD_HASH\}''', + ] diff --git a/specs/sprint-01-production-stability.md b/specs/sprint-01-production-stability.md index 3c8572d..15a0f11 100644 --- a/specs/sprint-01-production-stability.md +++ b/specs/sprint-01-production-stability.md @@ -14,7 +14,7 @@ - **Verify by:** Push a trivial change to `dev` → workflow runs on `nas` runner → deploy succeeds → `curl http://nas:4001/api/health` returns 200 - **Risk:** None — this is the same runner used by `deploy.yml` and `deploy-claude-dev-dev.yml`. -- [ ] S01.1 — Fix dev deploy runner label +- [x] S01.1 — Fix dev deploy runner label ## S01.2 — Add test gate to dev deploy @@ -27,7 +27,7 @@ 3. Workflow summary in Gitea UI shows test→deploy dependency clearly - **Risk:** Adds 2-3 minutes to dev deploy cycle. Acceptable trade-off for safety. -- [ ] S01.2 — Add test gate to dev deploy +- [x] S01.2 — Add test gate to dev deploy ## S01.3 — Add error handling to Docker.svelte @@ -40,7 +40,7 @@ 3. During normal operation → no regression (page works as before) - **Risk:** Low. Add `let error = $state("")` and an `{#if error}` block in the template. Keep existing `loading` state. -- [ ] S01.3 — Add error handling to Docker.svelte +- [x] S01.3 — Add error handling to Docker.svelte ## S01.4 — Fix cpu_percent always returning 0 @@ -54,7 +54,7 @@ 4. Stop stress → next call shows lower value - **Risk:** `psutil.cpu_percent(interval=0.1)` blocks the request for 100ms. This is acceptable for a system stats endpoint. Alternative: call `cpu_percent()` once at startup (in lifespan) to prime the counter, then use `interval=0` in the endpoint. -- [ ] S01.4 — Fix cpu_percent always returning 0 +- [x] S01.4 — Fix cpu_percent always returning 0 ## S01.5 — Verify production docker-socket-proxy