mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 14:18:37 +00:00
macos: add mode-toggle remote token sync coverage
This commit is contained in:
committed by
Nimrod Gutman
parent
bd0e6a6efd
commit
37e0b01684
@@ -508,15 +508,19 @@ final class AppState {
|
||||
}
|
||||
}
|
||||
|
||||
private func syncGatewayConfigIfNeeded() {
|
||||
guard !self.isPreview, !self.isInitializing else { return }
|
||||
private static func syncedGatewayRoot(
|
||||
currentRoot: [String: Any],
|
||||
connectionMode: ConnectionMode,
|
||||
remoteTransport: RemoteTransport,
|
||||
remoteTarget: String,
|
||||
remoteIdentity: String,
|
||||
remoteUrl: String,
|
||||
remoteToken: String) -> (root: [String: Any], changed: Bool)
|
||||
{
|
||||
var root = currentRoot
|
||||
var gateway = root["gateway"] as? [String: Any] ?? [:]
|
||||
var changed = false
|
||||
|
||||
let connectionMode = self.connectionMode
|
||||
let remoteTarget = self.remoteTarget
|
||||
let remoteIdentity = self.remoteIdentity
|
||||
let remoteTransport = self.remoteTransport
|
||||
let remoteUrl = self.remoteUrl
|
||||
let remoteToken = self.remoteToken
|
||||
let desiredMode: String? = switch connectionMode {
|
||||
case .local:
|
||||
"local"
|
||||
@@ -525,15 +529,6 @@ final class AppState {
|
||||
case .unconfigured:
|
||||
nil
|
||||
}
|
||||
let remoteHost = connectionMode == .remote
|
||||
? CommandResolver.parseSSHTarget(remoteTarget)?.host
|
||||
: nil
|
||||
|
||||
Task { @MainActor in
|
||||
// Keep app-only connection settings local to avoid overwriting remote gateway config.
|
||||
var root = OpenClawConfigFile.loadDict()
|
||||
var gateway = root["gateway"] as? [String: Any] ?? [:]
|
||||
var changed = false
|
||||
|
||||
let currentMode = (gateway["mode"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if let desiredMode {
|
||||
@@ -547,6 +542,7 @@ final class AppState {
|
||||
}
|
||||
|
||||
if connectionMode == .remote {
|
||||
let remoteHost = CommandResolver.parseSSHTarget(remoteTarget)?.host
|
||||
let currentRemote = gateway["remote"] as? [String: Any] ?? [:]
|
||||
let updated = Self.updatedRemoteGatewayConfig(
|
||||
current: currentRemote,
|
||||
@@ -562,13 +558,38 @@ final class AppState {
|
||||
}
|
||||
}
|
||||
|
||||
guard changed else { return }
|
||||
guard changed else { return (currentRoot, false) }
|
||||
|
||||
if gateway.isEmpty {
|
||||
root.removeValue(forKey: "gateway")
|
||||
} else {
|
||||
root["gateway"] = gateway
|
||||
}
|
||||
OpenClawConfigFile.saveDict(root)
|
||||
return (root, true)
|
||||
}
|
||||
|
||||
private func syncGatewayConfigIfNeeded() {
|
||||
guard !self.isPreview, !self.isInitializing else { return }
|
||||
|
||||
let connectionMode = self.connectionMode
|
||||
let remoteTarget = self.remoteTarget
|
||||
let remoteIdentity = self.remoteIdentity
|
||||
let remoteTransport = self.remoteTransport
|
||||
let remoteUrl = self.remoteUrl
|
||||
let remoteToken = self.remoteToken
|
||||
|
||||
Task { @MainActor in
|
||||
// Keep app-only connection settings local to avoid overwriting remote gateway config.
|
||||
let synced = Self.syncedGatewayRoot(
|
||||
currentRoot: OpenClawConfigFile.loadDict(),
|
||||
connectionMode: connectionMode,
|
||||
remoteTransport: remoteTransport,
|
||||
remoteTarget: remoteTarget,
|
||||
remoteIdentity: remoteIdentity,
|
||||
remoteUrl: remoteUrl,
|
||||
remoteToken: remoteToken)
|
||||
guard synced.changed else { return }
|
||||
OpenClawConfigFile.saveDict(synced.root)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,6 +761,25 @@ extension AppState {
|
||||
remoteIdentity: remoteIdentity,
|
||||
remoteToken: remoteToken).remote
|
||||
}
|
||||
|
||||
static func _testSyncedGatewayRoot(
|
||||
currentRoot: [String: Any],
|
||||
connectionMode: ConnectionMode,
|
||||
remoteTransport: RemoteTransport,
|
||||
remoteTarget: String,
|
||||
remoteIdentity: String,
|
||||
remoteUrl: String,
|
||||
remoteToken: String) -> [String: Any]
|
||||
{
|
||||
Self.syncedGatewayRoot(
|
||||
currentRoot: currentRoot,
|
||||
connectionMode: connectionMode,
|
||||
remoteTransport: remoteTransport,
|
||||
remoteTarget: remoteTarget,
|
||||
remoteIdentity: remoteIdentity,
|
||||
remoteUrl: remoteUrl,
|
||||
remoteToken: remoteToken).root
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -31,4 +31,44 @@ struct AppStateRemoteConfigTests {
|
||||
|
||||
#expect((remote["token"] as? String) == nil)
|
||||
}
|
||||
|
||||
@Test
|
||||
func syncedGatewayRootPreservesTokenAcrossModeToggleAndClearsOnBlankRemoteToken() {
|
||||
let remoteRoot = AppState._testSyncedGatewayRoot(
|
||||
currentRoot: [:],
|
||||
connectionMode: .remote,
|
||||
remoteTransport: .direct,
|
||||
remoteTarget: "",
|
||||
remoteIdentity: "",
|
||||
remoteUrl: "wss://gateway.example",
|
||||
remoteToken: " persisted-token ")
|
||||
let remoteGateway = remoteRoot["gateway"] as? [String: Any]
|
||||
let remoteConfig = remoteGateway?["remote"] as? [String: Any]
|
||||
#expect(remoteGateway?["mode"] as? String == "remote")
|
||||
#expect(remoteConfig?["token"] as? String == "persisted-token")
|
||||
|
||||
let localRoot = AppState._testSyncedGatewayRoot(
|
||||
currentRoot: remoteRoot,
|
||||
connectionMode: .local,
|
||||
remoteTransport: .direct,
|
||||
remoteTarget: "",
|
||||
remoteIdentity: "",
|
||||
remoteUrl: "",
|
||||
remoteToken: "")
|
||||
let localGateway = localRoot["gateway"] as? [String: Any]
|
||||
let localRemoteConfig = localGateway?["remote"] as? [String: Any]
|
||||
#expect(localGateway?["mode"] as? String == "local")
|
||||
#expect(localRemoteConfig?["token"] as? String == "persisted-token")
|
||||
|
||||
let clearedRoot = AppState._testSyncedGatewayRoot(
|
||||
currentRoot: localRoot,
|
||||
connectionMode: .remote,
|
||||
remoteTransport: .direct,
|
||||
remoteTarget: "",
|
||||
remoteIdentity: "",
|
||||
remoteUrl: "wss://gateway.example",
|
||||
remoteToken: " ")
|
||||
let clearedRemote = (clearedRoot["gateway"] as? [String: Any])?["remote"] as? [String: Any]
|
||||
#expect((clearedRemote?["token"] as? String) == nil)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user