| const commandInput = document.getElementById('command');
|
| const output = document.getElementById('output');
|
| const history = document.getElementById('history');
|
| const executeButton = document.getElementById('executeButton');
|
| const loadingIndicator = document.getElementById('loadingIndicator');
|
|
|
| commandInput.addEventListener('keypress', function (event) {
|
| if (event.key === 'Enter') {
|
| executeCommand();
|
| }
|
| });
|
|
|
| async function executeCommand() {
|
| const command = commandInput.value;
|
| if (!command.trim()) return;
|
|
|
| showLoading(true);
|
| output.textContent = '正在执行命令...';
|
|
|
| try {
|
| let response = await fetch('/api/execute', {
|
| method: 'POST',
|
| headers: {
|
| 'Content-Type': 'application/json',
|
| 'Authorization': `Bearer ${localStorage.getItem('token')}`
|
| },
|
| body: JSON.stringify({ command })
|
| });
|
|
|
| if (response.status === 403) {
|
|
|
| const refreshed = await refreshToken();
|
| if (refreshed) {
|
|
|
| response = await fetch('/api/execute', {
|
| method: 'POST',
|
| headers: {
|
| 'Content-Type': 'application/json',
|
| 'Authorization': `Bearer ${localStorage.getItem('token')}`
|
| },
|
| body: JSON.stringify({ command })
|
| });
|
| } else {
|
| throw new Error('Token 刷新失败');
|
| }
|
| }
|
|
|
| if (!response.ok) {
|
| throw new Error(`HTTP error! status: ${response.status}`);
|
| }
|
|
|
| const data = await response.json();
|
| output.textContent = data.output || data.error || '命令执行成功,但没有输出。';
|
| commandInput.value = '';
|
| loadCommandHistory();
|
| } catch (error) {
|
| console.error('执行命令时出错:', error);
|
| output.textContent = '错误: ' + (error.message || '未知错误');
|
| if (error.message.includes('Token 刷新失败')) {
|
| alert('访问被拒绝。请重新登录。');
|
| localStorage.removeItem('token');
|
| localStorage.removeItem('username');
|
| localStorage.removeItem('password');
|
| checkLoginStatus();
|
| }
|
| } finally {
|
| showLoading(false);
|
| }
|
| }
|
|
|
| async function loadCommandHistory() {
|
| try {
|
| const response = await fetch('/api/command-history', {
|
| headers: {
|
| 'Authorization': `Bearer ${localStorage.getItem('token')}`
|
| }
|
| });
|
| const data = await response.json();
|
| history.innerHTML = '';
|
| data.reverse().forEach(item => {
|
| const li = document.createElement('li');
|
| li.textContent = `${filterXSS(item.command)} (${new Date(item.timestamp).toLocaleString()})`;
|
| li.className = 'cursor-pointer hover:text-blue-500';
|
| li.onclick = () => {
|
| console.log(`Clicked on command: ${item.command}`);
|
| commandInput.value = item.command;
|
| };
|
| history.appendChild(li);
|
| });
|
| } catch (error) {
|
| console.error('加载命令历史失败:', error);
|
| }
|
| }
|
|
|
| function showLoading(isLoading) {
|
| loadingIndicator.style.display = isLoading ? 'block' : 'none';
|
| executeButton.disabled = isLoading;
|
| }
|
|
|
| async function login() {
|
| const username = document.getElementById('username').value;
|
| const password = document.getElementById('password').value;
|
| try {
|
| const response = await fetch('/api/login', {
|
| method: 'POST',
|
| headers: { 'Content-Type': 'application/json' },
|
| body: JSON.stringify({ username, password })
|
| });
|
| const data = await response.json();
|
| if (response.ok) {
|
| localStorage.setItem('token', data.token);
|
| localStorage.setItem('username', username);
|
| localStorage.setItem('password', password);
|
| document.getElementById('loginForm').style.display = 'none';
|
| document.getElementById('commandInterface').style.display = 'block';
|
| loadCommandHistory();
|
| } else {
|
| alert('登录失败: ' + data.error);
|
| }
|
| } catch (error) {
|
| alert('登录错误: ' + error.message);
|
| }
|
| }
|
|
|
| async function refreshToken() {
|
| const username = localStorage.getItem('username');
|
| const password = localStorage.getItem('password');
|
| if (!username || !password) {
|
|
|
| document.getElementById('loginForm').style.display = 'block';
|
| document.getElementById('commandInterface').style.display = 'none';
|
| return;
|
| }
|
| try {
|
| const response = await fetch('/api/login', {
|
| method: 'POST',
|
| headers: { 'Content-Type': 'application/json' },
|
| body: JSON.stringify({ username, password })
|
| });
|
| const data = await response.json();
|
| if (response.ok) {
|
| localStorage.setItem('token', data.token);
|
| return true;
|
| } else {
|
| throw new Error(data.error);
|
| }
|
| } catch (error) {
|
| console.error('刷新 token 失败:', error);
|
| return false;
|
| }
|
| }
|
|
|
| document.getElementById('loginButton').addEventListener('click', login);
|
|
|
| loadCommandHistory();
|
|
|
| function checkLoginStatus() {
|
| const token = localStorage.getItem('token');
|
| if (token) {
|
| document.getElementById('loginForm').style.display = 'none';
|
| document.getElementById('commandInterface').style.display = 'block';
|
| loadCommandHistory();
|
| }
|
| }
|
|
|
|
|
| window.addEventListener('load', checkLoginStatus);
|
| document.getElementById('executeButton').addEventListener('click', executeCommand); |