179 lines
9.9 KiB
HTML
179 lines
9.9 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Welcome to your Pi-Kit</title>
|
||
<link rel="stylesheet" href="/style.css?v=2" />
|
||
</head>
|
||
<body>
|
||
<main class="card">
|
||
<header>
|
||
<div class="dot"></div>
|
||
<h1>Welcome to your Pi-Kit</h1>
|
||
</header>
|
||
|
||
<p class="welcome">Great news — you’re already on your Pi-Kit and it’s responding.</p>
|
||
<div class="status-row" aria-live="polite">
|
||
<span class="status-chip" id="statusChip">You’re on HTTP — trust the CA or continue to HTTPS.</span>
|
||
</div>
|
||
<p class="subtle">
|
||
Everything stays on your local network. Let’s move you to the secure (HTTPS) dashboard so you
|
||
can manage Pi-Kit safely.
|
||
</p>
|
||
|
||
<section class="steps">
|
||
<h3>Why switch to HTTPS?</h3>
|
||
<ul>
|
||
<li>Encrypts traffic on your LAN so no one can snoop your Pi-Kit dashboard.</li>
|
||
<li>Stops mixed-content / “not secure” browser warnings.</li>
|
||
<li>Needed for some browser features (clipboard, notifications, service workers).</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="steps">
|
||
<h3>If you see a warning</h3>
|
||
<ul>
|
||
<li>Brave/Chrome: click <strong>Advanced</strong> → <strong>Proceed</strong>.</li>
|
||
<li>Firefox: click <strong>Advanced</strong> → <strong>Accept the Risk & Continue</strong>.</li>
|
||
</ul>
|
||
<p>This warning is expected the first time. It’s safe for your own Pi on your own network.</p>
|
||
</section>
|
||
|
||
<section class="steps">
|
||
<h3>Install the Pi-Kit CA (recommended, one-time)</h3>
|
||
<div class="ca-download">
|
||
<p>This removes future warnings for the Pi-Kit dashboard.</p>
|
||
<a class="ghost download-inline" id="downloadCa" href="http://pikit.local/assets/pikit-ca.crt" download>
|
||
Download Pi-Kit CA
|
||
</a>
|
||
</div>
|
||
<p class="checksum">SHA256: <code class="inline">6bc217c340e502ef20117bd4dc35e05f9f16c562cc3a236d3831a9947caddb97</code></p>
|
||
<details>
|
||
<summary id="win">Windows</summary>
|
||
<p>Run <strong>mmc</strong> → Add/Remove Snap-in → Certificates (Computer) → Trusted Root CAs → Import <em>pikit-ca.crt</em>.</p>
|
||
</details>
|
||
<details>
|
||
<summary id="mac">macOS</summary>
|
||
<p>Double-click <em>pikit-ca.crt</em> → Always Trust.</p>
|
||
</details>
|
||
<details>
|
||
<summary id="linux">Linux</summary>
|
||
<p><strong>Arch-based:</strong> <code id="archCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo install -m644 /tmp/pikit-ca.crt /etc/ca-certificates/trust-source/anchors/ && sudo trust extract-compat</code></p>
|
||
<button class="copy" data-target="archCmd">Copy Arch command</button>
|
||
<p><strong>Debian/Ubuntu:</strong> <code id="debCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo cp /tmp/pikit-ca.crt /usr/local/share/ca-certificates/pikit-ca.crt && sudo update-ca-certificates</code></p>
|
||
<button class="copy" data-target="debCmd">Copy Debian/Ubuntu command</button>
|
||
<p><strong>Fedora/RHEL:</strong> <code id="fedoraCmd">curl -s http://pikit.local/assets/pikit-ca.crt -o /tmp/pikit-ca.crt && sudo cp /tmp/pikit-ca.crt /etc/pki/ca-trust/source/anchors/pikit-ca.crt && sudo update-ca-trust</code></p>
|
||
<button class="copy" data-target="fedoraCmd">Copy Fedora/RHEL command</button>
|
||
</details>
|
||
<details>
|
||
<summary id="bsd">BSD (FreeBSD / OpenBSD)</summary>
|
||
<code id="bsdCmd">fetch -o /tmp/pikit-ca.crt http://pikit.local/assets/pikit-ca.crt && sudo install -m644 /tmp/pikit-ca.crt /usr/local/share/certs/pikit-ca.crt && sudo certctl rehash</code>
|
||
<button class="copy" data-target="bsdCmd">Copy</button>
|
||
</details>
|
||
<div id="copyStatus" class="copy-status" aria-live="polite"></div>
|
||
</section>
|
||
|
||
|
||
<section class="actions">
|
||
<button id="continueBtn">Go to secure dashboard</button>
|
||
</section>
|
||
|
||
<section class="qr-wrap">
|
||
<div class="qr-block">
|
||
<div>
|
||
<p class="qr-title">Use your phone</p>
|
||
<p class="subtle tiny">Scan to open http://pikit.local</p>
|
||
</div>
|
||
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAklEQVR4AewaftIAAAWtSURBVO3BsXUlWQ5EwSTO1yhRpyNQYBaMeGZBgVsrjDDKZPWe6i2S03sj3vT+8SkA/ygEwAoBsEIArBAAKwTACgGwQgCsl34lp/Un2TpyclpXto6cnNa/ydbRXTmtP8nWkRECYIUAWCEAVgiAFQJghQBYL/2OraOfJqf1lJzWE7aOnJzWE3JaV7aO7to6+mlyWjeEAFghAFYIgBUCYIUAWCEAVgiA9dKTclpP2Dr6abaOnrB1dCWn5WwdOTmt75DTesLW0QNCAKwQACsEwAoBsEIArBAA6yX8b+S0nK2ju3JaV7aOnJyWs3WEXwoBsEIArBAAKwTACgGwQgCsEADrJfz3to6cnJaT03pKTguPCQGwQgCsEAArBMAKAbBCAKyXnrR19G+ydXTX1pGT07qydXRXTuuOnNaVraMnbB39i4QAWCEAVgiAFQJghQBYIQDWS78jp/UnyWld2TpyclrO1tGVnJazdXTX1pGT03pKTusPEQJghQBYIQBWCIAVAmCFAFghANab3j8+hb/ktO7aOnJyWle2jvAjhQBYIQBWCIAVAmCFAFghANZLvyOnddfW0ZWclrN15OS07to6uiun5WwdXclpOVtHT8hpXdk6cnJaV7aOnJzWT7N1ZIQAWCEAVgiAFQJghQBYIQBWCID10q/ktJytoys5rbu2jpyclrN19JSclrN15OS0rmwdOTmtK1tHT8hpPWHr6DvktG4IAbBCAKwQACsEwAoBsEIArDe9f3zqKTmtu7aOnJzWE7aO7sppPWHr6EpOy9k6+g45rTu2jq7ktJ6wdWSEAFghAFYIgBUCYIUAWCEA1ku/ktNyto6ubB3dldO6Y+vorpzWla2jO7aOruS0nJzWE3JaV7aOnJzWd9g6cnJaV7aObggBsEIArBAAKwTACgGwQgCsEADrpe+S07qydXRHTuvfZuvorpyWk9O6K6d119bRHTmtK1tHd+W0nK0jIwTACgGwQgCsEAArBMAKAbDe9P7xqZ8op+VsHT0hp3XX1tFdOa0nbB05Oa2nbB3dkdO6snV0V07L2ToyQgCsEAArBMAKAbBCAKwQACsEwHrpV3JaztbRlZyWs3X0hJzWla0jZ+voSk7rCVtHTk7rO2wdPSGn5WwdXclpfbEQACsEwAoBsEIArBAAKwTAetP7x6fuymld2Tp6Qk7L2Tp6Sk7rq20d3ZXTumvr6K6clrN15OS0rmwdOTmtK1tHN4QAWCEAVgiAFQJghQBYIQDWm94/PnUlp+VsHX2HnNZ32DpyclrO1tFTclr/L7aOvlgIgBUCYIUAWCEAVgiAFQJghQBYb3r/+BT+ktO6snXk5LScraMrOS1n6+iunNZdW0dPyGn9NFtHRgiAFQJghQBYIQBWCIAVAmC99Cs5rT/J1tFdOa07clpXto6cnNaVraOvltO6snV0x9bRXTmtB4QAWCEAVgiAFQJghQBYIQBWCID10u/YOvppclp3bR1dyWndsXX0HbaOnJzWXVtHT8hpXdk6+mIhAFYIgBUCYIUAWCEAVgiA9dKTclpP2Dp6Qk7rytbRV9s6+g45ra+2dXTX1tGVnNYNIQBWCIAVAmCFAFghAFYIgPUS/rZ1dCWndcfW0ZWc1l1bR05O666toyfktO7KaTlbR1e2jm4IAbBCAKwQACsEwAoBsEIArBAA6yX8Lad1ZevIyWk5Oa0rW0d35bTu2Dq6ktNyto6u5LTuyGld2Tq6K6flbB0ZIQBWCIAVAmCFAFghAFYIgPXSk7aO/iQ5LWfryMlpXclp3bV15OS0nJzWla2ju7aOnJzWE3JaV7aObggBsEIArBAAKwTACgGwQgCsEADrpd+R0/qTbB3dldO6a+voCVtHTk7rrpzWXVtH3yGn5WwdGSEAVgiAFQJghQBYIQBWCID1pvePTwH4RyEAVgiAFQJghQBYIQBWCID1H2sRkkI2gzaOAAAAAElFTkSuQmCC" alt="QR code to http://pikit.local" />
|
||
</div>
|
||
</section>
|
||
|
||
<p class="footnote">Once trusted, this page will auto-forward you to the secure dashboard.</p>
|
||
<p class="footnote">If the hostname ever fails, try http://<pi-ip>/ (or https://<pi-ip>/ — your browser will show the same warning to bypass).</p>
|
||
|
||
<script>
|
||
(function () {
|
||
const target = `https://${location.hostname}`;
|
||
const hasCookie = document.cookie.includes("pikit_https_ok=1");
|
||
const statusChip = document.getElementById("statusChip");
|
||
const copyStatus = document.getElementById("copyStatus");
|
||
|
||
document.getElementById("continueBtn").addEventListener("click", () => {
|
||
window.location = target;
|
||
});
|
||
|
||
document.querySelectorAll(".copy").forEach((btn) => {
|
||
btn.addEventListener("click", async () => {
|
||
const id = btn.dataset.target;
|
||
const el = document.getElementById(id);
|
||
const text = el.textContent.trim();
|
||
try {
|
||
if (navigator.clipboard && window.isSecureContext) {
|
||
await navigator.clipboard.writeText(text);
|
||
} else {
|
||
const ta = document.createElement("textarea");
|
||
ta.value = text;
|
||
ta.style.position = "fixed";
|
||
ta.style.opacity = "0";
|
||
document.body.appendChild(ta);
|
||
ta.select();
|
||
document.execCommand("copy");
|
||
document.body.removeChild(ta);
|
||
}
|
||
const original = btn.dataset.label || btn.textContent;
|
||
btn.textContent = "Copied";
|
||
copyStatus.textContent = "Copied to clipboard.";
|
||
setTimeout(() => {
|
||
btn.textContent = original;
|
||
copyStatus.textContent = "";
|
||
}, 1600);
|
||
} catch (err) {
|
||
const original = btn.dataset.label || btn.textContent;
|
||
btn.textContent = "Failed";
|
||
copyStatus.textContent = "Copy failed. Try manual copy.";
|
||
setTimeout(() => (btn.textContent = original), 1500);
|
||
}
|
||
});
|
||
});
|
||
|
||
// Accordion: keep only one platform section open at a time
|
||
const detailBlocks = Array.from(document.querySelectorAll("details"));
|
||
detailBlocks.forEach((d) => {
|
||
d.addEventListener("toggle", () => {
|
||
if (!d.open) return;
|
||
detailBlocks.forEach((other) => {
|
||
if (other !== d) other.removeAttribute("open");
|
||
});
|
||
});
|
||
});
|
||
|
||
// Auto-open matching OS section
|
||
const ua = (navigator.userAgent || "").toLowerCase();
|
||
const platform = (navigator.platform || "").toLowerCase();
|
||
const openOne = (id) => {
|
||
const el = document.getElementById(id)?.parentElement;
|
||
if (el && el.tagName === "DETAILS") {
|
||
el.setAttribute("open", "");
|
||
detailBlocks.forEach((other) => {
|
||
if (other !== el) other.removeAttribute("open");
|
||
});
|
||
}
|
||
};
|
||
const has = (s) => ua.includes(s) || platform.includes(s);
|
||
if (has("windows")) openOne("win");
|
||
else if (has("mac")) openOne("mac");
|
||
else if (has("linux")) openOne("linux");
|
||
else if (has("bsd")) openOne("bsd");
|
||
|
||
if (hasCookie) {
|
||
statusChip.textContent = "HTTPS trusted — redirecting…";
|
||
window.location = target;
|
||
} else {
|
||
statusChip.textContent = "You’re on HTTP — trust the CA or click Go to secure dashboard.";
|
||
}
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|