added auth improvements and luci

This commit is contained in:
Russel Yasol
2024-10-03 05:48:00 +08:00
parent 661a3c3f44
commit 7d36748dce
16 changed files with 3059 additions and 2270 deletions

View File

@@ -1,30 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- Logo -->
<link rel="logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<!-- Font awesome icons -->
<script src="https://kit.fontawesome.com/b0caedfab3.js" crossorigin="anonymous"></script>
<script
src="https://kit.fontawesome.com/b0caedfab3.js"
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -55,7 +58,7 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
@@ -68,8 +71,15 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<a class="navbar-item has-text-weight-bold" href="/about.html"> About </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
<div class="navbar-end">
@@ -88,11 +98,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -128,9 +138,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
Device Information
</div>
<div class="card-header-title">Device Information</div>
</div>
<div class="card-content">
<table class="table is-fullwidth is-borderless">
@@ -164,13 +172,14 @@
<th>
<div class="field has-addons is-hidden-mobile">
<div class="control">
<input class="input has-text-weight-semibold" type="text"
placeholder="IMEI Here">
<input
class="input has-text-weight-semibold"
type="text"
placeholder="IMEI Here"
/>
</div>
<div class="control">
<button class="button is-link">
Change
</button>
<button class="button is-link">Change</button>
</div>
</div>
<span class="is-block-mobile is-hidden">
@@ -188,7 +197,7 @@
</tr>
<tr>
<td>WWAN IPv6</td>
<th style="word-break: break-all;">
<th style="word-break: break-all">
5be8:dde9:7f0b:d5a7:bd01:b3be:9c69:573b
</th>
</tr>
@@ -201,50 +210,58 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
About Us
</div>
<div class="card-header-title">About Us</div>
</div>
<div class="card-content">
<div class="content">
<p class="title">
QuecManager
</p>
<p class="title">QuecManager</p>
<p class="subtitle mt-2">
Simple Admin began as part of the RGMII toolkit, offering users a basic GUI.
However, with our fork and continued development, it has evolved to include more
advanced features, making "simple" no longer an ideal name for the dashboard.
Despite this shift, we remain committed to providing advanced functionality while
maintaining an intuitive and user-friendly GUI.
Simple Admin began as part of the RGMII toolkit, offering
users a basic GUI. However, with our fork and continued
development, it has evolved to include more advanced
features, making "simple" no longer an ideal name for the
dashboard. Despite this shift, we remain committed to
providing advanced functionality while maintaining an
intuitive and user-friendly GUI.
</p>
<p class="subtitle mt-6 has-text-weight-bold">
Thanks to
</p>
<p class="subtitle mt-6 has-text-weight-bold">Thanks to</p>
<ul class="has-text-weight-semibold">
<li>
RGMII Toolkit and Documentation
<a href="https://github.com/iamromulan" target="_blank">iamromulan</a>
<a href="https://github.com/iamromulan" target="_blank"
>iamromulan</a
>
</li>
<li>
Simple Admin 2.0 and QuecManager
<a href="https://github.com/dr-dolomite" target="_blank">dr-dolomite</a>
<a href="https://github.com/dr-dolomite" target="_blank"
>dr-dolomite</a
>
</li>
<li>
SMS Feature
<a href="https://github.com/snjzb" target="_blank">snjzb</a>
<a href="https://github.com/snjzb" target="_blank"
>snjzb</a
>
</li>
<li>
Original Simple Admin
<a href="https://github.com/aesthernr" target="_blank">aesthernr</a>
<a href="https://github.com/aesthernr" target="_blank"
>aesthernr</a
>
</li>
<li>
Original Socat Bridge
<a href="https://github.com/natecarlson" target="_blank">natecarlson</a>
<a href="https://github.com/natecarlson" target="_blank"
>natecarlson</a
>
</li>
<li>
Initial Original Simple Admin Fixes
<a href="https://github.com/rbflurry/" target="_blank">rbflurry</a>
<a href="https://github.com/rbflurry/" target="_blank"
>rbflurry</a
>
</li>
</ul>
</div>
@@ -258,11 +275,34 @@
<footer class="footer">
<div class="content has-text-centered">
<p>
<strong> <a href="https://github.com/iamromulan/quectel-rgmii-toolkit.git">QuecManager</a></strong>
<strong>
<a href="https://github.com/iamromulan/quectel-rgmii-toolkit.git"
>QuecManager</a
></strong
>
version 1.0. All rights reserved.
</p>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">40</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -19,10 +19,12 @@
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script src="/js/handle-at-input.js"></script>
<script src="/js/advance/at-terminal.js"></script>
<script>
(function () {
@@ -57,7 +59,7 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
@@ -70,7 +72,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item has-text-weight-bold" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -90,11 +99,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -125,74 +134,81 @@
</nav>
<div class="column-margin">
<div class="fixed-grid has-2-cols has-1-cols-mobile">
<div class="grid">
<div class="cell">
<div class="columns">
<div class="column">
<div class="card">
<form id="commandForm">
<div class="card-header">
<div class="card-header-title">AT command Terminal</div>
<p class="card-header-title">AT Command Terminal</p>
</div>
<div class="card-content">
<div class="fixed-grid has-1-cols">
<div class="grid is-gap-5">
<div class="cell">
<form id="commandForm">
<div class="field">
<label class="label">AT Command</label>
<label class="label">Output</label>
<div class="control">
<textarea
class="textarea"
id="output"
placeholder="AT Response"
rows="10"
disabled
readonly
placeholder="AT command responses will appear here..."
></textarea>
</div>
</div>
<div class="field is-hidden-touch">
<div class="level">
<div class="level-left">
<div class="level-item">
<label class="label">Command History</label>
</div>
</div>
<div class="level-right">
<div class="level-item">
<button
type="button"
id="clearHistory"
class="button is-small is-link has-text-white"
>
Clear All
</button>
</div>
</div>
</div>
<div class="command-history" id="commandHistory">
<div class="no-history" id="noHistory">No commands yet</div>
</div>
</div>
<div class="cell">
<div class="field">
<label class="label">Input AT Command</label>
<div class="control">
<div class="field has-addons">
<div class="control is-expanded">
<input
class="input"
type="text"
placeholder="ATI"
id="command"
name="command"
placeholder="Enter AT command (e.g., ATI)"
autocomplete="off"
/>
</div>
<p class="help">
Some commands may take time to execute so wait
patiently.
</p>
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
id="sendCommand"
<div class="control" style="position: relative">
<button
type="submit"
class="button is-link"
id="sendButton"
>
Send AT Command
</a>
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
id="resetForm"
>
Reset
</a>
<span class="icon">
<i class="fas fa-paper-plane"></i>
</span>
<span>Send</span>
</button>
<span id="cooldownTimer"></span>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="cell">
<div class="column">
<div class="card">
<div class="card-header">
<div class="card-header-title">Advance Settings</div>
@@ -254,9 +270,7 @@
<div class="cell">
<div class="field">
<label class="label"
>Onboard DNS Proxy Mode</label
>
<label class="label">Onboard DNS Proxy Mode</label>
<p class="control has-icons-left">
<span class="select">
<select>
@@ -329,9 +343,7 @@
<i class="fas fa-wifi"></i>
</span>
</div>
<p
class="help is-success has-text-weight-semibold"
>
<p class="help is-success has-text-weight-semibold">
Set the TTL Value to 0 to disable.
</p>
</div>
@@ -360,7 +372,6 @@
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="content">
@@ -396,52 +407,25 @@
</div>
</div>
</footer>
<script>
// Handle form submission via JavaScript
document
.getElementById("sendCommand")
.addEventListener("click", function (e) {
e.preventDefault(); // Prevent default link behavior
const commandInput = document.getElementById("command").value;
const outputTextarea = document.getElementById("output");
// Make sure input is not empty
if (commandInput.trim() === "") {
outputTextarea.value = "Please enter a valid AT command.";
return;
}
// Send the AT command to the CGI script via fetch
fetch("/cgi-bin/atinout_handler.sh", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: `command=${encodeURIComponent(commandInput)}`,
})
.then((response) => response.json())
.then((data) => {
// Display the response in the textarea
if (data.output) {
outputTextarea.value = data.output;
} else {
outputTextarea.value = "Error: No output received.";
}
})
.catch((error) => {
outputTextarea.value = `Error fetching data: ${error.message}`;
});
});
// Reset form functionality
document
.getElementById("resetForm")
.addEventListener("click", function (e) {
e.preventDefault();
document.getElementById("commandForm").reset();
document.getElementById("output").value = "";
});
</script>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">80</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -1,29 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- Logo -->
<link rel="simpleadmin-logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<!-- Font awesome icons -->
<script src="https://kit.fontawesome.com/b0caedfab3.js" crossorigin="anonymous"></script>
<script
src="https://kit.fontawesome.com/b0caedfab3.js"
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -53,7 +57,7 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
@@ -66,7 +70,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -86,11 +97,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -126,9 +137,7 @@
<div class="cell is-col-span-2 is-col-span-1-mobile">
<div class="card">
<div class="card-header">
<div class="card-header-title">
4G LTE Band Locking
</div>
<div class="card-header-title">4G LTE Band Locking</div>
</div>
<div class="card-content">
<div class="fixed-grid has-5-cols has-3-cols-mobile">
@@ -138,15 +147,24 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Lock LTE Bands
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Uncheck All
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -156,9 +174,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
5G-NR NSA Band Locking
</div>
<div class="card-header-title">5G-NR NSA Band Locking</div>
</div>
<div class="card-content">
<div class="fixed-grid has-5-cols has-3-cols-mobile">
@@ -168,15 +184,24 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Lock NSA Bands
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Uncheck All
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -186,9 +211,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
5G-NR SA Band Locking
</div>
<div class="card-header-title">5G-NR SA Band Locking</div>
</div>
<div class="card-content">
<div class="fixed-grid has-5-cols has-3-cols-mobile">
@@ -198,15 +221,24 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Lock SA Bands
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Uncheck All
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -229,7 +261,8 @@
</div>
<p class="block has-text-weight-semibold">
If problem persists after locking bands, please reboot the modem.
If problem persists after locking bands, please reboot the
modem.
</p>
</div>
@@ -249,10 +282,31 @@
</div>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">40</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
<script>
var lte_bands = "1:2:3:4:5:7:8:12:13:14:18:19:20:25:26:28:29:30:32:34:38:39:40:41:42:43:46:48:66:71";
var lte_bands =
"1:2:3:4:5:7:8:12:13:14:18:19:20:25:26:28:29:30:32:34:38:39:40:41:42:43:46:48:66:71";
var nsa_bands = "1:2:3:5:7:8:12:20:25:28:38:40:41:48:66:71:77:78:79";
var sa_bands = "1:2:3:5:7:8:12:20:25:28:38:40:41:48:66:71:77:78:79";
@@ -261,7 +315,10 @@
var html = "";
for (var i = 0; i < bandsArray.length; i++) {
html += '<div class="cell"><label class="checkbox"><input type="checkbox" /> B' + bandsArray[i] + '</label></div>';
html +=
'<div class="cell"><label class="checkbox"><input type="checkbox" /> B' +
bandsArray[i] +
"</label></div>";
}
// Inject the generated HTML into the target element
@@ -269,10 +326,8 @@
}
// Populate the bands in their respective grids
populateBands(lte_bands, '#lte_bands');
populateBands(nsa_bands, '#nsa_bands');
populateBands(sa_bands, '#sa_bands');
populateBands(lte_bands, "#lte_bands");
populateBands(nsa_bands, "#nsa_bands");
populateBands(sa_bands, "#sa_bands");
</script>
</html>

View File

@@ -1,29 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- Logo -->
<link rel="simpleadmin-logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<!-- Font awesome icons -->
<script src="https://kit.fontawesome.com/b0caedfab3.js" crossorigin="anonymous"></script>
<script
src="https://kit.fontawesome.com/b0caedfab3.js"
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -54,7 +58,7 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
@@ -67,7 +71,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -87,11 +98,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -127,9 +138,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
4G LTE Cell Locking
</div>
<div class="card-header-title">4G LTE Cell Locking</div>
</div>
<div class="card-content">
<div class="fixed-grid has-2-cols">
@@ -139,7 +148,11 @@
<div class="field">
<label class="label">EARFCN 1</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="EARFCN">
<input
class="input"
type="email"
placeholder="EARFCN"
/>
<span class="icon is-left">
<i class="fas fa-bolt"></i>
</span>
@@ -151,7 +164,7 @@
<div class="field">
<label class="label">PCI 1</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="PCI">
<input class="input" type="email" placeholder="PCI" />
<span class="icon is-left">
<i class="fa-solid fa-signal"></i>
</span>
@@ -165,7 +178,11 @@
<div class="field">
<label class="label">EARFCN 2</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="EARFCN">
<input
class="input"
type="email"
placeholder="EARFCN"
/>
<span class="icon is-left">
<i class="fas fa-bolt"></i>
</span>
@@ -177,7 +194,7 @@
<div class="field">
<label class="label">PCI 2</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="PCI">
<input class="input" type="email" placeholder="PCI" />
<span class="icon is-left">
<i class="fa-solid fa-signal"></i>
</span>
@@ -191,7 +208,11 @@
<div class="field">
<label class="label">EARFCN 3</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="EARFCN">
<input
class="input"
type="email"
placeholder="EARFCN"
/>
<span class="icon is-left">
<i class="fas fa-bolt"></i>
</span>
@@ -203,7 +224,7 @@
<div class="field">
<label class="label">PCI 3</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="PCI">
<input class="input" type="email" placeholder="PCI" />
<span class="icon is-left">
<i class="fa-solid fa-signal"></i>
</span>
@@ -215,11 +236,17 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Lock LTE Cells
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -229,9 +256,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
5G-NR SA Cell Locking
</div>
<div class="card-header-title">5G-NR SA Cell Locking</div>
</div>
<div class="card-content">
<div class="fixed-grid has-2-cols">
@@ -241,7 +266,11 @@
<div class="field">
<label class="label">NR ARFCN</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="NR-ARFCN">
<input
class="input"
type="email"
placeholder="NR-ARFCN"
/>
<span class="icon is-left">
<i class="fas fa-bolt"></i>
</span>
@@ -253,7 +282,11 @@
<div class="field">
<label class="label">NR PCI</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="NR PCI">
<input
class="input"
type="email"
placeholder="NR PCI"
/>
<span class="icon is-left">
<i class="fa-solid fa-signal"></i>
</span>
@@ -288,7 +321,11 @@
<div class="field">
<label class="label">NR Band</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="NR Band">
<input
class="input"
type="email"
placeholder="NR Band"
/>
<span class="icon is-left">
<i class="fa-solid fa-signal"></i>
</span>
@@ -300,11 +337,17 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Lock SA Cells
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -327,9 +370,10 @@
</div>
<p class="block has-text-weight-semibold">
Cell locking is an advance feature and may cause network interruptions. <br />
Cell locking will also only work with the main band (PCC) if you are using carrier
aggregation.
Cell locking is an advance feature and may cause network
interruptions. <br />
Cell locking will also only work with the main band (PCC) if you
are using carrier aggregation.
<br />
Proceed with caution.
</p>
@@ -351,6 +395,25 @@
</div>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">40</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -1,29 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- Logo -->
<link rel="simpleadmin-logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<!-- Font awesome icons -->
<script src="https://kit.fontawesome.com/b0caedfab3.js" crossorigin="anonymous"></script>
<script
src="https://kit.fontawesome.com/b0caedfab3.js"
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -54,7 +58,7 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
@@ -67,7 +71,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -87,11 +98,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -135,150 +146,127 @@
<table class="table is-fullwidth">
<thead>
<tr>
<th>
Network Provider
</th>
<th>
Name
</th>
<th>
EARFCN
</th>
<th>
Bandwidth
</th>
<th>
Physical ID
</th>
<th class="is-hidden-mobile">
RSRP
</th>
<th class="is-hidden-mobile">
RSRQ
</th>
<th class="is-hidden-mobile">
SINR
</th>
<th>Network Provider</th>
<th>Name</th>
<th>EARFCN</th>
<th>Bandwidth</th>
<th>Physical ID</th>
<th class="is-hidden-mobile">RSRP</th>
<th class="is-hidden-mobile">RSRQ</th>
<th class="is-hidden-mobile">SINR</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Smart
</td>
<td>
B1
</td>
<td>
150
</td>
<td>
10
</td>
<td>
623
</td>
<td>Smart</td>
<td>B1</td>
<td>150</td>
<td>10</td>
<td>623</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -103 </span>
<span class="tag is-danger is-size-6 has-text-white"> Poor </span>
<span class="tag is-danger is-size-6 has-text-white">
Poor
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -103 </span>
<span class="tag is-danger is-size-6 has-text-white"> Poor </span>
<span class="tag is-danger is-size-6 has-text-white">
Poor
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -5 </span>
<span class="tag is-danger is-size-6 has-text-white"> Poor </span>
<span class="tag is-danger is-size-6 has-text-white">
Poor
</span>
</div>
</td>
</tr>
<tr>
<td>
DITO
</td>
<td>
B2
</td>
<td>
150
</td>
<td>
10
</td>
<td>
623
</td>
<td>DITO</td>
<td>B2</td>
<td>150</td>
<td>10</td>
<td>623</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -90 </span>
<span class="tag is-warning is-size-6 has-text-white"> Medium </span>
<span class="tag is-warning is-size-6 has-text-white">
Medium
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -90 </span>
<span class="tag is-warning is-size-6 has-text-white"> Medium </span>
<span class="tag is-warning is-size-6 has-text-white">
Medium
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> 10 </span>
<span class="tag is-warning is-size-6 has-text-white"> Medium </span>
<span class="tag is-warning is-size-6 has-text-white">
Medium
</span>
</div>
</td>
</tr>
<tr>
<td>
Globe
</td>
<td>
B3
</td>
<td>
150
</td>
<td>
10
</td>
<td>
623
</td>
<td>Globe</td>
<td>B3</td>
<td>150</td>
<td>10</td>
<td>623</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -65 </span>
<span class="tag is-success is-size-6 has-text-white"> Strong </span>
<span class="tag is-success is-size-6 has-text-white">
Strong
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -65 </span>
<span class="tag is-success is-size-6 has-text-white"> Strong </span>
<span class="tag is-success is-size-6 has-text-white">
Strong
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> 30 </span>
<span class="tag is-success is-size-6 has-text-white"> Strong </span>
<span class="tag is-success is-size-6 has-text-white">
Strong
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Start Full Scan
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -288,146 +276,129 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
Full Neighbour Cell Scanner
</div>
<div class="card-header-title">Full Neighbour Cell Scanner</div>
</div>
<div class="card-content">
<table class="table is-fullwidth">
<thead>
<tr>
<th>
Name
</th>
<th>
EARFCN
</th>
<th>
Bandwidth
</th>
<th>
Physical ID
</th>
<th class="is-hidden-mobile">
RSRP
</th>
<th class="is-hidden-mobile">
RSRQ
</th>
<th class="is-hidden-mobile">
SINR
</th>
<th>Name</th>
<th>EARFCN</th>
<th>Bandwidth</th>
<th>Physical ID</th>
<th class="is-hidden-mobile">RSRP</th>
<th class="is-hidden-mobile">RSRQ</th>
<th class="is-hidden-mobile">SINR</th>
</tr>
</thead>
<tbody>
<tr>
<td>
B1
</td>
<td>
150
</td>
<td>
10
</td>
<td>
623
</td>
<td>B1</td>
<td>150</td>
<td>10</td>
<td>623</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -103 </span>
<span class="tag is-danger is-size-6 has-text-white"> Poor </span>
<span class="tag is-danger is-size-6 has-text-white">
Poor
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -103 </span>
<span class="tag is-danger is-size-6 has-text-white"> Poor </span>
<span class="tag is-danger is-size-6 has-text-white">
Poor
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -5 </span>
<span class="tag is-danger is-size-6 has-text-white"> Poor </span>
<span class="tag is-danger is-size-6 has-text-white">
Poor
</span>
</div>
</td>
</tr>
<tr>
<td>
B2
</td>
<td>
150
</td>
<td>
10
</td>
<td>
623
</td>
<td>B2</td>
<td>150</td>
<td>10</td>
<td>623</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -90 </span>
<span class="tag is-warning is-size-6 has-text-white"> Medium </span>
<span class="tag is-warning is-size-6 has-text-white">
Medium
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -90 </span>
<span class="tag is-warning is-size-6 has-text-white"> Medium </span>
<span class="tag is-warning is-size-6 has-text-white">
Medium
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> 10 </span>
<span class="tag is-warning is-size-6 has-text-white"> Medium </span>
<span class="tag is-warning is-size-6 has-text-white">
Medium
</span>
</div>
</td>
</tr>
<tr>
<td>
B3
</td>
<td>
150
</td>
<td>
10
</td>
<td>
623
</td>
<td>B3</td>
<td>150</td>
<td>10</td>
<td>623</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -65 </span>
<span class="tag is-success is-size-6 has-text-white"> Strong </span>
<span class="tag is-success is-size-6 has-text-white">
Strong
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> -65 </span>
<span class="tag is-success is-size-6 has-text-white"> Strong </span>
<span class="tag is-success is-size-6 has-text-white">
Strong
</span>
</div>
</td>
<td class="is-hidden-mobile">
<div class="tags has-addons">
<span class="tag is-size-6"> 30 </span>
<span class="tag is-success is-size-6 has-text-white"> Strong </span>
<span class="tag is-success is-size-6 has-text-white">
Strong
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Start Neighbourcell Scan
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -450,10 +421,11 @@
</div>
<p class="block has-text-weight-semibold">
Full Network Provider Cell Scanner will scan all of the cells in your area even from other
network providers.
Full Network Provider Cell Scanner will scan all of the cells in
your area even from other network providers.
<br />
The NR-5G scan will only display SA bands available in your area.
The NR-5G scan will only display SA bands available in your
area.
<br />
Scanning will take a few minutes so please wait patiently.
<br />
@@ -470,9 +442,11 @@
</div>
<p class="block has-text-weight-semibold">
Full Neighbour Cell Scanner will only scan the bands of your active network provider.
Full Neighbour Cell Scanner will only scan the bands of your
active network provider.
<br />
The NR-5G scan result is based on your current active 5G network mode.
The NR-5G scan result is based on your current active 5G network
mode.
<br />
If problem persists after scanning, please reboot the modem.
</p>
@@ -481,6 +455,25 @@
</div>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">40</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -1,29 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- Logo -->
<link rel="simpleadmin-logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<!-- Font awesome icons -->
<script src="https://kit.fontawesome.com/b0caedfab3.js" crossorigin="anonymous"></script>
<script
src="https://kit.fontawesome.com/b0caedfab3.js"
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -54,7 +58,7 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
@@ -67,7 +71,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -87,11 +98,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -127,9 +138,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
Basic Cellular Settings
</div>
<div class="card-header-title">Basic Cellular Settings</div>
</div>
<div class="card-content">
<div class="fixed-grid has-2-cols">
@@ -138,9 +147,15 @@
<div class="field">
<label class="label">Current APN</label>
<div class="control">
<input class="input" type="text" placeholder="Current APN Here">
<input
class="input"
type="text"
placeholder="Current APN Here"
/>
</div>
<p class="help">Changing this will disable automatic APN.</p>
<p class="help">
Changing this will disable automatic APN.
</p>
</div>
</div>
@@ -170,7 +185,9 @@
<p class="control has-icons-left">
<span class="select">
<select>
<option selected>Select Preferred Network Mode</option>
<option selected>
Select Preferred Network Mode
</option>
<option>Automatic</option>
<option>LTE Only</option>
<option>5G SA Only</option>
@@ -206,10 +223,16 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Save
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -219,9 +242,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
APN and ICCID Based Locking
</div>
<div class="card-header-title">APN and ICCID Based Locking</div>
</div>
<div class="card-content">
<div class="fixed-grid has-1-cols">
@@ -233,9 +254,15 @@
<div class="field">
<label class="label">APN Profile 1</label>
<div class="control">
<input class="input" type="text" placeholder="APN Here">
<input
class="input"
type="text"
placeholder="APN Here"
/>
</div>
<p class="help">This will override the current APN.</p>
<p class="help">
This will override the current APN.
</p>
</div>
</div>
@@ -245,7 +272,9 @@
<p class="control has-icons-left">
<span class="select">
<select>
<option selected>Select APN PDP Type</option>
<option selected>
Select APN PDP Type
</option>
<option>IPv4 Only</option>
<option>IPv6 Only</option>
<option>IPv4 and IPv6</option>
@@ -263,7 +292,11 @@
<div class="field">
<label class="label">ICCID Profile 1</label>
<div class="control">
<input class="input" type="text" placeholder="ICCID Here">
<input
class="input"
type="text"
placeholder="ICCID Here"
/>
</div>
</div>
</div>
@@ -278,9 +311,15 @@
<div class="field">
<label class="label">APN Profile 2</label>
<div class="control">
<input class="input" type="text" placeholder="APN Here">
<input
class="input"
type="text"
placeholder="APN Here"
/>
</div>
<p class="help">This will override the current APN.</p>
<p class="help">
This will override the current APN.
</p>
</div>
</div>
@@ -290,7 +329,9 @@
<p class="control has-icons-left">
<span class="select">
<select>
<option selected>Select APN PDP Type</option>
<option selected>
Select APN PDP Type
</option>
<option>IPv4 Only</option>
<option>IPv6 Only</option>
<option>IPv4 and IPv6</option>
@@ -308,7 +349,11 @@
<div class="field">
<label class="label">ICCID Profile 2</label>
<div class="control">
<input class="input" type="text" placeholder="ICCID Here">
<input
class="input"
type="text"
placeholder="ICCID Here"
/>
</div>
</div>
</div>
@@ -317,13 +362,18 @@
</div>
</div>
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Save
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
@@ -346,9 +396,11 @@
</div>
<p class="block has-text-weight-semibold">
Changing APN disconnects and reconnects the network automatically.
Changing APN disconnects and reconnects the network
automatically.
<br />
If problem persists after changing settings, please reboot the modem.
If problem persists after changing settings, please reboot the
modem.
<br />
Please use the settings with caution.
</p>
@@ -363,7 +415,8 @@
</div>
<p class="block has-text-weight-semibold">
APN and ICCID Based Locking will use a stored APN profile based on the current SIM's ICCID.
APN and ICCID Based Locking will use a stored APN profile based
on the current SIM's ICCID.
<br />
Currently experimental.
<br />
@@ -373,6 +426,25 @@
</div>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">40</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -1,29 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- Logo -->
<link rel="simpleadmin-logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<!-- Font awesome icons -->
<script src="https://kit.fontawesome.com/b0caedfab3.js" crossorigin="anonymous"></script>
<script
src="https://kit.fontawesome.com/b0caedfab3.js"
crossorigin="anonymous"
></script>
<script src="js/styles/nav-burger.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -54,9 +58,9 @@
<div id="navMenu" class="navbar-menu">
<div class="navbar-start ml-6">
<a class="navbar-item" href="/"> Home </a>
<a class="navbar-item has-text-weight-bold" href="/"> Home </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link has-text-weight-bold"> Cellular </a>
<a class="navbar-link"> Cellular </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/bandlock.html"> Band Locking </a>
<a class="navbar-item" href="/cell-locking.html">Cell Locking</a>
@@ -67,7 +71,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -87,11 +98,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -127,32 +138,34 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
SMS Inbox
</div>
<div class="card-header-title">SMS Inbox</div>
</div>
<div class="card-content">
<div class="fixed-grid has-1-cols" style="height: 450px; overflow-y: scroll;">
<div
class="fixed-grid has-1-cols"
style="height: 450px; overflow-y: scroll"
>
<div class="grid is-gap-4 is-fullwidth">
<div class="cell">
<div class="is-flex is-align-items-center">
<div class="checkbox mr-6">
<input type="checkbox">
<input type="checkbox" />
</div>
<div class="is-flex is-flex-direction-column is-align-items-start">
<div
class="is-flex is-flex-direction-column is-align-items-start"
>
<p class="has-text-weight-semibold">
Senders Name Here
</p>
<p>2022-11-20 13:30:00</p>
<p>
2022-11-20 13:30:00
</p>
<p>
Message content here. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Corrupti doloremque voluptatum velit repellendus
ipsum delectus blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur quo, deleniti ea
nihil.
Message content here. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Corrupti doloremque
voluptatum velit repellendus ipsum delectus
blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur
quo, deleniti ea nihil.
</p>
</div>
</div>
@@ -161,21 +174,22 @@
<div class="cell">
<div class="is-flex is-align-items-center">
<div class="checkbox mr-6">
<input type="checkbox">
<input type="checkbox" />
</div>
<div class="is-flex is-flex-direction-column is-align-items-start">
<div
class="is-flex is-flex-direction-column is-align-items-start"
>
<p class="has-text-weight-semibold">
Senders Name Here
</p>
<p>2022-11-20 13:30:00</p>
<p>
2022-11-20 13:30:00
</p>
<p>
Message content here. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Corrupti doloremque voluptatum velit repellendus
ipsum delectus blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur quo, deleniti ea
nihil.
Message content here. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Corrupti doloremque
voluptatum velit repellendus ipsum delectus
blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur
quo, deleniti ea nihil.
</p>
</div>
</div>
@@ -184,21 +198,22 @@
<div class="cell">
<div class="is-flex is-align-items-center">
<div class="checkbox mr-6">
<input type="checkbox">
<input type="checkbox" />
</div>
<div class="is-flex is-flex-direction-column is-align-items-start">
<div
class="is-flex is-flex-direction-column is-align-items-start"
>
<p class="has-text-weight-semibold">
Senders Name Here
</p>
<p>2022-11-20 13:30:00</p>
<p>
2022-11-20 13:30:00
</p>
<p>
Message content here. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Corrupti doloremque voluptatum velit repellendus
ipsum delectus blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur quo, deleniti ea
nihil.
Message content here. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Corrupti doloremque
voluptatum velit repellendus ipsum delectus
blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur
quo, deleniti ea nihil.
</p>
</div>
</div>
@@ -207,21 +222,22 @@
<div class="cell">
<div class="is-flex is-align-items-center">
<div class="checkbox mr-6">
<input type="checkbox">
<input type="checkbox" />
</div>
<div class="is-flex is-flex-direction-column is-align-items-start">
<div
class="is-flex is-flex-direction-column is-align-items-start"
>
<p class="has-text-weight-semibold">
Senders Name Here
</p>
<p>2022-11-20 13:30:00</p>
<p>
2022-11-20 13:30:00
</p>
<p>
Message content here. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Corrupti doloremque voluptatum velit repellendus
ipsum delectus blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur quo, deleniti ea
nihil.
Message content here. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Corrupti doloremque
voluptatum velit repellendus ipsum delectus
blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur
quo, deleniti ea nihil.
</p>
</div>
</div>
@@ -230,21 +246,22 @@
<div class="cell">
<div class="is-flex is-align-items-center">
<div class="checkbox mr-6">
<input type="checkbox">
<input type="checkbox" />
</div>
<div class="is-flex is-flex-direction-column is-align-items-start">
<div
class="is-flex is-flex-direction-column is-align-items-start"
>
<p class="has-text-weight-semibold">
Senders Name Here
</p>
<p>2022-11-20 13:30:00</p>
<p>
2022-11-20 13:30:00
</p>
<p>
Message content here. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Corrupti doloremque voluptatum velit repellendus
ipsum delectus blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur quo, deleniti ea
nihil.
Message content here. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Corrupti doloremque
voluptatum velit repellendus ipsum delectus
blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur
quo, deleniti ea nihil.
</p>
</div>
</div>
@@ -253,37 +270,42 @@
<div class="cell">
<div class="is-flex is-align-items-center">
<div class="checkbox mr-6">
<input type="checkbox">
<input type="checkbox" />
</div>
<div class="is-flex is-flex-direction-column is-align-items-start">
<div
class="is-flex is-flex-direction-column is-align-items-start"
>
<p class="has-text-weight-semibold">
Senders Name Here
</p>
<p>2022-11-20 13:30:00</p>
<p>
2022-11-20 13:30:00
</p>
<p>
Message content here. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Corrupti doloremque voluptatum velit repellendus
ipsum delectus blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur quo, deleniti ea
nihil.
Message content here. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Corrupti doloremque
voluptatum velit repellendus ipsum delectus
blanditiis quis dolores. Maxime labore esse
laboriosam inventore error molestiae consequuntur
quo, deleniti ea nihil.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Refresh
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Delete Selected
</a>
</div>
@@ -293,9 +315,7 @@
<div class="cell">
<div class="card">
<div class="card-header">
<div class="card-header-title">
Send SMS
</div>
<div class="card-header-title">Send SMS</div>
</div>
<div class="card-content">
<div class="fixed-grid has-5-cols has-1-cols-mobile">
@@ -304,7 +324,11 @@
<div class="field">
<label class="label">Receipient's Phone Number</label>
<div class="control has-icons-left">
<input class="input" type="text" placeholder="Input Phone Number">
<input
class="input"
type="text"
placeholder="Input Phone Number"
/>
<span class="icon is-small is-left">
<i class="fas fa-user"></i>
</span>
@@ -316,7 +340,10 @@
<div class="field">
<label class="label">Message</label>
<div class="control">
<textarea class="textarea" placeholder="Textarea"></textarea>
<textarea
class="textarea"
placeholder="Textarea"
></textarea>
</div>
</div>
</div>
@@ -324,19 +351,23 @@
</div>
</div>
<div class="card-footer">
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Send SMS
</a>
<a href="#" class="card-footer-item has-text-link has-text-weight-semibold has-text-white">
<a
href="#"
class="card-footer-item has-text-link has-text-weight-semibold has-text-white"
>
Reset
</a>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -352,13 +383,32 @@
</div>
<p class="block has-text-weight-semibold">
This is an experimental feature and may cause an error in some cases.
This is an experimental feature and may cause an error in some
cases.
</p>
</div>
</div>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none">
<div class="custom-loader"></div>
<div class="countdown-text">
Rebooting... <span id="countdown">40</span>s
</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -19,25 +19,16 @@ RAW_COMMAND=$(echo "$INPUT_DATA" | sed 's/command=//g')
# URL-decode the command
COMMAND=$(urldecode "$RAW_COMMAND")
# Save the command input to a unique at_input file
AT_INPUT_FILE="/tmp/at_input_$$.txt"
echo "$COMMAND" > "$AT_INPUT_FILE"
# Define unique input/output files and AT port
INPUT_FILE="/tmp/input_$$.txt"
OUTPUT_FILE="/tmp/output_$$.txt"
AT_PORT="/dev/smd11"
INPUT_FILE="/tmp/custom_input_$$.txt"
OUTPUT_FILE="/tmp/custom_output_$$.txt"
AT_PORT="/dev/smd7"
# Ensure exclusive access to the AT port to avoid overloading smd11
(
flock -x 200
# Copy the user input to the input file
cp "$AT_INPUT_FILE" "$INPUT_FILE"
# Write the command directly to the input file
echo "$COMMAND" > "$INPUT_FILE"
# Run the command using atinout
atinout "$INPUT_FILE" "$AT_PORT" "$OUTPUT_FILE"
) 200>/tmp/atinout.lock
# Read the output from output.txt
OUTPUT=$(cat "$OUTPUT_FILE")
@@ -58,4 +49,4 @@ echo "$JSON_RESPONSE" >> /tmp/cgi_debug.log
echo "$JSON_RESPONSE"
# Clean up temporary files
rm "$AT_INPUT_FILE" "$INPUT_FILE" "$OUTPUT_FILE"
rm "$INPUT_FILE" "$OUTPUT_FILE"

View File

@@ -15,7 +15,7 @@ INPUT_PASSWORD=$(echo "$POST_DATA" | sed -n 's/^.*password=\([^&]*\).*$/\1/p')
INPUT_PASSWORD=$(echo "$INPUT_PASSWORD" | sed 's/+/ /g;s/%\(..\)/\\x\1/g' | xargs -0 printf "%b")
# Log received password for debugging (remove in production)
echo "Received password: $INPUT_PASSWORD" >&2
# echo "Received password: $INPUT_PASSWORD" >&2
# Extract the hashed password from /etc/shadow for the specified user
USER_SHADOW_ENTRY=$(grep "^$USER:" /etc/shadow)

View File

@@ -1,11 +1,11 @@
/* */
/* import Poppins font */
@import url('https://fonts.googleapis.com/css2?family=Euclid+Flex:wght@400;500;600;700&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Euclid+Flex:wght@400;500;600;700&display=swap");
/* use Poppins everywhere */
* {
font-family: 'Poppins', sans-serif;
font-family: "Poppins", sans-serif;
}
html {
@@ -65,3 +65,98 @@ html.theme-light {
#dataConnState .tag {
transition: all 0.3s ease-in-out;
}
/* Add a bit of roundness on the corner */
.rounded-edge {
border-radius: 1rem;
}
.command-history {
max-height: 300px;
overflow-y: auto;
}
.loading {
opacity: 0.7;
pointer-events: none;
}
.history-item {
position: relative;
padding-right: 2rem;
}
.delete-history {
position: absolute;
top: 0.5rem;
right: 0.5rem;
cursor: pointer;
opacity: 0.7;
transition: opacity 0.2s;
}
.delete-history:hover {
opacity: 1;
}
.command-text {
cursor: pointer;
color: #485fc7;
}
.command-text:hover {
text-decoration: underline;
}
.no-history {
padding: 1rem;
text-align: center;
color: #7a7a7a;
}
@keyframes fadeOut {
to {
opacity: 0;
height: 0;
padding: 0;
margin: 0;
overflow: hidden;
}
}
.fade-out {
animation: fadeOut 0.3s ease-out forwards;
}
#cooldownTimer {
position: absolute;
right: 0.5rem;
top: 50%;
transform: translateY(-50%);
font-size: 0.8rem;
color: #666;
pointer-events: none;
}
.countdown-text {
text-align: center;
margin-top: 1rem;
margin-left: 1.5rem;
font-size: 1.2rem;
font-weight: 600;
}
/* Center content in modal */
.modal-card-body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 200px;
}
.custom-loader {
width:50px;
height:50px;
--c:radial-gradient(farthest-side,#766DF4 92%,#0000);
background:
var(--c) 50% 0,
var(--c) 50% 100%,
var(--c) 100% 50%,
var(--c) 0 50%;
background-size:12px 12px;
background-repeat:no-repeat;
animation:s7 1s infinite;
}
@keyframes s7 {to{transform: rotate(.5turn)}}

View File

@@ -19,9 +19,12 @@
crossorigin="anonymous"
></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/home/main.js"></script>
<script src="js/styles/toggle-theme.js"></script>
<script src="/js/styles/nav-burger.js"></script>
<script src="/js/styles/modal-trigger.js"></script>
<script src="/js/utils/reboot.js"></script>
<script defer src="/js/auth/auth.js"></script>
<script>
@@ -69,7 +72,14 @@
<a class="navbar-item" href="/cell-sms.html"> Cell SMS </a>
</div>
</div>
<a class="navbar-item" href="/advance-settings.html"> Advance </a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> Advance </a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="/advance-settings.html"> Advance Settings </a>
<a class="navbar-item" href="#">Experimental Features</a>
<a class="navbar-item" href="/cgi-bin/luci">OpenWRT Luci</a>
</div>
</div>
<a class="navbar-item" href="/about.html"> About </a>
</div>
@@ -89,11 +99,11 @@
</p>
<div class="is-flex is-mobile is-align-items-center">
<p class="control">
<a href="#" class="button is-warning is-outlined">
<div href="#" class="button is-warning is-outlined reboot-modal" data-target="reboot-modal" >
<span class="icon">
<i class="fas fa-power-off"></i>
</span>
</a>
</div>
</p>
<p class="control ml-2 is-mobile">
<a
@@ -463,5 +473,23 @@
</div>
</div>
</footer>
<div id="reboot-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<section class="modal-card-body rounded-edge">
<p class="subtitle" id="modal-message">
Do you want to reboot the device?
</p>
<div id="loading-content" style="display: none;">
<div class="custom-loader"></div>
<div class="countdown-text">Rebooting... <span id="countdown">80</span>s</div>
</div>
<div class="buttons" id="modal-buttons">
<button class="button is-warning" id="rebootModem">Reboot</button>
<button class="button cancel" aria-label="close">Cancel</button>
</div>
</section>
</div>
</div>
</body>
</html>

View File

@@ -1,23 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Logo -->
<link rel="simpleadmin-logo" href="favicon.ico" />
<link rel="stylesheet" href="css/bulma/bulma.scss">
<link rel="stylesheet" href="css/bulma/css/bulma.min.css">
<link rel="stylesheet" href="css/bulma/css/bulma.css">
<link rel="stylesheet" href="css/custom.css">
<link rel="stylesheet" href="css/bulma/bulma.scss" />
<link rel="stylesheet" href="css/bulma/css/bulma.min.css" />
<link rel="stylesheet" href="css/bulma/css/bulma.css" />
<link rel="stylesheet" href="css/custom.css" />
<script src="js/styles/toggle-theme.js"></script>
<script>
(function () {
const savedTheme = localStorage.getItem('theme') || 'theme-dark';
const savedTheme = localStorage.getItem("theme") || "theme-dark";
document.documentElement.classList.add(savedTheme);
})();
</script>
@@ -33,15 +32,16 @@
<div class="cell">
<div class="field is-grouped">
<div class="control">
<img src="/assets/logo.png" alt="Logo" class="image is-square image is-32x32">
<img
src="/assets/logo.png"
alt="Logo"
class="image is-square image is-32x32"
/>
</div>
<div class="control">
<h1 class="title">
QuecManager Login
</h1>
<h1 class="title">QuecManager Login</h1>
</div>
</div>
</div>
<div class="cell">
@@ -49,26 +49,38 @@
<div class="field">
<label class="label">Username</label>
<div class="control">
<input class="input" id="username" type="text" required placeholder="Username" />
<input
class="input"
id="username"
type="text"
required
placeholder="Username"
/>
</div>
</div>
<div class="field">
<label class="label">Password</label>
<div class="control">
<input class="input" id="password" type="password" required placeholder="********" />
<input
class="input"
id="password"
type="password"
required
placeholder="********"
/>
</div>
</div>
<button class="button is-primary" type="submit">Sign in</button>
<p id="error" class="has-text-danger has-text-weight-semibold mt-2">
</p>
<p
id="error"
class="has-text-danger has-text-weight-semibold mt-2"
></p>
</form>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,135 @@
document.addEventListener("DOMContentLoaded", function () {
const form = document.getElementById("commandForm");
const output = document.getElementById("output");
const commandInput = document.getElementById("command");
const sendButton = document.getElementById("sendButton");
const commandHistory = document.getElementById("commandHistory");
const noHistory = document.getElementById("noHistory");
const clearHistoryButton = document.getElementById("clearHistory");
const cooldownTimer = document.getElementById("cooldownTimer");
const COOLDOWN_DURATION = 1000; // 1 second cooldown
let isLoading = false;
let cooldownActive = false;
function setLoading(loading) {
isLoading = loading;
sendButton.classList.toggle("is-loading", loading);
form.classList.toggle("loading", loading);
}
function setCooldown() {
cooldownActive = true;
sendButton.classList.add("cooldown");
let timeLeft = COOLDOWN_DURATION;
function updateTimer() {
timeLeft -= 100;
if (timeLeft <= 0) {
cooldownActive = false;
sendButton.classList.remove("cooldown");
cooldownTimer.textContent = "";
return;
}
cooldownTimer.textContent = `${(timeLeft / 1000).toFixed(1)}s`;
setTimeout(updateTimer, 100);
}
updateTimer();
}
function updateHistoryVisibility() {
const hasHistoryItems =
commandHistory.querySelectorAll(".history-item").length > 0;
noHistory.style.display = hasHistoryItems ? "none" : "block";
clearHistoryButton.style.display = hasHistoryItems ? "block" : "none";
}
function addToHistory(command, response) {
const historyItem = document.createElement("div");
historyItem.className = "box mb-2 history-item";
historyItem.innerHTML = `
<button class="delete delete-history" aria-label="delete"></button>
<strong class="command-text">${command}</strong>
<pre style="margin-top: 0.5rem; font-size: 0.85em; white-space: pre-wrap;">${response}</pre>
`;
historyItem
.querySelector(".command-text")
.addEventListener("click", () => {
commandInput.value = command;
commandInput.focus();
});
historyItem
.querySelector(".delete-history")
.addEventListener("click", (e) => {
e.stopPropagation();
historyItem.classList.add("fade-out");
setTimeout(() => {
historyItem.remove();
updateHistoryVisibility();
}, 300);
});
commandHistory.insertBefore(historyItem, commandHistory.firstChild);
updateHistoryVisibility();
}
clearHistoryButton.addEventListener("click", () => {
const historyItems = commandHistory.querySelectorAll(".history-item");
historyItems.forEach((item) => {
item.classList.add("fade-out");
});
setTimeout(() => {
commandHistory.innerHTML = "";
commandHistory.appendChild(noHistory);
updateHistoryVisibility();
}, 300);
});
async function sendCommand(command) {
try {
setLoading(true);
const response = await fetch("/cgi-bin/atinout_handler.sh", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: `command=${encodeURIComponent(command)}`,
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
output.value = data.output || "No response received";
addToHistory(command, data.output || "No response received");
setCooldown();
} catch (error) {
const errorMessage = `Error: ${error.message}\n\nTroubleshooting steps:\n1. Check if the device is connected\n2. Verify AT port settings\n3. Ensure atinout utility is installed`;
output.value = errorMessage;
addToHistory(command, errorMessage);
} finally {
setLoading(false);
}
}
form.addEventListener("submit", async function (e) {
e.preventDefault();
if (isLoading || cooldownActive) return;
const command = commandInput.value.trim();
if (!command) {
output.value = "Please enter a command";
return;
}
await sendCommand(command);
commandInput.value = "";
});
// Initialize visibility
updateHistoryVisibility();
});

View File

@@ -1,108 +1,205 @@
document.addEventListener("DOMContentLoaded", () => {
// 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;
class AuthManager {
constructor() {
this.protectedPages = new Set([
'/home.html',
'/advance-settings.html',
'/bandlock.html',
'/cell-locking.html',
'/cell-scanner.html',
'/cell-settings.html',
'/cell-sms.html',
'/about.html'
]);
// Session timeout in milliseconds (e.g., 30 minutes)
this.sessionTimeout = 30 * 60 * 1000;
this.init();
}
// Initially hide the body to prevent content from flashing
document.body.style.display = "none";
init() {
// Initially hide the body to prevent content flashing
document.body.style.display = 'none';
// Check if the user is already logged in
const authToken = localStorage.getItem("authToken");
// Check authentication state
this.checkAuthState();
// Define which pages should be protected
const protectedPages = [
"/home.html",
"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
];
// Set up event listeners
this.setupEventListeners();
const currentPage = window.location.pathname;
// If the user is not logged in and tries to access a protected page, redirect to login
if (!authToken && protectedPages.includes(currentPage)) {
window.location.href = "index.html";
} else {
// Show the page if authentication is successful or not required
document.body.style.display = "";
// Show body after auth check
document.body.style.display = '';
}
// If the user is logged in and tries to access the login page, redirect to home
if (authToken && currentPage.includes("index.html")) {
window.location.href = "home.html";
generateAuthToken(length = 32) {
const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
return Array.from(crypto.getRandomValues(new Uint8Array(length)))
.map(x => charset[x % charset.length])
.join('');
}
// Login form logic (only for login page)
const loginForm = document.getElementById("loginForm");
if (loginForm) {
loginForm.addEventListener("submit", async (e) => {
e.preventDefault();
isProtectedPage(path) {
return this.protectedPages.has(path) ||
Array.from(this.protectedPages).some(page => path.includes(page));
}
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
const errorElement = document.getElementById("error");
getSessionData() {
const sessionStr = localStorage.getItem('session');
if (!sessionStr) return null;
try {
const formData = new URLSearchParams();
formData.append("username", username);
formData.append("password", encodeURIComponent(password)); // URL-encode the password
return JSON.parse(sessionStr);
} catch {
return null;
}
}
const response = await fetch("/cgi-bin/auth.sh", {
method: "POST",
setSessionData(token) {
const session = {
token,
lastActivity: Date.now(),
expiresAt: Date.now() + this.sessionTimeout
};
localStorage.setItem('session', JSON.stringify(session));
}
isSessionValid() {
const session = this.getSessionData();
if (!session) return false;
const now = Date.now();
// Check if session has expired
if (now > session.expiresAt) {
this.logout();
return false;
}
// Update last activity and extend session if needed
if (now - session.lastActivity > 5 * 60 * 1000) { // Update every 5 minutes
this.setSessionData(session.token);
}
return true;
}
checkAuthState() {
const currentPath = window.location.pathname;
const isAuthenticated = this.isSessionValid();
// Redirect logic
if (!isAuthenticated && this.isProtectedPage(currentPath)) {
window.location.href = '/index.html';
return false;
}
if (isAuthenticated && currentPath.includes('index.html')) {
window.location.href = '/home.html';
return false;
}
return true;
}
async login(username, password) {
try {
const formData = new URLSearchParams();
formData.append('username', username);
formData.append('password', encodeURIComponent(password));
const response = await fetch('/cgi-bin/auth.sh', {
method: 'POST',
body: formData,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
'Content-Type': 'application/x-www-form-urlencoded'
}
});
const result = await response.json(); // Parse JSON response
const result = await response.json();
if (result.state === "success") {
const newToken = generateAuthToken();
localStorage.setItem("authToken", newToken); // Store the token
window.location.href = "home.html"; // Redirect on success
} else {
document.getElementById("error").textContent =
"Invalid username or password";
console.log("Invalid username or password");
if (result.state === 'success') {
const token = this.generateAuthToken();
this.setSessionData(token);
window.location.href = '/home.html';
return true;
}
return false;
} catch (error) {
console.error('Login error:', error);
throw new Error('An error occurred during login');
}
}
logout() {
localStorage.removeItem('session');
window.location.href = '/index.html';
}
setupEventListeners() {
// Handle login form
const loginForm = document.getElementById('loginForm');
if (loginForm) {
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const errorElement = document.getElementById('error');
try {
const success = await this.login(username, password);
if (!success) {
errorElement.textContent = 'Invalid username or password';
}
} catch (error) {
// Handle any errors (e.g., network issues)
errorElement.textContent = "An error occurred. Please try again later.";
errorElement.textContent = error.message;
}
});
}
// Logout button logic (only for pages that have the logout button)
const logoutButton = document.getElementById("logoutButton");
// Handle component loading
window.addEventListener('componentLoaded', (event) => {
if (event.detail.componentId === 'nav-placeholder') {
this.setupNavbarHandlers();
}
});
// Set up periodic session check
setInterval(() => {
if (this.isProtectedPage(window.location.pathname)) {
this.isSessionValid();
}
}, 60000); // Check every minute
}
setupNavbarHandlers() {
// Handle 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
logoutButton.addEventListener('click', (e) => {
e.preventDefault();
this.logout();
});
}
// 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")) {
// Handle home navigation
const homeLinks = document.querySelectorAll('.navbar-item');
homeLinks.forEach(link => {
if (link.textContent.trim() === 'Home') {
link.addEventListener('click', (e) => {
e.preventDefault();
window.location.href = "home.html";
if (this.isSessionValid()) {
window.location.href = '/home.html';
} else {
window.location.href = '/index.html';
}
});
}
});
}
}
// Initialize auth manager when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
window.authManager = new AuthManager();
});

View File

@@ -0,0 +1,42 @@
document.addEventListener('DOMContentLoaded', () => {
// Functions to open and close a modal
function openModal($el) {
$el.classList.add('is-active');
}
function closeModal($el) {
$el.classList.remove('is-active');
}
function closeAllModals() {
(document.querySelectorAll('.modal') || []).forEach(($modal) => {
closeModal($modal);
});
}
// Add a click event on buttons to open a specific modal
(document.querySelectorAll('.reboot-modal') || []).forEach(($trigger) => {
const modal = $trigger.dataset.target;
const $target = document.getElementById(modal);
$trigger.addEventListener('click', () => {
openModal($target);
});
});
// Add a click event on various child elements to close the parent modal
(document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-body .cancel') || []).forEach(($close) => {
const $target = $close.closest('.modal');
$close.addEventListener('click', () => {
closeModal($target);
});
});
// Add a keyboard event to close all modals
document.addEventListener('keydown', (event) => {
if(event.key === "Escape") {
closeAllModals();
}
});
});

132
www/js/utils/reboot.js Normal file
View File

@@ -0,0 +1,132 @@
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('reboot-modal');
const rebootButton = document.getElementById('rebootModem');
const cancelButtons = modal.querySelectorAll('.cancel, .modal-background');
const restartConnectionBtn = document.querySelector('a.button.is-link.is-outlined');
const modalMessage = document.getElementById('modal-message');
const loadingContent = document.getElementById('loading-content');
const modalButtons = document.getElementById('modal-buttons');
const countdownElement = document.getElementById('countdown');
let countdownInterval;
function toggleModal(show = true) {
modal.classList.toggle('is-active', show);
document.documentElement.classList.toggle('is-clipped', show);
// Reset modal content when closing
if (!show) {
modalMessage.style.display = 'block';
loadingContent.style.display = 'none';
modalButtons.style.display = 'flex';
if (countdownInterval) {
clearInterval(countdownInterval);
}
countdownElement.textContent = '80';
}
}
function startCountdown() {
let timeLeft = 80;
// Update display for countdown
modalMessage.style.display = 'none';
loadingContent.style.display = 'flex';
modalButtons.style.display = 'none';
countdownInterval = setInterval(() => {
timeLeft--;
countdownElement.textContent = timeLeft;
if (timeLeft <= 0) {
clearInterval(countdownInterval);
window.location.reload();
}
}, 1000);
}
// Show modal when restart connection button is clicked
restartConnectionBtn.addEventListener('click', function(e) {
e.preventDefault();
toggleModal(true);
});
// Hide modal when cancel or background is clicked
cancelButtons.forEach(button => {
button.addEventListener('click', () => toggleModal(false));
});
// Handle ESC key press
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && modal.classList.contains('is-active')) {
toggleModal(false);
}
});
// Function to send AT command
async function sendRebootCommand() {
try {
// Disable the reboot button and show loading state
rebootButton.classList.add('is-loading');
rebootButton.disabled = true;
const response = await fetch('/cgi-bin/atinout_handler.sh', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'command=' + encodeURIComponent('AT+CFUN=1,1')
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
if (data.output && data.output.includes('OK')) {
startCountdown();
} else {
throw new Error('Reboot command failed');
}
} catch (error) {
console.error('Error:', error);
toggleModal(false);
showNotification('Failed to reboot device. Please try again.', 'is-danger');
} finally {
// Re-enable the reboot button and remove loading state
rebootButton.classList.remove('is-loading');
rebootButton.disabled = false;
}
}
// Function to show notification (for errors only now)
function showNotification(message, type = 'is-info') {
const notification = document.createElement('div');
notification.className = `notification ${type} is-light`;
notification.style.position = 'fixed';
notification.style.top = '1rem';
notification.style.right = '1rem';
notification.style.zIndex = '9999';
notification.style.maxWidth = '300px';
const deleteButton = document.createElement('button');
deleteButton.className = 'delete';
deleteButton.addEventListener('click', () => notification.remove());
notification.appendChild(deleteButton);
notification.appendChild(document.createTextNode(message));
document.body.appendChild(notification);
setTimeout(() => {
if (document.body.contains(notification)) {
notification.remove();
}
}, 5000);
}
// Handle reboot button click
rebootButton.addEventListener('click', sendRebootCommand);
});