1+ import crypto from 'node:crypto'
2+
13import bcrypt from 'bcrypt'
24import { eq } from 'drizzle-orm'
35import type { Context , MiddlewareHandler } from 'hono'
@@ -21,17 +23,22 @@ const internalToken = process.env.INTERNAL_API_TOKEN ?? 'internal-dev-token'
2123const authInternalApiKey = process . env . AUTH_INTERNAL_API_KEY ?? ''
2224const sessionSecret = process . env . SESSION_SECRET ?? 'dev-secret-change-me'
2325
26+ function timingSafeEquals ( a : string , b : string ) : boolean {
27+ if ( a . length !== b . length ) return false
28+ return crypto . timingSafeEqual ( Buffer . from ( a ) , Buffer . from ( b ) )
29+ }
30+
2431export const authMiddleware = createMiddleware < AuthEnv > ( async ( c , next ) => {
2532 // Internal service calls (legacy header)
2633 const internalHeader = c . req . header ( 'x-internal-token' )
27- if ( internalHeader === internalToken ) {
34+ if ( internalHeader && timingSafeEquals ( internalHeader , internalToken ) ) {
2835 c . set ( 'apiKeyScope' , 'read' )
2936 return next ( )
3037 }
3138
3239 // Auth provider internal API key (used by /api/kf/* endpoints)
3340 const auth = c . req . header ( 'authorization' )
34- if ( authInternalApiKey && auth === `Bearer ${ authInternalApiKey } ` ) {
41+ if ( authInternalApiKey && auth && timingSafeEquals ( auth , `Bearer ${ authInternalApiKey } ` ) ) {
3542 c . set ( 'apiKeyScope' , 'admin' )
3643 return next ( )
3744 }
0 commit comments