Guide d'utilisation
1. Présentation
Cercle est une application Android privée pour la famille et les proches. Un cercle est un groupe de personnes invitées ; tout ce qui s'y passe n'est visible que par ses membres.
- Discussions : salons publics du cercle, groupes, messages privés.
- Carte : position des membres.
- Agenda : rendez-vous et tâches partagés, avec rappels.
- Notes : bloc-notes partagé avec photos et fichiers.
- Appareils : caméras et objets connectés de la maison.
Cercle est gratuit, sans publicité, sans compte Google ni adresse e-mail : les données sont gardées sur un serveur personnel, pas chez un géant du web.
2. Premiers pas
- Télécharge l'app sur la page Télécharger et installe-la (autorise l'installation hors Play Store).
- Choisis un pseudo et un mot de passe : ils protègent l'app sur ton téléphone.
- Crée un cercle, ou rejoins-en un avec le code d'invitation reçu d'un membre.
- Note ton code de récupération : il permet de retrouver ton compte sur un nouveau téléphone. Il n'est montré qu'une seule fois, à la création du compte. Code perdu : demande un nouveau code à la personne qui gère le serveur de ton cercle.
Pour inviter quelqu'un : Paramètres › Inviter, ou la fiche du cercle (toucher son nom en haut de l'écran). On peut appartenir à plusieurs cercles et passer de l'un à l'autre.
3. Discussions
Écrire et envoyer
- Texte, emojis, photos (une ou plusieurs, ou une rafale prise à la suite), vidéos, messages vocaux, documents (PDF, Word… jusqu'à 50 Mo).
- Un message pas encore envoyé reste en brouillon.
- On peut partager vers Cercle depuis une autre app (bouton Partager d'Android).
- Sondages, message épinglé en haut de la discussion, recherche.
- Les liens (sites, e-mails, numéros de téléphone) sont cliquables, dans les messages comme dans les notes.
Gestes sur un message
- Glisser à droite : répondre à ce message.
- Glisser à gauche : réagir avec un emoji.
- Appui long : copier, modifier (10 minutes après l'envoi), sauvegarder, supprimer, voir « Vu et lu par ».
Gérer une discussion
- Infos de la discussion : membres, photo, galerie des photos / vidéos / documents envoyés.
- Vider la discussion pour tout le monde (créateur ou propriétaire) ou seulement chez moi.
- Le propriétaire du cercle peut choisir une durée de conservation : les messages plus vieux s'effacent seuls (sauf ceux sauvegardés).
4. Carte
- La carte (OpenStreetMap) montre les membres du cercle, chacun avec sa couleur ; les personnes proches sont regroupées.
- Le partage de position est actif dès que la localisation est autorisée. Pour l'arrêter : retirer l'autorisation de localisation dans les réglages Android.
- Les positions sont demandées à l'ouverture de la carte (pas de suivi permanent).
5. Agenda et tâches
- L'onglet s'ouvre sur un récapitulatif filtrable (personne, période, mot) ; l'icône calendrier affiche le mois.
- Le bouton + ajoute un rendez-vous (date, heure de début et de fin, lieu, couleur, « pour qui ») ou une tâche (une ou plusieurs personnes, date limite, cochée par celui qui la fait).
- Toucher le lieu d'un rendez-vous (souligné) l'ouvre dans Google Maps ou Waze.
- Rappels : par défaut la veille, ou aux moments choisis ; ils sonnent sur les téléphones concernés.
- Partage choisi : un élément peut être visible par tout le cercle ou seulement par certaines personnes.
- Notifications et pastilles : un rendez-vous ou une tâche « pour » certaines personnes ne prévient qu'elles (et celui qui l'a créé), même si tout le cercle peut le voir.
- Les anniversaires des membres apparaissent automatiquement.
6. Notes
- Plusieurs notes partagées, avec photos et fichiers.
- Une note s'ouvre en lecture ; le bouton Modifier permet de l'écrire, Terminé revient en lecture.
- Mise en forme :
**gras**,*italique*,__souligné__, titre avec « # », listes « • » et cases à cocher « ☐ / ☑ ». - Enregistrement automatique ; si deux personnes modifient en même temps, les changements de chacun sont fusionnés.
7. Appareils
- Relier une caméra Wi-Fi, un ancien téléphone utilisé comme caméra, une prise ou un capteur (eau, fumée, porte, mouvement, température).
- Voir l'image en direct, allumer / éteindre, orienter une caméra motorisée.
- Les alertes importantes (fuite d'eau, fumée) préviennent tout le cercle, même pendant les heures calmes.
- Une seule personne à la fois pilote un appareil ; il est libéré après 2 minutes sans geste.
8. Réglages, thèmes, notifications
- Thèmes et polices : choisis sur les pages Thèmes et Polices, appliqués d'un toucher dans l'app.
- Notifications : messages privés, groupes, salons, agenda, notes, appareils — chacune peut être coupée. Heures calmes possibles.
- Mises à jour : l'app se met à jour toute seule depuis ce site (au plus une proposition par jour).
- Sauvegarde : export de ses données dans un fichier depuis les réglages.
9. Vie privée
- Aucune publicité, aucun traqueur, aucune revente de données.
- Les messages sont chiffrés sur le serveur (voir Sécurité et Contrôle des données).
- Effacer mes données : chaque membre peut supprimer ses messages, fichiers et positions d'un cercle.
- Le propriétaire peut supprimer le cercle entier : tout son contenu est effacé.
Documentation technique
10. Architecture
| Partie | Technologie | Rôle |
|---|---|---|
| Application | Android, Kotlin, Jetpack Compose | Interface, cache hors ligne, notifications, localisation, caméra |
| Serveur | Python 3 (bibliothèque standard), un seul programme | API HTTP + JSON, droits d'accès, temps réel, page web |
| Base de données | SQLite (mode WAL) | Comptes, cercles, messages, agenda, notes, appareils |
| Chiffrement | AES-256-GCM (bibliothèque cryptography) | Contenu des discussions chiffré dans la base |
| Carte | osmdroid + tuiles OpenStreetMap | Tuiles relayées et gardées en cache par le serveur |
| Recherche de lieux | Géoplateforme IGN, geo.api.gouv.fr (villes), Photon (OpenStreetMap) | Suggestions rapides (IGN, 0,2 s) puis complètes (Photon : commerces, étranger), demandées par le serveur, réponses gardées 7 jours |
| Itinéraires | Liens Google Maps et Waze | Ouvrent l'app installée (ou le site) |
| Accès internet | HTTPS (certificat automatique) | Connexion chiffrée entre les téléphones et le serveur |
Le serveur est hébergé à la maison, dans un service système isolé (bac à sable : système de fichiers en lecture seule sauf ses données, pas d'accès au réseau local de la maison). Une sauvegarde de la base est faite automatiquement et gardée 30 jours.
11. Données enregistrées
| Table | Contenu | Chiffré |
|---|---|---|
users, tokens | Comptes anonymes (identifiant + empreinte SHA-256 du jeton, jamais le jeton lui-même) | empreinte |
cercles, members | Nom du cercle, propriétaire, membres, pseudo, photo, anniversaire | non |
rooms | Discussions : type, membres ; aperçu du dernier message, auteur, message épinglé | oui (aperçu, auteur, épingle) |
messages | Texte, nom affiché, pièce jointe, réponse, sondage, réactions | oui |
files | Contenu des photos, vidéos, vocaux et documents (morceaux de 1 Mo) | oui |
events, tasks | Agenda et tâches, avec qui peut les voir | oui (titre, lieu, détails) |
notes, note_files | Notes et leurs fichiers | oui |
locations | Dernière position de chacun | oui (nom et coordonnées) |
changes | Journal des modifications (pastilles et notifications) | oui (titre, détail) |
devices, switchbot | Appareils reliés (seule l'empreinte de leur clé est gardée) ; adresse et mot de passe des caméras achetées, compte SwitchBot | empreinte ; oui (mots de passe, compte) |
Restent en clair dans messages seulement les identifiants, les heures et la liste de ceux qui ont sauvegardé le message : ils servent à trier, compter les non-lus et appliquer la durée de conservation.
12. Sécurité
Chiffrement des messages
Liste des données chiffrées : voir Données enregistrées.
- Algorithme AES-256-GCM : chiffre et vérifie l'intégrité (une donnée modifiée dans la base est refusée).
- Un nombre aléatoire neuf (96 bits) pour chaque valeur : deux messages identiques donnent deux résultats différents.
- Chaque valeur est liée à sa colonne (« données associées ») : on ne peut pas déplacer un texte chiffré d'une colonne à une autre.
- La clé (256 bits, tirée au hasard) est dans un fichier séparé de la base, lisible par le serveur seul. Une copie volée de la base seule est illisible.
- Les messages enregistrés avant le chiffrement sont chiffrés automatiquement au démarrage, puis le fichier est réécrit pour ne laisser aucune trace en clair.
- Effacement sûr (
secure_delete) : un message supprimé est réellement écrasé dans le fichier.
Accès et droits
- Chaque requête porte un jeton secret (
Authorization: Bearer …) ; le serveur n'en garde que l'empreinte. - Un jeton pas utilisé depuis 6 mois est coupé ; « Déconnecter mes autres téléphones » coupe tous les autres jetons du compte (téléphone perdu ou volé).
- Le nom affiché d'un message, d'une citation ou d'un message épinglé est repris de l'annuaire du cercle et du vrai message : personne ne peut écrire sous le nom d'un autre.
- Code d'invitation changé tout seul quand le propriétaire retire quelqu'un (et à la demande) : la personne retirée ne peut pas revenir avec l'ancien.
- Place des fichiers limitée (20 Go par cercle, et rien quand le disque a moins de 10 Go de libre).
- Les comptes qui ne sont dans aucun cercle n'ont accès à rien (pas d'état du serveur ni de recherche de lieux) et sont effacés au bout de 30 jours.
- Chaque route vérifie l'appartenance au cercle et à la discussion (un message privé n'est lisible que par ses deux membres).
- Limites anti-abus par adresse (la dernière adresse donnée par Tailscale, impossible à inventer ; tentatives de code d'invitation, rafales de requêtes refusées) et alertes de sécurité envoyées aux membres.
- Connexion toujours en HTTPS.
13. Contrôle des données reçues
Avant toute écriture dans la base, le serveur contrôle ce qu'il reçoit :
- Pas de SQL possible dans les saisies : toutes les requêtes sont paramétrées (vérifié par les tests) (
?). Un texte comme'; DROP TABLE messages; --est enregistré comme un simple texte et n'est jamais exécuté. Les seuls noms insérés dans une requête sont des noms de tables écrits dans le code. - Nettoyage : caractères de contrôle invisibles retirés (sauf retour à la ligne et tabulation), caractères Unicode cassés remplacés, nombres impossibles (
NaN, infini) refusés, données trop imbriquées refusées. - Types et tailles : chaque champ est vérifié (texte non vide, longueur maximale : message 2 000 caractères, pseudo 30, etc. ; coordonnées dans les bornes ; dates au bon format).
- Pièces jointes : seulement les champs connus, sorte parmi image / vidéo / audio / fichier, nom de fichier limité aux lettres, chiffres,
_et-(pas de../), tailles plafonnées. - Réponses et messages épinglés : seulement identifiant, nom et extrait (150 caractères).
- Tailles des envois : 2 Mo par requête JSON, 1 Mo par morceau de fichier.
- Les pages web échappent tout texte affiché (
html.escape).
14. API (liste des adresses)
Toutes les réponses sont en JSON. {cid} = identifiant du cercle, {rid} = discussion. Les routes /api/c/… demandent d'être membre du cercle.
| Domaine | Adresses |
|---|---|
| Compte | POST /api/register, GET /api/me, GET|PUT /api/profile, POST /api/recovery/link|login |
| Cercles | POST /api/cercles, POST /api/join, GET|PATCH|DELETE /api/c/{cid}, /members, /members/me, /presence, /delete-my-data |
| Discussions | GET|POST /api/c/{cid}/rooms, GET|PATCH|DELETE /rooms/{rid}, /clear, /clear-mine, /read, /receipts, /stats, /typing, /purge |
| Messages | GET|POST /rooms/{rid}/messages, PATCH|DELETE /messages/{mid} (opérations : edit, react, vote, save), GET|PUT /rooms/{rid}/files/{fid}, GET /api/c/{cid}/news |
| Carte | PUT /locations, GET|DELETE /locations/{aud}, POST /locate, GET /api/geocode?q=…&ville=…&near=lat,lng&source=rapide|complet (recherche de lieu) |
| Agenda, notes | GET /agenda, PUT|DELETE /agenda/{eid}, GET /tasks, PUT|DELETE /tasks/{tid}, GET /notes, PUT|DELETE /notes/{nid}, /notes/{nid}/files/{fid}, GET /changes |
| Appareils | GET|POST /devices, PATCH|DELETE /devices/{did}, /command, /control, /frame, /stream, /hls/… ; côté appareil : /api/device/state|push|frame|commands|pair |
| Temps réel | GET /api/c/{cid}/events (flux SSE) |
| Public | /telecharger, /cercle.apk, /version.json, /themes, /polices, /documentation, /api/health |
Codes d'erreur : 400 donnée invalide, 401 jeton absent ou expiré, 403 accès refusé, 404 introuvable, 413 trop gros, 429 trop de demandes.
15. Temps réel et notifications
- L'app garde une connexion SSE ouverte (
/events) ; le serveur y envoie seulement le sujet qui a changé (rooms,msgs:{rid},typing:{rid},members,changes…), jamais le contenu. L'app relit alors la donnée concernée. - En arrière-plan, un service léger garde cette connexion (notification système masquée) : pas de service Google, pas de vérification périodique.
- Le journal
changesregroupe les modifications d'agenda, de notes et d'appareils pour les pastilles et les notifications. - Présence : l'app annonce toutes les 30 s qu'elle est à l'écran ; « en ligne » s'éteint après 75 s sans nouvelles.
16. Mises à jour de l'app
- Le numéro de version est le nombre de modifications enregistrées dans l'historique du code (1.N).
- L'app lit
/version.jsonau démarrage et au retour à l'écran ; si une version plus récente existe, elle télécharge/cercle.apket l'installe (proposée au plus une fois par jour, sauf correction urgente). - L'historique des versions est affiché sur la page Télécharger.
17. Tests de non-régression
Avant chaque mise en ligne :
- Serveur : un programme d'essai lance une copie du serveur sur une base vide et vérifie plus de 200 scénarios : création de cercle, droits (un étranger est refusé), messages, réactions, sondages, fichiers, agenda, notes, appareils, limites anti-abus, et notamment :
- textes piégés avec du SQL enregistrés tels quels, tables intactes ;
- caractères invisibles retirés, nombres et pièces jointes invalides refusés ;
- chiffrement : aucun texte, nom, sondage, réaction ou fichier lisible en clair dans le fichier de la base, mais tout est relu normalement par l'app ; anciens messages chiffrés au démarrage.
- Application : tests unitaires (lecture des codes QR des appareils, conversions de données, non-régression) et essai automatique de milliers de gestes au hasard sur un émulateur.