Introduce coValue nicknames and change how agentIDs work

This commit is contained in:
Anselm
2023-08-07 17:52:58 +01:00
parent f07ec976c9
commit 8578d0f2fc
8 changed files with 161 additions and 100 deletions

View File

@@ -10,7 +10,7 @@ import { LocalNode } from "./node";
import { sign } from "./crypto";
test("Can create coValue with new agent credentials and add transaction to it", () => {
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -48,9 +48,8 @@ test("Can create coValue with new agent credentials and add transaction to it",
});
test("transactions with wrong signature are rejected", () => {
const agent = newRandomAgentCredential();
const wrongAgent = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential();
const wrongAgent = newRandomAgentCredential("wrongAgent");
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -88,8 +87,7 @@ test("transactions with wrong signature are rejected", () => {
});
test("transactions with correctly signed, but wrong hash are rejected", () => {
const agent = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -131,7 +129,7 @@ test("transactions with correctly signed, but wrong hash are rejected", () => {
node.ownSessionID,
[transaction],
expectedNewHash,
sign(agent.signatorySecret, expectedNewHash)
sign(agentCredential.signatorySecret, expectedNewHash)
)
).toBe(false);
});

View File

@@ -33,27 +33,32 @@ import {
import { LocalNode } from "./node";
import { CoValueKnownState, NewContentMessage } from "./sync";
export type RawCoValueID = `coval_${string}`;
export type RawCoValueID = `co_z${string}` | `co_${string}_z${string}`;
export type CoValueHeader = {
type: ContentType["type"];
ruleset: RulesetDef;
meta: JsonValue;
publicNickname?: string;
};
function coValueIDforHeader(header: CoValueHeader): RawCoValueID {
const hash = shortHash(header);
return `coval_${hash.slice("shortHash_".length)}`;
if (header.publicNickname) {
return `co_${header.publicNickname}_z${hash.slice("shortHash_z".length)}`;
} else {
return `co_z${hash.slice("shortHash_z".length)}`;
}
}
export type SessionID = `session_${string}_${AgentID}`;
export type SessionID = `${AgentID}_session_z${string}`;
export function agentIDfromSessionID(sessionID: SessionID): AgentID {
return `agent_${sessionID.substring(sessionID.lastIndexOf("_") + 1)}`;
return sessionID.split("_session")[0] as AgentID;
}
export function newRandomSessionID(agentID: AgentID): SessionID {
return `session_${base58.encode(randomBytes(8))}_${agentID}`;
return `${agentID}_session_z${base58.encode(randomBytes(8))}`;
}
type SessionLog = {
@@ -482,25 +487,26 @@ export class CoValue {
return this.header.ruleset.type === "team"
? expectTeamContent(this.getCurrentContent())
.keys()
.filter((k): k is AgentID => k.startsWith("agent_"))
.map((agent) => agentIDAsCoValueID(agent))
.filter((k): k is AgentID => k.startsWith("co_agent"))
: this.header.ruleset.type === "ownedByTeam"
? [this.header.ruleset.team]
: [];
}
}
export type AgentID = `agent_${string}`;
export type AgentID = `co_agent${string}_z${string}`;
export type Agent = {
signatoryID: SignatoryID;
recipientID: RecipientID;
publicNickname?: string;
};
export function getAgent(agentCredential: AgentCredential) {
return {
signatoryID: getSignatoryID(agentCredential.signatorySecret),
recipientID: getRecipientID(agentCredential.recipientSecret),
publicNickname: agentCredential.publicNickname,
};
}
@@ -513,28 +519,24 @@ export function getAgentCoValueHeader(agent: Agent): CoValueHeader {
initialRecipientID: agent.recipientID,
},
meta: null,
publicNickname: "agent" + agent.publicNickname?.slice(0, 1).toUpperCase() + agent.publicNickname?.slice(1),
};
}
export function getAgentID(agent: Agent): AgentID {
return `agent_${coValueIDforHeader(getAgentCoValueHeader(agent)).slice(
"coval_".length
)}`;
}
export function agentIDAsCoValueID(agentID: AgentID): RawCoValueID {
return `coval_${agentID.substring("agent_".length)}`;
return coValueIDforHeader(getAgentCoValueHeader(agent)) as AgentID;
}
export type AgentCredential = {
signatorySecret: SignatorySecret;
recipientSecret: RecipientSecret;
publicNickname?: string;
};
export function newRandomAgentCredential(): AgentCredential {
export function newRandomAgentCredential(publicNickname: string): AgentCredential {
const signatorySecret = newRandomSignatory();
const recipientSecret = newRandomRecipient();
return { signatorySecret, recipientSecret };
return { signatorySecret, recipientSecret, publicNickname };
}
// type Role = "admin" | "writer" | "reader";

View File

@@ -8,7 +8,7 @@ import {
import { LocalNode } from "./node";
test("Empty COJSON Map works", () => {
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -32,7 +32,7 @@ test("Empty COJSON Map works", () => {
});
test("Can insert and delete Map entries in edit()", () => {
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -64,7 +64,7 @@ test("Can insert and delete Map entries in edit()", () => {
});
test("Can get map entry values at different points in time", () => {
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -103,7 +103,7 @@ test("Can get map entry values at different points in time", () => {
});
test("Can get all historic values of key", () => {
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))
@@ -160,7 +160,7 @@ test("Can get all historic values of key", () => {
});
test("Can get last tx ID for a key", () => {
const agentCredential = newRandomAgentCredential();
const agentCredential = newRandomAgentCredential("agent1");
const node = new LocalNode(
agentCredential,
newRandomSessionID(getAgentID(getAgent(agentCredential)))

View File

@@ -49,8 +49,8 @@ test("Sealing round-trips, but invalid receiver can't unseal", () => {
const recipient3 = newRandomRecipient();
const nOnceMaterial = {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 0 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 0 },
} as const;
const sealed = seal(
@@ -106,23 +106,23 @@ test("Encryption for transactions round-trips", () => {
const { secret } = newRandomKeySecret();
const encrypted1 = encryptForTransaction({ a: "hello" }, secret, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 0 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 0 },
});
const encrypted2 = encryptForTransaction({ b: "world" }, secret, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 1 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 1 },
});
const decrypted1 = decryptForTransaction(encrypted1, secret, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 0 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 0 },
});
const decrypted2 = decryptForTransaction(encrypted2, secret, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 1 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 1 },
});
expect([decrypted1, decrypted2]).toEqual([{ a: "hello" }, { b: "world" }]);
@@ -133,23 +133,23 @@ test("Encryption for transactions doesn't decrypt with a wrong key", () => {
const { secret: secret2 } = newRandomKeySecret();
const encrypted1 = encryptForTransaction({ a: "hello" }, secret, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 0 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 0 },
});
const encrypted2 = encryptForTransaction({ b: "world" }, secret, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 1 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 1 },
});
const decrypted1 = decryptForTransaction(encrypted1, secret2, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 0 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 0 },
});
const decrypted2 = decryptForTransaction(encrypted2, secret2, {
in: "coval_zTEST",
tx: { sessionID: "session_zTEST_agent_zTEST", txIndex: 1 },
in: "co_zTEST",
tx: { sessionID: "co_agent_zTEST_session_zTEST", txIndex: 1 },
});
expect([decrypted1, decrypted2]).toEqual([undefined, undefined]);

View File

@@ -89,6 +89,7 @@ export class LocalNode {
type: "comap",
ruleset: { type: "team", initialAdmin: this.agentID },
meta: null,
publicNickname: "team",
});
let teamContent = expectTeamContent(teamCoValue.getCurrentContent());

View File

@@ -17,7 +17,7 @@ import {
function teamWithTwoAdmins() {
const { team, admin, adminID } = newTeam();
const otherAdmin = newRandomAgentCredential();
const otherAdmin = newRandomAgentCredential("otherAdmin");
const otherAdminID = getAgentID(getAgent(otherAdmin));
let content = expectTeamContent(team.getCurrentContent());
@@ -38,7 +38,7 @@ function teamWithTwoAdmins() {
}
function newTeam() {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -47,6 +47,7 @@ function newTeam() {
type: "comap",
ruleset: { type: "team", initialAdmin: adminID },
meta: null,
publicNickname: "team"
});
const teamContent = expectTeamContent(team.getCurrentContent());
@@ -64,7 +65,7 @@ test("Initial admin can add another admin to a team", () => {
});
function newTeamHighLevel() {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -77,7 +78,7 @@ function newTeamHighLevel() {
function teamWithTwoAdminsHighLevel() {
const { admin, adminID, node, team } = newTeamHighLevel();
const otherAdmin = newRandomAgentCredential();
const otherAdmin = newRandomAgentCredential("otherAdmin");
const otherAdminID = getAgentID(getAgent(otherAdmin));
node.addKnownAgent(getAgent(otherAdmin));
@@ -103,7 +104,7 @@ test("Added admin can add a third admin to a team", () => {
expect(otherContent.get(otherAdminID)).toEqual("admin");
const thirdAdmin = newRandomAgentCredential();
const thirdAdmin = newRandomAgentCredential("admin");
const thirdAdminID = getAgentID(getAgent(thirdAdmin));
otherContent.edit((editable) => {
@@ -125,7 +126,7 @@ test("Added adming can add a third admin to a team (high level)", () => {
newRandomSessionID(otherAdminID)
);
const thirdAdmin = newRandomAgentCredential();
const thirdAdmin = newRandomAgentCredential("admin");
const thirdAdminID = getAgentID(getAgent(thirdAdmin));
node.addKnownAgent(getAgent(thirdAdmin));
@@ -187,7 +188,7 @@ test("Admins can't demote other admins in a team (high level)", () => {
test("Admins an add writers to a team, who can't add admins, writers, or readers", () => {
const { team } = newTeam();
const writer = newRandomAgentCredential();
const writer = newRandomAgentCredential("writer");
const writerID = getAgentID(getAgent(writer));
let teamContent = expectTeamContent(team.getCurrentContent());
@@ -211,7 +212,7 @@ test("Admins an add writers to a team, who can't add admins, writers, or readers
expect(teamContentAsWriter.get(writerID)).toEqual("writer");
const otherAgent = newRandomAgentCredential();
const otherAgent = newRandomAgentCredential("otherAgent");
const otherAgentID = getAgentID(getAgent(otherAgent));
teamContentAsWriter.edit((editable) => {
@@ -233,7 +234,7 @@ test("Admins an add writers to a team, who can't add admins, writers, or readers
test("Admins an add writers to a team, who can't add admins, writers, or readers (high level)", () => {
const { team, node } = newTeamHighLevel();
const writer = newRandomAgentCredential();
const writer = newRandomAgentCredential("writer");
const writerID = getAgentID(getAgent(writer));
node.addKnownAgent(getAgent(writer));
@@ -248,7 +249,7 @@ test("Admins an add writers to a team, who can't add admins, writers, or readers
expect(teamAsWriter.teamMap.get(writerID)).toEqual("writer");
const otherAgent = newRandomAgentCredential();
const otherAgent = newRandomAgentCredential("otherAgent");
const otherAgentID = getAgentID(getAgent(otherAgent));
node.addKnownAgent(getAgent(otherAgent));
@@ -268,7 +269,7 @@ test("Admins an add writers to a team, who can't add admins, writers, or readers
test("Admins can add readers to a team, who can't add admins, writers, or readers", () => {
const { team } = newTeam();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
let teamContent = expectTeamContent(team.getCurrentContent());
@@ -292,7 +293,7 @@ test("Admins can add readers to a team, who can't add admins, writers, or reader
expect(teamContentAsReader.get(readerID)).toEqual("reader");
const otherAgent = newRandomAgentCredential();
const otherAgent = newRandomAgentCredential("otherAgent");
const otherAgentID = getAgentID(getAgent(otherAgent));
teamContentAsReader.edit((editable) => {
@@ -314,7 +315,7 @@ test("Admins can add readers to a team, who can't add admins, writers, or reader
test("Admins can add readers to a team, who can't add admins, writers, or readers (high level)", () => {
const { team, node } = newTeamHighLevel();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
node.addKnownAgent(getAgent(reader));
@@ -329,7 +330,7 @@ test("Admins can add readers to a team, who can't add admins, writers, or reader
expect(teamAsReader.teamMap.get(readerID)).toEqual("reader");
const otherAgent = newRandomAgentCredential();
const otherAgent = newRandomAgentCredential("otherAgent");
const otherAgentID = getAgentID(getAgent(otherAgent));
node.addKnownAgent(getAgent(otherAgent));
@@ -354,6 +355,7 @@ test("Admins can write to an object that is owned by their team", () => {
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
let childContent = expectMap(childObject.getCurrentContent());
@@ -384,7 +386,7 @@ test("Admins can write to an object that is owned by their team (high level)", (
test("Writers can write to an object that is owned by their team", () => {
const { node, team } = newTeam();
const writer = newRandomAgentCredential();
const writer = newRandomAgentCredential("writer");
const writerID = getAgentID(getAgent(writer));
expectTeamContent(team.getCurrentContent()).edit((editable) => {
@@ -396,6 +398,7 @@ test("Writers can write to an object that is owned by their team", () => {
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
const childObjectAsWriter = childObject.testWithDifferentCredentials(
@@ -420,7 +423,7 @@ test("Writers can write to an object that is owned by their team", () => {
test("Writers can write to an object that is owned by their team (high level)", () => {
const { node, team } = newTeamHighLevel();
const writer = newRandomAgentCredential();
const writer = newRandomAgentCredential("writer");
const writerID = getAgentID(getAgent(writer));
node.addKnownAgent(getAgent(writer));
@@ -446,7 +449,7 @@ test("Writers can write to an object that is owned by their team (high level)",
test("Readers can not write to an object that is owned by their team", () => {
const { node, team } = newTeam();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
expectTeamContent(team.getCurrentContent()).edit((editable) => {
@@ -458,6 +461,7 @@ test("Readers can not write to an object that is owned by their team", () => {
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
const childObjectAsReader = childObject.testWithDifferentCredentials(
@@ -482,7 +486,7 @@ test("Readers can not write to an object that is owned by their team", () => {
test("Readers can not write to an object that is owned by their team (high level)", () => {
const { node, team } = newTeamHighLevel();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
node.addKnownAgent(getAgent(reader));
@@ -533,6 +537,7 @@ test("Admins can set team read key and then use it to create and read private tr
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
let childContent = expectMap(childObject.getCurrentContent());
@@ -562,7 +567,7 @@ test("Admins can set team read key and then use it to create and read private tr
test("Admins can set team read key and then writers can use it to create and read private transactions in owned objects", () => {
const { node, team, admin } = newTeam();
const writer = newRandomAgentCredential();
const writer = newRandomAgentCredential("writer");
const writerID = getAgentID(getAgent(writer));
const { secret: readKey, id: readKeyID } = newRandomKeySecret();
@@ -591,6 +596,7 @@ test("Admins can set team read key and then writers can use it to create and rea
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
const childObjectAsWriter = childObject.testWithDifferentCredentials(
@@ -617,7 +623,7 @@ test("Admins can set team read key and then writers can use it to create and rea
test("Admins can set team read key and then writers can use it to create and read private transactions in owned objects (high level)", () => {
const { node, team, admin } = newTeamHighLevel();
const writer = newRandomAgentCredential();
const writer = newRandomAgentCredential("writer");
const writerID = getAgentID(getAgent(writer));
node.addKnownAgent(getAgent(writer));
@@ -643,7 +649,7 @@ test("Admins can set team read key and then writers can use it to create and rea
test("Admins can set team read key and then use it to create private transactions in owned objects, which readers can read", () => {
const { node, team, admin } = newTeam();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
const { secret: readKey, id: readKeyID } = newRandomKeySecret();
@@ -672,6 +678,7 @@ test("Admins can set team read key and then use it to create private transaction
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
expectMap(childObject.getCurrentContent()).edit((editable) => {
@@ -696,7 +703,7 @@ test("Admins can set team read key and then use it to create private transaction
test("Admins can set team read key and then use it to create private transactions in owned objects, which readers can read (high level)", () => {
const { node, team, admin } = newTeamHighLevel();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
node.addKnownAgent(getAgent(reader));
@@ -722,9 +729,9 @@ test("Admins can set team read key and then use it to create private transaction
test("Admins can set team read key and then use it to create private transactions in owned objects, which readers can read, even with a separate later revelation for the same read key", () => {
const { node, team, admin } = newTeam();
const reader1 = newRandomAgentCredential();
const reader1 = newRandomAgentCredential("reader1");
const reader1ID = getAgentID(getAgent(reader1));
const reader2 = newRandomAgentCredential();
const reader2 = newRandomAgentCredential("reader2");
const reader2ID = getAgentID(getAgent(reader2));
const { secret: readKey, id: readKeyID } = newRandomKeySecret();
@@ -772,6 +779,7 @@ test("Admins can set team read key and then use it to create private transaction
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
expectMap(childObject.getCurrentContent()).edit((editable) => {
@@ -809,9 +817,9 @@ test("Admins can set team read key and then use it to create private transaction
test("Admins can set team read key and then use it to create private transactions in owned objects, which readers can read, even with a separate later revelation for the same read key (high level)", () => {
const { node, team, admin } = newTeamHighLevel();
const reader1 = newRandomAgentCredential();
const reader1 = newRandomAgentCredential("reader1");
const reader1ID = getAgentID(getAgent(reader1));
const reader2 = newRandomAgentCredential();
const reader2 = newRandomAgentCredential("reader2");
const reader2ID = getAgentID(getAgent(reader2));
node.addKnownAgent(getAgent(reader1));
@@ -872,6 +880,7 @@ test("Admins can set team read key, make a private transaction in an owned objec
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
let childContent = expectMap(childObject.getCurrentContent());
@@ -951,6 +960,7 @@ test("Admins can set team read key, make a private transaction in an owned objec
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
const teamContent = expectTeamContent(team.getCurrentContent());
@@ -984,7 +994,7 @@ test("Admins can set team read key, make a private transaction in an owned objec
childContent = expectMap(childObject.getCurrentContent());
expect(childContent.get("foo")).toEqual("bar");
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
const { secret: readKey2, id: readKeyID2 } = newRandomKeySecret();
@@ -1064,7 +1074,7 @@ test("Admins can set team read key, make a private transaction in an owned objec
expect(childObject.coValue.getCurrentReadKey()).not.toEqual(firstReadKey);
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
node.addKnownAgent(getAgent(reader));
@@ -1093,13 +1103,14 @@ test("Admins can set team read rey, make a private transaction in an owned objec
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "childObject"
});
const teamContent = expectTeamContent(team.getCurrentContent());
const { secret: readKey, id: readKeyID } = newRandomKeySecret();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
const reader2 = newRandomAgentCredential();
const reader2 = newRandomAgentCredential("reader2");
const reader2ID = getAgentID(getAgent(reader));
teamContent.edit((editable) => {
@@ -1229,9 +1240,9 @@ test("Admins can set team read rey, make a private transaction in an owned objec
const secondReadKey = childObject.coValue.getCurrentReadKey();
const reader = newRandomAgentCredential();
const reader = newRandomAgentCredential("reader");
const readerID = getAgentID(getAgent(reader));
const reader2 = newRandomAgentCredential();
const reader2 = newRandomAgentCredential("reader2");
const reader2ID = getAgentID(getAgent(reader2));
node.addKnownAgent(getAgent(reader));

View File

@@ -271,7 +271,7 @@ export class Team {
rotateReadKey() {
const currentlyPermittedReaders = this.teamMap.keys().filter((key) => {
if (key.startsWith("agent_")) {
if (key.startsWith("co_agent")) {
const role = this.teamMap.get(key);
return (
role === "admin" || role === "writer" || role === "reader"
@@ -342,6 +342,7 @@ export class Team {
team: this.teamMap.id,
},
meta: meta || null,
publicNickname: "map",
})
.getCurrentContent() as CoMap<M, Meta>;
}

View File

@@ -1,6 +1,5 @@
import {
AgentID,
agentIDAsCoValueID,
getAgent,
getAgentID,
newRandomAgentCredential,
@@ -19,7 +18,7 @@ import {
test(
"Node replies with initial tx and header to empty subscribe",
async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -74,6 +73,7 @@ test(
type: "comap",
ruleset: { type: "ownedByTeam", team: team.id },
meta: null,
publicNickname: "map",
},
newContent: {
[node.ownSessionID]: {
@@ -103,7 +103,7 @@ test(
);
test("Node replies with only new tx to subscribe with some known state", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -188,7 +188,7 @@ test.todo(
);
test("After subscribing, node sends own known state and new txs to peer", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -309,7 +309,7 @@ test("After subscribing, node sends own known state and new txs to peer", async
});
test("Client replies with known new content to tellKnownState from server", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -391,7 +391,7 @@ test("Client replies with known new content to tellKnownState from server", asyn
});
test("No matter the optimistic known state, node respects invalid known state messages and resyncs", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -496,7 +496,7 @@ test("No matter the optimistic known state, node respects invalid known state me
});
test("If we add a peer, but it never subscribes to a coValue, it won't get any messages", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -525,7 +525,7 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
});
test("If we add a server peer, all updates to all coValues are sent to it, even if it doesn't subscribe", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -547,7 +547,7 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
const reader = outRx.getReader();
expect((await reader.read()).value).toMatchObject({
action: "subscribe",
coValueID: agentIDAsCoValueID(adminID),
coValueID: adminID,
});
expect((await reader.read()).value).toMatchObject({
action: "subscribe",
@@ -602,7 +602,7 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
});
test("If we add a server peer, newly created coValues are auto-subscribed to", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -624,7 +624,7 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
const reader = outRx.getReader();
expect((await reader.read()).value).toMatchObject({
action: "subscribe",
coValueID: agentIDAsCoValueID(adminID),
coValueID: adminID,
});
expect((await reader.read()).value).toMatchObject({
action: "subscribe",
@@ -658,7 +658,7 @@ test.todo(
);
test("When we connect a new server peer, we try to sync all existing coValues to it", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -696,7 +696,7 @@ test("When we connect a new server peer, we try to sync all existing coValues to
});
test("When receiving a subscribe with a known state that is ahead of our own, peers should respond with a corresponding subscribe response message", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node = new LocalNode(admin, newRandomSessionID(adminID));
@@ -740,7 +740,7 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", async () => {
// TODO: this test is mostly correct but also slightly unrealistic, make sure we pass all messages back and forth as expected and then it should work
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node1 = new LocalNode(admin, newRandomSessionID(adminID));
@@ -778,7 +778,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
const adminSubscribeMessage = await from1.read();
expect(adminSubscribeMessage.value).toMatchObject({
action: "subscribe",
coValueID: agentIDAsCoValueID(adminID),
coValueID: adminID,
});
const teamSubscribeMsg = await from1.read();
expect(teamSubscribeMsg.value).toMatchObject({
@@ -862,7 +862,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
test.skip("When loading a coValue on one node, the server node it is requested from replies with all the necessary depended on coValues to make it work", async () => {
// TODO: this test is mostly correct but also slightly unrealistic, make sure we pass all messages back and forth as expected and then it should work
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const node1 = new LocalNode(admin, newRandomSessionID(adminID));
@@ -891,7 +891,7 @@ test.skip("When loading a coValue on one node, the server node it is requested f
});
test("Can sync a coValue through a server to another client", async () => {
const admin = newRandomAgentCredential();
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const client1 = new LocalNode(admin, newRandomSessionID(adminID));
@@ -903,7 +903,55 @@ test("Can sync a coValue through a server to another client", async () => {
editable.set("hello", "world", "trusting");
});
const server = new LocalNode(admin, newRandomSessionID(adminID));
const serverUser = newRandomAgentCredential("serverUser");
const serverUserID = getAgentID(getAgent(serverUser));
const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
trace: true,
peer1role: "server",
peer2role: "client",
});
client1.sync.addPeer(serverAsPeer);
server.sync.addPeer(client1AsPeer);
const client2 = new LocalNode(admin, newRandomSessionID(adminID));
const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
"server",
"client2",
{ trace: true, peer1role: "server", peer2role: "client" }
);
client2.sync.addPeer(serverAsOtherPeer);
server.sync.addPeer(client2AsPeer);
const mapOnClient2 = await client2.loadCoValue(map.coValue.id);
expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual(
"world"
);
});
test("Can sync a coValue with private transactions through a server to another client", async () => {
const admin = newRandomAgentCredential("admin");
const adminID = getAgentID(getAgent(admin));
const client1 = new LocalNode(admin, newRandomSessionID(adminID));
const team = client1.createTeam();
const map = team.createMap();
map.edit((editable) => {
editable.set("hello", "world", "private");
});
const serverUser = newRandomAgentCredential("serverUser");
const serverUserID = getAgentID(getAgent(serverUser));
const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
trace: true,
@@ -942,7 +990,7 @@ function teamContentEx(team: Team) {
function admContEx(adminID: AgentID) {
return {
action: "newContent",
coValueID: agentIDAsCoValueID(adminID),
coValueID: adminID,
};
}
@@ -956,7 +1004,7 @@ function teamStateEx(team: Team) {
function admStateEx(adminID: AgentID) {
return {
action: "tellKnownState",
coValueID: agentIDAsCoValueID(adminID),
coValueID: adminID,
};
}