fix: corrections de l'audit de sécurité et de robustesse
- VPN retiré : le contrôle reste activé (alerte parent, tunnel remonté après 30 s, autorisation redemandée à l'ouverture) - Horloge de référence : changer date/heure/fuseau ne contourne plus les plages horaires ni le temps d'écran (signalé au parent) - Mot de passe : PBKDF2 + attente croissante après 3 échecs ; conversion automatique des anciens hachages - Écrans protégés : aucun affichage avant chargement des réglages ; effacement du journal protégé - Signature release via keystore.properties (même clé que les versions publiées) - Sauvegarde Google : réglages, appairage et journal exclus - Alerte admin fiable (goAsync), relance refusée signalée, liste d'applis renvoyée à chaque installation, code d'appairage consommé - Journal thread-safe et sans recopie à chaque ligne ; correctifs lint - Tests unitaires (mot de passe, règles, versions, config Firebase) ; README aligné sur le comportement réel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9CBCVP5oDu2sfoYPisNCQ
This commit is contained in:
1 parent
f33776bbb5
commit
e269e9932a
37 files changed
+809
-147
No files matched your search
@@ -2,9 +2,9 @@ package com.jttools.datacontrol.log
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
@@ -31,8 +31,9 @@ object AppLog {
|
||||
private val io = Executors.newSingleThreadExecutor()
|
||||
private val fmt = SimpleDateFormat("MM-dd HH:mm:ss", Locale.FRANCE)
|
||||
private val lines = ArrayDeque<Entry>()
|
||||
private val _entries = MutableStateFlow<List<String>>(emptyList())
|
||||
val entries: StateFlow<List<String>> = _entries.asStateFlow()
|
||||
/** Incrémenté à chaque changement : la liste n'est reconstruite que si l'onglet Journal l'observe. */
|
||||
private val version = MutableStateFlow(0L)
|
||||
val entries: Flow<List<String>> = version.map { synchronized(lines) { lines.map { it.text } } }
|
||||
|
||||
@Volatile private var file: File? = null
|
||||
private var prunedSinceCompact = 0
|
||||
@@ -65,8 +66,9 @@ object AppLog {
|
||||
private fun add(level: String, tag: String, message: String) {
|
||||
Log.println(when (level) { "E" -> Log.ERROR; "W" -> Log.WARN; else -> Log.INFO }, "DataControl/$tag", message)
|
||||
val now = System.currentTimeMillis()
|
||||
val entry = Entry(now, "${fmt.format(Date(now))} $level $tag: $message")
|
||||
synchronized(lines) {
|
||||
// SimpleDateFormat n'est pas sûr entre threads : formaté sous le verrou.
|
||||
val entry = Entry(now, "${fmt.format(Date(now))} $level $tag: $message")
|
||||
lines.addLast(entry)
|
||||
prune(now)
|
||||
publish()
|
||||
@@ -87,7 +89,7 @@ object AppLog {
|
||||
}
|
||||
|
||||
private fun publish() {
|
||||
_entries.value = lines.map { it.text }
|
||||
version.value++
|
||||
}
|
||||
|
||||
/** Réécrit le fichier avec les seules entrées conservées. À appeler sous verrou. */
|
||||
|
||||
Reference in new issue
Block a user