A production-grade proxy and VPS management platform. Admin syncs proxies from proxy-seller.com, assigns them to customers, and manages renewals. Customers log in to view their credentials.
- Create a Supabase project at https://supabase.com
- Go to SQL Editor and run
database/schema.sql - Copy your Project URL and service_role key (Settings → API)
cd backend
cp .env.example .env
# Fill in .env with your real values
npm install
node scripts/createAdmin.js # Create initial admin user (once)
npm run dev # Development
npm start # ProductionGenerate secure secrets:
# JWT secrets
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
# Encryption key (run twice for JWT_SECRET and JWT_REFRESH_SECRET)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"cd frontend
cp .env.example .env
# Set VITE_API_URL= (leave empty for local dev, set to Render URL for production)
npm install
npm run dev| Variable | Description |
|---|---|
SUPABASE_URL |
Supabase project URL |
SUPABASE_SERVICE_KEY |
service_role key (NOT anon key!) |
JWT_SECRET |
64-byte hex string |
JWT_REFRESH_SECRET |
Different 64-byte hex string |
ENCRYPTION_KEY |
64-char hex (32 bytes) for AES-256-GCM |
PROXY_SELLER_API_KEY |
Your proxy-seller.com API key |
FRONTEND_URL |
Your Vercel URL (for CORS) |
COOKIE_SECRET |
Random 64-byte hex string |
PORT |
3000 (default) |
| Variable | Description |
|---|---|
VITE_API_URL |
Backend URL (empty for local dev w/ proxy) |
- Push
backend/to GitHub - Create new Web Service on Render
- Build command:
npm install - Start command:
node server.js - Add all env vars from
.env.example - Note the Render URL
- Push
frontend/to GitHub - Import to Vercel
- Set
VITE_API_URL=https://your-render-url.onrender.com - Deploy → copy the Vercel URL
- Add Vercel URL as
FRONTEND_URLin Render env vars - Redeploy backend
.envis in.gitignore— never commit it- Backend uses service_role key — never expose to frontend
- Refresh tokens are hashed (SHA-256) before DB storage
- Proxy/VPS passwords encrypted with AES-256-GCM
- All admin routes return 403 if
role !== 'admin' - CORS restricted to FRONTEND_URL only
POST /api/auth/login { username, password } → { accessToken, user }
POST /api/auth/refresh (cookie) → { accessToken }
POST /api/auth/logout → clears cookie + DB
GET /api/admin/stats
GET /api/admin/proxies/sync
GET /api/admin/proxies
POST /api/admin/proxies/:id/assign { userId }
DELETE /api/admin/proxies/:id
POST /api/admin/vps { ip, password, ... }
GET /api/admin/vps
POST /api/admin/vps/:id/assign { userId }
DELETE /api/admin/vps/:id
GET /api/admin/users
POST /api/admin/users { name, username, password }
GET /api/admin/users/:id
PUT /api/admin/users/:id/password { newPassword }
DELETE /api/admin/users/:id
GET /api/admin/renewals
POST /api/admin/renewals/:id/complete { months }
GET /api/user/proxies
GET /api/user/vps
POST /api/user/proxies/:id/renew
POST /api/user/vps/:id/renew
PUT /api/user/password { currentPassword, newPassword }
GET /api/user/profile