[rooms] fix staff delete

This commit is contained in:
Devin Zuczek
2026-09-22 00:08:21 -04:00
parent 2d7d37f382
commit 3bcef61c32
2 changed files with 42 additions and 3 deletions
+3 -3
View File
@@ -1858,8 +1858,7 @@ const app = new Hono<App>()
Error: 'This room does not exist!', Error: 'This room does not exist!',
}) })
} }
const isOwner = room.CreatorAccountId === accountId if (room.CreatorAccountId !== accountId) {
if (!isOwner && !(await isStaff(c))) {
return roomResult(c, { return roomResult(c, {
Success: false, Success: false,
ErrorId: 'Rooms.NotOwner', ErrorId: 'Rooms.NotOwner',
@@ -2098,7 +2097,8 @@ const app = new Hono<App>()
Error: 'This room does not exist!', Error: 'This room does not exist!',
}) })
} }
if (room.CreatorAccountId !== accountId) { const isOwner = room.CreatorAccountId === accountId
if (!isOwner && !(await isStaff(c))) {
return roomResult(c, { return roomResult(c, {
Success: false, Success: false,
ErrorId: 'Rooms.NotOwner', ErrorId: 'Rooms.NotOwner',
@@ -1634,6 +1634,45 @@ describe('rooms endpoints', () => {
expect(interactions!.n).toBe(0) expect(interactions!.n).toBe(0)
}) })
it('DELETE /rooms/:id also lets staff through — the website’s takedown — but only there', async () => {
// Somebody else's room. A moderator token may delete it; the same token may NOT
// rename it, which is what a misapplied check once allowed.
await env.DB.prepare('INSERT INTO room (data) VALUES (?1)')
.bind(
JSON.stringify({
RoomId: 9501,
Name: 'TakeMeDown',
CreatorAccountId: 1,
IsDorm: false,
Accessibility: 1,
ImageName: '',
SubRooms: [],
})
)
.run()
const staff = await bearer('999', ['gameClient', 'moderator'])
const roomExists = async () =>
(await env.DB.prepare('SELECT 1 FROM room WHERE room_id = 9501').first()) !== null
const rename = await SELF.fetch(`${ORIGIN}/rooms/9501/name`, {
method: 'PUT',
headers: { ...staff, 'content-type': 'application/x-www-form-urlencoded' },
body: 'name=Renamed',
})
expect(await bodyOf(rename)).toMatchObject({ Success: false, ErrorId: 'Rooms.NotOwner' })
// A plain player is still refused; the moderator gets through.
const del = async (headers: Record<string, string>) =>
bodyOf(await SELF.fetch(`${ORIGIN}/rooms/9501`, { method: 'DELETE', headers }))
expect(await del(await bearer('2', ['gameClient']))).toMatchObject({
Success: false,
ErrorId: 'Rooms.NotOwner',
})
expect(await roomExists()).toBe(true)
expect(await del(staff)).toMatchObject({ Success: true })
expect(await roomExists()).toBe(false)
})
it('PUT /rooms/:id/roles/:accountId grants a helper role outright, but never co-owner', async () => { it('PUT /rooms/:id/roles/:accountId grants a helper role outright, but never co-owner', async () => {
type Role = { type Role = {
AccountId: number AccountId: number