fake route for oculus

This commit is contained in:
Devin Zuczek
2026-07-20 21:38:40 -04:00
parent 21f7eff384
commit 64bfc9f851
4 changed files with 55 additions and 5 deletions
+28 -2
View File
@@ -25,6 +25,7 @@ import {
CachedLogin,
ChangePasswordRequest,
ChangePasswordResponse,
FakeCachedLogin,
form,
json,
OAuthError,
@@ -58,6 +59,18 @@ const PLATFORM_TYPES: Record<number, string> = {
8: 'Pico',
}
/** PlatformType for Oculus, which `/cachedlogin/forplatformid` currently stubs out. */
const OCULUS_PLATFORM = 1
/** The canned entry served for any Oculus cached-login lookup. See the route below. */
const FAKE_OCULUS_CACHED_LOGIN = {
platform: OCULUS_PLATFORM,
platformId: '1',
accountId: 1,
lastLoginTime: '2026-07-19T17:13:29.225Z',
requirePassword: true,
} as const
/**
* Signup caps, enforced on create_account only (never on login — an existing account
* always stays reachable, however many accounts its owner has since accumulated).
@@ -254,7 +267,9 @@ const app = new Hono<App>()
'Accounts the client may offer on its login screen for this platform identity. ' +
'Filtered to those a `cached_login` grant would actually accept, so an entry here ' +
'is always redeemable. An unknown id yields `[]` (not a 404) and the client falls ' +
'back to a fresh login or create_account.',
'back to a fresh login or create_account. ' +
'EXCEPT platform 1 (Oculus), which is stubbed: it ignores the id and returns one ' +
'canned, non-redeemable entry with `requirePassword: true`.',
parameters: [
{
name: 'platform',
@@ -271,12 +286,23 @@ const app = new Hono<App>()
schema: { type: 'string' },
},
],
responses: { 200: json(CachedLogin.array(), 'Matching accounts; `[]` if none') },
responses: {
200: json(
CachedLogin.or(FakeCachedLogin).array(),
'Matching accounts; `[]` if none. The canned entry for platform 1 (Oculus).'
),
},
}),
async (c) => {
const { platform, id } = c.req.param()
logger.info('cached login lookup', { platform, id })
const platformInt = Number.parseInt(platform, 10)
// Oculus has no identity flow yet, so there is nothing in the DB to look up and
// the real path would always yield []. Hand back one canned entry instead, so the
// Oculus client gets past its login screen. `requirePassword` is true — unlike a
// genuine cached login there is no platform ticket behind this, so the client must
// prompt. Delete this branch once Oculus platform auth lands.
if (platformInt === OCULUS_PLATFORM) return c.json([FAKE_OCULUS_CACHED_LOGIN])
const accounts = await getAccountsByPlatformId(c.env.DB, id)
// Offer only accounts the `cached_login` grant will actually accept — same check.
return c.json(
+8
View File
@@ -70,6 +70,14 @@ export const CachedLogin = z.object({
.describe('Always false — platform ownership is the credential for a cached login'),
})
/**
* The stubbed Oculus cached login. Same shape as `CachedLogin`, but `requirePassword`
* is true — nothing proves platform ownership, so the client has to prompt.
*/
export const FakeCachedLogin = CachedLogin.extend({
requirePassword: z.literal(true).describe('Always true — the entry is not platform-backed'),
})
/** OAuth-shaped error body. Always HTTP 400 except `server_error` (500). */
export const OAuthError = z.object({
error: z.enum(['invalid_grant', 'invalid_request', 'server_error']),
+17 -1
View File
@@ -117,12 +117,28 @@ describe('auth worker routes', () => {
expect(await res.text()).toBe('"AA=="')
})
// Platform 0 (Steam), not 1 — platform 1 is Oculus, which is stubbed below.
test('GET /cachedlogin/forplatformid/:platform/:id returns [] (no cached login)', async () => {
const res = await exports.default.fetch(`${ORIGIN}/cachedlogin/forplatformid/1/abc123`)
const res = await exports.default.fetch(`${ORIGIN}/cachedlogin/forplatformid/0/abc123`)
expect(res.status).toBe(200)
expect(await res.json()).toEqual([])
})
// Oculus is stubbed: no DB lookup, one canned entry whatever the id.
test('GET /cachedlogin/forplatformid/1/:id returns the canned Oculus entry', async () => {
const res = await exports.default.fetch(`${ORIGIN}/cachedlogin/forplatformid/1/anything`)
expect(res.status).toBe(200)
expect(await res.json()).toEqual([
{
platform: 1,
platformId: '1',
accountId: 1,
lastLoginTime: '2026-07-19T17:13:29.225Z',
requirePassword: true,
},
])
})
// Only Steam (platform 0) can be verified (via its signed platform_auth ticket),
// so every OTHER platform is rejected on the platform-authenticated grants — we
// won't bind or authorize an identity we can't prove.