ADR 0105 – Favori « Envoyer vers l'inbox »
Accepté (2026-10-17, vague 3 du document d'idées)
ADR 0105 – Favori « Envoyer vers l’inbox »
Statut : Accepté (2026-10-17, vague 3 du document d’idées)
Capturer une page web depuis un ordinateur demandait de copier son adresse puis d’ouvrir la capture. Sur mobile, le partage vers l’application installée existe (ADR 0034) ; sur ordinateur, il manquait l’équivalent : un favori qui envoie la page ouverte.
Décision
- Un favori
javascript:sans secret ni appel inter-sites. Il litlocation.href,document.titleet la sélection (bornés à 2 000, 300 et 2 000 caractères), puis ouvre une petite fenêtre de l’application :/capture/bookmarklet?url=…&title=…&text=…. Si le navigateur bloque la fenêtre, la page courante est remplacée par celle de l’application. Aucune requête n’est faite vers l’API depuis le site visité : pas de CORS à ouvrir, pas de jeton dans le favori. - La page de l’application confirme, puis écrit.
BookmarkletPage(features/capture/) montre le titre, l’adresse et le passage, et ne crée le nœud d’inbox qu’au clic « Ajouter à l’inbox », parPOST /api/nodes(inbox: true) avec la session et le jeton CSRF habituels : aucune nouvelle route serveur. Tout site peut ouvrir cette page avec des paramètres de son choix, d’où la confirmation (même raison que pourshare_target, ADR 0034). - Contrôles des paramètres (
core/capture/bookmarklet.ts) : seule une adressehttp/httpssans identifiants est retenue (jamaisjavascript:,data:,file:), caractères de contrôle retirés, longueurs bornées. Sans adresse valide, la page affiche l’explication et rien n’est écrit. - Réutilisation de l’existant. La note se compose comme un partage (
sharedNote, ADR 0034) : titre de la page (sinon l’adresse), corps = passage cité en Markdown (> …) puis adresse. Le titre vient du navigateur : le service de titre des liens (ADR 0075, appel sortant du serveur) n’est pas sollicité. Le favori ne passe pas par leshare_targetde la PWA, qui exige l’application installée et un POST géré par le service worker. - Installation. La page
/capture/bookmarkletexplique et montre le favori à glisser (lienjavascript:marqué sûr pour Angular, uniquement celui que nous produisons), avec le code à copier si le glisser-déposer n’est pas possible. Accès par la palette (« Aller à : Favori… ») et une carte de la page Données. Le favori est lié à l’origine de l’application au moment de l’installation.
Alternatives écartées
fetchdu favori vers/api/nodes: exigerait CORS avec cookies depuis n’importe quel site, un jeton CSRF lisible par la page visitée et un secret dans le favori. Rejeté.- Jeton d’API dédié dans le favori : un secret à garder, révoquer et faire tourner, pour un gain faible.
- Écriture automatique à l’ouverture de la fenêtre : n’importe quel site pourrait remplir l’inbox à l’insu de l’utilisateur.
- Extension de navigateur : une autre chaîne de publication, hors périmètre.
Limites connues
- Un site dont la politique de sécurité (CSP) interdit les favoris
javascript:ne peut pas être capturé ainsi ; la page le dit et renvoie vers le partage ou la capture d’une adresse. - Il faut être connecté dans ce navigateur ; sans session, l’écriture échoue et l’erreur est affichée dans la fenêtre.
- La sélection est le texte brut (pas la mise en forme), limité à 2 000 caractères.
Corrections de la revue
- Le code du favori borne chaque valeur sans couper une paire de substitution : un émoji à la limite de longueur faisait lever
URIErroràencodeURIComponent(le demi-caractère final est retiré après chaqueslice). Test avec un émoji à la limite. - La page ouverte par le favori met
window.opener = null: le site d’origine ne garde aucun lien vers la fenêtre de l’application. - Un clic (ou Entrée) sur le bouton d’installation, au lieu de le glisser, affiche « glissez ce bouton dans la barre de favoris ».