mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 09:14:33 +00:00
Merge pull request #552 from CyberMind-FR/feature/551-android-apk-zero-tap-auto-run-silent-onb
Some checks are pending
License Headers / check (push) Waiting to run
Some checks are pending
License Headers / check (push) Waiting to run
Android: zero-tap auto-run silent onboarding on root (#551)
This commit is contained in:
commit
dc6505a2f2
|
|
@ -12,10 +12,13 @@ import the WireGuard profile, verify the tunnel, then open the live
|
|||
4. **Verify** — polls `/wg/r3-check` → "Tunnel R3 actif ✓".
|
||||
5. **Live metrics** — opens `/social/me` (cartographie sociale).
|
||||
|
||||
## Root path — fully-automated silent onboarding (#538)
|
||||
When the device is **rooted**, the Discover step shows an extra
|
||||
**⚡ Installation automatique (root)** button. Tapping it runs the whole
|
||||
onboarding with zero further interaction (`RootAuto` step, streaming log):
|
||||
## Root path — fully-automated silent onboarding (#538, #551)
|
||||
When the device is **rooted**, the app runs the whole onboarding with **zero
|
||||
taps**: on launch it auto-detects root and, if this cabine host hasn't been
|
||||
onboarded yet, starts the silent sequence automatically (`RootAuto` step,
|
||||
streaming log). The **⚡ Installation automatique (root)** button stays for
|
||||
re-runs. The "already onboarded" flag is persisted per host (SharedPreferences)
|
||||
so reopening the app doesn't redo it. Steps:
|
||||
|
||||
1. **System CA install** — downloads `/wg/ca.pem`, computes the OpenSSL
|
||||
`subject_hash_old` in pure Kotlin, and bind-mounts a populated copy of
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ android {
|
|||
applicationId = "in.secubox.toolbox"
|
||||
minSdk = 26
|
||||
targetSdk = 34
|
||||
versionCode = 1
|
||||
versionName = "0.1.0"
|
||||
versionCode = 2
|
||||
versionName = "0.2.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
|
|
|||
|
|
@ -64,8 +64,50 @@ fun OnboardApp() {
|
|||
val api = remember(host) { ToolboxApi(host) }
|
||||
var rootAvail by remember { mutableStateOf(false) }
|
||||
val rootLog = remember { mutableStateListOf<String>() }
|
||||
val prefs = remember {
|
||||
ctx.getSharedPreferences("secubox-toolbox", android.content.Context.MODE_PRIVATE)
|
||||
}
|
||||
var autoTried by remember { mutableStateOf(false) }
|
||||
|
||||
// The whole root-mode silent run, reused by the ⚡ button AND the
|
||||
// zero-tap auto-launch (#551). Persists an onboarded flag per host on
|
||||
// success so reopening the app doesn't redo it.
|
||||
val runRootAuto: () -> Unit = {
|
||||
busy = true; status = ""; rootLog.clear()
|
||||
scope.launch {
|
||||
val ok = withContext(Dispatchers.IO) { api.reachable() }
|
||||
if (!ok) {
|
||||
busy = false; status = "Borne injoignable — vérifie le réseau."
|
||||
} else {
|
||||
step = Step.RootAuto
|
||||
val onb = RootOnboard(api, ctx.cacheDir)
|
||||
val out = withContext(Dispatchers.IO) {
|
||||
onb.runSilent { line -> scope.launch(Dispatchers.Main) { rootLog.add(line) } }
|
||||
}
|
||||
busy = false
|
||||
onTunnel = out.verified
|
||||
if (out.verified) prefs.edit().putBoolean("onboarded:$host", true).apply()
|
||||
when {
|
||||
out.verified -> step = Step.Done
|
||||
out.wgViaApp -> { step = Step.ImportProfile
|
||||
status = "CA installé en root ✓ — termine le tunnel via l'app WireGuard." }
|
||||
else -> { step = Step.Verify
|
||||
status = "Active le tunnel puis vérifie." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detect root once, off the main thread.
|
||||
LaunchedEffect(Unit) { rootAvail = withContext(Dispatchers.IO) { RootShell.available() } }
|
||||
// Zero-tap (#551): on a rooted device, auto-run the silent onboarding
|
||||
// once on launch — unless this host was already onboarded.
|
||||
LaunchedEffect(rootAvail) {
|
||||
if (rootAvail && !autoTried && step == Step.Discover) {
|
||||
autoTried = true
|
||||
if (!prefs.getBoolean("onboarded:$host", false)) runRootAuto()
|
||||
}
|
||||
}
|
||||
|
||||
MaterialTheme(colorScheme = darkColorScheme(
|
||||
primary = Gold, secondary = Cyan, background = Cosmos, surface = Cosmos,
|
||||
|
|
@ -105,32 +147,11 @@ fun OnboardApp() {
|
|||
}
|
||||
if (rootAvail) {
|
||||
Spacer(Modifier.height(10.dp))
|
||||
Text("🔓 Root détecté — installation 100% automatique possible.",
|
||||
Text("🔓 Root détecté — l'installation se lance automatiquement. " +
|
||||
"Tu peux aussi la relancer ici.",
|
||||
color = Matrix, fontSize = 12.sp)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
OutlinedButton(onClick = {
|
||||
busy = true; status = ""; rootLog.clear()
|
||||
scope.launch {
|
||||
val ok = withContext(Dispatchers.IO) { api.reachable() }
|
||||
if (!ok) { busy = false; status = "Borne injoignable."; return@launch }
|
||||
step = Step.RootAuto
|
||||
val onb = RootOnboard(api, ctx.cacheDir)
|
||||
val out = withContext(Dispatchers.IO) {
|
||||
onb.runSilent { line ->
|
||||
scope.launch(Dispatchers.Main) { rootLog.add(line) }
|
||||
}
|
||||
}
|
||||
busy = false
|
||||
onTunnel = out.verified
|
||||
when {
|
||||
out.verified -> step = Step.Done
|
||||
out.wgViaApp -> { step = Step.ImportProfile
|
||||
status = "CA installé en root ✓ — termine le tunnel via l'app WireGuard." }
|
||||
else -> { step = Step.Verify
|
||||
status = "Active le tunnel puis vérifie." }
|
||||
}
|
||||
}
|
||||
}, modifier = Modifier.fillMaxWidth(),
|
||||
OutlinedButton(onClick = runRootAuto, modifier = Modifier.fillMaxWidth(),
|
||||
border = BorderStroke(1.dp, Matrix),
|
||||
colors = ButtonDefaults.outlinedButtonColors(contentColor = Matrix)) {
|
||||
Text("⚡ Installation automatique (root)", fontWeight = FontWeight.Bold)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user