fix(demo): lock removing a Steam link on the demo (DM27)
The step-5 walk found demo-player could remove its stand-in Steam link from its Rust page, and staff could remove it from Admin -> Users. That link is what the player tour's Rust pages, rewards and grants hang on. - module.json demoLocks gains DELETE /player/rust/links/:steamId. - The staff route, DELETE /admin/users/:id/rust/links/:steamId, serves under core's users mount, which a module's demoLocks may not name, so its handler refuses with DEMO_LOCKED behind ctx.demoMode before the link is touched. Off the demo both behave as before. Checked on a real core with the demo seed: both answer 403 DEMO_LOCKED and the link stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
// ── The public demo's module-side locks (DEMO_MODE.md §3.4, §3.5) ──────────
|
||||
//
|
||||
// Core locks this module's two link routes by `demoLocks` in module.json. What a
|
||||
// route list cannot express lives here, behind `ctx.demoMode` (MODULE_API
|
||||
// 1.18.0), and every handler that enforces one of these asks this file:
|
||||
// Core locks this module's two rig-link routes and the player's Steam unlink by
|
||||
// `demoLocks` in module.json. What a route list cannot express lives here, behind
|
||||
// `ctx.demoMode` (MODULE_API 1.18.0), and every handler that enforces one of these
|
||||
// asks this file:
|
||||
//
|
||||
// the staff Steam unlink on Admin → Users (step-5 walk, W4): it serves under
|
||||
// core's users mount, which a module's demoLocks may not name, so its handler
|
||||
// refuses instead. The demo player's seeded link stays put either way;
|
||||
// the console-command deny list (§3.4, DM11): the commands that would break
|
||||
// the rig for every visitor until the next wipe. Asked at save, through
|
||||
// core's `demoRefuses` hook (1.19.0, DM18), and again at run;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
const crypto = require('node:crypto')
|
||||
|
||||
const core = require('../../core')
|
||||
const demo = require('../../demo')
|
||||
|
||||
const backpacks = require('../../model/backpacks/backpacks.model')
|
||||
const economics = require('../../model/economics/economics.model')
|
||||
@@ -54,6 +55,10 @@ async function removeLink(req, res) {
|
||||
const { steamId } = req.params
|
||||
const userId = req.params.id
|
||||
|
||||
// On the demo the player's own unlink is locked by demoLocks; this route serves
|
||||
// under core's users mount, which a module may not lock by route, so it asks here.
|
||||
if (demo.isDemo()) return demo.refuse(res)
|
||||
|
||||
try {
|
||||
const removed = await links.unlinkOwned(steamId, userId)
|
||||
|
||||
|
||||
@@ -447,11 +447,40 @@ test('the seed sets the faction table, saves each profile, and styles each group
|
||||
|
||||
// ── The manifest (§3.2) ────────────────────────────────────────────────────
|
||||
|
||||
test('module.json locks the two link routes and needs a core that asks demoRefuses', () => {
|
||||
test('module.json locks the two rig-link routes and the player Steam unlink, and needs a core that asks demoRefuses', () => {
|
||||
const manifest = require('../../module.json')
|
||||
assert.deepEqual(manifest.demoLocks, [
|
||||
{ method: 'PUT', path: '/admin/rust/servers/:id' },
|
||||
{ method: 'DELETE', path: '/admin/rust/servers/:id' },
|
||||
{ method: 'DELETE', path: '/player/rust/links/:steamId' },
|
||||
])
|
||||
assert.equal(manifest.coreApi, '^1.19.0')
|
||||
})
|
||||
|
||||
// ── The staff Steam unlink (W4) ────────────────────────────────────────────
|
||||
|
||||
test('staff cannot sever a Steam link on the demo, and the link is never touched', async () => {
|
||||
for (const demoMode of [true, false]) {
|
||||
withCore({ demo: demoMode })
|
||||
const links = require('../model/links/links.model')
|
||||
const asked = []
|
||||
links.unlinkOwned = async (steamId, userId) => {
|
||||
asked.push([steamId, userId])
|
||||
return true
|
||||
}
|
||||
const res = fakeRes()
|
||||
await require('../router/admin/usersRust.controller').removeLink(
|
||||
{ params: { id: '3', steamId: '76561190000000001' }, user: { id: 1 } },
|
||||
res,
|
||||
)
|
||||
if (demoMode) {
|
||||
assert.equal(res.statusCode, 403)
|
||||
assert.equal(res.body.code, 'DEMO_LOCKED')
|
||||
assert.deepEqual(asked, [])
|
||||
} else {
|
||||
assert.equal(res.statusCode, 200)
|
||||
assert.deepEqual(res.body, { unlinked: true })
|
||||
assert.deepEqual(asked, [['76561190000000001', '3']])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user