This guide walks you through setting up JobHunter Max with the secure backend for API key management.
- Node.js 18+ (download from nodejs.org)
- npm 9+ (comes with Node.js)
- API Keys (optional):
- OpenAI API key from platform.openai.com
- DeepSeek API key from deepseek.com
- OR Ollama installed from ollama.com for local AI
# Navigate to your project
cd cyber-job-hunter
# Install frontend dependencies
npm install
# Install backend dependencies
npm run server:install# Enter the server directory
cd server
# Copy environment template
cp .env.example .env
# Edit .env with your settings
nano .env
# (or use your preferred editor: code .env, vim .env, etc.)What to configure in .env:
PORT=3001
NODE_ENV=development
FRONTEND_URL=http://localhost:5173
SESSION_SECRET=your-secret-key-min-32-characters
# Optional: Add API keys here (or set them in the app)
OPENAI_API_KEY=
DEEPSEEK_API_KEY=# Go back to root directory
cd ..
# Copy environment template
cp .env.example .env.local
# Edit .env.local
nano .env.localWhat to configure in .env.local:
VITE_API_URL=http://localhost:3001Terminal 1 - Backend Server:
npm run serverYou should see:
🔒 Secure API server running on http://localhost:3001
Terminal 2 - Frontend App:
npm run devYou should see:
VITE v7.3.1 ready in 500 ms
➜ Local: http://localhost:5173/
➜ press h to show help
Open http://localhost:5173 and go to Settings:
Option A: Local AI with Ollama
- Install Ollama from ollama.com
- Run:
ollama pull llama3.2 - In Settings, select "Ollama (Local)"
- The app will auto-detect your models
Option B: OpenAI
- Get API key from platform.openai.com/api-keys
- In Settings, select "OpenAI"
- Paste your API key and click "Save"
- The backend securely stores it (encrypted)
Option C: DeepSeek
- Get API key from DeepSeek
- In Settings, select "DeepSeek"
- Paste your API key and click "Save"
- The backend securely stores it (encrypted)
| Variable | Purpose | Example |
|---|---|---|
PORT |
Server port | 3001 |
NODE_ENV |
Environment mode | development or production |
FRONTEND_URL |
Frontend URL (CORS) | http://localhost:5173 |
SESSION_SECRET |
Encryption key (NEVER share!) | your-random-string-here |
OPENAI_API_KEY |
OpenAI credentials | sk-... |
DEEPSEEK_API_KEY |
DeepSeek credentials | sk-... |
# On macOS/Linux:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# On Windows (PowerShell):
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Copy the output and paste it into .env as SESSION_SECRET.
| Variable | Purpose | Example |
|---|---|---|
VITE_API_URL |
Backend API URL | http://localhost:3001 |
# Build the frontend
npm run build
# Output will be in the 'dist' folder
# Upload to your hosting servicecyber-job-hunter/
├── src/ # Frontend React app
│ ├── components/ # Reusable components
│ ├── pages/ # Page components
│ │ └── Settings.tsx # ⭐ API key configuration
│ ├── store/ # Zustand store (non-sensitive data only)
│ ├── types/ # TypeScript types
│ ├── utils/
│ │ ├── ai.ts # AI utilities
│ │ └── backend-api.ts # ⭐ Backend communication
│ └── App.tsx
│
├── server/ # Backend Node.js server
│ ├── index.js # ⭐ Main server file
│ ├── crypto.js # ⭐ Encryption/decryption
│ ├── package.json
│ ├── .env.example # Environment template
│ └── .gitignore # Don't commit .env!
│
├── .env.example # Frontend env template
├── .gitignore # Git ignore rules
├── README.md # Main documentation
├── SECURITY.md # Security policy
└── SETUP.md # This file
- You enter API key → Settings page (password field)
- Backend encrypts it → AES-256-GCM encryption
- Stored securely → Backend server only (not in browser)
- Used by backend → Calls OpenAI/DeepSeek APIs
- Frontend never sees key → Only receives AI responses
Settings → Select Provider → Paste API Key → Click "Save"
↓
Backend receives encrypted transmission (HTTPS)
↓
Backend encrypts with AES-256-GCM
↓
Backend stores in memory/database
↓
Success message shown to user
Click "Generate" → Frontend sends request to backend
↓
Backend retrieves encrypted key
↓
Backend decrypts key
↓
Backend calls OpenAI/DeepSeek API
↓
Backend sends response back to frontend
↓
User sees AI-generated content
Settings → Click "Delete" → Confirm
↓
Backend removes encrypted key from storage
↓
API key is no longer accessible
# Check if backend is running
curl http://localhost:3001/health
# If not running:
npm run server
# Check for port conflicts
lsof -i :3001 # macOS/Linux
netstat -ano | findstr :3001 # Windows# Start Ollama
ollama serve
# In another terminal, download a model
ollama pull llama3.2
# Ollama runs on http://localhost:11434- Check browser console for errors (F12 → Console)
- Check backend logs in terminal
- Ensure backend is running on correct port
- Verify
FRONTEND_URLin.envmatches your frontend URL
# Check .env FRONTEND_URL matches your actual frontend URL:
# ❌ WRONG: FRONTEND_URL=http://localhost:5173 (but running on 5174)
# ✅ RIGHT: FRONTEND_URL=http://localhost:5174# Generate a new one:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Add to .env:
SESSION_SECRET=<generated-string># 1. Set environment variables on your host
# PORT, NODE_ENV=production, FRONTEND_URL, SESSION_SECRET
# OPENAI_API_KEY, DEEPSEEK_API_KEY
# 2. Install dependencies
npm install
# 3. Start server (with production process manager)
# Using PM2:
npm install -g pm2
pm2 start server/index.js --name "jobhunter-api"
# Using systemd:
# Create /etc/systemd/system/jobhunter.service with:
# [Service]
# ExecStart=/usr/bin/node /path/to/server/index.js
# Environment="NODE_ENV=production"
# Environment="PORT=3000"# 1. Set environment variable
VITE_API_URL=https://your-api.com
# 2. Build
npm run build
# 3. Deploy dist/ folder to your host- Use HTTPS/TLS certificates
- Set
NODE_ENV=production - Generate strong
SESSION_SECRET - Configure
FRONTEND_URLwith HTTPS - Never commit
.envfiles - Review CORS settings
- Set up monitoring and logging
- Enable rate limiting
- Update all dependencies
# Terminal 1: Backend
npm run server
# Terminal 2: Frontend
npm run dev
# Access app at http://localhost:5173# Frontend
npm run dev # Start dev server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Check code quality
# Backend
npm run server # Start server (from root with server/ dir)
npm run server:install # Install server dependencies
# Or from server/ directory:
cd server
npm run dev # Start with auto-reload
npm start # Start normallyFrontend Debug (Browser DevTools):
- Open: http://localhost:5173
- Press: F12
- Tab: Console, Network, Application
Backend Debug:
// Add logs in server/index.js
console.log('🔍 Debug:', variable);Check API Connectivity:
# Test health endpoint
curl http://localhost:3001/health
# Should return: {"status":"Server is running"}- ✅ Complete setup (Steps 1-5 above)
- 📖 Read README.md for feature overview
- 🔒 Review SECURITY.md for security details
- 🧪 Test with sample data
- 🚀 Deploy to production when ready
- 📚 Check README.md for feature documentation
- 🔒 Read SECURITY.md for security questions
- 💬 Check browser console (F12 → Console) for errors
- 📋 Review backend logs in terminal
After setup, you should have these files:
- ✅
.env(backend config) - DO NOT COMMIT - ✅
.env.local(frontend config) - DO NOT COMMIT - ✅
server/.env(server config) - DO NOT COMMIT - ✅
SECURITY.md(this security guide) - ✅
SETUP.md(this setup guide) - ✅ Updated
README.mdwith security info
✅ API Keys - Encrypted with AES-256-GCM on backend
✅ Sessions - Validated server-side
✅ Transport - HTTPS in production
✅ Data - Never exposed to frontend
✅ Credentials - Not stored in browser
Ready to start? Run the Quick Start (5 minutes) section above and you'll be up and running!