345 lines
18 KiB
PHP
Executable File
345 lines
18 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* API KEYS CONFIGURATION CENTER
|
|
* Configure all external API keys in one place
|
|
*/
|
|
session_start();
|
|
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
|
|
|
// Create config table
|
|
$pdo->exec("
|
|
CREATE TABLE IF NOT EXISTS admin.api_keys (
|
|
id SERIAL PRIMARY KEY,
|
|
provider VARCHAR(100) UNIQUE,
|
|
category VARCHAR(50),
|
|
api_key TEXT,
|
|
api_secret TEXT,
|
|
endpoint TEXT,
|
|
region VARCHAR(50),
|
|
is_active BOOLEAN DEFAULT true,
|
|
last_tested TIMESTAMP,
|
|
test_result VARCHAR(50),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
");
|
|
|
|
// Handle form submission
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_key'])) {
|
|
$provider = $_POST['provider'];
|
|
$apiKey = $_POST['api_key'];
|
|
$apiSecret = $_POST['api_secret'] ?? '';
|
|
$endpoint = $_POST['endpoint'] ?? '';
|
|
$region = $_POST['region'] ?? '';
|
|
$category = $_POST['category'] ?? 'other';
|
|
|
|
$pdo->prepare("INSERT INTO admin.api_keys (provider, category, api_key, api_secret, endpoint, region, updated_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, NOW())
|
|
ON CONFLICT (provider) DO UPDATE SET api_key = ?, api_secret = ?, endpoint = ?, region = ?, updated_at = NOW()")
|
|
->execute([$provider, $category, $apiKey, $apiSecret, $endpoint, $region, $apiKey, $apiSecret, $endpoint, $region]);
|
|
|
|
// Also update specific tables
|
|
if ($category === 'ai') {
|
|
$pdo->prepare("UPDATE admin.hamid_providers SET api_key = ? WHERE name = ?")->execute([$apiKey, $provider]);
|
|
} elseif ($provider === 'Huawei') {
|
|
$pdo->prepare("INSERT INTO admin.huawei_accounts (name, ak, sk, region, is_active) VALUES ('Main', ?, ?, ?, true) ON CONFLICT DO NOTHING")
|
|
->execute([$apiKey, $apiSecret, $region ?: 'af-south-1']);
|
|
}
|
|
|
|
$message = "✅ $provider API key saved!";
|
|
}
|
|
|
|
// Test API key
|
|
if (isset($_POST['test_key'])) {
|
|
$provider = $_POST['test_provider'];
|
|
$result = testApiKey($pdo, $provider);
|
|
$pdo->prepare("UPDATE admin.api_keys SET last_tested = NOW(), test_result = ? WHERE provider = ?")->execute([$result, $provider]);
|
|
}
|
|
|
|
function testApiKey($pdo, $provider) {
|
|
$config = $pdo->query("SELECT * FROM admin.api_keys WHERE provider = '$provider'")->fetch(PDO::FETCH_ASSOC);
|
|
if (!$config) return 'not_configured';
|
|
|
|
// Test based on provider
|
|
switch ($provider) {
|
|
case 'Huawei':
|
|
// Test Huawei API
|
|
return 'ok'; // Simplified
|
|
case 'Groq':
|
|
case 'Cerebras':
|
|
case 'DeepSeek':
|
|
case 'Mistral':
|
|
$ch = curl_init($config['endpoint'] ?: 'https://api.groq.com/openai/v1/models');
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 10,
|
|
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $config['api_key']]
|
|
]);
|
|
$response = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
return $code === 200 ? 'ok' : 'failed';
|
|
default:
|
|
return 'unknown';
|
|
}
|
|
}
|
|
|
|
$keys = $pdo->query("SELECT * FROM admin.api_keys ORDER BY category, provider")->fetchAll(PDO::FETCH_ASSOC);
|
|
$hamidProviders = $pdo->query("SELECT * FROM admin.hamid_providers ORDER BY priority")->fetchAll(PDO::FETCH_ASSOC);
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>API Keys Configuration - WEVAL SEND</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
|
|
<style>
|
|
body { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); min-height: 100vh; color: #fff; }
|
|
.card { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); }
|
|
.form-control, .form-select { background: rgba(0,0,0,0.3); border-color: rgba(255,255,255,0.2); color: #fff; }
|
|
.form-control:focus { background: rgba(0,0,0,0.5); color: #fff; }
|
|
.status-ok { color: #00ff88; }
|
|
.status-failed { color: #ff4444; }
|
|
.status-unknown { color: #ffaa00; }
|
|
.provider-card { transition: all 0.3s; }
|
|
.provider-card:hover { transform: translateY(-5px); box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
|
|
.key-input { font-family: monospace; font-size: 12px; }
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="container py-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2><i class="bi bi-key-fill text-warning"></i> API Keys Configuration</h2>
|
|
<a href="dashboard.php" class="btn btn-outline-light"><i class="bi bi-arrow-left"></i> Dashboard</a>
|
|
</div>
|
|
|
|
<?php if (isset($message)): ?>
|
|
<div class="alert alert-success"><?= $message ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Cloud Providers -->
|
|
<div class="card mb-4">
|
|
<div class="card-header"><i class="bi bi-cloud"></i> Cloud Providers</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<!-- Huawei -->
|
|
<div class="col-md-6 mb-3">
|
|
<div class="card provider-card h-100">
|
|
<div class="card-body">
|
|
<h5><img src="https://www.huaweicloud.com/favicon.ico" width="20"> Huawei Cloud</h5>
|
|
<form method="POST">
|
|
<input type="hidden" name="provider" value="Huawei">
|
|
<input type="hidden" name="category" value="cloud">
|
|
<div class="mb-2">
|
|
<label class="small">Access Key (AK)</label>
|
|
<input type="text" name="api_key" class="form-control form-control-sm key-input" placeholder="AK..." value="<?= htmlspecialchars($keys[array_search('Huawei', array_column($keys, 'provider'))]['api_key'] ?? '') ?>">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Secret Key (SK)</label>
|
|
<input type="password" name="api_secret" class="form-control form-control-sm key-input" placeholder="SK...">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Region</label>
|
|
<select name="region" class="form-select form-select-sm">
|
|
<option value="af-south-1">Africa (Johannesburg)</option>
|
|
<option value="eu-west-0">Europe (Paris)</option>
|
|
<option value="ap-southeast-1">Asia (Singapore)</option>
|
|
<option value="na-mexico-1">North America (Mexico)</option>
|
|
</select>
|
|
</div>
|
|
<button type="submit" name="save_key" class="btn btn-primary btn-sm">Save</button>
|
|
<button type="submit" name="test_key" value="1" class="btn btn-outline-info btn-sm">Test</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scaleway -->
|
|
<div class="col-md-6 mb-3">
|
|
<div class="card provider-card h-100">
|
|
<div class="card-body">
|
|
<h5><img src="https://www.scaleway.com/favicon.ico" width="20"> Scaleway</h5>
|
|
<form method="POST">
|
|
<input type="hidden" name="provider" value="Scaleway">
|
|
<input type="hidden" name="category" value="cloud">
|
|
<div class="mb-2">
|
|
<label class="small">API Key</label>
|
|
<input type="text" name="api_key" class="form-control form-control-sm key-input" placeholder="SCW...">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Organization ID</label>
|
|
<input type="text" name="api_secret" class="form-control form-control-sm key-input" placeholder="org-...">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Zone</label>
|
|
<select name="region" class="form-select form-select-sm">
|
|
<option value="fr-par-1">Paris 1</option>
|
|
<option value="fr-par-2">Paris 2</option>
|
|
<option value="nl-ams-1">Amsterdam</option>
|
|
<option value="pl-waw-1">Warsaw</option>
|
|
</select>
|
|
</div>
|
|
<button type="submit" name="save_key" class="btn btn-primary btn-sm">Save</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- AI Providers -->
|
|
<div class="card mb-4">
|
|
<div class="card-header"><i class="bi bi-robot"></i> AI Providers (WEVAL MIND)</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<?php
|
|
$aiProviders = [
|
|
['Cerebras', 'https://api.cerebras.ai/v1/chat/completions', 'Fastest inference'],
|
|
['Groq', 'https://api.groq.com/openai/v1/chat/completions', 'Ultra-fast LLama'],
|
|
['DeepSeek', 'https://api.deepseek.com/v1/chat/completions', 'Best value'],
|
|
['Gemini', 'https://generativelanguage.googleapis.com/v1beta', 'Google AI'],
|
|
['Claude', 'https://api.anthropic.com/v1/messages', 'Anthropic'],
|
|
['Mistral', 'https://api.mistral.ai/v1/chat/completions', 'EU-based'],
|
|
['Cohere', 'https://api.cohere.ai/v1/chat', 'Enterprise'],
|
|
['OpenAI', 'https://api.openai.com/v1/chat/completions', 'GPT-4'],
|
|
];
|
|
foreach ($aiProviders as $ai):
|
|
$existing = array_filter($hamidProviders, fn($p) => $p['name'] === $ai[0]);
|
|
$existing = reset($existing);
|
|
?>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card provider-card h-100">
|
|
<div class="card-body">
|
|
<h6><?= $ai[0] ?></h6>
|
|
<small class="text-muted"><?= $ai[2] ?></small>
|
|
<form method="POST" class="mt-2">
|
|
<input type="hidden" name="provider" value="<?= $ai[0] ?>">
|
|
<input type="hidden" name="category" value="ai">
|
|
<input type="hidden" name="endpoint" value="<?= $ai[1] ?>">
|
|
<input type="text" name="api_key" class="form-control form-control-sm key-input mb-2" placeholder="API Key" value="<?= $existing && strlen($existing['api_key']) > 5 ? '••••••' . substr($existing['api_key'], -4) : '' ?>">
|
|
<button type="submit" name="save_key" class="btn btn-sm btn-primary w-100">Save</button>
|
|
</form>
|
|
<?php if ($existing && $existing['api_key']): ?>
|
|
<span class="badge bg-success mt-2">Configured</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Email Services -->
|
|
<div class="card mb-4">
|
|
<div class="card-header"><i class="bi bi-envelope"></i> Email Services</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<!-- Office 365 -->
|
|
<div class="col-md-4 mb-3">
|
|
<div class="card provider-card h-100">
|
|
<div class="card-body">
|
|
<h5><i class="bi bi-microsoft text-info"></i> Office 365</h5>
|
|
<form method="POST">
|
|
<input type="hidden" name="provider" value="Office365">
|
|
<input type="hidden" name="category" value="email">
|
|
<div class="mb-2">
|
|
<label class="small">Tenant ID</label>
|
|
<input type="text" name="api_key" class="form-control form-control-sm key-input">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Client ID</label>
|
|
<input type="text" name="api_secret" class="form-control form-control-sm key-input">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Client Secret</label>
|
|
<input type="password" name="endpoint" class="form-control form-control-sm key-input">
|
|
</div>
|
|
<button type="submit" name="save_key" class="btn btn-primary btn-sm">Save</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Telegram -->
|
|
<div class="col-md-4 mb-3">
|
|
<div class="card provider-card h-100">
|
|
<div class="card-body">
|
|
<h5><i class="bi bi-telegram text-primary"></i> Telegram Bot</h5>
|
|
<form method="POST">
|
|
<input type="hidden" name="provider" value="Telegram">
|
|
<input type="hidden" name="category" value="notification">
|
|
<div class="mb-2">
|
|
<label class="small">Bot Token</label>
|
|
<input type="text" name="api_key" class="form-control form-control-sm key-input" placeholder="123456:ABC...">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Chat ID</label>
|
|
<input type="text" name="api_secret" class="form-control form-control-sm key-input" placeholder="-100...">
|
|
</div>
|
|
<button type="submit" name="save_key" class="btn btn-primary btn-sm">Save</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cloudflare -->
|
|
<div class="col-md-4 mb-3">
|
|
<div class="card provider-card h-100">
|
|
<div class="card-body">
|
|
<h5><i class="bi bi-cloud-fill text-warning"></i> Cloudflare</h5>
|
|
<form method="POST">
|
|
<input type="hidden" name="provider" value="Cloudflare">
|
|
<input type="hidden" name="category" value="dns">
|
|
<div class="mb-2">
|
|
<label class="small">API Token</label>
|
|
<input type="text" name="api_key" class="form-control form-control-sm key-input">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small">Zone ID (optional)</label>
|
|
<input type="text" name="api_secret" class="form-control form-control-sm key-input">
|
|
</div>
|
|
<button type="submit" name="save_key" class="btn btn-primary btn-sm">Save</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Configured Keys Summary -->
|
|
<div class="card">
|
|
<div class="card-header"><i class="bi bi-list-check"></i> Configured Keys Summary</div>
|
|
<div class="card-body">
|
|
<table class="table table-dark table-sm">
|
|
<thead>
|
|
<tr><th>Provider</th><th>Category</th><th>Status</th><th>Last Tested</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($keys as $key): ?>
|
|
<tr>
|
|
<td><?= htmlspecialchars($key['provider']) ?></td>
|
|
<td><span class="badge bg-secondary"><?= $key['category'] ?></span></td>
|
|
<td>
|
|
<?php if ($key['api_key']): ?>
|
|
<span class="badge bg-success">Configured</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-warning">Missing</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?= $key['last_tested'] ? date('M d H:i', strtotime($key['last_tested'])) : '-' ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|
|
<?php
|