Files
carmanagement/apps/api/src/middleware/requireApiKey.ts
T
2026-06-10 00:40:19 -04:00

36 lines
1.2 KiB
TypeScript

import { Request, Response, NextFunction } from 'express'
import { prisma } from '../lib/prisma'
import { getApiKeyPrefix, hashApiKey, timingSafeEqualHex } from '../security/apiKeys'
export async function requireApiKey(req: Request, res: Response, next: NextFunction) {
const apiKey = req.headers['x-api-key'] as string | undefined
if (!apiKey) {
return res.status(401).json({ error: 'missing_api_key', message: 'API key required in x-api-key header', statusCode: 401 })
}
const prefix = getApiKeyPrefix(apiKey)
if (!prefix) {
return res.status(401).json({ error: 'invalid_api_key', message: 'Invalid API key', statusCode: 401 })
}
const keyRecord = await (prisma as any).companyApiKey.findUnique({
where: { prefix },
include: { company: true },
})
const hashed = hashApiKey(apiKey)
if (!keyRecord || keyRecord.revokedAt || !timingSafeEqualHex(hashed, keyRecord.keyHash)) {
return res.status(401).json({ error: 'invalid_api_key', message: 'Invalid API key', statusCode: 401 })
}
await (prisma as any).companyApiKey.update({
where: { id: keyRecord.id },
data: { lastUsedAt: new Date() },
})
req.company = keyRecord.company
req.companyId = keyRecord.companyId
next()
}