import crypto from 'crypto' import { db, schema } from './db/connection' import { eq, and } from 'drizzle-orm' export interface ApiKey { id: number keyHash: string name: string permissions: string[] rateLimit: number isActive: boolean lastUsed?: Date createdAt: Date } export function generateApiKey(): string { return 'ak_' + crypto.randomBytes(32).toString('hex') } export function hashApiKey(key: string): string { return crypto.createHash('sha256').update(key).digest('hex') } export async function validateApiKey(key: string): Promise { if (!key || !key.startsWith('ak_')) return null const keyHash = hashApiKey(key) try { const apiKeys = await db.select() .from(schema.apiKeys) .where(and( eq(schema.apiKeys.keyHash, keyHash), eq(schema.apiKeys.isActive, true) )) .limit(1) if (apiKeys.length === 0) return null const apiKey = apiKeys[0] // Update last_used timestamp await db.update(schema.apiKeys) .set({ lastUsed: new Date() }) .where(eq(schema.apiKeys.id, apiKey.id)) return { id: apiKey.id, keyHash: apiKey.keyHash, name: apiKey.name, permissions: apiKey.permissions ? JSON.parse(apiKey.permissions) : [], rateLimit: apiKey.rateLimit, isActive: apiKey.isActive, lastUsed: apiKey.lastUsed, createdAt: apiKey.createdAt } } catch (error) { console.error('API key validation error:', error) return null } } export function hasPermission(apiKey: ApiKey, permission: string): boolean { return apiKey.permissions.includes('*') || apiKey.permissions.includes(permission) } export const ApiPermissions = { READ_SOURCES: 'sources:read', WRITE_SOURCES: 'sources:write', READ_REPORTS: 'reports:read', WRITE_REPORTS: 'reports:write', ADMIN: '*' } as const