refactor(api): l'application ne nomme plus son identité — elle l'apprend
Lot C de la revue adverse. Cinq corrections, dont une qui change la forme de la surface. **L'application ne pouvait pas obtenir son identité par l'API.** `ensureIdentity()` rendait `void`, `getCurrentUser` n'est plus publié — et pourtant `createEntityDoc(id, …)` et `listMyEntityDocs(id, …)` l'exigeaient. L'app d'exemple s'en sortait en lisant `localStorage["ng-eventually:identity"]` et le paramètre `?ng-id`, deux constantes PRIVÉES du portail d'accès. Une frontière qu'aucun consommateur ne devrait voir, et encore moins dont il devrait dépendre. Vérifié au niveau 2 avant de trancher : `session_start(wallet_name, user_id)` prend l'identité — donc en amont l'application la DÉTIENT, elle la tient du portefeuille qu'elle a ouvert. Ici c'est le portail qui la choisit, donc c'est au portail de la rendre. Deux changements, tous deux vers la cible : - `ensureIdentity()` rend l'identité qu'il a établie ; - `createEntityDoc(scope)`, `listMyEntityDocs(scope)`, `resolveWriteGraph(scope)` perdent leur paramètre d'identité. En amont `doc_create(session_id, …)` ne porte aucun utilisateur : une session EST celle d'un utilisateur. Passer la sienne à chaque appel de placement était un geste sans successeur. L'application garde l'identité pour l'afficher, et ne la passe plus à rien. **`inbox.share` provisionnait un destinataire inexistant.** Une faute de frappe créait les trois stores et l'inbox de ce nom, et la clé atterrissait où personne ne regarde — sans la moindre erreur. En amont on ne peut pas viser un nom qu'on invente : un dépôt est scellé vers une clé d'inbox qui vous est parvenue par un contact entrant. Refuser est fidèle ; provisionner était l'invention. **`createEntityDoc` avalait l'échec de ses deux écritures** et rendait quand même une référence — le document n'était dans aucun store, donc la session suivante ne le listait pas et sa lecture rendait vide, en silence. Il lève maintenant, comme `doc_create` en amont propage les siennes. **Deux entrées prenaient `Nuri` au lieu de `NuriLike`** (`inbox.watch`, `openDocumentInbox`), ce qui contredisait la raison même pour laquelle aucune garde de type n'est publiée. Et **deux messages d'erreur nommaient des symboles retirés** (`storeRegistry.documentInboxAddress`, `setCurrentUser`) : une erreur qui envoie vers une fonction inexistante est pire qu'une erreur muette. Contrat d'API et feuille `contract_sdk-surface` mis à jour ; `readForDocument` et le refus de `share` obtiennent enfin leur règle en §9. 189 tests unitaires, e2e 40/40 et applicatif 12/12.
This commit is contained in:
@@ -515,16 +515,16 @@ const identity = new IdentityStore(
|
||||
// and the caps of what you create are filed under the identity you were acting
|
||||
// as. Creating B's document while connected as A is not a thing the model has.
|
||||
setCurrentUser(idA);
|
||||
const dA1 = await storeRegistry.createEntityDoc(idA, "public");
|
||||
const dA2 = await storeRegistry.createEntityDoc(idA, "public");
|
||||
const dA1 = await storeRegistry.createEntityDoc("public");
|
||||
const dA2 = await storeRegistry.createEntityDoc("public");
|
||||
setCurrentUser(idB);
|
||||
const dB1 = await storeRegistry.createEntityDoc(idB, "public");
|
||||
const dB1 = await storeRegistry.createEntityDoc("public");
|
||||
// listMyEntityDocs(A) → only A's docs (poll: the index append can lag).
|
||||
setCurrentUser(idA);
|
||||
let listA: string[] = [];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
registryInternals.resetRegistryCache();
|
||||
listA = await storeRegistry.listMyEntityDocs(idA, "public");
|
||||
listA = await storeRegistry.listMyEntityDocs("public");
|
||||
if (listA.includes(dA1) && listA.includes(dA2)) break;
|
||||
await new Promise((r) => setTimeout(r, 1000));
|
||||
}
|
||||
@@ -556,7 +556,7 @@ const identity = new IdentityStore(
|
||||
// document is filed under nobody and the very session that created it is
|
||||
// refused the write below.
|
||||
setCurrentUser(id);
|
||||
const entityNuri = await storeRegistry.createEntityDoc(id, scope);
|
||||
const entityNuri = await storeRegistry.createEntityDoc(scope);
|
||||
const marker = "recon-" + Date.now();
|
||||
await docs.sparqlUpdate(
|
||||
s.session_id,
|
||||
@@ -569,7 +569,7 @@ const identity = new IdentityStore(
|
||||
let listed: string[] = [];
|
||||
for (let i = 0; i < 15; i++) {
|
||||
registryInternals.resetRegistryCache();
|
||||
listed = await storeRegistry.listMyEntityDocs(id, scope);
|
||||
listed = await storeRegistry.listMyEntityDocs(scope);
|
||||
if (listed.includes(entityNuri)) break;
|
||||
await new Promise((r) => setTimeout(r, 1000));
|
||||
}
|
||||
@@ -595,7 +595,7 @@ const identity = new IdentityStore(
|
||||
await connectedUser();
|
||||
|
||||
registryInternals.resetRegistryCache();
|
||||
const listed = await storeRegistry.listMyEntityDocs(id, scope);
|
||||
const listed = await storeRegistry.listMyEntityDocs(scope);
|
||||
// DIAGNOSTIC: a RAW anchored read of the entity doc with NO open — reports how
|
||||
// many rows the bare anchored query resolves for a not-yet-opened repo (the
|
||||
// premise: 0 until opened). Uses the low-level docs primitive directly, bypassing
|
||||
@@ -731,7 +731,7 @@ const identity = new IdentityStore(
|
||||
registryInternals.resetRegistryCache();
|
||||
const id = "@ws-" + handle;
|
||||
setCurrentUser(id);
|
||||
const doc = await storeRegistry.createEntityDoc(id, "protected");
|
||||
const doc = await storeRegistry.createEntityDoc("protected");
|
||||
const s = await sessionReady;
|
||||
// Seed the entity doc with the shape's type + a title (anchored default graph).
|
||||
await docs.sparqlUpdate(
|
||||
@@ -742,7 +742,7 @@ const identity = new IdentityStore(
|
||||
// Wait until this session sees the index append (data persisted on the broker).
|
||||
for (let i = 0; i < 15; i++) {
|
||||
registryInternals.resetRegistryCache();
|
||||
const listed = await storeRegistry.listMyEntityDocs(id, "protected");
|
||||
const listed = await storeRegistry.listMyEntityDocs("protected");
|
||||
if (listed.includes(doc)) break;
|
||||
await new Promise((r) => setTimeout(r, 1000));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user