This commit is contained in:
devdatt 2026-01-08 05:35:36 +05:30
commit fa6a8b6e61
26 changed files with 5973 additions and 0 deletions

0
attempts.json Normal file
View File

52
backup_private.pem Normal file
View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCaSua4bKKMn8hX
zoH8afGUjdAd5WuLBZk8X4L98LxMN4fPcy7NwOPlEb6JUNnBcrbtOYbA++bOuXho
LMNLPQJhXpSPV2Bdyu9ttDZ3HSEiTl8aauQixNec2LxBaXdVl9BptPYPy9ME0uMR
lk/RZgUmQHs6+NmZS02MLUH1H8hOWgcse15MXLdb5ZRSwqsjsLnuAKeyrbjbYdAb
Xjv9hQRQMeFwfI/dByPzv1TZ5CbJJ8hRO4unzXLCx5XTVfyFbhaChCAJi32FCZSW
wtPEIX3/Vxu/SeAO3Z8PSdDEPPirFUYkEV+JB3m3Ts0dsYCFo78STa/KhmMkGEtA
dK+Pe2zWd8Z5cLg2DHtQROyLJ+iGX767kPOB04PlG+rJTDYHOZBAMgKv4DxiDMRK
hRNF4l3CDiKtnA35au6bjuWgiseTfgQuRuJt9GK7tnN+r6RcUPRVs1Ys/1EvJDLd
4e9VAiZraELnFprE3N/oh3F6TVDTUr/bCY++RGLCEFOY5iUQ/4FnJHONbFYRdYa8
ga2gfZYA+X2x26thdn0rjoj5Opl5K/AQ7l7DYz2VJjG+ZTYAV0Y7Frb9HDEsoZa3
/oqDlbB7jk6t3ZbxN9LpDODITqfid8hLlURm2F9uW/wU4GVWc0D0nnZnaoXPL0nA
bQWZuwpK06QiIIxDKs/MsIQfaIlNKwIDAQABAoICAEeB/kMsCfvdk8bqLQE0gqOk
Q/ePG9P/IMFDzNxvRX2XYOiKy/7M7nH8Us+mOn228kOonST0ukhF2iGB2XMVz/Qb
lwOF7eIaSvQPiQyUYgZZxybhsmDQ1NLa+gjg3c88AHn1RfMVNnPuXxGIFe8I9sr/
KH2w1nx+025rjT2TYMy7WcbKWG5QrCQ5lw/yK8nrPoipIg+kBuAaCY6dknURQGoA
bCireitog0eU/bjMThN9ThAj5jo7c/wE7xHWsKWQW3tay9RQozhUs9pZajbkhNYh
43i4vtB08yJtRgWk8mSsA+l0adACuGz15wdjfBqzxLqxaY8V0H3qinnReoonnE1i
wpBpK34DFL8NIWJZ2SVpnn847kW/cP0jxeLDDgQZMPC8WDSQsu1gOO+n98ACr9Iv
WuXp3TcIsHSXNQm6KATH9opiNM7dqxR2KklGYNBC+Vr2Z1J8nszLUtNH+VeU30qE
Q/4p/M9Akqy6fI4Gx52a98f1hyeG0VGJ247qA56Mlg1lUMZoBjr57xpHgoVBc3Bp
YvTuN9eNUJWgkSFWwiET+sjbVLLnwyH3pDCjohl9PLUze2RqMhb3WWHy/ZelzEnX
k71XuCseduCO4jgpQeGy3bg8k1qJaj0veiuon6+WVvZ333iwO4cWF/bxPJkgLS0X
pRf2e8iGBppXFR641YxhAoIBAQDXGa+2t9tFq6EQBgvYMVxP+b0y2DCJAt2mq3ZT
sABSExbg6/o9ZW+wE9CE5G7Vh6Tqu1kgMwCUY4LWBj/hPrb7n817H78e0kkUemHh
NehvPSgHnwOPoRl2suQTy60I7Qdr3pWnkrqIixJFGL/HB9ULiBV/+iEfzdiivIqL
5mTRtAnRjtPHaPD5pCm9YqI0lFJGs9PNQUnDHt0JgemNCzeqAWwoonI/szcSxvrT
0qQJI7688Hgr/fRnG6hAkOYN4QyIpwZ9fF43MzH3WiwkRz3YKVEiEkoZXTLK5X05
7/X4H6TY/AG2puFhwBALcLE2CjutHCmsllCi/8W970lL1kqhAoIBAQC3oU+wlnIt
bMNsVraTDvTfN+3H96sJ/snh0mDZQYyUxbN22TMnEqcjKJ/afNymvp3UffZT9EiK
wm05UxMlBXAXPTiXI+71K9QVgew9lIoXop8/7BoACeLCvzRsFzYNsH0vtDHTz1yO
0RGrarb3BsONeDLtUikwfgi+CLtYRbSeRAULvU29yOFr10cHOXw7ItDMBSMwU/hP
3aKSEYAn6CVqLqAAPr6T5RwjXuT2daDKoyq3P/X0NkLMVMtGaeSjO41QnLf4pSWb
7x1ec0D6l6OEboKLilknh/x/2nedmOwAEiNM4pSIhqSY1JZw6rO+J6Y6FEkdxzy0
zWYLLQEdO3BLAoIBAQC0KzHBDHNAAihgcZAOQBogawEMy4Sr3pil+EyegHdkR9UM
BNyP/Jz2kUJBbc1gUcPTUaWvkMjVghyfBJERLCS80vecP9UoDd9kpbXCnBLayhDz
gT/MWJYplGHyKtH+/fsPYVtdB0vy/voIolhQb8EFbbEEhxCjwRnKBb7Ou+aKuBDZ
VJcTGlVt5RGJLkrLW8kmq42nCR6trvZZ9lUX7ONtJM/hoV+s94IT2lNShcccWLJ1
M76UqpzCmKnvmu73hR+ofq6zAS8xcVJS61a59Gpa2xC4RzWF1UisJlkj5FjUwjyj
+0G8Kj/yTpuh2Xy11RBzSXmmtClKvo51Ly7ntNDBAoIBACwZfmTfTJ5iH3CWRpR8
pAwzh1Rdw2LMILmt53plhph3/kiNkv5QOXl1GSbEk80rvAW7FnxFD2LbnJWGwPNE
Ig5CsqOBirKwiud7YzvKv3s7n9kfH4Ng3Gd+ud03mdCh0P6y3MCMbSMTTJYJM9WR
d0czVa+u6pttuTXCLRPe8aiMl1WhadkpNBHNCo7OnGorS0+j8DZ8BAdSJ+fCci+j
TdD5T42fg+9Kt347HOufhjUECI8nui6jFVmzB3pqlfEprR9t87SwHJ8dRsVXEoTc
A/YbABj46b5XpykhU1ay0gKWWInvZFKBW2gkrdiCVRZWuVH7ay/OmGKnbVlDvp/B
lY8CggEALa9Dw8kMDet9sysx4zC9f3IyQT6iR15RaD6uTc2J2wTBjry5deC+M+pt
g277uvfRgr5EGsXidJ03jD7Sc5wNM1i1q1AC8QPAKX4j0l35N7SxjJP+cxIdwll+
dQqg0dr1A4mCbgm22IatmlvEH4oGu/WozDDlhz11WLhG2m28npAspdEAacCsvncX
DDzaff/4FxjN8BilhqBHaLgZuqQROfDVWJb7vfq/BTO4uZBUjYONLEgG37cA002H
HIBqMEzbewdNtLSbi4xCvmgnofZ1WtsyPfAWCHX+A6wjF8Ey8PdU2/0ILHQwx3WO
oo7uGCyxw179QUUzXs18xVnordQGvA==
-----END PRIVATE KEY-----

14
backup_public.pem Normal file
View File

@ -0,0 +1,14 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmkrmuGyijJ/IV86B/Gnx
lI3QHeVriwWZPF+C/fC8TDeHz3MuzcDj5RG+iVDZwXK27TmGwPvmzrl4aCzDSz0C
YV6Uj1dgXcrvbbQ2dx0hIk5fGmrkIsTXnNi8QWl3VZfQabT2D8vTBNLjEZZP0WYF
JkB7OvjZmUtNjC1B9R/ITloHLHteTFy3W+WUUsKrI7C57gCnsq2422HQG147/YUE
UDHhcHyP3Qcj879U2eQmySfIUTuLp81ywseV01X8hW4WgoQgCYt9hQmUlsLTxCF9
/1cbv0ngDt2fD0nQxDz4qxVGJBFfiQd5t07NHbGAhaO/Ek2vyoZjJBhLQHSvj3ts
1nfGeXC4Ngx7UETsiyfohl++u5DzgdOD5RvqyUw2BzmQQDICr+A8YgzESoUTReJd
wg4irZwN+Wrum47loIrHk34ELkbibfRiu7Zzfq+kXFD0VbNWLP9RLyQy3eHvVQIm
a2hC5xaaxNzf6Idxek1Q01K/2wmPvkRiwhBTmOYlEP+BZyRzjWxWEXWGvIGtoH2W
APl9sdurYXZ9K46I+TqZeSvwEO5ew2M9lSYxvmU2AFdGOxa2/RwxLKGWt/6Kg5Ww
e45Ord2W8TfS6QzgyE6n4nfIS5VEZthfblv8FOBlVnNA9J52Z2qFzy9JwG0FmbsK
StOkIiCMQyrPzLCEH2iJTSsCAwEAAQ==
-----END PUBLIC KEY-----

34
html/about_us.php Executable file
View File

@ -0,0 +1,34 @@
<?php include 'header.php'; ?>
<div class="containerindex">
<div class="grid">
<div class="card wide">
<h3>ShreeBhattJi</h3>
<p>If youve ever read the Panchatantra, a few stories begin like this: “Once upon a time, there lived a poor Brahmin in a village. In this story, that Brahmin is me ShreeBhattJi, also known as Devdatt Bhatt, the King of Automation and Remote Control from the land of great beginnings, Bhavnagar.
<p>I am here to help provide a great viewing experience for users, generate strong commissions for LCOs, MSOs, and ISPs, and create substantial revenue for content owners while contributing fair taxes to the government. I have reason to believe that by upgrading a few devices at the transmission point, both streaming operations and customer viewing experiences can be improved exponentially.
<p>We are proud to present Universal Digital Encoder Decoder as all format to all format encoder cum decoder for dedicated hardware , virtual machines and proxmox lxc images .
<p><a href="https://urmic.org/trusted-partners/" target="_blank"><button class="red-btn">Meet Our Partners</button></a>
</div>
<div class="card wide">
<h3>Bhavnagar :- The Land Of Great Beginnings</h3>
<ul>
<li>The great country called India began to exist at Bhavnagar. On 15 August 1947, Indian administrative control effectively began with Bhavnagar after Maharaja Krishnakumarsinhji Bhavsinhji Gohil merged his princely state into the independent Union of India.</li>
<p>
<li>The “bull gift” from Maharaja Krishnakumarsinhji of Bhavnagar to Brazilian cattle baron Celso Garcia Sid helped shape the Brazilian dairy industry, leading to the world-famous Girolando breed. Today, Girolando cows produce over 80% of Brazils milk. <a href="https://youtu.be/HLJHFibZ130">DD INDIA REPORT</a></li>
<p>
<li>The first diamond-cutting industry in India started in Bhavnagar, not Surat. Skilled jewelers and artisans in Bhavnagar (Saurashtra region, Gujarat) began cutting and polishing small rough diamonds imported from Africa. These craftsmen later moved to Surat, which eventually became the worlds largest diamond-cutting and polishing hub.</li>
<p>
<li>The largest ship-breaking yard in the world, “Alang Ship Breaking Yard, located in Bhavnagar district, Gujarat, started operations in 1983. It handles over 50% of global ship recycling by tonnage and is a major source of recycled steel for Indias economy.</li>
<p>
<li>After the Kurukshetra war, the Pandavas sought absolution for the killing that occurred in battle. Following the guidance of Lord Krishna, who gave them a black flag and a black cow, they were instructed to follow the cow until both turned white. Krishna told them that when this happened, they would be forgiven. The Pandavas followed the cow for many years to various places, but the flag and cow remained black. Finally, when they reached Koliyak Beach, both miraculously turned white.</li>
<br>
<br>
<br>
<br>
</ul>
</div>
</div>
</div>
<br>
<br>
<?php include 'footer.php'; ?>

186
html/certification.html Normal file
View File

@ -0,0 +1,186 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Self Certification</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
background: #f4f6f8;
margin: 0;
padding: 0;
color: #111;
}
.top-bar {
background: #0f172a;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.top-bar button {
background: #2563eb;
border: none;
color: #fff;
padding: 8px 16px;
font-size: 14px;
cursor: pointer;
border-radius: 4px;
}
.top-bar button:hover {
background: #1d4ed8;
}
.container {
max-width: 900px;
margin: 24px auto;
background: #ffffff;
padding: 32px;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
h1 {
text-align: center;
margin-bottom: 24px;
}
p {
line-height: 1.6;
margin-bottom: 16px;
font-size: 15px;
}
.section-title {
font-weight: bold;
margin-top: 24px;
margin-bottom: 8px;
}
.signature {
margin-top: 48px;
display: flex;
justify-content: space-between;
}
.sign-box {
width: 40%;
}
.sign-line {
margin-top: 40px;
border-top: 1px solid #000;
padding-top: 6px;
font-size: 14px;
}
@media print {
.top-bar {
display: none;
}
body {
background: #fff;
}
.container {
box-shadow: none;
margin: 0;
border-radius: 0;
}
}
</style>
<script>
function goHome() {
window.location.href = "index.html";
}
function printPage() {
window.print();
}
</script>
</head>
<body>
<div class="top-bar">
<button onclick="goHome()">Home</button>
<button onclick="printPage()">Print</button>
</div>
<div class="container">
<h1>Self Certification Declaration</h1>
<p>
This document serves as a formal self-certification confirming compliance with all applicable
legal, security, and operational requirements related to the provided software, firmware,
service, or system.
</p>
<div class="section-title">Compliance & Safety Declaration</div>
<p>
I hereby declare and guarantee that the delivered software or system contains no malware,
spyware, backdoors, or harmful components of any kind. The system does not perform unauthorized
surveillance, user behavior tracking, or data collection beyond what is strictly required for
its intended operation.
</p>
<div class="section-title">Privacy Assurance</div>
<p>
No usage tracking, analytics, or hidden monitoring mechanisms are implemented. Any data processed
by the system is handled transparently and solely for functional or security-related purposes.
</p>
<div class="section-title">License Verification Notice</div>
<p>
For licensing and authenticity verification purposes, limited hardware-related identifiers may
be securely stored. This information is used exclusively for license validation and protection
against unauthorized use, duplication, or redistribution.
</p>
<div class="section-title">Limitation of Liability</div>
<p>
The developer, author, or distributor shall not be held liable for any direct, indirect,
incidental, special, consequential, or punitive damages, including but not limited to loss
of data, system failure, business interruption, or financial loss, arising from the use,
misuse, or inability to use the software or system.
</p>
<p>
The software or system is provided on an “as-is” and “as-available” basis, without warranties
of any kind, whether express or implied. The user assumes full responsibility for deployment,
configuration, operation, and compliance with applicable laws and regulations.
</p>
<div class="section-title">Declaration</div>
<p>
I confirm that the above statements are true and accurate to the best of my knowledge and accept
full responsibility for compliance with this declaration.
</p>
<div class="section-title">Device Id</div>
<p>
certificatecertificatecertificatecertificate
</p>
<div class="signature">
<div class="sign-box">
Devdatt Bhatt aka ShreeBhattji <br> Bhavnagar
<div class="sign-line">Authorized Signature</div>
</div>
<div class="sign-box">
<br>01 Jan , 2026
<div class="sign-line">Date</div>
</div>
</div>
</div>
</body>
</html>

14
html/chart.js Normal file

File diff suppressed because one or more lines are too long

54
html/contact_us.php Executable file
View File

@ -0,0 +1,54 @@
<?php include 'header.php'; ?>
<div class="containerindex">
<div class="grid">
<div class="card wide">
<h3>How Can We Help ?</h3>
<ul>
<li>We provide free RTMP and EPG file hosting for Registared Broadcastors.</li>
<li>Auto Publishing channel on Cable Tv, IPTV , OTT APP like <a href="https://play.google.com/store/apps/details?id=org.urmic.ott">URMIC OTT.</a></li>
<li>LCO and MSO can get local channels via STREAMINGBOX ( One Box 30 channel - No Encoder Needed - QAM is must )</li>
<li>ISP will get scalable Intranet OTT for resellers and customers .</li>
</ul>
</div>
<div class="card wide">
<h3>Say Hello to Us</h3>
<p>C-1819 , <br>Radhesyam Soc,<br>Kalyabid, <br>Bhavnagar - 364001<br>INDIA
<p>support@urmic.org
<br>+91-8000-74-1919
</div>
<div class="card wide">
<div class="social-row" aria-label="Social links">
<a class="social-btn" href="https://www.facebook.com/WorldwideDigitalAssociation" target="_blank" rel="noopener" aria-label="Facebook page">
<svg viewBox="0 0 23 23" fill="currentColor" aria-hidden="true">
<path d="M22 12.07C22 6.47 17.52 2 11.92 2S2 6.47 2 12.07c0 4.99 3.66 9.12 8.44 9.86v-6.98H8.1v-2.88h2.34V9.41c0-2.31 1.37-3.59 3.46-3.59.99 0 2.03.18 2.03.18v2.23h-1.14c-1.12 0-1.47.7-1.47 1.42v1.7h2.5l-.4 2.88h-2.1v6.98C18.34 21.19 22 17.06 22 12.07z"/>
</svg>
</a>
<a class="social-btn" href="https://www.linkedin.com/in/dbhatt-org/" target="_blank" rel="noopener" aria-label="LinkedIn profile">
<svg viewBox="0 0 23 23" fill="currentColor" aria-hidden="true">
<path d="M4.98 3.5C4.98 4.88 3.86 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1 4.98 2.12 4.98 3.5zM.5 8h4v14h-4V8zm7.5 0h3.84v1.93h.05c.54-1.02 1.86-2.1 3.83-2.1 4.1 0 4.86 2.7 4.86 6.21V22h-4V15.2c0-1.61-.03-3.68-2.24-3.68-2.24 0-2.58 1.75-2.58 3.55V22h-4V8z"/>
</svg>
</a>
<a class="social-btn" href="https://wa.me/918000741919?text=Hello%20from%20website" target="_blank" rel="noopener" aria-label="WhatsApp chat">
<svg viewBox="0 0 23 23" fill="currentColor" aria-hidden="true">
<path d="M20.52 3.48A11.93 11.93 0 0 0 12 0C5.37 0 .05 5.32.05 11.92c0 2.1.55 4.15 1.6 5.95L0 24l6.4-1.68c1.75 1.02 3.77 1.56 5.6 1.56 6.63 0 11.95-5.32 11.95-11.95 0-3.2-1.25-6.2-3.43-8.45zM12 21.95c-1.55 0-3.06-.4-4.36-1.16l-.31-.18-3.8 1 1-3.5-.2-.34A8.72 8.72 0 0 1 3.1 11.9c0-4.85 3.95-8.8 8.8-8.8 2.35 0 4.56.92 6.22 2.6a8.76 8.76 0 0 1-6.13 15.45zM17.03 14.1c-.29-.15-1.7-.84-1.97-.93-.27-.09-.47-.14-.67.14-.2.28-.77.93-.94 1.12-.17.19-.34.21-.63.07-.29-.15-1.23-.45-2.34-1.44-.87-.78-1.46-1.74-1.63-2.03-.17-.29-.02-.45.13-.6.13-.13.29-.34.44-.51.14-.17.19-.29.29-.48.1-.19.05-.36-.02-.51-.07-.15-.67-1.6-.92-2.19-.24-.58-.49-.5-.67-.51l-.57-.01c-.19 0-.5.07-.76.36-.27.29-1.03 1.01-1.03 2.47s1.05 2.87 1.2 3.07c.15.19 2.07 3.19 5.02 4.47 2.95 1.28 3.12.88 3.68.83.56-.05 1.78-.72 2.03-1.41.25-.69.25-1.28.18-1.41-.07-.13-.27-.19-.56-.34z"/>
</svg>
</a>
<a class="social-btn" href="sms:+918000741919?body=Test%20message" aria-label="Send test SMS">
<svg viewBox="0 0 23 23" fill="currentColor" aria-hidden="true">
<path d="M20 2H4c-1.1 0-2 .9-2 2v14l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"/>
</svg>
</a>
<a class="social-btn" href="mailto:hello@urmic.org?subject=Hello&body=Hi%2C%20I%20am%20contacting%20you%20from%20the%20website." aria-label="Send email">
<svg viewBox="0 0 23 23" fill="currentColor" aria-hidden="true">
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>
</svg>
</a>
</div>
</div>
</div>
</div>
<br>
<br>
<?php include 'footer.php'; ?>

214
html/domain.php Executable file
View File

@ -0,0 +1,214 @@
<?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'; ?>

201
html/firewall.php Normal file
View File

@ -0,0 +1,201 @@
<?php include 'header.php' ?>
<?php
$jsonFile = __DIR__ . '/firewall.json';
$defaults = [
'80' => '',
'443' => '',
];
$data = $defaults;
if (is_file($jsonFile)) {
$stored = json_decode(file_get_contents($jsonFile), true);
if (is_array($stored)) {
$data = $stored;
}
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exec("echo y | sudo ufw reset");
exec("sudo ufw default allow outgoing");
exec("sudo ufw default deny incoming");
exec("sudo ufw allow proto udp to 224.0.0.0/4");
exec("sudo ufw route allow proto udp to 224.0.0.0/4");
exec("sudo ufw deny out to 239.255.254.254 port 39000 proto udp");
foreach ($defaults as $port => $_) {
$data[$port] = trim($_POST["port_$port"] ?? '');
}
$tmp = $jsonFile . '.tmp';
file_put_contents(
$tmp,
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
);
rename($tmp, $jsonFile);
foreach ($data as $port => $value) {
$tmp = array_filter(
array_map('trim', explode(',', (string)$value)),
'strlen'
);
if (count($tmp) > 0) {
foreach ($tmp as $ip) {
exec("sudo ufw allow from " . $ip." to any port " . $port . " proto tcp");
}
} else {
exec("sudo ufw allow " . $port);
}
}
exec("sudo ufw allow from 172.16.111.112 to 172.16.111.111 port 80");
exec("sudo ufw allow from 172.16.111.112 to 172.16.111.111 port 443");
exec("sudo ufw --force enable");
exec("sudo ufw reload");
}
?>
?>
<style>
body {
font-family: system-ui, sans-serif;
background: #f5f7fa;
}
.container {
max-width: 520px;
margin: 40px auto;
background: #fff;
padding: 24px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0, 0, 0, .08);
}
h2 {
margin-bottom: 20px;
font-size: 20px;
}
.row {
margin-bottom: 16px;
}
label {
display: block;
font-weight: 600;
margin-bottom: 6px;
}
input[type=text] {
width: 100%;
padding: 16px 14px;
border-radius: 8px;
border: 1px solid #ccc;
font-size: 11px;
line-height: 1.4;
}
textarea {
width: 100%;
padding: 14px;
border-radius: 8px;
border: 1px solid #ccc;
font-size: 13px;
line-height: 1.5;
resize: vertical;
}
input[type=text]:invalid {
border-color: #d33;
}
small {
color: #666;
}
input[type=text]:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 2px rgba(37, 99, 235, .15);
}
button {
margin-top: 20px;
padding: 12px 18px;
border: none;
border-radius: 8px;
background: #2563eb;
color: #fff;
font-size: 15px;
cursor: pointer;
}
button:hover {
background: #1e4ed8;
}
</style>
<script>
function validateIPs(input) {
if (!input.value.trim()) return true;
const ips = input.value.split(',').map(i => i.trim());
const ipv4 =
/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
const ipv6 =
/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::1|::)$/;
for (const ip of ips) {
if (!(ipv4.test(ip) || ipv6.test(ip))) {
return false;
}
}
return true;
}
function attachValidation() {
document.querySelectorAll('input[type=text]').forEach(inp => {
inp.addEventListener('input', () => {
inp.setCustomValidity(
validateIPs(inp) ? '' : 'Invalid IPv4 or IPv6 address'
);
});
});
}
window.onload = attachValidation;
</script>
<div class="containerindex">
<div class="grid">
<div class="card wide">
<h2>Limit Access</h2>
<form method="post">
<?php foreach ($data as $port => $value): ?>
<div class="row">
<label>Port <?= htmlspecialchars($port) ?></label>
<textarea
name="port_<?= $port ?>"
rows="2"
placeholder="IPv4, IPv6 (comma separated)"><?= htmlspecialchars($value) ?></textarea>
<small>Example: 192.168.1.10/24, 2001:db8::1</small>
</div>
<?php endforeach; ?>
<button type="submit">Limit Access</button>
<br>
<br>
<br>
<br>
</form>
</div>
</div>
</div>
<?php include 'footer.php' ?>

456
html/firmware.php Executable file
View File

@ -0,0 +1,456 @@
<?php
include 'header.php';
exec("sudo chmod 444 /sys/class/dmi/id/product_uuid");
$version = 1;
function fail(string $msg): never
{
fwrite(STDERR, "ERROR: $msg\n");
exit(1);
}
function download(string $url, string $dest): void
{
$fp = fopen($dest, 'wb');
if (!$fp) fail("Cannot write $dest");
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_FILE => $fp,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_FAILONERROR => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_SSL_VERIFYPEER => true,
]);
if (!curl_exec($ch)) {
fail("Download failed: " . curl_error($ch));
}
curl_close($ch);
fclose($fp);
}
$device_id = trim(file_get_contents('/sys/class/dmi/id/product_uuid'));
$publicKey = "-----BEGIN PUBLIC KEY-----
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAm6glpTALuc82R+9Mqb5f
HVRC5dScc7USgWoIsYN1tF8YE0d7rhSIFvayVabiyabVmWscjAIlmYf6InSlLsDx
avfmapg32ECd92H49ZbsvXQpLqasyOkN7z6FUcuQ6pEMqfPBmBXKGngHazPp420o
Iki9hLc7IE9EMlDHfozckuJI8mB+bsd2oqua6SSTBYx5HYuSCbootf9GliSd7PVk
H6uir88j49/NFfvmrReicFBiMba959uOdBIhWl9AveZL+iI2NdS5SPw6eWltaMot
PSk7/5Z4Vn5Od7sQA0yUqmCj5XNV5EzRlP1jhP7SDv0D6Mpdf3HuKWdCBqepJBe2
rCHPQ9KrChQau4eEbJb5LIE3gFDpLxTHk9FEp+50evkpFONj0aAjSb3P4wsEGiOk
95Tm56gDRirnbbw/6SzhE7pEvXRUfMl1KO6maYK1z7KNMgEH99C2zCjZhpaXL5Io
rywCw009zoMT2qdKPMGOyQ4KPlCLCJYSF0y/rE07WNgl4BupVZR41B5MbXL5L7+X
OD0jBpbWI7v2ChP9rn5u6Lqpq6ewvc2RJO8lrAyZtzrNJNZNYmUKHrm7qAHJeJZX
Zh7OEf9U/T9JBpzf8l0MzyywlQGUBzb/niG0iZILt3XIpD+Xeyrr6hr+nabeiKXV
jHyUcG84zzLjv7sREzWEGoLBrdztMy69rbfd3d0DpjS90xceKZYBDd3vwjn6h0TN
KssqUb7BMH+zkCe/LQg6EGdXB13+xUSUjFKLLeBKu1VxMPfd/WmV1QumOodidvee
rQAv6yMevq2hVFkiFo7CUpaRv6dvQnQaqX2rHFKZY6zEIzbJXTznl6ZMtCcmcZMk
CYcoWZIAUR5tFP221XzIfJmymVRfJGiKTvt+g/SUUFJt6mq8ettu11XS4KSIxtaA
l8q2SSxpRQa80NUuaBpQc/3eP293wgcf/EOfzhCjxDLjsHSKV1AkSMyjvCzSsCdG
mMEIuT/D7PB7N8vlfhn5qsyt1Sm81/1EZ3u8UqToELhe8j7G26GVl/8ptSxofvZE
X0goYwW18PPhtZvkR8CXpZ7qwjqDcL5cQzcCldufjtqJ5GAwN6SrcmnYjQoo2cu9
XlWo0InPE8BpjR7vJpKLbppQzwUs9GQYx2bMSTbsrduc8zDXlPT5aOfgkJui/NQa
uxttvsXqXd3nNJhbO0BN+wCDT0j4LNRvMlJloWEGrBkY4SA5I1MX8XBL34Csy6Bu
bHWxXNBAGYMchcJKly7XN2hA61V4QCCiFz/MP9l1llw/Mk4D5IUTxcfcEDHx7LO0
To+pc5kuXS6Aps6lKJdwv6h0Bi9SWtBpFi2RtpQpAc+dVPQ9lwq3VTJV5GZz3AgV
KQIDAQAB
-----END PUBLIC KEY-----
";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
switch ($_POST['action']) {
case 'update':
$payload['device_id'] = $device_id;
$payload['project_id'] = "28f27590923d962388f0da125553c5";
$payload['version'] = $version;
$payload = json_encode($payload, JSON_UNESCAPED_UNICODE);
openssl_public_encrypt(
$payload,
$encrypted,
$publicKey,
OPENSSL_PKCS1_OAEP_PADDING
);
$postData = [
'encrypted' => base64_encode($encrypted)
];
$ch = curl_init('https://account.urmic.org/encoder/update_transcoder.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo '<script>alert("'
. htmlspecialchars($data['message'], ENT_QUOTES)
. '");</script>';
error_log($data['status']);
if ($data['status'] == "valid") {
$public_key = "-----BEGIN PUBLIC KEY-----
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAm+7Vl0fEgey2tF6v2mTn
3C/FDGn589uY5a9rpDeZLlhjdOdFaTMWL3d8oEhmImCd+aPELpxydQ+xGxVPNOzO
WKbF3V/FymwxyU3yCD8rfCPyd05z9ANeicVEZMO2K0CwjLoM1OFpxoo/GRmetHuY
Yt2WxDWHPN9DjDDkIMrx2PKFHPqJnyWliyFWJ4aaaK174GH+b4rHRkAm31fUhbaG
RBcQWJhWv1gJ+lxz2z3oHi9nI6Q/Hkb+u3B11tcx3j6rScxKXk8T6Bw64vEk3t0l
i1kYgnPI4Eya0BXuROMfn+zGG50TNgq+vWntzBoKaWuPVbvvmzTlHK8My9qZUliy
otDNd340xhBCmIYqkwxiN2w4g+TAM9X3r9/4lgJYx5ezh3Y0uLGf6mHZ5wFyDAhh
uLJxkOCZY0b3zoRW5wqqKR67/FxBCpcLS6Y8wlKSR8UU8y73hr2tGD28JgNr9sjx
reRItpdGhQgO8gLZKLK6LhihTFtbt5tiL1l6Fkc11DSac+N/xFyHfRe6K3lIV+cD
WMx0+6YX3p8i4cmRXGn59Xu1VdZvmB03Dl5YmIb6wBNMCEPWohRz0bGmamXGW1Ze
EZQhGJRUqIFNuTQwc/RI1wPUgefXXXitCOlo52oyahuKWxWuGMN/8Uyw74poK7NK
7Tbu+JLNuqMsuPoVkrl7havRUbwQy7xUt93wFew0GFDaOobZzoGIjp3pWGvZiQ7y
XMyzklS42/ZC7rJAJTyuLTHxMeUMB4Zt7Qmp7GQ3NaOUq4egPQ6KZUO4qDNtAJaK
mvHca0HHmskP20/yb4iVtz65zhj6BWt98SsFuRMrMDDoBDEtcd1T7xIRK4nqfIhX
8Nw8z1+m8TVItJM3XxvLx6eXgtnJ8BqWInjRoFkbpzEON56zA1ZwPCFm7MWACKEs
m4Gul3+liBwDnpaJvHLLs6+9R4T1/d6nrwwRPDBz9AhBZV2Qz0/Z67qAyGvT2Joh
qR6fIHe+jsKlPSW4TBBx8C2H6avKv7W0CH7z4Y9APuDucvMQ2X3CCekTRaejU7nr
JOGs8ALAtsL+eXL+KMvU/16zxzcbT4ZW/6kdRFtwkaWlq07Q1yU13s+JQRzenut5
7j1GMcmtt1K/CSBzhs2d2UTwiO3fRDs4TCUAj/vq2OlfL1UOAZ3ni8QmfA1vD/BD
Xqfivizijmypv83rv8se5b6dr78ti+wiAIEJEDX+/yISmEWuDXGaL+eVATr1Rw+0
8vFY2f7lS2/QsSv+X7B6lOs3L18sG7AAYrkFjrfhQ8RC9Lv62ITUAV6B6G/BJ4o0
UubReGWsYm092Z9SWEB8KBUlwMWjEMl6Q2f3AfkAKR3EMYBqmNfL8teAcb711xA2
EwIDAQAB
-----END PUBLIC KEY-----
";
error_log("starting");
$tmpDir = sys_get_temp_dir() . '/payload_' . bin2hex(random_bytes(6));
$zipFile = $tmpDir . '/payload.zip';
$sigFile = $tmpDir . '/payload.zip.sig';
$extractDir = $tmpDir . '/extract';
error_log("setting up directory");
mkdir($tmpDir, 0700, true);
mkdir($extractDir, 0700, true);
error_log("directory created");
error_log($tmpDir);
download($data['link'], $zipFile);
download($data['signature'], $sigFile);
error_log("download compltete");
$publicKey = openssl_pkey_get_public($public_key);
if (!$publicKey) fail('Invalid public key');
$data = file_get_contents($zipFile);
$signature = file_get_contents($sigFile);
error_log("loading zip and sig");
$verified = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
if ($verified !== 1) {
error_log("verification failed");
fail('Signature verification FAILED');
}
error_log("varification complete");
$zip = new ZipArchive();
if ($zip->open($zipFile) !== true) {
error_log("zip unzip problem");
fail('Unable to open ZIP');
}
for ($i = 0; $i < $zip->numFiles; $i++) {
$name = $zip->getNameIndex($i);
if (str_contains($name, '..') || str_starts_with($name, '/')) {
fail('Zip traversal detected');
}
}
$zip->extractTo($extractDir);
$zip->close();
$setup = $extractDir . '/setup.sh';
if (!is_file($setup)) {
fail('setup.sh not found');
}
chmod($setup, 0755);
$descriptorSpec = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$process = proc_open(
['/bin/bash', $setup],
$descriptorSpec,
$pipes,
$extractDir
);
if (!is_resource($process)) {
fail('Failed to execute setup.sh');
}
$output = stream_get_contents($pipes[1]);
$error = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$exitCode = proc_close($process);
}
break;
case 'reset':
$files = glob('/var/www/encoder/*.json');
foreach ($files as $file) {
if (is_file($file)) {
unlink($file);
}
}
break;
case 'reboot':
exec('sudo reboot');
break;
case 'backup':
$jsonFiles = [
'input.json',
'output.json',
'firewall.json',
'network.json',
'firmware.json',
];
$tmpZip = sys_get_temp_dir() . '/backup.zip';
$outputFile = __DIR__ . '/universal_encoder_decoder.bin';
$publicKey = file_get_contents('/var/www/backup_private.pem');
$publicKey = file_get_contents('/var/www/backup_public.pem');
$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));
}
}
$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',
$aesKey,
OPENSSL_RAW_DATA,
$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),
'data' => base64_encode($encryptedData)
]);
$filename = 'universal_encoder_decoder.bin';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . strlen($payload));
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
echo $payload;
flush();
unlink($tmpZip);
break;
case 'restore':
$jsonFiles = [
'input.json',
'output.json',
'firewall.json',
'network.json',
'firmware.json',
];
foreach ($jsonFiles as $json) {
if (file_exists($json)) {
unlink($json);
}
}
$tmpZip = sys_get_temp_dir() . '/restore.zip';
$upload = $_FILES['shree_bhattji_encoder'];
if ($upload['error'] !== UPLOAD_ERR_OK) {
die('Upload failed');
}
if (pathinfo($upload['name'], PATHINFO_EXTENSION) !== 'bin') {
die('Invalid file type');
}
$privateKeyPem = file_get_contents('/var/www/backup_private.pem');
if (!$privateKeyPem) {
die('Private key not found');
}
$privateKey = openssl_pkey_get_private($privateKeyPem);
if (!$privateKey) {
die('Invalid private key');
}
$payloadRaw = file_get_contents($upload['tmp_name']);
$payload = json_decode($payloadRaw, true);
if (
!is_array($payload)
|| !isset($payload['key'], $payload['iv'], $payload['data'])
) {
die('Invalid backup file format');
}
$encryptedKey = base64_decode($payload['key'], true);
$iv = base64_decode($payload['iv'], true);
$encryptedData = base64_decode($payload['data'], true);
if ($encryptedKey === false || $iv === false || $encryptedData === false) {
die('Corrupt backup data');
}
if (!openssl_private_decrypt($encryptedKey, $aesKey, $privateKey)) {
die('Key mismatch or wrong private key');
}
$zipBinary = openssl_decrypt(
$encryptedData,
'AES-256-CBC',
$aesKey,
OPENSSL_RAW_DATA,
$iv
);
if ($zipBinary === false) {
die('Failed to decrypt data');
}
$tmpZip = sys_get_temp_dir() . '/restore_' . uniqid() . '.zip';
file_put_contents($tmpZip, $zipBinary);
$zip = new ZipArchive();
if ($zip->open($tmpZip) !== true) {
unlink($tmpZip);
die('Invalid ZIP archive');
}
$zip->extractTo(__DIR__); // overwrites existing JSON
$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;
}
}
?>
<script>
function confirmReboot() {
return confirm("Are you sure you want to reboot?");
}
function confirmReset() {
return confirm("All settings will be gone . Are you sure you want to reset ?");
}
function confirmUpdate() {
return confirm("Newer version will be downloaded and installed Do not turn off power .");
}
function confirmbackup() {
return confirm("Are you sure you want to download backup ? ");
}
</script>
<div class="containerindex">
<div class="grid">
<div class="card wide">
Device ID :- <?php echo trim(file_get_contents('/sys/class/dmi/id/product_uuid')); ?><br>
Project Name :- URMI Universal Encoder / Decoder<br>
Software Version :- <?php echo $version; ?> <br>
</div>
<div class="card wide">
<form method="post" class="form-center">
<button type="submit" name="action" value="backup" class="green-btn">Download Backup File</button>
</form>
</div>
<div class="card wide">
<form method="post" class="form-center" onsubmit="return confirmReboot();">
<button type="submit" name="action" value="reboot" class="green-btn">Reboot</button>
</form>
</div>
<div class="card wide">
<form method="post" class="form-center" onsubmit="return confirmReset();">
<button type="submit" name="action" value="reset" class="red-btn">Reset Settings</button>
</form>
</div>
<div class="card wide">
<form method="post" class="form-center">
<button type="submit" name="action" value="update" class="red-btn">Update Firmware</button>
</form>
</div>
<div class="card wide">
<form method="post" class="form-center" enctype="multipart/form-data"
onsubmit="return confirm('Are you sure you want to restore using this file ? All settings will be restored as per backup file .')">
<label>Select restore file (.bin only):</label><br><br>
<input type="file"
name="shree_bhattji_encoder"
accept=".bin"
required><br><br>
<button type="submit" name="action" value="restore" class="red-btn">Restore</button>
</form>
</div>
<br>
</div>
<br>
</div>
<br><br>
<?php include 'footer.php'; ?>

6
html/footer.php Executable file
View File

@ -0,0 +1,6 @@
<footer class="site-footer">
Crafted with ❤️ by ShreeBhattJi ( Devdatt Bhatt ) &nbsp;&nbsp; +91-8000-74-1919
</footer>
</body>
</html>

408
html/forgot.php Normal file
View File

@ -0,0 +1,408 @@
<?php
declare(strict_types=1);
session_start();
$ALLOWED_IP = '172.16.111.112';
$clientIp = $_SERVER['REMOTE_ADDR'] ?? '';
$usersFile = '/var/www/users.json';
/* ---------- helpers ---------- */
function load_json(string $file): array {
return is_file($file) ? json_decode(file_get_contents($file), true) ?: [] : [];
}
function save_json(string $file, array $data): void {
file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
}
/* ---------- CSRF ---------- */
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
$error = '';
$success = '';
/* ---------- HANDLE RESET ---------- */
if ($clientIp === $ALLOWED_IP && $_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'] ?? '')) {
http_response_code(400);
die('Invalid request');
}
$username = strtolower(trim($_POST['username'] ?? ''));
$password = $_POST['password'] ?? '';
$confirm = $_POST['confirm'] ?? '';
if (!preg_match('/^[a-z0-9_]{3,32}$/', $username)) {
$error = 'Invalid username format.';
} elseif (strlen($password) < 8) {
$error = 'Password must be at least 8 characters.';
} elseif ($password !== $confirm) {
$error = 'Passwords do not match.';
}
if (!$error) {
$users = load_json($usersFile);
$users[$username] = [
'password' => password_hash($password, PASSWORD_DEFAULT)
];
save_json($usersFile, $users);
$success = 'Username and password reset successfully.';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>URMIC powred by Shreebhattji</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg-1: #0f172a;
--bg-2: #1d4ed8;
--bg-3: #22c55e;
--accent: #f97316;
--text-main: #f9fafb;
--text-muted: #cbd5f5;
}
html,
body {
height: 100%;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
sans-serif;
color: var(--text-main);
background:
radial-gradient(circle at top left, #22c55e33, transparent 60%),
radial-gradient(circle at bottom right, #f9731633, transparent 65%),
linear-gradient(135deg, var(--bg-1), var(--bg-2));
overflow: hidden;
}
.page-wrap {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
isolation: isolate;
}
.rain-container {
position: fixed;
inset: 0;
overflow: hidden;
pointer-events: none;
z-index: 0;
}
.raindrop {
position: absolute;
width: 2px;
height: 70px;
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 0.9),
rgba(255, 255, 255, 0)
);
opacity: 0.55;
border-radius: 999px;
filter: blur(0.3px);
animation-name: fall;
animation-timing-function: linear;
animation-iteration-count: infinite;
will-change: transform;
}
@keyframes fall {
0% {
transform: translate3d(0, -120px, 0);
}
100% {
transform: translate3d(0, 110vh, 0);
}
}
.card {
position: relative;
z-index: 1;
max-width: 720px;
width: 100%;
padding: 2.5rem 2rem;
border-radius: 1.75rem;
border: 1px solid rgba(148, 163, 184, 0.6);
background: linear-gradient(
135deg,
rgba(15, 23, 42, 0.9),
rgba(15, 23, 42, 0.7)
)
border-box;
backdrop-filter: blur(16px);
box-shadow:
0 20px 60px rgba(15, 23, 42, 0.7),
0 0 0 1px rgba(15, 23, 42, 0.9);
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.badge {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.25rem 0.7rem;
border-radius: 999px;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--text-main);
background: linear-gradient(
90deg,
rgba(59, 130, 246, 0.6),
rgba(34, 197, 94, 0.75)
);
}
.badge-dot {
width: 0.35rem;
height: 0.35rem;
border-radius: 999px;
background: #bbf7d0;
}
h1 {
font-size: clamp(2.1rem, 4vw, 2.8rem);
line-height: 1.08;
}
h1 span.highlight {
font-size: clamp(1.1rem, 2vw, 1.8rem);
background-image: linear-gradient(
120deg,
#22c55e,
#a855f7,
#f97316
);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
white-space: nowrap;
}
p.subtitle {
font-size: 0.95rem;
color: var(--text-muted);
max-width: 40rem;
}
.tagline {
margin-top: 0.5rem;
font-size: 0.9rem;
color: #e5e7eb;
}
.pill-row {
display: flex;
flex-wrap: wrap;
gap: 0.65rem;
margin-top: 0.75rem;
}
.pill {
padding: 0.35rem 0.8rem;
border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.8);
font-size: 0.75rem;
color: #e5e7eb;
background: radial-gradient(
circle at top left,
rgba(59, 130, 246, 0.22),
rgba(15, 23, 42, 0.7)
);
}
.footer {
margin-top: 1.5rem;
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
align-items: center;
justify-content: space-between;
font-size: 0.8rem;
color: var(--text-muted);
}
.brand {
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.brand span {
color: var(--accent);
}
.links {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
}
.link {
text-decoration: none;
font-size: 0.8rem;
color: var(--text-muted);
border-bottom: 1px dashed rgba(148, 163, 184, 0.7);
}
.link:hover {
color: #ffffff;
border-bottom-style: solid;
}
@media (min-width: 640px) {
.card {
padding: 3rem;
}
}
@media (max-width: 480px) {
.footer {
align-items: flex-start;
gap: 0.4rem;
}
}
</style>
</head>
<body>
<div class="rain-container" id="rain"></div>
<div class="page-wrap">
<main class="card">
<div class="badge">
<span class="badge-dot"></span>
<span>Password Recovery</span>
</div>
<h1>
Universal Encoder / Decoder
<span class="highlight">powred by Shreebhattji</span>
</h1>
<?php if ($clientIp !== $ALLOWED_IP): ?>
<p class="subtitle">
Set you computer ip to <strong>172.16.111.112</strong> then
Connect USB dongle to encoder and visit
<strong>172.16.111.111</strong> for password reset
</p>
<?php else: ?>
<?php if ($error): ?>
<p style="color:#fca5a5"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<?php if ($success): ?>
<p style="color:#86efac"><?= htmlspecialchars($success) ?></p>
<?php endif; ?>
<form method="post" autocomplete="off" style="display:flex;flex-direction:column;gap:0.75rem">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
<input
type="text"
name="username"
placeholder="New Username"
required
style="padding:0.7rem;border-radius:0.5rem;border:none"
/>
<input
type="password"
name="password"
placeholder="New Password"
required
style="padding:0.7rem;border-radius:0.5rem;border:none"
/>
<input
type="password"
name="confirm"
placeholder="Confirm Password"
required
style="padding:0.7rem;border-radius:0.5rem;border:none"
/>
<button
type="submit"
style="padding:0.75rem;border-radius:0.6rem;border:none;
background:#22c55e;color:#000;font-weight:600">
Reset Credentials
</button>
</form>
<?php endif; ?>
</main>
</div>
<!-- ===== YOUR RAIN SCRIPT (UNCHANGED) ===== -->
<script>
(function () {
const container = document.getElementById("rain");
function generateRain() {
if (!container) return;
container.innerHTML = "";
const width = window.innerWidth;
const height = window.innerHeight;
let drops = Math.floor(width * 0.16);
if (window.innerWidth < 600) drops = Math.floor(width * 0.10);
else if (window.innerWidth > 1400) drops = Math.floor(width * 0.18);
for (let i = 0; i < drops; i++) {
const drop = document.createElement("span");
drop.className = "raindrop";
drop.style.left = Math.random() * 100 + "vw";
drop.style.top = -120 - Math.random() * height * 0.3 + "px";
drop.style.animationDuration = (0.7 + Math.random() * 1.2) + "s";
drop.style.animationDelay = (Math.random() * -3) + "s";
drop.style.opacity = (0.35 + Math.random() * 0.55).toFixed(2);
container.appendChild(drop);
}
}
let resizeTimer;
window.addEventListener("resize", () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(generateRain, 180);
});
window.addEventListener("DOMContentLoaded", generateRain);
})();
</script>
</body>
</html>

459
html/header.php Executable file
View File

@ -0,0 +1,459 @@
<?php
require 'require_login.php';
include 'static.php';
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ShreeBhattJi</title>
<script src="chart.js"></script>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
:root {
--header-h: 64px;
--header-bg: linear-gradient(90deg, #1e293b, #0f172a);
--header-color: #e6eef8;
--footer-h: 52px;
--footer-bg: linear-gradient(90deg, #1e293b, #0f172a);
--footer-color: #e6eef8;
}
main {
height: calc(100vh - var(--header-h) - var(--footer-h));
overflow: auto;
-webkit-overflow-scrolling: touch;
padding: 16px;
padding-bottom: calc(var(--footer-h) + 16px);
}
.container {
max-width: 1100px;
margin: 12px auto;
padding: 12px;
background: #ffffff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(2, 6, 23, 0.06);
}
.containerindex {
max-width: 1100px;
margin: 12px auto;
padding: 12px;
padding-top: 160px;
/* Adjusted for multiple headers */
background: #ffffff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(2, 6, 23, 0.06);
}
.grid {
display: flex;
gap: 12px;
flex-wrap: wrap;
align-items: flex-start;
}
.card {
flex: 1 1 43%;
min-width: 300px;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.02));
border-radius: 10px;
padding: 12px;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.06);
}
.card.wide {
flex-basis: 100%;
}
.card h3 {
margin: 0 0 8px 0;
font-size: 1.3rem;
}
.card .chart-wrap {
flex: 1 1 auto;
min-height: 180px;
height: 247px;
position: relative;
}
.card canvas {
display: block;
width: 100% !important;
height: 100% !important;
}
.status-row {
margin-top: 12px;
color: #9fb2d6;
display: flex;
justify-content: space-between;
font-size: 11px;
}
@media (max-width: 640px) {
:root {
--header-h: 56px;
--footer-h: 56px;
}
main {
padding: 10px;
}
.card {
flex: 1 1 100%;
min-width: auto;
}
.card .chart-wrap {
height: 220px;
min-height: 160px;
}
}
.site-footer {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: var(--footer-h);
display: flex;
align-items: center;
justify-content: center;
text-align: center;
padding: 0 32px;
background: var(--footer-bg);
color: var(--footer-color);
z-index: 999;
box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.18);
font-size: 14px;
}
/* === MULTIPLE TOP HEADERS === */
.top-header-1 {
position: fixed;
left: 0;
right: 0;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
color: #e6eef8;
font-size: 17px;
z-index: 1001;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.top-header-2 {
position: fixed;
left: 0;
right: 0;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #e6eef8;
font-size: 14px;
z-index: 1001;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.top-header-1 {
top: 0;
background: #0f172a;
font-size: 20px;
}
.top-header-2 {
position: fixed;
top: 50px;
left: 0;
right: 0;
height: var(--footer-h, 73px);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 48px;
margin-bottom: 57px;
background: linear-gradient(90deg, #0f172a, #1e293b);
color: #e6eef8;
font-weight: bold;
font-size: 15px;
font-weight: 500;
letter-spacing: 0.4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
z-index: 999;
transition: all 0.3s ease;
}
.top-header-2 nav a {
margin-left: 28px;
color: #e6eef8;
text-decoration: none;
transition: color 0.3s ease;
font-weight: bold;
}
/* === MAIN NAV HEADER === */
.site-header {
position: fixed;
top: 90px;
left: 0;
right: 0;
height: var(--footer-h, 73px);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 48px;
margin-bottom: 57px;
background: linear-gradient(90deg, #0f172a, #1e293b);
color: #e6eef8;
font-weight: bold;
font-size: 15px;
font-weight: 500;
letter-spacing: 0.4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
z-index: 999;
transition: all 0.3s ease;
}
.site-header nav a {
margin-left: 28px;
color: #e6eef8;
text-decoration: none;
transition: color 0.3s ease;
font-weight: bold;
}
.site-header nav a:hover {
color: #38bdf8;
}
.dropdown-container {
display: flex;
align-items: center;
gap: 12px;
margin: 7px;
}
.dropdown-label {
font-size: 13px;
font-weight: 500;
color: #1e293b;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown select {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
color: black;
padding: 12px 40px 12px 16px;
border: none;
border-radius: 12px;
font-size: 13px;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.dropdown select:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
}
.dropdown::after {
content: "";
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
color: white;
font-size: 12px;
}
.dropdown select option {
background: #ffffff;
color: #1e293b;
padding: 7px;
}
.input-container {
display: flex;
flex-wrap: nowrap;
gap: 10px;
}
.input-group {
position: relative;
width: auto;
min-width: 333px;
margin: 5px;
}
.input-group input {
width: 100%;
padding: 11px 11px;
font-size: 13px;
border: 2px solid #cbd5e1;
border-radius: 8px;
outline: none;
background: white;
transition: border-color 0.3s ease;
margin: 5px;
}
.input-group input:focus {
border-color: #3b82f6;
}
.input-group label {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: #64748b;
font-size: 13px;
pointer-events: none;
transition: 0.3s ease all;
background: white;
padding: 0 4px;
}
.input-group input:focus+label,
.input-group input:not(:placeholder-shown)+label {
top: -6px;
left: 8px;
font-size: 12px;
color: #3b82f6;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
}
.checkbox-group input[type="checkbox"] {
accent-color: #3b82f6;
width: 18px;
height: 18px;
cursor: pointer;
}
.checkbox-group label {
font-size: 13px;
color: #1e293b;
cursor: pointer;
}
.green-btn {
background-color: green;
color: white;
font-weight: bold;
padding: 10px 20px;
border: none;
width: 33%;
border-radius: 7px;
cursor: pointer;
}
.red-btn {
background-color: red;
color: white;
font-weight: bold;
padding: 10px 20px;
border: none;
width: 33%;
border-radius: 7px;
cursor: pointer;
}
.red-btn:hover {
background-color: darkred;
}
.form-center {
text-align: center;
}
.social-row {
display: flex;
gap: 12px;
align-items: center;
padding: 8px;
}
.social-btn {
width: 67px;
height: 67px;
display: inline-grid;
place-items: center;
border-radius: 8px;
background: #f3f4f6;
text-decoration: none;
transition: transform .12s, box-shadow .12s;
}
.social-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 18px rgba(0,0,0,.08); }
.social-btn svg { width: 22px; height: 22px; display: block; }
.sr-only { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
</style>
</head>
<body>
<!-- Three stacked headers -->
<header class="top-header-1"><a href="index.php" style="color:white; text-decoration:none;">URMI Universal Digital Encoder / Decoder</a></header>
<header class="top-header-2">
<nav aria-label="Top navigation">
<a href="https://learn.urmic.org/" target="_blank">Tutorials</a>
<a href="about_us.php">About Us</a>
<a href="contact_us.php">Contact Us ( Free Service )</a>
<a href="premium_service.php">Premium Service</a>
</nav>
</header>
<!-- Main navigation header -->
<header class="site-header">
<nav aria-label="Top navigation">
<a href="status.php">Status</a>
<a href="index.php">Monitor</a>
<a href="firewall.php">Firewall</a>
<a href="firmware.php">Firmware</a>
<a href="password.php">Password</a>
<a href="logout.php">Logout</a>
</nav>
</header>
</body>
</html>

337
html/index.html Normal file
View File

@ -0,0 +1,337 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>URMIC powred by Shreebhattji</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg-1: #0f172a;
--bg-2: #1d4ed8;
--bg-3: #22c55e;
--accent: #f97316;
--text-main: #f9fafb;
--text-muted: #cbd5f5;
}
html,
body {
height: 100%;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
sans-serif;
color: var(--text-main);
background:
radial-gradient(circle at top left, #22c55e33, transparent 60%),
radial-gradient(circle at bottom right, #f9731633, transparent 65%),
linear-gradient(135deg, var(--bg-1), var(--bg-2));
overflow: hidden;
}
.page-wrap {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
isolation: isolate;
}
.rain-container {
position: fixed;
inset: 0;
overflow: hidden;
pointer-events: none;
z-index: 0;
}
.raindrop {
position: absolute;
width: 2px;
height: 70px;
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 0.9),
rgba(255, 255, 255, 0)
);
opacity: 0.55;
border-radius: 999px;
filter: blur(0.3px);
animation-name: fall;
animation-timing-function: linear;
animation-iteration-count: infinite;
will-change: transform;
}
@keyframes fall {
0% {
transform: translate3d(0, -120px, 0);
}
100% {
transform: translate3d(0, 110vh, 0);
}
}
.card {
position: relative;
z-index: 1;
max-width: 720px;
width: 100%;
padding: 2.5rem 2rem;
border-radius: 1.75rem;
border: 1px solid rgba(148, 163, 184, 0.6);
background: linear-gradient(
135deg,
rgba(15, 23, 42, 0.9),
rgba(15, 23, 42, 0.7)
)
border-box;
backdrop-filter: blur(16px);
box-shadow:
0 20px 60px rgba(15, 23, 42, 0.7),
0 0 0 1px rgba(15, 23, 42, 0.9);
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.badge {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.25rem 0.7rem;
border-radius: 999px;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--text-main);
background: linear-gradient(
90deg,
rgba(59, 130, 246, 0.6),
rgba(34, 197, 94, 0.75)
);
}
.badge-dot {
width: 0.35rem;
height: 0.35rem;
border-radius: 999px;
background: #bbf7d0;
}
h1 {
font-size: clamp(2.1rem, 4vw, 2.8rem);
line-height: 1.08;
}
h1 span.highlight {
font-size: clamp(1.1rem, 2vw, 1.8rem);
background-image: linear-gradient(
120deg,
#22c55e,
#a855f7,
#f97316
);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
white-space: nowrap;
}
p.subtitle {
font-size: 0.95rem;
color: var(--text-muted);
max-width: 40rem;
}
.tagline {
margin-top: 0.5rem;
font-size: 0.9rem;
color: #e5e7eb;
}
.pill-row {
display: flex;
flex-wrap: wrap;
gap: 0.65rem;
margin-top: 0.75rem;
}
.pill {
padding: 0.35rem 0.8rem;
border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.8);
font-size: 0.75rem;
color: #e5e7eb;
background: radial-gradient(
circle at top left,
rgba(59, 130, 246, 0.22),
rgba(15, 23, 42, 0.7)
);
}
.footer {
margin-top: 1.5rem;
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
align-items: center;
justify-content: space-between;
font-size: 0.8rem;
color: var(--text-muted);
}
.brand {
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.brand span {
color: var(--accent);
}
.links {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
}
.link {
text-decoration: none;
font-size: 0.8rem;
color: var(--text-muted);
border-bottom: 1px dashed rgba(148, 163, 184, 0.7);
}
.link:hover {
color: #ffffff;
border-bottom-style: solid;
}
@media (min-width: 640px) {
.card {
padding: 3rem;
}
}
@media (max-width: 480px) {
.footer {
align-items: flex-start;
gap: 0.4rem;
}
}
</style>
</head>
<body>
<div class="rain-container" id="rain"></div>
<div class="page-wrap">
<main class="card">
<div class="badge">
<span class="badge-dot"></span>
<span>Any format to any format</span>
</div>
<h1>
Universal Encoder / Decoder
<span class="highlight">powred by Shreebhattji</span>
</h1>
<p class="subtitle">
Full Free Taining
</p>
<p class="subtitle">
10 Year Long Term Software Support
</p>
<p class="subtitle">
Industry wide format support
</p>
<p class="subtitle">
Wordwide availibility of hardware via hardware partners
</p>
<div class="pill-row">
<span class="pill"><a style="color: #ffffff;" href="https://www.facebook.com/WorldwideDigitalAssociation/">Facebook</a></span>
<span class="pill"><a style="color: #ffffff;" href="https://www.linkedin.com/in/dbhatt-org/">Linkedin</a></span>
<span class="pill"><a style="color: #ffffff;" href="https://wa.me/+918000741919">What's app</a></span>
<span class="pill"><a style="color: #ffffff;" href="mailto:hello@urmic.org">Email</a></span>
<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="footer">
<div class="brand">
URMIC • <span>Shreebhattji</span>
</div>
<div class="links">
<a href="https://urmic.org/trusted-partners/" class="link">Meet Out Partners</a>
</div>
</div>
</main>
</div>
<script>
(function () {
const container = document.getElementById("rain");
function generateRain() {
if (!container) return;
container.innerHTML = "";
// Density: more width -> more raindrops
const width = window.innerWidth;
const height = window.innerHeight;
const baseDensity = 0.16; // drops per vw
let drops = Math.floor(width * baseDensity);
if (window.innerWidth < 600) {
drops = Math.floor(width * 0.10);
} else if (window.innerWidth > 1400) {
drops = Math.floor(width * 0.18);
}
for (let i = 0; i < drops; i++) {
const drop = document.createElement("span");
drop.className = "raindrop";
const left = Math.random() * 100; // vw
const delay = Math.random() * -3; // negative so its already falling
const duration = 0.7 + Math.random() * 1.2; // seconds
const offsetY = Math.random() * height * 0.3;
drop.style.left = left + "vw";
drop.style.top = -120 - offsetY + "px";
drop.style.animationDuration = duration + "s";
drop.style.animationDelay = delay + "s";
drop.style.opacity = (0.35 + Math.random() * 0.55).toFixed(2);
container.appendChild(drop);
}
}
// Basic debounce for resize
let resizeTimer = null;
window.addEventListener("resize", () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(generateRain, 180);
});
window.addEventListener("DOMContentLoaded", generateRain);
})();
</script>
</body>
</html>

206
html/index.php Executable file
View File

@ -0,0 +1,206 @@
<?php include 'header.php'; ?>
<div class="containerindex">
<div class="grid">
<div class="card">
<h3>CPU (%)</h3>
<div class="chart-wrap"><canvas id="cpuChart"></canvas></div>
</div>
<div class="card">
<h3>RAM (%)</h3>
<div class="chart-wrap"><canvas id="ramChart"></canvas></div>
</div>
<div class="card wide">
<h3>Network (KB/s)</h3>
<div class="chart-wrap"><canvas id="netChart"></canvas></div>
</div>
<div class="card wide">
<h3>Disk I/O (KB/s) & Disk %</h3>
<div class="chart-wrap"><canvas id="diskChart"></canvas></div>
</div>
</div>
<div style="margin-top:12px; color:#9fb2d6; display:flex; justify-content:space-between;">
<div>Last update: <span id="lastUpdate"></span></div>
<div>CPU: <span id="lastCpu"></span>% · RAM: <span id="lastRam"></span>% · In: <span id="lastIn"></span>KB/s ·
Out: <span id="lastOut"></span>KB/s</div>
</div>
<br>
<br>
<br>
<br>
</div>
<script>
const POLL_MS = 1000;
const JSON_URL = "metrics.json";
function toKB(v) {
return Math.round(v / 1024);
}
const cpuChart = new Chart(document.getElementById('cpuChart').getContext('2d'), {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'CPU %',
data: [],
fill: false,
tension: 0.2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
min: 0,
max: 100
}
}
}
});
const ramChart = new Chart(document.getElementById('ramChart').getContext('2d'), {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'RAM %',
data: [],
fill: false,
tension: 0.2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
min: 0,
max: 100
}
}
}
});
const netChart = new Chart(document.getElementById('netChart').getContext('2d'), {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Net In (KB/s)',
data: [],
fill: false,
tension: 0.2
},
{
label: 'Net Out (KB/s)',
data: [],
fill: false,
tension: 0.2
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
const diskChart = new Chart(document.getElementById('diskChart').getContext('2d'), {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Disk Read (KB/s)',
data: [],
fill: false,
tension: 0.2
},
{
label: 'Disk Write (KB/s)',
data: [],
fill: false,
tension: 0.2
},
{
label: 'Disk %',
data: [],
yAxisID: 'percent',
fill: false,
tension: 0.2
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
position: 'left',
beginAtZero: true
},
percent: {
position: 'right',
min: 0,
max: 100,
grid: {
display: false
},
ticks: {
callback: v => v + '%'
}
}
}
}
});
async function update() {
try {
const res = await fetch(JSON_URL + "?_=" + Date.now(), {
cache: 'no-store'
});
if (!res.ok) throw new Error('fetch fail ' + res.status);
const j = await res.json();
const labels = j.timestamps.map(t => new Date(t).toLocaleTimeString());
cpuChart.data.labels = labels;
cpuChart.data.datasets[0].data = j.cpu_percent;
ramChart.data.labels = labels;
ramChart.data.datasets[0].data = j.ram_percent;
netChart.data.labels = labels;
netChart.data.datasets[0].data = j.net_in_Bps.map(toKB);
netChart.data.datasets[1].data = j.net_out_Bps.map(toKB);
diskChart.data.labels = labels;
diskChart.data.datasets[0].data = j.disk_read_Bps.map(toKB);
diskChart.data.datasets[1].data = j.disk_write_Bps.map(toKB);
diskChart.data.datasets[2].data = j.disk_percent;
cpuChart.update();
ramChart.update();
netChart.update();
diskChart.update();
const last = labels.length - 1;
if (last >= 0) {
document.getElementById('lastUpdate').textContent = labels[last];
document.getElementById('lastCpu').textContent = j.cpu_percent[last];
document.getElementById('lastRam').textContent = j.ram_percent[last];
document.getElementById('lastIn').textContent = toKB(j.net_in_Bps[last]);
document.getElementById('lastOut').textContent = toKB(j.net_out_Bps[last]);
}
} catch (e) {
console.error('update failed', e);
}
}
setInterval(update, POLL_MS);
update();
</script>
<?php include 'footer.php'; ?>

441
html/login.php Normal file
View File

@ -0,0 +1,441 @@
<?php
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');
session_start();
if (!empty($_SESSION['user'])) {
header('Location: /index.php', true, 302);
exit;
}
/* ---------- CONFIG ---------- */
$usersFile = '/var/www/users.json';
$attemptsFile = '/var/www/attempts.json';
$MAX_ATTEMPTS = 3;
$LOCK_TIME = 3600;
/* ---------- HELPERS ---------- */
function client_ip(): string
{
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}
function load_json($file): array
{
return is_file($file) ? json_decode(file_get_contents($file), true) ?: [] : [];
}
function save_json($file, $data): void
{
file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
}
/* ---------- CSRF ---------- */
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
/* ---------- RATE LIMIT ---------- */
$ip = client_ip();
$attempts = load_json($attemptsFile);
if (isset($attempts[$ip])) {
if (
$attempts[$ip]['count'] >= $MAX_ATTEMPTS &&
time() - $attempts[$ip]['last'] < $LOCK_TIME
) {
http_response_code(429);
die("Too many attempts. Try again later.");
}
}
/* ---------- LOGIN ---------- */
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'] ?? '')) {
http_response_code(400);
die('Invalid request');
}
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
if (empty($_POST['agree'])) {
$error = 'You must agree to the Privacy Policy and Terms & Conditions.';
echo '<script>alert("'
. htmlspecialchars($error, ENT_QUOTES)
. '");</script>';
}
$users = load_json($usersFile);
$valid = isset($users[$username]) &&
password_verify($password, $users[$username]['password']);
if ($valid) {
session_regenerate_id(true);
unset($attempts[$ip]);
save_json($attemptsFile, $attempts);
$_SESSION['user'] = $username;
header('Location: index.php');
exit;
}
// Failed login
$attempts[$ip]['count'] = ($attempts[$ip]['count'] ?? 0) + 1;
$attempts[$ip]['last'] = time();
save_json($attemptsFile, $attempts);
$error = 'Invalid username or password';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>URMIC powred by Shreebhattji</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg-1: #0f172a;
--bg-2: #1d4ed8;
--bg-3: #22c55e;
--accent: #f97316;
--text-main: #f9fafb;
--text-muted: #cbd5f5;
}
html,
body {
height: 100%;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
sans-serif;
color: var(--text-main);
background:
radial-gradient(circle at top left, #22c55e33, transparent 60%),
radial-gradient(circle at bottom right, #f9731633, transparent 65%),
linear-gradient(135deg, var(--bg-1), var(--bg-2));
overflow: hidden;
}
.page-wrap {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
isolation: isolate;
}
.rain-container {
position: fixed;
inset: 0;
overflow: hidden;
pointer-events: none;
z-index: 0;
}
.raindrop {
position: absolute;
width: 2px;
height: 70px;
background: linear-gradient(to bottom,
rgba(255, 255, 255, 0.9),
rgba(255, 255, 255, 0));
opacity: 0.55;
border-radius: 999px;
filter: blur(0.3px);
animation-name: fall;
animation-timing-function: linear;
animation-iteration-count: infinite;
will-change: transform;
}
@keyframes fall {
0% {
transform: translate3d(0, -120px, 0);
}
100% {
transform: translate3d(0, 110vh, 0);
}
}
.card {
position: relative;
z-index: 1;
max-width: 720px;
width: 100%;
padding: 2.5rem 2rem;
border-radius: 1.75rem;
border: 1px solid rgba(148, 163, 184, 0.6);
background: linear-gradient(135deg,
rgba(15, 23, 42, 0.9),
rgba(15, 23, 42, 0.7)) border-box;
backdrop-filter: blur(16px);
box-shadow:
0 20px 60px rgba(15, 23, 42, 0.7),
0 0 0 1px rgba(15, 23, 42, 0.9);
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.badge {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.25rem 0.7rem;
border-radius: 999px;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--text-main);
background: linear-gradient(90deg,
rgba(59, 130, 246, 0.6),
rgba(34, 197, 94, 0.75));
}
.badge-dot {
width: 0.35rem;
height: 0.35rem;
border-radius: 999px;
background: #bbf7d0;
}
h1 {
font-size: clamp(2.1rem, 4vw, 2.8rem);
line-height: 1.08;
}
h1 span.highlight {
font-size: clamp(1.1rem, 2vw, 1.8rem);
background-image: linear-gradient(120deg,
#22c55e,
#a855f7,
#f97316);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
white-space: nowrap;
}
p.subtitle {
font-size: 0.95rem;
color: var(--text-muted);
max-width: 40rem;
}
.tagline {
margin-top: 0.5rem;
font-size: 0.9rem;
color: #e5e7eb;
}
.pill-row {
display: flex;
flex-wrap: wrap;
gap: 0.65rem;
margin-top: 0.75rem;
}
.pill {
padding: 0.35rem 0.8rem;
border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.8);
font-size: 0.75rem;
color: #e5e7eb;
background: radial-gradient(circle at top left,
rgba(59, 130, 246, 0.22),
rgba(15, 23, 42, 0.7));
}
.footer {
margin-top: 1.5rem;
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
align-items: center;
justify-content: space-between;
font-size: 0.8rem;
color: var(--text-muted);
}
.brand {
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.brand span {
color: var(--accent);
}
.links {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
}
.link {
text-decoration: none;
font-size: 0.8rem;
color: var(--text-muted);
border-bottom: 1px dashed rgba(148, 163, 184, 0.7);
}
.link:hover {
color: #ffffff;
border-bottom-style: solid;
}
@media (min-width: 640px) {
.card {
padding: 3rem;
}
}
@media (max-width: 480px) {
.footer {
align-items: flex-start;
gap: 0.4rem;
}
}
</style>
</head>
<body>
<div class="rain-container" id="rain"></div>
<div class="page-wrap">
<main class="card">
<h1>Welcome</h1>
<?php if ($error): ?>
<p style="color:#fca5a5"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<form method="post" autocomplete="off">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
<div style="display:flex;flex-direction:column;gap:0.75rem">
<input
type="text"
name="username"
placeholder="Username"
required
style="padding:0.7rem;border-radius:0.5rem;border:none" />
<input
type="password"
name="password"
placeholder="Password"
required
style="padding:0.7rem;border-radius:0.5rem;border:none" />
<label style="display:flex; gap:0.5rem; align-items:flex-start; font-size:0.8rem; color:#e5e7eb;">
<input
type="checkbox"
name="agree"
value="1"
required
style="margin-top:0.15rem">
<span>
I agree to the
<a href="https://urmic.org/2025/12/31/privacy-policy-and-terms-conditions-for-encoder/" target="_blank" class="link">Privacy Policy</a>
and
<a href="https://urmic.org/2025/12/31/privacy-policy-and-terms-conditions-for-encoder/" target="_blank" class="link">Terms & Conditions</a>
</span>
</label>
<button
type="submit"
style="padding:0.75rem;border-radius:0.6rem;border:none;
background:#22c55e;color:#000;font-weight:600">
Login
</button>
</div>
</form>
<div style="margin-top:0.75rem">
<a href="forgot.php" class="link">Forgot password?</a>
</div>
<div class="footer">
<div class="brand">
URMIC <span>Shreebhattji</span>
</div>
<div class="links">
<a href="https://urmic.org/trusted-partners/" class="link">Meet Out Partners</a>
</div>
</div>
</main>
</div>
<script>
(function() {
const container = document.getElementById("rain");
function generateRain() {
if (!container) return;
container.innerHTML = "";
// Density: more width -> more raindrops
const width = window.innerWidth;
const height = window.innerHeight;
const baseDensity = 0.16; // drops per vw
let drops = Math.floor(width * baseDensity);
if (window.innerWidth < 600) {
drops = Math.floor(width * 0.10);
} else if (window.innerWidth > 1400) {
drops = Math.floor(width * 0.18);
}
for (let i = 0; i < drops; i++) {
const drop = document.createElement("span");
drop.className = "raindrop";
const left = Math.random() * 100; // vw
const delay = Math.random() * -3; // negative so its already falling
const duration = 0.7 + Math.random() * 1.2; // seconds
const offsetY = Math.random() * height * 0.3;
drop.style.left = left + "vw";
drop.style.top = -120 - offsetY + "px";
drop.style.animationDuration = duration + "s";
drop.style.animationDelay = delay + "s";
drop.style.opacity = (0.35 + Math.random() * 0.55).toFixed(2);
container.appendChild(drop);
}
}
// Basic debounce for resize
let resizeTimer = null;
window.addEventListener("resize", () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(generateRain, 180);
});
window.addEventListener("DOMContentLoaded", generateRain);
})();
</script>
</body>
</html>

22
html/logout.php Normal file
View File

@ -0,0 +1,22 @@
<?php
session_start();
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$p = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$p['path'],
$p['domain'],
$p['secure'],
$p['httponly']
);
}
session_destroy();
header('Location: /login.php');
exit;

135
html/password.php Normal file
View File

@ -0,0 +1,135 @@
<?php
declare(strict_types=1);
include 'header.php';
?>
<?php
$usersFile = '/var/www/users.json';
function load_json(string $file): array
{
return is_file($file) ? json_decode(file_get_contents($file), true) ?: [] : [];
}
function save_json(string $file, array $data): void
{
file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
}
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
$error = '';
$success = '';
$currentUser = $_SESSION['user'];
$users = load_json($usersFile);
if (!isset($users[$currentUser])) {
// Safety fallback
session_destroy();
header('Location: /login.php');
exit;
}
/* ---------- POST ---------- */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'] ?? '')) {
http_response_code(400);
die('Invalid request');
}
$newUsername = strtolower(trim($_POST['new_username'] ?? ''));
$currentPass = $_POST['current_password'] ?? '';
$newPass = $_POST['new_password'] ?? '';
$confirmPass = $_POST['confirm_password'] ?? '';
// Verify current password
if (!password_verify($currentPass, $users[$currentUser]['password'])) {
$error = 'Current password is incorrect.';
}
// Validate new password if provided
if (!$error && $newPass !== '') {
if (strlen($newPass) < 8) {
$error = 'New password must be at least 8 characters.';
} elseif ($newPass !== $confirmPass) {
$error = 'New passwords do not match.';
}
}
// Validate new username if provided
if (!$error && $newUsername !== '' && $newUsername !== $currentUser) {
if (!preg_match('/^[a-z0-9_]{3,32}$/', $newUsername)) {
$error = 'Username must be 332 chars (az, 09, underscore).';
} elseif (isset($users[$newUsername])) {
$error = 'Username already exists.';
}
}
if (!$error) {
// Apply changes
$updatedUser = $currentUser;
if ($newPass !== '') {
$users[$currentUser]['password'] =
password_hash($newPass, PASSWORD_DEFAULT);
}
if ($newUsername !== '' && $newUsername !== $currentUser) {
$users[$newUsername] = $users[$currentUser];
unset($users[$currentUser]);
$updatedUser = $newUsername;
}
save_json($usersFile, $users);
// Update session safely
session_regenerate_id(true);
$_SESSION['user'] = $updatedUser;
$success = 'Credentials updated successfully.';
}
}
?>
<div class="containerindex">
<div class="grid">
<div class="card wide">
<h3>Change Username / Password</h3>
<?php if ($error): ?>
<p style="color:#dc2626"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<?php if ($success): ?>
<p style="color:#16a34a"><?= htmlspecialchars($success) ?></p>
<?php endif; ?>
<form method="post" autocomplete="off">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
<p>
<label>New Username (optional)</label><br>
<input type="text" name="new_username" placeholder="leave blank to keep current">
</p>
<p>
<label>Current Password (required)</label><br>
<input type="password" name="current_password" required>
</p>
<p>
<label>New Password (optional)</label><br>
<input type="password" name="new_password">
</p>
<p>
<label>Confirm New Password</label><br>
<input type="password" name="confirm_password">
</p>
<button type="submit">Update</button>
</form>
</div>
</div>
</div>
<?php include 'footer.php'; ?>

292
html/premium_service.php Executable file
View File

@ -0,0 +1,292 @@
<?php include 'header.php'; ?>
<style>
:root {
--accent: #0b74de;
--muted: #6b7280;
--card: #ffffff;
--bg: #f3f4f6
}
body {
font-family: Inter, system-ui, Arial, Helvetica, sans-serif;
background: var(--bg);
color: #111;
margin: 0;
padding: 32px
}
.wrap {
max-width: 1100px;
margin: 0 auto
}
header {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 20px
}
header h1 {
margin: 0;
font-size: 20px
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 16px
}
.card {
background: var(--card);
border-radius: 12px;
box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06);
padding: 20px
}
.price {
font-size: 28px;
font-weight: 700;
color: var(--accent)
}
.muted {
color: var(--muted);
font-size: 13px
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 8px
}
th,
td {
padding: 10px;
border-bottom: 1px solid #eef2f6;
text-align: left;
font-size: 14px
}
th {
background: transparent;
font-weight: 600
}
.feature {
display: flex;
align-items: center
}
.pill {
display: inline-block;
background: #eef6ff;
border-radius: 999px;
padding: 6px 10px;
font-size: 13px;
margin-left: auto
}
.cta {
display: inline-block;
padding: 10px 14px;
border-radius: 10px;
font-weight: 600;
text-decoration: none
}
.cta-primary {
background: var(--accent);
color: #fff
}
.cta-ghost {
border: 1px solid #e6eefa;
color: var(--accent)
}
.benefits {
margin-top: 18px
}
.note {
font-size: 13px;
color: #374151;
background: #fff;
padding: 12px;
border-radius: 8px
}
footer {
margin-top: 20px;
font-size: 13px;
color: var(--muted)
}
@media (max-width:600px) {
header {
flex-direction: column;
align-items: flex-start
}
header h1 {
margin-bottom: 8px
}
}
</style>
<body>
<div class="wrap">
<br>
<br>
<br>
<br>
<br>
<br>
<section class="benefits">
<div class="card">
<h3 style="margin-top:0">Why choose hosted streaming over just buying a static IP from your ISP ?</h3>
<ul style="margin:8px 0 0 18px">
<li><strong>DDoS & attack protection:</strong> Professional hosts run network-level DDoS mitigation and web application firewalls (WAF) that absorb and block large-scale attacks before they reach your origin server.</li>
<li><strong>Scalable bandwidth & CDN:</strong> Hosting + CDN provides globally distributed edge points and the ability to scale to many thousands of viewers without saturating a single home/office link.</li>
<li><strong>Higher availability & SLA:</strong> Providers operate redundant infrastructure and SLAs that keep streams online even when single links or hardware fail.</li>
<li><strong>Managed SSL, domain & DNS:</strong> Automated SSL issuance/renewal (Let's Encrypt), DNS features and a dedicated domain remove operational friction compared to configuring services on a raw ISP IP.</li>
<li><strong>Security isolation:</strong> Dedicated servers and hosting accounts isolate your traffic and services from other customers, reducing risks that come with shared consumer-grade network equipment.</li>
<li><strong>Monitoring & support:</strong> 24/7 monitoring, alerting and expert support are part of hosting plans ISPs rarely provide application-level stream support.</li>
<li><strong>Optional reserved (static) IPs:</strong> If you still need a static IP for whitelisting, we can provision a reserved IP on a dedicated plan and keep it behind our mitigation/CDN layer.</li>
</ul>
<div class="note" style="margin-top:12px">
<strong>Quick notes:</strong> "Unlimited data for links" refers to stream delivery (no per-GB charge on the plan level for the specified formats). Extremely large egress (multi-TB per month) or abusive usage may require a custom enterprise agreement. CDN bandwidth, archival storage and advanced security may be subject to fair-use or tiered pricing.
</div>
<div class="note" style="margin-top:12px">
<strong>Hosting :</strong> All servers are hosted with our CDN ISP partners. This project aims to transform ISPs into data-center service providers through a hybrid partnership model. All billing is handled directly by the ISP. We found this is lowest letency and stable solutions for broadcastors . Price includes GST and 2 month will be free on yearly payment .
</div>
</div>
</section>
<div class="cards">
<!-- Shared Streaming -->
<div class="card">
<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">
<div>
<div class="muted">Shared Streaming</div>
<div class="price">₹2,000 / month</div>
</div>
<div style="margin-left:auto;text-align:right">
<div class="pill">Best for small producers</div>
</div>
</div>
<table>
<tr>
<th>Feature</th>
<th>Included</th>
</tr>
<tr>
<td>Delivery formats</td>
<td>HLS (m3u8), RTMP, SRT, DASH unlimited data for links</td>
</tr>
<tr>
<td>Bandwidth</td>
<td>Shared pool burst-capable (fair-usage policy)</td>
</tr>
<tr>
<td>Domain</td>
<td>Subdomain (example.customer.example.com)</td>
</tr>
<tr>
<td>SSL</td>
<td>Let's Encrypt (shared certificate)</td>
</tr>
<tr>
<td>Support</td>
<td>Email & chat (business hours)</td>
</tr>
<tr>
<td>Uptime SLA</td>
<td>99.5%</td>
</tr>
</table>
<div style="margin-top:12px;display:flex;gap:8px">
<a class="cta cta-primary" href="contact_us.php">Contact Us</a>
<a class="cta cta-ghost" href="https://urmic.org/trusted-partners/">Our ISP Partners</a>
</div>
</div>
<!-- Dedicated Streaming -->
<div class="card">
<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">
<div>
<div class="muted">Dedicated Streaming</div>
<div class="price">₹4,000 / month</div>
</div>
<div style="margin-left:auto;text-align:right">
<div class="pill">Recommended for events & scale</div>
</div>
</div>
<table>
<tr>
<th>Feature</th>
<th>Included</th>
</tr>
<tr>
<td>Delivery formats</td>
<td>HLS (m3u8), RTMP, SRT, DASH unlimited data for links</td>
</tr>
<tr>
<td>Bandwidth</td>
<td>Dedicated bandwidth allocation (higher sustained throughput up to 10gbe spike )</td>
</tr>
<tr>
<td>Domain</td>
<td>Dedicated domain included (example: yourbrand.live)</td>
</tr>
<tr>
<td>SSL</td>
<td>Free SSL certificate (Let's Encrypt) + automated renewals</td>
</tr>
<tr>
<td>DDoS / Attack protection</td>
<td>Network-level mitigation & WAF</td>
</tr>
<tr>
<td>Static IP</td>
<td>Dedicated ip ipv4 and ipv6 available (reserved IP) useful for whitelisting</td>
</tr>
<tr>
<td>Uptime SLA</td>
<td>99.9% with priority support</td>
</tr>
<tr>
<td>Support</td>
<td>24/7 priority support & onboarding</td>
</tr>
</table>
<div style="margin-top:12px;display:flex;gap:8px">
<a class="cta cta-primary" href="contact_us.php">Contact Us</a>
<a class="cta cta-ghost" href="https://urmic.org/trusted-partners/">Our ISP Partners</a>
</div>
</div>
</div>
<br>
<br>
<br>
<footer>
<div class="muted">Need an exportable copy of this pricing page or custom branding? Contact sales for a tailored quote and SLA.</div>
</footer>
</div>
</body>
<?php include 'footer.php'; ?>

146
html/request_cert.php Executable file
View File

@ -0,0 +1,146 @@
<?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));

21
html/require_login.php Normal file
View File

@ -0,0 +1,21 @@
<?php
// auth/require_login.php
declare(strict_types=1);
session_start();
/* ---------- SECURITY HEADERS (optional but recommended) ---------- */
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: strict-origin-when-cross-origin');
/* ---------- LOGIN CHECK ---------- */
if (empty($_SESSION['user'])) {
// Prevent cache of protected pages
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Location: /login.php', true, 302);
exit;
}

1424
html/static.php Executable file

File diff suppressed because it is too large Load Diff

684
html/status.php Executable file
View File

@ -0,0 +1,684 @@
<?php include 'header.php'; ?>
<?php
$domain = "";
$https = false;
$jsonFile = __DIR__ . '/domain.json';
if (file_exists($jsonFile)) {
$raw = file_get_contents($jsonFile);
$data = json_decode($raw, true);
$domain = $data['domain'];
$https = $data['https'];
} else {
$domain = $_SERVER['SERVER_NAME'];
}
$jsonFile = __DIR__ . '/output.json';
if (file_exists($jsonFile)) {
$raw = file_get_contents($jsonFile);
$data = json_decode($raw, true);
}
$service_rtmp0_multiple = $data['service_rtmp0_multiple'];
$service_rtmp0_hls = $data['service_rtmp0_hls'];
$service_rtmp0_dash = $data['service_rtmp0_dash'];
$service_rtmp1_multiple = $data['service_rtmp1_multiple'];
$service_rtmp1_hls = $data['service_rtmp1_hls'];
$service_rtmp1_dash = $data['service_rtmp1_dash'];
$service_srt_multiple = $data['service_srt_multiple'];
$text = "<h3>Encoder</h3>";
$text .= "<h5>http://" . $domain;
if ($https) $text .= "<br>https://" . $domain;
$text .= "</h5>";
if ($service_rtmp0_multiple == 'enable') {
$text .= "<h5>rtmp://" . $domain . "/shree/bhattji<br>";
if ($service_rtmp0_dash == 'enable') {
$text .= "http://" . $domain . "/hls/shree/bhattji.m3u8<br>";
if ($https) {
$text .= "https://" . $domain . "/hls/shree/bhattji.m3u8<br><br>";
}
}
if ($service_rtmp0_dash == 'enable') {
$text .= "http://" . $domain . "/dash/shree/bhattji.mpd<br>";
if ($https) {
$text .= "https://" . $domain . "/dash/shree/bhattji.mpd<br>";
}
}
$text .= "</h5>";
}
if ($service_rtmp1_multiple == 'enable') {
$text .= "<h5>rtmp://" . $domain . "/shreeshree/bhattji<br>";
if ($service_rtmp1_dash == 'enable') {
$text .= "http://" . $domain . "/hls/shreeshree/bhattji.m3u8<br>";
if ($https) {
$text .= "https://" . $domain . "/hls/shreeshree/bhattji.m3u8<br><br>";
}
}
if ($service_rtmp1_dash == 'enable') {
$text .= "http://" . $domain . "/dash/shreeshree/bhattji.mpd<br>";
if ($https) {
$text .= "https://" . $domain . "/dash/shreeshree/bhattji.mpd<br>";
}
}
$text .= "</h5>";
}
if($service_srt_multiple){
$text .= "<h5>srt://" . $domain . ":1937?streamid=shree/bhatt/ji</h5><br><br>";
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['action'])) {
$data = explode("_", $_POST['action']);
switch ($data[0]) {
case 'main':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl enable encoder-main');
exec('sudo systemctl restart encoder-main');
break;
case 'enable':
exec('sudo systemctl enable encoder-main');
exec('sudo systemctl restart encoder-main');
break;
case 'disable':
exec('sudo systemctl stop encoder-main');
exec('sudo systemctl disable encoder-main');
break;
}
break;
case 'rtmp0':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl enable encoder-rtmp0');
exec('sudo systemctl restart encoder-rtmp0');
break;
case 'enable':
exec('sudo systemctl enable encoder-rtmp0');
exec('sudo systemctl restart encoder-rtmp0');
break;
case 'disable':
exec('sudo systemctl stop encoder-rtmp0');
exec('sudo systemctl disable encoder-rtmp0');
break;
}
break;
case 'rtmp1':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl enable encoder-rtmp1');
exec('sudo systemctl restart encoder-rtmp1');
break;
case 'enable':
exec('sudo systemctl enable encoder-rtmp1');
exec('sudo systemctl restart encoder-rtmp1');
break;
case 'disable':
exec('sudo systemctl stop encoder-rtmp1');
exec('sudo systemctl disable encoder-rtmp1');
break;
}
break;
case 'srt':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl enable srt');
exec('sudo systemctl restart srt');
exec('sudo systemctl enable encoder-srt');
exec('sudo systemctl restart encoder-srt');
break;
case 'enable':
exec('sudo systemctl enable srt');
exec('sudo systemctl restart srt');
exec('sudo systemctl enable encoder-srt');
exec('sudo systemctl restart encoder-srt');
break;
case 'disable':
exec('sudo systemctl stop encoder-srt');
exec('sudo systemctl disable encoder-srt');
exec('sudo systemctl stop srt');
exec('sudo systemctl disable srt');
break;
}
break;
case 'udp0':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl restart encoder-udp0');
break;
case 'enable':
exec('sudo systemctl enable encoder-udp0');
exec('sudo systemctl restart encoder-udp0');
break;
case 'disable':
exec('sudo systemctl stop encoder-udp0');
exec('sudo systemctl disable encoder-udp0');
break;
}
case 'udp1':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl restart encoder-udp1');
break;
case 'enable':
exec('sudo systemctl enable encoder-udp1');
exec('sudo systemctl restart encoder-udp1');
break;
case 'disable':
exec('sudo systemctl stop encoder-udp1');
exec('sudo systemctl disable encoder-udp1');
break;
}
case 'udp2':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl restart encoder-udp2');
break;
case 'enable':
exec('sudo systemctl enable encoder-udp2');
exec('sudo systemctl restart encoder-udp2');
break;
case 'disable':
exec('sudo systemctl stop encoder-udp2');
exec('sudo systemctl disable encoder-udp2');
break;
}
break;
case 'custom':
switch ($data[1]) {
case 'restart':
exec('sudo systemctl restart encoder-custom');
break;
case 'enable':
exec('sudo systemctl enable encoder-custom');
exec('sudo systemctl restart encoder-custom');
break;
case 'disable':
exec('sudo systemctl stop encoder-custom');
exec('sudo systemctl disable encoder-custom');
break;
}
break;
}
}
}
?>
<style>
.card-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
.card-left,
.card-right {
display: flex;
flex-direction: column;
gap: 6px;
}
.card-left {
flex: 1 1 55%;
}
.card-right {
flex: 1 1 40%;
align-items: flex-end;
text-align: right;
}
.input-wrapper {
position: relative;
width: 100%;
}
.input-wrapper input {
width: 100%;
padding: 10px 40px 10px 12px;
border-radius: 25px;
border: 1px solid #ccc;
font-size: 0.95rem;
outline: none;
background: #f9fafb;
}
.copy-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
font-size: 1.1rem;
color: #444;
pointer-events: none;
/* visual only */
}
.service-label {
font-size: 0.9rem;
color: #4b5563;
}
.badge {
display: inline-block;
padding: 3px 10px;
border-radius: 999px;
font-size: 0.8rem;
font-weight: 600;
margin-left: 6px;
}
.badge-enabled {
background: #16a34a22;
color: #15803d;
border: 1px solid #16a34a;
}
.badge-disabled {
background: #b91c1c22;
color: #b91c1c;
border: 1px solid #b91c1c;
}
.service-buttons {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 4px;
}
.service-buttons button {
padding: 6px 14px;
border-radius: 999px;
border: 1px solid transparent;
font-size: 0.85rem;
cursor: pointer;
white-space: nowrap;
}
.btn-restart {
border-color: #0f172a;
background: #0f172a;
color: #fff;
}
.btn-enable {
border-color: #15803d;
background: #15803d;
color: #fff;
}
.btn-disable {
border-color: #b91c1c;
background: #b91c1c;
color: #fff;
}
.hls-player-wrapper {
max-width: 900px;
margin: 20px auto;
padding: 16px;
box-sizing: border-box;
background: #121212;
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: #f1f1f1;
}
.hls-video {
width: 100%;
max-height: 70vh;
border-radius: 10px;
background: #000;
outline: none;
}
.hls-video:focus-visible {
outline: 2px solid #1e88e5;
outline-offset: 2px;
}
@media (max-width: 768px) {
.card-right {
align-items: flex-start;
text-align: left;
}
}
</style>
<div class="containerindex">
<div class="grid">
<div class="card wide">
<h3>Input Service</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-main 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="main_restart" class="btn-restart">
Restart
</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="main_disable" class="btn-disable">
Disable
</button>
<?php else: ?>
<button type="submit" name="action" value="main_enable" class="btn-enable">
Enable
</button>
<?php endif; ?>
</form>
</div>
</div>
<div class="card wide">
<h3>RTMP0 Server</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-rtmp0 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="card-right">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="rtmp0_restart" class="btn-restart">Restart</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="rtmp0_disable" class="btn-disable">Disable</button>
<?php else: ?>
<button type="submit" name="action" value="rtmp0_enable" class="btn-enable">Enable</button>
<?php endif; ?>
</form>
</div>
</div>
</div>
<div class="card wide">
<h3>RTMP1 Server</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-rtmp1 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="card-right">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="rtmp1_restart" class="btn-restart">Restart</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="rtmp1_disable" class="btn-disable">Disable</button>
<?php else: ?>
<button type="submit" name="action" value="rtmp1_enable" class="btn-enable">Enable</button>
<?php endif; ?>
</form>
</div>
</div>
</div>
<div class="card wide">
<h3>SRT Server</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-srt 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="card-right">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="srt_restart" class="btn-restart">Restart</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="srt_disable" class="btn-disable">Disable</button>
<?php else: ?>
<button type="submit" name="action" value="srt_enable" class="btn-enable">Enable</button>
<?php endif; ?>
</form>
</div>
</div>
</div>
<div class="card">
<h3>Udp0 Service</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-udp0 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="udp0_restart" class="btn-restart">
Restart
</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="udp0_disable" class="btn-disable">
Disable
</button>
<?php else: ?>
<button type="submit" name="action" value="udp0_enable" class="btn-enable">
Enable
</button>
<?php endif; ?>
</form>
</div>
</div>
<div class="card">
<h3>Udp1 Service</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-udp1 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="udp1_restart" class="btn-restart">
Restart
</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="udp1_disable" class="btn-disable">
Disable
</button>
<?php else: ?>
<button type="submit" name="action" value="udp1_enable" class="btn-enable">
Enable
</button>
<?php endif; ?>
</form>
</div>
</div>
<div class="card">
<h3>Udp2 Service</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-udp2 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="udp_restart" class="btn-restart">
Restart
</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="udp_disable" class="btn-disable">
Disable
</button>
<?php else: ?>
<button type="submit" name="action" value="udp_enable" class="btn-enable">
Enable
</button>
<?php endif; ?>
</form>
</div>
</div>
<div class="card">
<h3>Custom Output Service</h3>
<?php
$status = shell_exec("sudo systemctl is-active encoder-custom 2>&1");
$status = trim($status);
if ($status === "active")
$serviceEnabled = true;
else
$serviceEnabled = false;
?>
<div class="card-row">
<div class="service-label">
<strong>Service</strong>
<?php if ($serviceEnabled): ?>
<span class="badge badge-enabled">Enabled</span>
<?php else: ?>
<span class="badge badge-disabled">Disabled</span>
<?php endif; ?>
</div>
<form method="post" class="service-buttons">
<button type="submit" name="action" value="custom_restart" class="btn-restart">
Restart
</button>
<?php if ($serviceEnabled): ?>
<button type="submit" name="action" value="custom_disable" class="btn-disable">
Disable
</button>
<?php else: ?>
<button type="submit" name="action" value="custom_enable" class="btn-enable">
Enable
</button>
<?php endif; ?>
</form>
</div>
</div>
<div class="card wide">
<h3>Output Links</h3>
<?php echo $text; ?>
</div>
<br>
<br>
<br>
</div>
</div>
<br>
<br>
<?php include 'footer.php'; ?>

0
html/transcoder.php Normal file
View File

162
install.sh Executable file
View File

@ -0,0 +1,162 @@
sudo apt update
sudo apt install -y apache2 php libapache2-mod-php vainfo ufw intel-media-va-driver-non-free libavcodec-extra mesa-utils i965-va-driver libmfx1 intel-gpu-tools ffmpeg v4l-utils python3-pip mpv alsa-utils vlan git zlib1g-dev php-zip php-curl
sudo pip3 install psutil --break-system-packages
cat > /etc/sudoers.d/www-data << 'EOL'
www-data ALL=(ALL) NOPASSWD: ALL
EOL
cat > /usr/local/bin/nginx_system_monitor_sampler.py<< 'EOL'
#!/usr/bin/env python3
"""
Lightweight sampler for nginx static frontend.
"""
import time, json, os
from collections import deque
from datetime import datetime
import psutil
OUT_FILE = "/var/www/encoder/metrics.json"
TMP_FILE = OUT_FILE + ".tmp"
SAMPLE_INTERVAL = 10.0 # seconds between samples
HISTORY_SECONDS = 15 * 60 # 15 minutes
MAX_SAMPLES = int(HISTORY_SECONDS / SAMPLE_INTERVAL)
# circular buffers
timestamps = deque(maxlen=MAX_SAMPLES)
cpu_hist = deque(maxlen=MAX_SAMPLES)
ram_hist = deque(maxlen=MAX_SAMPLES)
net_in_hist = deque(maxlen=MAX_SAMPLES)
net_out_hist = deque(maxlen=MAX_SAMPLES)
disk_read_hist = deque(maxlen=MAX_SAMPLES)
disk_write_hist = deque(maxlen=MAX_SAMPLES)
disk_percent_hist = deque(maxlen=MAX_SAMPLES)
_prev_net = psutil.net_io_counters()
_prev_disk = psutil.disk_io_counters()
_prev_time = time.time()
def sample_once():
global _prev_net, _prev_disk, _prev_time
now = time.time()
iso = datetime.fromtimestamp(now).isoformat(timespec='seconds')
cpu = psutil.cpu_percent(interval=None)
ram = psutil.virtual_memory().percent
net = psutil.net_io_counters()
disk = psutil.disk_io_counters()
try:
disk_percent = psutil.disk_usage("/").percent
except Exception:
disk_percent = 0.0
elapsed = now - _prev_time if _prev_time else SAMPLE_INTERVAL
if elapsed <= 0:
elapsed = SAMPLE_INTERVAL
in_rate = int(((net.bytes_recv - _prev_net.bytes_recv) / elapsed) * 8)
out_rate = int(((net.bytes_sent - _prev_net.bytes_sent) / elapsed) * 8)
read_rate = (disk.read_bytes - _prev_disk.read_bytes) / elapsed
write_rate = (disk.write_bytes - _prev_disk.write_bytes) / elapsed
timestamps.append(iso)
cpu_hist.append(round(cpu, 2))
ram_hist.append(round(ram, 2))
net_in_hist.append(int(in_rate))
net_out_hist.append(int(out_rate))
disk_read_hist.append(int(read_rate))
disk_write_hist.append(int(write_rate))
disk_percent_hist.append(round(disk_percent, 2))
_prev_net = net
_prev_disk = disk
_prev_time = now
def write_json_atomic():
payload = {
"timestamps": list(timestamps),
"cpu_percent": list(cpu_hist),
"ram_percent": list(ram_hist),
"net_in_Bps": list(net_in_hist),
"net_out_Bps": list(net_out_hist),
"disk_read_Bps": list(disk_read_hist),
"disk_write_Bps": list(disk_write_hist),
"disk_percent": list(disk_percent_hist),
"sample_interval": SAMPLE_INTERVAL,
"generated_at": datetime.utcnow().isoformat(timespec='seconds') + "Z"
}
with open(TMP_FILE, "w") as f:
json.dump(payload, f)
os.replace(TMP_FILE, OUT_FILE)
def main():
global _prev_net, _prev_disk, _prev_time
_prev_net = psutil.net_io_counters()
_prev_disk = psutil.disk_io_counters()
_prev_time = time.time()
time.sleep(0.2) # warm-up
while True:
try:
sample_once()
write_json_atomic()
except Exception as e:
# systemd journal will capture prints
print("Sampler error:", e)
time.sleep(SAMPLE_INTERVAL)
if __name__ == "__main__":
main()
EOL
cat >/etc/netplan/00-stream.yaml<< 'EOL'
network:
version: 2
renderer: networkd
ethernets:
eth:
match:
name: enx*
addresses:
- 172.16.111.111/24
EOL
sudo cp -r html/* /var/www/html/
sudo cp backup_private.pem /var/www/
sudo cp backup_public.pem /var/www/
sudo cp 00-stream.yaml /var/www/
sudo cp attempts.json /var/www/
sudo cp users.json /var/www/
sudo a2enmod ssl
sudo systemctl enable apache2
sudo systemctl restart apache2
sudo a2ensite default-ssl
sudo chmod +x /usr/local/bin/nginx_system_monitor_sampler.py
sudo systemctl daemon-reload
sudo chmod 777 -R /var/www
sudo chown -R www-data:www-data /var/www
sudo systemctl daemon-reload
sudo chmod 444 /sys/class/dmi/id/product_uuid
sudo systemctl disable systemd-networkd-wait-online.service
sudo systemctl mask systemd-networkd-wait-online.service
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow proto udp to 224.0.0.0/4
sudo ufw route allow proto udp to 224.0.0.0/4
sudo ufw deny out to 239.255.254.254 port 39000 proto udp
sudo ufw allow from 172.16.111.112 to 172.16.111.111 port 80
sudo ufw allow from 172.16.111.112 to 172.16.111.111 port 443
sudo ufw --force enable
DEVICE_ID="$(sudo cat /sys/class/dmi/id/product_uuid | tr -d '\n')"
sudo sed -i 's/certificatecertificatecertificatecertificate/'$DEVICE_ID'/g' /var/www/html/certification.html

5
users.json Normal file
View File

@ -0,0 +1,5 @@
{
"shreebhattji": {
"password": "$2y$10$BInKRv9mhK69VfYKIi4WVegAs9VWtLhfdZH4YoDk5aE2U61cmyT2a"
}
}