Skip to content

Latest commit

 

History

History
422 lines (329 loc) · 11.5 KB

File metadata and controls

422 lines (329 loc) · 11.5 KB

Environment Variables Import Verification

✅ Verification Complete - All Imports Are Correct!

🎯 How Environment Variables Work in Node.js

Important: You only need to import dotenv ONCE at the entry point of your application. Once dotenv.config() is called, all process.env variables are available globally throughout your entire application.


📋 Current Implementation Status

✅ Entry Points (Correct)

1. Main API Server (index.js)

// Line 1-2
import dotenv from "dotenv";
dotenv.config();

// Then all other imports...
import express from "express";
import cookieParser from "cookie-parser";
// etc...

Status: ✅ CORRECT - dotenv loaded FIRST

2. Worker Process (worker.js)

// Line 4-5
import dotenv from "dotenv";
dotenv.config();

// Then all other imports...
import mongoose from "mongoose";
import Groq from "groq-sdk";
// etc...

Status: ✅ CORRECT - dotenv loaded FIRST


✅ Config Files (Correct - No Import Needed)

1. Redis Config (config/redis.js)

import Redis from 'ioredis';

// Uses process.env directly
const config = {
    host: process.env.REDIS_HOST || 'localhost',
    port: process.env.REDIS_PORT || 6379,
    password: process.env.REDIS_PASSWORD || undefined,
    // ...
};

Status: ✅ CORRECT - No dotenv import needed (already loaded by index.js)

2. Queue Config (config/queue.js)

import Queue from 'bull';

// Uses process.env directly
const REDIS_CONFIG = {
    host: process.env.REDIS_HOST || 'localhost',
    port: process.env.REDIS_PORT || 6379,
    password: process.env.REDIS_PASSWORD || undefined,
    // ...
};

Status: ✅ CORRECT - No dotenv import needed (already loaded by index.js)


✅ Services (Correct - No Import Needed)

1. OTP Service (services/otpService.js)

import crypto from 'crypto';
import { getRedisClient } from '../config/redis.js';

// No process.env usage in this file
// All configuration comes from function parameters

Status: ✅ CORRECT - No env vars used directly

2. Email Service (services/emailService.js)

import nodemailer from 'nodemailer';

// Uses process.env directly
static getTransporter() {
    const emailService = process.env.EMAIL_SERVICE || 'smtp';
    // ...
    pass: process.env.SENDGRID_API_KEY
    // ...
}

Status: ✅ CORRECT - No dotenv import needed (already loaded by index.js)


✅ Controllers (Correct - No Import Needed)

1. User Controller (controllers/userController.js)

import { User } from "../models/user.model.js";
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { OTPService } from '../services/otpService.js';
import { EmailService } from '../services/emailService.js';

// Uses process.env directly
const token = jwt.sign(
    { userId: user._id },
    process.env.JWT_SECRET,  // ✅ Available
    { expiresIn: '7d' }
);

const maxAttempts = parseInt(process.env.OTP_RATE_LIMIT_MAX) || 3;  // ✅ Available
const expiryMinutes = parseInt(process.env.OTP_EXPIRY_MINUTES) || 10;  // ✅ Available

Status: ✅ CORRECT - No dotenv import needed (already loaded by index.js)


🔍 Environment Variables Usage Map

Variables Used in Password Reset Feature

Variable Used In Default Required
EMAIL_SERVICE emailService.js smtp ✅ Yes
EMAIL_FROM emailService.js noreply@intervai.com ✅ Yes
EMAIL_FROM_NAME emailService.js IntervAI Support No
SENDGRID_API_KEY emailService.js - If using SendGrid
SMTP_HOST emailService.js smtp.gmail.com If using SMTP
SMTP_PORT emailService.js 587 If using SMTP
SMTP_USER emailService.js - If using SMTP
SMTP_PASS emailService.js - If using SMTP
OTP_EXPIRY_MINUTES userController.js 10 No
OTP_MAX_ATTEMPTS userController.js 3 No
OTP_RATE_LIMIT_MAX userController.js 3 No
PASSWORD_MIN_LENGTH userController.js 6 No
REDIS_HOST redis.js, queue.js localhost ✅ Yes
REDIS_PORT redis.js, queue.js 6379 ✅ Yes
REDIS_PASSWORD redis.js, queue.js - ✅ Yes (Production)

Variables Used in Existing Features

Variable Used In Required
JWT_SECRET userController.js, auth.middleware.js ✅ Yes
NODE_ENV index.js, multiple files No
PORT index.js No
MONGO_URI worker.js, db.js ✅ Yes
GROQ_API_KEY questionController.js, worker.js ✅ Yes
CLIENT_URL index.js No

🧪 Testing Environment Variable Loading

Test 1: Check if dotenv is loaded

# Start the API server
npm run dev

# Check console output - should see:
# ✅ Database connected
# ✅ Redis Connected
# ✅ Server running on http://localhost:8000

Test 2: Verify env vars are accessible

Create a test endpoint temporarily:

// Add to index.js (for testing only)
app.get('/test-env', (req, res) => {
    res.json({
        EMAIL_SERVICE: process.env.EMAIL_SERVICE || 'not set',
        OTP_EXPIRY_MINUTES: process.env.OTP_EXPIRY_MINUTES || 'not set',
        REDIS_HOST: process.env.REDIS_HOST || 'not set',
        hasJWT: !!process.env.JWT_SECRET,
        hasMongoURI: !!process.env.MONGO_URI
    });
});
curl http://localhost:8000/test-env

Expected Output:

{
  "EMAIL_SERVICE": "gmail",
  "OTP_EXPIRY_MINUTES": "10",
  "REDIS_HOST": "redis",
  "hasJWT": true,
  "hasMongoURI": true
}

Test 3: Check Redis connection with password

docker-compose logs api | grep Redis

Expected Output:

✅ Redis Connected
✅ Redis Ready

If you see errors like NOAUTH Authentication required, then REDIS_PASSWORD is not being read correctly.


🐛 Common Issues & Solutions

Issue 1: Environment variables not loading

Symptom: process.env.VARIABLE_NAME is undefined

Causes:

  1. .env file doesn't exist
  2. .env file is in wrong location
  3. Variable name typo in .env
  4. dotenv not imported in entry point

Solution:

# Check .env exists
ls -la .env

# Check .env location (should be in project root)
pwd
# Should show: /path/to/intervai

# Check .env content
cat .env | grep EMAIL_SERVICE

# Restart server
docker-compose down
docker-compose up -d

Issue 2: Redis password not working

Symptom: NOAUTH Authentication required

Check:

# 1. Check .env has password
cat .env | grep REDIS_PASSWORD

# 2. Check docker-compose.yml uses password
cat docker-compose.yml | grep REDIS_PASSWORD

# 3. Restart services
docker-compose down
docker-compose up -d

# 4. Test Redis connection
docker exec -it intervai-redis redis-cli
> AUTH your-password
OK

Issue 3: Email not sending

Symptom: Failed to send email

Check:

# 1. Check email config in .env
cat .env | grep EMAIL
cat .env | grep SMTP

# 2. Check logs
docker-compose logs api | grep Email

# 3. Test SMTP connection
node -e "
const nodemailer = require('nodemailer');
require('dotenv').config();
const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: process.env.SMTP_PORT,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS
  }
});
transporter.verify().then(() => console.log('✅ SMTP OK')).catch(console.error);
"

Issue 4: OTP configuration not working

Symptom: OTP expires too quickly or rate limiting not working

Check:

# 1. Check OTP config in .env
cat .env | grep OTP

# 2. Check if defaults are being used
docker-compose logs api | grep OTP

# 3. Verify in code
# If you see "expires in 10 minutes" but set OTP_EXPIRY_MINUTES=5,
# then env var is not being read

✅ Verification Checklist

Entry Points

  • index.js imports dotenv at the top
  • worker.js imports dotenv at the top
  • dotenv.config() called before other imports

Config Files

  • config/redis.js uses process.env (no dotenv import needed)
  • config/queue.js uses process.env (no dotenv import needed)
  • config/db.js uses process.env (no dotenv import needed)

Services

  • services/otpService.js - No env vars used directly
  • services/emailService.js uses process.env (no dotenv import needed)
  • services/cacheService.js uses process.env (no dotenv import needed)

Controllers

  • controllers/userController.js uses process.env (no dotenv import needed)
  • All other controllers use process.env (no dotenv import needed)

Middlewares

  • middlewares/auth.middleware.js uses process.env (no dotenv import needed)
  • All other middlewares use process.env (no dotenv import needed)

📊 Import Flow Diagram

┌─────────────────────────────────────────┐
│  index.js (Entry Point)                 │
│  ┌─────────────────────────────────┐   │
│  │ import dotenv from "dotenv"     │   │
│  │ dotenv.config()                 │   │
│  │ ↓                               │   │
│  │ process.env is now populated    │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ↓ imports                              │
│                                         │
│  ├─ config/redis.js                    │
│  │  └─ uses process.env.REDIS_HOST    │
│  │                                     │
│  ├─ config/queue.js                    │
│  │  └─ uses process.env.REDIS_PORT    │
│  │                                     │
│  ├─ routes/user.routes.js              │
│  │  └─ imports controllers             │
│  │     └─ controllers/userController.js│
│  │        └─ uses process.env.JWT_SECRET│
│  │        └─ imports services          │
│  │           └─ services/emailService.js│
│  │              └─ uses process.env.EMAIL_*│
│  │                                     │
│  └─ All imports have access to         │
│     process.env variables              │
└─────────────────────────────────────────┘

🎯 Summary

✅ All Imports Are Correct!

Why it works:

  1. dotenv.config() is called at the very top of index.js and worker.js
  2. This populates process.env with all variables from .env file
  3. All subsequent imports (config, services, controllers) can access process.env
  4. No need to import dotenv in every file

Best Practice:

  • ✅ Import dotenv ONLY in entry points (index.js, worker.js)
  • ✅ Call dotenv.config() BEFORE any other imports
  • ✅ Use process.env directly in all other files
  • ❌ Don't import dotenv in config/service/controller files

Current Implementation:

  • ✅ Follows best practices
  • ✅ All env vars are accessible
  • ✅ No redundant imports
  • ✅ Clean and maintainable

📚 Additional Resources


Verification Date: February 14, 2026
Status: ✅ ALL CORRECT
Action Required: None - Implementation is correct!