mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 07:28:45 -07:00
Document admin page and refresh architecture docs
This commit is contained in:
+136
@@ -0,0 +1,136 @@
|
||||
# DorkNet Admin Page
|
||||
|
||||
The admin page is the browser operations console for DorkNet. In the
|
||||
microservices deployment it lives at `https://admin.<domain>/` and is
|
||||
served by the `web` service from the built Vite SPA assets.
|
||||
|
||||
The admin backend endpoints are under `/api/admin/v1`. Requests from the
|
||||
SPA are same-origin, so `https://admin.<domain>/api/admin/v1/*` is also
|
||||
handled by the `web` service route on the admin host. The same
|
||||
`/api/admin/*` route family is available as a path-owned moderation slice
|
||||
for non-admin-host routing, so `/internal/routes` can show moderation as
|
||||
the owner for that path family.
|
||||
|
||||
## Runtime Routing
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| SPA source | `DorkNet.Server/admin-ui` |
|
||||
| Build output | `DorkNet.Server/wwwroot/admin` |
|
||||
| Container path | `/app/wwwroot/admin` |
|
||||
| Public browser host | `admin.<domain>` |
|
||||
| API base used by the SPA | `/api/admin/v1` |
|
||||
| Login endpoint | `POST /api/admin/v1/login` |
|
||||
| Same-origin admin-host service | `web` |
|
||||
| Path-routed admin API slice | `moderation` |
|
||||
|
||||
`DorkNet.Gateway` preserves the original Host header when it proxies to
|
||||
backend services. That matters for the admin page: the `admin.<domain>`
|
||||
host route must reach `web`, and `web` must contain
|
||||
`/app/wwwroot/admin/index.html`.
|
||||
|
||||
## Authentication
|
||||
|
||||
The first account created on a fresh database is promoted to admin so
|
||||
there is always a bootstrap operator. The login form posts to
|
||||
`/api/admin/v1/login`; the SPA stores the returned values in browser
|
||||
`localStorage`:
|
||||
|
||||
| Key | Contents |
|
||||
|---|---|
|
||||
| `dorknet.admin.token` | DorkNet admin JWT |
|
||||
| `dorknet.admin.me` | Admin identity object used by the layout |
|
||||
|
||||
Every admin API request sends `Authorization: Bearer <token>`. Protected
|
||||
actions are guarded by `AdminOnlyAttribute`, which checks the resolved
|
||||
player row still has `IsAdmin = true`. A `401` clears the local session
|
||||
and sends the browser back to login.
|
||||
|
||||
If the admin host is public, put it behind Cloudflare Access or an
|
||||
equivalent outer access control. The DorkNet JWT is still required after
|
||||
that outer check.
|
||||
|
||||
## Navigation
|
||||
|
||||
| Section | Routes | Workflows |
|
||||
|---|---|---|
|
||||
| Overview | `/` | Live ops dashboard, online players, active sessions, quick kick/ban/broadcast actions |
|
||||
| Moderation | `/players` | Player directory, bans, reports, per-player ban/grant/gift/password/avatar/account actions |
|
||||
| Activity | `/activity` | Admin audit log and per-player request logs |
|
||||
| Content | `/rooms`, `/rooms/:id`, `/import-room`, `/content` | Room list/detail, room import, instances, leaderboards, community board, loading tips |
|
||||
| Operations | `/broadcast`, `/settings` | Server broadcast, server toggles, signup codes, weekly challenges, Play menu tags, Rec Center doors, game config values |
|
||||
|
||||
Several older admin URLs are kept as redirects:
|
||||
|
||||
| Old route | Current route |
|
||||
|---|---|
|
||||
| `/bans` | `/players?tab=bans` |
|
||||
| `/reports` | `/players?tab=reports` |
|
||||
| `/gift`, `/passwords`, `/grants` | `/players` |
|
||||
| `/audit` | `/activity?tab=audit` |
|
||||
| `/logs` | `/activity?tab=logs` |
|
||||
| `/rr-originals`, `/instances`, `/leaderboards` | `/rooms` |
|
||||
| `/community` | `/content?tab=community` |
|
||||
| `/loading-tips` | `/content?tab=tips` |
|
||||
| `/signup-codes` | `/settings?tab=signup` |
|
||||
|
||||
`/import-room-legacy` still exists for the legacy room importer.
|
||||
|
||||
## Build And Deploy
|
||||
|
||||
The service Dockerfile builds the admin SPA for service images that need
|
||||
static assets. In the microservices stack the `web` image must include:
|
||||
|
||||
```text
|
||||
/app/wwwroot/admin/index.html
|
||||
/app/wwwroot/admin/assets/*
|
||||
```
|
||||
|
||||
The admin SPA calls relative URLs, so it does not need a configured API
|
||||
origin as long as the browser is opened on `https://admin.<domain>/`.
|
||||
|
||||
The native admin mobile app points at the same public admin host; see
|
||||
[`../DorkNet.AdminMobile/README.md`](../DorkNet.AdminMobile/README.md).
|
||||
|
||||
## Smoke Checks
|
||||
|
||||
Check the static host:
|
||||
|
||||
```bash
|
||||
curl -I https://admin.yourdomain.com/
|
||||
```
|
||||
|
||||
Check that protected admin API routing is alive. A `401` is expected
|
||||
without a valid admin token:
|
||||
|
||||
```bash
|
||||
curl -i https://admin.yourdomain.com/api/admin/v1/stats
|
||||
```
|
||||
|
||||
Check the built assets inside the running `web` container:
|
||||
|
||||
```bash
|
||||
docker exec <web-container> sh -lc 'find /app/wwwroot/admin -maxdepth 2 -type f | sort | head -50'
|
||||
```
|
||||
|
||||
Useful logs:
|
||||
|
||||
```bash
|
||||
docker logs <stack>-gateway-1 --tail=200
|
||||
docker logs <stack>-web-1 --tail=200
|
||||
docker logs <stack>-moderation-1 --tail=200
|
||||
```
|
||||
|
||||
For normal browser admin traffic, start with `gateway` and `web`.
|
||||
Check `moderation` when you are testing `/api/admin/*` through a
|
||||
non-admin host such as `api.<domain>`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Check |
|
||||
|---|---|
|
||||
| `admin.<domain>/` returns 404 | `web` logs for `probe="/app/wwwroot/admin/index.html" exists=False`; rebuild/redeploy the `web` image |
|
||||
| Admin page loads but actions 404 | Gateway `/internal/routes`, then whether the request host is `admin.<domain>` or a path-routed host |
|
||||
| Login or actions return 401 | Token expired, local session cleared, or the player no longer has `IsAdmin = true` |
|
||||
| Browser spins forever | Open the browser network tab, then check `gateway` and `web` logs for the stuck URL |
|
||||
| Upload/import fails near 100 MB | Use the chunked importer; the SPA uses 50 MB chunks to stay below Cloudflare request limits |
|
||||
@@ -45,8 +45,8 @@ DorkNet.sln
|
||||
| `DorkNet.Services.Social` | Clubs, groups, announcements, player events, subscriptions | .NET 9 |
|
||||
| `DorkNet.Services.Commerce` | Catalog, storefronts, econ, inventory, inventions | .NET 9 |
|
||||
| `DorkNet.Services.Platform` | Service URLs, config, version checks, geo, strings, telemetry-style surfaces | .NET 9 |
|
||||
| `DorkNet.Services.Moderation` | Bug reporting, player reporting, sanitize, admin API, testcase routes | .NET 9 |
|
||||
| `DorkNet.Services.Web` | Public site, admin static host, feed static host, site API | .NET 9 |
|
||||
| `DorkNet.Services.Moderation` | Bug reporting, player reporting, sanitize, path-routed admin API, testcase routes | .NET 9 |
|
||||
| `DorkNet.Services.Web` | Public site, admin static host, same-origin admin browser API, feed static host, site API | .NET 9 |
|
||||
| `DorkNet.ClientMod` | MelonLoader 0.6.x IL2CPP mod — the client patcher, JSON config | .NET 6 |
|
||||
|
||||
`ClientMod` applies the client-side patches needed to point the 2020
|
||||
@@ -119,6 +119,10 @@ SPAs for service images that need static assets, publishes the selected
|
||||
.NET project, and runs that DLL in the runtime image. The root
|
||||
`Dockerfile` builds only the standalone/fallback `DorkNet.Server` image.
|
||||
|
||||
For the admin browser console specifically, including the host routing
|
||||
split between the admin static host and `/api/admin/v1`, see
|
||||
[`admin.md`](admin.md).
|
||||
|
||||
### Controllers/ groupings
|
||||
|
||||
20 top-level groups, each responsible for one product surface the
|
||||
|
||||
+10
-2
@@ -29,8 +29,8 @@ while route slices move out of the fallback server.
|
||||
| `social` | Clubs, groups, announcements, player events, subscriptions |
|
||||
| `commerce` | Catalog, storefronts, econ, inventory, inventions |
|
||||
| `platform` | Service directory, config, version checks, geo, strings |
|
||||
| `moderation` | Bug reports, player reports, sanitize, admin API, testcase routes |
|
||||
| `web` | Apex/www/admin/feed static hosts and site API |
|
||||
| `moderation` | Bug reports, player reports, sanitize, path-routed admin API, testcase routes |
|
||||
| `web` | Apex/www/admin/feed static hosts, same-origin admin browser API, and site API |
|
||||
| `monolith` | Fallback shared server for route families not split yet |
|
||||
| `postgres` | Bundled Postgres for the compose network |
|
||||
| `redis` | Bundled Redis for ephemeral state and fan-out |
|
||||
@@ -240,11 +240,15 @@ Expected key files:
|
||||
slice or to the monolith fallback. `/internal/services/health` reports
|
||||
gateway-visible health for each backend service.
|
||||
|
||||
For the admin page's browser routes, auth flow, same-origin API calls,
|
||||
and focused troubleshooting, see [`admin.md`](admin.md).
|
||||
|
||||
### Useful Logs
|
||||
|
||||
```bash
|
||||
docker logs <stack>-gateway-1 --tail=200
|
||||
docker logs <stack>-web-1 --tail=200
|
||||
docker logs <stack>-moderation-1 --tail=200
|
||||
docker logs <stack>-platform-1 --tail=200
|
||||
docker logs <stack>-cloudflared-1 --tail=200
|
||||
```
|
||||
@@ -260,6 +264,10 @@ That means the `web` image did not include the built SPA assets or the
|
||||
old container is still running. Force a clean Dokploy rebuild on the
|
||||
latest branch commit.
|
||||
|
||||
Admin browser traffic on `admin.<domain>` is routed to `web`. The
|
||||
`moderation` service is still useful when testing the `/api/admin/*`
|
||||
path family through non-admin hosts.
|
||||
|
||||
---
|
||||
|
||||
## Local Microservices
|
||||
|
||||
Reference in New Issue
Block a user