mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-25 23:18:51 -07:00
[2026] relax versioncheck to major versions
This commit is contained in:
@@ -2,7 +2,7 @@ import { Hono } from 'hono'
|
||||
import { describeRoute } from 'hono-openapi'
|
||||
|
||||
import { GAME_VERSION, isSupportedGameVersion } from '@repo/domain'
|
||||
import { validateAndGetVersion } from '@repo/jwt'
|
||||
import { validateAndGetBuild } from '@repo/jwt'
|
||||
|
||||
import apiConfigV2 from '../../static/api-config-v2.json'
|
||||
import gameConfigsV1All2025 from '../../static/gameconfigs-v1-all-2025.json'
|
||||
@@ -140,8 +140,9 @@ export const configRoutes = new Hono<App>({ strict: false })
|
||||
// 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.
|
||||
// get the 2023 one. Builds are date-stamped (`20230414`, `20250718`), so they order as
|
||||
// strings, the same comparison `match` makes for cross-build joins — compared as BUILDS,
|
||||
// so a same-day point release of the target (`20230414.01`) stays on the 2023 catalog.
|
||||
//
|
||||
// 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
|
||||
@@ -163,8 +164,8 @@ export const configRoutes = new Hono<App>({ strict: false })
|
||||
responses: { 200: json(JsonObject, 'The game config catalog for the caller’s build') },
|
||||
}),
|
||||
async (c) => {
|
||||
const version = await validateAndGetVersion(c.req.raw, await c.env.JWT_SECRET.get())
|
||||
const newerThanTarget = version !== null && version > GAME_VERSION
|
||||
const build = await validateAndGetBuild(c.req.raw, await c.env.JWT_SECRET.get())
|
||||
const newerThanTarget = build !== null && build > GAME_VERSION
|
||||
return c.json(newerThanTarget ? gameConfigsV1All2025 : gameConfigsV1All)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ import { describeRoute } from 'hono-openapi'
|
||||
|
||||
import { Accessibility, createNotification, GAME_VERSION, MessageType } from '@repo/domain'
|
||||
import { logger } from '@repo/hono-helpers'
|
||||
import { validateAndGetVersion } from '@repo/jwt'
|
||||
import { validateAndGetBuild } from '@repo/jwt'
|
||||
|
||||
// The notification-type ids the hub carries (owned by the `notify` worker). Imported
|
||||
// as a value — the enum has no runtime dependencies.
|
||||
@@ -306,15 +306,16 @@ async function pushEventInvitation(
|
||||
* the split is the one `/api/gameconfigs/v1/all` already makes: anything NEWER than
|
||||
* `GAME_VERSION` (20230414) gets the pairs; that build, anything older, and a request
|
||||
* with no readable token version all get the 2023 names. Builds are date-stamped, so they
|
||||
* order as strings. `TagModifyResult.Tags` is a name list to every build — only the
|
||||
* inline field moves.
|
||||
* order as strings — compared as BUILDS, with the client's point release dropped, so a
|
||||
* same-day rebuild of the target stays on its side. `TagModifyResult.Tags` is a name list
|
||||
* to every build — only the inline field moves.
|
||||
*
|
||||
* Like the other version gates here the claim is unverified — a client that lies about its
|
||||
* build only empties its own tag chips.
|
||||
*/
|
||||
async function eventResult(c: Context<App>, event: PlayerEvent, tags: EventTag[]) {
|
||||
const version = await validateAndGetVersion(c.req.raw, await c.env.JWT_SECRET.get())
|
||||
const isModernBuild = version !== null && version > GAME_VERSION
|
||||
const build = await validateAndGetBuild(c.req.raw, await c.env.JWT_SECRET.get())
|
||||
const isModernBuild = build !== null && build > GAME_VERSION
|
||||
return toEventResult(event, tags, isModernBuild)
|
||||
}
|
||||
|
||||
|
||||
@@ -301,6 +301,18 @@ describe('public endpoints', () => {
|
||||
}
|
||||
})
|
||||
|
||||
test('GET /api/versioncheck/v4 ignores the point release: every .NN of a supported build is current', async () => {
|
||||
// The list holds bare dates; the client reports `YYYYMMDD.NN`, and the `.NN` is a
|
||||
// same-day rebuild of the same build. All of these are the beta build.
|
||||
for (const version of ['20250718.01', '20250718.2', '20250718', '20250718.99']) {
|
||||
const res = await exports.default.fetch(`${ORIGIN}/api/versioncheck/v4?v=${version}`)
|
||||
expect(await res.json(), version).toMatchObject({ VersionStatus: 0 })
|
||||
}
|
||||
// ...and a point release of a build that ISN'T supported is still not.
|
||||
const res = await exports.default.fetch(`${ORIGIN}/api/versioncheck/v4?v=19990101.01`)
|
||||
expect(await res.json()).toMatchObject({ VersionStatus: 1 })
|
||||
})
|
||||
|
||||
test('GET /api/versioncheck/v4 flags a mismatched build', async () => {
|
||||
const res = await exports.default.fetch(`${ORIGIN}/api/versioncheck/v4?v=19990101`)
|
||||
expect(await res.json()).toMatchObject({ VersionStatus: 1 })
|
||||
@@ -331,6 +343,9 @@ describe('public endpoints', () => {
|
||||
|
||||
test('GET /api/gameconfigs/v1/all serves the 2023 catalog to the target build', async () => {
|
||||
expect(await gameConfigKeys(GAME_VERSION)).not.toContain(KEY_2025_ONLY)
|
||||
// A same-day point release of the target is the target build: compared as a build,
|
||||
// not as a string that happens to sort after `20230414`.
|
||||
expect(await gameConfigKeys(`${GAME_VERSION}.01`)).not.toContain(KEY_2025_ONLY)
|
||||
})
|
||||
|
||||
test('GET /api/gameconfigs/v1/all serves the 2023 catalog to an older build', async () => {
|
||||
|
||||
Reference in New Issue
Block a user