- Use type-only import for HttpContext in exceptions/handler.ts - Use #services alias instead of relative path in device_record.ts - Reformat api_key_middleware and cwmp_logger_middleware per prettier
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
import { timingSafeEqual } from 'node:crypto'
|
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
import type { NextFn } from '@adonisjs/core/types/http'
|
|
import env from '#start/env'
|
|
|
|
/**
|
|
* ApiKeyMiddleware
|
|
*
|
|
* Protects REST API routes by validating a fixed API key provided in the
|
|
* X-Api-Key request header. The expected key is configured via:
|
|
* API_KEY (required env variable)
|
|
*
|
|
* Security:
|
|
* - Constant-time comparison (timingSafeEqual) to prevent timing attacks
|
|
*
|
|
* Responds with 401 if the header is missing or the key does not match.
|
|
*/
|
|
export default class ApiKeyMiddleware {
|
|
async handle({ request, response }: HttpContext, next: NextFn) {
|
|
const apiKey = request.header('x-api-key') ?? ''
|
|
const expectedKey = env.get('API_KEY')!
|
|
|
|
const provided = Buffer.from(apiKey)
|
|
const expected = Buffer.from(expectedKey)
|
|
|
|
// Lengths must match and content must match in constant time
|
|
const valid = provided.length === expected.length && timingSafeEqual(provided, expected)
|
|
|
|
if (!valid) {
|
|
return response.status(401).send('Unauthorized: invalid or missing X-Api-Key header')
|
|
}
|
|
|
|
return next()
|
|
}
|
|
}
|