CatPtain commited on
Commit
e67695a
·
verified ·
1 Parent(s): be8e331

Upload 3 files

Browse files
Files changed (2) hide show
  1. config-check.php +216 -0
  2. storage.php +161 -18
config-check.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__ . '/storage.php';
3
+
4
+ // 简单的测试认证
5
+ $testAuth = false;
6
+ if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
7
+ $users = StorageConfig::getUsers();
8
+ $testAuth = isset($users[$_SERVER['PHP_AUTH_USER']]) &&
9
+ $users[$_SERVER['PHP_AUTH_USER']] === $_SERVER['PHP_AUTH_PW'];
10
+ }
11
+
12
+ if (!$testAuth) {
13
+ header('WWW-Authenticate: Basic realm="VvvebJs Config Check"');
14
+ header('HTTP/1.0 401 Unauthorized');
15
+ die('Authentication required for config check');
16
+ }
17
+
18
+ $github = StorageConfig::getGitHubConfig();
19
+ $kv = StorageConfig::getKVConfig();
20
+ $storageType = StorageConfig::getStorageType();
21
+
22
+ // 检查配置状态
23
+ function checkConfig() {
24
+ $github = StorageConfig::getGitHubConfig();
25
+ $issues = [];
26
+
27
+ // 检查GitHub Token
28
+ if (empty($github['token']) || $github['token'] === 'YOUR_ACTUAL_GITHUB_TOKEN') {
29
+ $issues[] = [
30
+ 'type' => 'error',
31
+ 'title' => 'GitHub Token 未配置',
32
+ 'message' => 'GITHUB_TOKEN 仍然是占位符或为空,需要设置真实的GitHub Token'
33
+ ];
34
+ }
35
+
36
+ // 检查GitHub基本配置
37
+ if (empty($github['owner'])) {
38
+ $issues[] = [
39
+ 'type' => 'error',
40
+ 'title' => 'GitHub Owner 未配置',
41
+ 'message' => 'GITHUB_OWNER 为空'
42
+ ];
43
+ }
44
+
45
+ if (empty($github['repo'])) {
46
+ $issues[] = [
47
+ 'type' => 'error',
48
+ 'title' => 'GitHub Repo 未配置',
49
+ 'message' => 'GITHUB_REPO 为空'
50
+ ];
51
+ }
52
+
53
+ return $issues;
54
+ }
55
+
56
+ $configIssues = checkConfig();
57
+ ?>
58
+
59
+ <!DOCTYPE html>
60
+ <html lang="en">
61
+ <head>
62
+ <meta charset="utf-8">
63
+ <meta name="viewport" content="width=device-width, initial-scale=1">
64
+ <title>VvvebJs 配置检查</title>
65
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
66
+ <style>
67
+ .config-value { background-color: #f8f9fa; padding: 2px 6px; border-radius: 3px; font-family: monospace; }
68
+ .status-ok { color: #28a745; }
69
+ .status-error { color: #dc3545; }
70
+ .status-warning { color: #ffc107; }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <div class="container mt-5">
75
+ <div class="row">
76
+ <div class="col-md-10 mx-auto">
77
+ <h1 class="mb-4">🔧 VvvebJs 配置检查</h1>
78
+
79
+ <!-- 配置问题检查 -->
80
+ <?php if (!empty($configIssues)): ?>
81
+ <div class="card mb-4">
82
+ <div class="card-header">
83
+ <h3 class="status-error">❌ 发现配置问题</h3>
84
+ </div>
85
+ <div class="card-body">
86
+ <?php foreach ($configIssues as $issue): ?>
87
+ <div class="alert alert-<?= $issue['type'] === 'error' ? 'danger' : 'warning' ?> mb-3">
88
+ <h5><?= htmlspecialchars($issue['title']) ?></h5>
89
+ <p><?= htmlspecialchars($issue['message']) ?></p>
90
+ </div>
91
+ <?php endforeach; ?>
92
+
93
+ <div class="alert alert-info">
94
+ <h5>🔑 如何修复GitHub Token问题:</h5>
95
+ <ol>
96
+ <li>访问 <a href="https://github.com/settings/tokens" target="_blank">GitHub Token 设置页面</a></li>
97
+ <li>点击 "Generate new token (classic)"</li>
98
+ <li>选择 <strong>repo</strong> 权限(包括完整的仓库访问权限)</li>
99
+ <li>复制生成的Token</li>
100
+ <li>在 <code>.env</code> 文件中将 <code>GITHUB_TOKEN=YOUR_ACTUAL_GITHUB_TOKEN</code> 替换为 <code>GITHUB_TOKEN=你的真实Token</code></li>
101
+ </ol>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ <?php else: ?>
106
+ <div class="alert alert-success">
107
+ <h3 class="status-ok">✅ 配置检查通过</h3>
108
+ <p>基本配置项都已正确设置。</p>
109
+ </div>
110
+ <?php endif; ?>
111
+
112
+ <!-- 当前配置详情 -->
113
+ <div class="card mb-4">
114
+ <div class="card-header">
115
+ <h3>📋 当前配置详情</h3>
116
+ </div>
117
+ <div class="card-body">
118
+ <div class="row">
119
+ <div class="col-md-6">
120
+ <h5>存储配置</h5>
121
+ <p><strong>存储类型:</strong> <span class="config-value"><?= htmlspecialchars($storageType) ?></span></p>
122
+
123
+ <h5 class="mt-4">GitHub 配置</h5>
124
+ <p><strong>Token:</strong>
125
+ <span class="config-value <?= empty($github['token']) || $github['token'] === 'YOUR_ACTUAL_GITHUB_TOKEN' ? 'status-error' : 'status-ok' ?>">
126
+ <?php
127
+ if (empty($github['token'])) {
128
+ echo '❌ 未设置';
129
+ } elseif ($github['token'] === 'YOUR_ACTUAL_GITHUB_TOKEN') {
130
+ echo '❌ 占位符';
131
+ } else {
132
+ echo '✅ ' . substr($github['token'], 0, 8) . '...';
133
+ }
134
+ ?>
135
+ </span>
136
+ </p>
137
+ <p><strong>Owner:</strong> <span class="config-value"><?= htmlspecialchars($github['owner']) ?></span></p>
138
+ <p><strong>Repo:</strong> <span class="config-value"><?= htmlspecialchars($github['repo']) ?></span></p>
139
+ <p><strong>Branch:</strong> <span class="config-value"><?= htmlspecialchars($github['branch']) ?></span></p>
140
+ <p><strong>Path:</strong> <span class="config-value"><?= htmlspecialchars($github['path']) ?></span></p>
141
+ </div>
142
+ <div class="col-md-6">
143
+ <h5>EdgeOne KV 配置</h5>
144
+ <p><strong>API Key:</strong>
145
+ <span class="config-value">
146
+ <?= !empty($kv['api_key']) ? '✅ ' . substr($kv['api_key'], 0, 8) . '...' : '❌ 未设置' ?>
147
+ </span>
148
+ </p>
149
+ <p><strong>Secret Key:</strong>
150
+ <span class="config-value">
151
+ <?= !empty($kv['secret_key']) ? '✅ ' . substr($kv['secret_key'], 0, 8) . '...' : '❌ 未设置' ?>
152
+ </span>
153
+ </p>
154
+ <p><strong>Zone ID:</strong> <span class="config-value"><?= htmlspecialchars($kv['zone_id']) ?></span></p>
155
+ <p><strong>Namespace:</strong> <span class="config-value"><?= htmlspecialchars($kv['namespace']) ?></span></p>
156
+ <p><strong>Endpoint:</strong> <span class="config-value"><?= htmlspecialchars($kv['endpoint']) ?></span></p>
157
+
158
+ <h5 class="mt-4">用户配置</h5>
159
+ <p><strong>当前用户:</strong> <span class="config-value"><?= htmlspecialchars(StorageConfig::getCurrentUser()) ?></span></p>
160
+ <p><strong>用户路径:</strong> <span class="config-value"><?= htmlspecialchars(StorageConfig::getUserPath()) ?></span></p>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ </div>
165
+
166
+ <!-- 测试连接 -->
167
+ <div class="card mb-4">
168
+ <div class="card-header">
169
+ <h3>🧪 快速测试</h3>
170
+ </div>
171
+ <div class="card-body">
172
+ <div class="row">
173
+ <div class="col-md-4">
174
+ <a href="github-advanced-test.php" class="btn btn-primary w-100">GitHub 完整测试</a>
175
+ </div>
176
+ <div class="col-md-4">
177
+ <a href="github-test.php" class="btn btn-info w-100">GitHub 基础测试</a>
178
+ </div>
179
+ <div class="col-md-4">
180
+ <a href="editor.html" class="btn btn-success w-100">返回编辑器</a>
181
+ </div>
182
+ </div>
183
+ </div>
184
+ </div>
185
+
186
+ <!-- 环境变量文件状态 -->
187
+ <div class="card">
188
+ <div class="card-header">
189
+ <h3>📄 环境变量文件状态</h3>
190
+ </div>
191
+ <div class="card-body">
192
+ <p><strong>.env 文件:</strong>
193
+ <span class="<?= file_exists(__DIR__ . '/.env') ? 'status-ok' : 'status-error' ?>">
194
+ <?= file_exists(__DIR__ . '/.env') ? '✅ 存在' : '❌ 不存在' ?>
195
+ </span>
196
+ </p>
197
+ <p><strong>.env.example 文件:</strong>
198
+ <span class="<?= file_exists(__DIR__ . '/.env.example') ? 'status-ok' : 'status-warning' ?>">
199
+ <?= file_exists(__DIR__ . '/.env.example') ? '✅ 存在' : '⚠️ 不存在' ?>
200
+ </span>
201
+ </p>
202
+
203
+ <?php if (!file_exists(__DIR__ . '/.env')): ?>
204
+ <div class="alert alert-warning mt-3">
205
+ <h5>⚠️ .env 文件不存在</h5>
206
+ <p>请从 .env.example 复制创建 .env 文件:</p>
207
+ <code>copy .env.example .env</code>
208
+ </div>
209
+ <?php endif; ?>
210
+ </div>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </body>
216
+ </html>
storage.php CHANGED
@@ -126,63 +126,156 @@ class KVStorage {
126
  }
127
 
128
  public function save($key, $content) {
129
- if (empty($this->config['api_key'])) return false;
 
 
 
 
 
 
 
 
130
 
131
  // Add user path to key
132
  $userKey = $this->userPath . $key;
133
 
134
- $url = $this->config['endpoint'] . '/';
 
135
  $params = [
136
- 'Action' => 'ModifyApplicationProxyRule',
137
  'Version' => '2022-09-01',
138
  'Region' => 'ap-beijing',
139
  'ZoneId' => $this->config['zone_id'],
 
140
  'Key' => $userKey,
141
- 'Value' => base64_encode($content)
 
142
  ];
143
 
144
- return $this->makeRequest($url, $params);
 
 
 
 
 
 
 
 
 
145
  }
146
 
147
  public function get($key) {
148
- if (empty($this->config['api_key'])) return false;
 
 
 
149
 
150
  // Add user path to key
151
  $userKey = $this->userPath . $key;
152
 
153
- $url = $this->config['endpoint'] . '/';
154
  $params = [
155
- 'Action' => 'DescribeApplicationProxyDetail',
156
  'Version' => '2022-09-01',
157
  'Region' => 'ap-beijing',
158
  'ZoneId' => $this->config['zone_id'],
 
159
  'Key' => $userKey
160
  ];
161
 
 
 
162
  $result = $this->makeRequest($url, $params);
163
- return $result ? base64_decode($result) : false;
 
 
 
 
 
164
  }
165
 
166
  public function listUserFiles() {
167
- // This would require additional API endpoints to list files
168
- // Implementation depends on the KV storage provider's capabilities
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  return [];
170
  }
171
 
172
  private function makeRequest($url, $params) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  $ch = curl_init();
174
  curl_setopt($ch, CURLOPT_URL, $url);
175
  curl_setopt($ch, CURLOPT_POST, true);
176
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
177
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
178
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
179
- 'Authorization: ' . $this->config['api_key'],
180
- 'Content-Type: application/x-www-form-urlencoded'
181
  ]);
182
 
183
  $result = curl_exec($ch);
 
 
184
  curl_close($ch);
185
- return $result;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  }
187
  }
188
 
@@ -443,14 +536,43 @@ class StorageManager {
443
  // Ensure filename is safe and doesn't contain path traversal
444
  $filename = $this->sanitizeFilename($filename);
445
 
 
 
 
 
446
  $success = false;
 
447
 
448
  if ($this->githubStorage) {
449
- $success = $this->githubStorage->save($filename, $content) || $success;
 
 
 
 
 
 
 
 
 
 
450
  }
451
 
452
  if ($this->kvStorage) {
453
- $success = $this->kvStorage->save($filename, $content) || $success;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  }
455
 
456
  return $success;
@@ -460,16 +582,37 @@ class StorageManager {
460
  // Ensure filename is safe and doesn't contain path traversal
461
  $filename = $this->sanitizeFilename($filename);
462
 
 
 
 
 
463
  if ($this->githubStorage) {
 
464
  $content = $this->githubStorage->get($filename);
465
- if ($content !== false) return $content;
 
 
 
 
 
 
 
466
  }
467
 
468
  if ($this->kvStorage) {
 
469
  $content = $this->kvStorage->get($filename);
470
- if ($content !== false) return $content;
 
 
 
 
 
 
 
471
  }
472
 
 
473
  return false;
474
  }
475
 
 
126
  }
127
 
128
  public function save($key, $content) {
129
+ if (empty($this->config['api_key'])) {
130
+ error_log("KV Save Error: API key is missing");
131
+ return false;
132
+ }
133
+
134
+ if (empty($this->config['zone_id']) || empty($this->config['namespace'])) {
135
+ error_log("KV Save Error: Zone ID or namespace is missing");
136
+ return false;
137
+ }
138
 
139
  // Add user path to key
140
  $userKey = $this->userPath . $key;
141
 
142
+ // Use correct EdgeOne KV API endpoints
143
+ $url = $this->config['endpoint'];
144
  $params = [
145
+ 'Action' => 'CreatePurgeTask', // 这需要根据实际的EdgeOne KV API调整
146
  'Version' => '2022-09-01',
147
  'Region' => 'ap-beijing',
148
  'ZoneId' => $this->config['zone_id'],
149
+ 'Namespace' => $this->config['namespace'],
150
  'Key' => $userKey,
151
+ 'Value' => base64_encode($content),
152
+ 'TTL' => 86400 // 24 hours TTL
153
  ];
154
 
155
+ error_log("KV Save Debug: Attempting to save key '$userKey' to namespace '{$this->config['namespace']}'");
156
+
157
+ $result = $this->makeRequest($url, $params);
158
+ if ($result) {
159
+ error_log("KV Save Success: Key saved successfully");
160
+ return true;
161
+ } else {
162
+ error_log("KV Save Error: API request failed");
163
+ return false;
164
+ }
165
  }
166
 
167
  public function get($key) {
168
+ if (empty($this->config['api_key'])) {
169
+ error_log("KV Get Error: API key is missing");
170
+ return false;
171
+ }
172
 
173
  // Add user path to key
174
  $userKey = $this->userPath . $key;
175
 
176
+ $url = $this->config['endpoint'];
177
  $params = [
178
+ 'Action' => 'DescribeOriginGroup', // 这需要根据实际的EdgeOne KV API调整
179
  'Version' => '2022-09-01',
180
  'Region' => 'ap-beijing',
181
  'ZoneId' => $this->config['zone_id'],
182
+ 'Namespace' => $this->config['namespace'],
183
  'Key' => $userKey
184
  ];
185
 
186
+ error_log("KV Get Debug: Attempting to get key '$userKey' from namespace '{$this->config['namespace']}'");
187
+
188
  $result = $this->makeRequest($url, $params);
189
+ if ($result && isset($result['Value'])) {
190
+ return base64_decode($result['Value']);
191
+ }
192
+
193
+ error_log("KV Get Error: Key not found or API request failed");
194
+ return false;
195
  }
196
 
197
  public function listUserFiles() {
198
+ if (empty($this->config['api_key'])) return [];
199
+
200
+ $url = $this->config['endpoint'];
201
+ $params = [
202
+ 'Action' => 'DescribeOriginGroups', // 这需要根据实际的EdgeOne KV API调整
203
+ 'Version' => '2022-09-01',
204
+ 'Region' => 'ap-beijing',
205
+ 'ZoneId' => $this->config['zone_id'],
206
+ 'Namespace' => $this->config['namespace'],
207
+ 'Prefix' => $this->userPath
208
+ ];
209
+
210
+ $result = $this->makeRequest($url, $params);
211
+ if ($result && isset($result['Keys']) && is_array($result['Keys'])) {
212
+ $files = [];
213
+ foreach ($result['Keys'] as $item) {
214
+ if (isset($item['Key'])) {
215
+ $relativePath = str_replace($this->userPath, '', $item['Key']);
216
+ $files[] = [
217
+ 'name' => basename($relativePath),
218
+ 'path' => $relativePath,
219
+ 'size' => $item['Size'] ?? 0,
220
+ 'url' => null
221
+ ];
222
+ }
223
+ }
224
+ return $files;
225
+ }
226
+
227
  return [];
228
  }
229
 
230
  private function makeRequest($url, $params) {
231
+ // 添加通用的腾讯云API参数
232
+ $commonParams = [
233
+ 'Timestamp' => time(),
234
+ 'Nonce' => rand(10000, 99999),
235
+ 'SecretId' => $this->config['api_key'],
236
+ 'SignatureMethod' => 'HmacSHA256'
237
+ ];
238
+
239
+ $params = array_merge($params, $commonParams);
240
+
241
+ // 生成签名 (这是简化版本,实际需要按照腾讯云API签名规范)
242
+ ksort($params);
243
+ $queryString = http_build_query($params);
244
+ $signature = hash_hmac('sha256', $queryString, $this->config['secret_key'], true);
245
+ $params['Signature'] = base64_encode($signature);
246
+
247
  $ch = curl_init();
248
  curl_setopt($ch, CURLOPT_URL, $url);
249
  curl_setopt($ch, CURLOPT_POST, true);
250
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
251
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
252
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
253
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
254
+ 'Content-Type: application/x-www-form-urlencoded',
255
+ 'User-Agent: VvvebJs-WebBuilder/1.0'
256
  ]);
257
 
258
  $result = curl_exec($ch);
259
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
260
+ $error = curl_error($ch);
261
  curl_close($ch);
262
+
263
+ if ($error) {
264
+ error_log("KV API cURL Error: $error");
265
+ return false;
266
+ }
267
+
268
+ if ($httpCode >= 200 && $httpCode < 300) {
269
+ $decoded = json_decode($result, true);
270
+ if (json_last_error() === JSON_ERROR_NONE) {
271
+ return $decoded;
272
+ }
273
+ error_log("KV API JSON Error: " . json_last_error_msg());
274
+ } else {
275
+ error_log("KV API HTTP Error: $httpCode - Response: $result");
276
+ }
277
+
278
+ return false;
279
  }
280
  }
281
 
 
536
  // Ensure filename is safe and doesn't contain path traversal
537
  $filename = $this->sanitizeFilename($filename);
538
 
539
+ error_log("StorageManager saveFile: Starting save for file '$filename'");
540
+ error_log("StorageManager saveFile: Storage type is '{$this->storageType}'");
541
+ error_log("StorageManager saveFile: Current user is '{$this->currentUser}'");
542
+
543
  $success = false;
544
+ $errors = [];
545
 
546
  if ($this->githubStorage) {
547
+ error_log("StorageManager saveFile: Attempting GitHub save...");
548
+ $githubSuccess = $this->githubStorage->save($filename, $content);
549
+ if ($githubSuccess) {
550
+ error_log("StorageManager saveFile: GitHub save SUCCESS");
551
+ $success = true;
552
+ } else {
553
+ error_log("StorageManager saveFile: GitHub save FAILED");
554
+ $errors[] = "GitHub save failed";
555
+ }
556
+ } else {
557
+ error_log("StorageManager saveFile: GitHub storage not configured");
558
  }
559
 
560
  if ($this->kvStorage) {
561
+ error_log("StorageManager saveFile: Attempting KV save...");
562
+ $kvSuccess = $this->kvStorage->save($filename, $content);
563
+ if ($kvSuccess) {
564
+ error_log("StorageManager saveFile: KV save SUCCESS");
565
+ $success = true;
566
+ } else {
567
+ error_log("StorageManager saveFile: KV save FAILED");
568
+ $errors[] = "KV save failed";
569
+ }
570
+ } else {
571
+ error_log("StorageManager saveFile: KV storage not configured");
572
+ }
573
+
574
+ if (!$success && !empty($errors)) {
575
+ error_log("StorageManager saveFile: All saves failed: " . implode(", ", $errors));
576
  }
577
 
578
  return $success;
 
582
  // Ensure filename is safe and doesn't contain path traversal
583
  $filename = $this->sanitizeFilename($filename);
584
 
585
+ error_log("StorageManager getFile: Starting load for file '$filename'");
586
+ error_log("StorageManager getFile: Storage type is '{$this->storageType}'");
587
+ error_log("StorageManager getFile: Current user is '{$this->currentUser}'");
588
+
589
  if ($this->githubStorage) {
590
+ error_log("StorageManager getFile: Attempting GitHub load...");
591
  $content = $this->githubStorage->get($filename);
592
+ if ($content !== false) {
593
+ error_log("StorageManager getFile: GitHub load SUCCESS");
594
+ return $content;
595
+ } else {
596
+ error_log("StorageManager getFile: GitHub load FAILED");
597
+ }
598
+ } else {
599
+ error_log("StorageManager getFile: GitHub storage not configured");
600
  }
601
 
602
  if ($this->kvStorage) {
603
+ error_log("StorageManager getFile: Attempting KV load...");
604
  $content = $this->kvStorage->get($filename);
605
+ if ($content !== false) {
606
+ error_log("StorageManager getFile: KV load SUCCESS");
607
+ return $content;
608
+ } else {
609
+ error_log("StorageManager getFile: KV load FAILED");
610
+ }
611
+ } else {
612
+ error_log("StorageManager getFile: KV storage not configured");
613
  }
614
 
615
+ error_log("StorageManager getFile: All load attempts failed");
616
  return false;
617
  }
618