diff --git a/dashboard/public/index.html b/dashboard/public/index.html index 8ccaa5d0657a4dcdddfbe0935349f1534d22256a..ca06a8a7cbaf41bfd8bed0674ca4fea03c984cfe 100644 --- a/dashboard/public/index.html +++ b/dashboard/public/index.html @@ -1,71 +1,71 @@ - +
-Key Types
-Admin Key - full management permissions
-Regular Key - server monitoring and command access
+密钥类型
+Admin Key - 拥有完整管理权限
+Regular Key - 服务器监测与命令访问
0
0
密钥创建成功!
-名称: ${keyData.name}
-类型: ${keyData.isSuperKey ? 'SuperKey' : '普通密钥'}
-Failed to load keys.
'; } } catch (error) { - console.error('Failed to load keys:', error); + adminKeysList.innerHTML = `Failed to load keys: ${error.message}
`; } } -async function loadRegularServerKeys() { +async function loadUserServerKeys() { + if (!userKeysList || !apiKey) { + return; + } try { const response = await fetch(`${API_URL}/manage/keys/server-keys`, { - headers: { 'Authorization': `Bearer ${superKey}` } + headers: authHeaders(apiKey) }); - + if (response.ok) { - const serverKeys = await response.json(); - renderServerKeys(serverKeys); + const keys = await response.json(); + renderUserServerKeys(keys); } else { - document.getElementById('keys-list').innerHTML = '无法加载Server Key列表
'; + userKeysList.innerHTML = 'Failed to load server keys.
'; } } catch (error) { - console.error('Failed to load server keys:', error); - document.getElementById('keys-list').innerHTML = '无法加载Server Key列表
'; + userKeysList.innerHTML = `Failed to load server keys: ${error.message}
`; } } -function renderServerKeys(keys) { - const keysList = document.getElementById('keys-list'); - - if (keys.length === 0) { - keysList.innerHTML = '暂无关联的Server Key
'; +function renderAdminKeys(keys) { + if (!adminKeysList) { return; } - - keysList.innerHTML = keys.map(key => ` -No API keys found.
'; + return; + } + + adminKeysList.innerHTML = keys.map((key) => ` +ID: ${key.id}
-前缀: ${key.keyPrefix}
- ${key.serverId ? `服务器ID: ${key.serverId}
` : ''} -创建时间: ${new Date(key.createdAt).toLocaleString('zh-CN')}
-最后使用: ${key.lastUsed ? new Date(key.lastUsed).toLocaleString('zh-CN') : '从未使用'}
+Prefix: ${key.keyPrefix}
+ ${key.serverId ? `Server ID: ${key.serverId}
` : ''} +Created: ${new Date(key.createdAt).toLocaleString()}
+Last Used: ${key.lastUsed ? new Date(key.lastUsed).toLocaleString() : 'Never'}
暂无API密钥
'; +function renderUserServerKeys(keys) { + if (!userKeysList) { return; } - - keysList.innerHTML = keys.map(key => ` -No server keys available.
'; + return; + } + + userKeysList.innerHTML = keys.map((key) => ` +ID: ${key.id}
-前缀: ${key.keyPrefix}
- ${key.serverId ? `服务器ID: ${key.serverId}
` : ''} -创建时间: ${new Date(key.createdAt).toLocaleString('zh-CN')}
-最后使用: ${key.lastUsed ? new Date(key.lastUsed).toLocaleString('zh-CN') : '从未使用'}
+Prefix: ${key.keyPrefix}
+ ${key.serverId ? `Server ID: ${key.serverId}
` : ''} +Created: ${new Date(key.createdAt).toLocaleString()}
+Last Used: ${key.lastUsed ? new Date(key.lastUsed).toLocaleString() : 'Never'}
Regular Key
+Name: ${payload.regularKey.name}
+Type: ${payload.regularKey.keyType}
+ID: ${payload.regularKey.id}
+Key: ${payload.regularKey.key}
+Server Key
+Name: ${payload.serverKey.name}
+Type: ${payload.serverKey.keyType}
+ID: ${payload.serverKey.id}
+Key: ${payload.serverKey.key}
+ `; + } else { + content = ` +Key Created
+Name: ${payload.name}
+Type: ${payload.keyType}
+ID: ${payload.id}
+Key: ${payload.key}
+ `; + } + + const detailsContent = document.getElementById('key-details-content'); + if (detailsContent) { + detailsContent.innerHTML = content; + } + + keyDetailsModal.classList.remove('hidden'); +} + +async function loadStats() { + try { + const response = await fetch(`${API_URL}/health`); + if (!response.ok) { + return; + } + const data = await response.json(); + + const connections = document.getElementById('user-stat-connections'); + if (connections) { + connections.textContent = data.active_ws || 0; + } + + const totalKeys = document.getElementById('user-stat-total-keys'); + if (totalKeys) { + totalKeys.textContent = data.keys_total || 0; + } + + const adminKeys = document.getElementById('user-stat-admin-keys'); + if (adminKeys) { + adminKeys.textContent = data.admin_active || 0; + } + + const regularKeys = document.getElementById('user-stat-regular-keys'); + if (regularKeys) { + regularKeys.textContent = data.regular_active || 0; + } + + const serverKeys = document.getElementById('user-stat-server-keys'); + if (serverKeys) { + serverKeys.textContent = data.server_active || 0; + } + } catch (error) { + console.error('Failed to load stats:', error); } } function connectWebSocket() { - if (!superKey) return; - - const wsUrl = `ws://localhost:8000/ws?api_key=${superKey}`; + if (!apiKey) { + return; + } + + const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; + const wsUrl = `${protocol}://${window.location.host}/ws?api_key=${apiKey}`; ws = new WebSocket(wsUrl); - + ws.onopen = () => { console.log('WebSocket connected'); }; - + ws.onmessage = (event) => { try { const message = JSON.parse(event.data); - if (message.type === 'minecraft_event') { addEventToList(message.event); } @@ -404,21 +401,23 @@ function connectWebSocket() { console.error('Failed to parse WebSocket message:', error); } }; - + ws.onerror = (error) => { console.error('WebSocket error:', error); }; - + ws.onclose = () => { console.log('WebSocket disconnected'); - setTimeout(() => { - if (superKey) { - connectWebSocket(); - } - }, 5000); + if (wsPingIntervalId) { + clearInterval(wsPingIntervalId); + wsPingIntervalId = null; + } + if (apiKey && currentRole === 'regular') { + setTimeout(() => connectWebSocket(), 5000); + } }; - - setInterval(() => { + + wsPingIntervalId = setInterval(() => { if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'ping' })); } @@ -426,19 +425,183 @@ function connectWebSocket() { } function addEventToList(event) { - const eventsList = document.getElementById('events-list'); - + if (!userEventsList) { + return; + } + const eventItem = document.createElement('div'); eventItem.className = 'event-item'; eventItem.innerHTML = ` ${event.event_type} - ${event.server_name}${JSON.stringify(event.data, null, 2)}
`;
-
- eventsList.insertBefore(eventItem, eventsList.firstChild);
-
- while (eventsList.children.length > 50) {
- eventsList.removeChild(eventsList.lastChild);
+
+ userEventsList.insertBefore(eventItem, userEventsList.firstChild);
+
+ while (userEventsList.children.length > 50) {
+ userEventsList.removeChild(userEventsList.lastChild);
+ }
+}
+
+function appendCommandHistory(command, status, detail) {
+ if (!commandHistory) {
+ return;
}
+
+ const entry = document.createElement('div');
+ entry.className = 'command-item';
+ entry.innerHTML = `
+ 密钥类型说明:
-👑 Admin Key - 完全管理权限
-🖥️ Server Key - 服务器管理权限
+Key Types
+Admin Key - full management permissions
+Regular Key - server monitoring and command access
0
+0
0
+0
0
+0
0
+0
+0
密钥创建成功!
+名称: ${keyData.name}
+类型: ${keyData.isSuperKey ? 'SuperKey' : '普通密钥'}
+无法加载Server Key列表
'; + } + } catch (error) { + console.error('Failed to load server keys:', error); + document.getElementById('keys-list').innerHTML = '无法加载Server Key列表
'; + } +} + +function renderServerKeys(keys) { + const keysList = document.getElementById('keys-list'); + + if (keys.length === 0) { + keysList.innerHTML = '暂无关联的Server Key
'; + return; + } + + keysList.innerHTML = keys.map(key => ` +ID: ${key.id}
+前缀: ${key.keyPrefix}
+ ${key.serverId ? `服务器ID: ${key.serverId}
` : ''} +创建时间: ${new Date(key.createdAt).toLocaleString('zh-CN')}
+最后使用: ${key.lastUsed ? new Date(key.lastUsed).toLocaleString('zh-CN') : '从未使用'}
+暂无API密钥
'; + return; + } + + keysList.innerHTML = keys.map(key => ` +ID: ${key.id}
+前缀: ${key.keyPrefix}
+ ${key.serverId ? `服务器ID: ${key.serverId}
` : ''} +创建时间: ${new Date(key.createdAt).toLocaleString('zh-CN')}
+最后使用: ${key.lastUsed ? new Date(key.lastUsed).toLocaleString('zh-CN') : '从未使用'}
+${JSON.stringify(event.data, null, 2)}
+ `;
+
+ eventsList.insertBefore(eventItem, eventsList.firstChild);
+
+ while (eventsList.children.length > 50) {
+ eventsList.removeChild(eventsList.lastChild);
+ }
+}
diff --git a/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/dashboard/public/index.html b/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/dashboard/public/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..2ed9581a917c042f3952a4aed8317e60d0cc5bfb
--- /dev/null
+++ b/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/hf_repo/dashboard/public/index.html
@@ -0,0 +1,103 @@
+
+
+
+
+
+ 密钥类型说明:
+👑 Admin Key - 完全管理权限
+🖥️ Server Key - 服务器管理权限
+0
+0
+0
+0
+