Merge branch 'QuecManager' of https://github.com/dr-dolomite/quectel-rgmii-toolkit into QuecManager
This commit is contained in:
@@ -1,108 +1,45 @@
|
|||||||
document.addEventListener("DOMContentLoaded", () => {
|
#!/bin/sh
|
||||||
// Function to generate a random token
|
|
||||||
function generateAuthToken(length = 32) {
|
|
||||||
const charset =
|
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
||||||
let token = "";
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
const randomIndex = Math.floor(Math.random() * charset.length);
|
|
||||||
token += charset[randomIndex];
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initially hide the body to prevent content from flashing
|
# Set Content-Type for CGI script
|
||||||
document.body.style.display = "none";
|
echo "Content-type: application/json"
|
||||||
|
echo ""
|
||||||
|
|
||||||
// Check if the user is already logged in
|
# Read POST data
|
||||||
const authToken = localStorage.getItem("authToken");
|
read POST_DATA
|
||||||
|
|
||||||
// Define which pages should be protected
|
# Extract the password from POST data (URL encoded)
|
||||||
const protectedPages = [
|
USER="root"
|
||||||
"/home.html",
|
INPUT_PASSWORD=$(echo "$POST_DATA" | sed -n 's/^.*password=\([^&]*\).*$/\1/p')
|
||||||
"advance-settings.html",
|
|
||||||
"/bandlock.html",
|
|
||||||
"/cell-locking.html",
|
|
||||||
"/cell-scanner.html",
|
|
||||||
"/cell-settings.html",
|
|
||||||
"/cell-sms.html",
|
|
||||||
"/about.html", // Add all the protected HTML pages here
|
|
||||||
];
|
|
||||||
|
|
||||||
const currentPage = window.location.pathname;
|
# URL-decode the password (replace + with space and decode %XX)
|
||||||
|
INPUT_PASSWORD=$(echo "$INPUT_PASSWORD" | sed 's/+/ /g;s/%\(..\)/\\x\1/g' | xargs -0 printf "%b")
|
||||||
|
|
||||||
// If the user is not logged in and tries to access a protected page, redirect to login
|
# Log received password for debugging (remove in production)
|
||||||
if (!authToken && protectedPages.includes(currentPage)) {
|
echo "Received password: $INPUT_PASSWORD" >&2
|
||||||
window.location.href = "index.html";
|
|
||||||
} else {
|
|
||||||
// Show the page if authentication is successful or not required
|
|
||||||
document.body.style.display = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user is logged in and tries to access the login page, redirect to home
|
# Extract the hashed password from /etc/shadow for the specified user
|
||||||
if (authToken && currentPage.includes("index.html")) {
|
USER_SHADOW_ENTRY=$(grep "^$USER:" /etc/shadow)
|
||||||
window.location.href = "home.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Login form logic (only for login page)
|
if [ -z "$USER_SHADOW_ENTRY" ]; then
|
||||||
const loginForm = document.getElementById("loginForm");
|
echo '{"state":"failed", "message":"User not found"}'
|
||||||
if (loginForm) {
|
exit 1
|
||||||
loginForm.addEventListener("submit", async (e) => {
|
fi
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const username = document.getElementById("username").value;
|
# Extract the password hash (it's the second field, colon-separated)
|
||||||
const password = document.getElementById("password").value;
|
USER_HASH=$(echo "$USER_SHADOW_ENTRY" | cut -d: -f2)
|
||||||
const errorElement = document.getElementById("error");
|
|
||||||
|
|
||||||
try {
|
# Extract the salt (MD5 uses the $1$ prefix followed by the salt)
|
||||||
const formData = new URLSearchParams();
|
SALT=$(echo "$USER_HASH" | cut -d'$' -f3)
|
||||||
formData.append("username", username);
|
|
||||||
formData.append("password", encodeURIComponent(password)); // URL-encode the password
|
|
||||||
|
|
||||||
const response = await fetch("/cgi-bin/auth.sh", {
|
# Generate a hash from the input password using the same salt
|
||||||
method: "POST",
|
GENERATED_HASH=$(echo "$INPUT_PASSWORD" | openssl passwd -1 -salt "$SALT" -stdin)
|
||||||
body: formData,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json(); // Parse JSON response
|
# Log generated hash for debugging
|
||||||
|
echo "Generated hash: $GENERATED_HASH" >&2
|
||||||
|
|
||||||
if (result.state === "success") {
|
# Compare the generated hash with the one in the shadow file
|
||||||
const newToken = generateAuthToken();
|
if [ "$GENERATED_HASH" = "$USER_HASH" ]; then
|
||||||
localStorage.setItem("authToken", newToken); // Store the token
|
echo '{"state":"success", "hashed_password":"'"$GENERATED_HASH"'"}'
|
||||||
window.location.href = "home.html"; // Redirect on success
|
else
|
||||||
} else {
|
echo '{"state":"failed", "hashed_password":"'"$GENERATED_HASH"'"}'
|
||||||
document.getElementById("error").textContent =
|
fi
|
||||||
"Invalid username or password";
|
|
||||||
console.log("Invalid username or password");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// Handle any errors (e.g., network issues)
|
|
||||||
errorElement.textContent = "An error occurred. Please try again later.";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logout button logic (only for pages that have the logout button)
|
|
||||||
const logoutButton = document.getElementById("logoutButton");
|
|
||||||
if (logoutButton) {
|
|
||||||
logoutButton.addEventListener("click", () => {
|
|
||||||
localStorage.removeItem("authToken"); // Remove token
|
|
||||||
window.location.href = "index.html"; // Redirect to login
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix for the issue of being redirected to login every time the Home button is clicked
|
|
||||||
document.querySelectorAll(".navbar-item").forEach((el) => {
|
|
||||||
if (el.textContent.includes("Home")) {
|
|
||||||
el.addEventListener("click", (e) => {
|
|
||||||
if (localStorage.getItem("authToken")) {
|
|
||||||
e.preventDefault();
|
|
||||||
window.location.href = "home.html";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user