This commit is contained in:
devdatt 2026-01-08 06:49:32 +05:30
parent fa6a8b6e61
commit 503c86ac0a
6 changed files with 120 additions and 1518 deletions

View File

@ -1,214 +0,0 @@
<?php include 'header.php'; ?>
<?php
$jsonFile = __DIR__ . '/domain.json';
$defaults = [
'domain' => 'example.com',
'subdomain' => 'www.example.com',
'email' => 'name@example.com',
];
if (file_exists($jsonFile)) {
$raw = file_get_contents($jsonFile);
$data = json_decode($raw, true);
if (!is_array($data)) $data = $defaults;
} else {
$data = $defaults;
}
?>
<body>
<style>
:root {
--accent: #0b74de;
--muted: #6b7280;
--bg: #f8fafc
}
body {
font-family: Inter, system-ui, Arial, Helvetica, sans-serif;
background: var(--bg);
color: #111;
margin: 0;
padding: 28px
}
.wrap {
width: 100%;
margin: 0;
padding: 0
}
.card {
background: #fff;
border-radius: 10px;
padding: 18px;
box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06)
}
label {
display: block;
margin-top: 12px;
font-weight: 600
}
input[type=text],
input[type=email],
select {
width: 100%;
padding: 10px;
margin-top: 6px;
border: 1px solid #e6eef6;
border-radius: 8px
}
.row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px
}
.muted {
color: var(--muted);
font-size: 13px
}
.actions {
display: flex;
gap: 8px;
margin-top: 14px
}
button {
padding: 10px 14px;
border-radius: 8px;
border: 0;
background: var(--accent);
color: #fff;
font-weight: 700
}
.ghost {
background: transparent;
border: 1px solid #e6eef6;
color: var(--accent)
}
.links {
margin-top: 10px
}
.note {
margin-top: 12px;
padding: 10px;
background: #f1f5f9;
border-radius: 8px;
font-size: 13px
}
.checkbox {
display: flex;
align-items: flex-start;
gap: 8px;
margin-top: 12px
}
pre {
white-space: pre-wrap;
background: #fbfcfe;
padding: 10px;
border-radius: 6px;
border: 1px dashed #e6eef6;
font-size: 13px
}
@media (max-width:700px) {
.row {
grid-template-columns: 1fr
}
}
</style>
<div class="containerindex">
<div class="grid">
<div class="wrap">
<div class="card">
<form method="post" action="request_cert.php">
<label for="domain">Primary domain</label>
<input id="domain" name="domain" type="text" placeholder="example.com" required pattern="^[A-Za-z0-9.-]{1,253}$" value="<?php if ($data['domain'] !== "example.com") echo $data['domain']; ?>" />
<label for="subdomains" class="muted">Subdomains</label>
<input id="subdomains" name="subdomains" type="text" placeholder="example.com (optional)" value="<?php if ($data['subdomain'] !== "www.example.com") echo $data['subdomain']; ?>" />
<label for="email">Contact email (for Let\'s Encrypt notices)</label>
<input id="email" name="email" type="email" placeholder="your_name@example.com" value="<?php if ($data['email'] !== "name@example.com") echo $data['email']; ?>" required />
<div class="row">
<div>
<label for="staging">Test mode</label>
<select id="staging" name="staging">
<option value="0">Production</option>
<option value="1">Staging (use for testing to avoid rate limits)</option>
</select>
</div>
</div>
<div class="checkbox">
<input type="checkbox" id="agree_tc" name="agree_tc" required />
<div>
<label for="agree_tc" style="font-weight:700">I agree to Certbot's Terms of Service and confirm that ports <strong>80 (HTTP)</strong> and <strong>443 (HTTPS)</strong> are forwarded to this server.</label>
<div class="muted">By checking this you authorise the server operator to run Certbot and modify nginx configuration for the supplied domain(s).</div>
</div>
</div>
<div class="links">
<a href="https://letsencrypt.org/repository/#let-s-encrypt-subscriber-agreement" target="_blank" rel="noopener">Certbot / Let's Encrypt Terms &amp; Conditions</a>
&nbsp;&nbsp;
<a href="https://letsencrypt.org/privacy/">Privacy Policy</a>
</div>
<div class="actions">
<button type="submit">Request Certificate</button>
<button type="reset" class="ghost">Reset</button>
</div>
<div class="note">
<strong>Why ports 80 and 443 are required</strong>
<pre>
- Port 80 (HTTP) is used by Certbot for the HTTP-01 challenge: Let's Encrypt connects over HTTP to verify you control the domain.
- Port 443 (HTTPS) is required to serve TLS traffic after the certificate is issued. Nginx must accept HTTPS on port 443 so browsers and streaming clients can connect securely.
Ensure both ports are reachable from the public internet and forwarded to this server's IP. If you use a firewall, add rules to allow inbound TCP 80 and 443.
</pre>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
document.getElementById('certForm').addEventListener('submit', function(e) {
var dom = document.getElementById('domain').value.trim();
var subs = document.getElementById('subdomains').value.trim();
if (!dom) {
e.preventDefault();
alert('Primary domain is required');
return;
}
var ok = document.getElementById('agree_tc').checked;
if (!ok) {
e.preventDefault();
alert('You must agree to the terms and confirm ports 80 and 443 are forwarded.');
}
});
</script>
</body>
<?php include 'footer.php'; ?>

View File

@ -162,7 +162,7 @@ EwIDAQAB
$zip = new ZipArchive();
if ($zip->open($zipFile) !== true) {
error_log("zip unzip problem");
error_log("zip unzip problem");
fail('Unable to open ZIP');
}
for ($i = 0; $i < $zip->numFiles; $i++) {
@ -220,13 +220,10 @@ EwIDAQAB
exec('sudo reboot');
break;
case 'backup':
$jsonFiles = [
'input.json',
'output.json',
'firewall.json',
'network.json',
'firmware.json',
];
$tmpZip = sys_get_temp_dir() . '/backup.zip';
@ -238,8 +235,6 @@ EwIDAQAB
$zip = new ZipArchive();
$zip->open($tmpZip, ZipArchive::CREATE | ZipArchive::OVERWRITE);
/* Add JSON files if exist */
foreach ($jsonFiles as $json) {
if (file_exists($json)) {
$zip->addFile($json, basename($json));
@ -249,11 +244,9 @@ EwIDAQAB
$zip->close();
$data = file_get_contents($tmpZip);
/* Generate AES key */
$aesKey = random_bytes(32);
$iv = random_bytes(16);
/* Encrypt ZIP */
$encryptedData = openssl_encrypt(
$data,
'AES-256-CBC',
@ -262,10 +255,7 @@ EwIDAQAB
$iv
);
/* Encrypt AES key using RSA public key */
openssl_public_encrypt($aesKey, $encryptedKey, $publicKey);
/* Final binary format */
$payload = json_encode([
'key' => base64_encode($encryptedKey),
'iv' => base64_encode($iv),
@ -281,7 +271,6 @@ EwIDAQAB
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
echo $payload;
flush();
@ -292,10 +281,8 @@ EwIDAQAB
case 'restore':
$jsonFiles = [
'input.json',
'output.json',
'firewall.json',
'network.json',
'firmware.json',
];
foreach ($jsonFiles as $json) {
@ -372,15 +359,6 @@ EwIDAQAB
$zip->close();
unlink($tmpZip);
update_service("display");
update_service("rtmp0");
update_service("rtmp1");
update_service("udp0");
update_service("udp1");
update_service("udp2");
update_service("srt");
update_service("custom");
update_service("input");
break;
}
}

View File

@ -270,6 +270,8 @@
<span class="pill"><a style="color: #ffffff;" href="tel:+918000741919">Call Us</a></span>
<span class="pill"><a style="color: #ffffff;" href="certification.html">Certificate</a></span>
</div>
<div class="pill-row">
</div>
<div class="footer">
<div class="brand">

116
html/input.php Normal file
View File

@ -0,0 +1,116 @@
<?php include 'header.php'; ?>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
button { padding: 8px 14px; cursor: pointer; }
#popup {
display:none; position: fixed; top: 50%; left: 50%;
transform: translate(-50%, -50%); background: #fff;
padding: 20px; border:1px solid #333; width: 350px;
}
#popup input, #popup select { width: 100%; margin-bottom: 10px; padding: 6px; }
#overlay { display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.6); }
.table { width: 100%; border-collapse: collapse; margin-top: 20px; }
.table th, .table td { padding: 10px; border: 1px solid #ccc; text-align: left; }
</style>
</head>
<h2>Service List</h2>
<button onclick="openPopup()">Add Service</button>
<!-- TABLE LIST -->
<table class="table">
<tr>
<th>ID</th>
<th>Input UDP</th>
<th>Output UDP</th>
<th>Video Format</th>
<th>Audio Format</th>
<th>Resolution</th>
<th>Video Bitrate</th>
<th>Audio Bitrate</th>
<th>Status</th>
</tr>
<?php foreach ($data as $row): ?>
<tr>
<td><?= htmlspecialchars($row["id"]) ?></td>
<td><?= htmlspecialchars($row["input_udp"]) ?></td>
<td><?= htmlspecialchars($row["output_udp"]) ?></td>
<td><?= htmlspecialchars($row["video_format"]) ?></td>
<td><?= htmlspecialchars($row["audio_format"]) ?></td>
<td><?= htmlspecialchars($row["resolution"]) ?></td>
<td><?= htmlspecialchars($row["video_bitrate"]) ?></td>
<td><?= htmlspecialchars($row["audio_bitrate"]) ?></td>
<td><?= htmlspecialchars($row["status"]) ?></td>
</tr>
<?php endforeach; ?>
</table>
<!-- POPUP -->
<div id="overlay"></div>
<div id="popup">
<h3>Add Service</h3>
<input type="text" id="in_udp" placeholder="Input UDP">
<input type="text" id="out_udp" placeholder="Output UDP">
<select id="video_format">
<option value="h264">H.264</option>
<option value="h265">H.265</option>
</select>
<select id="audio_format">
<option value="aac">AAC</option>
<option value="mp3">MP3</option>
</select>
<select id="resolution">
<option value="1920x1080">1920x1080</option>
<option value="1280x720">1280x720</option>
<option value="720x576">720x576</option>
</select>
<input type="text" id="video_bitrate" placeholder="Video Bitrate (kbps)">
<input type="text" id="audio_bitrate" placeholder="Audio Bitrate (kbps)">
<select id="status">
<option value="enable">Enable</option>
<option value="disable">Disable</option>
</select>
<button onclick="saveService()">Save</button>
<button onclick="closePopup()">Close</button>
</div>
<script>
function openPopup() {
document.getElementById("popup").style.display = "block";
document.getElementById("overlay").style.display = "block";
}
function closePopup() {
document.getElementById("popup").style.display = "none";
document.getElementById("overlay").style.display = "none";
}
function saveService() {
let form = new FormData();
form.append("action", "add");
form.append("input_udp", document.getElementById("in_udp").value);
form.append("output_udp", document.getElementById("out_udp").value);
form.append("video_format", document.getElementById("video_format").value);
form.append("audio_format", document.getElementById("audio_format").value);
form.append("resolution", document.getElementById("resolution").value);
form.append("video_bitrate", document.getElementById("video_bitrate").value);
form.append("audio_bitrate", document.getElementById("audio_bitrate").value);
form.append("status", document.getElementById("status").value);
fetch("input.php", { method: "POST", body: form })
.then(r => r.text())
.then(res => {
if (res === "OK") location.reload();
});
}
</script>
<?php include 'footer.php'; ?>

View File

@ -1,146 +0,0 @@
<?php
// request_cert.php
// Parameters (POST):
// - domain (required)
// - subdomains (optional, comma-separated)
// - email (required)
// - staging (0 or 1)
$FORM_PAGE = "domain.php"; // redirect back to your form
$https = false;
function alert_and_back($message)
{
global $https;
global $domain;
global $subdomains_raw;
global $email;
$jsonFile = __DIR__ . '/domain.json';
$new = [
'domain' => $domain,
'subdomain' => $subdomains_raw,
'email' => $email,
'https' => $https
];
$json = json_encode($new, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
file_put_contents($jsonFile, $json, LOCK_EX);
global $FORM_PAGE;
// SAFELY escape entire message for JavaScript (supports newlines, quotes, etc.)
$msg = json_encode($message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
// Escape redirect target too
$page = json_encode($FORM_PAGE);
echo "<script>
(function(){
var msg = $msg;
var dest = $page;
// Run after DOM to avoid errors when printed inside <head>
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function(){
alert(msg);
window.location.href = dest;
});
} else {
alert(msg);
window.location.href = dest;
}
})();
</script>";
exit;
}
$domain = trim($_POST['domain'] ?? '');
$subdomains_raw = trim($_POST['subdomains'] ?? '');
$email = trim($_POST['email'] ?? '');
$staging = ($_POST['staging'] ?? "0") === "1" ? 1 : 0;
// Validation helpers
function valid_domain_name($d)
{
$d = trim($d); // important!
return (bool) preg_match(
'/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i',
$d
);
}
// Validate domain
if ($domain === '' || !valid_domain_name($domain)) {
alert_and_back("Invalid domain name.");
}
// Validate email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
alert_and_back("Invalid email address.");
}
// Process subdomains
$subdomains = [];
if ($subdomains_raw !== '') {
$parts = preg_split('/[,\s;]+/', $subdomains_raw, -1, PREG_SPLIT_NO_EMPTY);
foreach ($parts as $p) {
$p = trim($p);
if ($p === '') continue;
// If user only entered "www", convert -> www.domain.com
if (strpos($p, '.') === FALSE) {
$candidate = "$p.$domain";
} else {
$candidate = $p;
}
if (!valid_domain_name($candidate)) {
alert_and_back("Invalid subdomain: $p");
}
$subdomains[] = $candidate;
}
}
// Merge primary domain + subdomains
$domains = array_values(array_unique(array_merge([$domain], $subdomains)));
// Build Certbot -d parameters
$dargs = "";
foreach ($domains as $d) {
$dargs .= " -d " . escapeshellarg($d);
}
// Build certbot command
$certbot = "/usr/bin/certbot";
$cmd = "sudo $certbot --nginx --agree-tos --non-interactive --email "
. escapeshellarg($email)
. " $dargs";
if ($staging === 1) {
$cmd .= " --staging";
}
// Run certbot
exec("$cmd 2>&1", $out, $rc);
if ($rc !== 0) {
alert_and_back("Certbot failed:\n" . implode("\n", $out));
}
// Test nginx
exec("sudo nginx -t 2>&1", $test_out, $test_rc);
if ($test_rc !== 0) {
alert_and_back("Certificate created, but nginx test failed:\n" . implode("\n", $test_out));
}
// Reload nginx
exec("sudo systemctl reload nginx 2>&1", $reload_out, $reload_rc);
if ($reload_rc !== 0) {
alert_and_back("Cert created, nginx tested OK, but reload failed:\n" . implode("\n", $reload_out));
}
$https = true;
// Success
alert_and_back("Certificate installed successfully for:\n" . implode(", ", $domains));

File diff suppressed because it is too large Load Diff