L'onboarding Tor a été refait de zéro : détection live d'Orbot toutes les 3 secondes, 4 états visuels distincts, lancement direct d'Orbot via intent Android, et un indicateur 🧅 visible dans la nav quand le mode est on. Trois panneaux pédagogiques expliquent ce que « activer Tor » et « ne pas activer » veulent vraiment dire.
Le problème
Avant la v1.6.2, l'app supportait déjà Tor techniquement : un HttpOverrides faisait passer le HttpClient global par 127.0.0.1:9050 quand le toggle est on, et AppConfig.baseUrl bascule automatiquement sur l'adresse .onion. Mais l'option était planquée dans Réglages → Sécurité, accessible une fois l'inscription terminée, sans contexte sur ce que ça apportait.
Résultat : une option que presque personne ne trouvait. C'est symétrique du problème Signal des stickers chiffrés — tant que l'option n'est pas présentée clairement au bon moment, personne ne la trouve.
4 états visuels
La nouvelle page d'onboarding a un status card qui change en temps réel. Un Timer.periodic(3s) ping 127.0.0.1:9050, et l'UI rerend l'état :
Orbot absent
Bouton « Installer Orbot » (F-Droid)
Orbot prêt
Bouton « Activer Tor maintenant »
Tor actif
Trafic anonymisé, indicateur 🧅 visible
Lien rompu
Tor on mais Orbot stoppé — bouton de relance
Le bouton primaire change avec l'état. Pas trois boutons cachés qu'il faut deviner : un seul bouton, qui dit ce qu'il va faire en fonction de où tu en es. C'est l'invariant principal.
Lancer Orbot sans quitter l'app
Quand Orbot est installé mais éteint, il faut le démarrer. Plutôt qu'imposer à l'utilisateur de quitter Nøbody, ouvrir le tiroir d'apps, etc., on lance Orbot via un intent Android avec url_launcher :
// lib/services/tor_service.dart
Future<bool> openOrbot() async {
if (!Platform.isAndroid) return false;
final intent = Uri.parse(
'intent:#Intent;action=android.intent.action.MAIN;'
'category=android.intent.category.LAUNCHER;'
'package=org.torproject.android;end',
);
if (await canLaunchUrl(intent)) {
return await launchUrl(intent, mode: LaunchMode.externalApplication);
}
return false;
}
Sur Android 11+ canLaunchUrl exige que le package cible soit listé dans <queries> du manifeste. On a ajouté :
<!-- AndroidManifest.xml -->
<queries>
<package android:name="org.torproject.android" />
</queries>
Pédagogie : 3 panneaux honnêtes
On ne peut pas demander à un utilisateur d'activer Tor sans lui dire ce que ça fait, ce que ça coûte, et ce qui se passe s'il ne le fait pas. La page contient donc 3 panneaux colorés sous le bouton primaire (leur texte a été précisé depuis ; voici la version actuelle) :
- Avec Tor activé — le serveur ne voit jamais ton IP, routage automatique vers les .onion, couche d'anonymat supplémentaire en plus du chiffrement E2E.
- Si tu n'actives pas — le serveur voit ton adresse IP à chaque connexion. Nous ne la gardons pas dans nos journaux — mais c'est une promesse, pas une garantie technique. Tor en fait une garantie, et cache aussi ton activité à ton fournisseur d'accès ou au Wi-Fi public. Tes messages privés restent chiffrés de bout en bout dans les deux cas.
- Caveat UnifiedPush — ton distributeur (ntfy, Gotify…) se connecte hors de Tor : Nøbody coupe donc les notifications push tant que le mode Tor est actif. Elles reviennent quand tu désactives Tor.
Honnêteté rédactionnelle. Beaucoup d'apps « privacy » sur-vendent leur mode Tor en prétendant qu'il fait disparaître tout risque. Faux. Tor protège contre l'observateur réseau, pas contre un compromis de l'application elle-même, ni contre des bugs côté serveur. La page dit ce que Tor protège — ton adresse IP, face au serveur et à ton fournisseur d'accès —, pas « Tor te rend invisible ».
L'indicateur 🧅 dans la nav
Une fois Tor activé, on veut que l'utilisateur sache à tout moment qu'il est dans ce mode. Un nouveau widget TorIndicator est droppé dans la AppBar du Feed :
- Petit pill 🧅 Tor — vert si Orbot répond, ambre si Orbot a stoppé.
- Tap → ouvre Réglages → Sécurité pour désactiver / fix d'un coup.
- Render
SizedBox.shrink()quand Tor est off — le widget est sûr à drop dans n'importe quelleAppBarsans vérification préalable.
Localisation : 25 clés × 10 langues
25 nouvelles clés ARB ont été ajoutées dans les 10 langues supportées : FR, EN, DE, ES, IT, PT, TR, AR, RU, UK. Pas de fallback — chaque langue a son texte propre, y compris l'arabe RTL et les cyrilliques russe/ukrainien. Le script check-l10n-sync.py confirme : 798 clés × 10 locales, 0 missing / 0 extras.
Et après ?
L'objectif moyen-terme est d'embarquer un binaire tor directement dans l'app (FOSS, distribué sous licence BSD), pour que les utilisateurs n'aient même plus à installer Orbot. Ce sera la prochaine grosse itération sur le mode anonyme — « Tor par défaut, sans configuration » au lieu de « Tor opt-in après un install séparé ».
Code source de toute la feature : onboarding.dart, tor_service.dart, tor_indicator.dart.