FishMMO CMS
Status: scaffold. The routes below exist and are reachable, but every handler body is a
TODOstub that returns a canned success response. There is no database wiring, no authentication, and no persistence yet. Do not deploy this, and do not treat its endpoints as a working API.
An ASP.NET Core web API for account management — self-service registration and password/2FA management for players, plus administrative account actions (ban, access level, token revocation, 2FA reset) for operators. It is the out-of-game counterpart to the in-game authentication handled by the LoginServer.
Table of Contents
- Overview
- Supported Platforms
- Project Structure
- Endpoints
- Configuration
- Build and Run
- Implementation Status
- Flow Diagram
- License
Overview
The CMS exists so that account operations that do not belong in the game client — creating an account before first launch, recovering from a lost authenticator, an operator banning a cheater — have a home outside the FishNet connection lifecycle.
It is wired to share the same primitives as the rest of the stack rather than
reimplement them: SRP salt/verifier generation and TOTP helpers are to come from
FishMMO-Auth and persistence from FishMMO-DB — both are referenced and
imported but not yet called — while username, password, and email validation are
already delegated to FishMMO.Shared.Authentication
so the rules cannot drift from the ones the LoginServer enforces
(FishMMO-SharedUtility/FishMMO-SharedUtility/Authentication.cs).
The launcher's news panel does not come from here. It is fetched from
Constants.Configuration.LauncherHtmlUrl, which is baked at build time fromGeneratedHostConfig.LauncherHtmlUrl(CI substitutes it fromFISHMMO_ROOT_DOMAIN). Nothing in this project serves it.
Supported Platforms
| Target | Status |
|---|---|
| .NET 8.0 — Linux | Yes (recommended) |
| .NET 8.0 — Windows | Yes |
| .NET 8.0 — macOS | Yes |
| Requirement | Version |
|---|---|
| .NET SDK | 8.0+ |
| PostgreSQL | Required once persistence is wired up |
Project Structure
FishMMO-CMS/
├── FishMMO-CMS.slnx
└── FishMMO-CMS.Server/
├── FishMMO-CMS.Server.csproj # net8.0 web SDK; RootNamespace FishMMO.CMS.Server;
│ # copies appsettings from FishMMO-Setup
├── Program.cs # Host builder, config layering, Swagger, controller mapping
└── Controllers/
├── AccountController.cs # api/Account — player self-service
└── AdminController.cs # api/Admin — operator actions
There is no client or frontend project — FishMMO-CMS.slnx contains exactly one
project, FishMMO-CMS.Server. Callers are the browser, curl, or the Swagger UI.
Project References
| Reference | Provides |
|---|---|
FishMMO-Auth/FishMMO-ServerAuth |
The server auth cores, and transitively FishMMO-AuthShared: ClientSrpData (SRP salt/verifier) and CryptoHelper.TwoFactor (TOTP secret, recovery codes, otpauth URI). Both controllers using FishMMO.Auth.Core / FishMMO.Auth.Implementation; neither calls anything from them yet |
FishMMO-Database/FishMMO-DB |
Account, token, and secret services (not yet registered in DI) |
Swashbuckle.AspNetCore 6.5.0 is the only NuGet package reference; it supplies
the Swagger UI, which is served only in the Development environment.
Endpoints
api/Account — player self-service
| Method | Route | Purpose |
|---|---|---|
| POST | register |
Create an account; generates SRP salt and verifier from the supplied credentials |
| POST | verify |
Confirm the account with the code emailed at registration |
| POST | change-password |
Re-derive SRP salt/verifier from a new password and revoke existing tokens |
| POST | 2fa/setup |
Return the otpauth URI and recovery codes for authenticator enrolment |
Request bodies are the DTOs declared alongside each controller: RegisterRequest
(Username, Password, Email, Age), VerifyRequest (Username, Code),
and ChangePasswordRequest (CurrentPassword, NewPassword). 2fa/setup
takes no body and reads no route or query parameter — there is nothing yet to
identify the caller with.
Within this controller register is the only route that runs all three
Authentication checks, returning 400 with an error member on failure.
change-password validates NewPassword only — CurrentPassword is never
read. verify checks that both fields are non-blank. Every other outcome is the
canned 200.
api/Admin — operator actions
| Method | Route | Purpose |
|---|---|---|
| GET | accounts/search?query= |
Find accounts by username or email |
| POST | accounts/{username}/ban |
Set access level to Banned, revoke tokens, disconnect live sessions |
| POST | accounts/{username}/unban |
Restore access level to Player |
| POST | accounts/{username}/access-level |
Set an arbitrary AccessLevel |
| POST | accounts/{username}/revoke-tokens |
Force re-authentication everywhere |
| POST | accounts/{username}/reset-2fa |
Clear the TOTP secret and recovery codes |
| POST | accounts/{username}/force-password-reset |
Admin-set password, revoking tokens |
accounts/search returns an empty array; the {username} routes echo the name
back in a message string without touching a database. force-password-reset
validates NewPassword via Authentication.IsAllowedPassword; access-level
accepts a SetAccessLevelRequest.AccessLevel byte and does not yet check it
against the AccessLevel enum.
Configuration
Program.cs layers configuration in this order, so a deployed instance can be
retuned without rebuilding:
- Bundled defaults —
ContentRootPathisAppContext.BaseDirectory, and the build copiesFishMMO-Setup/Development/appsettings.CMS.jsonto the output directory asappsettings.json(and the Production variant asappsettings.Production.json, when it exists). - Working-directory overrides —
./appsettings.jsonand./appsettings.{Environment}.json, both optional, bothreloadOnChange.
Edit the templates under FishMMO-Setup/, not the copies in bin/ — the build
overwrites those.
The Development template sets AllowedHosts to localhost and ships an empty
ConnectionStrings block; the PostgreSQL connection string is expected from the
ConnectionStrings__DefaultConnection environment variable in both environments,
never from the committed file. Nothing in Program.cs reads either key yet — see
Implementation Status.
Build and Run
cd FishMMO-CMS
dotnet build FishMMO-CMS.slnx -c Release
# Development (Swagger UI at /swagger)
dotnet run --project FishMMO-CMS.Server
app.UseHttpsRedirection() is active, so plain-HTTP callers are redirected.
Behind NGINX, terminate TLS at the proxy as the other FishMMO web services do.
Implementation Status
Everything below must be built before this service is usable. The TODO
comments in the source are the authoritative list; this is the summary.
| Area | State |
|---|---|
| Route surface and request DTOs | Done |
| Input validation (username, password, email) | Done — via FishMMO.Shared.Authentication |
| Swagger / OpenAPI | Done (Development only) |
| Configuration layering | Done |
| Database service registration | Not started — Program.cs TODO |
| Auth service registration | Not started — Program.cs TODO |
| SRP salt/verifier generation and persistence | Not started |
| Email verification (send + confirm) | Not started |
| TOTP secret generation, encryption, recovery-code hashing | Not started |
Caller authentication on api/Account |
Not started — change-password and 2fa/setup are unauthenticated |
Admin authorization on api/Admin |
Not started — every admin route is open |
| Token revocation and live-session kick | Not started |
Program.cs calls app.UseAuthorization() but registers neither
AddAuthentication nor AddAuthorization, and no controller carries an
[Authorize] attribute — so the middleware has no policy to enforce and every
request is permitted.
Until the two authorization rows are addressed, this service must not be exposed to a network. Any caller can invoke every administrative route.
Flow Diagram
flowchart TD
Player[Player browser] -->|POST api/Account/register| CMS
Operator[Operator] -->|POST api/Admin/accounts/name/ban| CMS
subgraph CMS["FishMMO-CMS.Server"]
Val[FishMMO.Shared.Authentication<br/>username / password / email rules]
Acct[AccountController]
Adm[AdminController]
Acct --> Val
Adm --> Val
end
CMS -.->|planned| Auth["FishMMO-Auth<br/>SRP salt+verifier, TOTP"]
CMS -.->|planned| DB[("PostgreSQL<br/>via FishMMO-DB")]
CMS -.->|planned| Mail[Verification email]
DB -.->|accounts, tokens| Login["LoginServer<br/>(in-game auth)"]
Solid edges are implemented. Dashed edges are the wiring the TODOs describe.
License
This project is part of the FishMMO project and is distributed under the FishMMO project license.