mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
move to JWT_SECRET
This commit is contained in:
@@ -97,7 +97,7 @@ async function placeNewPlayerInOrientation(env: App['Bindings'], accountId: numb
|
||||
async function authedId(c: Context<App>): Promise<number | null> {
|
||||
const authHeader = c.req.header('Authorization') ?? ''
|
||||
if (!authHeader.toLowerCase().startsWith('bearer ')) return null
|
||||
const sub = await validateAndGetAccountId(authHeader.slice('Bearer '.length))
|
||||
const sub = await validateAndGetAccountId(authHeader.slice('Bearer '.length), c.env.JWT_SECRET)
|
||||
const id = sub ? Number.parseInt(sub, 10) : Number.NaN
|
||||
return Number.isNaN(id) ? null : id
|
||||
}
|
||||
@@ -153,7 +153,7 @@ const app = new Hono<App>()
|
||||
const account = await createAccount(c.env.DB, { platforms: platformInt || 0 })
|
||||
accountId = String(account.accountId)
|
||||
// Place the new player in Orientation (they don't matchmake into it).
|
||||
await placeNewPlayerInOrientation(c.env, account.accountId)
|
||||
//await placeNewPlayerInOrientation(c.env, account.accountId)
|
||||
} else {
|
||||
const posted = typeof body.account_id === 'string' ? body.account_id.trim() : ''
|
||||
if (!/^\d+$/.test(posted)) {
|
||||
@@ -165,10 +165,7 @@ const app = new Hono<App>()
|
||||
accountId = posted
|
||||
}
|
||||
|
||||
const accessToken = await generateToken(accountId, platformId, platform)
|
||||
|
||||
// TODO: also create the player's dorm on create_account, and remove any
|
||||
// RoomInstance owned by accountId on login.
|
||||
const accessToken = await generateToken(accountId, platformId, platform, c.env.JWT_SECRET)
|
||||
|
||||
return c.json({
|
||||
access_token: accessToken,
|
||||
|
||||
@@ -9,6 +9,11 @@ export type Env = SharedHonoEnv & {
|
||||
// the new player's presence is seeded to the Orientation room so the match
|
||||
// heartbeat keeps them there instead of bouncing them to the dorm.
|
||||
RECFLARE_MATCH_PRESENCE: KVNamespace
|
||||
// HS256 signing key for issued access tokens. Set as a Cloudflare secret
|
||||
// (`wrangler secret put JWT_SECRET`) in deployed environments and via `.dev.vars`
|
||||
// locally — never committed. `keep_vars` in wrangler.jsonc stops deploys from
|
||||
// clearing it.
|
||||
JWT_SECRET: string
|
||||
}
|
||||
|
||||
/** Variables can be extended */
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/**
|
||||
* Minimal HS256 JWT generation.
|
||||
*
|
||||
* No real signing-key binding yet — uses a placeholder dev secret. Swap this for
|
||||
* a secret binding (e.g. `c.env.JWT_SECRET`) before this is used for anything real.
|
||||
* The signing key is supplied by the caller from the `JWT_SECRET` binding
|
||||
* (a Cloudflare secret in deployed envs, `.dev.vars` locally) — see context.ts.
|
||||
*/
|
||||
const DEV_SECRET = 'dev-insecure-signing-key-change-me'
|
||||
|
||||
/** Token lifetime in seconds (mirrored in the `expires_in` response field). */
|
||||
export const TOKEN_TTL_SECONDS = 3600
|
||||
@@ -32,7 +31,7 @@ function base64urlToBytes(input: string): Uint8Array {
|
||||
*/
|
||||
export async function validateAndGetAccountId(
|
||||
token: string,
|
||||
secret: string = DEV_SECRET
|
||||
secret: string
|
||||
): Promise<string | null> {
|
||||
const parts = token.split('.')
|
||||
if (parts.length !== 3) return null
|
||||
@@ -88,7 +87,7 @@ export async function generateToken(
|
||||
accountId: string,
|
||||
platformId: string,
|
||||
platform: string,
|
||||
secret: string = DEV_SECRET
|
||||
secret: string
|
||||
): Promise<string> {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const header = { alg: 'HS256', typ: 'JWT' }
|
||||
|
||||
Reference in New Issue
Block a user