mirror of
https://forgejo.ultimateplayer.xyz/ultimateplayer1999/dcordabuse.git
synced 2026-09-15 20:55:49 -04:00
116 lines
6.0 KiB
Markdown
116 lines
6.0 KiB
Markdown
# dcordabuse
|
|
|
|
Zelf-gehoste, gemodereerde meldingsdatabase voor Discord-accounts, geïnspireerd op Dangercord maar met een ingebouwde moderatiequeue: reports worden pas publiek zichtbaar nadat een beheerder ze goedkeurt. Dit voorkomt dat het systeem zonder controle gebruikt kan worden voor ongefundeerde beschuldigingen, doxxing of stalking.
|
|
Stack
|
|
Next.js 16 (App Router) + TypeScript
|
|
PostgreSQL via Prisma
|
|
API-key auth (SHA-256 gehasht, twee rollen: `SUBMITTER` en `ADMIN`)
|
|
Database-based rate limiting (30 requests/minuut per key, aan te passen in `src/lib/rateLimit.ts`)
|
|
Lokale setup
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
# vul DATABASE_URL in
|
|
|
|
npm install
|
|
npx prisma migrate dev --name init
|
|
npm run dev
|
|
```
|
|
|
|
Maak daarna je eerste keys aan:
|
|
|
|
```bash
|
|
npx tsx scripts/create-api-key.ts "Admin dashboard" ADMIN
|
|
npx tsx scripts/create-api-key.ts "Report-bot server X" SUBMITTER
|
|
```
|
|
|
|
De plaintext key wordt eenmalig getoond — bewaar hem meteen (bv. in een password manager of `.env` van de client die 'm gebruikt). In de database staat alleen de hash.
|
|
Draaien met Docker Compose
|
|
|
|
```bash
|
|
echo "POSTGRES_PASSWORD=$(openssl rand -base64 24)" > .env
|
|
docker compose up -d --build
|
|
docker compose exec app npx prisma migrate deploy
|
|
docker compose exec app npx tsx scripts/create-api-key.ts "Admin dashboard" ADMIN
|
|
```
|
|
|
|
De app luistert intern op poort 3000. Onderstaande de config voor NGINX:
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl;
|
|
listen [::]:443 ssl; # niet vergeten, zoals je eerder al vaker tegenkwam
|
|
server_name dangerguard.jouwdomein.nl;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/jouwdomein.nl/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/jouwdomein.nl/privkey.pem;
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:3000;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
}
|
|
}
|
|
```
|
|
|
|
De endpoint link is naar eigen wens aan te maken, maar zorg ervoor dat het matched met je keuze, dus ook in alle overige voorbeelden.
|
|
|
|
Let bij Cloudflare op dat WAF-regels de `Authorization`-header en `PATCH`/`POST`-requests naar `/api/*` niet blokkeren.
|
|
API
|
|
Alle endpoints verwachten `Authorization: Bearer <key>`.
|
|
`GET /api/v1/users/:discordId`
|
|
Rol: SUBMITTER of ADMIN. Geeft alleen goedgekeurde reports terug.
|
|
|
|
```bash
|
|
curl -H "Authorization: Bearer dg_live_xxx" \
|
|
https://dangerguard.jouwdomein.nl/api/v1/users/123456789012345678
|
|
```
|
|
|
|
`POST /api/v1/reports`
|
|
Rol: SUBMITTER of ADMIN. Dient een nieuwe report in — komt binnen als `PENDING`.
|
|
|
|
```bash
|
|
curl -X POST -H "Authorization: Bearer dg_live_xxx" -H "Content-Type: application/json" \
|
|
-d '{"discordId":"123456789012345678","category":"SCAM","description":"Stuurde phishing-links via DM naar meerdere serverleden."}' \
|
|
https://dangerguard.jouwdomein.nl/api/v1/reports
|
|
```
|
|
|
|
`GET /api/admin/reports?status=PENDING`
|
|
Rol: ADMIN. Lijst openstaande reports voor moderatie.
|
|
`PATCH /api/admin/reports/:id`
|
|
Rol: ADMIN. Keurt goed of af.
|
|
|
|
```bash
|
|
|
|
curl -X PATCH -H "Authorization: Bearer dg_live_admin" -H "Content-Type: application/json" \
|
|
-d '{"action":"approve"}' \
|
|
https://dangerguard.jouwdomein.nl/api/admin/reports/abc123
|
|
```
|
|
|
|
## Frontend
|
|
|
|
`/search` — publieke zoekpagina (vraagt om een SUBMITTER/ADMIN key)
|
|
`/admin` — moderatiedashboard (vraagt om een ADMIN key)
|
|
Deze pagina's sturen de key vanuit de browser mee als Bearer-token; voor productiegebruik is het verstandiger hier een sessie/login-laag voor te zetten in plaats van de raw key te laten intypen, zeker voor het admin-dashboard.
|
|
Discord-integratie: notificatie + moderatie via buttons
|
|
Bij elke nieuwe report wordt (indien `DISCORD_WEBHOOK_URL` gezet is) een bericht gestuurd met een Approve/Reject-button. Klikken op een button verwerkt de moderatie direct in Discord — geen aparte bot-proces nodig, alleen een HTTPS endpoint dat Discord kan bereiken.
|
|
Setup:
|
|
Maak een Discord Application aan op [de Discord applicatie portaal](https://discord.com/developers/applications) (of gebruik een bestaande).
|
|
Kopieer de Public Key (General Information) naar `DISCORD_PUBLIC_KEY`.
|
|
Zet de Interactions Endpoint URL op bijvoorbeeld `https://dangerguard.jouwdomein.nl/api/discord/interactions` (zorg ervoor dat het matched met wat je hebt gekozen).
|
|
Discord test deze meteen met een PING-request; die moet dus al live staan vóórdat je 'm opslaat.
|
|
Maak in het doelkanaal een webhook aan (Kanaal-instellingen > Integraties) en zet de URL in `DISCORD_WEBHOOK_URL`.
|
|
Zet de Role ID van je moderator-rol in `DISCORD_ADMIN_ROLE_ID`. Alleen leden met deze rol kunnen de buttons daadwerkelijk gebruiken; anderen krijgen een ephemeral "geen rechten"-melding.
|
|
Belangrijk: de rolcheck werkt alleen als de bot/applicatie ook daadwerkelijk in de server (guild) aanwezig is — anders stuurt Discord geen `member.roles` mee. Voeg de applicatie dus toe als bot met minimale permissies (alleen `View Channels` + `Send Messages` op het meldingskanaal is genoeg, want de buttons lopen via de Interactions endpoint, niet via bot-acties).
|
|
Uitbreidingsmogelijkheden die je zelf makkelijk kan toevoegen:
|
|
Een modal (`InteractionResponseType.MODAL`) bij "Afwijzen" om een eigen reden te typen in plaats van de generieke tekst.
|
|
Een slash command `/report <discordId> <categorie> <omschrijving>` als alternatief voor de HTTP API.
|
|
Per-server `DISCORD_ADMIN_ROLE_ID` als je dit ooit voor meerdere servers tegelijk wil draaien (nu is het één globale rol).
|
|
Waarom de moderatiequeue er is
|
|
Een open systeem waarin iedereen direct publiek zichtbare beschuldigingen over een account kan plaatsen, is een uitnodiging tot misbruik (valse reports, laster, doxxing). Door reports pas na goedkeuring zichtbaar te maken, houd je de nuttige functie (een gedeelde blocklist) zonder dat blackbox-beschuldigingen direct schade aanrichten. Overweeg daarnaast:
|
|
Alleen vertrouwde SUBMITTER-keys uitdelen (bv. aan bekende moderatiebots van servers).
|
|
`evidenceUrl` verplicht te maken voor bepaalde categorieën.
|
|
Een audit-log export (`AuditLog`-tabel is al aanwezig) periodiek te reviewen.
|