has('status')) { switch ($request->status) { case 'active': $query->active(); break; case 'expired': $query->expired(); break; case 'inactive': $query->where('is_active', false); break; } } // Filter by user if ($request->has('user_id') && $request->user_id) { $query->where('user_id', $request->user_id); } // Search by key name if ($request->has('search') && $request->search) { $query->where('key_name', 'like', '%' . $request->search . '%'); } // Sort $sortBy = $request->get('sort_by', 'created_at'); $sortOrder = $request->get('sort_order', 'desc'); $query->orderBy($sortBy, $sortOrder); $apiKeys = $query->paginate(20)->withQueryString(); $gatewayUsers = GatewayUser::orderBy('alias')->get(); return view('api-keys.index', compact('apiKeys', 'gatewayUsers')); } /** * Show the form for creating a new API key. */ public function create() { $gatewayUsers = GatewayUser::orderBy('alias')->get(); return view('api-keys.create', compact('gatewayUsers')); } /** * Store a newly created API key. */ public function store(Request $request) { $validated = $request->validate([ 'key_name' => 'required|string|max:255', 'user_id' => 'required|string|exists:gateway_users,user_id', 'expires_at' => 'nullable|date|after:now', 'metadata' => 'nullable|json', ]); try { // Generate a unique API token $token = 'llmg_' . Str::random(48); // Parse metadata if provided $metadata = null; if (!empty($validated['metadata'])) { $metadata = json_decode($validated['metadata'], true); if (json_last_error() !== JSON_ERROR_NONE) { return back()->with('error', 'Invalid JSON in metadata field'); } } // Create API key directly in database $apiKey = ApiKey::create([ 'token' => $token, 'user_id' => $validated['user_id'], 'key_name' => $validated['key_name'], 'key_alias' => $validated['key_name'], // Use key_name as alias 'expires' => $validated['expires_at'] ?? null, 'metadata' => $metadata, 'permissions' => [], // Default empty permissions 'models' => [], // Default empty models ]); // Store the token in session for one-time display session()->flash('new_api_key', $token); session()->flash('new_api_key_id', $apiKey->token); return redirect()->route('api-keys.index') ->with('success', 'API Key created successfully! Make sure to copy it now - it won\'t be shown again.'); } catch (\Exception $e) { Log::error('Exception creating API key', ['error' => $e->getMessage()]); return back()->with('error', 'Failed to create API key: ' . $e->getMessage()); } } /** * Display the specified API key. */ public function show(string $id) { $apiKey = ApiKey::with(['gatewayUser', 'usageLogs'])->findOrFail($id); // Get usage statistics $stats = [ 'total_requests' => $apiKey->usageLogs()->count(), 'total_cost' => $apiKey->usageLogs()->sum('cost'), 'total_tokens' => $apiKey->usageLogs()->sum('total_tokens'), 'last_30_days_requests' => $apiKey->usageLogs() ->where('timestamp', '>=', now()->subDays(30)) ->count(), ]; // Get recent activity $recentLogs = $apiKey->usageLogs() ->orderByDesc('timestamp') ->limit(20) ->get(); return view('api-keys.show', compact('apiKey', 'stats', 'recentLogs')); } /** * Revoke the specified API key. */ public function revoke(string $id) { try { $apiKey = ApiKey::findOrFail($id); // Delete the API key from database $apiKey->delete(); return redirect()->route('api-keys.index') ->with('success', 'API Key revoked successfully'); } catch (\Exception $e) { Log::error('Exception revoking API key', ['error' => $e->getMessage()]); return back()->with('error', 'Failed to revoke API key: ' . $e->getMessage()); } } /** * Remove the specified API key. */ public function destroy(string $id) { // This is an alias for revoke return $this->revoke($id); } }