Add optional HTTPS support for backend and Vite dev server#400
Add optional HTTPS support for backend and Vite dev server#400stephenfeather wants to merge 1 commit intositeboon:mainfrom
Conversation
📝 WalkthroughWalkthroughThis 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
Sequence DiagramsequenceDiagram
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
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 | 🟡 MinorMinor: Development URL still hardcodes
http://.Line 204 says
http://localhost:3001but with HTTPS enabled the server will be onhttps://. Consider noting this or making the URL protocol-agnostic (e.g., "Development:https://localhost:3001(orhttp://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:isTruthyEnvis duplicated acrossvite.config.jsandserver/index.js.Both files define an identical
isTruthyEnvhelper. Consider extracting it to a shared utility module (e.g.,server/utils.jsor a commonlib/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) |
There was a problem hiding this comment.
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.httpsshould be driven byVITE_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://').
| '/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 | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "vite.config.js" -o -name "vite.config.ts" | head -5Repository: 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.proxyis 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 -5Repository: siteboon/claudecodeui
Length of output: 114
🏁 Script executed:
cat -n README.md | head -100Repository: siteboon/claudecodeui
Length of output: 4137
🏁 Script executed:
grep -i "self-signed\|certificate\|https\|ssl" README.mdRepository: 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.
Summary
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:
http/ws->https/wsswhen enabled)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
Documentation