readme update
This commit is contained in:
128
README.md
128
README.md
@@ -1 +1,127 @@
|
|||||||
# ECS FULL STACK
|
# ECS Full Stack
|
||||||
|
|
||||||
|
A full-stack example project that integrates a React frontend, an Express backend, and a Discord bot. The app provides a dashboard for server admins to manage bot settings and invites, plus Discord moderation/integration features via a bot running with discord.js.
|
||||||
|
|
||||||
|
This README documents how to get the project running, what environment variables are required, where to get Discord keys, how the invite token flow works, and basic troubleshooting tips.
|
||||||
|
|
||||||
|
## Repository layout
|
||||||
|
|
||||||
|
- `frontend/` — React (Create React App) frontend. Uses `REACT_APP_API_BASE` to communicate with the backend in dev and production.
|
||||||
|
- `backend/` — Express backend and API server that also coordinates with the `discord-bot` library to manage guilds, invites, and settings. Uses environment variables for configuration.
|
||||||
|
- `discord-bot/` — small wrapper that logs the bot in and exposes the discord.js client used by the backend.
|
||||||
|
- `checklist.md`, `README.md`, other docs and small scripts at repo root.
|
||||||
|
|
||||||
|
## What this project does
|
||||||
|
|
||||||
|
- Provides a React dashboard where a user can view servers the bot is connected to and manage per-server settings (welcome/leave messages, autorole, toggling commands, invite creation/listing/deletion).
|
||||||
|
- Runs a Discord bot (discord.js) that performs moderation and server features. The backend and bot are closely integrated: the backend hosts the API and the bot client is shared to fetch guild data and manipulate invites/channels/roles.
|
||||||
|
- Uses a short-lived token flow to authorize invite deletions from the frontend without embedding long-lived secrets in the client.
|
||||||
|
|
||||||
|
## Quickstart — prerequisites
|
||||||
|
|
||||||
|
- Node.js (recommended 18.x or later) and npm
|
||||||
|
- A Discord application with a Bot user (to get `DISCORD_CLIENT_ID` and `DISCORD_CLIENT_SECRET`) — see below for setup steps
|
||||||
|
- Optional: a VPS or Tailscale IP if you want to run the frontend/backend on a non-localhost address
|
||||||
|
|
||||||
|
## Environment configuration (.env)
|
||||||
|
|
||||||
|
There are env files used by the backend and frontend. Create `.env` files in the `backend/` and `frontend/` folders for local development. Examples follow.
|
||||||
|
|
||||||
|
### backend/.env (example)
|
||||||
|
|
||||||
|
PORT=3002
|
||||||
|
HOST=0.0.0.0
|
||||||
|
BACKEND_BASE=http://your-server-or-ip:3002
|
||||||
|
FRONTEND_BASE=http://your-server-or-ip:3001
|
||||||
|
CORS_ORIGIN=http://your-server-or-ip:3001
|
||||||
|
DISCORD_CLIENT_ID=your_discord_client_id
|
||||||
|
DISCORD_CLIENT_SECRET=your_discord_client_secret
|
||||||
|
ENCRYPTION_KEY=a-32-byte-or-longer-secret
|
||||||
|
INVITE_TOKEN_SECRET=optional-second-secret-for-invite-tokens
|
||||||
|
|
||||||
|
- `PORT` / `HOST`: where the backend listens.
|
||||||
|
- `BACKEND_BASE` and `FRONTEND_BASE`: used for constructing OAuth redirect URIs and links.
|
||||||
|
- `CORS_ORIGIN`: optional; set to your frontend origin to restrict CORS.
|
||||||
|
- `DISCORD_CLIENT_ID` / `DISCORD_CLIENT_SECRET`: from the Discord Developer Portal (see below).
|
||||||
|
- `ENCRYPTION_KEY` or `INVITE_TOKEN_SECRET`: used to sign short-lived invite tokens. Keep this secret.
|
||||||
|
|
||||||
|
Note: This project previously supported an `INVITE_API_KEY` static secret; that requirement has been removed. Invite deletes are authorized via short-lived invite tokens by default.
|
||||||
|
|
||||||
|
### frontend/.env (example)
|
||||||
|
|
||||||
|
HOST=0.0.0.0
|
||||||
|
PORT=3001
|
||||||
|
REACT_APP_API_BASE=http://your-server-or-ip:3002
|
||||||
|
|
||||||
|
Set `REACT_APP_API_BASE` to point at the backend so the frontend can call API endpoints.
|
||||||
|
|
||||||
|
## Create a Discord Application and Bot (short)
|
||||||
|
|
||||||
|
1. Go to the Discord Developer Portal: https://discord.com/developers/applications
|
||||||
|
2. Create a new application.
|
||||||
|
3. Under "OAuth2" -> "General", add your redirect URI:
|
||||||
|
- For dev: `http://your-server-or-ip:3002/auth/discord/callback`
|
||||||
|
- Make sure `BACKEND_BASE` matches the host/port you set in `backend/.env`.
|
||||||
|
4. Under "Bot" create a Bot user and copy the Bot token (NOT committed to source).
|
||||||
|
5. Under "OAuth2" -> "URL Generator" select scopes `bot` and `applications.commands` and select permissions (e.g., Administrator if you want full access for testing). Use the generated URL to invite the bot to your guild during testing.
|
||||||
|
|
||||||
|
Store the Client ID / Client Secret in your `backend/.env` as `DISCORD_CLIENT_ID` and `DISCORD_CLIENT_SECRET`.
|
||||||
|
|
||||||
|
## Invite token flow (why and how)
|
||||||
|
|
||||||
|
- To avoid embedding long-lived secrets in a web client, invite deletions are authorized with a short-lived HMAC-signed token.
|
||||||
|
- The frontend requests a token with:
|
||||||
|
GET /api/servers/:guildId/invite-token
|
||||||
|
- The backend returns `{ token: '...' }`. The frontend then calls
|
||||||
|
DELETE /api/servers/:guildId/invites/:code
|
||||||
|
with header `x-invite-token: <token>`
|
||||||
|
- Token TTL is short (default 5 minutes) and is signed using `INVITE_TOKEN_SECRET` or `ENCRYPTION_KEY` from backend `.env`.
|
||||||
|
|
||||||
|
Security note: Currently the `/invite-token` endpoint issues tokens to any caller. For production you should restrict this endpoint by requiring OAuth authentication and checking that the requesting user is authorized for the target guild.
|
||||||
|
|
||||||
|
## Run the app locally
|
||||||
|
|
||||||
|
1. Backend
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd backend
|
||||||
|
npm install
|
||||||
|
# create backend/.env from the example above
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Frontend
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd frontend
|
||||||
|
npm install
|
||||||
|
# create frontend/.env with REACT_APP_API_BASE pointing to the backend
|
||||||
|
npm run start
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Discord bot
|
||||||
|
|
||||||
|
- The backend boots the bot client (see `discord-bot/`), so if the backend is started and credentials are correct, the bot will log in and register slash commands. You can also run the `discord-bot` project separately if you prefer.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- Backend refuses to start or missing package.json: ensure you run `npm install` in the `backend` folder and run `npm start` from that folder.
|
||||||
|
- CORS errors: verify `CORS_ORIGIN` and `REACT_APP_API_BASE` match your frontend origin.
|
||||||
|
- Invite delete unauthorized: ensure backend `INVITE_TOKEN_SECRET` or `ENCRYPTION_KEY` is present and token TTL has not expired. Check the backend logs for validation details.
|
||||||
|
- Token issues: clock skew can cause tokens to appear expired — ensure server and client clocks are reasonably in sync.
|
||||||
|
|
||||||
|
## Developer notes
|
||||||
|
|
||||||
|
- The dashboard UI is in `frontend/src/components/` (notable files: `Dashboard.js`, `ServerSettings.js`, `Login.js`).
|
||||||
|
- The Express API is in `backend/index.js` and uses `discord-bot` (discord.js client) to operate on guilds, invites, channels and roles.
|
||||||
|
- Invite delete flow: frontend fetches a short-lived token then requests DELETE with header `x-invite-token`.
|
||||||
|
|
||||||
|
## Next steps / suggestions
|
||||||
|
|
||||||
|
- Harden `/api/servers/:guildId/invite-token` to require an authenticated user and verify the user has admin permissions for the guild.
|
||||||
|
- Add rate-limiting to token issuance and optionally keep the old `INVITE_API_KEY` option for server-to-server automation.
|
||||||
|
|
||||||
|
If you want, I can add step-by-step instructions to create the `.env` files from templates, or implement the production safe option of authenticating `/invite-token` requests. Tell me which you'd prefer.
|
||||||
|
|
||||||
|
---
|
||||||
|
Updated: Oct 4, 2025
|
||||||
Reference in New Issue
Block a user