Skip to content

Claude/cpu guard script dn d8u - #123

Merged
gamblecodezcom merged 2 commits into
mainfrom
claude/cpu-guard-script-DnD8u
Mar 3, 2026
Merged

Claude/cpu guard script dn d8u#123
gamblecodezcom merged 2 commits into
mainfrom
claude/cpu-guard-script-DnD8u

Conversation

@gamblecodezcom

@gamblecodezcom gamblecodezcom commented Mar 3, 2026

Copy link
Copy Markdown
Owner

User description

Summary by Sourcery

Manage the backend endpoint process as a systemd service (with nohup fallback), harden backend logging and webhook body handling, and update runtime dependencies.

New Features:

  • Add production script support for installing and restarting the runewager-endpoint backend service with systemd and nohup fallback.

Bug Fixes:

  • Ensure the /autofix webhook uses the preserved raw request body for HMAC verification instead of a JSON-reencoded payload, avoiding signature mismatches.
  • Guard backend log file streams against creation failures and log stream errors, falling back to console output when necessary.

Enhancements:

  • Improve backend logging initialization and error reporting around log directory and file handling.
  • Free any existing endpoint port listeners before restarting the backend service to reduce restart conflicts.

Build:

  • Relax the Node.js engine constraint to allow versions >=20 without an upper bound and bump express to 4.22.1 in package metadata.

Deployment:

  • Adjust systemd service configurations for runewager services (including runewager-endpoint) to align with the new process management flow.

CodeAnt-AI Description

Restart and harden backend endpoint startup and webhook verification

What Changed

  • /autofix webhooks now use the original raw request bytes for HMAC verification, preventing signature mismatches and rejected webhooks
  • Backend logging is protected from filesystem errors: failures to open or write log files no longer crash the process and log lines fall back to console
  • The production install script now installs/refreshes and restarts a runewager-endpoint service (port 3001), clears any stale process holding the port before start, and falls back to nohup when systemd restart fails so the endpoint reliably comes up
  • Service units updated to run as root and the endpoint service gets pre-start port clearing and rate limits to avoid immediate crash-restart loops
  • Package metadata updated to allow Node >=20 and lock Express to 4.22.1 to match tested dependencies

Impact

✅ Fewer webhook signature failures
✅ Fewer endpoint restart crash-loops
✅ Logs still visible when disk logging fails

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added a new endpoint service with dedicated management, logging, and port configuration.
  • Improvements

    • Enhanced logging resilience with fallback mechanisms for system stability.
    • Strengthened security posture with improved service isolation and configuration.
  • Chores

    • Updated Node.js version requirements and dependencies for improved compatibility.

claude added 2 commits March 3, 2026 20:23
… main

Combines all changes from this PR into a single clean commit:

- backend.js: store raw buffer on req.rawBody before express.json() runs
  so HMAC verification uses the original bytes (not JSON.stringify output);
  guard log stream creation in try-catch with .on('error') fallback to
  console so filesystem failures never crash the process
- package.json: broaden engine range from >=20 <22 to >=20 (Node v24 compat)
- package-lock.json: regenerate with express@4.x and all transitive deps
  (was missing, causing npm ci to fail on VPS)
- runewager-endpoint.service: User/Group → root (VPS runs as root)
- runewager.service: User/Group → root (VPS runs as root)

https://claude.ai/code/session_01WpEqAiDbpqnBywMjYXJHf4
- Pin express to 4.22.1 (remove ^ semver range) to match the
  explicitly installed version and prevent future version drift
  that caused the missing-dependency failure on Node 21.

- Add ExecStartPre to runewager-endpoint.service: kills any stale
  process holding port 3001 before each systemd start, eliminating
  the EADDRINUSE → instant-crash → restart loop.  Also tightened
  StartLimitBurst=4 / RestartSec=10 / StartLimitIntervalSec=120
  to reduce CPU spike if the service still fails repeatedly.

- Add section 9d to prod-run.sh: installs/refreshes the endpoint
  service unit from the repo copy, clears port 3001 before restart,
  restarts via systemd with a nohup fallback — so a full prod-run
  now brings both services up cleanly without manual intervention.

https://claude.ai/code/session_01WpEqAiDbpqnBywMjYXJHf4
@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@gamblecodezcom
gamblecodezcom merged commit 947bb5a into main Mar 3, 2026
3 of 4 checks passed
@sourcery-ai

sourcery-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR adds a managed systemd-based deployment path (with nohup fallback) for the runewager backend endpoint, hardens backend logging so failures to open log files don’t crash logging, fixes raw-body handling for the /autofix webhook HMAC verification, and updates Node/Express versions.

Sequence diagram for /autofix webhook raw-body capture and HMAC verification

sequenceDiagram
    actor AutofixClient
    participant ExpressApp
    participant RawAutofixMiddleware
    participant JsonBodyParser
    participant WebhookHandler
    participant SignatureVerifier

    AutofixClient->>ExpressApp: POST /autofix/webhook
    ExpressApp->>RawAutofixMiddleware: invoke for /autofix
    RawAutofixMiddleware->>RawAutofixMiddleware: express.raw() parse body
    RawAutofixMiddleware-->>ExpressApp: set req.rawBody (Buffer)
    ExpressApp->>JsonBodyParser: apply express.json()
    JsonBodyParser-->>ExpressApp: set req.body (parsed JSON)
    ExpressApp->>WebhookHandler: call /autofix/webhook handler
    WebhookHandler->>WebhookHandler: read headers x-autofix-signature
    WebhookHandler->>WebhookHandler: const rawBody = req.rawBody || Buffer.alloc(0)
    WebhookHandler->>SignatureVerifier: verifySignature(rawBody, signature)
    SignatureVerifier-->>WebhookHandler: valid/invalid
    alt signature valid and AUTOFIX_SECRET set
        WebhookHandler-->>AutofixClient: 200 OK
    else signature invalid or secret missing
        WebhookHandler-->>AutofixClient: 401 Unauthorized
    end
Loading

Class diagram for backend logger and /autofix webhook handling

classDiagram
    class Logger {
        -WritableStream _logStream
        -WritableStream _errStream
        +_entry(level, eventType, msg, extra) Object
        +_write(streams, obj) void
        +info(eventType, msg, extra) void
        +warn(eventType, msg, extra) void
        +error(eventType, msg, extra) void
    }

    class BackendLogInit {
        +LOG_DIR String
        +LOG_FILE String
        +ERR_FILE String
        +_logStream WritableStream
        +_errStream WritableStream
        +initialize() void
    }

    class RawAutofixMiddleware {
        +handle(req, res, next) void
        +captureRawBody(req, res, next) void
        +setReqRawBody(req) void
    }

    class JsonBodyParserMiddleware {
        +handle(req, res, next) void
    }

    class WebhookHandler {
        +postAutofixWebhook(req, res) Promise~void~
        -getSignature(req) String
        -getRawBody(req) Buffer
        -handleInvalidSignature(res, reason) void
    }

    class SignatureVerifier {
        +verifySignature(body, signature) Boolean
    }

    class ExpressApp {
        +use(middleware) void
        +post(path, handler) void
    }

    BackendLogInit --> Logger : configures
    ExpressApp --> RawAutofixMiddleware : uses on path /autofix
    ExpressApp --> JsonBodyParserMiddleware : uses globally
    ExpressApp --> WebhookHandler : route /autofix/webhook
    WebhookHandler --> SignatureVerifier : calls
    RawAutofixMiddleware --> WebhookHandler : sets req.rawBody
    Logger <.. WebhookHandler : logging usage
    Logger <.. RawAutofixMiddleware : logging usage
    Logger <.. BackendLogInit : logging usage
Loading

File-Level Changes

Change Details Files
Add systemd-managed startup and safe restart for the runewager backend endpoint (backend.js on configurable port).
  • Introduce ENDPOINT_* configuration variables and logs for backend.js, including deriving port from ENDPOINT_PORT env with default 3001.
  • Install or refresh a runewager-endpoint systemd unit from the repo copy when systemd is available, with daemon-reload and enable.
  • Before restart, detect and free any process holding the endpoint port, then restart the systemd service, logging success or warning on failure.
  • On systemd restart failure, kill existing backend.js processes and start backend.js with nohup as a fallback, wiring stdout/stderr to backend log files.
  • When systemd is not available, always kill existing backend.js, free the port if needed, and start it via nohup with logging.
prod-run.sh
runewager-endpoint.service
runewager.service
Make backend logging resilient to log directory/file errors and stream failures.
  • Create log directory and open log and error streams inside a try/catch, storing them in mutable variables that may remain null on failure.
  • Attach error handlers to log streams that null out the corresponding stream and report errors to console.error.
  • Change logger._write to handle null streams and fall back to console.log when a stream is unavailable, instead of assuming streams are always valid.
  • Adjust startup error message to describe failure to open log files rather than only directory creation.
backend.js
Fix /autofix webhook raw-body capture to correctly support HMAC verification after JSON parsing.
  • Replace direct express.raw middleware with a wrapper that runs express.raw for /autofix, then copies the raw buffer into req.rawBody before passing control onward.
  • Ensure express.json still runs after raw-body capture so other routes and handlers continue to see parsed JSON bodies.
  • Update webhook handler to use req.rawBody for signature verification, defaulting to an empty buffer when not present.
backend.js
Update runtime and framework constraints (Node engine and Express version).
  • Relax Node.js engines constraint to allow any Node version >= 20, removing the <22 upper bound.
  • Bump express dependency from ^4.21.2 to 4.22.1 and refresh package-lock.json accordingly.
package.json
package-lock.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gamblecodezcom
gamblecodezcom deleted the claude/cpu-guard-script-DnD8u branch March 3, 2026 21:15
@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 834ce80 and 722c7a0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • backend.js
  • package.json
  • prod-run.sh
  • runewager-endpoint.service
  • runewager.service

📝 Walkthrough

Walkthrough

This PR introduces resilience improvements to the backend logging system with lazy-created log streams and error fallback, implements secure raw request body capture for webhook signature verification, adds a new systemd-managed endpoint service on port 3001 with automated deployment integration, updates Node engine and Express versions, and elevates service process privileges from the runewager user to root across all systemd services.

Changes

Cohort / File(s) Summary
Backend Application Logic
backend.js
Introduces optional, lazily-created log streams with try/catch error guards. Implements custom middleware to capture raw request body before JSON parsing, preserving original payload for webhook signature verification. Falls back to console logging when streams are unavailable.
Dependency and Version Updates
package.json
Broadens Node engine requirement from >=20 <22 to >=20 and updates Express from ^4.21.2 to pinned version 4.22.1.
Deployment Automation
prod-run.sh
Adds comprehensive endpoint service management block that installs and manages a separate Runewager endpoint service on port 3001 with systemd integration (when available) or nohup fallback. Includes port conflict clearing and dedicated logging.
SystemD Service Configuration
runewager-endpoint.service, runewager.service
Changes service execution user/group from runewager to root across both services. Endpoint service adds ExecStartPre port cleanup, adjusts restart parameters, and introduces security/isolation directives including ProtectSystem, ProtectHome, PrivateTmp, NoNewPrivileges, UMask, and LimitNOFILE. Main service receives only user/group privilege elevation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

codex, size:XL

Poem

🐰 A log stream born lazy, with grace,

Raw bodies captured in their place,

Endpoint service dances on port 3001,

Root privileges claimed when service runs,

Infrastructure blooms—the work is done! 🌱

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/cpu-guard-script-DnD8u

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Mar 3, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="prod-run.sh" line_range="427" />
<code_context>
+        say "runewager-endpoint restarted via systemd"
+    else
+        warn "systemctl restart runewager-endpoint failed — falling back to nohup"
+        pkill -f "node .*backend\.js" 2>/dev/null || true
+        sleep 1
+        nohup node "$PROJECT_DIR/backend.js" \
+            >> "$ENDPOINT_LOG" 2>> "$ENDPOINT_ERR" < /dev/null &
+        disown || true
+        say "runewager-endpoint started via nohup fallback"
+    fi
+else
+    # No systemd — direct nohup
+    pkill -f "node .*backend\.js" 2>/dev/null || true
+    sleep 1
+    if is_port_listening "$ENDPOINT_PORT"; then
</code_context>
<issue_to_address>
**issue (bug_risk):** The pkill pattern for backend.js may kill unrelated node processes

`pkill -f "node .*backend\.js"` will terminate any Node process whose command line contains `backend.js`, including ones from other apps on the same host. In multi-app or shared environments this risks killing unrelated services. Please either narrow the match (e.g., include `$PROJECT_DIR` in the pattern) or track the specific PID you start and kill only that process.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread prod-run.sh
say "runewager-endpoint restarted via systemd"
else
warn "systemctl restart runewager-endpoint failed — falling back to nohup"
pkill -f "node .*backend\.js" 2>/dev/null || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The pkill pattern for backend.js may kill unrelated node processes

pkill -f "node .*backend\.js" will terminate any Node process whose command line contains backend.js, including ones from other apps on the same host. In multi-app or shared environments this risks killing unrelated services. Please either narrow the match (e.g., include $PROJECT_DIR in the pattern) or track the specific PID you start and kill only that process.

@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Service runs as root
    The endpoint service now runs as User=root/Group=root. Running Node apps as root increases attack surface and risk of privilege escalation if the app or dependencies are compromised. Prefer a dedicated unprivileged service user or drop capabilities instead of running as root.

  • Service runs as root (main)
    The main runewager.service was changed to User=root/Group=root. This mirrors the endpoint change and similarly increases risk. Verify this is intentional and document the justification; if not strictly required, revert to a dedicated unprivileged service user.

  • ExecStartPre hazards
    The added ExecStartPre embeds a complex shell pipeline that finds and kills port holders with kill -9. This can abruptly terminate unrelated processes, may behave unexpectedly if lsof/fuser are absent, and could rely on environment variables that might not be available at the time of ExecStartPre execution. Consider a safer, reproducible prestart helper script that handles missing tools, attempts graceful SIGTERM first, and validates multiple PIDs properly.

  • Port free race
    The script frees endpoint port listeners before restart but uses immediate retries/sleeps and concurrent pkill/kill -9 calls. There is still a race where a lingering process may rebind, or the PID list may change mid-loop. Validate that freed ports are reliably free before starting node (e.g., wait/check loop), and avoid aggressive SIGKILL until graceful termination attempt fails.

  • Stream lifecycle on shutdown
    The code creates file write streams for logs but doesn't explicitly close or flush them on shutdown. Open file descriptors may be left until process exit. Consider properly ending streams during graceful shutdown to ensure buffered log data is flushed and descriptors released.

Comment thread runewager.service
Comment on lines +28 to +29
User=root
Group=root

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Running the Node.js service as the root user is a security vulnerability: if the process or any dependency is compromised, an attacker gains full system control, so this should instead run under a dedicated unprivileged service account (with appropriate filesystem permissions configured) to follow the principle of least privilege. [security]

Severity Level: Critical 🚨
- ❌ Telegram bot backend always runs as root on deployed hosts.
- ❌ Any RCE in `index.js` grants full system control.
- ⚠️ Undermines `ProtectSystem`/`NoNewPrivileges` hardening in unit file.
Suggested change
User=root
Group=root
User=runewager
Group=runewager
Steps of Reproduction ✅
1. Inspect the systemd unit template at `/workspace/Runewager/runewager.service` lines
24–31, where the `[Service]` section is defined, including:

   - `ExecStart=/usr/bin/node /var/www/html/Runewager/index.js` (line 27)

   - `User=root` (line 28)

   - `Group=root` (line 29).

2. Follow the documented deployment instructions in the same file at lines 11–14 (`cp
runewager.service /etc/systemd/system/runewager.service`, `systemctl daemon-reload`,
`systemctl enable --now runewager`) to install and start the service on a VPS.

3. On the deployed host, run `systemctl status runewager` (referencing the service name
from `runewager.service`) and observe that systemd reports the main Node.js process
(`/var/www/html/Runewager/index.js`) running under `User=root`/`Group=root`, as dictated
by the unit file configuration.

4. Recognize that all application code and dependencies loaded by `index.js` (the bot's
entrypoint) now execute with full root privileges, so any remote code execution
vulnerability or path traversal in the Node/Express stack would immediately execute as
root rather than an unprivileged account, significantly increasing the impact of a
compromise compared to running under a dedicated `runewager` user.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** runewager.service
**Line:** 28:29
**Comment:**
	*Security: Running the Node.js service as the root user is a security vulnerability: if the process or any dependency is compromised, an attacker gains full system control, so this should instead run under a dedicated unprivileged service account (with appropriate filesystem permissions configured) to follow the principle of least privilege.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants