Files
2025-12-29 00:24:59 +01:00

355 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>M7350 Quick Status - Auto Run</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<style>
body {
font-family: 'Courier New', monospace;
background: #121212;
color: #00ff00;
padding: 20px;
line-height: 1.6;
}
.container {
max-width: 800px;
margin: auto;
border: 2px solid #00ff00;
padding: 25px;
box-shadow: 0 0 20px #00ff0044;
background: #0a0a0a;
}
.handshake {
color: #888;
font-size: 0.8em;
margin-bottom: 25px;
border-bottom: 1px dashed #444;
padding-bottom: 15px;
}
.status-container {
border: 1px solid #333;
padding: 20px;
margin-bottom: 20px;
background: #1a1a1a;
border-radius: 5px;
}
.status-header {
color: #00ff00;
font-size: 1.3em;
border-bottom: 2px solid #00ff00;
padding-bottom: 10px;
margin-bottom: 20px;
text-align: center;
text-transform: uppercase;
letter-spacing: 2px;
}
.status-row {
margin: 12px 0;
padding: 8px 0;
display: flex;
align-items: center;
border-bottom: 1px solid #222;
transition: all 0.2s;
}
.status-row:hover {
background: rgba(0, 255, 0, 0.05);
padding-left: 10px;
}
.label {
color: #00aaff;
font-weight: bold;
width: 180px;
flex-shrink: 0;
}
.value {
color: #ffffff;
font-family: 'Courier New', monospace;
flex-grow: 1;
}
.value-highlight {
color: #00ffaa;
font-weight: bold;
}
.value-note {
color: #888;
font-size: 0.9em;
font-style: italic;
}
#status {
color: #ffaa00;
margin: 15px 0;
font-weight: bold;
padding: 10px;
background: rgba(255, 170, 0, 0.1);
border-left: 3px solid #ffaa00;
}
.pass-info {
font-size: 0.8em;
color: #666;
margin-top: 5px;
}
.auto-note {
color: #ffff00;
font-size: 0.9em;
margin-bottom: 15px;
padding: 10px;
background: #222;
border-radius: 3px;
border-left: 3px solid #ffff00;
}
.refresh-btn {
background: #222;
color: #00ff00;
border: 2px solid #00ff00;
padding: 10px 20px;
cursor: pointer;
font-family: 'Courier New', monospace;
font-weight: bold;
transition: all 0.3s;
margin-top: 15px;
display: inline-block;
}
.refresh-btn:hover {
background: #00ff00;
color: #121212;
transform: translateY(-2px);
box-shadow: 0 0 15px #00ff00;
}
.error {
color: #ff5555;
border: 1px solid #ff5555;
padding: 15px;
background: rgba(255, 85, 85, 0.1);
margin: 15px 0;
border-radius: 3px;
}
.success {
color: #00ff00;
padding: 10px;
text-align: center;
font-weight: bold;
}
.bytes-info {
font-size: 0.85em;
color: #888;
margin-top: 5px;
padding-left: 180px;
}
.connection-status {
display: inline-block;
padding: 3px 8px;
background: #00aa00;
color: white;
border-radius: 3px;
font-size: 0.9em;
margin-left: 10px;
}
.network-type {
display: inline-block;
padding: 3px 8px;
background: #0055aa;
color: white;
border-radius: 3px;
font-size: 0.9em;
margin-left: 10px;
}
</style>
</head>
<body onload="fetchQuickStatus()">
<div class="container">
<h3 style="text-align: center; color: #00ff00; margin-bottom: 10px;">TP-Link M7350 Quick Status</h3>
<h4 style="text-align: center; color: #888; margin-top: 0; margin-bottom: 20px;">Auto-run on page load</h4>
<div class="auto-note">⏳ Fetching quick status from router...</div>
<div class="handshake">
<div class="pass-info">Reading credentials from <i>password.txt</i>...</div>
<div style="margin-top:12px; display: flex; gap: 20px; flex-wrap: wrap;">
<div>Nonce: <span id="n-out" style="color:#d2a8ff; font-weight: bold;">---</span></div>
<div>Token: <span id="t-out" style="color:#d2a8ff; font-weight: bold;">---</span></div>
</div>
</div>
<div id="status">Initializing connection to router...</div>
<div id="output"></div>
<div style="text-align: center; margin-top: 20px;">
<button class="refresh-btn" onclick="fetchQuickStatus()">⟳ Refresh Status</button>
</div>
</div>
<script>
const host = "192.168.0.1";
let currentToken = '';
let currentNonce = '';
async function fetchQuickStatus() {
const status = document.getElementById('status');
const output = document.getElementById('output');
try {
output.innerHTML = '';
status.innerHTML = '<span style="color:#ffff00">⏳ Reading password from password.txt...</span>';
const passRes = await fetch('password.txt');
if (!passRes.ok) throw new Error("Could not find password.txt in directory.");
const password = (await passRes.text()).trim();
status.innerHTML = '<span style="color:#ffff00">⏳ Getting nonce from router...</span>';
const nRes = await fetch(`http://${host}/cgi-bin/auth_cgi`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Referer': `http://${host}/login.html`
},
body: JSON.stringify({module: "authenticator", action: 0})
});
const nData = await nRes.json();
currentNonce = nData.nonce;
document.getElementById('n-out').innerText = currentNonce || '---';
if (!currentNonce) throw new Error("Failed to get nonce from router");
status.innerHTML = '<span style="color:#ffff00">⏳ Logging in...</span>';
const digest = CryptoJS.MD5(`${password}:${currentNonce}`).toString();
const lRes = await fetch(`http://${host}/cgi-bin/auth_cgi`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Referer': `http://${host}/login.html`
},
body: JSON.stringify({module: "authenticator", action: 1, digest: digest})
});
const lData = await lRes.json();
currentToken = lData.token;
document.getElementById('t-out').innerText = currentToken || '---';
if (!currentToken) throw new Error("Login Failed - check password.txt content.");
status.innerHTML = '<span style="color:#ffff00">⏳ Fetching status information...</span>';
const sRes = await fetch(`http://${host}/cgi-bin/web_cgi`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Referer': `http://${host}/settings.html`
},
body: JSON.stringify({
token: currentToken,
module: "status",
action: 0
})
});
const rawData = await sRes.text();
function extractValue(key) {
const regex = new RegExp(`"${key}"\\s*:\\s*"([^"]*)"`);
const match = rawData.match(regex);
return match ? match[1] : null;
}
const ipv4 = extractValue('ipv4');
const ssid = extractValue('ssid');
const model = extractValue('model');
const firmware = extractValue('firmwareVer');
const mac = extractValue('mac');
const clientsMatch = rawData.match(/"number"\s*:\s*(\d+)/);
const clients = clientsMatch ? clientsMatch[1] : '0';
const bytesMatch = rawData.match(/"totalStatistics"\s*:\s*"([^"]*)"/);
const bytesStr = bytesMatch ? bytesMatch[1] : '0';
const bytes = parseInt(bytesStr.split('.')[0]) || 0;
const gb = (bytes / 1073741824).toFixed(2);
output.innerHTML = '';
const statusDiv = document.createElement('div');
statusDiv.className = 'status-container';
statusDiv.innerHTML = `
<div class="status-header">=== FINAL STATUS ===</div>
<div class="status-row">
<span class="label">Connection Status:</span>
<span class="value">
Connected
<span class="connection-status">✓</span>
</span>
</div>
<div class="status-row">
<span class="label">Network Type:</span>
<span class="value">
LTE
<span class="network-type">4G</span>
</span>
</div>
<div class="status-row">
<span class="label">IPv4 Address:</span>
<span class="value value-highlight">${ipv4 || 'N/A'}</span>
</div>
<div class="status-row">
<span class="label">SSID:</span>
<span class="value value-highlight">${ssid || 'N/A'}</span>
</div>
<div class="status-row">
<span class="label">Current Clients:</span>
<span class="value value-highlight">${clients}</span>
</div>
<div class="status-row">
<span class="label">Monthly Used:</span>
<span class="value value-highlight">${gb} GB</span>
</div>
<div class="bytes-info">(Raw bytes: ${bytes.toLocaleString()})</div>
<div class="status-row">
<span class="label">Model:</span>
<span class="value">${model || 'Unknown'}</span>
</div>
<div class="status-row">
<span class="label">Firmware:</span>
<span class="value">${firmware || 'Unknown'}</span>
</div>
<div class="status-row">
<span class="label">MAC Address:</span>
<span class="value">${mac || 'Unknown'}</span>
</div>
`;
output.appendChild(statusDiv);
status.innerHTML = '<span style="color:#00ff00">✓ Status fetched successfully!</span>';
const doneDiv = document.createElement('div');
doneDiv.className = 'success';
doneDiv.textContent = 'Done.';
output.appendChild(doneDiv);
} catch (e) {
status.innerHTML = `<span style="color:#ff5555">✗ Error: ${e.message}</span>`;
console.error(e);
const errorDiv = document.createElement('div');
errorDiv.className = 'error';
errorDiv.innerHTML = `
<strong>Error Details:</strong><br>
${e.message}<br><br>
<small>Check console for more details.</small>
`;
output.appendChild(errorDiv);
}
}
</script>
</body>
</html>