Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible de générer l'attestation en hors ligne. #118

Open
arnaudsav opened this issue Nov 3, 2020 · 12 comments
Open

Impossible de générer l'attestation en hors ligne. #118

arnaudsav opened this issue Nov 3, 2020 · 12 comments

Comments

@arnaudsav
Copy link

Bonjour à tous,

Une fois la page chargée, il semble impossible de générer le PDF (incluant le QR code) en mode avion, le fichier ne se génère qu'en présence d'une connexion internet.

Problème constaté sur plusieurs équipements: Pixel4a/Chrone, un W10/Edge, un W10/Opera, un Macbookpro/Safari

J'ai remarqué qu'une trentaine de paquets TCP/TLS1.3 sont échangés entre mon PC et une adresse IP publique dans le cadre de la génération de ce fichier d'attestation.

En mode debug j'ai un le comportement suivant:
pdf-util.js:45 GET https://media.interieur.gouv.fr/deplacement-covid-19/certificate.d1673940.pdf net::ERR_INTERNET_DISCONNECTED
(anonymous) @ pdf-util.js:45
f @ runtime.js:63
(anonymous) @ runtime.js:293
(anonymous) @ runtime.js:118
n @ asyncToGenerator.js:3
c @ asyncToGenerator.js:25
(anonymous) @ asyncToGenerator.js:32

Merci par avance pour votre éclaircissement

@a2br
Copy link

a2br commented Nov 3, 2020

Bonjour,
En commençant à lire ton message j'ai été surpris mais quand tu as donné l'erreur, ça a pris sens : une requête HTTP devait être faite pour télécharger le fichier (GET {URL} ...) Par conséquent, il y avait besoin d'une connexion Internet. Je regarderai le problème de plus près quand je pourrai, c'est peut être possible de télécharger un PDF sans connexion. À priori, le PDF est généré localement, pas sur le serveur...

@maximebochon
Copy link

maximebochon commented Nov 3, 2020

Le principe de création du PDF est de partir d'un PDF de formulaire vierge et d'y placer les informations saisies par l'utilisateur ainsi que le QR-Code. Ces opérations sont faites côté client (dans le navigateur) grâce à une bibliothèque JavaScript de manipulation de PDF.

La génération est donc bien réalisée côté client, donc pas d'appel au serveur pour la génération en tant que telle, mais comme celle-ci s'appuie sur un fichier PDF "modèle", ce dernier est récupéré préalablement, juste avant la génération, via une requête GET.

Voici le fichier en question : https://github.com/LAB-MI/attestation-deplacement-derogatoire-q4-2020/blob/main/src/certificate.pdf

Techniquement il semble possible de générer le PDF entièrement sans s'appuyer sur un fichier "modèle". Il faudrait construire chaque bloc de texte, chaque case à cocher, etc... Ce serait d'ailleurs plus rassurant d'un point de vue sécurité que de reposer sur une ressource binaire dont l'origine n'est pas le fruit d'une compilation du code source.

Il doit également être possible d'embarquer le PDF sous forme binaire dans le code source dans le but d'un fonctionnement hors connexion, même si ce n'est pas très élégant. Une autre solution assez proche peut consister à stocker au chargement de la page le PDF "modèle" dans le "LocalStorage" du navigateur qui servira alors de "cache".

Cependant il faut garder à l'esprit que l'application peut évoluer et le mode hors connexion pourrait conduire l'utilisateur à produire un document qui n'est plus à jour par rapport aux attentes du gouvernement.

@arnaudsav
Copy link
Author

Bonjour Maxime, merci beaucoup pour votre retour ultra complet. J’apprécie vraiment le temps que vous y avez consacré.
C'est en effet plus clair et je comprend bien mieux le cheminement du script.

Cependant il y a quelque chose que je ne comprend pas: une fois sur a page, certains utilisateurs arrivent à générer le PDF en mode hors connexion. C'est donc lié au fait qu'ils ont le fichier PDF "modèle" en cache ?

Ce qui est étrange c'est que durant le premier confinement j'étais capable de générer le fichier PDF (une fois la page web chargée préalablement) en étant hors ligne + en navigation privée. Normalement en navigation privée il n'y a pas de cache.
Il y a t'il quelque chose qui a changé dans le script depuis ce temps ?

@nyroDev
Copy link

nyroDev commented Nov 3, 2020

Le fichier pdf vierge n'est chargé qu'une seule fois, lors de la première génération.

Il est ensuite mis en cache (via l'api cache).

Normalement (je ne peux pas tester tout de suite), tout fonctionne 100% hors ligne.

Il y avait un bug qui empêchait le hors ligne de fonctionner, je ne sais pas si la correction #93 a été mise en ligne.

@maximebochon
Copy link

Si un mécanisme de cache est déjà en place sur le PDF "modèle", le plus simple est peut-être de déplacer le chargement du PDF dès le chargement de la page.

(Cela aura en plus l'avantage de lever toute suspicion concernant l'échange HTTP qui a actuellement lieu au moment de la génération de l'attestation.)

@arnaudsav
Copy link
Author

arnaudsav commented Nov 4, 2020

Bonjour Maxime, oui cela aurait plus de sens de pouvoir faire en sorte que le PDF "modèle" soit chargé dés le chargement de la page et non pas au moment de la génération du PDF.
Car en effet il y a un échange HTTP au moment de la génération du PDF. Comme cet échange est crypté en TLS1.3 on ne sait pas exactement ce qu'il s'y passe.
Est-ce quelque chose qui peut-être modifié directement sur la version actuellement utilisée ? Qui peut prendre cette décision et comment demander ces modifs ?

@maximebochon
Copy link

maximebochon commented Nov 4, 2020

@arnaudsav Le chiffrement de l'échange est une bonne chose, c'est standard à l'heure actuelle de fonctionner en HTTPS. Pour autant cela ne doit pas vous empêcher de savoir exactement ce qui se passe : par exemple dans Chrome, la touche F12 permet d'accéder aux outils de développement et l'onglet Network tracera tous les échanges HTTP qui seront affichés en clair. Cet outil destiné au débogage est disponible dans la plupart des navigateurs modernes.

Je ne suis pas mainteneur de ce projet, je me contente pour l'instant de suivre et de réagir aux sujets. Voici la page de l'équipe officielle : https://github.com/orgs/LAB-MI/people

De ce que j'ai vu dans le code source actuel, c'est assez subtile ce qui se passe. Le PDF "modèle" est chargé non pas par un GET explicite mais par un import JavaScript comme s'il s'agissait d'une dépendance : import pdfBase from '../certificate.pdf'

Donc en théorie le chargement pourrait avoir lieu au chargement de la page. Mon interprétation sur le fait que ça n'a pas lieu est que le moteur d'exécution JavaScript, dans de nombreux navigateurs, retarde cet import au moment de l'utilisation effective de pdfBase, pour des raisons de performance et d'économie de bande passante, ce qui en soit est une bonne chose.

Mais il doit exister une astuce pour forcer cet import au chargement de la page. Je regarderai ce point ce weekend si personne n'a fait de proposition de correctif d'ici là.

@arnaudsav
Copy link
Author

@maximebochon
Merci pour ce suivi, tenez nous au courant.

@a2br
Copy link

a2br commented Nov 4, 2020

@maximebochon je ne suis pas sûr de ce que je dis, mais remplacer

import pdfBase from '../certificate.pdf'

par

const pdfBase = fs.readFileSync('src/certificate.pdf')

devrait peut-être régler le problème. Je ferai sans doute des tests plus tard.
Edit: ne faites pas attention à l'edit, j'ai l'habitude d'importer des JSON, pas des PDF x)

@arnaudsav
Copy link
Author

arnaudsav commented Nov 4, 2020

Apparemment le problème semble être résolu.
Maintenant quand je me connecte sur la page https://media.interieur.gouv.fr/deplacement-covid-19/ on me dis qu'il y a une nouvelle mise à jour de disponible
image
En cliquant dessus la page est rechargée. On peut alors se mettre alors en mode avion puis générer l'attestation.
Le PDF est donc préchargé préalablement

Quelque chose a été modifié depuis tout à l'heure ? Si c'est le cas chapeau les développeurs pour votre réactivité !!

@a2br
Copy link

a2br commented Nov 4, 2020

Je ne sais pas vraiment crois que c'est juste un message pour vider le cache :'> désolé de te décevoir
J'en trouve souvent quand j'ouvre mon fork dans le navigateur

@arnaudsav
Copy link
Author

En tout cas lorsqu'on clique sur le bouton "mettre à jour" le comportement est différent et ce sur tout mes équipements (smartphone, PC etc..)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants