// ── Whether this site creates game accounts, and in which direction ──────── // // This policy was core's until slice 3 of the Phase 3 extraction, and it should // never have been: the setting's own help text names *Bridge.cfg* and says the // game server's `SignupMode` must agree with it. That is a sentence about a UO // shard, and core cannot own a sentence about a UO shard. // // **The setting key is unchanged.** `game_account_signup` keeps its name and its // row in core's `settings` table, read and written through `ctx.settings`. The // key is not prefixed because renaming it would silently reset every existing // instance's configured mode to the default — the same reasoning that // grandfathered `spawn_atlas_servuo_path`, `cliloc_client_path` and the seven // stream ids (MODULE_API.md §6.5). A module owning an unprefixed settings key is // a grandfathering, not a pattern to copy. // // **It was also broken.** Slice 1 ported the call site // (`router/player/shard.controller.js`) still calling // `settings.isGameAccountSignupEnabled()`, which `ctx.settings` does not expose — // it is three functions, not the model. So `POST /player/shard/account` threw a // TypeError and answered 500 for every caller, and no test saw it because the // module's suite never reached that branch. This file is where that function now // lives, on the side that actually uses it. const { settings } = require('../core') const KEY = 'game_account_signup' /** * The four modes, and what each means. * * `website` and `hybrid` are the two that accept a site-created account; `game` * means accounts are made in the client and only linked here. The shard's own * `SignupMode` still has the final say when the call is actually made — this is * the site half of an agreement between two systems, which is exactly why it * reads as UO policy rather than as site configuration. */ const MODES = ['disabled', 'website', 'hybrid', 'game'] const OFFERS_SIGNUP = ['website', 'hybrid'] /** The configured mode, or `disabled` for anything unset or unrecognised. */ async function getMode() { const value = await settings.get(KEY) return MODES.includes(value) ? value : 'disabled' } /** * Does this site offer game-account creation right now? * * Fails CLOSED on an unreadable setting, because `getMode` resolves an unknown * value to `disabled`. Offering a form that the shard will refuse is a dead end * a player cannot distinguish from a bug. */ async function isEnabled() { return OFFERS_SIGNUP.includes(await getMode()) } /** @throws if `mode` is not one of MODES — the caller validates first. */ async function setMode(mode, updatedBy) { if (!MODES.includes(mode)) throw new Error(`unknown game-signup mode "${mode}"`) return settings.set(KEY, mode, updatedBy) } module.exports = { KEY, MODES, OFFERS_SIGNUP, getMode, isEnabled, setMode }