Skip to content

Comments

Add optional HTTPS support for backend and Vite dev server#400

Open
stephenfeather wants to merge 1 commit intositeboon:mainfrom
stephenfeather:feat-ssl-support
Open

Add optional HTTPS support for backend and Vite dev server#400
stephenfeather wants to merge 1 commit intositeboon:mainfrom
stephenfeather:feat-ssl-support

Conversation

@stephenfeather
Copy link

@stephenfeather stephenfeather commented Feb 19, 2026

Summary

  • add optional HTTPS server creation for backend via env + cert paths
  • add optional HTTPS support for Vite dev server and protocol-aware proxy targets
  • document HTTPS env/config in .env.example and README

Relationship to #362

This is not intended to compete with #362. It is a complementary follow-up that can be folded into #362 if preferred.

PR #362 adds backend SSL fallback behavior. This PR adds related improvements for consistency:

  • Vite HTTPS support using env-driven cert/key paths
  • protocol-aware proxy targets (http/ws -> https/wss when enabled)
  • matching docs/env guidance for local setup

If maintainers prefer, I can close this PR and provide these commits/changes to be cherry-picked directly into #362.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added HTTPS/SSL support for local development with automatic fallback to HTTP if certificates are unavailable.
  • Documentation

    • Added setup guide for configuring HTTPS with self-signed certificates for testing.
    • Documented new environment variables for SSL configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

This pull request adds SSL/HTTPS support infrastructure to the application. Environment variables control SSL activation for both the backend Express server and Vite development server. Certificate and key file paths are configurable. The system gracefully falls back to HTTP if certificates are unavailable or if SSL is disabled.

Changes

Cohort / File(s) Summary
Configuration & Documentation
.env.example, README.md
Adds SSL/HTTPS environment variables and self-signed certificate setup instructions for local development testing.
Server Implementation
server/index.js, vite.config.js
Implements SSL/HTTPS support with certificate file loading, protocol toggling, and proxy configuration for both backend and Vite dev server with HTTP fallback behavior.

Sequence Diagram

sequenceDiagram
    participant App as Application Start
    participant Env as Environment Config
    participant FS as File System
    participant Server as HTTP/HTTPS Server
    participant Vite as Vite Dev Server
    participant Client as Client Browser

    App->>Env: Read SSL_ENABLED, VITE_HTTPS flags
    Env-->>App: Return SSL configuration values
    
    alt SSL Enabled
        App->>FS: Read certificate files
        FS-->>App: Return cert & key data
        App->>Server: Create HTTPS server
    else SSL Disabled
        App->>Server: Create HTTP server
    end
    
    Server-->>App: Server created with protocol
    
    alt VITE_HTTPS Enabled
        App->>Vite: Configure HTTPS proxy<br/>(api, ws, shell targets)
    else VITE_HTTPS Disabled
        App->>Vite: Configure HTTP proxy<br/>(api, ws, shell targets)
    end
    
    Vite-->>App: Dev server configured
    App->>Client: Server ready on configured protocol
Loading

Poem

🐰 A protocol of trust, with certificates so fine,
HTTPS now shields both backend and Vite line,
When SSL's enabled, the handshake flows,
But graceful HTTP fallback always goes—
Secure development without the fuss! 🔐

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding optional HTTPS support to both backend and Vite dev server, which aligns with all four modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
README.md (1)

203-204: ⚠️ Potential issue | 🟡 Minor

Minor: Development URL still hardcodes http://.

Line 204 says http://localhost:3001 but with HTTPS enabled the server will be on https://. Consider noting this or making the URL protocol-agnostic (e.g., "Development: https://localhost:3001 (or http:// if SSL is not enabled)").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 203 - 204, The README currently hardcodes the
development URL as "http://localhost:3001"; update the text around the
Development URL (the bullet under "Open your browser") to be protocol-agnostic
or mention HTTPS explicitly (for example "https://localhost:3001 (or http:// if
SSL is not enabled)" or use "//localhost:3001") so it accurately reflects
environments with SSL enabled; change the line that currently reads
`http://localhost:3001` to the chosen protocol-agnostic/HTTPS-aware wording.
🧹 Nitpick comments (1)
vite.config.js (1)

6-7: isTruthyEnv is duplicated across vite.config.js and server/index.js.

Both files define an identical isTruthyEnv helper. Consider extracting it to a shared utility module (e.g., server/utils.js or a common lib/ file) to keep them in sync.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vite.config.js` around lines 6 - 7, Duplicate helper isTruthyEnv should be
extracted to a shared module and both callers should import it; create a new
utility file (e.g., utils.js or lib/env.js) that exports isTruthyEnv, move the
existing function implementation there, then replace the local definitions in
vite.config.js and server/index.js with imports of the shared isTruthyEnv;
ensure the exported function name and behavior remain identical and update any
references to call the imported symbol.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@vite.config.js`:
- Line 13: The current httpsEnabled constant (const httpsEnabled =
isTruthyEnv(env.VITE_HTTPS) || isTruthyEnv(env.SSL_ENABLED)) conflates Vite's
own server HTTPS and the backend proxy protocol; change logic so Vite's
server.https is driven only by VITE_HTTPS (and cert paths) while the proxy
target protocol is computed from SSL_ENABLED. Update the code references to stop
using httpsEnabled for both purposes: use a new viteHttps flag derived from
isTruthyEnv(env.VITE_HTTPS) for server.https configuration (and cert options),
and use a separate backendHttps flag derived from isTruthyEnv(env.SSL_ENABLED)
when building proxy target URLs (choose 'https://' or 'http://').
- Around line 42-50: The proxy entries for '/ws' and '/shell' already use object
form but need secure: false added to allow self-signed certs, and the '/api'
entry must be converted from string form to an object with target set to
`${apiProtocol}://localhost:${env.PORT || 3001}` and secure: false; update the
proxy config in vite.config.js (the '/api', '/ws', '/shell' entries) to include
secure: false so HTTPS/WSS proxies accept self-signed certificates.

---

Outside diff comments:
In `@README.md`:
- Around line 203-204: The README currently hardcodes the development URL as
"http://localhost:3001"; update the text around the Development URL (the bullet
under "Open your browser") to be protocol-agnostic or mention HTTPS explicitly
(for example "https://localhost:3001 (or http:// if SSL is not enabled)" or use
"//localhost:3001") so it accurately reflects environments with SSL enabled;
change the line that currently reads `http://localhost:3001` to the chosen
protocol-agnostic/HTTPS-aware wording.

---

Nitpick comments:
In `@vite.config.js`:
- Around line 6-7: Duplicate helper isTruthyEnv should be extracted to a shared
module and both callers should import it; create a new utility file (e.g.,
utils.js or lib/env.js) that exports isTruthyEnv, move the existing function
implementation there, then replace the local definitions in vite.config.js and
server/index.js with imports of the shared isTruthyEnv; ensure the exported
function name and behavior remain identical and update any references to call
the imported symbol.




const httpsEnabled = isTruthyEnv(env.VITE_HTTPS) || isTruthyEnv(env.SSL_ENABLED)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bug: Conflating Vite HTTPS and backend HTTPS will cause proxy failures.

httpsEnabled uses isTruthyEnv(env.VITE_HTTPS) || isTruthyEnv(env.SSL_ENABLED), which means setting VITE_HTTPS=true alone (without SSL_ENABLED) will enable Vite HTTPS and derive proxy targets as https://, even though the backend is running plain HTTP. Conversely, SSL_ENABLED=true alone will enable Vite HTTPS even if the user only intended backend HTTPS.

These are independent concerns and should be decoupled:

  • Vite's own server.https should be driven by VITE_HTTPS (+ its cert paths).
  • The proxy target protocol should be driven by SSL_ENABLED (the backend's SSL state).
Proposed fix: decouple Vite HTTPS from backend HTTPS
-  const httpsEnabled = isTruthyEnv(env.VITE_HTTPS) || isTruthyEnv(env.SSL_ENABLED)
-  const certPath = env.VITE_SSL_CERT_PATH || env.SSL_CERT_PATH
-  const keyPath = env.VITE_SSL_KEY_PATH || env.SSL_KEY_PATH
+  // Vite dev server HTTPS (independent of backend)
+  const viteHttpsEnabled = isTruthyEnv(env.VITE_HTTPS)
+  const viteCertPath = env.VITE_SSL_CERT_PATH || env.SSL_CERT_PATH
+  const viteKeyPath = env.VITE_SSL_KEY_PATH || env.SSL_KEY_PATH
+
+  // Backend SSL (controls proxy target protocol)
+  const backendSslEnabled = isTruthyEnv(env.SSL_ENABLED)

   let httpsConfig
-  if (httpsEnabled) {
-    if (certPath && keyPath) {
+  if (viteHttpsEnabled) {
+    if (viteCertPath && viteKeyPath) {
       try {
         httpsConfig = {
-          cert: fs.readFileSync(path.resolve(certPath)),
-          key: fs.readFileSync(path.resolve(keyPath))
+          cert: fs.readFileSync(path.resolve(viteCertPath)),
+          key: fs.readFileSync(path.resolve(viteKeyPath))
         }
       } catch (error) {
         console.warn('[vite] HTTPS enabled but SSL cert files could not be read. Falling back to HTTP.', error?.message || error)
       }
     } else {
-      console.warn('[vite] HTTPS enabled but VITE_SSL_CERT_PATH/VITE_SSL_KEY_PATH (or SSL_CERT_PATH/SSL_KEY_PATH) are missing. Falling back to HTTP.')
+      console.warn('[vite] HTTPS enabled but VITE_SSL_CERT_PATH (or SSL_CERT_PATH) are missing. Falling back to HTTP.')
     }
   }

-  const apiProtocol = httpsConfig ? 'https' : 'http'
-  const wsProtocol = httpsConfig ? 'wss' : 'ws'
+  const apiProtocol = backendSslEnabled ? 'https' : 'http'
+  const wsProtocol = backendSslEnabled ? 'wss' : 'ws'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vite.config.js` at line 13, The current httpsEnabled constant (const
httpsEnabled = isTruthyEnv(env.VITE_HTTPS) || isTruthyEnv(env.SSL_ENABLED))
conflates Vite's own server HTTPS and the backend proxy protocol; change logic
so Vite's server.https is driven only by VITE_HTTPS (and cert paths) while the
proxy target protocol is computed from SSL_ENABLED. Update the code references
to stop using httpsEnabled for both purposes: use a new viteHttps flag derived
from isTruthyEnv(env.VITE_HTTPS) for server.https configuration (and cert
options), and use a separate backendHttps flag derived from
isTruthyEnv(env.SSL_ENABLED) when building proxy target URLs (choose 'https://'
or 'http://').

Comment on lines +42 to 50
'/api': `${apiProtocol}://localhost:${env.PORT || 3001}`,
'/ws': {
target: `ws://localhost:${env.PORT || 3001}`,
target: `${wsProtocol}://localhost:${env.PORT || 3001}`,
ws: true
},
'/shell': {
target: `ws://localhost:${env.PORT || 3001}`,
target: `${wsProtocol}://localhost:${env.PORT || 3001}`,
ws: true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find . -name "vite.config.js" -o -name "vite.config.ts" | head -5

Repository: siteboon/claudecodeui

Length of output: 81


🏁 Script executed:

cat -n vite.config.js | sed -n '35,55p'

Repository: siteboon/claudecodeui

Length of output: 728


🌐 Web query:

Vite proxy self-signed certificate secure: false configuration

💡 Result:

To proxy from Vite to an HTTPS backend with a self‑signed cert, set secure: false on that proxy rule. This tells the underlying proxy (Vite uses node-http-proxy-style options) not to validate the target TLS certificate (i.e., it effectively disables rejectUnauthorized). Use this for local/dev only. [1], [2]

// vite.config.ts
import { defineConfig } from "vite";

export default defineConfig({
  server: {
    proxy: {
      "/api": {
        target: "https://localhost:5001", // your HTTPS backend
        changeOrigin: true,
        secure: false,                    // allow self-signed certs
        // rewrite: (p) => p.replace(/^\/api/, ""), // optional
      },
    },
  },
});

Notes:

  • server.proxy is dev-server only; it’s not part of the production build. [3]
  • Prefer fixing trust properly (install a cert or trust a local CA) instead of leaving verification disabled. [4]

Sources: node-http-proxy HTTPS/cert validation behavior [1]; example Vite proxy config using secure: false [2]; Vite server proxy is dev-only context [3]; why disabling TLS verification is risky [4].


🏁 Script executed:

cat -n vite.config.js | sed -n '1,45p'

Repository: siteboon/claudecodeui

Length of output: 1978


🏁 Script executed:

find . -name "Contributing.md" -o -name "README.md" | head -5

Repository: siteboon/claudecodeui

Length of output: 114


🏁 Script executed:

cat -n README.md | head -100

Repository: siteboon/claudecodeui

Length of output: 4137


🏁 Script executed:

grep -i "self-signed\|certificate\|https\|ssl" README.md

Repository: siteboon/claudecodeui

Length of output: 2504


Add secure: false to proxy targets to allow self-signed certificates.

When HTTPS is enabled (as documented in the setup), the proxies target https://localhost:3001 and wss://localhost:3001. Without secure: false, Node's TLS will reject the self-signed certificate with UNABLE_TO_VERIFY_LEAF_SIGNATURE, causing all proxied requests to fail. The /api proxy must be expanded to object form to support the secure property.

Proposed fix
       '/api': {
+        target: `${apiProtocol}://localhost:${env.PORT || 3001}`,
+        secure: false
       },
       '/ws': {
         target: `${wsProtocol}://localhost:${env.PORT || 3001}`,
-        ws: true
+        ws: true,
+        secure: false
       },
       '/shell': {
         target: `${wsProtocol}://localhost:${env.PORT || 3001}`,
-        ws: true
+        ws: true,
+        secure: false
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vite.config.js` around lines 42 - 50, The proxy entries for '/ws' and
'/shell' already use object form but need secure: false added to allow
self-signed certs, and the '/api' entry must be converted from string form to an
object with target set to `${apiProtocol}://localhost:${env.PORT || 3001}` and
secure: false; update the proxy config in vite.config.js (the '/api', '/ws',
'/shell' entries) to include secure: false so HTTPS/WSS proxies accept
self-signed certificates.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant