[api] 2025 gameconfig swap, implement sanitize

This commit is contained in:
Devin Zuczek
2026-08-19 17:10:19 -04:00
parent ec808d3cd8
commit 6916ed2557
6 changed files with 6373 additions and 33 deletions
+31 -4
View File
@@ -1,9 +1,11 @@
import { Hono } from 'hono'
import { describeRoute } from 'hono-openapi'
import { isSupportedGameVersion } from '@repo/domain'
import { GAME_VERSION, isSupportedGameVersion } from '@repo/domain'
import { validateAndGetVersion } from '@repo/jwt'
import apiConfigV2 from '../../static/api-config-v2.json'
import gameConfigsV1All2025 from '../../static/gameconfigs-v1-all-2025.json'
import gameConfigsV1All from '../../static/gameconfigs-v1-all.json'
import {
AmplitudeConfig,
@@ -129,15 +131,40 @@ export const configRoutes = new Hono<App>({ strict: false })
}),
(c) => c.json([])
)
// Two catalogs, one per client generation: the 2023 build and the 2025 build read
// different keys out of this, and the 2025 one carries entries (`Screens.*`, the
// creative-door queries) the older catalog never had.
//
// Which one a caller gets is decided by the token's `rn.ver` claim — the build the
// client posted at login — since the request itself carries no version. Anything NEWER
// than `GAME_VERSION` (20230414) gets the 2025 catalog; that build and anything older
// get the 2023 one. Builds are date-stamped (`20230414`, `20250718.01`), so they order
// as strings, the same comparison `match` makes for cross-build joins.
//
// A request with no readable token version gets the 2023 catalog, the same body this
// route has always served: unauthenticated is not evidence of a newer client, and this
// stack targets `GAME_VERSION`. Like the version gate on `featuredrooms`, the claim is
// unverified — a client that lies about its build only misconfigures itself.
.get(
'/api/gameconfigs/v1/all',
describeRoute({
tags: ['Config'],
summary: 'Per-game configuration',
description: 'An opaque static catalog of per-game settings, served verbatim.',
responses: { 200: json(JsonObject, 'The game config catalog') },
description:
'An opaque static catalog of per-game settings, served verbatim. There are two: a ' +
'build NEWER than `20230414` gets the 2025 catalog, which carries keys the older one ' +
'never had; that build and anything older get the 2023 catalog. Builds are ' +
'date-stamped, so they compare as strings. The build is read from the tokens ' +
'`rn.ver` claim — the request carries no version of its own — so auth is optional ' +
'here and only selects the catalog; a request without a readable token version gets ' +
'the 2023 one.',
responses: { 200: json(JsonObject, 'The game config catalog for the callers build') },
}),
(c) => c.json(gameConfigsV1All)
async (c) => {
const version = await validateAndGetVersion(c.req.raw, await c.env.JWT_SECRET.get())
const newerThanTarget = version !== null && version > GAME_VERSION
return c.json(newerThanTarget ? gameConfigsV1All2025 : gameConfigsV1All)
}
)
// The property bag the client would attach to its Statsig user. The reference server