fix: la barrière s'affiche à chaque chargement en page de tête, comme chez Festipod

Notre version décidait d'afficher la barrière sur la présence de l'identifiant.
Festipod décidait sur la session — jamais établie en page de tête, donc l'écran
s'affichait toujours, l'identifiant servant seulement à pré-remplir le champ.

La différence n'est pas ergonomique. L'identifiant est un état qu'on observe ;
le portefeuille, lui, vit dans le stockage d'une autre origine et nous est
illisible. Un écran conditionnel doit donc DEVINER cet état invisible — et
quand il devine « déjà installé » alors que le portefeuille a disparu du
navigateur, il cache les seuls contrôles qui répareraient la situation et
précipite la personne dans une impasse.

Impasse observée sur le site réel : sans portefeuille, la page du broker affiche
un texte statique, zéro bouton, un seul lien vers nextgraph.eu qui NE TRANSPORTE
AUCUN retour vers l'application. Le retour arrière du navigateur est la seule
issue — et il ne sert à rien si la barrière ne reprend pas la personne à
l'arrivée.

Le discriminant devient le cadre, pas l'identifiant : page de tête → toujours,
iframe → on s'efface. C'est le signal que @ng-org/web utilise lui-même et que
Festipod utilisait un étage plus bas.

On ne détecte rien et on ne demande rien. Les trois étapes s'affichent toujours ;
qui possède déjà son portefeuille ignore les deux premières. Aucune case « je
l'ai déjà » : savoir si l'on a importé un portefeuille dans ce navigateur est
une question trop technique pour être posée.

Garde-fou repris de Festipod, qu'on n'avait pas : après un aller-retour vers
l'onglet NextGraph et un retour arrière, la barrière restait figée sur un bouton
mort. Elle recharge désormais sur pageshow persisted — seul moyen de rejouer le
init() qui porte la redirection.

Vérifié sur navigateur : cliquer « Import a Wallet File » ouvre un sélecteur sur
place, sans navigation ni changement d'onglet, et notre onglet ne reçoit AUCUN
signal quand l'import réussit. Détecter le retour est donc impossible, pas
seulement fragile.
This commit is contained in:
Sylvain Duchesne
2026-08-12 14:59:10 +02:00
parent c5b4703687
commit f5a3adc385
9 changed files with 621 additions and 65 deletions
+7 -3
View File
@@ -203,9 +203,13 @@ async function main(): Promise<void> {
`shown=${r.shown} disabledWhenEmpty=${r.disabledWhenEmpty} identity=${r.identity} stillMounted=${r.stillMounted}`,
);
});
await step("the gate stays away when the identity is already known", async () => {
const r = await sdk<any>(frame, "accessGateReturningVisit", "erin");
check("no barrier for a returning user", r.shown === false && r.identity === "erin", `shown=${r.shown}`);
// This harness page runs INSIDE the broker iframe — which is the whole of what makes
// the check below true. Top-level the barrier shows on every load, known identity or
// not, because a top-level page is one redirect away from a dead end for anyone whose
// browser has no wallet. The applicative suite walks that side (`e2e/notebook.ts`).
await step("past the round-trip, a known identity stands the barrier down", async () => {
const r = await sdk<any>(frame, "accessGateIdentityAlreadyKnown", "erin");
check("no barrier inside the broker iframe once the identity is known", r.shown === false && r.identity === "erin", `shown=${r.shown}`);
});
// ── docs primitives ─────────────────────────────────────────────────────