Be careful what you wish for
This commit is contained in:
commit
53e90202ee
150
itube.html
Normal file
150
itube.html
Normal file
@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>iTube.lan</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #222;
|
||||
}
|
||||
h1, .YouTubeWrapper {
|
||||
color: #ccc;
|
||||
text-align: center;
|
||||
margin: 1em;
|
||||
}
|
||||
iframe {
|
||||
border-radius: 1em;
|
||||
}
|
||||
#urlInput {
|
||||
width: 40em;
|
||||
}
|
||||
#urlInput, button {
|
||||
border-radius: 1em;
|
||||
}
|
||||
#logContainer {
|
||||
display: none;
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="youtube"><h1>iTube.lan</h1></a>
|
||||
<div class="YouTubeWrapper">
|
||||
<label for="urlInput"></label>
|
||||
<input type="text" id="urlInput" placeholder="https://www.youtube.com/watch?v=dQw4w9WgXcQ&pp=chopped">
|
||||
<button onclick="updateIframe()">Load Video</button>
|
||||
<button onclick="toggleLog()">Toggle Log</button>
|
||||
<div id="logContainer"></div>
|
||||
</div>
|
||||
<div class="YouTubeWrapper">
|
||||
<iframe id="YouTubePlayer" width="1280" height="720" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
<script>
|
||||
// Function to get query parameters
|
||||
function getQueryParam(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
function sanitizeAndModifyURL(url) {
|
||||
try {
|
||||
let parsedUrl = new URL(url);
|
||||
|
||||
// **1. Allow only certain domains (whitelist)**
|
||||
const allowedDomains = ["youtu.be", "youtube.com"];
|
||||
if (!allowedDomains.some(domain => parsedUrl.hostname.endsWith(domain))) {
|
||||
console.warn("Blocked an untrusted URL:", url);
|
||||
return null;
|
||||
}
|
||||
|
||||
// **2. Remove unwanted tracking / continuation parameters**
|
||||
const unwantedParams = ["si", "pp", "t", "start", "utm_source", "utm_medium", "utm_campaign", "tracking_id"];
|
||||
unwantedParams.forEach(param => parsedUrl.searchParams.delete(param));
|
||||
|
||||
// **3. Apply regex transformations**
|
||||
let modifiedURL = parsedUrl.toString();
|
||||
|
||||
// Example regex: Replace 'http' with 'https' (if needed)
|
||||
modifiedURL = modifiedURL.replace(/^http:/, "https:");
|
||||
|
||||
// Example regex: Remove 'www.' if present
|
||||
modifiedURL = modifiedURL.replace(/\/\/www\./, "//");
|
||||
|
||||
// Production regex: Replace "youtu.be" with "youtube.com/embed"
|
||||
modifiedURL = modifiedURL.replace(/youtu.be/, "youtube.com\/embed");
|
||||
|
||||
// Production regex: Replace "watch?v=NOOTEsFnOuM&list" with "embed/videoseries?list"
|
||||
modifiedURL = modifiedURL.replace(/watch\?v=.*\&list/, "embed\/videoseries\?list");
|
||||
|
||||
// Production regex: Replace "watch?list=RDj03h1i6ouA8&v=j03h1i6ouA8" with "embed/videoseries?list"
|
||||
modifiedURL = modifiedURL.replace(/watch\?list/, "embed\/videoseries\?list");
|
||||
|
||||
// Production regex: Replace "watch?v=" with "embed/"
|
||||
modifiedURL = modifiedURL.replace(/watch\?v=/, "embed\/");
|
||||
|
||||
// Production regex: Replace "shorts" with "embed"
|
||||
modifiedURL = modifiedURL.replace(/shorts/, "embed");
|
||||
|
||||
console.log("Sanitized URL:", modifiedURL); // Log sanitized URL
|
||||
updateLog(url, modifiedURL); // Update UI Log
|
||||
|
||||
return modifiedURL;
|
||||
} catch (error) {
|
||||
console.error("Invalid URL provided:", url);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the 'url' parameter from the query string
|
||||
let iframeSrc = getQueryParam('url');
|
||||
if (iframeSrc) {
|
||||
iframeSrc = sanitizeAndModifyURL(iframeSrc);
|
||||
if (iframeSrc) {
|
||||
document.getElementById('YouTubePlayer').src = iframeSrc;
|
||||
}
|
||||
}
|
||||
|
||||
function updateIframe() {
|
||||
const inputUrl = document.getElementById('urlInput').value;
|
||||
const sanitizedUrl = sanitizeAndModifyURL(inputUrl);
|
||||
|
||||
if (sanitizedUrl) {
|
||||
document.getElementById('YouTubePlayer').src = sanitizedUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function updateLog(original, sanitized) {
|
||||
const logContainer = document.getElementById('logContainer');
|
||||
logContainer.innerHTML = `Original URL: ${original}\nSanitized URL: ${sanitized}`;
|
||||
}
|
||||
|
||||
function toggleLog() {
|
||||
const logContainer = document.getElementById('logContainer');
|
||||
logContainer.style.display = logContainer.style.display === "none" ? "block" : "none";
|
||||
}
|
||||
|
||||
// **Load URL from GET param (if available)**
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
let iframeSrc = getQueryParam('url');
|
||||
if (iframeSrc) {
|
||||
iframeSrc = sanitizeAndModifyURL(iframeSrc);
|
||||
if (iframeSrc) {
|
||||
document.getElementById('YouTubePlayer').src = iframeSrc;
|
||||
document.getElementById('urlInput').value = iframeSrc; // Fill the input with the loaded URL
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// **Trigger button click on pressing Enter**
|
||||
document.getElementById("urlInput").addEventListener("keypress", function (event) {
|
||||
if (event.key === "Enter") {
|
||||
updateIframe();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user