feat(inbox): un utilisateur a DEUX inboxes, comme en amont
Tranché par la cascade plutôt qu'en attendant une réponse : le niveau 3 (ORM) ne dit rien des inbox, le niveau 2 non plus — `@ng-org/web` n'expose aucune méthode contenant « inbox » et la session n'en publie aucune. C'est donc le modèle du moteur qui décide, et il dit DEUX : un site porte une inbox sur son repo de store public et une autre sur son protégé (`engine/verifier/src/site.rs:127-152`), les seuls `AddInboxCap` du moteur, `new_store_default` n'en posant une que `if !private`. Elles sont adressées séparément jusque dans les enregistrements de contact, qui choisissent leur prédicat selon le profil visé — `ng:site_inbox` pour un profil public, `ng:protected_inbox` sinon (`engine/verifier/src/inbox_processor.rs:787,823-824`). `userInbox(id)` en exposait une : une cardinalité que cette bibliothèque avait inventée, et que le nom `walletInbox` avait contribué à masquer. Elle prend désormais le scope, et le store PRIVÉ n'en a pas — d'où `InboxScope` plutôt que `Scope` : demander l'inbox privée n'est pas une recherche qui ne rend rien, c'est une question sans référent dans le modèle, et le type l'interdit. `myInboxes` énumère les deux, `isOwnInbox` reconnaît les deux. Le shim garde un triple par (user, scope). 160 tests unitaires, typecheck src/test/e2e vert, e2e 40/40 contre le broker.
This commit is contained in:
@@ -228,7 +228,7 @@ test("(a) sharing one document's cap to ONE inbox reveals it there, and only the
|
||||
|
||||
// The app decides alice↔bob are related: alice shares ONE document's cap into
|
||||
// bob's OWN inbox — the only cross-wallet act there is.
|
||||
const bobInbox = await userInbox("bob");
|
||||
const bobInbox = await userInbox("bob", "protected");
|
||||
setCurrentUser("alice");
|
||||
await shareCap(capFor(shared)!, bobInbox);
|
||||
|
||||
@@ -239,7 +239,7 @@ test("(a) sharing one document's cap to ONE inbox reveals it there, and only the
|
||||
|
||||
// carol, who was not shared with, still reads nothing.
|
||||
setCurrentUser("carol");
|
||||
await readInbox(await userInbox("carol"));
|
||||
await readInbox(await userInbox("carol", "protected"));
|
||||
expect(view(items)).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -247,7 +247,7 @@ test("a cap deposit is absorbed, not surfaced as a consumer deposit", async () =
|
||||
inject();
|
||||
setCurrentUser("alice");
|
||||
const doc = await createEntityDoc("alice", "protected");
|
||||
const bobInbox = await userInbox("bob");
|
||||
const bobInbox = await userInbox("bob", "protected");
|
||||
await shareCap(capFor(doc)!, bobInbox);
|
||||
|
||||
setCurrentUser("bob");
|
||||
@@ -320,7 +320,7 @@ test("an inbox may be DEPOSITED into by anyone, and READ only by its owner", asy
|
||||
inject();
|
||||
setCurrentUser("alice");
|
||||
const secret = await createEntityDoc("alice", "protected");
|
||||
const bobInbox = await userInbox("bob");
|
||||
const bobInbox = await userInbox("bob", "protected");
|
||||
|
||||
// Alice deposits into bob's inbox — allowed, and it grants her nothing back.
|
||||
await shareCap(capFor(secret)!, bobInbox);
|
||||
|
||||
Reference in New Issue
Block a user