harden oneliner session backend recovery
This commit is contained in:
@@ -562,6 +562,17 @@ function setLastSeenAt(value) {
|
|||||||
appState.lastSeenAt = SESSION_STORE.setLastSeenAt(value);
|
appState.lastSeenAt = SESSION_STORE.setLastSeenAt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeBackendUrlValue(value) {
|
||||||
|
return String(value || "").trim().replace(/\/$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasSessionBackendMismatch(expectedBackendUrl = DEFAULT_BACKEND_URL) {
|
||||||
|
if (!appState.session) return false;
|
||||||
|
const expected = normalizeBackendUrlValue(expectedBackendUrl);
|
||||||
|
const current = normalizeBackendUrlValue(appState.session.backendUrl);
|
||||||
|
return Boolean(expected && current && expected !== current);
|
||||||
|
}
|
||||||
|
|
||||||
function compareDateDesc(leftValue, rightValue) {
|
function compareDateDesc(leftValue, rightValue) {
|
||||||
return new Date(rightValue || 0).getTime() - new Date(leftValue || 0).getTime();
|
return new Date(rightValue || 0).getTime() - new Date(leftValue || 0).getTime();
|
||||||
}
|
}
|
||||||
@@ -1139,6 +1150,10 @@ async function loginWithAutoSession(backendUrl = DEFAULT_BACKEND_URL) {
|
|||||||
async function ensureAutoSession(options = {}) {
|
async function ensureAutoSession(options = {}) {
|
||||||
const backendUrl = options.backendUrl || readAuthForm().backendUrl || DEFAULT_BACKEND_URL;
|
const backendUrl = options.backendUrl || readAuthForm().backendUrl || DEFAULT_BACKEND_URL;
|
||||||
const force = Boolean(options.force);
|
const force = Boolean(options.force);
|
||||||
|
const backendMismatch = hasSessionBackendMismatch(backendUrl);
|
||||||
|
if (backendMismatch) {
|
||||||
|
persistSession(null);
|
||||||
|
}
|
||||||
if (appState.session && !force) {
|
if (appState.session && !force) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1689,10 +1704,11 @@ async function loadPlatformAccount(platform, accountId, requestToken = 0) {
|
|||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
renderAll();
|
renderAll();
|
||||||
if (!appState.session) {
|
const backendMismatch = hasSessionBackendMismatch();
|
||||||
setBusy(true, "正在自动连接后端...");
|
if (!appState.session || backendMismatch) {
|
||||||
|
setBusy(true, backendMismatch ? "正在切换到当前工作区后端..." : "正在自动连接后端...");
|
||||||
try {
|
try {
|
||||||
await ensureAutoSession();
|
await ensureAutoSession({ force: backendMismatch });
|
||||||
} finally {
|
} finally {
|
||||||
setBusy(false, "");
|
setBusy(false, "");
|
||||||
}
|
}
|
||||||
@@ -8279,7 +8295,8 @@ document.addEventListener("submit", async (event) => {
|
|||||||
openOneLinerPanel();
|
openOneLinerPanel();
|
||||||
renderAll();
|
renderAll();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert("OneLiner 调度失败: " + error.message);
|
presentActionFailure(error, "OneLiner 调度失败");
|
||||||
|
openOneLinerPanel();
|
||||||
} finally {
|
} finally {
|
||||||
setBusy(false, "");
|
setBusy(false, "");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,3 +75,21 @@ test("ensureAutoSession re-renders immediately when auto-connect starts", () =>
|
|||||||
assert.match(source, /appState\.autoConnectAttempted = true;/);
|
assert.match(source, /appState\.autoConnectAttempted = true;/);
|
||||||
assert.match(source, /renderAll\(\);/);
|
assert.match(source, /renderAll\(\);/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("bootstrap does not trust a stored session from a different backend", () => {
|
||||||
|
const helpers = extractBetween(APP, "function loadStoredSession()", "function compareDateDesc(");
|
||||||
|
const ensure = extractBetween(APP, "async function ensureAutoSession(options = {})", "async function refreshFromAuthModal()");
|
||||||
|
const bootstrap = extractBetween(APP, "async function bootstrap()", "async function markTrackingDigestRead()");
|
||||||
|
|
||||||
|
assert.match(helpers, /function normalizeBackendUrlValue\(/);
|
||||||
|
assert.match(helpers, /function hasSessionBackendMismatch\(/);
|
||||||
|
assert.match(ensure, /const backendMismatch = hasSessionBackendMismatch\(backendUrl\);/);
|
||||||
|
assert.match(ensure, /persistSession\(null\);/);
|
||||||
|
assert.match(bootstrap, /const backendMismatch = hasSessionBackendMismatch\(\);/);
|
||||||
|
assert.match(bootstrap, /await ensureAutoSession\(\{ force: backendMismatch \}\);/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("oneliner submit failures stay inside the app instead of using a browser alert", () => {
|
||||||
|
assert.doesNotMatch(APP, /alert\("OneLiner 调度失败:/);
|
||||||
|
assert.match(APP, /presentActionFailure\(error,\s*"OneLiner 调度失败"\)/);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user