diff --git a/projects/ProvinceSystem/DEPLOY.md b/projects/ProvinceSystem/DEPLOY.md index 45e7000..b4fb97e 100644 --- a/projects/ProvinceSystem/DEPLOY.md +++ b/projects/ProvinceSystem/DEPLOY.md @@ -51,7 +51,7 @@ the `ps-preview-router` Caddy container (`127.0.0.1:8090`, behind the `*.tfminec creation and privileged restore use trusted Dev tooling; branch code takes no part. The schema follows Dev's migrations, so once Dev has a new migration, a preview of a branch cut before it fails its migration check until the branch is rebased onto `main`. -- **Scrub:** before startup, the helper clears sessions, user sessions, Discord OAuth/link state, preview sign-in +- **Scrub:** before startup, the helper clears code sessions, user sessions, Discord OAuth/link state, preview sign-in tickets, Microsoft link state, and Patreon tokens, OAuth and pending-link state, including creator credentials. It revokes redemption and war declaration codes and clears redemption-code plaintext, retaining rows needed by foreign-key-linked content. diff --git a/projects/ProvinceSystem/docs/architecture.md b/projects/ProvinceSystem/docs/architecture.md index b4aed95..34ffb70 100644 --- a/projects/ProvinceSystem/docs/architecture.md +++ b/projects/ProvinceSystem/docs/architecture.md @@ -158,10 +158,13 @@ Configuration, migrations, backups and restores: [PostgreSQL storage](ops/postgr | Table family | Purpose | |--------------|---------| -| `codes`, `submissions` | Skins workflow | +| `login_codes`, `code_sessions` | In-game codes and the sessions they open | +| `skin_submissions` | Skins workflow | | `drink_submissions`, `drink_textures`, `drink_catalog` | Drinks workflow | | `discord_links`, `discord_link_codes` | Identity | -| Character sessions, roster, wardrobe, wills and catalog | Characters API | +| `player_notifications` | Bot outbox for Discord DMs to players: staff warnings and bird mail | +| `war_declaration_codes` | War declaration codes | +| Character sessions, roster, creation requests (`character_creation_requests`, `character_creation_wardrobe`), wardrobe, wills and catalog | Characters API | | `web_entitlements` | Per-realm rank entitlements from TFMCWeb: character limit, name colours, wardrobe slots, skin kinds, drink perks, permission flags | | `character_account_meta` | Per-account data from RPCharacters' roster push: 18+ answer, account creation time, kit cooldowns | | `users`, `user_sessions`, OAuth states | Website accounts and sign-in | diff --git a/projects/ProvinceSystem/docs/cosmetics/drinks.md b/projects/ProvinceSystem/docs/cosmetics/drinks.md index 0a79207..34268bd 100644 --- a/projects/ProvinceSystem/docs/cosmetics/drinks.md +++ b/projects/ProvinceSystem/docs/cosmetics/drinks.md @@ -64,7 +64,7 @@ sequenceDiagram ## Data (ProvinceSystem) - `drink_submissions` - recipe JSON, status, player UUID, optional texture -- `drink_textures` - owner UUID, CMD, IA id, refcount, png path +- `drink_textures` - owner UUID, `custom_model_data` (DrinkBuilder's route and payload call it `cmd`), IA id, refcount, png path - `drink_catalog` - ingredients allowlist + category labels + effects blacklist - `drink_notifications` - staff/bot outbox diff --git a/projects/ProvinceSystem/docs/cosmetics/skins.md b/projects/ProvinceSystem/docs/cosmetics/skins.md index 252584a..16d8720 100644 --- a/projects/ProvinceSystem/docs/cosmetics/skins.md +++ b/projects/ProvinceSystem/docs/cosmetics/skins.md @@ -10,7 +10,7 @@ End-to-end design for donator texture submissions on **ProvinceSystem** (store + - Players start a skin from the Profile wardrobe ([below](#profile-wardrobe)) or with a TFMCWeb code (`/token create skin` or **`/token create skin staff`**); either is bound to the player UUID. - **Player:** staff approve/deny in Discord; ArmourShop writes **`tfmc_submissions`** + `ps_*` + LP. - **Staff curated:** auto-approve (no bot); category + scroll on upload; writes **`tfmc_armorshop`** into real ArmourShop categories. -- **Kit item customise** (character creator) also creates `submissions` rows via an internal `lore_upload` code per player — not a donator mint token. Staff review and ArmourShop apply use the same pipeline as Profile skin uploads. +- **Kit item customise** (character creator) also creates `skin_submissions` rows via an internal `lore_upload` code per player — not a donator mint token. Staff review and ArmourShop apply use the same pipeline as Profile skin uploads. ## Upload kinds @@ -109,8 +109,9 @@ Player DMs: submitted (outbox poll); approved / denied from cog after staff API Site records share `DATABASE_URL`; see [database configuration and migrations](../ops/postgresql.md). -- `codes` - hashed codes, player UUID, expiry, redeemed_at on submit -- `submissions` - kind, display_name, status, paths, discord_user_id, tiers, base_set, grip_preset, name colours/styles +- `login_codes` - hashed codes, player UUID, scope, expiry, redeemed_at on submit, `minted_via` +- `code_sessions` - the sessions redeemed codes open; the hourly housekeeping sweep deletes expired ones +- `skin_submissions` - kind, display_name, status, paths, discord_user_id, tiers, base_set, grip_preset, name colours/styles - `discord_links` / `discord_link_codes` - identity bind ### Disk @@ -212,7 +213,7 @@ the `/token create` rules: A refusal is a 409 whose `detail` is `{ "reason", "next_at" }`. An unused, unexpired code of the same scope and realm is reused, whether Profile or `/token create` made it. Otherwise the start records a new code with no plaintext -and `codes.minted_via = 'site'`, which starts the shared cooldown. A skin or drink +and `login_codes.minted_via = 'site'`, which starts the shared cooldown. A skin or drink code that expires without a submission stops counting once no session from it can still upload, whether Profile or `/token create` made it, so a code that lapses unused costs nothing. A used code keeps counting after it expires. Source: [`codes.py`](https://github.com/TF-Minecraft/ProvinceSystem/blob/main/backend/src/skins/codes.py). diff --git a/projects/ProvinceSystem/docs/identity/auth-security.md b/projects/ProvinceSystem/docs/identity/auth-security.md index b2703c0..31d996c 100644 --- a/projects/ProvinceSystem/docs/identity/auth-security.md +++ b/projects/ProvinceSystem/docs/identity/auth-security.md @@ -178,7 +178,7 @@ answers every `POST`, `PUT`, `PATCH` and `DELETE` sent with the view's session cookie with **403** `viewing_as_player`. Only leaving the view, signing out and opening or closing Profile get through, and Profile's Linked accounts card shows the player's accounts with its actions disabled. Profile opened during a view records its code -with `minted_via = staff_view:`, ends with the view, and the guard +with `minted_via = 'staff_view'` and the view's user session in `view_session_id`, ends with the view, and the guard refuses its Bearer writes the same way. The view has no staff rights even if the player's role changes, and dev will not hand it to a branch preview. Signing out during a view also signs the admin out, and signing in with Discord @@ -201,10 +201,11 @@ their views and their Profile sessions; the role change or revocation is the aud | Profile / map staff | `profile` scope session from `/profile` redeem or a linked Discord account ([Profile without a code](#profile-without-a-code)); carries `player_uuid` and `realm_id` for permission checks | | No website passwords | Codes are UUID-bound and not shareable by design | -Codes are **hashed at rest** (SHA-256). Plaintext shown once in-game at mint. The `codes` row keeps the +Codes are **hashed at rest** (SHA-256). Plaintext shown once in-game at mint. The `login_codes` row keeps the plaintext only while the code is open, for the plugin list of active codes (`GET /skins/plugin/codes/active`). Redeeming a profile code, using a skin or drink code for a submission, and revoking a code clear it in the same -update. The backend's hourly housekeeping loop clears it once a code expires unused. +update. The backend's hourly housekeeping loop clears it once a code expires unused, and deletes expired +`code_sessions` rows. ### Scope enforcement diff --git a/projects/ProvinceSystem/docs/identity/tfmcweb.md b/projects/ProvinceSystem/docs/identity/tfmcweb.md index 28583f8..670281e 100644 --- a/projects/ProvinceSystem/docs/identity/tfmcweb.md +++ b/projects/ProvinceSystem/docs/identity/tfmcweb.md @@ -86,7 +86,7 @@ Link tables live in the site PostgreSQL database (`discord_links`, `discord_link ## War declare codes -One-time codes that gate an in-game war declaration. Staff mint one in Discord (`tfmc_bot` `factions` cog, `/warcode`), the attacking leader types it in SimpleFactions, and it pins the war goal. Rows live in `war_declare_codes`, realm-scoped, hashed with **no plaintext column**: staff see the code once and a lost code is revoked and reminted. +One-time codes that gate an in-game war declaration. Staff mint one in Discord (`tfmc_bot` `factions` cog, `/warcode`), the attacking leader types it in SimpleFactions, and it pins the war goal. Rows live in `war_declaration_codes`, realm-scoped, hashed with **no plaintext column**: staff see the code once and a lost code is revoked and reminted. | Route | Auth | Role | |-------|------|------| diff --git a/projects/ProvinceSystem/docs/ops/postgresql.md b/projects/ProvinceSystem/docs/ops/postgresql.md index 5669b50..96de2c1 100644 --- a/projects/ProvinceSystem/docs/ops/postgresql.md +++ b/projects/ProvinceSystem/docs/ops/postgresql.md @@ -34,7 +34,7 @@ settings bound queries and locks. Domain advisory locks coordinate checks that s absence of a row; file guards coordinate wardrobe and map assets across workers. An hourly housekeeping loop in the backend, which also runs at startup, clears data that has outlived its use. -It currently clears the plaintext of login codes that expired unused +It clears the plaintext of login codes that expired unused and deletes expired code sessions ([opaque Bearer sessions](../identity/auth-security.md#opaque-bearer-sessions)). ## Schema migrations @@ -47,6 +47,10 @@ revision that lacks a migration the database already has, because its code expec ([deploy steps](#deploy-steps)). Add a new numbered migration for a schema change; do not edit an applied file. To undo a change, add another migration. +CHECK constraints limit login code scopes and `minted_via`, skin and drink submission statuses, character +creation request statuses and lore item states to the values the code writes or still reads, so an edit in +Database Studio must use one of those values. + Precedent and patch-note tables have their own migrations and keep their data. ## Deploy steps diff --git a/projects/RPCharacters/docs/realm-wipe.md b/projects/RPCharacters/docs/realm-wipe.md index 93f76c7..debf716 100644 --- a/projects/RPCharacters/docs/realm-wipe.md +++ b/projects/RPCharacters/docs/realm-wipe.md @@ -40,9 +40,9 @@ Usage / errors: `Usage: /rpcharacter wipe website [confirm]`. `Nothing to confir Delete: - `character_roster` -- `character_creates` +- `character_creation_requests` - `character_wardrobe_slots` -- `character_create_wardrobe` +- `character_creation_wardrobe` - `lore_item_customisations` Do not delete player rank/age meta.