updating types

This commit is contained in:
Devin Zuczek
2026-06-30 23:57:29 -04:00
parent 8e513c1275
commit ba33003343
40 changed files with 49940 additions and 16163 deletions
+34 -4
View File
@@ -35,6 +35,8 @@ export interface Account {
createdAt: string
/** Set via POST /account/me/email; absent until the player provides one. */
email?: string
/** Set via POST /account/me/phone; absent until the player provides one. */
phone?: string
/** Set via PUT /account/me/bio; read back via GET /account/:id/bio. */
bio?: string
}
@@ -49,12 +51,40 @@ const parseAll = (rows: AccountRow[]): Account[] => rows.map((r) => JSON.parse(r
/** Word lists for auto-assigned usernames (players don't pick one on signup). */
const ADJECTIVES = [
'Swift', 'Brave', 'Clever', 'Happy', 'Mighty', 'Lucky', 'Sunny', 'Cosmic',
'Witty', 'Nimble', 'Jolly', 'Bold', 'Gentle', 'Fuzzy', 'Speedy', 'Shiny',
'Swift',
'Brave',
'Clever',
'Happy',
'Mighty',
'Lucky',
'Sunny',
'Cosmic',
'Witty',
'Nimble',
'Jolly',
'Bold',
'Gentle',
'Fuzzy',
'Speedy',
'Shiny',
]
const NOUNS = [
'Fox', 'Otter', 'Falcon', 'Panda', 'Tiger', 'Comet', 'Maple', 'Pixel',
'Robin', 'Wolf', 'Koala', 'Dragon', 'Penguin', 'Badger', 'Heron', 'Lynx',
'Fox',
'Otter',
'Falcon',
'Panda',
'Tiger',
'Comet',
'Maple',
'Pixel',
'Robin',
'Wolf',
'Koala',
'Dragon',
'Penguin',
'Badger',
'Heron',
'Lynx',
]
/** A random, readable username (e.g. "SwiftFox4821"). */
+20 -2
View File
@@ -3,7 +3,13 @@ import { useWorkersLogger } from 'workers-tagged-logger'
import { withNotFound, withOnError } from '@repo/hono-helpers'
import { createAccount, defaultAccount, getAccount, getAccountsByIds, updateAccount } from './accounts-db'
import {
createAccount,
defaultAccount,
getAccount,
getAccountsByIds,
updateAccount,
} from './accounts-db'
import { validateAndGetAccountId } from './jwt'
import type { Context } from 'hono'
@@ -129,7 +135,9 @@ const app = new Hono<App>()
const accountId = Number.parseInt(c.req.param('id'), 10)
if (Number.isNaN(accountId)) return c.body(null, 400)
// Load the stored account, falling back to a synthesized default.
return c.json(toAccountDto((await getAccount(c.env.DB, accountId)) ?? defaultAccount(accountId)))
return c.json(
toAccountDto((await getAccount(c.env.DB, accountId)) ?? defaultAccount(accountId))
)
})
// ---- Create --------------------------------------------------------------
@@ -180,6 +188,16 @@ const app = new Hono<App>()
return c.json({ success: true })
})
// Set the player's phone (persisted on the account row).
.post('/account/me/phone', async (c) => {
const id = await authedId(c)
if (id === null) return unauthorized(c)
const phone = (await formField(c, 'phone')).trim()
if (phone === '') return c.body(null, 400)
await updateAccount(c.env.DB, id, { phone })
return c.json({ success: true })
})
// Set the player's identityFlags bitmask (persisted; surfaced by /account/me).
.put('/account/me/identityflags', async (c) => {
const id = await authedId(c)
@@ -232,6 +232,38 @@ describe('auth-gated endpoints', () => {
expect(((await me.json()) as { identityFlags: number }).identityFlags).toBe(384)
})
test('POST /account/me/phone 401s without a token', async () => {
const res = await exports.default.fetch(`${ORIGIN}/account/me/phone`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'phone=%2B14444444444',
})
expect(res.status).toBe(401)
})
test('POST /account/me/phone 400s on empty, persists a real number', async () => {
const headers = {
...(await bearer('891')),
'Content-Type': 'application/x-www-form-urlencoded',
}
// Empty phone → 400.
const empty = await exports.default.fetch(`${ORIGIN}/account/me/phone`, {
method: 'POST',
headers,
body: 'phone=',
})
expect(empty.status).toBe(400)
// Set it → success.
const res = await exports.default.fetch(`${ORIGIN}/account/me/phone`, {
method: 'POST',
headers,
body: 'phone=%2B14444444444',
})
expect(res.status).toBe(200)
expect(await res.json()).toEqual({ success: true })
})
test('PUT /account/me/bio 401s without a token', async () => {
const res = await exports.default.fetch(`${ORIGIN}/account/me/bio`, { ...form({ bio: 'x' }) })
expect(res.status).toBe(401)