Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 35 additions & 14 deletions server/.env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,44 @@
# ── Server ────────────────────────────────────────────────────────────────────
PORT=8000
MONGO_URI=mongodb+srv://@cluster0.fshcjhd.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0
JWT_SECRET=your_jwt_secret_here
NODE_ENV=development

# ── Database ──────────────────────────────────────────────────────────────────
MONGO_URI=mongodb+srv://<username>:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0

# ── JWT ───────────────────────────────────────────────────────────────────────
# Use long, random strings β€” at least 64 characters each. Never reuse JWT_SECRET for refresh.
JWT_SECRET=your_long_random_access_token_secret_here
JWT_ACCESS_EXPIRES_IN=15m
JWT_REFRESH_SECRET=your_separate_refresh_secret_here
JWT_REFRESH_SECRET=your_completely_separate_long_random_refresh_secret_here
JWT_REFRESH_EXPIRES_IN=30d
GEMINI_API_KEY=your_gemini_key_here
NVIDIA_API_KEY=your_nvidia_key_here

# ── Frontend URL (CORS + OAuth redirects) ────────────────────────────────────
# Development: http://localhost:5173
# Production: https://your-app.vercel.app (your actual Vercel URL)
CLIENT_URL=http://localhost:5173
NODE_ENV=development

# GitHub OAuth
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
# ── GitHub OAuth ──────────────────────────────────────────────────────────────
# Create an OAuth App at: https://github.com/settings/developers
# Homepage URL: http://localhost:5173 (or your Vercel URL in prod)
# Callback URL: http://localhost:8000/api/auth/github/callback
# (or https://your-api.onrender.com/api/auth/github/callback in prod)
GITHUB_CLIENT_ID=your_github_oauth_app_client_id
GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
GITHUB_CALLBACK_URL=http://localhost:8000/api/auth/github/callback
GITHUB_STATE_SECRET=your_optional_dedicated_state_secret
# Optional: separate secret for the OAuth state JWT. Falls back to JWT_SECRET if not set.
GITHUB_STATE_SECRET=your_optional_github_state_jwt_secret

# ── AI ────────────────────────────────────────────────────────────────────────
GEMINI_API_KEY=your_google_gemini_api_key
# NVIDIA_API_KEY is optional β€” only needed if NVIDIA AI features are used
NVIDIA_API_KEY=your_nvidia_api_key_optional

# ── Email (Nodemailer / Gmail SMTP) ──────────────────────────────────────────
# For Gmail:
# 1. Enable 2-factor authentication on your Google account
# 2. Generate an App Password at: https://myaccount.google.com/apppasswords
# 3. Use that 16-character App Password as SMTP_PASS (NOT your Gmail password)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your email
SMTP_PASS=your pass

REDIS_URL=redis://localhost:6379
SMTP_USER=your-gmail@gmail.com
SMTP_PASS=your_16_char_gmail_app_password
12 changes: 11 additions & 1 deletion server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@ import { globalLimiter, apiLimiter } from "./middlewares/rateLimiter.js";

const app = express();

// ── Trust Proxy (REQUIRED for Render deployment) ──────────────────────────────
// Render sits behind a reverse proxy. Without this, express-rate-limit sees
// the proxy's IP for every user β€” meaning the first user to hit the rate limit
// blocks EVERYONE. This tells Express to trust the X-Forwarded-For header from
// Render's proxy layer so each real client IP is identified separately.
app.set("trust proxy", 1);

// ── Allowed CORS origins ──────────────────────────────────────────────────────
// CLIENT_URL must be your live Vercel URL in production, e.g. https://codelens.vercel.app
const allowedOrigins = [
process.env.CLIENT_URL,
process.env.CLIENT_URI,
// Allow localhost in non-production for local development to keep working
...(process.env.NODE_ENV !== "production" ? ["http://localhost:5173"] : [])
].filter(Boolean);

const corsOptions = {
origin: function (origin, callback) {
// Allow requests with no origin (curl, Postman, server-to-server)
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
Expand Down
5 changes: 3 additions & 2 deletions server/config/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const requiredEnvVars = [
"PORT",
"MONGO_URI",
"JWT_SECRET",
"JWT_EXPIRES_IN",
"JWT_ACCESS_EXPIRES_IN",
// JWT_REFRESH_SECRET must be a separate key from JWT_SECRET.
// Using the same key for both would allow forging refresh tokens from an access token.
"JWT_REFRESH_SECRET",
Expand All @@ -29,8 +29,9 @@ export const env = {
PORT: process.env.PORT,
MONGO_URI: process.env.MONGO_URI,
JWT_SECRET: process.env.JWT_SECRET,
JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN,
JWT_ACCESS_EXPIRES_IN: process.env.JWT_ACCESS_EXPIRES_IN,
JWT_REFRESH_SECRET: process.env.JWT_REFRESH_SECRET,
JWT_REFRESH_EXPIRES_IN: process.env.JWT_REFRESH_EXPIRES_IN,
GEMINI_API_KEY: process.env.GEMINI_API_KEY,
CLIENT_URL: process.env.CLIENT_URL,
NODE_ENV: process.env.NODE_ENV,
Expand Down
5 changes: 4 additions & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
Expand All @@ -24,8 +25,10 @@
"jsonwebtoken": "^9.0.3",
"mongoose": "^9.3.3",
"nodemailer": "^8.0.4",
"nodemon": "^3.1.14",
"openai": "^6.33.0",
"zod": "^4.3.6"
},
"devDependencies": {
"nodemon": "^3.1.14"
}
}
Loading
Loading