VPSHUB/config_add.php
2026-05-30 09:34:47 +08:00

425 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* VPS配置管理页面
* 用于添加和管理多平台VPS配置
*/
require_once __DIR__ . '/app/db_helper.php';
require_once __DIR__ . '/mofangidc.php';
// Token文件路径(存储API_PASS)
$tokenFile = __DIR__ . '/app/pass.php'; # 更新路径为app/pass.php避免与其他配置文件混淆
// 检查是否首次访问(需要设置API_PASS)
$needSetup = !file_exists($tokenFile);
// 处理API_PASS设置
if ($needSetup && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['setup_pass'])) {
$apiPass = trim($_POST['api_pass']);
if (empty($apiPass)) {
$setupError = '密码不能为空!';
} elseif (strlen($apiPass) < 8) {
$setupError = '密码至少8位';
} elseif (!preg_match('/^[a-zA-Z0-9]+$/', $apiPass)) {
$setupError = '密码只能包含字母和数字!';
} else {
// 保存API_PASS
$content = "<?php\n";
$content .= "// API访问密码 - 自动生成\n";
$content .= "// 警告: 不要手动修改此文件\n\n";
$content .= "define('API_PASS', '" . addslashes($apiPass) . "');\n";
$content .= "?>\n";
if (file_put_contents($tokenFile, $content)) {
chmod($tokenFile, 0600);
header('Location: config_add.php?pass=' . urlencode($apiPass));
exit;
} else {
$setupError = '保存失败,请检查目录权限!';
}
}
}
// 如果需要设置密码,显示设置页面
if ($needSetup) {
?>n
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="./static/favicon.ico" type="image/x-icon">
<link href="./static/initial.css" rel="stylesheet" type="text/css">
<title>初始设置 - VPS Hub</title>
</head>
<body>
<div class="config-container">
<div class="config-header">
<h1>🔐 初始设置</h1>
<p>请设置管理面板的访问密码</p>
</div>
<?php if (isset($setupError)): ?>
<div class="error-message">
❌ <?php echo htmlspecialchars($setupError); ?>
</div>
<?php endif; ?>
<div class="info-box">
💡 提示:此密码用于保护配置管理页面的访问权限。<br>
密码要求至少8位只能包含字母(a-z,A-Z)和数字(0-9)
</div>
<form method="POST" onsubmit="return validatePassword()">
<div class="form-group">
<label for="api_pass">设置访问密码</label>
<input type="password" id="api_pass" name="api_pass" required
placeholder="至少8位字母和数字"
pattern="[a-zA-Z0-9]{8,}"
title="至少8位只能包含字母和数字">
</div>
<button type="submit" name="setup_pass" class="btn-submit">
✅ 保存并继续
</button>
</form>
</div>
<script>
function validatePassword() {
var password = document.getElementById('api_pass').value;
if (password.length < 8) {
alert('密码至少需要8位');
return false;
}
if (!/^[a-zA-Z0-9]+$/.test(password)) {
alert('密码只能包含字母和数字!');
return false;
}
return true;
}
</script>
</body>
</html>
<?php
exit;
}
// 加载API_PASS
if (file_exists($tokenFile)) {
include $tokenFile;
}
// 验证pass参数
$pass = isset($_GET['pass']) ? $_GET['pass'] : '';
if (!defined('API_PASS') || $pass !== API_PASS) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['status' => 403, 'msg' => '访问密码错误'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
// 处理添加配置
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['add_config'])) {
$apiLabel = trim($_POST['api_label']);
$siteType = trim($_POST['site_type']);
$siteUrl = trim($_POST['site_url']);
$account = trim($_POST['account']);
$apiKey = trim($_POST['api_key']);
$autoMonitor = isset($_POST['auto_monitor']) ? 1 : 0;
if (empty($apiLabel) || empty($siteType) || empty($siteUrl) || empty($account) || empty($apiKey)) {
$message = '<div class="error-message">❌ API标识、网站类型、网站链接、账户和密钥不能为空</div>';
} else {
// 验证URL格式不允许包含路径
$parsedUrl = parse_url($siteUrl);
if (!$parsedUrl || !isset($parsedUrl['scheme']) || !isset($parsedUrl['host'])) {
$message = '<div class="error-message">❌ 网站链接格式错误请输入完整的URL例如: https://www.example.com</div>';
} elseif (isset($parsedUrl['path']) && $parsedUrl['path'] !== '/') {
$message = '<div class="error-message">❌ 网站链接严禁包含路径部分!只允许输入根域名(例如: https://www.example.com不要添加 /v1、/api 等路径</div>';
} else {
$db = getVpsDB();
// 检查API标识是否已存在
$existingConfig = $db->queryOne('SELECT id FROM configs WHERE api_label = ?', [$apiLabel]);
if ($existingConfig) {
$message = '<div class="error-message">❌ API标识 "' . htmlspecialchars($apiLabel) . '" 已存在,请使用其他标识!</div>';
} else {
$configId = $db->insert(
'INSERT INTO configs (api_label, site_type, site_url, account, api_key, auto_monitor) VALUES (?, ?, ?, ?, ?, ?)',
[$apiLabel, $siteType, $siteUrl, $account, $apiKey, $autoMonitor]
);
if ($configId) {
$message = '<div class="success-message">✅ 配置添加成功ID: ' . $configId . '</div>';
// 如果是首次添加配置提示运行install.sh
$configCount = $db->queryOne('SELECT COUNT(*) as count FROM configs')['count'];
if ($configCount == 1) {
$message .= '<div class="info-box">💡 这是第一个配置,请运行 <code>app/install.sh</code> 安装监控服务</div>';
// 尝试自动执行install.sh需要PHP有执行权限
$installScript = __DIR__ . '/app/install.sh';
if (file_exists($installScript)) {
// 检查exec函数是否可用
if (!function_exists('exec')) {
$message .= '<div class="warning-message">⚠️ exec函数被禁用无法自动安装监控服务。请手动执行: sudo bash app/install.sh</div>';
} else {
// 先设置可执行权限
chmod($installScript, 0755);
// 执行安装脚本
$output = [];
$returnVar = 0;
exec("bash {$installScript} 2>&1", $output, $returnVar);
if ($returnVar === 0) {
$message .= '<div class="success-message">✅ 监控服务已自动安装并启动</div>';
} else {
$message .= '<div class="error-message">⚠️ 自动安装失败,请手动执行: sudo bash app/install.sh</div>';
// 输出错误信息以便调试
if (!empty($output)) {
$message .= '<details><summary>查看错误详情</summary><pre>' . htmlspecialchars(implode("\n", $output)) . '</pre></details>';
}
}
}
}
}
// 自动刷新VPS列表
if ($siteType === 'mofang') {
refreshVpsListForConfig($configId);
$message .= '<div class="info-box">✅ 已自动获取VPS列表</div>';
}
} else {
$message = '<div class="error-message">❌ 配置添加失败!</div>';
}
}
}
}
} elseif (isset($_POST['delete_config'])) {
$configId = intval($_POST['config_id']);
$db = getVpsDB();
$db->execute('DELETE FROM configs WHERE id = ?', [$configId]);
$message = '<div class="success-message">✅ 配置已删除</div>';
}
}
// 获取所有配置
$db = getVpsDB();
$configs = $db->query('SELECT * FROM configs ORDER BY id');
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="./static/favicon.ico" type="image/x-icon">
<link href="./static/style.css" rel="stylesheet" type="text/css">
<title>配置管理 - VPS Hub</title>
<style>
.config-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.config-table th, .config-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.config-table th {
background-color: #f5f5f5;
font-weight: bold;
}
.config-table tr:hover {
background-color: #f9f9f9;
}
.btn-delete {
background-color: #dc3545;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
}
.btn-delete:hover {
background-color: #c82333;
}
.form-section {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.form-row {
display: flex;
gap: 15px;
margin-bottom: 15px;
flex-wrap: wrap;
}
.form-group-inline {
flex: 1;
min-width: 200px;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 8px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>⚙️ VPS配置管理</h1>
<p>添加和管理多平台VPS配置</p>
<a href="index.php?pass=<?php echo urlencode($pass); ?>" class="btn" style="float: right; margin-top: -60px;">返回首页</a>
</div>
<div class="content">
<?php echo $message; ?>
<!-- 添加配置表单 -->
<div class="form-section">
<h2> 添加新配置</h2>
<form method="POST">
<div class="form-row">
<div class="form-group-inline">
<label>API标识 * <small>(例如: 核云、阿里云主账号)</small></label>
<input type="text" name="api_label" required placeholder="输入唯一标识" pattern="[a-zA-Z0-9\u4e00-\u9fa5_\-]+" title="只能包含字母、数字、中文、下划线和连字符">
</div>
</div>
<div class="form-row">
<div class="form-group-inline">
<label>网站类型 *</label>
<select name="site_type" required onchange="toggleSiteUrl(this.value)">
<option value="mofang">魔方平台</option>
<option value="aliyun">阿里云(暂不支持)</option>
<option value="tencent">腾讯云(暂不支持)</option>
</select>
</div>
<div class="form-group-inline" id="site_url_group">
<label>网站链接/API地址 *</label>
<input type="url" name="site_url" required placeholder="https://www.example.com" id="site_url_input">
<small style="color: #dc3545;">⚠️ 严禁包含路径部分(如 /v1、/api只允许根域名</small>
</div>
</div>
<div class="form-row">
<div class="form-group-inline">
<label>账户 * <small>(邮箱或手机号)</small></label>
<input type="text" name="account" required placeholder="输入账户">
</div>
<div class="form-group-inline">
<label>API密钥 *</label>
<input type="password" name="api_key" required placeholder="输入API密钥">
</div>
</div>
<div class="form-row">
<div class="checkbox-group">
<input type="checkbox" name="auto_monitor" id="auto_monitor" checked>
<label for="auto_monitor">开启自动开机监控</label>
</div>
</div>
<button type="submit" name="add_config" class="btn btn-success">
✅ 添加配置
</button>
</form>
</div>
<!-- 配置列表 -->
<div class="form-section">
<h2>📋 现有配置</h2>
<?php if (empty($configs)): ?>
<p style="color: #999; text-align: center; padding: 40px;">暂无配置,请添加第一个配置</p>
<?php else: ?>
<table class="config-table">
<thead>
<tr>
<th>序号</th>
<th>API标识</th>
<th>网站类型</th>
<th>网站链接</th>
<th>账户</th>
<th>自动监控</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($configs as $config): ?>
<tr>
<td><?php echo $config['id']; ?></td>
<td><strong><?php echo htmlspecialchars($config['api_label']); ?></strong></td>
<td>
<?php
$typeMap = [
'mofang' => '魔方',
'aliyun' => '阿里云',
'tencent' => '腾讯云'
];
echo $typeMap[$config['site_type']] ?? $config['site_type'];
?>
</td>
<td><?php echo htmlspecialchars($config['site_url'] ?? '-'); ?></td>
<td><?php echo htmlspecialchars($config['account']); ?></td>
<td>
<?php echo $config['auto_monitor'] ? '✅ 开启' : '❌ 关闭'; ?>
</td>
<td><?php echo date('Y-m-d H:i', strtotime($config['created_at'])); ?></td>
<td>
<form method="POST" style="display: inline;"
onsubmit="return confirm('确认删除此配置?')">
<input type="hidden" name="config_id" value="<?php echo $config['id']; ?>">
<button type="submit" name="delete_config" class="btn-delete">
🗑️ 删除
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
<center><div class="copyright">
© 2026 Gaming Master Cybersecurity |
<a href="https://git.masonliu.com/MasonLiu/VPSHUB" target="_blank">MasonLiu In Gitea</a>
</div></center>
</div>
<script>
function toggleSiteUrl(siteType) {
const urlGroup = document.getElementById('site_url_group');
const urlInput = document.getElementById('site_url_input');
if (siteType === 'mofang') {
urlInput.placeholder = '例如: https://www.heyunidc.cn';
} else if (siteType === 'aliyun') {
urlInput.placeholder = '例如: https://ecs.aliyuncs.com';
} else if (siteType === 'tencent') {
urlInput.placeholder = '例如: https://cvm.tencentcloudapi.com';
} else {
urlInput.placeholder = '例如: https://www.example.com';
}
}
</script>
</body>
</html>