60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
import { Request, Response, NextFunction } from 'express';
|
|
import { ApiKeyService, type ApiKeyWithSlugs } from '../../services/ApiKeyService';
|
|
|
|
// Extend Express Request type to include apiKey with slugs
|
|
declare global {
|
|
namespace Express {
|
|
interface Request {
|
|
apiKey?: ApiKeyWithSlugs;
|
|
}
|
|
}
|
|
}
|
|
|
|
const apiKeyService = new ApiKeyService();
|
|
|
|
/**
|
|
* Middleware to validate API key from X-API-Key header
|
|
*/
|
|
export async function validateApiKey(
|
|
req: Request,
|
|
res: Response,
|
|
next: NextFunction,
|
|
): Promise<void> {
|
|
const providedKey = req.headers['x-api-key'] as string;
|
|
|
|
if (!providedKey) {
|
|
res.status(401).json({
|
|
error: 'Missing API key',
|
|
message: 'Provide your API key via X-API-Key header',
|
|
});
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const apiKey = await apiKeyService.validateKey(providedKey);
|
|
|
|
if (!apiKey) {
|
|
res.status(401).json({
|
|
error: 'Invalid API key',
|
|
message: 'The provided API key is invalid, expired, or revoked',
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Attach to request for use in routes
|
|
req.apiKey = apiKey;
|
|
|
|
console.log(
|
|
`[${new Date().toISOString()}] API key validated: ${apiKey.id} (${apiKey.keyType})`,
|
|
);
|
|
|
|
next();
|
|
} catch (error) {
|
|
console.error(`[${new Date().toISOString()}] API key validation error:`, error);
|
|
res.status(500).json({
|
|
error: 'Authentication failed',
|
|
message: 'An error occurred during authentication',
|
|
});
|
|
}
|
|
}
|