From 0699e4409ec47fdfef4772f7bcb4f069b293651b Mon Sep 17 00:00:00 2001 From: Devin Zuczek Date: Fri, 21 Aug 2026 01:24:58 -0400 Subject: [PATCH] [auth] made up nonce for oculus --- apps/auth/src/auth.app.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/apps/auth/src/auth.app.ts b/apps/auth/src/auth.app.ts index e1b9293..e479c19 100644 --- a/apps/auth/src/auth.app.ts +++ b/apps/auth/src/auth.app.ts @@ -1,6 +1,7 @@ import { Hono } from 'hono' import { describeRoute, openAPIRouteHandler } from 'hono-openapi' import { useWorkersLogger } from 'workers-tagged-logger' +import { z } from 'zod' import { countAccountsBySignupIp, @@ -1178,6 +1179,31 @@ const app = new Hono() return c.json(account.isModerator === true) }) + // @guess Oculus nonce. The client asks for this before a Meta login; the exact shape + // it expects hasn't been observed, so this mints a fresh 64-char hex nonce (the length + // Meta's own `GetUserProof` nonces have) and answers it as a bare JSON string. Nothing + // is stored — Meta's nonce validation (meta-nonce.ts) is what actually proves a login, + // so this value is not security-relevant to the server. Revisit once the client's use + // of it is seen. + .get( + '/oculus/nonce', + describeRoute({ + tags: ['Account'], + summary: 'A fresh nonce for the Oculus login flow', + description: [ + 'Mints a random 64-char hex nonce and returns it as a bare JSON string. Not stored', + 'and not verified later — a best guess at the shape the client wants.', + ].join(' '), + responses: { 200: json(z.string(), 'The nonce') }, + }), + (c) => { + const bytes = crypto.getRandomValues(new Uint8Array(32)) + const nonce = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('') + logger.info('oculus nonce issued') + return c.json(nonce) + } + ) + // The generated spec. Documentation only — no request is validated against it (see // openapi.ts). `hide: true` keeps this route out of its own output. app.get(