// ── Admin · Rust · Visibility ───────────────────────────────────────────── // // Mounted under the admin tier's `/rust` prefix, so every path here is // `/api/v1/admin/rust/visibility`. Who may see what the servers say about the // people on them — a fourth subject beside the bridge, the permissions and the // mod configuration. // // **Every route is `requireRole('admin')`.** The tier's own gate admits editors // and moderators, and a moderator widening the roll call to the public is the // decision the org lead settled should be deliberate. Reading is gated the same // as writing: the screen is one form, and a view of the settings without the // power to change them is not something anybody has asked for. const core = require('../../core') const express = core.express const visibility = require('./visibility.controller') const { requireRole, validate } = core.middleware const { body } = core.validator const visibilityRouter = express.Router() const AUDIENCES = ['staff', 'signed_in', 'public'] const CLAN_AUDIENCES = ['members', 'signed_in', 'public'] visibilityRouter.get( '/', // #swagger.tags = ['Admin · Rust'] // #swagger.summary = 'Who may see who is online, and who may see a clan roster' // #swagger.description = 'The presence fleet default and every server’s optional override. It governs the Online list, every feed item that names a player who was on the server (connects, respawns, deaths, chat, tallies) and the leaderboard’s `lastSeen`. The default is `staff`: nothing names who is online until an operator widens it. The player count is public at every setting. `clans` carries the clan roster audience (default `members`: the clan’s own linked members, and staff) and each server’s clan board — whether it is current, at the game’s 100-clan ceiling, or running the uMod Clans plugin, whose clans are not Teams. `map` carries the live map’s switches: each layer’s fleet audience (`world` and `events` public, `players` and `bases` staff by default), the own-and-mates switch (on), the monument-label switches (`minorLabels` start hidden, every other label is drawn; `markerLabels` lists each server’s current map’s labels), each server’s overrides, and what each server’s map picture is — its source, the map it is of, when it was fetched, and how long a render would stall that server.' /* #swagger.responses[200] = { description: 'The fleet default and each server', content: { "application/json": { schema: { $ref: "#/components/schemas/RustVisibility" } } } } */ requireRole('admin'), visibility.read, ) visibilityRouter.put( '/', // #swagger.tags = ['Admin · Rust'] // #swagger.summary = 'Change who may see who is online, who may see a clan roster, or which servers say news in chat' // #swagger.description = 'Sets the presence fleet default, one or more server overrides, the clan roster audience, the per-server news-in-chat switches, or any of them together. A server set to `null` follows the fleet default again. `news` maps a server id to `true` or `false`: whether a published news post is also said in the in-game chat of that server (off by default). `newsDelivery` maps a server id to `chat` or `popup`: where that post goes — a popup needs PopupNotifications on the server, and one without it refuses the post with a reason. Validated whole before anything is written: a request naming a server that does not exist changes nothing. Widening the clan roster audience also shows which members are online to that audience, because a roster row carries it. `map` is `{ fleet, servers }`: `fleet` maps a layer (`world`, `events`, `players`, `bases`) to an audience and `mates` to true or false; `servers` maps a server id to the same shape, where null follows the fleet. `markers`, in either, maps a monument label key (lower case) to true or false, and null clears it (D196). The players layer never shows more than who may see who is online, whatever it is set to.' /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/RustVisibilityUpdate" } } } } */ /* #swagger.responses[200] = { description: 'Saved; answers the new state', content: { "application/json": { schema: { $ref: "#/components/schemas/RustVisibility" } } } } */ /* #swagger.responses[400] = { description: 'An audience that does not exist' } */ /* #swagger.responses[404] = { description: 'A server that does not exist' } */ requireRole('admin'), body('fleet').optional().isIn(AUDIENCES).withMessage(`fleet must be one of ${AUDIENCES.join(', ')}`), body('servers').optional().isObject().withMessage('servers maps a server id to an audience or null'), body('clanRoster').optional().isIn(CLAN_AUDIENCES).withMessage(`clanRoster must be one of ${CLAN_AUDIENCES.join(', ')}`), body('news').optional().isObject().withMessage('news maps a server id to true or false'), body('newsDelivery').optional().isObject().withMessage('newsDelivery maps a server id to chat or popup'), body('map').optional().isObject().withMessage('map carries fleet and servers, each an object of layer switches'), validate, visibility.update, ) module.exports = visibilityRouter