Les push natives ne sont branchées nulle part, et le README affirme l'inverse

Vérifié dans les deux dépôts : web/push_notify.py envoie via ntfy, en se
servant du token du device comme nom de topic. Aucun enregistrement de token
APNs côté serveur (recherche registerToken / /api/devices / device_token :
zéro résultat), et le web n'appelle jamais PushNotifications de Capacitor
(zéro résultat). La moitié native est prête — plugin installé, aps-environment
déclaré, remote-notification dans UIBackgroundModes — et personne ne la
branche. Pour recevoir un rappel, il faut installer l'app ntfy et s'abonner à
un topic.

Deux conséquences. Le README liste « ✅ Push notifications natives » comme
PREMIER argument de sa section anti-rejet Guideline 4.2 : l'argument ne tient
pas si un examinateur teste les rappels, et 4.2 est justement le risque de
cette architecture. Et une capability déclarée mais inutilisée tombe sous
2.3.1(a) (« hidden, dormant, or undocumented features »).

En contrepartie, le risque APNs que l'audit supposait en § 5.1 (token
production envoyé au sandbox, notification jetée silencieusement) est sans
objet : il n'y a pas d'APNs. Un item de moins, un plus sérieux à la place.

La décision est produit avant d'être technique : brancher la chaîne APNs, ou
assumer ntfy et retirer plugin + entitlement + la ligne du README. L'état
actuel est le seul qui cumule les inconvénients des deux.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Bettinelli
2026-09-22 06:58:17 +00:00
parent b1e7cf6d47
commit a29569c05c

View File

@@ -238,10 +238,46 @@ procédure de vérification, et c'est la seule qui conclut :
> Organizer → archive → Distribute/Validate → feuille Summary → dépliant
> **Binary and Entitlements** → lire la valeur réelle dans le binaire signé.
**Le vrai risque est ailleurs, et il est côté backend** : un token production
envoyé vers `api.sandbox.push.apple.com` (ou l'inverse) est traité comme
invalide et **la notification est jetée silencieusement** (TN2265). À vérifier
dans `web/push_notify.py`.
**Le risque APNs supposé est sans objet [vérifié le 2026-09-22]** : il n'y a
pas d'APNs. `web/push_notify.py` envoie via **ntfy**, en utilisant le `token`
du device comme *nom de topic*. L'en-tête du fichier annonce « V2+ : remplacer
par APNs (iOS) + FCM (Android) » — ce n'est pas fait. Voir §5.1bis, qui est le
vrai sujet.
### 5.1bis [vérifié] La chaîne de notifications push natives n'existe pas de bout en bout
Trois constats, chacun vérifié par recherche dans les deux dépôts :
1. `web/push_notify.py:47-52` — le canal est **ntfy**. `platform == "web"`
rend `False` (« Web Push : à implémenter (V2) »).
2. **Aucun enregistrement de token APNs côté serveur.** Recherche de
`registerToken` / `/api/devices` / `device_token` dans `web/` : **zéro
résultat**.
3. **Le web n'appelle jamais `PushNotifications`** de Capacitor. Recherche dans
`web/**/*.js` et `web/**/*.html` : **zéro résultat**.
Côté natif, tout est pourtant en place : `@capacitor/push-notifications` est
installé, `aps-environment` est déclaré, `UIBackgroundModes` contient
`remote-notification`. **La moitié native est prête et personne ne la branche.**
Pour recevoir un rappel, l'utilisateur doit installer l'app **ntfy** et
s'abonner à un topic — ce n'est pas une notification de l'app.
Deux conséquences :
- **Le README se trompe.** Il liste « ✅ Push notifications natives (rappel
séances) — implémenté côté iOS » **dans la section anti-rejet Guideline
4.2**. C'est le premier argument de la liste, et il ne tient pas : un
examinateur qui teste les rappels ne verra rien. Or 4.2 est précisément le
risque de cette architecture wrapper (§5.3).
- **Une capability déclarée et inutilisée** est au mieux inerte. Apple 2.3.1(a) :
« Don't include any hidden, dormant, or undocumented features in your app ».
**Décision à prendre**, et elle est produit avant d'être technique : soit
brancher la chaîne APNs (demande de permission + récupération du token côté
web, endpoint d'enregistrement, envoi via APNs côté serveur), soit assumer ntfy
et **retirer le plugin, l'entitlement et la ligne du README**. La situation
actuelle — déclarer une capability qu'on n'utilise pas et l'annoncer comme
implémentée — est la seule qui cumule les inconvénients des deux.
### 5.2 [doc] Ce qu'Apple exige, et où on en est
@@ -431,8 +467,11 @@ Par honnêteté sur la couverture :
la validation Play Console reste en attente.
- **Le backend** (`coach_sportif/web`) n'a été audité que sur l'ergonomie et
deux points de conformité. Ni sécurité serveur, ni justesse des formules.
- **`web/push_notify.py`** n'a pas été lu — c'est pourtant là que se joue le
risque APNs de §5.1.
- **Le contenu de la politique de confidentialité** n'a pas été relu contre les
trois exigences de 5.1.1(i) — son existence a été vérifiée, pas son contenu.
*(`web/push_notify.py` a été lu après coup : voir §5.1bis, qui remplace le
risque APNs initialement supposé.)*
---
@@ -465,8 +504,10 @@ chiffre mort :**
**Avant soumission :**
9. Vérifier `aps-environment` dans le Summary de l'archive **et** l'endpoint
APNs du backend (§5.1).
9. **Trancher la question des push (§5.1bis)** — brancher APNs, ou assumer ntfy
et retirer plugin + entitlement + la ligne du README. C'est une décision
produit, et elle conditionne l'argument anti-4.2. Puis vérifier
`aps-environment` dans le Summary de l'archive (§5.1).
10. Nutrition labels, Notes for Review nommant les fonctions natives, compte de
démo avec backend allumé (§5.2).