Skip to content
Geovanni-devPublic

About

API em Node.js (TypeScript, Prisma, Supabase) desenvolvida para consultar uma blacklist de IDs do Mobile Legends (MLBB). O projeto protege a comunidade contra fraudes em negociações e possui um front-end responsivo (Tailwind) exclusivo para demonstração técnica no portfólio.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🇧🇷 Português

🛡️ IDQuery Blacklist

💼 Freelance Project — This API was developed for a client as a lookup service for the Mobile Legends community, allowing players to verify account IDs with a history of theft or fraud before making any trade. See it live at: blacklist.reicontas.com.br


🛠️ Tech Stack

Back-end & Infrastructure:

  • Node.js + TypeScript — Solid, typed, and scalable foundation
  • Express — API routing and middlewares
  • Prisma ORM — Type-safe data modeling and queries
  • Supabase (PostgreSQL) — Cloud-hosted relational database
  • Docker — Full containerization for standardized deployment
  • GitHub Actions — CI/CD pipeline for automated build and deploy
  • ESLint + Prettier — Static analysis and consistent code style enforcement

📁 Project Structure

/
├── .github/
│   └── workflows/
│       └── deploy.yml          # CI/CD pipeline
├── prisma/
│   ├── migrations/             # Database migrations history
│   └── schema.prisma           # Data models definition
├── public/                     # Static assets directory (not served by the current app)
├── src/
│   ├── IDs/
│   │   ├── controller/
│   │   │   └── idController.ts # Request handlers
│   │   └── routes/
│   │       └── idRoutes.ts     # Route definitions
│   ├── lib/
│   │   └── prisma.ts           # Prisma client singleton
│   ├── middlewares/            # Custom middlewares (rate limit, etc.)
│   ├── app.ts                  # Express app setup
│   └── server.ts               # HTTP server entry point
├── .dockerignore
├── .editorconfig
├── .env.example
├── .prettierrc
├── docker-compose.yml
├── Dockerfile
├── eslint.config.js
├── package.json
├── prisma.config.ts
├── tsconfig.json
└── yarn.lock

⚙️ Features & Security

  • ID management — Public lookup, individual or bulk creation, and deletion. There is no update route.
  • Redis rate limiting — Independent quotas per IP: 10 lookups per minute and 5 administrative attempts per minute shared across all three write routes. Excess requests return 429; there is no additional five-minute cooldown. IPv6 addresses are grouped according to the library default.
  • Administrative authentication — Write routes require x-api-key, compared with API_KEY_SECRET in constant time for equal-length keys. Rate limiting runs before authentication, so invalid attempts (401) also count.
  • Zod validation — Creation requires numeric IDs with at least four digits. Lookup and deletion extract the first numeric sequence and validate the result: 74694823 (1278) is accepted; abcd and abc1 are rejected.
  • Trusted proxies — TRUSTED_PROXIES defines the proxy addresses Express trusts when interpreting forwarded headers.
  • CORS — CLIENT_URL controls which origins may read responses in browsers. CORS does not replace authentication or block external HTTP clients.

📍 API Endpoints

Method Route Authentication Quota per minute
GET /ids/:id Public 10 per IP
POST /ids/add x-api-key 5 per IP, shared across administrative routes
POST /ids/bulk x-api-key Same administrative quota
DELETE /ids/:id x-api-key Same administrative quota

Creation accepts { "id": "12345678", "server": 1234, "descricao": "example" }. server and descricao are optional; the server must be a four-digit integer and the description must contain at least four characters. /ids/bulk accepts an array of these objects. Keep the administrative key private.

🚀 Local Setup

Clone the repository and enter the project directory. Use .env.example as a starting point and complete .env with the variables below; the example file does not yet list all of them:

PORT=3333
DATABASE_URL="postgresql://user:password@postgres:5432/postgres"
REDIS_URL="redis://redis:6379"
API_KEY_SECRET="replace-with-a-long-random-key"
CLIENT_URL="http://localhost:3000"
TRUSTED_PROXIES=

PostgreSQL and Redis must be available at the configured addresses. postgres and redis are example hostnames and must resolve inside the container. The local Compose file does not create these services. API_KEY_SECRET is required; the API will not start without it. CLIENT_URL accepts comma-separated origins. Without REDIS_URL, the code tries redis://localhost:6379, which refers to the container itself when running in Docker.

docker compose up -d --build

The repository Compose file builds the image locally and publishes 3333:3333. Prepare the database structure according to prisma/schema.prisma; starting the container does not automatically apply migrations.

🌐 Proxy and Production

Use the same image on different VPS instances and set TRUSTED_PROXIES in each API environment to the Nginx Proxy Manager IP on the shared network. Illustrative example:

TRUSTED_PROXIES=172.18.0.2

This is the NPM IP, not the API IP entered as the forwarding destination in its dashboard. The application splits the variable by commas, removes whitespace and empty entries, and passes the list to trust proxy. If missing or empty, it uses false. This replaces one-hop trust (trust proxy = 1) with trust in the configured addresses.

NPM must forward visitor headers correctly. Keep the API port unpublished on the host and communicate through the shared Docker network. Ensure the NPM IP stays stable or update the variable when it changes; recreate the API container to apply environment changes.

Example VPS Compose file, separate from the development Compose file:

services:
  api:
    image: geovani3344/id-query-v20-api:latest
    container_name: id-query
    restart: always
    env_file:
      - .env
    networks:
      - rede-proxy

networks:
  rede-proxy:
    external: true

The external network must exist and be shared with NPM. Adjust its name on each VPS and configure access to PostgreSQL and Redis.

To update manually, run these commands in that Compose directory:

docker compose pull api
docker compose up -d api
docker compose ps
docker compose logs --tail=50 api

There is no need to run down first: the API remains active during the download, with a possible brief interruption when the container is recreated.

⚙️ CI/CD with GitHub Actions

On every push to main, .github/workflows/deploy.yml builds and publishes <DOCKERHUB_USERNAME>/id-query-v20-api:latest. It then connects to the VPS over SSH, enters ~/id-query-v20-api, and runs docker compose pull followed by docker compose up -d. The remote Compose file must reference the published image and load the VPS .env file.

Secret Contents
DOCKERHUB_USERNAME Docker Hub username
DOCKERHUB_TOKEN Docker Hub access token
SSH_HOST VPS IP or domain, without ssh, a protocol, or a username
SSH_USER SSH username
SSH_KEY Private key used to authenticate the deployment
SSH_KNOWN_HOSTS VPS address and known public host key in known_hosts format

From a trusted session on the VPS receiving deployments, retrieve its public host key:

cat /etc/ssh/ssh_host_ed25519_key.pub

Create SSH_KNOWN_HOSTS under Settings → Secrets and variables → Actions with a single line in this format:

VPS_ADDRESS ssh-ed25519 VPS_PUBLIC_KEY

Replace VPS_ADDRESS with the exact value of SSH_HOST and VPS_PUBLIC_KEY with the returned key. Do not include root@, quotes, or only the key without its address. Use only the .pub file. The current workflow uses the default SSH port, 22.

The workflow writes secrets through environment variables, restricts SSH file permissions, and uses StrictHostKeyChecking=yes. The connection fails if the identity is not recognized; it does not use ssh-keyscan to trust a key obtained during deployment. set -e stops remote commands on failure. Since downloading precedes recreation, a failed pull does not first take the API down.

These SSH secrets belong to Actions and are not included in the image. Other VPS instances can pull the same image manually with their own environment variables.

📄 License

MIT © Geovani Rodrigues

About

API em Node.js (TypeScript, Prisma, Supabase) desenvolvida para consultar uma blacklist de IDs do Mobile Legends (MLBB). O projeto protege a comunidade contra fraudes em negociações e possui um front-end responsivo (Tailwind) exclusivo para demonstração técnica no portfólio.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages