(a: string, b: string)
| 14 | // Tradeoff: this allocates temporary buffers. That's acceptable here (called once |
| 15 | // per auth check) and avoids tricky timing branches. |
| 16 | export function safeEq(a: string, b: string): boolean { |
| 17 | const bufA = Buffer.from(a); |
| 18 | const bufB = Buffer.from(b); |
| 19 | |
| 20 | const maxLen = Math.max(bufA.length, bufB.length); |
| 21 | |
| 22 | // timingSafeEqual requires equal-length buffers. |
| 23 | const paddedA = Buffer.alloc(maxLen); |
| 24 | const paddedB = Buffer.alloc(maxLen); |
| 25 | bufA.copy(paddedA); |
| 26 | bufB.copy(paddedB); |
| 27 | |
| 28 | const bytesMatch = timingSafeEqual(paddedA, paddedB); |
| 29 | return bytesMatch && bufA.length === bufB.length; |
| 30 | } |
| 31 | |
| 32 | function extractBearerToken(header: string | string[] | undefined): string | null { |
| 33 | const h = Array.isArray(header) ? header[0] : header; |
no outgoing calls
no test coverage detected