Add accounts, presets, live sheet panel and equipment tiles

- Login with registration code, sessions, rate limiting, per-user characters
- Share characters with other users (read-only), admin CLI
- Rules presets with a Presets tab, applied/pending changes with diff in a side sheet
- Equipment as tiles with amounts, starting kit removed
- Rename nav tab to "Character", add "New character" button
- Stop tracking _to_delete/

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJhXuLD2Z6hv3Wqeq9UL9K
This commit is contained in:
Claude
2026-10-20 20:37:09 +00:00
parent afbdc4b139
commit 5f3b2b2874
27 changed files with 857 additions and 244 deletions
+36 -11
View File
@@ -12,7 +12,29 @@ Website for creating characters for the Arcane Wasteland TTRPG, with a searchabl
docker compose up -d --build
```
Then open `http://<server>:8080`. Characters are stored in `./db/aw.db`. For HTTPS and a domain, put the container behind a reverse proxy (nginx, Caddy, Traefik).
Then open `http://<server>:8080`. Users, characters and presets are stored in `./db/aw.db`.
### Login and accounts
Everything (the whole API, rules, characters) is behind a login. The only public things are the login page itself and the app's JavaScript.
1. Copy `.env.example` to `.env` and set `AW_REGISTRATION_CODE`. People need this code **once** to create an account; with an empty code registration is disabled.
2. Open the site, choose "Create account", enter a username, a password (min. 8 characters) and the registration code.
3. Sessions last 30 days (HttpOnly cookie, stored server-side). Logging out or changing the password ends them.
Wrong logins and wrong registration codes are throttled (10 failures per address, 8 per username, 5 wrong codes per address and 30 per hour for the whole server), so a short code is not trivially guessable, but a long one is still better. Passwords are stored as scrypt hashes.
**HTTPS is a must when the site is reachable from the internet**, otherwise passwords travel in plain text. Put the container behind a reverse proxy (Caddy, nginx, Traefik) that terminates TLS, pass the `Host` header through, and set `AW_TRUST_PROXY=1` in `.env` so the app sees the real client address and marks the cookie `Secure`.
Admin tasks (list users, reset a password, delete a user):
```bash
docker compose exec awcc python -m app.admin list
docker compose exec awcc python -m app.admin passwd <username>
docker compose exec awcc python -m app.admin delete <username>
```
Characters and presets made before accounts existed are adopted automatically by the account that logs in from the same browser (the old secret keys are used once and then removed).
## Edit the rules
@@ -36,7 +58,7 @@ In the creator, the Concept page only has a "Rules preset" selector. Presets are
### Equipment
`equipment` lists every item with `id`, `name`, `cat` (category), `stat` (damage / armor / type), `kg` and `note`. The starting-kit rules are in `creation.kit` (allowed weapon categories, armor tiers, number of resources). Weights are approximate; for ranges in the source document the upper value is used.
`equipment` lists every item with `id`, `name`, `cat` (category), `stat` (damage / armor / type), `kg` and `note`. There are no starting-kit rules: players pick any items (with an amount) on the Equipment page and the total weight is checked against the carry capacity. Weights are approximate; for ranges in the source document the upper value is used.
## Development
@@ -51,9 +73,7 @@ cd frontend && npm install && npm run dev
## Saving and sharing
There are no user accounts. When saved, a character gets an ID and a secret write key that stays in the browser ("My characters" page). The link `/#creator/<ID>` lets others view the character; only the holder of the key can change it. To move to another browser use the JSON backup (Summary page: "JSON backup" and "Import JSON").
If the site is reachable from the internet, protect it with Basic Auth at the reverse proxy.
Characters are saved in your account ("My characters" page). Only the owner can see a character, change it or delete it. On "My characters" the **Share** button lets you add usernames (e.g. your DM): they get read-only access, see the character under "Shared with me" and can open it through `/#creator/<ID>`. Saving a viewed character creates their own copy. Use the JSON backup (Summary page) to move a character between servers.
While creating, the full character sheet stays visible next to the wizard. Edits are shown as a difference (old → new, added / removed items) until you press **Apply** (or **Apply & next**); **Discard** drops them.
@@ -61,12 +81,17 @@ Each wizard page has a **Reset this page** button that clears only that page's d
## API
All `/api/*` routes except `/api/auth/me`, `/api/auth/register` and `/api/auth/login` need the session cookie.
| Method | Path | Purpose |
|---|---|---|
| GET | `/api/rules` | Rule data |
| POST | `/api/characters` | Create a character, returns `id` and `token` |
| GET | `/api/characters/{id}` | Read a character |
| PUT / DELETE | `/api/characters/{id}` | Change / delete, header `X-Edit-Token` |
| POST | `/api/presets` | Create a preset, returns `id` and `token` |
| PUT / DELETE | `/api/presets/{id}` | Change / delete, header `X-Edit-Token` |
| GET | `/api/auth/me` | Current user (or `null`) |
| POST | `/api/auth/register` / `login` / `logout` / `password` | Accounts |
| GET | `/api/rules` | Rule data including presets |
| GET / POST | `/api/characters` | Own and shared-with-me characters / create one |
| GET | `/api/characters/{id}` | Read (owner or shared users) |
| POST / DELETE | `/api/characters/{id}/shares[/{username}]` | Share / unshare (owner only) |
| PUT / DELETE | `/api/characters/{id}` | Change / delete (owner only) |
| POST | `/api/presets` | Create a preset |
| PUT / DELETE | `/api/presets/{id}` | Change / delete (owner only) |
| POST | `/api/export/pdf` or `/docx` | Character JSON in the body, file in the response |