mirror of https://github.com/openclaw/openclaw.git
fix(android): restore setup-code operator bootstrap connect
This commit is contained in:
parent
2dced6b4a0
commit
deead11dcd
|
|
@ -204,10 +204,6 @@ class MainViewModel(app: Application) : AndroidViewModel(app) {
|
|||
prefs.setOnboardingCompleted(value)
|
||||
}
|
||||
|
||||
fun hasStoredNodeDeviceToken(): Boolean {
|
||||
return ensureRuntime().hasStoredNodeDeviceToken()
|
||||
}
|
||||
|
||||
fun setCanvasDebugStatusEnabled(value: Boolean) {
|
||||
prefs.setCanvasDebugStatusEnabled(value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -535,10 +535,6 @@ class NodeRuntime(
|
|||
fun setGatewayBootstrapToken(value: String) = prefs.setGatewayBootstrapToken(value)
|
||||
fun setGatewayPassword(value: String) = prefs.setGatewayPassword(value)
|
||||
fun setOnboardingCompleted(value: Boolean) = prefs.setOnboardingCompleted(value)
|
||||
fun hasStoredNodeDeviceToken(): Boolean {
|
||||
val deviceId = identityStore.loadOrCreate().deviceId
|
||||
return !deviceAuthStore.loadToken(deviceId, "node").isNullOrBlank()
|
||||
}
|
||||
val lastDiscoveredStableId: StateFlow<String> = prefs.lastDiscoveredStableId
|
||||
val canvasDebugStatusEnabled: StateFlow<Boolean> = prefs.canvasDebugStatusEnabled
|
||||
val notificationForwardingEnabled: StateFlow<Boolean> = prefs.notificationForwardingEnabled
|
||||
|
|
@ -783,8 +779,9 @@ class NodeRuntime(
|
|||
val bootstrapToken = prefs.loadGatewayBootstrapToken()
|
||||
val password = prefs.loadGatewayPassword()
|
||||
val tls = connectionManager.resolveTlsParams(endpoint)
|
||||
val bootstrapOnly = isBootstrapOnlyGatewayAuth(token, bootstrapToken, password)
|
||||
if (bootstrapOnly) {
|
||||
val connectOperator =
|
||||
shouldConnectOperatorSession(token, bootstrapToken, password, loadStoredRoleDeviceToken("operator"))
|
||||
if (!connectOperator) {
|
||||
operatorConnected = false
|
||||
operatorStatusText = "Offline"
|
||||
operatorSession.disconnect()
|
||||
|
|
@ -807,7 +804,7 @@ class NodeRuntime(
|
|||
connectionManager.buildNodeConnectOptions(),
|
||||
tls,
|
||||
)
|
||||
if (!bootstrapOnly) {
|
||||
if (connectOperator) {
|
||||
operatorSession.reconnect()
|
||||
}
|
||||
nodeSession.reconnect()
|
||||
|
|
@ -835,8 +832,9 @@ class NodeRuntime(
|
|||
val token = prefs.loadGatewayToken()
|
||||
val bootstrapToken = prefs.loadGatewayBootstrapToken()
|
||||
val password = prefs.loadGatewayPassword()
|
||||
val bootstrapOnly = isBootstrapOnlyGatewayAuth(token, bootstrapToken, password)
|
||||
if (bootstrapOnly) {
|
||||
val connectOperator =
|
||||
shouldConnectOperatorSession(token, bootstrapToken, password, loadStoredRoleDeviceToken("operator"))
|
||||
if (!connectOperator) {
|
||||
operatorConnected = false
|
||||
operatorStatusText = "Offline"
|
||||
operatorSession.disconnect()
|
||||
|
|
@ -890,6 +888,11 @@ class NodeRuntime(
|
|||
connect(GatewayEndpoint.manual(host = host, port = port))
|
||||
}
|
||||
|
||||
private fun loadStoredRoleDeviceToken(role: String): String? {
|
||||
val deviceId = identityStore.loadOrCreate().deviceId
|
||||
return deviceAuthStore.loadToken(deviceId, role)
|
||||
}
|
||||
|
||||
fun disconnect() {
|
||||
connectedEndpoint = null
|
||||
_pendingGatewayTrust.value = null
|
||||
|
|
@ -1219,12 +1222,18 @@ class NodeRuntime(
|
|||
|
||||
}
|
||||
|
||||
internal fun isBootstrapOnlyGatewayAuth(
|
||||
internal fun shouldConnectOperatorSession(
|
||||
token: String?,
|
||||
bootstrapToken: String?,
|
||||
password: String?,
|
||||
storedOperatorToken: String?,
|
||||
): Boolean {
|
||||
return !bootstrapToken.isNullOrBlank() && token.isNullOrBlank() && password.isNullOrBlank()
|
||||
return (
|
||||
!token.isNullOrBlank() ||
|
||||
!bootstrapToken.isNullOrBlank() ||
|
||||
!password.isNullOrBlank() ||
|
||||
!storedOperatorToken.isNullOrBlank()
|
||||
)
|
||||
}
|
||||
|
||||
private enum class HomeCanvasGatewayState {
|
||||
|
|
|
|||
|
|
@ -228,13 +228,8 @@ fun OnboardingFlow(viewModel: MainViewModel, modifier: Modifier = Modifier) {
|
|||
var manualTls by rememberSaveable { mutableStateOf(false) }
|
||||
var gatewayError by rememberSaveable { mutableStateOf<String?>(null) }
|
||||
var attemptedConnect by rememberSaveable { mutableStateOf(false) }
|
||||
val canRecoverBootstrapRetry =
|
||||
gatewayInputMode == GatewayInputMode.SetupCode &&
|
||||
attemptedConnect &&
|
||||
statusText.contains("bootstrap token invalid or expired", ignoreCase = true) &&
|
||||
viewModel.hasStoredNodeDeviceToken()
|
||||
val canFinishOnboarding =
|
||||
isConnected || (gatewayInputMode == GatewayInputMode.SetupCode && (isNodeConnected || canRecoverBootstrapRetry))
|
||||
isConnected || (gatewayInputMode == GatewayInputMode.SetupCode && isNodeConnected)
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
val qrScannerOptions =
|
||||
|
|
|
|||
|
|
@ -6,15 +6,16 @@ import org.junit.Test
|
|||
|
||||
class GatewayBootstrapAuthTest {
|
||||
@Test
|
||||
fun detectsBootstrapOnlyGatewayAuth() {
|
||||
assertTrue(isBootstrapOnlyGatewayAuth(token = "", bootstrapToken = "bootstrap-1", password = ""))
|
||||
assertTrue(isBootstrapOnlyGatewayAuth(token = null, bootstrapToken = "bootstrap-1", password = null))
|
||||
fun connectsOperatorSessionWhenBootstrapAuthExists() {
|
||||
assertTrue(shouldConnectOperatorSession(token = "", bootstrapToken = "bootstrap-1", password = "", storedOperatorToken = ""))
|
||||
assertTrue(shouldConnectOperatorSession(token = null, bootstrapToken = "bootstrap-1", password = null, storedOperatorToken = null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rejectsBootstrapOnlyGatewayAuthWhenSharedCredentialsExist() {
|
||||
assertFalse(isBootstrapOnlyGatewayAuth(token = "shared-token", bootstrapToken = "bootstrap-1", password = null))
|
||||
assertFalse(isBootstrapOnlyGatewayAuth(token = null, bootstrapToken = "bootstrap-1", password = "shared-password"))
|
||||
assertFalse(isBootstrapOnlyGatewayAuth(token = null, bootstrapToken = "", password = null))
|
||||
fun skipsOperatorSessionOnlyWhenNoSharedBootstrapOrStoredAuthExists() {
|
||||
assertTrue(shouldConnectOperatorSession(token = "shared-token", bootstrapToken = "bootstrap-1", password = null, storedOperatorToken = null))
|
||||
assertTrue(shouldConnectOperatorSession(token = null, bootstrapToken = "bootstrap-1", password = "shared-password", storedOperatorToken = null))
|
||||
assertTrue(shouldConnectOperatorSession(token = null, bootstrapToken = null, password = null, storedOperatorToken = "stored-token"))
|
||||
assertFalse(shouldConnectOperatorSession(token = null, bootstrapToken = "", password = null, storedOperatorToken = null))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue