UI updates and remove CSP for plugins

This commit is contained in:
KingKDot
2026-05-15 11:52:26 -05:00
parent da3bec8de1
commit 12972d6e8b
7 changed files with 86 additions and 63 deletions
+1
View File
@@ -68,6 +68,7 @@ plugins/build-toxi.bat
Overlord-Server/plugins/*
plugins/toxi/*
plugins/toxi copy/*
plugins/extension/*
*.zip
@@ -124,7 +124,7 @@ if (typeof anime !== "undefined") {
form?.addEventListener("submit", async (e) => {
e.preventDefault();
errEl.textContent = "";
successEl.style.display = "none";
successEl.textContent = "";
if (newPass.value !== confirmPass.value) {
errEl.textContent = "New passwords do not match";
@@ -164,19 +164,14 @@ form?.addEventListener("submit", async (e) => {
sessionStorage.removeItem("temp_user");
successEl.textContent = "Password changed successfully! Redirecting...";
successEl.style.opacity = "0";
successEl.style.display = "block";
if (typeof anime !== "undefined") {
anime({
targets: successEl,
opacity: [0, 1],
translateY: [-5, 0],
duration: 400,
easing: "easeOutQuad",
});
} else {
successEl.style.opacity = "1";
}
setTimeout(() => {
+57 -4
View File
@@ -1478,21 +1478,74 @@ article.card[data-bookmarked="true"] {
.error {
color: #ff9b9b;
min-height: 18px;
margin-top: 12px;
font-size: 13px;
text-align: center;
padding: 8px;
padding: 0;
border-radius: 8px;
background: rgba(255, 99, 99, 0.1);
border: 1px solid rgba(255, 99, 99, 0.2);
background: transparent;
border: 1px solid transparent;
opacity: 0;
transition:
opacity 220ms ease,
padding 220ms ease,
background-color 220ms ease,
border-color 220ms ease;
}
.error:not(:empty) {
opacity: 1;
padding: 8px 10px;
background: rgba(255, 99, 99, 0.1);
border-color: rgba(255, 99, 99, 0.22);
}
.success {
color: #6ee7b7;
margin-top: 12px;
font-size: 13px;
text-align: center;
padding: 0;
border-radius: 8px;
background: transparent;
border: 1px solid transparent;
opacity: 0;
transition:
opacity 220ms ease,
padding 220ms ease,
background-color 220ms ease,
border-color 220ms ease;
}
.success:not(:empty) {
opacity: 1;
padding: 8px 10px;
background: rgba(16, 185, 129, 0.12);
border-color: rgba(16, 185, 129, 0.28);
}
.login-footer {
margin-top: 18px;
padding-top: 16px;
border-top: 1px solid rgba(255, 255, 255, 0.06);
text-align: center;
font-size: 13px;
color: var(--color-text-muted);
}
.login-footer a {
color: #c4b8ff;
text-decoration: none;
border-bottom: 1px solid rgba(196, 184, 255, 0.25);
transition: color 180ms ease, border-color 180ms ease;
}
.login-footer a:hover {
color: #e6dffe;
border-bottom-color: rgba(230, 223, 254, 0.7);
}
.console-body {
background:
radial-gradient(120% 120% at 20% 20%, #102040 0%, transparent 45%),
+16 -31
View File
@@ -23,28 +23,23 @@
</div>
<div class="login-card">
<div class="login-crown-wrapper">
<i
class="fa-solid fa-shield-halved login-crown"
style="color: #f59e0b"
></i>
<i class="fa-solid fa-shield-halved login-crown"></i>
</div>
<div class="brand login-brand" style="color: #f59e0b">
Password Change Required
</div>
<h2 class="login-title">Change Default Password</h2>
<div class="brand login-brand">Secure your account</div>
<h2 class="login-title">Set a new password</h2>
<p class="muted login-subtitle">
For security reasons, you must change the default password before
continuing.
Choose a fresh password to replace the default before you continue.
</p>
<form id="change-password-form">
<div class="form-group">
<label class="label">Current Password</label>
<label class="label">Current password</label>
<div class="input-row input-animated">
<i class="fa-solid fa-lock"></i
><input
id="current-pass"
name="current-pass"
type="password"
autocomplete="current-password"
required
placeholder="Enter current password"
/>
@@ -52,52 +47,42 @@
</div>
<div class="form-group">
<label class="label">New Password</label>
<label class="label">New password</label>
<div class="input-row input-animated">
<i class="fa-solid fa-key"></i
><input
id="new-pass"
name="new-pass"
type="password"
autocomplete="new-password"
required
placeholder="Enter new password (min 6 characters)"
minlength="6"
placeholder="At least 6 characters"
/>
</div>
</div>
<div class="form-group">
<label class="label">Confirm New Password</label>
<label class="label">Confirm new password</label>
<div class="input-row input-animated">
<i class="fa-solid fa-key"></i
><input
id="confirm-pass"
name="confirm-pass"
type="password"
autocomplete="new-password"
required
placeholder="Confirm new password"
placeholder="Re-enter new password"
/>
</div>
</div>
<button type="submit" class="button primary full login-btn">
<span class="btn-text">Change Password</span>
<i class="fa-solid fa-check btn-icon"></i>
<span class="btn-text">Update password</span>
<i class="fa-solid fa-arrow-right btn-icon"></i>
</button>
<div id="error" class="error" aria-live="polite"></div>
<div
id="success"
class="success"
style="
color: #10b981;
margin-top: 12px;
text-align: center;
padding: 8px;
border-radius: 8px;
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.2);
"
aria-live="polite"
></div>
<div id="success" class="success" aria-live="polite"></div>
</form>
</div>
<script type="module" src="/assets/change-password.js"></script>
+5 -8
View File
@@ -26,10 +26,8 @@
<i class="fa-solid fa-crown login-crown"></i>
</div>
<div class="brand login-brand">Overlord</div>
<h2 class="login-title">Sign in</h2>
<p class="muted login-subtitle">
Access your Overlord
</p>
<h2 class="login-title">Welcome back</h2>
<p class="muted login-subtitle">Sign in to your control plane</p>
<form id="login-form">
<div class="form-group">
<label class="label">Username</label>
@@ -65,10 +63,9 @@
</button>
<div id="error" class="error" aria-live="polite"></div>
</form>
<div id="register-link" style="text-align: center; margin-top: 1rem; display: none">
<a href="/register.html" class="muted" style="font-size: 0.85rem; text-decoration: underline"
>Don't have an account? Register</a
>
<div id="register-link" class="login-footer" style="display: none">
Don't have an account?
<a href="/register.html">Create one</a>
</div>
</div>
<script src="/assets/login.js"></script>
-8
View File
@@ -7,14 +7,6 @@ export function secureHeaders(contentType?: string) {
};
}
export function securePluginHeaders() {
return {
...SECURITY_HEADERS,
"X-Frame-Options": "SAMEORIGIN",
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' wss: ws:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'",
};
}
const MIME_TYPES: Record<string, string> = {
".html": "text/html; charset=utf-8",
".css": "text/css; charset=utf-8",
@@ -1065,9 +1065,9 @@ export async function handlePluginRoutes(
return new Response(null, { status: 304 });
}
return new Response(injected, {
headers: { ...deps.secureHeaders("text/html; charset=utf-8"), "Cache-Control": "no-cache", ETag: etag },
});
const frameHeaders = { ...deps.secureHeaders("text/html; charset=utf-8"), "Cache-Control": "no-cache", ETag: etag };
delete (frameHeaders as any)["Content-Security-Policy"];
return new Response(injected, { headers: frameHeaders });
}
const pluginPageMatch = url.pathname.match(/^\/plugins\/([^/]+)$/);
@@ -1166,9 +1166,9 @@ export async function handlePluginRoutes(
</body>
</html>`;
return new Response(html, {
headers: { ...deps.secureHeaders("text/html; charset=utf-8"), "Cache-Control": "no-cache", ETag: etag },
});
const pageHeaders = { ...deps.secureHeaders("text/html; charset=utf-8"), "Cache-Control": "no-cache", ETag: etag };
delete (pageHeaders as any)["Content-Security-Policy"];
return new Response(html, { headers: pageHeaders });
}
const pluginAssetMatch = url.pathname.match(/^\/plugins\/([^/]+)\/assets\/(.+)$/);