v1.6.2 — Tor en 1 tap, depuis l'inscription

TL;DR

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 : PinnedHttpOverrides route le HttpClient global vers 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 : 0 utilisateur sur ~1500 avait le mode Tor activé. 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 :

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 le dit : « Tor ajoute une protection contre l'analyse de trafic », 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 :

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.

Retour au blog · Page d'accueil · Code source AGPL-3.0