fix(android): reset auth on new setup codes

This commit is contained in:
Ayaan Zaidi
2026-04-08 21:08:48 +05:30
parent 11bd40fe8a
commit 6090afa0e5
7 changed files with 106 additions and 6 deletions

View File

@@ -204,6 +204,10 @@ class MainViewModel(app: Application) : AndroidViewModel(app) {
prefs.setGatewayPassword(value)
}
fun resetGatewaySetupAuth() {
ensureRuntime().resetGatewaySetupAuth()
}
fun setOnboardingCompleted(value: Boolean) {
if (value) {
ensureRuntime()

View File

@@ -556,6 +556,12 @@ class NodeRuntime(
fun setGatewayToken(value: String) = prefs.setGatewayToken(value)
fun setGatewayBootstrapToken(value: String) = prefs.setGatewayBootstrapToken(value)
fun setGatewayPassword(value: String) = prefs.setGatewayPassword(value)
fun resetGatewaySetupAuth() {
prefs.clearGatewaySetupAuth()
val deviceId = identityStore.loadOrCreate().deviceId
deviceAuthStore.clearToken(deviceId, "node")
deviceAuthStore.clearToken(deviceId, "operator")
}
fun setOnboardingCompleted(value: Boolean) = prefs.setOnboardingCompleted(value)
val lastDiscoveredStableId: StateFlow<String> = prefs.lastDiscoveredStableId
val canvasDebugStatusEnabled: StateFlow<Boolean> = prefs.canvasDebugStatusEnabled
@@ -1325,8 +1331,6 @@ internal fun resolveOperatorSessionConnectAuth(
val storedToken = storedOperatorToken?.trim()?.takeIf { it.isNotEmpty() }
if (storedToken != null) {
// Bootstrap can seed the operator token, but operator should reconnect
// through the stored device-token path rather than bootstrap auth itself.
return NodeRuntime.GatewayConnectAuth(
token = null,
bootstrapToken = null,
@@ -1334,6 +1338,15 @@ internal fun resolveOperatorSessionConnectAuth(
)
}
val explicitBootstrapToken = auth.bootstrapToken?.trim()?.takeIf { it.isNotEmpty() }
if (explicitBootstrapToken != null) {
return NodeRuntime.GatewayConnectAuth(
token = null,
bootstrapToken = explicitBootstrapToken,
password = null,
)
}
return null
}

View File

@@ -402,6 +402,18 @@ class SecurePrefs(
securePrefs.edit { putString(key, password.trim()) }
}
fun clearGatewaySetupAuth() {
val instanceId = _instanceId.value
securePrefs.edit {
remove("gateway.manual.token")
remove("gateway.token.$instanceId")
remove("gateway.bootstrapToken.$instanceId")
remove("gateway.password.$instanceId")
}
_gatewayToken.value = ""
_gatewayBootstrapToken.value = ""
}
fun loadGatewayTlsFingerprint(stableId: String): String? {
val key = "gateway.tls.$stableId"
return plainPrefs.getString(key, null)?.trim()?.takeIf { it.isNotEmpty() }

View File

@@ -293,6 +293,9 @@ fun ConnectTabScreen(viewModel: MainViewModel) {
}
validationText = null
if (inputMode == ConnectInputMode.SetupCode) {
viewModel.resetGatewaySetupAuth()
}
viewModel.setManualEnabled(true)
viewModel.setManualHost(config.host)
viewModel.setManualPort(config.port)

View File

@@ -580,6 +580,7 @@ fun OnboardingFlow(viewModel: MainViewModel, modifier: Modifier = Modifier) {
return@addOnSuccessListener
}
setupCode = scannedSetupCode.setupCode
viewModel.resetGatewaySetupAuth()
gatewayInputMode = GatewayInputMode.SetupCode
gatewayError = null
attemptedConnect = false
@@ -817,6 +818,7 @@ fun OnboardingFlow(viewModel: MainViewModel, modifier: Modifier = Modifier) {
)
return@Button
}
viewModel.resetGatewaySetupAuth()
gatewayUrl = parsedSetup.url
viewModel.setGatewayBootstrapToken(parsedSetup.bootstrapToken.orEmpty())
val sharedToken = parsedSetup.token.orEmpty().trim()
@@ -899,6 +901,8 @@ fun OnboardingFlow(viewModel: MainViewModel, modifier: Modifier = Modifier) {
viewModel.setManualTls(parsed.config.tls)
if (gatewayInputMode == GatewayInputMode.Manual) {
viewModel.setGatewayBootstrapToken("")
} else {
viewModel.resetGatewaySetupAuth()
}
if (token.isNotEmpty()) {
viewModel.setGatewayToken(token)