First capability-securable implementation of Dataspaces.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.7 KiB

4 months ago
  1. import {
  2. $claimNick,
  3. $joinedUser,
  4. $says,
  5. $user,
  6. Join,
  7. NickConflict,
  8. UserId,
  9. UserInfo,
  10. asNickClaim,
  11. fromJoin,
  12. fromNickConflict,
  13. fromUserInfo,
  14. } from "../gen/secure-chat-protocol.js";
  15. import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js";
  16. import { observe, during, $Observe, asObserve, Dataspace } from "../runtime/dataspace.js";
  17. import { attenuate, rfilter, pRec, pEmbedded, pString, pLit } from "../runtime/rewrite.js";
  18. import { attenuate as sturdyAttenuate, KEY_LENGTH, sturdyEncode, fromSturdyRef, mint } from "../transport/sturdy.js";
  19. import { Bind, fromBind } from "../gen/gatekeeper.js";
  20. import { Bytes, Embedded } from "@preserves/core";
  21. export default function (t: Turn, gatekeeperDs_ptr: Embedded<Ref>) {
  22. const gatekeeperDs = gatekeeperDs_ptr.embeddedValue;
  23. const ds = t.ref(new Dataspace());
  24. const chatOid = 'chat';
  25. const chatKey = new Bytes(KEY_LENGTH);
  26. t.assert(gatekeeperDs, fromBind(Bind({ oid: chatOid, key: chatKey, target: ds })));
  27. mint(chatOid, chatKey).then(async r => {
  28. r = await sturdyAttenuate(r, rfilter(pRec($Observe, pLit($joinedUser), pEmbedded())));
  29. console.log(fromSturdyRef(r).asPreservesText());
  30. console.log(sturdyEncode(fromSturdyRef(r)).toHex());
  31. });
  32. const nicks = new Map<string, UserId>();
  33. let nextUserId: UserId = 0;
  34. observe(t, ds, $Observe, during(async (t, o0) => {
  35. const o = asObserve(o0);
  36. if (o.label !== $joinedUser) return null;
  37. const uid: UserId = nextUserId++;
  38. const f = t.facet(t => {
  39. t.assert(o.observer, fromJoin(Join({
  40. uid,
  41. handle: attenuate(ds, rfilter(
  42. pRec($Observe, pLit($user), pEmbedded()),
  43. pRec($Observe, pLit($says), pEmbedded()),
  44. pRec($claimNick, pLit(uid), pString(), pEmbedded()),
  45. pRec($says, pLit(uid), pString()))),
  46. })));
  47. let infoHandle: Handle | undefined;
  48. let nick: string | undefined;
  49. observe(t, ds, $claimNick, {
  50. assert(t: Turn, c0: Assertion): void {
  51. const c = asNickClaim(c0);
  52. if (c.uid !== uid) return;
  53. if (nicks.has(c.name)) {
  54. t.message(c.k, fromNickConflict(NickConflict()));
  55. } else {
  56. t.message(c.k, true);
  57. if (nick !== void 0) nicks.delete(nick);
  58. infoHandle = t.replace(ds, infoHandle, fromUserInfo(UserInfo(c)));
  59. nick = c.name;
  60. nicks.set(nick, uid);
  61. }
  62. }
  63. });
  64. });
  65. return t => t.stop(f);
  66. }));
  67. }