feat(app): an authenticator's key copied, marked sensitive, and its code six digits
A phone without a camera whose authenticator doesn't open otpauth: had no way but typing the key. It is copied again, the key alone (ADR 0017 amended, the developer's decision of 3 Nov 2026): on Android through each app's SensitiveClipboard.kt, marked EXTRA_IS_SENSITIVE, so Gboard and the system show no preview and keep it out of their histories; elsewhere through Flutter's clipboard. Emptied 60 seconds later if the clipboard still holds it. The recovery phrase and codes stay never copied. The code's field counted "/7", taking an optional space for a seventh character: it now takes six digits alone, a pasted space dropped, and counts nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
55fc245859
commit
8c70ad98a1
2 changed files with 470 additions and 36 deletions
|
|
@ -20,6 +20,7 @@ class MainActivity : FlutterActivity() {
|
|||
val messenger = flutterEngine.dartExecutor.binaryMessenger
|
||||
PomodoroService.appBack()
|
||||
ScreenGuard.attach(this, messenger)
|
||||
SensitiveClipboard.attach(this, messenger)
|
||||
// A question searched with the device's own web search (its default
|
||||
// browser or search app answers ACTION_WEB_SEARCH); false where none does,
|
||||
// and the app opens a search engine's address instead.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
package app.halkyon.learn
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.PersistableBundle
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
/**
|
||||
* Copies an authenticator's key for halkyon_app's PlatformSecretClipboard,
|
||||
* marked sensitive (ClipDescription.EXTRA_IS_SENSITIVE, read by the system
|
||||
* from Android 13 on and by Gboard before it), so it shows no preview and
|
||||
* stays out of clipboard histories; and empties the clipboard again if it
|
||||
* still holds the key, which Android lets an app read only while in front.
|
||||
*/
|
||||
object SensitiveClipboard {
|
||||
private const val IS_SENSITIVE = "android.content.extra.IS_SENSITIVE"
|
||||
|
||||
fun attach(context: Context, messenger: BinaryMessenger) {
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
MethodChannel(messenger, "app.halkyon/clipboard").setMethodCallHandler { call, result ->
|
||||
when (call.method) {
|
||||
"copySensitive" -> {
|
||||
val clip = ClipData.newPlainText("", call.arguments as String)
|
||||
clip.description.extras = PersistableBundle().apply { putBoolean(IS_SENSITIVE, true) }
|
||||
clipboard.setPrimaryClip(clip)
|
||||
result.success(null)
|
||||
}
|
||||
"clearIf" -> {
|
||||
val held = clipboard.primaryClip?.takeIf { it.itemCount > 0 }?.getItemAt(0)?.text
|
||||
if (held?.toString() == call.arguments as String) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
clipboard.clearPrimaryClip()
|
||||
} else {
|
||||
clipboard.setPrimaryClip(ClipData.newPlainText("", ""))
|
||||
}
|
||||
}
|
||||
result.success(null)
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue