security update + make easter egg optional.

This commit is contained in:
KingKDot
2026-08-01 01:54:07 -05:00
parent bd7b3ea6f4
commit 34158ba673
22 changed files with 534 additions and 90 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ import { checkFeatureAccess } from "./feature-gate.js";
import { createKeyboardCapture } from "./keyboard-capture.js";
import { WhepClient } from "./whep.js";
import { P2PClient } from "./webrtc-p2p.js";
import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-settings.js";
import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./generated/shared-ui-settings.js";
(async function () {
const urlParams = new URLSearchParams(location.search);
@@ -0,0 +1,65 @@
const EASTER_EGG_ENABLED_KEY = "overlord_easter_egg_enabled";
const EASTER_EGG_SHOWN_KEY = "overlord_easter_egg_shown";
const EASTER_EGG_URL = "/assets/console.gif";
let activeRender = null;
export function isEasterEggEnabled() {
try {
return localStorage.getItem(EASTER_EGG_ENABLED_KEY) === "true";
} catch {
return false;
}
}
export function setEasterEggEnabled(enabled) {
try {
localStorage.setItem(EASTER_EGG_ENABLED_KEY, String(Boolean(enabled)));
} catch {}
if (!enabled) {
try {
sessionStorage.removeItem(EASTER_EGG_SHOWN_KEY);
} catch {}
}
}
function wasShownThisSession() {
try {
return sessionStorage.getItem(EASTER_EGG_SHOWN_KEY) === "true";
} catch {
return false;
}
}
function markShownThisSession() {
try {
sessionStorage.setItem(EASTER_EGG_SHOWN_KEY, "true");
} catch {}
}
export async function showEnabledEasterEgg({ force = false } = {}) {
if (!isEasterEggEnabled() || (!force && wasShownThisSession())) return false;
if (activeRender) return activeRender;
activeRender = (async () => {
const response = await fetch(EASTER_EGG_URL);
if (!response.ok) throw new Error(`Easter egg failed to load (${response.status})`);
const blob = await response.blob();
if (!blob.type.startsWith("image/")) throw new Error("Easter egg response was not an image");
const objectUrl = URL.createObjectURL(blob);
console.log(
"%c ",
`background:url("${objectUrl}") left top/contain no-repeat;font-size:320px;background-color:transparent`,
);
markShownThisSession();
setTimeout(() => URL.revokeObjectURL(objectUrl), 30_000);
return true;
})().finally(() => {
activeRender = null;
});
return activeRender;
}
+3 -37
View File
@@ -15,6 +15,7 @@ import {
} from "./data.js";
import { ThumbnailLoader } from "./thumbnail-loader.js";
import { initDashboardStats, updateDashboardStatsFromClients } from "./dashboard-stats.js";
import { showEnabledEasterEgg } from "./easter-egg.js";
const grid = document.getElementById("grid");
const totalPill = document.getElementById("total-pill");
@@ -2243,40 +2244,5 @@ menu.addEventListener("click", async (e) => {
loadCurrentUser();
// console easter egg
(function () {
const runWhenIdle = (fn) => {
if ("requestIdleCallback" in window) {
window.requestIdleCallback(fn, { timeout: 5000 });
return;
}
window.addEventListener("load", () => setTimeout(fn, 1500), { once: true });
};
const consoleimg = {
load: function (src, { size = 320, color = "transparent" } = {}) {
const reader = new FileReader();
reader.addEventListener("load", function () {
const style =
"background: url('" + reader.result + "') left top no-repeat; font-size: " +
size +
"px; background-size: contain; background-color:" +
color;
console.log("%c ", style);
}, false);
fetch(src)
.then((r) => r.blob())
.then((blob) => {
if (blob.type.indexOf("image") === 0) {
if (blob.size > 8192 && navigator.userAgent.indexOf("Firefox") > 0)
throw new Error("Image size too big to be displayed in Firefox.");
return blob;
}
throw new Error("Valid image not found.");
})
.then((blob) => reader.readAsDataURL(blob))
.catch((err) => console.warn(err.message));
},
};
runWhenIdle(() => consoleimg.load("/assets/console.gif", { size: 320, color: "transparent" }));
})();
// Opt-in console easter egg. Disabled users never request the large image.
showEnabledEasterEgg().catch((err) => console.warn(err.message));
@@ -4,7 +4,7 @@ import { WhepClient } from "./whep.js";
import { P2PClient } from "./webrtc-p2p.js";
import { AdaptiveDesktopQuality, normalizeAdaptiveProfiles } from "./rd-adaptive-quality.js";
import { createKeyboardCapture } from "./keyboard-capture.js";
import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-settings.js";
import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./generated/shared-ui-settings.js";
(async function () {
const clientId = new URLSearchParams(location.search).get("clientId");
+40
View File
@@ -7,6 +7,11 @@ import {
} from "./notify-client.js";
import { escapeHtml, formatBytes as formatSharedBytes, formatDate as formatSharedDate } from "./format.js";
import { getCertificateTrustGuide } from "./cert-banner.js";
import {
isEasterEggEnabled,
setEasterEggEnabled,
showEnabledEasterEgg,
} from "./easter-egg.js";
const PREF_REFRESH_KEY = "overlord_refresh_interval_seconds";
const NAV_MODE_KEY = "sb_mode";
@@ -40,6 +45,8 @@ const prefNotificationsInput = document.getElementById("pref-notifications");
const prefDesktopNotificationsInput = document.getElementById("pref-desktop-notifications");
const prefDesktopNotificationsHint = document.getElementById("pref-desktop-notifications-hint");
const prefRefreshSecondsInput = document.getElementById("pref-refresh-seconds");
const easterEggEnabledInput = document.getElementById("easter-egg-enabled");
const easterEggStatus = document.getElementById("easter-egg-status");
const inputArchiveUserForm = document.getElementById("input-archive-user-form");
const inputArchiveMyEnabledInput = document.getElementById("input-archive-my-enabled");
@@ -656,6 +663,38 @@ function loadPrefs() {
}
}
function initEasterEggPreference() {
if (!easterEggEnabledInput) return;
easterEggEnabledInput.checked = isEasterEggEnabled();
easterEggEnabledInput.addEventListener("change", async () => {
const enabled = easterEggEnabledInput.checked;
setEasterEggEnabled(enabled);
if (!easterEggStatus) return;
if (!enabled) {
easterEggStatus.textContent = "Disabled. The image will not be requested.";
easterEggStatus.className = "text-xs text-slate-500";
return;
}
easterEggEnabledInput.disabled = true;
easterEggStatus.textContent = "Loading the easter egg…";
easterEggStatus.className = "text-xs text-violet-300";
try {
await showEnabledEasterEgg({ force: true });
easterEggStatus.textContent = "Enabled and shown in the browser console.";
easterEggStatus.className = "text-xs text-emerald-400";
} catch (error) {
setEasterEggEnabled(false);
easterEggEnabledInput.checked = false;
easterEggStatus.textContent = `Could not load the easter egg: ${error.message}`;
easterEggStatus.className = "text-xs text-rose-400";
} finally {
easterEggEnabledInput.disabled = false;
}
});
}
async function loadCurrentUser() {
const res = await fetch("/api/auth/me", { credentials: "include" });
if (!res.ok) {
@@ -2926,6 +2965,7 @@ async function init() {
await loadCurrentUser();
applyPermissionVisibility();
loadPrefs();
initEasterEggPreference();
await loadMfaStatus();
if (userHas("clients:build")) {
@@ -1,60 +0,0 @@
export async function loadSharedUiSettings(scope) {
try {
const res = await fetch(`/api/ui-settings/${encodeURIComponent(scope)}`, {
credentials: "include",
});
if (!res.ok) return {};
const data = await res.json().catch(() => ({}));
return data && typeof data.settings === "object" && data.settings ? data.settings : {};
} catch (err) {
console.warn(`ui-settings: failed to load ${scope}`, err);
return {};
}
}
export function createSharedUiSettingsSaver(scope, readSettings, delayMs = 350) {
let timer = null;
let lastPayload = "";
async function saveNow() {
if (timer) {
clearTimeout(timer);
timer = null;
}
let settings = {};
try {
settings = readSettings() || {};
} catch (err) {
console.warn(`ui-settings: failed to read ${scope}`, err);
return;
}
const payload = JSON.stringify(settings);
if (payload === lastPayload) return;
lastPayload = payload;
try {
const res = await fetch(`/api/ui-settings/${encodeURIComponent(scope)}`, {
method: "PUT",
credentials: "include",
keepalive: true,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ settings }),
});
if (!res.ok) {
lastPayload = "";
}
} catch (err) {
lastPayload = "";
console.warn(`ui-settings: failed to save ${scope}`, err);
}
}
function scheduleSave() {
if (timer) clearTimeout(timer);
timer = setTimeout(saveNow, delayMs);
}
return { scheduleSave, saveNow };
}
+1 -1
View File
@@ -2,7 +2,7 @@ import { encodeMsgpack, decodeMsgpack } from "./msgpack-helpers.js";
import { checkFeatureAccess } from "./feature-gate.js";
import { WhepClient } from "./whep.js";
import { P2PClient } from "./webrtc-p2p.js";
import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-settings.js";
import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./generated/shared-ui-settings.js";
(async function () {
const clientId = new URLSearchParams(location.search).get("clientId");