diff --git a/apps/auth/src/auth.app.ts b/apps/auth/src/auth.app.ts index 5b80ac8..cab346b 100644 --- a/apps/auth/src/auth.app.ts +++ b/apps/auth/src/auth.app.ts @@ -522,25 +522,30 @@ const app = new Hono() return c.json({ success: true }) }) - // Developer role lookup. The role is off by default and only an operator grants - // it (via `runx admin grant-developer`, which sets the account's isDeveloper flag). - // The same flag also rides in the token's `role` claim (see accountRoles). + // Developer role lookup. Returns a bare JSON boolean (the client reads the body as + // a bool), and 404s for an unknown player — mirroring the reference API. The role + // is off by default and only an operator grants it (via `runx admin grant-developer`, + // which sets the account's isDeveloper flag); it also rides in the token's `role` + // claim (see accountRoles). .get('/role/developer/:id', async (c) => { const { id } = c.req.param() logger.info('developer role lookup', { id }) const accountId = Number.parseInt(id, 10) const account = Number.isNaN(accountId) ? null : await getAccount(c.env.DB, accountId) - return c.json({ success: account?.isDeveloper === true }) + if (!account) return c.body(null, 404) + return c.json(account.isDeveloper === true) }) - // Moderator role lookup, mirroring developer. Operator-granted only (via - // `runx admin grant-moderator`); the flag also rides in the token's `role` claim. + // Moderator role lookup, mirroring developer (bare boolean, 404 for unknown player). + // Operator-granted only (via `runx admin grant-moderator`); the flag also rides in + // the token's `role` claim. .get('/role/moderator/:id', async (c) => { const { id } = c.req.param() logger.info('moderator role lookup', { id }) const accountId = Number.parseInt(id, 10) const account = Number.isNaN(accountId) ? null : await getAccount(c.env.DB, accountId) - return c.json({ success: account?.isModerator === true }) + if (!account) return c.body(null, 404) + return c.json(account.isModerator === true) }) export default app diff --git a/apps/auth/src/test/integration/api.test.ts b/apps/auth/src/test/integration/api.test.ts index 6fe9066..790c406 100644 --- a/apps/auth/src/test/integration/api.test.ts +++ b/apps/auth/src/test/integration/api.test.ts @@ -587,30 +587,37 @@ describe('auth worker routes', () => { expect(await rotate.json()).toEqual({ success: true }) }) - test('GET /role/developer/:id does not grant developer', async () => { + test('GET /role/developer/:id returns a bare false for an un-flagged account', async () => { const res = await exports.default.fetch(`${ORIGIN}/role/developer/42`) expect(res.status).toBe(200) - expect(await res.json()).toEqual({ success: false }) + expect(await res.json()).toBe(false) }) - test('GET /role/developer/:id grants developer when the account is flagged', async () => { + test('GET /role/developer/:id returns a bare true when the account is flagged', async () => { await env.DB.prepare('INSERT OR IGNORE INTO account (data) VALUES (?1)') .bind(JSON.stringify({ accountId: 4242, username: 'DevPlayer', isDeveloper: true })) .run() const res = await exports.default.fetch(`${ORIGIN}/role/developer/4242`) expect(res.status).toBe(200) - expect(await res.json()).toEqual({ success: true }) + expect(await res.json()).toBe(true) }) - test('GET /role/moderator/:id reflects the isModerator flag', async () => { + test('GET /role/developer/:id 404s for an unknown player', async () => { + const res = await exports.default.fetch(`${ORIGIN}/role/developer/99999`) + expect(res.status).toBe(404) + }) + + test('GET /role/moderator/:id reflects the isModerator flag as a bare boolean', async () => { await env.DB.prepare('INSERT OR IGNORE INTO account (data) VALUES (?1)') .bind(JSON.stringify({ accountId: 4343, username: 'ModPlayer', isModerator: true })) .run() const granted = await exports.default.fetch(`${ORIGIN}/role/moderator/4343`) - expect(await granted.json()).toEqual({ success: true }) + expect(await granted.json()).toBe(true) // An account without the flag (42) is not a moderator. const plain = await exports.default.fetch(`${ORIGIN}/role/moderator/42`) - expect(await plain.json()).toEqual({ success: false }) + expect(await plain.json()).toBe(false) + // Unknown player → 404. + expect((await exports.default.fetch(`${ORIGIN}/role/moderator/99999`)).status).toBe(404) }) test('unknown path returns 404', async () => {