v0.31.1
This commit is contained in:
1 parent
76b8bb7ee2
commit
24af7478b8
29 files changed
+321
-171
No files matched your search
@@ -396,12 +396,13 @@ async function activate(info) {
|
||||
window.rustProxyRedirects?.applyPreferences(preferences);
|
||||
window.rustProxyNotFound?.applyPreferences(preferences);
|
||||
window.rustProxyStreams?.applyPreferences(preferences);
|
||||
// The live SSE stream is already running. Configuration can load behind the
|
||||
// visible shell; it does not belong in the live refresh cycle.
|
||||
try { await loadConfig(); }
|
||||
catch (error) {
|
||||
if (authenticated && epoch === authEpoch) toast(error.message, true);
|
||||
return;
|
||||
for (let attempt = 0; attempt < 3 && authenticated && epoch === authEpoch; attempt++) {
|
||||
try { await loadConfig(); break; }
|
||||
catch (error) {
|
||||
if (!authenticated || epoch !== authEpoch || error?.status === 401) return;
|
||||
if (attempt === 2) { showStartupFailure(error); return; }
|
||||
await new Promise(resolve => setTimeout(resolve, (attempt + 1) * 400));
|
||||
}
|
||||
}
|
||||
if (!authenticated || epoch !== authEpoch) return;
|
||||
// A single full snapshot seeds non-live diagnostics; subsequent updates
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
(async () => {
|
||||
// All modules must be available before any asynchronous session/config work can
|
||||
// render the panel. DOMContentLoaded also waits for the complete deferred bundle.
|
||||
function verifyAdminModules() {
|
||||
const required = [
|
||||
["rustProxyIntegrations", "bindings"],
|
||||
["rustProxyVhosts", "render"],
|
||||
["rustProxySettings", "render"],
|
||||
["rustProxyCachePanel", "refresh"],
|
||||
["rustProxyTrafficPanel", "refresh"],
|
||||
["rustProxyPreferences", "load"],
|
||||
["rustProxyRefresh", "start"],
|
||||
];
|
||||
const missing = required.find(([module, method]) => typeof window[module]?.[method] !== "function");
|
||||
if (missing) throw new Error(`Panel resources incomplete (${missing[0]}). Reload to retry.`);
|
||||
}
|
||||
|
||||
async function startAdminPanel() {
|
||||
try {
|
||||
verifyAdminModules();
|
||||
// Revalidate the session first. The anonymous document has its own login.js;
|
||||
// app.js belongs to the authenticated shell and must not fall back to its
|
||||
// legacy embedded sign-in form when another startup step fails.
|
||||
@@ -18,7 +35,12 @@
|
||||
}
|
||||
showStartupFailure(e);
|
||||
}
|
||||
})();
|
||||
}
|
||||
// The previous bootstrap ran while sibling deferred scripts were still loading.
|
||||
// Starting only after DOMContentLoaded prevents fast API responses from racing
|
||||
// against a slower or failed JS resource on mobile/reverse-proxied connections.
|
||||
if (document.readyState === "complete") startAdminPanel();
|
||||
else document.addEventListener("DOMContentLoaded", startAdminPanel, { once: true });
|
||||
|
||||
function certificateUsesExternalFiles(cert) {
|
||||
return String(cert?.cert_file || "").startsWith("/") && String(cert?.key_file || "").startsWith("/");
|
||||
|
||||
Reference in new issue
Block a user