import { NextRequest, NextResponse } from "next/server"; import { db } from "@/db"; import { apiKeys, user } from "@/db/schema"; import { eq, and } from "drizzle-orm"; import { verifyJWT, isValidAPIKeyFormat } from "./jwt"; import { UserRole } from "./permissions"; export interface AuthenticatedRequest extends NextRequest { userId?: string; email?: string; role?: UserRole; } export interface AuthResult { authenticated: boolean; userId?: string; email?: string; role?: UserRole; error?: string; } /** * API isteklerini doğrula (JWT token veya API key ile) * * Kullanım: * const authResult = await authenticateAPIRequest(request); * if (!authResult.authenticated) { * return NextResponse.json({ error: authResult.error }, { status: 401 }); * } * const userId = authResult.userId; */ export async function authenticateAPIRequest(request: NextRequest): Promise { const authHeader = request.headers.get("authorization"); if (!authHeader) { return { authenticated: false, error: "Authorization header eksik. Bearer token veya API key gerekli.", }; } // Bearer token kontrolü if (authHeader.startsWith("Bearer ")) { const token = authHeader.substring(7); // JWT token mu yoksa API key mi? if (isValidAPIKeyFormat(token)) { // API Key doğrulama return await validateAPIKey(token); } else { // JWT token doğrulama return await validateJWTToken(token); } } return { authenticated: false, error: "Geçersiz authorization formatı. 'Bearer ' formatında olmalı.", }; } /** * JWT token doğrula ve kullanıcı bilgilerini getir */ async function validateJWTToken(token: string): Promise { const payload = verifyJWT(token); if (!payload) { return { authenticated: false, error: "Geçersiz veya süresi dolmuş token.", }; } // Kullanıcı bilgilerini DB'den al (role için) try { const users = await db .select() .from(user) .where(eq(user.id, payload.userId)) .limit(1); if (users.length === 0) { return { authenticated: false, error: "Kullanıcı bulunamadı.", }; } const userData = users[0]; return { authenticated: true, userId: payload.userId, email: payload.email, role: (userData.role as UserRole) || "user", }; } catch (error) { console.error("User lookup error:", error); return { authenticated: false, error: "Kimlik doğrulama sırasında bir hata oluştu.", }; } } /** * API key doğrula (veritabanından kontrol) */ async function validateAPIKey(key: string): Promise { try { const apiKey = await db .select() .from(apiKeys) .where(and(eq(apiKeys.key, key), eq(apiKeys.isActive, true))) .limit(1); if (apiKey.length === 0) { return { authenticated: false, error: "Geçersiz API key.", }; } const keyData = apiKey[0]; // Süre kontrolü if (keyData.expiresAt && keyData.expiresAt < new Date()) { return { authenticated: false, error: "API key süresi dolmuş.", }; } // Kullanıcı bilgilerini al const users = await db .select() .from(user) .where(eq(user.id, keyData.userId)) .limit(1); if (users.length === 0) { return { authenticated: false, error: "Kullanıcı bulunamadı.", }; } const userData = users[0]; // Son kullanım tarihini güncelle (opsiyonel) await db .update(apiKeys) .set({ lastUsedAt: new Date() }) .where(eq(apiKeys.id, keyData.id)); return { authenticated: true, userId: keyData.userId, email: userData.email, role: (userData.role as UserRole) || "user", }; } catch (error) { console.error("API key doğrulama hatası:", error); return { authenticated: false, error: "Kimlik doğrulama sırasında bir hata oluştu.", }; } }