import type { Request, Response } from 'express'; import type { Types } from 'mongoose'; import { logger } from '@librechat/data-schemas'; export interface ApiKeyHandlerDependencies { createAgentApiKey: (params: { userId: string | Types.ObjectId; name: string; expiresAt?: Date | null; }) => Promise<{ id: string; name: string; key: string; keyPrefix: string; createdAt: Date; expiresAt?: Date; }>; listAgentApiKeys: (userId: string | Types.ObjectId) => Promise< Array<{ id: string; name: string; keyPrefix: string; lastUsedAt?: Date; expiresAt?: Date; createdAt: Date; }> >; deleteAgentApiKey: ( keyId: string | Types.ObjectId, userId: string | Types.ObjectId, ) => Promise; getAgentApiKeyById: ( keyId: string | Types.ObjectId, userId: string | Types.ObjectId, ) => Promise<{ id: string; name: string; keyPrefix: string; lastUsedAt?: Date; expiresAt?: Date; createdAt: Date; } | null>; } interface AuthenticatedRequest extends Request { user?: { id: string; _id: Types.ObjectId; }; } export function createApiKeyHandlers(deps: ApiKeyHandlerDependencies) { async function createApiKey(req: AuthenticatedRequest, res: Response) { try { const { name, expiresAt } = req.body; if (!name || typeof name !== 'string' || name.trim() === '') { return res.status(400).json({ error: 'API key name is required', }); } const result = await deps.createAgentApiKey({ userId: req.user?.id || '', name: name.trim(), expiresAt: expiresAt ? new Date(expiresAt) : null, }); res.status(201).json({ id: result.id, name: result.name, key: result.key, keyPrefix: result.keyPrefix, createdAt: result.createdAt, expiresAt: result.expiresAt, }); } catch (error) { logger.error('[createApiKey] Error creating API key:', error); res.status(500).json({ error: 'Failed to create API key' }); } } async function listApiKeys(req: AuthenticatedRequest, res: Response) { try { const keys = await deps.listAgentApiKeys(req.user?.id || ''); res.status(200).json({ keys }); } catch (error) { logger.error('[listApiKeys] Error listing API keys:', error); res.status(500).json({ error: 'Failed to list API keys' }); } } async function getApiKey(req: AuthenticatedRequest, res: Response) { try { const key = await deps.getAgentApiKeyById(req.params.id, req.user?.id || ''); if (!key) { return res.status(404).json({ error: 'API key not found' }); } res.status(200).json(key); } catch (error) { logger.error('[getApiKey] Error getting API key:', error); res.status(500).json({ error: 'Failed to get API key' }); } } async function deleteApiKey(req: AuthenticatedRequest, res: Response) { try { const deleted = await deps.deleteAgentApiKey(req.params.id, req.user?.id || ''); if (!deleted) { return res.status(404).json({ error: 'API key not found' }); } res.status(204).send(); } catch (error) { logger.error('[deleteApiKey] Error deleting API key:', error); res.status(500).json({ error: 'Failed to delete API key' }); } } return { createApiKey, listApiKeys, getApiKey, deleteApiKey, }; }