fix(auth): préremplir l'identifiant à la barrière — plus de re-saisie à l'arrivée
Symptôme (vraie app) : au retour dans Festipod, la barrière redemandait un
identifiant NU et VIDE alors qu'il était déjà choisi/stocké.
Cause racine (pas une perte de localStorage — l'identifiant survit au round-trip) :
au rechargement, AccountProvider restaure `username` depuis le store, mais
NextGraphContext repart en `disconnected`, donc AuthGate réaffiche la barrière ;
et AccessGateScreen initialisait son champ à useState('') → vide malgré le stocké.
Fix : AuthGate passe `initialIdentifier={username}` ; AccessGateScreen préremplit
le champ. L'identifiant est saisi UNE FOIS au premier accès, persisté, puis
prérempli au retour — jamais retapé.
Test garde-fou @ui (barriere-acces-identifiant.feature) : prérempli / vide au
premier accès / Entrer remonte la valeur. Rouge si on remet useState(''). Utile
car le flux de barrière est désactivé en @e2e (__FESTIPOD_ACCESS_GATE_DISABLED__),
donc invisible à cette couche. renderElement() ajouté au harness @ui pour rendre
un composant prop-driven hors registre/providers.
Doctrine: app-security/knowledge_authentication documente la saisie-unique + prérempli.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,37 @@ export async function renderScreen(screenId: string, path?: string): Promise<Doc
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an arbitrary React element (a prop-driven component) into the same
|
||||
* happy-dom container. Unlike {@link renderScreen}, this does NOT go through the
|
||||
* screen registry or wrap in the data/router providers — use it for standalone,
|
||||
* prop-driven components such as the AccessGateScreen (the access barrier), which
|
||||
* take their state as props rather than reading it from context. Returns the
|
||||
* rendered document for DOM assertions.
|
||||
*/
|
||||
export async function renderElement(element: React.ReactElement): Promise<Document> {
|
||||
await ensureDomGlobals();
|
||||
if (!window) throw new Error('DOM globals not installed');
|
||||
|
||||
if (root) {
|
||||
root.unmount();
|
||||
root = null;
|
||||
}
|
||||
|
||||
const doc = window.document as unknown as Document;
|
||||
doc.body.innerHTML = '<div id="root"></div>';
|
||||
const container = doc.getElementById('root')!;
|
||||
|
||||
root = createRoot(container);
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
root.render(element);
|
||||
setTimeout(resolve, 0);
|
||||
});
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a registry path with `:id` placeholders to a concrete URL using the
|
||||
* first seed event/user when applicable. Tests can override via the explicit
|
||||
|
||||
Reference in New Issue
Block a user