chore: update stuff

This commit is contained in:
MattTheTekie 2026-02-27 17:24:39 -05:00
commit 29d7d29288

View file

@ -14,21 +14,27 @@ let NAV_PREV = document.getElementById("navMusicPrevious");
// ===============================
// URL SANITIZER
// UNIVERSAL AUDIO URL SANITIZER
// ===============================
function sanitizeMp3Url(raw) {
function sanitizeAudioUrl(raw) {
if (!raw) return null;
// Reject invalid placeholders
// Reject placeholders or HTML anchors
if (raw === "#" || raw === "/" || raw === "./" || raw === "../") return null;
// Reject URLs that are not MP3 files
if (!raw.endsWith(".mp3")) return null;
// Allowed audio extensions
const audioExtensions = [
".mp3", ".ogg", ".wav", ".m4a", ".aac", ".flac", ".opus", ".webm"
];
// If JSON gives absolute URL
const lower = raw.toLowerCase();
const isAudio = audioExtensions.some(ext => lower.endsWith(ext));
if (!isAudio) return null;
// Absolute URL
if (raw.startsWith("http")) return raw;
// If JSON gives /music/... or /audio/...
// JSON gives /music/... or /audio/...
if (raw.startsWith("/")) {
return "https://frutigeraeroarchive.org" + raw;
}
@ -39,10 +45,13 @@ function sanitizeMp3Url(raw) {
// ===============================
// LOAD MUSIC DATA
// LOAD MUSIC DATA (CORS PROXY)
// ===============================
async function loadMusicData() {
const response = await fetch("https://frutigeraeroarchive.org/data/music.min.json");
const response = await fetch(
"https://corsproxy.io/?url=https%3A%2F%2Ffrutigeraeroarchive.org%2Fdata%2Fmusic.min.json"
);
const data = await response.json();
const section = data.ols.find(item => item["@id"] === "frutigerAeroBliss");
@ -51,22 +60,15 @@ async function loadMusicData() {
// KEEP JSON ORDER EXACTLY, but filter invalid URLs
return section.li
.map(item => {
const fixedUrl = sanitizeMp3Url(item.a["@data-src-mp3"]);
const fixedUrl = sanitizeAudioUrl(item.a["@data-src-mp3"]);
if (!fixedUrl) return null;
return {
title: item.a.title,
url: fixedUrl,
background: item.a["@data-background"] || "",
artist: item.a["@data-artist"] || "",
spotify: item.a["@data-spotify"] || "",
youtube: item.a["@data-youtube"] || "",
description: item.a["@data-description"] || "",
copyright: item.a["@data-copyright"] || "",
date: item.a["@data-date"] || ""
...item.a,
"@data-src-mp3": fixedUrl
};
})
.filter(Boolean); // remove null entries
.filter(Boolean);
}
@ -90,7 +92,7 @@ function createAlbum(album) {
small.textContent = album.small;
list.appendChild(small);
// Build playlist in EXACT JSON ORDER
// Build playlist ONLY from valid songs
album.li.forEach((song, index) => {
const li = document.createElement("li");
const a = document.createElement("a");
@ -98,7 +100,6 @@ function createAlbum(album) {
a.textContent = song.a.title;
a.href = "#";
// Apply metadata
for (const key in song.a) {
if (key.startsWith("@data-")) {
a.setAttribute(key.replace("@", ""), song.a[key]);
@ -121,7 +122,6 @@ function createAlbum(album) {
});
});
// ALWAYS START AT SONG 0
currentSongIndex = 0;
updateSong(0);
}