Gateway: fix node invoke receive loop

This commit is contained in:
Mariano Belinky
2026-01-31 17:46:57 +01:00
committed by Mariano Belinky
parent 78f7e5147b
commit 84e115834f
6 changed files with 440 additions and 12 deletions

View File

@@ -284,6 +284,9 @@ final class GatewayConnectionController {
private func makeConnectOptions() -> GatewayConnectOptions {
let defaults = UserDefaults.standard
let displayName = self.resolvedDisplayName(defaults: defaults)
let manualClientId = defaults.string(forKey: "gateway.manual.clientId")?
.trimmingCharacters(in: .whitespacesAndNewlines)
let resolvedClientId = manualClientId?.isEmpty == false ? manualClientId! : "openclaw-ios"
return GatewayConnectOptions(
role: "node",
@@ -291,7 +294,7 @@ final class GatewayConnectionController {
caps: self.currentCaps(),
commands: self.currentCommands(),
permissions: self.currentPermissions(),
clientId: "openclaw-ios",
clientId: resolvedClientId,
clientMode: "node",
clientDisplayName: displayName)
}

View File

@@ -11,6 +11,7 @@ enum GatewaySettingsStore {
private static let manualHostDefaultsKey = "gateway.manual.host"
private static let manualPortDefaultsKey = "gateway.manual.port"
private static let manualTlsDefaultsKey = "gateway.manual.tls"
private static let manualPasswordDefaultsKey = "gateway.manual.password"
private static let discoveryDebugLogsDefaultsKey = "gateway.discovery.debugLogs"
private static let instanceIdAccount = "instanceId"
@@ -21,6 +22,7 @@ enum GatewaySettingsStore {
self.ensureStableInstanceID()
self.ensurePreferredGatewayStableID()
self.ensureLastDiscoveredGatewayStableID()
self.ensureManualGatewayPassword()
}
static func loadStableInstanceID() -> String? {
@@ -174,4 +176,23 @@ enum GatewaySettingsStore {
}
}
private static func ensureManualGatewayPassword() {
let defaults = UserDefaults.standard
let instanceId = defaults.string(forKey: self.instanceIdDefaultsKey)?
.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
guard !instanceId.isEmpty else { return }
let manualPassword = defaults.string(forKey: self.manualPasswordDefaultsKey)?
.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
guard !manualPassword.isEmpty else { return }
if self.loadGatewayPassword(instanceId: instanceId) == nil {
self.saveGatewayPassword(manualPassword, instanceId: instanceId)
}
if self.loadGatewayPassword(instanceId: instanceId) == manualPassword {
defaults.removeObject(forKey: self.manualPasswordDefaultsKey)
}
}
}

View File

@@ -12,6 +12,9 @@ private let nodeService = "ai.openclaw.node"
private let instanceIdEntry = KeychainEntry(service: nodeService, account: "instanceId")
private let preferredGatewayEntry = KeychainEntry(service: gatewayService, account: "preferredStableID")
private let lastGatewayEntry = KeychainEntry(service: gatewayService, account: "lastDiscoveredStableID")
private func gatewayPasswordEntry(instanceId: String) -> KeychainEntry {
KeychainEntry(service: gatewayService, account: "gateway-password.\(instanceId)")
}
private func snapshotDefaults(_ keys: [String]) -> [String: Any?] {
let defaults = UserDefaults.standard
@@ -124,4 +127,33 @@ private func restoreKeychain(_ snapshot: [KeychainEntry: String?]) {
#expect(defaults.string(forKey: "gateway.preferredStableID") == "preferred-from-keychain")
#expect(defaults.string(forKey: "gateway.lastDiscoveredStableID") == "last-from-keychain")
}
@Test func bootstrapCopiesManualPasswordToKeychainWhenMissing() {
let instanceId = "node-test"
let defaultsKeys = [
"node.instanceId",
"gateway.manual.password",
]
let passwordEntry = gatewayPasswordEntry(instanceId: instanceId)
let defaultsSnapshot = snapshotDefaults(defaultsKeys)
let keychainSnapshot = snapshotKeychain([passwordEntry, instanceIdEntry])
defer {
restoreDefaults(defaultsSnapshot)
restoreKeychain(keychainSnapshot)
}
applyDefaults([
"node.instanceId": instanceId,
"gateway.manual.password": "manual-secret",
])
applyKeychain([
passwordEntry: nil,
instanceIdEntry: nil,
])
GatewaySettingsStore.bootstrapPersistence()
#expect(KeychainStore.loadString(service: gatewayService, account: passwordEntry.account) == "manual-secret")
#expect(UserDefaults.standard.string(forKey: "gateway.manual.password") == nil)
}
}