Files
infohliadka/lib/api-auth.ts
Lukas Davidovic 249a672cd7 transform admin panel with comprehensive professional UI
- migrate from SQLite to PostgreSQL with Drizzle ORM
- implement comprehensive AdminLayout with expandable sidebar navigation
- create professional dashboard with real-time charts and metrics
- add advanced monitoring, reporting, and export functionality
- fix menu alignment and remove non-existent pages
- eliminate duplicate headers and improve UI consistency
- add Tailwind CSS v3 for professional styling
- expand database schema from 6 to 15 tables
- implement role-based access control and API key management
- create comprehensive settings, monitoring, and system info pages
2025-09-06 15:14:20 +02:00

73 lines
1.9 KiB
TypeScript

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<ApiKey | null> {
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 || 1000,
isActive: apiKey.isActive || false,
lastUsed: apiKey.lastUsed || undefined,
createdAt: apiKey.createdAt || new Date()
}
} 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