mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-09 07:01:27 -07:00
updating types
This commit is contained in:
@@ -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"). */
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user