mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(macos): explain pairing approval in onboarding
This commit is contained in:
@@ -510,6 +510,8 @@ extension OnboardingView {
|
|||||||
return ("wrench.and.screwdriver.fill", .orange)
|
return ("wrench.and.screwdriver.fill", .orange)
|
||||||
case .passwordRequired:
|
case .passwordRequired:
|
||||||
return ("lock.slash.fill", .orange)
|
return ("lock.slash.fill", .orange)
|
||||||
|
case .pairingRequired:
|
||||||
|
return ("link.badge.plus", .orange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
case tokenMismatch
|
case tokenMismatch
|
||||||
case gatewayTokenNotConfigured
|
case gatewayTokenNotConfigured
|
||||||
case passwordRequired
|
case passwordRequired
|
||||||
|
case pairingRequired
|
||||||
|
|
||||||
init?(error: Error) {
|
init?(error: Error) {
|
||||||
guard let authError = error as? GatewayConnectAuthError else {
|
guard let authError = error as? GatewayConnectAuthError else {
|
||||||
@@ -21,6 +22,8 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
self = .gatewayTokenNotConfigured
|
self = .gatewayTokenNotConfigured
|
||||||
case .authPasswordMissing, .authPasswordMismatch, .authPasswordNotConfigured:
|
case .authPasswordMissing, .authPasswordMismatch, .authPasswordNotConfigured:
|
||||||
self = .passwordRequired
|
self = .passwordRequired
|
||||||
|
case .pairingRequired:
|
||||||
|
self = .pairingRequired
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -30,7 +33,7 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
switch self {
|
switch self {
|
||||||
case .tokenRequired, .tokenMismatch:
|
case .tokenRequired, .tokenMismatch:
|
||||||
true
|
true
|
||||||
case .gatewayTokenNotConfigured, .passwordRequired:
|
case .gatewayTokenNotConfigured, .passwordRequired, .pairingRequired:
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,6 +48,8 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
"This gateway host needs token setup"
|
"This gateway host needs token setup"
|
||||||
case .passwordRequired:
|
case .passwordRequired:
|
||||||
"This gateway is using unsupported auth"
|
"This gateway is using unsupported auth"
|
||||||
|
case .pairingRequired:
|
||||||
|
"This device needs pairing approval"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +63,8 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
"This gateway is set to token auth, but no `gateway.auth.token` is configured on the gateway host. If the gateway uses an environment variable instead, set `OPENCLAW_GATEWAY_TOKEN` before starting the gateway."
|
"This gateway is set to token auth, but no `gateway.auth.token` is configured on the gateway host. If the gateway uses an environment variable instead, set `OPENCLAW_GATEWAY_TOKEN` before starting the gateway."
|
||||||
case .passwordRequired:
|
case .passwordRequired:
|
||||||
"This onboarding flow does not support password auth yet. Reconfigure the gateway to use token auth, then retry."
|
"This onboarding flow does not support password auth yet. Reconfigure the gateway to use token auth, then retry."
|
||||||
|
case .pairingRequired:
|
||||||
|
"Approve this device from an already-paired OpenClaw client. In your OpenClaw chat, run `/pair approve`, then click **Check connection** again."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +72,8 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
switch self {
|
switch self {
|
||||||
case .tokenRequired, .gatewayTokenNotConfigured:
|
case .tokenRequired, .gatewayTokenNotConfigured:
|
||||||
"No token yet? Generate one on the gateway host with `openclaw doctor --generate-gateway-token`, then set it as `gateway.auth.token`."
|
"No token yet? Generate one on the gateway host with `openclaw doctor --generate-gateway-token`, then set it as `gateway.auth.token`."
|
||||||
|
case .pairingRequired:
|
||||||
|
"If you do not have another paired OpenClaw client yet, approve the pending request on the gateway host with `openclaw devices approve`."
|
||||||
case .tokenMismatch, .passwordRequired:
|
case .tokenMismatch, .passwordRequired:
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
@@ -80,6 +89,8 @@ enum RemoteGatewayAuthIssue: Equatable {
|
|||||||
"This gateway has token auth enabled, but no gateway.auth.token is configured on the host."
|
"This gateway has token auth enabled, but no gateway.auth.token is configured on the host."
|
||||||
case .passwordRequired:
|
case .passwordRequired:
|
||||||
"This gateway uses password auth. Remote onboarding on macOS cannot collect gateway passwords yet."
|
"This gateway uses password auth. Remote onboarding on macOS cannot collect gateway passwords yet."
|
||||||
|
case .pairingRequired:
|
||||||
|
"Pairing required. In an already-paired OpenClaw client, run /pair approve, then check the connection again."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ struct OnboardingRemoteAuthPromptTests {
|
|||||||
message: "password missing",
|
message: "password missing",
|
||||||
detailCode: GatewayConnectAuthDetailCode.authPasswordMissing.rawValue,
|
detailCode: GatewayConnectAuthDetailCode.authPasswordMissing.rawValue,
|
||||||
canRetryWithDeviceToken: false)
|
canRetryWithDeviceToken: false)
|
||||||
|
let pairingRequired = GatewayConnectAuthError(
|
||||||
|
message: "pairing required",
|
||||||
|
detailCode: GatewayConnectAuthDetailCode.pairingRequired.rawValue,
|
||||||
|
canRetryWithDeviceToken: false)
|
||||||
let unknown = GatewayConnectAuthError(
|
let unknown = GatewayConnectAuthError(
|
||||||
message: "other",
|
message: "other",
|
||||||
detailCode: "SOMETHING_ELSE",
|
detailCode: "SOMETHING_ELSE",
|
||||||
@@ -30,6 +34,7 @@ struct OnboardingRemoteAuthPromptTests {
|
|||||||
#expect(RemoteGatewayAuthIssue(error: tokenMismatch) == .tokenMismatch)
|
#expect(RemoteGatewayAuthIssue(error: tokenMismatch) == .tokenMismatch)
|
||||||
#expect(RemoteGatewayAuthIssue(error: tokenNotConfigured) == .gatewayTokenNotConfigured)
|
#expect(RemoteGatewayAuthIssue(error: tokenNotConfigured) == .gatewayTokenNotConfigured)
|
||||||
#expect(RemoteGatewayAuthIssue(error: passwordMissing) == .passwordRequired)
|
#expect(RemoteGatewayAuthIssue(error: passwordMissing) == .passwordRequired)
|
||||||
|
#expect(RemoteGatewayAuthIssue(error: pairingRequired) == .pairingRequired)
|
||||||
#expect(RemoteGatewayAuthIssue(error: unknown) == nil)
|
#expect(RemoteGatewayAuthIssue(error: unknown) == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +88,20 @@ struct OnboardingRemoteAuthPromptTests {
|
|||||||
remoteToken: "",
|
remoteToken: "",
|
||||||
remoteTokenUnsupported: false,
|
remoteTokenUnsupported: false,
|
||||||
authIssue: .gatewayTokenNotConfigured) == false)
|
authIssue: .gatewayTokenNotConfigured) == false)
|
||||||
|
#expect(OnboardingView.shouldShowRemoteTokenField(
|
||||||
|
showAdvancedConnection: false,
|
||||||
|
remoteToken: "",
|
||||||
|
remoteTokenUnsupported: false,
|
||||||
|
authIssue: .pairingRequired) == false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func `pairing required copy points users to pair approve`() {
|
||||||
|
let issue = RemoteGatewayAuthIssue.pairingRequired
|
||||||
|
|
||||||
|
#expect(issue.title == "This device needs pairing approval")
|
||||||
|
#expect(issue.body.contains("`/pair approve`"))
|
||||||
|
#expect(issue.statusMessage.contains("/pair approve"))
|
||||||
|
#expect(issue.footnote?.contains("`openclaw devices approve`") == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func `paired device success copy explains auth source`() {
|
@Test func `paired device success copy explains auth source`() {
|
||||||
|
|||||||
Reference in New Issue
Block a user