Repository navigation
Releases: gitubpatrice/AGENDA-TECH
Release list
v1.2.0 — Three month displays, five languages
The month now shows what each day holds, the app speaks German, Italian and Spanish, and all-day events keep their own date wherever the phone is.
Added
- Three ways to show the month, chosen from the top bar or by pinching the month: dots, as before; titles inside the grid, where a lone event uses every free line of its day instead of being cut after a few letters; and one row per day, with every title whole and the free days kept in place. In the titles view a tap opens the day over the month, and a swipe moves to the next day without closing it. Asked by a user who could not see what each day held without tapping it.
- Long-press a day to create an event on it, and tap the month name to jump to any date.
- The month speaks to screen readers: each day announces its full date and its events, instead of a bare number.
- German, Italian and Spanish, alongside English and French: every screen, notification and widget, the F-Droid listing, the privacy policy and the new terms of use. Machine-assisted and not yet reviewed by a native speaker — corrections welcome, see
TRANSLATING.md. - Language entry in Settings (Android 13 and later), opening Android's per-app language screen.
- Terms of use, linked from About. For them and for the privacy policy, the French version prevails.
Changed
- The main action of each screen is a filled button in the app's blue: the "+" button, Save, the backup banner, "See updates".
- The selected day is outlined rather than filled; the neighbouring months are read with the one shown, so a swipe slides in a month already filled in; the splash logo has rounded corners.
- A busy month settles faster in the titles view (16 events a day on a Galaxy S9: worst frame 105–150 ms before, 61–69 ms after).
- Build: Android Gradle Plugin 9.4.1, Gradle 9.8.0, SQLCipher 4.19.1 (same database format; a 1.1.1 agenda opens in place).
Fixed
- An all-day event created in another time zone spilled onto two days — after a journey, or after restoring a backup made elsewhere: two days in the month, week and day views, the day before in the agenda, a day late in the widget, and saving it unchanged moved it by a day. Its dates are now read in the zone it was created in, everywhere, and its reminders ring at the phone's midnight. Also in 1.1.1.
- An open app kept the old time zone after a journey until it was closed; the screens, the widgets and the reminders now follow a change of time zone at once. Also in 1.1.1.
- After changing the app's language, the week kept the old language's first day until the app was closed.
- One day of an all-day series could open ending the day before it began around a change of summer time, and saving it stored a day of no length. Found by external review.
- Coming back to the month could show the next one after a visit to Settings, the editor or search.
- At the largest text sizes, two-digit day numbers were cut; a day with more than four events showed no "+"; reminder and repeat labels read "day(s)"; an all-day reminder showed a clock time; the first calendar kept the language of the first launch; the F-Droid listing claimed "Argon2-grade PBKDF2" (backups use PBKDF2-HMAC-SHA256 at 600,000 iterations).
Checked before publishing
515 unit tests · 0 skipped · detekt 0 · lint 0 · instrumented tests on Android 10 (CI) · 23 negative controls on the time-zone fixes, each part broken in turn and detected · external review (GPT 5.6, Gemini 3.1 Pro) and a three-axis pre-release audit, every finding checked against the code first · update from the published 1.1.1 on a Galaxy S9 (Android 10): events, PIN and settings kept · Galaxy S24 (Android 16) · Android 14 emulator: five languages at 100, 130 and 200 % text, a 320 dp screen, dark theme, time zone changed with the app open · merged manifest: no network permission · signing certificate unchanged.
Which file to download
agenda-tech-universel-1.2.0.apk works on every phone. The others are lighter but specific to one processor architecture.
Français
Le mois montre désormais ce que contient chaque jour, l'application parle allemand, italien et espagnol, et les journées entières gardent leur date où que soit le téléphone.
Ajouté
- Trois façons d'afficher le mois, au choix dans la barre du haut ou en pinçant le mois : les points, comme avant ; les titres dans la grille, où un événement seul occupe toutes les lignes libres de sa case au lieu d'être coupé après quelques lettres ; et une ligne par jour, titres entiers, jours libres conservés. En mode titres, un tap ouvre le jour par-dessus le mois, et un glissement passe au jour suivant sans le refermer. Demandé par un utilisateur qui ne voyait pas ce que contenait chaque jour sans le toucher.
- Appui long sur un jour pour y créer un événement, et tap sur le nom du mois pour aller à n'importe quelle date.
- Le mois se lit avec un lecteur d'écran : chaque jour annonce sa date complète et ses événements, au lieu d'un simple chiffre.
- Allemand, italien et espagnol, en plus de l'anglais et du français : tous les écrans, les notifications et le widget, la fiche F-Droid, la politique de confidentialité et les nouvelles conditions d'utilisation. Traductions assistées par machine, pas encore relues par un locuteur natif — corrections bienvenues, voir
TRANSLATING.md. - Entrée « Langue de l'application » dans les réglages (Android 13 et plus).
- Conditions d'utilisation, accessibles depuis « À propos ». Pour elles comme pour la politique de confidentialité, la version française fait foi.
Modifié
- L'action principale de chaque écran est un bouton plein, du bleu de l'application : le « + », Enregistrer, le bandeau de sauvegarde, « Voir les mises à jour ».
- Le jour sélectionné est entouré plutôt que surligné ; les mois voisins sont lus avec celui qui est affiché, un glissement fait donc arriver un mois déjà rempli ; le logo de démarrage a ses coins arrondis.
- Un mois chargé s'affiche plus vite en mode titres (16 événements par jour sur un Galaxy S9 : pire image de 105–150 ms à 61–69 ms).
- Chaîne de build : Android Gradle Plugin 9.4.1, Gradle 9.8.0, SQLCipher 4.19.1 (même format de base ; un agenda 1.1.1 s'ouvre tel quel).
Corrigé
- Une journée entière créée dans un autre fuseau horaire débordait sur deux jours — après un voyage, ou après la restauration d'une sauvegarde faite ailleurs : deux jours dans les vues mois, semaine et jour, la veille dans l'agenda, un jour trop tard dans le widget, et l'enregistrer sans rien changer la déplaçait d'un jour. Ses dates sont désormais lues partout dans le fuseau où elle a été créée, et ses rappels sonnent à minuit, heure du téléphone. Présent aussi dans la 1.1.1.
- L'application ouverte gardait l'ancien fuseau après un voyage jusqu'à sa fermeture ; les écrans, les widgets et les rappels suivent désormais aussitôt un changement de fuseau. Présent aussi dans la 1.1.1.
- Après un changement de langue de l'application, la semaine gardait le premier jour de l'ancienne jusqu'à la fermeture de l'application.
- Un jour d'une série « journée entière » pouvait s'ouvrir avec une fin la veille de son début autour d'un changement d'heure, et l'enregistrer créait une journée de durée nulle. Trouvé par une relecture externe.
- Revenir au mois pouvait afficher le suivant après un passage par les réglages, l'éditeur ou la recherche.
- Aux plus grandes tailles de texte, les numéros de jour à deux chiffres étaient coupés ; un jour de plus de quatre événements n'affichait pas de « + » ; les libellés de rappel et de répétition disaient « jour(s) » ; le rappel d'une journée entière affichait une heure ; le premier calendrier gardait la langue du premier lancement ; la fiche F-Droid annonçait « Argon2-grade PBKDF2 » (les sauvegardes utilisent PBKDF2-HMAC-SHA256 à 600 000 itérations).
Quel fichier télécharger
agenda-tech-universel-1.2.0.apk fonctionne sur tous les téléphones. Les autres sont plus légers mais propres à une architecture de processeur.
v1.1.1 — Restore with the PIN lock, key store safety
Two fixes that matter to anyone on 1.1.0. One was found by testing on a phone, the other by an external code review; both were checked against the code and on a device before being fixed.
Fixed
- With the app lock on, restoring a backup stopped after the PIN. Opening the file picker locked the app, and unlocking rebuilt the navigation on the month view, so the password dialog never appeared. The app no longer asks for the PIN after a file picker it opened itself, and unlocking always returns to the screen you left — an event being typed survives a phone call. The lock still applies when you leave the app, when the screen turns off while a picker is open, when you come back through a notification, the widget or the app icon, and when you come back more than 3 minutes later.
- Android 8 to 11: a key store that briefly stopped responding could erase the agenda. On those versions the system reports a key it cannot reach as missing. The app then created a new key, which destroyed the real one: the agenda was reset, or the PIN could never be verified again. A key is now never created while reading. The app refuses to open, erases nothing, and says to restart the phone.
Changed
- Build toolchain: Android Gradle Plugin 9.4, Gradle 9.7.1, Kotlin 2.4.10, compileSdk 37 (target unchanged, 35). SQLCipher 4.19.
Checked before publishing
427 unit tests · 0 skipped · detekt 0 · lint 0 · instrumented tests with a real SQLCipher and Keystore on a Galaxy S9 (Android 10) and an Android 14 emulator · negative controls: the new tests fail on the previous code · manual test on the Galaxy S9 with the lock on: restore, export, screen off during a picker, back to the editor after Home · a 1.1.0 database and its data opened in place by the new build · merged manifest: no network permission · signing certificate unchanged.
Which file to download
agenda-tech-universel-1.1.1.apk works on every phone. The others are lighter but specific to one processor architecture.
Français
Deux corrections importantes pour les utilisateurs de la 1.1.0. L'une a été trouvée en testant sur téléphone, l'autre par une relecture externe du code ; les deux ont été vérifiées dans le code et sur appareil avant d'être corrigées.
Corrigé
- Avec le verrouillage par code PIN, la restauration s'arrêtait après le code. Ouvrir le sélecteur de fichier verrouillait l'application, et le déverrouillage ramenait sur le mois : la fenêtre du mot de passe ne s'ouvrait jamais. L'application ne redemande plus le code après un sélecteur qu'elle a ouvert, et le déverrouillage ramène toujours à l'écran quitté — un événement en cours de saisie survit à un appel. Le verrou s'applique toujours en quittant l'application, si l'écran s'éteint pendant un sélecteur, au retour par une notification, le widget ou l'icône, et au retour après plus de 3 minutes.
- Android 8 à 11 : un stockage de clés muet un instant pouvait effacer l'agenda. Sur ces versions, le système signale comme absente une clé qu'il ne parvient pas à joindre. L'application en créait alors une nouvelle, ce qui détruisait la vraie : l'agenda était réinitialisé, ou le code PIN ne pouvait plus jamais être vérifié. Une clé n'est désormais jamais créée en relisant. L'application refuse d'ouvrir, n'efface rien, et invite à redémarrer le téléphone.
Modifié
- Chaîne de build : Android Gradle Plugin 9.4, Gradle 9.7.1, Kotlin 2.4.10, compileSdk 37 (cible inchangée, 35). SQLCipher 4.19.
Quel fichier télécharger
agenda-tech-universel-1.1.1.apk fonctionne sur tous les téléphones. Les autres sont plus légers mais propres à une architecture de processeur.
Empreintes SHA-256
192371860ebe305d6cc1f7a5e638bfada6879c5c963a2a165f6c000e2c1965e6 agenda-tech-universel-1.1.1.apk
9415dd53cd99103f81de6a63203aa8668465a1185ec5951b4db6645f7a8c4766 app-arm64-v8a-release.apk
81bc24f568083ad0a3ef30728dcc5a49e94bbacbf22e4feb6319f5141e3c2dac app-armeabi-v7a-release.apk
0bf8dacb95aef6df103efac5942bb52ba2571c2bde76f15caa3665b60ecd671c app-x86_64-release.apk
v1.1.0 — Sauvegarde automatique, anniversaires, duplication
Trois fonctionnalités nouvelles, et l'audit le plus profond que l'application ait reçu.
Nouveau
- Sauvegarde chiffrée automatique. Une fois par semaine, dans le dossier de votre choix, sans rien faire. Même chiffrement que la sauvegarde manuelle ; le mot de passe est rangé dans le magasin sécurisé du téléphone. À activer — rien ne part sans que vous l'ayez demandé.
- Événements d'anniversaire. Donnez l'année de naissance une fois : l'âge se calcule tout seul et se met à jour chaque année.
- Dupliquer un événement en une tape, récurrence comprise.
Corrigé
Vingt-six constats, issus d'un audit global puis d'un audit de cohérence. Les plus coûteux :
- Un
.ics« toute la journée » sansDTENDdevenait invisible. La RFC 5545 rendDTENDfacultatif et admetDURATIONà sa place ; l'import donnait à ces événements une durée nulle, et tous les filtres par jour les écartaient. L'événement était bien en base, mais introuvable dans les vues mois, jour et semaine. - Les rappels ne survivaient pas à un « forcer l'arrêt » jusqu'au redémarrage du téléphone.
- Le widget n'était jamais redessiné après une écriture : un événement supprimé y restait affiché jusqu'à une demi-heure.
- Un double-tap créait deux événements, et sur l'écran Calendriers, deux calendriers.
- Des échecs d'écriture passaient inaperçus : le PIN, le calendrier et la suppression se refermaient comme si l'écriture avait eu lieu.
- Supprimer un calendrier laissait ses alarmes armées auprès du système.
- L'écran d'import depuis l'agenda du téléphone pouvait se bloquer sans sortie : il verrouille le bouton retour pendant l'opération, et un échec de base laissait son drapeau posé pour toujours.
Modifié
- Les widgets prennent les couleurs du logo — le bleu et le rouge de son damier — et des angles arrondis qui fonctionnent dès Android 8, non plus seulement à partir d'Android 12.
- L'import
.icsaffiche enfin qu'il travaille.
Sécurité
Aucune vulnérabilité trouvée. La promesse « aucune permission Internet » est désormais vérifiée au niveau du noyau, sur appareil : le processus n'appartient pas au groupe AID_INET (gid 3003), sans lequel l'ouverture d'un socket réseau échoue quoi que le code tente. Mesuré sur Galaxy S9 avec un témoin positif dans la même session.
La CI construit maintenant la variante release minifiée — R8 n'était exercé par aucun job, donc aucune règle keep manquante n'aurait été vue avant publication. CodeQL a été ajouté.
Vérifié avant publication
402 tests unitaires · 0 ignoré · detekt 0 · lint 0 · 15 tests instrumentés sur Galaxy S9 (API 29, SQLCipher et Keystore réels) · manifeste fusionné : 11 permissions, aucune réseau · parité FR/EN 310 chaînes des deux côtés · release minifiée installée par-dessus la v1.0.3 sans désinstallation, donc certificat de signature inchangé et chemin de mise à jour exercé.
Quel fichier télécharger
agenda-tech-universel-1.1.0.apk fonctionne sur tous les téléphones. Les autres sont plus légers mais spécifiques à une architecture.
Agenda Tech 1.0.3 — un binaire sans passager clandestin
Agenda Tech 1.0.3 — un binaire sans passager clandestin
Aucun changement fonctionnel. L'application se comporte exactement comme la 1.0.2.
Ce qui est retiré
L'outil de compilation de Google glissait, dans le bloc de signature de chaque APK publié, un
bloc « Dependency metadata » : la liste chiffrée de nos bibliothèques, destinée à la console
Play. Ici, 9085 octets de données illisibles, que personne ne peut inspecter.
Aucune application Files Tech n'est publiée sur le Play Store. Ce bloc n'avait donc aucune raison
d'exister, et il contredisait ce que cette application promet : un binaire vérifiable de bout en
bout. Il est supprimé (dependenciesInfo { includeInApk = false }).
Pourquoi maintenant, et pas avant
Il était là depuis toujours — dans chaque APK publié — mais personne ne le regardait. Le scanner
de F-Droid n'analysait que l'APK non signé qu'il reconstruisait lui-même, et un APK sans
signature n'a pas de bloc de signature : rien à y trouver.
C'est en déclarant notre binaire signé comme référence de build reproductible, en 1.0.2, que le
scanner s'est mis à examiner ce que vous téléchargez réellement. Le bloc est sorti au premier
passage. Rendre un binaire vérifiable, c'est aussi accepter que la vérification trouve quelque
chose.
Agenda Tech 1.0.3 — a binary with no stowaway
No functional change. The app behaves exactly as 1.0.2 does.
Google's build tooling was placing a "Dependency metadata" block — an encrypted list of our
libraries, meant for the Play console — inside the signing block of every published APK. Here,
9085 bytes nobody can inspect. No Files Tech app is published on the Play Store, so it had no
reason to be there, and it contradicted what this app claims: a binary you can verify end to end.
It is now removed.
It had always been there. F-Droid's scanner only ever looked at the unsigned APK it rebuilt
itself, and an unsigned APK has no signing block to inspect. Declaring our signed binary as the
reproducible-build reference in 1.0.2 is what made the scanner look at what you actually download
— and it found it on the first pass.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04
Si vous ne savez pas quel fichier prendre, prenez agenda-tech-universel-1.0.3.apk.
If you are unsure which file to take, take agenda-tech-universel-1.0.3.apk.
Agenda Tech 1.0.2 — un build reproductible
Agenda Tech 1.0.2 — un build que vous pouvez refaire vous-même
Aucun changement fonctionnel. L'application se comporte exactement comme la 1.0.1. Ce qui
change est la façon dont elle est construite — et ce que ça vous permet de vérifier.
Le build est désormais reproductible
N'importe qui peut cloner ce dépôt au tag v1.0.2, lancer la construction, et obtenir le même
APK que celui publié ici, octet pour octet. Pas « équivalent » : identique.
Ce n'était pas le cas avant, et pour une raison invisible depuis le code : settings.gradle.kts
déclarait le plugin foojay-resolver-convention, inutilisé ici puisque le projet compile en
Java 17 sans demander la moindre toolchain. Mais sa seule présence changeait le binaire — R8
attribuait d'autres noms d'obfuscation et comptait sept champs de plus, et le profil de démarrage
qui en dérive suivait. Sur 1481 fichiers dans l'APK, trois différaient.
Pourquoi ça compte pour vous
F-Droid reconstruit les applications depuis les sources. Quand le résultat correspond au binaire
signé par l'auteur, F-Droid peut distribuer ce binaire-là au lieu de le resigner avec sa propre
clé. Concrètement : la même application des deux côtés, et une mise à jour qui passe sans avoir à
désinstaller. Sans reproductibilité, ce choix est perdu définitivement à la première publication.
Vérifier par vous-même
git clone https://github.com/gitubpatrice/AGENDA-TECH && cd AGENDA-TECH
git checkout v1.0.2 && ./gradlew clean assembleRelease
Agenda Tech 1.0.2 — a build you can reproduce yourself
No functional change. The app behaves exactly as 1.0.1 does. What changed is how it is built,
and what that lets you check.
The build is now reproducible: clone this repository at v1.0.2, build it, and you get the
very same APK published here, byte for byte. The obstacle was an unused
foojay-resolver-convention plugin in settings.gradle.kts — its mere presence changed R8's
output, and with it the ART profile. Three files out of 1481 differed.
This is what allows F-Droid to distribute the build we signed ourselves rather than re-signing it
with its own key: the same app from either source, and updates that keep working. That choice is
lost for good at first publication if the build is not reproducible.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04
Si vous ne savez pas quel fichier prendre, prenez agenda-tech-universel-1.0.2.apk.
If you are unsure which file to take, take agenda-tech-universel-1.0.2.apk.
Agenda Tech 1.0.1 — la description du magasin
Agenda Tech 1.0.1 — la description du magasin, et rien d'autre
Aucun changement de code. L'application est identique à la 1.0.0, octet pour octet du côté
de son comportement : cette version n'existe que pour corriger la mise en forme du texte affiché
sur les magasins d'applications.
Ce qui change
La description était écrite en Markdown — les titres soulignés par une ligne de =. F-Droid ne
rend pas le Markdown : il affichait ces soulignements tels quels, au milieu du texte. Elle est
désormais écrite dans le sous-ensemble HTML qu'il met réellement en forme (<b>, <ul>, <li>).
Le contrôle amont de fdroiddata le signalait sur les deux langues. Il lit les métadonnées dans
l'arbre du commit visé par l'entrée de build, et non au dernier commit de la branche — d'où une
version à part entière pour un changement qui, autrement, n'en aurait pas mérité une.
Contenu inchangé : 22 lignes de texte avant comme après, dans les deux langues.
Signalé par @seekme-seekyou sur fdroiddata!42991.
Agenda Tech 1.0.1 — store description only
No code change at all. The app behaves exactly as 1.0.0 does. This release exists only to fix
the formatting of the text shown on app stores.
What changed
The description was written in Markdown, with headings underlined by a row of =. F-Droid does
not render Markdown, so it showed those underlines literally, in the middle of the text. It is
now written in the limited HTML subset F-Droid actually renders (<b>, <ul>, <li>).
The upstream fdroiddata check flagged it in both locales. It reads the metadata from the tree of
the commit a build entry points at, not from the branch tip — hence a release of its own for a
change that would not otherwise have deserved one.
Content is unchanged: 22 lines of text before and after, in both languages.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04
Si vous ne savez pas quel fichier prendre, prenez agenda-tech-universel-1.0.1.apk.
If you are unsure which file to take, take agenda-tech-universel-1.0.1.apk.
Agenda Tech 1.0.0 — cinq passes d'audit
Agenda Tech 1.0.0 — cinq passes d'audit
Aucune fonctionnalité nouvelle. Ce 1.0.0 marque autre chose : toute la surface de
l'application a enfin été regardée en entier — base et migrations, import .ics, cryptographie
de sauvegarde, alarmes et rappels, widget, notifications, interactions et branchements. Trente
et un commits séparent cette version de la 0.5.4.
Les défauts les plus graves corrigés
- La base pouvait s'effacer d'elle-même. Une ligne censée interdire l'effacement lors d'un
retour à une version antérieure l'armait : depuis Room 2.7, le booléen qu'elle prend ne
veut plus dire « autoriser » mais « supprimer toutes les tables ». Vérifié au désassemblage. - Un incident passager du coffre matériel effaçait tout l'agenda. Avec
allowBackup=false,
il n'existe aucune autre copie sur l'appareil. Une simple indisponibilité du Keystore pendant
un démarrage suffisait. - Une sauvegarde faite par une version plus récente était annoncée « pas une sauvegarde ».
Sur ce qui peut être l'unique exemplaire de votre agenda, c'est une invitation à supprimer le
fichier. - L'écran de sauvegarde annonçait un échec pendant qu'il remplaçait l'agenda.
- Des rappels récurrents pouvaient rester désarmés après un redémarrage, sans un mot.
- Le widget laissait les titres d'événements lisibles jusqu'à trente minutes après
l'activation du verrouillage. - Trois contrôles de sécurité échouaient en ouvert.
- Import
.ics: fuseaux Outlook corrompus, lignesEXDATErépétées perdues, emojis cassés
au pliage des lignes.
Ce qui a changé dans la façon de vérifier
Ce dépôt n'avait aucune intégration continue. Elle existe désormais et s'exécute aussi sur
les branches de travail : construction, tests, lint, detekt, tests instrumentés sur appareil
API 29, et un contrôle automatique qui échoue si une permission réseau apparaît dans l'APK.
État mesuré : 324 tests unitaires, lint 0, detekt 0 sans baseline (il en signalait 520
au début de l'audit), tests instrumentés verts.
Vie privée
Toujours aucune permission Internet. Les 11 permissions de l'APK sont documentées dans
PRIVACY.fr.md.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04
Si vous ne savez pas quel fichier prendre, prenez agenda-tech-universel-1.0.0.apk.
Agenda Tech v0.5.4 — Release de sécurité
🇫🇷 Release de sécurité
Ferme les deux derniers findings du scan de sécurité du 31/07/2026 — le scan est désormais entièrement traité — plus 8 défauts trouvés en revue de ce lot.
- Le déverrouillage biométrique est enfin adossé au coffre matériel. Jusqu'ici, l'agenda s'ouvrait sur la foi du rappel
onAuthenticationSucceeded: une affirmation faite par le processus de l'application elle-même, donc sans valeur là où ce processus peut être manipulé.BiometricPromptreçoit maintenant unCryptoObjectadossé à une clé AndroidKeyStore dédiée, créée sans fenêtre de validité — le processeur sécurisé exige donc une authentification Classe 3 pour chaque usage, et l'écran ne s'ouvre que si l'opération cryptographique aboutit réellement. Sur Android 11+, le palier est épinglé par l'OS lui-même. - Ré-enrôlement géré. Ajouter une empreinte détruit la clé, par conception : qui peut enrôler ne doit pas hériter du déverrouillage. L'app le détecte, désactive le déverrouillage biométrique et vous le dit, au lieu de laisser un bouton qui échoue en silence.
- Le code PIN reste affiché en toutes circonstances : aucun de ces chemins ne peut vous enfermer hors de vos données.
- Un agenda importé volumineux ne peut plus figer l'affichage. Le plafond de calcul était appliqué par événement, ce qui ne dit rien du nombre d'événements — et c'est exactement ce qu'un import contrôle. Le travail d'un rendu est désormais plafonné globalement : un agenda pathologique est tronqué, jamais transformé en gel de l'interface.
- Import
.icsplus robuste : une règle de répétition malformée ne fait plus perdre la répétition de tout l'événement.
Déverrouillage biométrique validé sur appareil réel.
🇬🇧 Security release
Closes the last two findings of the 2026-07-31 security scan — the scan is now fully addressed — plus 8 defects caught while reviewing this batch.
- Biometric unlock is finally bound to the hardware vault. Until now the calendar opened on the strength of the
onAuthenticationSucceededcallback: a statement made by the application's own process, and therefore worth nothing where that process can be manipulated.BiometricPromptnow receives aCryptoObjectbacked by a dedicated AndroidKeyStore key created with no validity window — so the secure processor demands a Class 3 authentication for every single use, and the screen opens only if the cryptographic operation actually succeeds. On Android 11+, the tier is pinned by the OS itself. - Re-enrolment handled. Adding a fingerprint destroys the key, by design: whoever can enrol must not inherit the unlock. The app detects this, turns biometric unlock off and tells you, instead of leaving a button that fails silently.
- The PIN field stays on screen in all circumstances: none of these paths can lock you out of your own data.
- A large imported calendar can no longer freeze the display. The computation cap applied per event, which says nothing about the number of events — and that is exactly what an import controls. The work one render may cost is now capped as a whole: a pathological calendar is truncated, never turned into a frozen UI.
- More robust
.icsimport: a malformed repeat rule no longer costs the event its whole recurrence.
Biometric unlock validated on a real device.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04
versionCode : 51
Agenda Tech v0.5.3 — Release de sécurité
🇫🇷 Release de sécurité
Corrige 10 des 11 findings du scan de sécurité du 31/07/2026 (8 MEDIUM, 3 LOW, aucun HIGH), plus 5 régressions et un bug préexistant trouvés en revue.
- Un fichier
.icspiégé pouvait rendre l'agenda inutilisable. Une règle de répétition avec un intervalle absurde faisait planter le mois, la semaine, le jour, la recherche et le widget à chaque rendu — en boucle dès le lancement. Comme l'événement fautif devenait inatteignable, la seule issue aurait été d'effacer toutes vos données. Les intervalles sont désormais bornés aux cinq points d'entrée, y compris à la lecture de la base et à la restauration d'une sauvegarde : un événement déjà enregistré par une version affectée est réparé à la lecture. - Un événement importé ne peut plus forger de lignes dans vos exports. L'identifiant
UIDétait la seule valeur écrite sans échappement : un saut de ligne y devenait une ligne de contenu, donc un.icsque vous exportiez et partagiez pouvait porter des événements entiers écrits par un tiers, sous votre nom. - Un retour chariot dans un titre cassait aussi la ligne exportée. Corrigé.
- Biométrie : Classe 3 uniquement. La Classe 2 est précisément le palier qu'Android interdit d'adosser à une clé du coffre matériel, parce qu'une photo l'usurpe sur beaucoup de déverrouillages faciaux. Le code PIN reste disponible en toutes circonstances — le durcissement ne peut pas vous enfermer hors de vos données.
- Tentatives de PIN concurrentes : deux essais simultanés ne comptent plus pour un seul.
- Bug préexistant corrigé : les
EXDATEd'un.icsimporté étaient parsées puis jetées. Un rendez-vous annulé ressuscitait à l'import, y compris lors d'un aller-retour par votre propre export.
Le bornage global de l'expansion des récurrences (finding F8) reste ouvert, hors périmètre.
234 tests unitaires. Chaque nouveau test a été vérifié en échec sans son correctif.
🇬🇧 Security release
Fixes 10 of the 11 findings from the 2026-07-31 security scan (8 MEDIUM, 3 LOW, no HIGH), plus 5 regressions and one pre-existing bug caught in review.
- A booby-trapped
.icsfile could render the calendar unusable. A repeat rule with an absurd interval crashed the month, week, day, search and widget views on every render — in a loop from launch. Since the offending event became unreachable, the only way out would have been erasing all your data. Intervals are now bounded at all five ingestion points, including on database read and backup restore: an event already stored by an affected build is healed as it is read. - An imported event can no longer forge lines in your exports. The
UIDwas the only value written without escaping: a line break in it became a content line, so an.icsyou exported and shared could carry whole events written by someone else, under your name. - A carriage return in a title broke the exported line too. Fixed.
- Biometrics: Class 3 only. Class 2 is exactly the tier Android forbids from gating a hardware-vault key, because a photo can spoof it on many face-unlock builds. The PIN stays available in all circumstances — the hardening cannot lock you out of your own data.
- Concurrent PIN attempts: two simultaneous guesses no longer count as one.
- Pre-existing bug fixed:
EXDATEentries in an imported.icswere parsed and then discarded. A cancelled appointment came back to life on import, including on a round-trip through your own export.
Global bounding of recurrence expansion (finding F8) remains open, out of scope.
234 unit tests. Every new test was verified to fail without its fix.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04
versionCode : 50
v0.5.2 — Release de sécurité
🇫🇷 Release de sécurité
Trois défauts trouvés par audit, dont un critique présent depuis le tout premier commit.
La base n'était pas réellement protégée
La vraie passphrase — 32 octets aléatoires, scellés sous l'AndroidKeyStore — était bien générée et bien stockée, mais jamais utilisée. Le tableau qui la portait était effacé de la mémoire juste après la construction de la base ; or Room n'ouvre réellement le fichier qu'à la première requête. Quand SQLCipher réclamait enfin la clé, il ne recevait plus que des zéros.
Conséquence : agendatech.db était déchiffrable par quiconque parvenait à l'extraire de l'appareil, sans avoir à toucher au coffre matériel.
Corrigé — et les bases existantes sont rechiffrées automatiquement au premier lancement, sans perte : l'agenda est copié de côté avant l'opération et remis en place si quoi que ce soit échoue. L'opération est jouée une seule fois, en arrière-plan.
Le compteur anti-force-brute du code PIN se réinitialisait trop facilement
Il ne vivait qu'en mémoire : fermer l'application de force — quelques appuis dans les réglages, aucun outil, aucun privilège — remettait le compteur à zéro et redonnait cinq essais. L'escalade des délais ne servait donc à rien face à quelqu'un de patient. Le compteur est désormais conservé d'un lancement à l'autre ; le plafond d'une minute est inchangé.
L'application se figeait pendant la sauvegarde et la restauration
Le calcul cryptographique qui protège un fichier .atbak (volontairement lent, c'est ce qui le rend résistant) tournait sur le fil de l'interface : gel d'environ une seconde à chaque export, et bien plus long face à un fichier hostile, au point de pouvoir faire tuer l'application par Android. Passé en arrière-plan.
Aussi
Démarrage plus fluide : la base était ouverte sur le fil de l'interface au lancement.
🇬🇧 Security release
Three flaws found by audit, including a critical one present since the very first commit.
The database was not actually protected
The real passphrase — 32 random bytes, sealed under the AndroidKeyStore — was generated and stored correctly, but never used. The array holding it was wiped from memory right after the database was built; but Room only opens the file on the first query. By the time SQLCipher finally asked for the key, all it got was zeros.
The upshot: agendatech.db could be decrypted by anyone able to extract it from the device, without ever touching the hardware vault.
Fixed — and existing databases are re-encrypted automatically on first launch, with no data loss: the agenda is copied aside beforehand and put back if anything fails. It runs once, in the background.
The PIN brute-force counter reset far too easily
It lived only in memory: force-stopping the app — a few taps in Settings, no tools, no privileges — reset the counter and handed back five fresh attempts. The escalating delays were therefore useless against a patient attacker. The counter now persists across launches; the one-minute ceiling is unchanged.
The app froze during backup and restore
The cryptographic work protecting an .atbak file (deliberately slow — that is what makes it resistant) ran on the UI thread: roughly a one-second freeze on every export, and far longer against a hostile file, to the point of being killed by Android. Moved to the background.
Also
Smoother startup: the database was being opened on the UI thread at launch.
Certificat de signature (inchangé) : 538bff8ab3162017038d031909fd4e06159f30a3371867f9e1d1bc146c9a1d04