Add environment variables panel for system diagnostics#1
Conversation
Adds a new Environment Variables panel to the dashboard that displays system environment variables for debugging and diagnostics purposes. This helps developers understand the runtime environment when troubleshooting issues. Changes: - Add /api/environment endpoint to server - Create EnvironmentPanel component with filtering support - Add CSS styles for the new panel - Integrate panel into main App layout 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughA new Environment Panel component was introduced to display server environment variables. The backend exposes a GET /api/environment endpoint, while the frontend component fetches and renders variables with optional filtering and expandable view for large result sets. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EnvironmentPanel
participant API as /api/environment
participant Server
User->>EnvironmentPanel: Mount component
activate EnvironmentPanel
EnvironmentPanel->>EnvironmentPanel: Set loading = true
EnvironmentPanel->>API: GET /api/environment
activate API
API->>Server: Request env vars
Server-->>API: Return all env variables
deactivate API
API-->>EnvironmentPanel: JSON array of {name, value}
EnvironmentPanel->>EnvironmentPanel: Set loading = false<br/>Store variables
EnvironmentPanel->>EnvironmentPanel: Apply filter (if provided)<br/>Compute memoized results
EnvironmentPanel-->>User: Display filtered list<br/>(with toggle if >10 items)
deactivate EnvironmentPanel
User->>EnvironmentPanel: Toggle expand/collapse
EnvironmentPanel-->>User: Show all / show first 10
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
server/index.ts (1)
260-266: Blocker: /api/environment +Access-Control-Allow-Origin: *enables cross-site secret exfiltration
Right now any website can fetchhttp://localhost:3001/api/environmentfrom a user’s browser and read all env vars (often includes secrets). Please restrict CORS and redact/guard the endpoint.Suggested patch (minimal, keeps dev UX):
@@ - // CORS headers - const corsHeaders = { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "GET, OPTIONS", - "Access-Control-Allow-Headers": "Content-Type", - }; + // CORS headers (avoid "*" to prevent cross-site reads from arbitrary origins) + const origin = req.headers.get("Origin"); + const allowedOrigins = (process.env.BTOP_ALLOWED_ORIGINS ?? "http://localhost:5173") + .split(",") + .map(s => s.trim()) + .filter(Boolean); + const corsHeaders: Record<string, string> = { + "Access-Control-Allow-Methods": "GET, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", + ...(origin && allowedOrigins.includes(origin) ? { "Access-Control-Allow-Origin": origin, "Vary": "Origin" } : {}), + }; @@ if (url.pathname === "/api/environment") { + if (req.method !== "GET") { + return new Response("Method Not Allowed", { status: 405, headers: corsHeaders }); + } + // Disable by default in production unless explicitly enabled + if (process.env.NODE_ENV === "production" && process.env.BTOP_EXPOSE_ENV !== "true") { + return new Response("Not Found", { status: 404, headers: corsHeaders }); + } // Return environment variables for system diagnostics - const envVars = Object.entries(process.env).map(([key, value]) => ({ - name: key, - value: value || "", - })); + const redact = (name: string) => /(pass(word)?|secret|token|api[_-]?key|private[_-]?key|session|cookie)/i.test(name); + const envVars = Object.entries(process.env) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, value]) => ({ + name: key, + value: redact(key) ? "<redacted>" : (value ?? ""), + })); return new Response(JSON.stringify({ variables: envVars }), { headers: { "Content-Type": "application/json", ...corsHeaders, }, }); }Also applies to: 290-302
🧹 Nitpick comments (2)
src/App.css (1)
568-673: Consider small-screen responsiveness for fixed.env-namewidth; also verify no duplicate env-panel blocksPotential tweak:
@@ .env-name { @@ min-width: 180px; @@ } + +@media (max-width: 800px) { + .env-name { min-width: 120px; } +}Quick verification (within this file): ensure there’s only one
/* Environment Panel */block /.env-panel {definition.src/components/EnvironmentPanel.tsx (1)
56-78: Displaying raw env values is risky; consider masking/reveal UX (even if server redacts)At minimum, consider masking values by default and revealing on click (per-row), since secrets can still slip through (or be present in non-obvious variable names).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
server/index.ts(1 hunks)src/App.css(1 hunks)src/App.tsx(2 hunks)src/components/EnvironmentPanel.tsx(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/EnvironmentPanel.tsx (1)
server/index.ts (1)
fetch(257-305)
src/App.tsx (1)
src/components/EnvironmentPanel.tsx (1)
EnvironmentPanel(12-80)
🔇 Additional comments (1)
src/App.tsx (1)
1-9: EnvironmentPanel integration looks correct (placement + prop wiring)Also applies to: 72-73
| useEffect(() => { | ||
| async function fetchEnvironment() { | ||
| try { | ||
| const response = await fetch('http://localhost:3001/api/environment'); | ||
| const data = await response.json(); | ||
| setEnvVars(data.variables); | ||
| } catch (error) { | ||
| console.error('Failed to fetch environment variables:', error); | ||
| } finally { | ||
| setLoading(false); | ||
| } | ||
| } | ||
|
|
||
| fetchEnvironment(); | ||
| }, []); | ||
|
|
There was a problem hiding this comment.
Avoid hard-coded API origin; handle non-2xx responses
Suggested patch:
@@
useEffect(() => {
async function fetchEnvironment() {
try {
- const response = await fetch('http://localhost:3001/api/environment');
+ const apiBase = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3001';
+ const response = await fetch(new URL('/api/environment', apiBase));
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
setEnvVars(data.variables);
} catch (error) {
console.error('Failed to fetch environment variables:', error);
} finally {
setLoading(false);
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| async function fetchEnvironment() { | |
| try { | |
| const response = await fetch('http://localhost:3001/api/environment'); | |
| const data = await response.json(); | |
| setEnvVars(data.variables); | |
| } catch (error) { | |
| console.error('Failed to fetch environment variables:', error); | |
| } finally { | |
| setLoading(false); | |
| } | |
| } | |
| fetchEnvironment(); | |
| }, []); | |
| useEffect(() => { | |
| async function fetchEnvironment() { | |
| try { | |
| const apiBase = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3001'; | |
| const response = await fetch(new URL('/api/environment', apiBase)); | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`); | |
| const data = await response.json(); | |
| setEnvVars(data.variables); | |
| } catch (error) { | |
| console.error('Failed to fetch environment variables:', error); | |
| } finally { | |
| setLoading(false); | |
| } | |
| } | |
| fetchEnvironment(); | |
| }, []); |
Summary
This PR adds a new Environment Variables panel to the btop dashboard that displays system environment variables. This feature helps developers quickly understand the runtime environment when debugging issues or verifying configuration.
Changes
/api/environmentendpoint that returns all environment variablesEnvironmentPanelcomponent with:Screenshots
The new panel appears below the process table and shows environment variables in a clean, scrollable list.
Test plan
bun run serverbun run dev🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
UI/Style
✏️ Tip: You can customize this high-level summary in your review settings.