refactor(client): delete the UO client half (phase 3, slice 3)
35 files and 5,332 lines out — twelve public pages, seven admin views, two player views, eight components, the two `data/` leaves and the three `lib/` ones, plus the two tests that came with them. §2.7.1's estimate of 51 files / ~3,700 lines was measured differently and is corrected in the docs PR. The seams core keeps, each smaller than what it replaced: Nine rows leave the public header and six leave the admin sidebar, and both lists are now free of `feature` gates and of `IconShard`. `moduleTitle` already handled a module page's heading, so the six TITLES entries and the `/admin/characters` branch of `sectionTitle` simply go. `/player` had `PlayerCharacters` as its index — a UO page — and rather than name a replacement or invent a landing screen it now resolves to the first row of the portal nav this viewer can reach (`firstDestinationFor`, beside `allowedPathsFor` and reading the BASE nav for the same reason: an override is presentation and where everybody lands is behaviour). With the module installed that is still Characters, so a player's first screen after signing in does not change. Deliberately generic and deliberately not in the portal layout — the admin index is the same question with a hardcoded answer, and if the two logged-in areas ever become one this is what serves both. `game_account_signup` goes with the rest of core's UO prose: the mode list, the derived public flag, the validation and a Site Settings field whose help text named Bridge.cfg. The row itself is untouched and module-uo reads it through ctx.settings — the data stays, the semantics move. KNOWN BREAK, accepted by the org lead: the shipped Android app reads `gameAccountSignup` off `/public/settings` (PublicDto.kt:80). The field has a `= false` default so nothing crashes; the app silently stops offering game-account creation until it reads the module's `/public/shard/features` instead. Out of scope here, recorded in the Android plan, and it lands well before this workstream's cutover reaches `main`. 620 server + 161 client tests. Manifest 158 public + 2 internal, unchanged; routes.guards unchanged. The OpenAPI spec loses exactly one property, and only because it was hand-written in swagger.js — regeneration alone would have left the spec documenting a field core no longer returns. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -55,27 +55,6 @@ function registrationFlags(mode) {
|
||||
}
|
||||
}
|
||||
|
||||
// Game-account signup (Protocol 2.0). The admin picks who mints game accounts:
|
||||
// disabled — the site never offers game-account creation (link-only).
|
||||
// website — the site is the authority (offer creation; pair with the shard in
|
||||
// website mode + AutoCreateAccounts=false).
|
||||
// hybrid — either side may create (the site offers creation).
|
||||
// game — the game server is the authority; the site does NOT offer creation.
|
||||
// The site OFFERS creation only for 'website'/'hybrid'; the shard's own SignupMode
|
||||
// (Bridge.cfg) still has the final say and may 403 a call regardless.
|
||||
const GAME_SIGNUP_KEY = 'game_account_signup'
|
||||
const GAME_SIGNUP_MODES = ['disabled', 'website', 'hybrid', 'game']
|
||||
const GAME_SIGNUP_OFFER = ['website', 'hybrid']
|
||||
|
||||
async function getGameSignupMode() {
|
||||
const v = await settingsDb.get(GAME_SIGNUP_KEY)
|
||||
return GAME_SIGNUP_MODES.includes(v) ? v : 'disabled'
|
||||
}
|
||||
|
||||
async function isGameAccountSignupEnabled() {
|
||||
return GAME_SIGNUP_OFFER.includes(await getGameSignupMode())
|
||||
}
|
||||
|
||||
// Android App Links opt-in (M9 follow-up). When on, the shard auto-serves
|
||||
// /.well-known/assetlinks.json and the mobile SSO bridge additionally accepts the
|
||||
// self-origin https://<host>/mobile/callback redirect. Stored as the string
|
||||
@@ -146,10 +125,12 @@ async function getPublic() {
|
||||
// page show/hide the password form and SSO buttons.
|
||||
const mode = REGISTRATION_MODES.includes(all[REGISTRATION_KEY]) ? all[REGISTRATION_KEY] : 'disabled'
|
||||
out.registration = registrationFlags(mode)
|
||||
// Whether the site offers game-account creation (the shard's own mode still has
|
||||
// the final say when the call is made). Lets the portal show/hide the form.
|
||||
const gsMode = GAME_SIGNUP_MODES.includes(all[GAME_SIGNUP_KEY]) ? all[GAME_SIGNUP_KEY] : 'disabled'
|
||||
out.gameAccountSignup = GAME_SIGNUP_OFFER.includes(gsMode)
|
||||
// `gameAccountSignup` was derived here until Phase 3 slice 3. It said whether
|
||||
// the site offers GAME-account creation, which is a question about a shard —
|
||||
// its own SignupMode has to agree — so it left with the rest of core's UO
|
||||
// prose. The `game_account_signup` row is unchanged and module-uo reads it
|
||||
// through ctx.settings; the derived flag is on its `/public/shard/features`.
|
||||
//
|
||||
// The effective CSS custom properties for the admin's theme, or absent when
|
||||
// no theme_visual row exists (or nothing in it was usable). The SPA writes
|
||||
// these onto <html>; absence means it writes nothing and theme.css's :root
|
||||
@@ -264,10 +245,6 @@ module.exports = {
|
||||
REGISTRATION_MODES,
|
||||
getRegistrationMode,
|
||||
registrationFlags,
|
||||
GAME_SIGNUP_KEY,
|
||||
GAME_SIGNUP_MODES,
|
||||
getGameSignupMode,
|
||||
isGameAccountSignupEnabled,
|
||||
MOBILE_APP_LINKS_KEY,
|
||||
isMobileAppLinksEnabled,
|
||||
}
|
||||
|
||||
@@ -520,12 +520,12 @@ async function updateSettings(req, res) {
|
||||
) {
|
||||
return res.status(400).json({ message: 'Invalid player_registration value' })
|
||||
}
|
||||
if (
|
||||
settings.GAME_SIGNUP_KEY in updates &&
|
||||
!settings.GAME_SIGNUP_MODES.includes(updates[settings.GAME_SIGNUP_KEY])
|
||||
) {
|
||||
return res.status(400).json({ message: 'Invalid game_account_signup value' })
|
||||
}
|
||||
// `game_account_signup` was validated here until Phase 3 slice 3. The key and
|
||||
// its stored value are unchanged, but the four legal modes are a fact about a
|
||||
// ServUO shard, so module-uo owns them and validates on its own route. This
|
||||
// endpoint takes arbitrary keys either way, and an unrecognised value resolves
|
||||
// to `disabled` on read — the module's gate fails closed, which is the right
|
||||
// direction for "may this player mint a game account".
|
||||
// App Links toggle is a boolean stored as a 'true'/'false' string; accept a real
|
||||
// boolean or those two strings and normalize, reject anything else.
|
||||
if (settings.MOBILE_APP_LINKS_KEY in updates) {
|
||||
|
||||
Reference in New Issue
Block a user