Skip to content

Make localhost/port values configurable via env vars#84

Open
LuisAPI wants to merge 3 commits into
mainfrom
feat/env-localhost-replace
Open

Make localhost/port values configurable via env vars#84
LuisAPI wants to merge 3 commits into
mainfrom
feat/env-localhost-replace

Conversation

@LuisAPI
Copy link
Copy Markdown
Collaborator

@LuisAPI LuisAPI commented Nov 19, 2025

Replaces hardcoded localhost and port values with environment-configurable options and documents them in README.

Changes:

  • backend/server.js: Use ALLOWED_ORIGINS env var (comma-separated) or a sensible local-default list. Use BACKEND_PORT/BACKEND_HOST for defaults/logs.
  • backend/routes/gmail.js: Use CLASSIFIER_URL env var (default http://localhost:5001) for classifier calls.
  • frontend/src/App.js: Use REACT_APP_BACKEND_URL if set; otherwise default to https://:<BACKEND_PORT> when on localhost, or current origin in non-local envs.
  • README.md: Added docs for ALLOWED_ORIGINS, CLASSIFIER_URL, BACKEND_PORT, BACKEND_HOST and default behavior.

This makes local host/port values configurable for different dev setups and avoids hardcoded redirect/URL values that caused problems when running on different ports or environments.

Summary by Sourcery

Enable configuring backend host, port, CORS origins, and classifier service URL via environment variables, and update frontend to respect REACT_APP_BACKEND_URL with dynamic fallback.

Enhancements:

  • Allow configuring CORS allowed origins through an ALLOWED_ORIGINS env var with sensible local-development defaults
  • Introduce CLASSIFIER_URL env var for the Gmail classifier endpoint
  • Support BACKEND_PORT and BACKEND_HOST env vars for backend startup port and log output
  • Update frontend to use REACT_APP_BACKEND_URL or dynamically construct the backend URL based on host and BACKEND_PORT

Documentation:

  • Document ALLOWED_ORIGINS, CLASSIFIER_URL, BACKEND_PORT, BACKEND_HOST, and REACT_APP_BACKEND_URL environment variables and their defaults in the README

- Use ALLOWED_ORIGINS env var or sensible default list for CORS
- Make CLASSIFIER_URL configurable (default http://localhost:5001)
- Make frontend REACT_APP_BACKEND_URL fallback dynamic (uses BACKEND_PORT)
- Add README docs for new env vars (ALLOWED_ORIGINS, CLASSIFIER_URL, BACKEND_PORT, BACKEND_HOST)
@netlify
Copy link
Copy Markdown

netlify Bot commented Nov 19, 2025

Deploy Preview for imfrisivmail ready!

Name Link
🔨 Latest commit 02c59b1
🔍 Latest deploy log https://app.netlify.com/projects/imfrisivmail/deploys/691dc7b14baeff0008c8db8c
😎 Deploy Preview https://deploy-preview-84--imfrisivmail.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Nov 19, 2025

Reviewer's Guide

This PR replaces hardcoded localhost and port values across backend and frontend with environment-variable-driven configuration for CORS origins, server host/ports, classifier URLs, and updates README accordingly.

Class diagram for updated configuration usage in backend and frontend

classDiagram
  class ExpressServer {
    +allowedOrigins: string[]
    +PORT: number
    +HOST: string
    +constructor()
    +startupLog()
  }
  class GmailRoute {
    +classifierBase: string
    +POST /classify
  }
  class ReactApp {
    +backendUrl: string
    +frontendUrl: string
    +handleGmailLogin()
  }
  ExpressServer <|-- GmailRoute
  ReactApp -- ExpressServer: "Sends login/auth requests"
  GmailRoute -- Classifier: "Calls classifier service"
  Classifier: "URL configurable via CLASSIFIER_URL"
  ExpressServer: "CORS origins configurable via ALLOWED_ORIGINS"
  ExpressServer: "Port configurable via BACKEND_PORT"
  ExpressServer: "Host configurable via BACKEND_HOST"
  ReactApp: "Backend URL configurable via REACT_APP_BACKEND_URL"
  GmailRoute: "Classifier URL configurable via CLASSIFIER_URL"
Loading

File-Level Changes

Change Details Files
Make CORS origins configurable via ALLOWED_ORIGINS env var
  • Read ALLOWED_ORIGINS as comma-separated list, trim entries
  • Fallback to original localhost/127.0.0.1 defaults if unset
backend/server.js
Allow BACKEND_PORT and BACKEND_HOST overrides for server startup
  • Use process.env.BACKEND_PORT before defaulting to 5002
  • Use process.env.BACKEND_HOST in HTTPS startup log
backend/server.js
Use CLASSIFIER_URL env var for classifier service endpoint backend/routes/gmail.js
Derive frontend backend URL from REACT_APP_BACKEND_URL or host/port env vars
  • Prefer REACT_APP_BACKEND_URL if set
  • On localhost use https://:<BACKEND_PORT> defaulting to 5002
  • Otherwise use current origin in production
frontend/src/App.js
Document new environment variables and defaults
  • Add ALLOWED_ORIGINS, CLASSIFIER_URL, BACKEND_PORT, BACKEND_HOST to README
  • Explain default behaviors and usage notes
README.md

Possibly linked issues

  • #[issue-id]: The PR makes backend host and port configurable via environment variables, directly addressing the issue's problem with hardcoded localhost URLs for mobile and tunneling setups.

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

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and they look great!

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

## Individual Comments

### Comment 1
<location> `backend/server.js:16` </location>
<code_context>
+const allowedOrigins = process.env.ALLOWED_ORIGINS
</code_context>

<issue_to_address>
**suggestion:** Consider validating ALLOWED_ORIGINS input for empty strings.

Empty strings in allowedOrigins may cause unexpected CORS behavior. Filter them out after splitting to improve robustness.

```suggestion
  ? process.env.ALLOWED_ORIGINS.split(",").map((s) => s.trim()).filter(Boolean)
```
</issue_to_address>

### Comment 2
<location> `backend/server.js:150-152` </location>
<code_context>
       };
       https.createServer(options, app).listen(PORT, () => {
-        console.log(`HTTPS server running at https://localhost:${PORT}`);
+        const host = process.env.BACKEND_HOST || "localhost";
+        console.log(`HTTPS server running at https://${host}:${PORT}`);
       });
</code_context>

<issue_to_address>
**suggestion:** BACKEND_HOST may not match actual binding host.

If the server binds to a different host than BACKEND_HOST, the log output may be inaccurate. Consider clarifying the log message or ensuring the binding matches BACKEND_HOST.

```suggestion
      https.createServer(options, app).listen(PORT, () => {
        // The server binds to 0.0.0.0 or localhost by default unless specified otherwise.
        // BACKEND_HOST may be used for external access, but may not match the actual binding host.
        const externalHost = process.env.BACKEND_HOST || "localhost";
        console.log(`HTTPS server running (bound to port ${PORT}). External access: https://${externalHost}:${PORT}`);
```
</issue_to_address>

### Comment 3
<location> `frontend/src/App.js:41-45` </location>
<code_context>
+  // to localhost on `BACKEND_PORT` (default 5002). In production default to the current origin.
+  const backendUrl =
+    process.env.REACT_APP_BACKEND_URL ||
+    ((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
+      ? `https://${window.location.hostname}:${process.env.BACKEND_PORT || 5002}`
+      : `${window.location.protocol}//${window.location.host}`);
   const frontendUrl = window.location.origin;
   const handleGmailLogin = () => {
</code_context>

<issue_to_address>
**suggestion:** Mixing protocol and port logic may cause issues in some dev setups.

Defaulting to https for localhost can cause connection errors if the backend uses http. Consider detecting the protocol or making it configurable to support different development setups.

```suggestion
  // Allow protocol override for localhost via REACT_APP_BACKEND_PROTOCOL, default to 'http'
  const backendProtocol =
    process.env.REACT_APP_BACKEND_PROTOCOL ||
    ((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') ? 'http' : window.location.protocol.replace(':', ''));

  const backendUrl =
    process.env.REACT_APP_BACKEND_URL ||
    ((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
      ? `${backendProtocol}://${window.location.hostname}:${process.env.BACKEND_PORT || 5002}`
      : `${window.location.protocol}//${window.location.host}`);
```
</issue_to_address>

### Comment 4
<location> `backend/routes/gmail.js:76-79` </location>
<code_context>
-    // Call classifier
-    const classificationResponse = await axios.post("http://localhost:5001/classify", {
+    // Call classifier (URL configurable via CLASSIFIER_URL env var)
+    const classifierBase = process.env.CLASSIFIER_URL || "http://localhost:5001";
+    const classificationResponse = await axios.post(`${classifierBase.replace(/\/$/,"")}/classify`, {
       emails: emailBodies,
</code_context>

<issue_to_address>
**suggestion:** Consider validating CLASSIFIER_URL for trailing slashes.

Also, trim whitespace from CLASSIFIER_URL to prevent issues from accidental spaces or formatting.

```suggestion
    let classifierBase = process.env.CLASSIFIER_URL || "http://localhost:5001";
    classifierBase = classifierBase.trim().replace(/\/+$/, "");
    const classificationResponse = await axios.post(`${classifierBase}/classify`, {
      emails: emailBodies,
    });
```
</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 backend/server.js
// Allow configuring allowed CORS origins via environment variable `ALLOWED_ORIGINS` as a comma-separated list.
// If not provided, fall back to a safe default set used for local development.
const allowedOrigins = process.env.ALLOWED_ORIGINS
? process.env.ALLOWED_ORIGINS.split(",").map((s) => s.trim())
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: Consider validating ALLOWED_ORIGINS input for empty strings.

Empty strings in allowedOrigins may cause unexpected CORS behavior. Filter them out after splitting to improve robustness.

Suggested change
? process.env.ALLOWED_ORIGINS.split(",").map((s) => s.trim())
? process.env.ALLOWED_ORIGINS.split(",").map((s) => s.trim()).filter(Boolean)

Comment thread backend/server.js
Comment on lines 146 to +152
https.createServer(options, app).listen(PORT, () => {
console.log(`HTTPS server running at https://localhost:${PORT}`);
const host = process.env.BACKEND_HOST || "localhost";
console.log(`HTTPS server running at https://${host}:${PORT}`);
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: BACKEND_HOST may not match actual binding host.

If the server binds to a different host than BACKEND_HOST, the log output may be inaccurate. Consider clarifying the log message or ensuring the binding matches BACKEND_HOST.

Suggested change
https.createServer(options, app).listen(PORT, () => {
console.log(`HTTPS server running at https://localhost:${PORT}`);
const host = process.env.BACKEND_HOST || "localhost";
console.log(`HTTPS server running at https://${host}:${PORT}`);
https.createServer(options, app).listen(PORT, () => {
// The server binds to 0.0.0.0 or localhost by default unless specified otherwise.
// BACKEND_HOST may be used for external access, but may not match the actual binding host.
const externalHost = process.env.BACKEND_HOST || "localhost";
console.log(`HTTPS server running (bound to port ${PORT}). External access: https://${externalHost}:${PORT}`);

Comment thread frontend/src/App.js
Comment on lines +41 to +45
const backendUrl =
process.env.REACT_APP_BACKEND_URL ||
((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
? `https://${window.location.hostname}:${process.env.BACKEND_PORT || 5002}`
: `${window.location.protocol}//${window.location.host}`);
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: Mixing protocol and port logic may cause issues in some dev setups.

Defaulting to https for localhost can cause connection errors if the backend uses http. Consider detecting the protocol or making it configurable to support different development setups.

Suggested change
const backendUrl =
process.env.REACT_APP_BACKEND_URL ||
((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
? `https://${window.location.hostname}:${process.env.BACKEND_PORT || 5002}`
: `${window.location.protocol}//${window.location.host}`);
// Allow protocol override for localhost via REACT_APP_BACKEND_PROTOCOL, default to 'http'
const backendProtocol =
process.env.REACT_APP_BACKEND_PROTOCOL ||
((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') ? 'http' : window.location.protocol.replace(':', ''));
const backendUrl =
process.env.REACT_APP_BACKEND_URL ||
((window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
? `${backendProtocol}://${window.location.hostname}:${process.env.BACKEND_PORT || 5002}`
: `${window.location.protocol}//${window.location.host}`);

Comment thread backend/routes/gmail.js
Comment on lines +76 to 79
const classifierBase = process.env.CLASSIFIER_URL || "http://localhost:5001";
const classificationResponse = await axios.post(`${classifierBase.replace(/\/$/,"")}/classify`, {
emails: emailBodies,
});
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: Consider validating CLASSIFIER_URL for trailing slashes.

Also, trim whitespace from CLASSIFIER_URL to prevent issues from accidental spaces or formatting.

Suggested change
const classifierBase = process.env.CLASSIFIER_URL || "http://localhost:5001";
const classificationResponse = await axios.post(`${classifierBase.replace(/\/$/,"")}/classify`, {
emails: emailBodies,
});
let classifierBase = process.env.CLASSIFIER_URL || "http://localhost:5001";
classifierBase = classifierBase.trim().replace(/\/+$/, "");
const classificationResponse = await axios.post(`${classifierBase}/classify`, {
emails: emailBodies,
});

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.

Fix OAuth Redirect URL in Production Allow a user to launch the backend server into a temporary tunnel

1 participant