# 🌍 Bitip - GeoIP Lookup Service Bitip is a professional GeoIP lookup service that provides IP geolocation data through a REST API and user-friendly web interface. Built with Express.js, TypeScript, React, and MaxMind GeoLite2 databases. ## ✨ Features - **πŸ” IP Geolocation Lookup**: Get detailed location information for any public IP address - **🌐 Web Interface**: Clean, professional web UI with interactive maps - **πŸ“‘ REST API**: Comprehensive API for single and batch IP lookups - **πŸ—ΊοΈ Interactive Maps**: Static preview and interactive map popups using OpenStreetMap/Leaflet - **πŸ” API Key Authentication**: Secure access with configurable rate limiting - **⚑ Performance**: In-memory caching and efficient database access - **πŸ“Š Structured Logging**: Optional integration with Seq for advanced logging - **🐳 Docker Ready**: Production deployment with Docker and geoipupdate integration - **πŸ”§ Configurable**: Runtime configuration via environment variables ## πŸš€ Quick Start ### Local Development (No Docker Required) #### Prerequisites - Node.js >= 18.0.0 - npm >= 9.0.0 - MaxMind GeoLite2 databases (download from https://www.maxmind.com/en/geolite2/signup or use geoipupdate) #### 1. Clone and Setup ```bash git clone cd Bitip ``` #### 2. Install Dependencies ```bash npm run install:all ``` #### 3. Configure Environment Create a `.env` file in the root directory: ```env # API Keys (change these for production!) FRONTEND_API_KEY=frontend-dev-key EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2 # Server Configuration PORT=3000 BASE_PATH=/ NODE_ENV=development # Database Path - Point to your MaxMind databases location MAXMIND_DB_PATH=D:\tools\maxmind-dbs # Windows # MAXMIND_DB_PATH=/usr/share/GeoIP # Linux/Mac # Rate Limiting Configuration FRONTEND_RATE_WINDOW_MS=60000 FRONTEND_RATE_MAX=30 EXTERNAL_RATE_WINDOW_MS=60000 EXTERNAL_RATE_MAX=1000 # Batch Configuration BATCH_LIMIT=100 DEBOUNCE_MS=2000 # Seq Logging (Optional) # SEQ_URL=http://localhost:5341 # SEQ_API_KEY=your-seq-api-key ``` #### 4. Start Development Servers ```bash npm run dev ``` This will start: - Backend API server on http://localhost:3000 - Frontend dev server on http://localhost:5173 (or next available port) - Frontend proxies API requests to backend #### 5. Access the Application - **Web Interface**: http://localhost:5173 (or the port shown in console) - **API Endpoint**: http://localhost:3000/api - **Health Check**: http://localhost:3000/api/health ### Production Deployment (Docker) #### Prerequisites - Docker and Docker Compose - MaxMind GeoLite2 account (free): https://www.maxmind.com/en/geolite2/signup #### 1. Configure Environment Edit `.env` file with your MaxMind credentials: ```env GEOIPUPDATE_ACCOUNT_ID=your_account_id_here GEOIPUPDATE_LICENSE_KEY=your_license_key_here FRONTEND_API_KEY=your-secure-frontend-api-key-here EXTERNAL_API_KEYS=your-secure-external-api-key-1,your-secure-external-api-key-2 ``` #### 2. Start Services ```bash docker-compose up -d ``` #### 3. Access the Service - **Web Interface**: http://localhost:3000 - **API Endpoint**: http://localhost:3000/api - **Health Check**: http://localhost:3000/api/health ## πŸ“– API Documentation ### Authentication All API requests require an API key sent via header or query parameter: ```bash # Via Header (recommended) curl -H "X-API-Key: your-api-key" http://localhost:3000/api/lookup?ip=8.8.8.8 # Via Query Parameter curl "http://localhost:3000/api/lookup?ip=8.8.8.8&apikey=your-api-key" ``` ### Endpoints #### Get Current IP ```http GET /api/ip ``` Returns the client's current IP address. **Response:** ```json { "ip": "203.0.113.42" } ``` #### Simple IP Lookup ```http GET /api/lookup?ip=8.8.8.8 ``` Returns basic location information: ```json { "ip": "8.8.8.8", "country": "United States", "country_code": "US", "region": "California", "city": "Mountain View", "latitude": 37.4056, "longitude": -122.0775, "timezone": "America/Los_Angeles", "postal_code": "94043" } ``` #### Detailed IP Lookup ```http GET /api/lookup/detailed?ip=8.8.8.8 ``` Returns comprehensive MaxMind database information including all available fields. #### Batch IP Lookup ```http POST /api/lookup/batch Content-Type: application/json { "ips": ["8.8.8.8", "1.1.1.1", "208.67.222.222"] } ``` **Response:** ```json { "results": [ { "ip": "8.8.8.8", "country": "United States", ... }, { "ip": "1.1.1.1", "country": "Australia", ... } ] } ``` #### Health Check ```http GET /api/health ``` Returns service health status including database connectivity. ### Error Handling The API returns appropriate HTTP status codes: - `400` - Bad Request (invalid IP, private IP, validation errors) - `401` - Unauthorized (missing or invalid API key) - `404` - Not Found (IP not in database) - `429` - Too Many Requests (rate limit exceeded) - `500` - Internal Server Error - `503` - Service Unavailable (database maintenance) ## πŸ› οΈ Development ### Project Structure ``` Bitip/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ backend/ # Express.js API server β”‚ β”‚ β”œβ”€β”€ routes/ # API route handlers β”‚ β”‚ β”œβ”€β”€ services/ # Business logic (GeoIP, config, logger) β”‚ β”‚ β”œβ”€β”€ middleware/ # Express middleware (auth, rate limiting) β”‚ β”‚ β”œβ”€β”€ types/ # TypeScript type definitions β”‚ β”‚ β”œβ”€β”€ index.ts # Main server entry point β”‚ β”‚ β”œβ”€β”€ nodemon.json # Nodemon configuration β”‚ β”‚ β”œβ”€β”€ tsconfig.json # TypeScript configuration β”‚ β”‚ └── package.json # Backend dependencies β”‚ └── frontend/ # React web application β”‚ β”œβ”€β”€ src/ β”‚ β”‚ β”œβ”€β”€ components/ # React components (MapComponent) β”‚ β”‚ β”œβ”€β”€ services/ # API client services β”‚ β”‚ β”œβ”€β”€ types/ # TypeScript types β”‚ β”‚ β”œβ”€β”€ App.tsx # Main App component β”‚ β”‚ β”œβ”€β”€ App.css # Application styles β”‚ β”‚ └── main.tsx # React entry point β”‚ β”œβ”€β”€ index.html # HTML template β”‚ β”œβ”€β”€ vite.config.ts # Vite configuration β”‚ β”œβ”€β”€ tsconfig.json # TypeScript configuration β”‚ └── package.json # Frontend dependencies β”œβ”€β”€ docs/ # Documentation (PRD, tech stack) β”œβ”€β”€ .env # Environment variables (not in git) β”œβ”€β”€ .env.example # Example environment file β”œβ”€β”€ Dockerfile # Production Docker image β”œβ”€β”€ docker-compose.yml # Production deployment └── package.json # Root package configuration ``` ### Available Scripts ```bash # Development npm run dev # Start both frontend and backend in dev mode npm run dev:backend # Start backend development server only npm run dev:frontend # Start frontend development server only # Building npm run build # Build both frontend and backend for production npm run build:backend # Build backend only npm run build:frontend # Build frontend only # Production npm start # Start production backend server (after build) # Code Quality npm run lint # Lint both frontend and backend npm run lint:fix # Fix linting issues npm run format # Format code with Prettier # Utilities npm run clean # Clean build artifacts npm run install:all # Install all dependencies (root + backend + frontend) ``` ### Technology Stack **Backend:** - Express.js 4.x with TypeScript - @maxmind/geoip2-node 5.x - GeoIP database reader - node-cache - In-memory caching - express-rate-limit - Rate limiting - helmet - Security headers - joi - Request validation - seq-logging - Optional structured logging **Frontend:** - React 18.x with TypeScript - Vite 4.x - Build tool and dev server - Leaflet & react-leaflet - Interactive maps - Axios - HTTP client - OpenStreetMap - Map tiles **Development Tools:** - TypeScript 5.x - ESLint & Prettier - nodemon - Auto-restart on changes - ts-node - TypeScript execution ## βš™οΈ Configuration ### Environment Variables | Variable | Default | Description | | ------------------------- | ---------------------- | -------------------------------------------- | | `PORT` | `3000` | Server port | | `BASE_PATH` | `/` | Application base path | | `NODE_ENV` | `development` | Environment mode (development/production) | | `MAXMIND_DB_PATH` | `/usr/share/GeoIP` | MaxMind database directory | | `FRONTEND_API_KEY` | `frontend-default-key` | Frontend API key | | `EXTERNAL_API_KEYS` | `external-default-key` | External API keys (comma-separated) | | `FRONTEND_RATE_WINDOW_MS` | `60000` | Frontend rate limit window (milliseconds) | | `FRONTEND_RATE_MAX` | `30` | Frontend rate limit max requests | | `EXTERNAL_RATE_WINDOW_MS` | `60000` | External rate limit window (milliseconds) | | `EXTERNAL_RATE_MAX` | `1000` | External rate limit max requests | | `BATCH_LIMIT` | `100` | Maximum IPs per batch request | | `DEBOUNCE_MS` | `2000` | Frontend input debounce delay (milliseconds) | | `SEQ_URL` | - | Seq logging server URL (optional) | | `SEQ_API_KEY` | - | Seq API key (optional) | ### MaxMind Database Setup The service requires MaxMind GeoLite2-City database. You have two options: **Option 1: Manual Download** 1. Sign up at https://www.maxmind.com/en/geolite2/signup 2. Download GeoLite2-City database (`.mmdb` file) 3. Place it in a directory (e.g., `D:\tools\maxmind-dbs` on Windows) 4. Set `MAXMIND_DB_PATH` environment variable to that directory **Option 2: Using geoipupdate (Production)** - Use the provided `docker-compose.yml` which includes geoipupdate service - geoipupdate automatically downloads and updates databases - Both services share a Docker volume for database access ### Rate Limiting Bitip implements different rate limiting for frontend and external API consumers: - **Frontend**: More restrictive limits for web UI usage (default: 100 req/min) - **External**: Higher limits for programmatic API access (default: 1000 req/min) Rate limits are fully configurable via environment variables and include standard HTTP headers in responses. ## 🐳 Docker Deployment ### Production Setup The service is designed to run alongside MaxMind's geoipupdate service: ```bash # Start both services docker-compose up -d # View logs docker-compose logs -f bitip # Stop services docker-compose down ``` The `docker-compose.yml` includes: - **geoipupdate**: Downloads and updates MaxMind databases - **bitip**: Main application server (API + Web UI) - **Shared volume**: For database access between services ### Health Monitoring The service includes comprehensive health checks: - Docker health check endpoint: `/api/health` - Database connectivity verification - Service status monitoring ## πŸ”§ Troubleshooting ### Common Issues **1. Database Not Found** - Ensure databases are downloaded to the path specified in `MAXMIND_DB_PATH` - Check that `GeoLite2-City.mmdb` file exists in that directory - Verify file permissions (read access required) **2. TypeScript Errors** - Run `npm run install:all` to ensure all dependencies are installed - Check that Node.js version is >= 18.0.0 - Try deleting `node_modules` and reinstalling **3. API Authentication Errors** - Verify API key in `.env` file matches the one you're using - Check `X-API-Key` header or `apikey` query parameter format - Ensure API key doesn't contain extra spaces **4. Rate Limiting** - Check rate limit headers in API responses (`X-RateLimit-*`) - Adjust rate limiting configuration if needed - Use external API keys for higher limits **5. Map Display Issues** - Verify internet connectivity for OpenStreetMap tiles - Check browser console for JavaScript errors - Ensure Leaflet CSS is loading correctly **6. Port Already in Use** - Frontend dev server will auto-increment port (5173, 5174, etc.) - Backend port can be changed via `PORT` environment variable - Check for other services using the same ports ### Logs and Debugging - Application logs are printed to console - Use `npm run dev` for detailed development logs - Configure Seq integration for structured logging - Docker logs: `docker-compose logs -f bitip` ## πŸ“¦ Package Versions **Current versions (as of project creation):** - Major packages are on stable versions but not latest - Consider updating for newer features and security fixes - Check `npm outdated` for available updates - Test thoroughly after major version updates **Key outdated packages:** - Express 4.x (5.x available but still beta) - React 18.x (19.x available) - Vite 4.x (7.x available - major update) - Many dev dependencies have newer versions ## πŸ“„ License **Copyright Β© 2025 Tudor Stanciu. All rights reserved.** This software is **proprietary** and confidential. Unauthorized use, copying, modification, distribution, or reverse engineering of this software, in whole or in part, is strictly prohibited without explicit written permission from the copyright holder. ### License Summary - βœ… **Evaluation Period**: 30-day trial for evaluation purposes - βœ… **Approved Use**: Requires explicit written approval from Tudor Stanciu - ❌ **No Redistribution**: Cannot be distributed, sublicensed, or transferred to third parties - ❌ **No Modification**: Cannot be modified or create derivative works without permission - ❌ **No Commercial Use**: Cannot be used for commercial services without separate license ### Obtaining a License For licensing inquiries, commercial use, or approval requests: **Contact**: Tudor Stanciu **Email**: tudor.stanciu94@gmail.com Please include: - Intended use case - Organization name and size - Expected deployment scale - Duration of use See [LICENSE](LICENSE) file for complete terms and conditions. ## πŸ™ Acknowledgments - **MaxMind** for providing GeoLite2 databases - **OpenStreetMap** for map tiles - **Leaflet** for interactive mapping - All open-source contributors --- **Bitip** - Professional GeoIP Lookup Service 🌍 Built with ❀️ using Express.js, React, and MaxMind GeoLite2