fix: scope localStorage settings key by basePath to prevent cross-deployment conflicts
- Add settingsKeyForGateway() function similar to tokenSessionKeyForGateway() - Use scoped key format: openclaw.control.settings.v1:https://example.com/gateway-a - Add migration from legacy static key on load - Fixes #47481
This commit is contained in:
parent
7cdd8a84a6
commit
5ece9afa8b
@ -1,8 +1,12 @@
|
|||||||
const KEY = "openclaw.control.settings.v1";
|
const SETTINGS_KEY_PREFIX = "openclaw.control.settings.v1:";
|
||||||
const LEGACY_TOKEN_SESSION_KEY = "openclaw.control.token.v1";
|
const LEGACY_TOKEN_SESSION_KEY = "openclaw.control.token.v1";
|
||||||
const TOKEN_SESSION_KEY_PREFIX = "openclaw.control.token.v1:";
|
const TOKEN_SESSION_KEY_PREFIX = "openclaw.control.token.v1:";
|
||||||
const MAX_SCOPED_SESSION_ENTRIES = 10;
|
const MAX_SCOPED_SESSION_ENTRIES = 10;
|
||||||
|
|
||||||
|
function settingsKeyForGateway(gatewayUrl: string): string {
|
||||||
|
return `${SETTINGS_KEY_PREFIX}${normalizeGatewayTokenScope(gatewayUrl)}`;
|
||||||
|
}
|
||||||
|
|
||||||
type ScopedSessionSelection = {
|
type ScopedSessionSelection = {
|
||||||
sessionKey: string;
|
sessionKey: string;
|
||||||
lastActiveSessionKey: string;
|
lastActiveSessionKey: string;
|
||||||
@ -188,7 +192,9 @@ export function loadSettings(): UiSettings {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const raw = storage?.getItem(KEY);
|
// First check for legacy key (no scope), then check for scoped key
|
||||||
|
const scopedKey = settingsKeyForGateway(defaults.gatewayUrl);
|
||||||
|
const raw = storage?.getItem(scopedKey) ?? storage?.getItem(SETTINGS_KEY_PREFIX + "default") ?? storage?.getItem("openclaw.control.settings.v1");
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
return defaults;
|
return defaults;
|
||||||
}
|
}
|
||||||
@ -256,9 +262,11 @@ function persistSettings(next: UiSettings) {
|
|||||||
persistSessionToken(next.gatewayUrl, next.token);
|
persistSessionToken(next.gatewayUrl, next.token);
|
||||||
const storage = getSafeLocalStorage();
|
const storage = getSafeLocalStorage();
|
||||||
const scope = normalizeGatewayTokenScope(next.gatewayUrl);
|
const scope = normalizeGatewayTokenScope(next.gatewayUrl);
|
||||||
|
const scopedKey = settingsKeyForGateway(next.gatewayUrl);
|
||||||
let existingSessionsByGateway: Record<string, ScopedSessionSelection> = {};
|
let existingSessionsByGateway: Record<string, ScopedSessionSelection> = {};
|
||||||
try {
|
try {
|
||||||
const raw = storage?.getItem(KEY);
|
// Try to migrate from legacy key or other scopes
|
||||||
|
const raw = storage?.getItem(scopedKey) ?? storage?.getItem(SETTINGS_KEY_PREFIX + "default") ?? storage?.getItem("openclaw.control.settings.v1");
|
||||||
if (raw) {
|
if (raw) {
|
||||||
const parsed = JSON.parse(raw) as PersistedUiSettings;
|
const parsed = JSON.parse(raw) as PersistedUiSettings;
|
||||||
if (parsed.sessionsByGateway && typeof parsed.sessionsByGateway === "object") {
|
if (parsed.sessionsByGateway && typeof parsed.sessionsByGateway === "object") {
|
||||||
@ -294,5 +302,5 @@ function persistSettings(next: UiSettings) {
|
|||||||
sessionsByGateway,
|
sessionsByGateway,
|
||||||
...(next.locale ? { locale: next.locale } : {}),
|
...(next.locale ? { locale: next.locale } : {}),
|
||||||
};
|
};
|
||||||
storage?.setItem(KEY, JSON.stringify(persisted));
|
storage?.setItem(scopedKey, JSON.stringify(persisted));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user