529 lines
15 KiB
HTML
529 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Mobile Login Debugger</title>
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
sans-serif;
|
|
padding: 20px;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
min-height: 100vh;
|
|
}
|
|
.container {
|
|
max-width: 500px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
}
|
|
h1 {
|
|
color: #333;
|
|
margin-bottom: 20px;
|
|
font-size: 24px;
|
|
}
|
|
.test-section {
|
|
margin: 20px 0;
|
|
padding: 15px;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
border-left: 4px solid #667eea;
|
|
}
|
|
.test-section h2 {
|
|
font-size: 16px;
|
|
color: #667eea;
|
|
margin-bottom: 10px;
|
|
}
|
|
.test-result {
|
|
padding: 8px 12px;
|
|
margin: 5px 0;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
.pass {
|
|
background: #d4edda;
|
|
color: #155724;
|
|
border-left: 3px solid #28a745;
|
|
}
|
|
.fail {
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
border-left: 3px solid #dc3545;
|
|
}
|
|
.info {
|
|
background: #d1ecf1;
|
|
color: #0c5460;
|
|
border-left: 3px solid #17a2b8;
|
|
}
|
|
button {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border: none;
|
|
padding: 12px 24px;
|
|
border-radius: 8px;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
width: 100%;
|
|
margin: 10px 0;
|
|
font-weight: 600;
|
|
}
|
|
button:active {
|
|
transform: scale(0.98);
|
|
}
|
|
.login-form {
|
|
margin-top: 20px;
|
|
}
|
|
input {
|
|
width: 100%;
|
|
padding: 12px;
|
|
margin: 8px 0;
|
|
border: 2px solid #e0e0e0;
|
|
border-radius: 8px;
|
|
font-size: 16px;
|
|
}
|
|
input:focus {
|
|
outline: none;
|
|
border-color: #667eea;
|
|
}
|
|
label {
|
|
display: block;
|
|
margin-top: 10px;
|
|
color: #555;
|
|
font-weight: 600;
|
|
}
|
|
.code-block {
|
|
background: #2d2d2d;
|
|
color: #f8f8f2;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-family: "Courier New", monospace;
|
|
font-size: 12px;
|
|
overflow-x: auto;
|
|
margin: 10px 0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🔍 Mobile Login Debugger</h1>
|
|
|
|
<div class="test-section">
|
|
<h2>System Tests</h2>
|
|
<div id="systemTests"></div>
|
|
<button onclick="runSystemTests()">Run System Tests</button>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Storage Tests</h2>
|
|
<div id="storageTests"></div>
|
|
<button onclick="runStorageTests()">Test Storage Capabilities</button>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>CryptoJS Library Test</h2>
|
|
<div id="cryptoTests"></div>
|
|
<button onclick="runCryptoTests()">Test Crypto Library</button>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Login Simulation</h2>
|
|
<div class="login-form">
|
|
<label for="testUsername">Username:</label>
|
|
<input
|
|
type="text"
|
|
id="testUsername"
|
|
value="hop"
|
|
placeholder="Enter username"
|
|
/>
|
|
|
|
<label for="testPassword">Password:</label>
|
|
<input
|
|
type="password"
|
|
id="testPassword"
|
|
placeholder="Enter password"
|
|
/>
|
|
|
|
<button onclick="testLogin()">Test Login</button>
|
|
<div id="loginResults"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Current Credentials</h2>
|
|
<div id="credentialInfo"></div>
|
|
<button onclick="showCredentials()">Show Stored Credentials</button>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Clear All Storage</h2>
|
|
<button
|
|
onclick="clearAllStorage()"
|
|
style="background: linear-gradient(135deg, #dc3545 0%, #c82333 100%)"
|
|
>
|
|
Clear localStorage & sessionStorage
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Load CryptoJS -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
|
|
|
<script>
|
|
// Default credentials from App.js
|
|
const MASTER_USERNAME = "hop";
|
|
const MASTER_PASSWORD_HASH =
|
|
"5cdf907c69ae7a7f0c2e18a67e9b70a4c4fc35f9582637354c1bc45edf092a79";
|
|
|
|
function addResult(containerId, message, type) {
|
|
const container = document.getElementById(containerId);
|
|
const div = document.createElement("div");
|
|
div.className = `test-result ${type}`;
|
|
div.innerHTML = message;
|
|
container.appendChild(div);
|
|
}
|
|
|
|
function clearResults(containerId) {
|
|
document.getElementById(containerId).innerHTML = "";
|
|
}
|
|
|
|
function runSystemTests() {
|
|
clearResults("systemTests");
|
|
|
|
// User Agent
|
|
addResult(
|
|
"systemTests",
|
|
`<strong>User Agent:</strong><br>${navigator.userAgent}`,
|
|
"info"
|
|
);
|
|
|
|
// Browser Info
|
|
const browserInfo = {
|
|
Platform: navigator.platform,
|
|
Language: navigator.language,
|
|
Online: navigator.onLine,
|
|
"Cookies Enabled": navigator.cookieEnabled,
|
|
"Touch Support":
|
|
"ontouchstart" in window || navigator.maxTouchPoints > 0,
|
|
};
|
|
|
|
Object.entries(browserInfo).forEach(([key, value]) => {
|
|
addResult(
|
|
"systemTests",
|
|
`<strong>${key}:</strong> ${value}`,
|
|
value ? "pass" : "fail"
|
|
);
|
|
});
|
|
|
|
// Screen Info
|
|
addResult(
|
|
"systemTests",
|
|
`<strong>Screen:</strong> ${window.screen.width}x${window.screen.height} (${window.devicePixelRatio}x DPR)`,
|
|
"info"
|
|
);
|
|
addResult(
|
|
"systemTests",
|
|
`<strong>Viewport:</strong> ${window.innerWidth}x${window.innerHeight}`,
|
|
"info"
|
|
);
|
|
}
|
|
|
|
function runStorageTests() {
|
|
clearResults("storageTests");
|
|
|
|
// Test localStorage
|
|
try {
|
|
localStorage.setItem("test", "value");
|
|
const retrieved = localStorage.getItem("test");
|
|
localStorage.removeItem("test");
|
|
if (retrieved === "value") {
|
|
addResult("storageTests", "✓ localStorage is working", "pass");
|
|
} else {
|
|
addResult("storageTests", "✗ localStorage read failed", "fail");
|
|
}
|
|
} catch (e) {
|
|
addResult(
|
|
"storageTests",
|
|
`✗ localStorage failed: ${e.message}`,
|
|
"fail"
|
|
);
|
|
}
|
|
|
|
// Test sessionStorage
|
|
try {
|
|
sessionStorage.setItem("test", "value");
|
|
const retrieved = sessionStorage.getItem("test");
|
|
sessionStorage.removeItem("test");
|
|
if (retrieved === "value") {
|
|
addResult("storageTests", "✓ sessionStorage is working", "pass");
|
|
} else {
|
|
addResult("storageTests", "✗ sessionStorage read failed", "fail");
|
|
}
|
|
} catch (e) {
|
|
addResult(
|
|
"storageTests",
|
|
`✗ sessionStorage failed: ${e.message}`,
|
|
"fail"
|
|
);
|
|
}
|
|
|
|
// Check if in private browsing mode (heuristic)
|
|
try {
|
|
if (window.localStorage && window.sessionStorage) {
|
|
addResult(
|
|
"storageTests",
|
|
"✓ Not in private browsing mode (likely)",
|
|
"pass"
|
|
);
|
|
}
|
|
} catch (e) {
|
|
addResult(
|
|
"storageTests",
|
|
"⚠ Might be in private browsing mode",
|
|
"fail"
|
|
);
|
|
}
|
|
}
|
|
|
|
function runCryptoTests() {
|
|
clearResults("cryptoTests");
|
|
|
|
if (typeof CryptoJS === "undefined") {
|
|
addResult("cryptoTests", "✗ CryptoJS is not loaded!", "fail");
|
|
addResult(
|
|
"cryptoTests",
|
|
"This is likely the problem - the library failed to load on mobile",
|
|
"fail"
|
|
);
|
|
return;
|
|
}
|
|
|
|
addResult("cryptoTests", "✓ CryptoJS library is loaded", "pass");
|
|
|
|
// Test SHA256 hashing
|
|
try {
|
|
const testPassword = "hop@2026ilovejesus";
|
|
const hash = CryptoJS.SHA256(testPassword).toString();
|
|
|
|
addResult(
|
|
"cryptoTests",
|
|
`<strong>Test Hash:</strong><br><div class="code-block">${hash}</div>`,
|
|
"info"
|
|
);
|
|
|
|
if (hash === MASTER_PASSWORD_HASH) {
|
|
addResult(
|
|
"cryptoTests",
|
|
"✓ Password hashing works correctly!",
|
|
"pass"
|
|
);
|
|
} else {
|
|
addResult(
|
|
"cryptoTests",
|
|
"✗ Hash mismatch - encryption issue",
|
|
"fail"
|
|
);
|
|
}
|
|
} catch (e) {
|
|
addResult("cryptoTests", `✗ Hashing failed: ${e.message}`, "fail");
|
|
}
|
|
}
|
|
|
|
function testLogin() {
|
|
clearResults("loginResults");
|
|
|
|
const username = document.getElementById("testUsername").value;
|
|
const password = document.getElementById("testPassword").value;
|
|
|
|
if (!username || !password) {
|
|
addResult(
|
|
"loginResults",
|
|
"⚠ Please enter both username and password",
|
|
"fail"
|
|
);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Check if CryptoJS is available
|
|
if (typeof CryptoJS === "undefined") {
|
|
addResult(
|
|
"loginResults",
|
|
"✗ CryptoJS not loaded - this is the problem!",
|
|
"fail"
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Get stored credentials
|
|
const storedUsername =
|
|
localStorage.getItem("masterUsername") || MASTER_USERNAME;
|
|
const storedPasswordHash =
|
|
localStorage.getItem("masterPasswordHash") || MASTER_PASSWORD_HASH;
|
|
|
|
addResult(
|
|
"loginResults",
|
|
`<strong>Stored Username:</strong> ${storedUsername}`,
|
|
"info"
|
|
);
|
|
addResult(
|
|
"loginResults",
|
|
`<strong>Input Username:</strong> ${username}`,
|
|
"info"
|
|
);
|
|
|
|
// Hash the input password
|
|
const inputHash = CryptoJS.SHA256(password).toString();
|
|
|
|
addResult(
|
|
"loginResults",
|
|
`<strong>Input Hash:</strong><br><div class="code-block">${inputHash}</div>`,
|
|
"info"
|
|
);
|
|
addResult(
|
|
"loginResults",
|
|
`<strong>Expected Hash:</strong><br><div class="code-block">${storedPasswordHash}</div>`,
|
|
"info"
|
|
);
|
|
|
|
// Compare
|
|
if (username === storedUsername && inputHash === storedPasswordHash) {
|
|
addResult("loginResults", "✓ LOGIN WOULD SUCCEED!", "pass");
|
|
|
|
// Try to set session storage
|
|
try {
|
|
const sessionId = `session_${Date.now()}_${Math.random()
|
|
.toString(36)
|
|
.substr(2, 9)}`;
|
|
sessionStorage.setItem("authenticated", "true");
|
|
sessionStorage.setItem("authTime", Date.now().toString());
|
|
sessionStorage.setItem("sessionId", sessionId);
|
|
|
|
addResult(
|
|
"loginResults",
|
|
"✓ Session data stored successfully",
|
|
"pass"
|
|
);
|
|
addResult(
|
|
"loginResults",
|
|
`<strong>Session ID:</strong> ${sessionId}`,
|
|
"info"
|
|
);
|
|
} catch (e) {
|
|
addResult(
|
|
"loginResults",
|
|
`✗ Failed to set session: ${e.message}`,
|
|
"fail"
|
|
);
|
|
}
|
|
} else {
|
|
if (username !== storedUsername) {
|
|
addResult("loginResults", "✗ Username does not match", "fail");
|
|
}
|
|
if (inputHash !== storedPasswordHash) {
|
|
addResult(
|
|
"loginResults",
|
|
"✗ Password hash does not match",
|
|
"fail"
|
|
);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
addResult(
|
|
"loginResults",
|
|
`✗ Login test failed: ${e.message}`,
|
|
"fail"
|
|
);
|
|
}
|
|
}
|
|
|
|
function showCredentials() {
|
|
clearResults("credentialInfo");
|
|
|
|
const storedUsername = localStorage.getItem("masterUsername");
|
|
const storedPasswordHash = localStorage.getItem("masterPasswordHash");
|
|
const sessionAuth = sessionStorage.getItem("authenticated");
|
|
const sessionTime = sessionStorage.getItem("authTime");
|
|
const sessionId = sessionStorage.getItem("sessionId");
|
|
|
|
addResult(
|
|
"credentialInfo",
|
|
`<strong>Default Username:</strong> ${MASTER_USERNAME}`,
|
|
"info"
|
|
);
|
|
addResult(
|
|
"credentialInfo",
|
|
`<strong>Default Password:</strong> hop@2026ilovejesus`,
|
|
"info"
|
|
);
|
|
|
|
if (storedUsername) {
|
|
addResult(
|
|
"credentialInfo",
|
|
`<strong>Custom Username:</strong> ${storedUsername}`,
|
|
"info"
|
|
);
|
|
} else {
|
|
addResult("credentialInfo", "(Using default username)", "info");
|
|
}
|
|
|
|
if (storedPasswordHash) {
|
|
addResult(
|
|
"credentialInfo",
|
|
`<strong>Custom Hash:</strong><br><div class="code-block">${storedPasswordHash}</div>`,
|
|
"info"
|
|
);
|
|
} else {
|
|
addResult("credentialInfo", "(Using default password)", "info");
|
|
}
|
|
|
|
addResult("credentialInfo", "<strong>Session Status:</strong>", "info");
|
|
if (sessionAuth === "true") {
|
|
addResult("credentialInfo", "✓ Currently authenticated", "pass");
|
|
if (sessionTime) {
|
|
const authDate = new Date(parseInt(sessionTime));
|
|
addResult(
|
|
"credentialInfo",
|
|
`Logged in at: ${authDate.toLocaleString()}`,
|
|
"info"
|
|
);
|
|
}
|
|
if (sessionId) {
|
|
addResult("credentialInfo", `Session ID: ${sessionId}`, "info");
|
|
}
|
|
} else {
|
|
addResult("credentialInfo", "✗ Not authenticated", "fail");
|
|
}
|
|
}
|
|
|
|
function clearAllStorage() {
|
|
if (
|
|
confirm(
|
|
"This will clear ALL localStorage and sessionStorage. Continue?"
|
|
)
|
|
) {
|
|
try {
|
|
localStorage.clear();
|
|
sessionStorage.clear();
|
|
alert("✓ All storage cleared! Reload the page to test fresh.");
|
|
} catch (e) {
|
|
alert("✗ Failed to clear storage: " + e.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Auto-run system tests on load
|
|
window.addEventListener("load", function () {
|
|
runSystemTests();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|