Share
Embed
Transcript
101 slides
-
key = "c0be" "a6ea178" = encrypt("my todo", key) key =
"c0be" "my todo" = decrypt("a6ea178", key) "a6ea178" "a6ea178" -
encrypt({ todoListKey: "8-Aw_2UhSVrgKGp77jsnT", content: JSON.stringify({ "1": { text: "Wash the
dishes", checked: false }, "2": { text: "Order sweets", checked: true }, }), }); Encrypt & send the entire list -
encrypt({ todoListKey: "8-Aw_2UhSVrgKGp77jsnT", content: JSON.stringify({ "1": { text: "Wash the
dishes", checked: false }, "2": { text: "Order sweets", checked: true }, }), }); Encrypt & send the entire list content: JSON.stringify({ "1": { text: "Wash the dishes", checked: false }, "2": { text: "Order sweets", checked: true }, }), -
Add todo 1 Change todo 1 Con fl icts Add
todo 1 Change todo 1 -
Add todo 1 Change todo 1 Change todo 1 Con
fl icts Add todo 1 Change todo 1 -
= CRDT Add todo 1 Add todo 1 Change todo
1 Change todo 1 Change todo 1 Change todo 1 -
c3 = encrypt( , key) Change todo 1 c1 =
encrypt( , key) c2 = encrypt( , key) Add todo 1 Change todo 1 -
c3 = encrypt( , key) c1 = encrypt( , key)
c2 = encrypt( , key) c1 c1 c2 c2 c3 c3 Add todo 1 Change todo 1 Change todo 1 -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); import * as Yjs from "yjs"; -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); // initializing CRDT document const doc = new Yjs.Doc(); -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); const todoList = doc.getMap("todos"); -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); // adding a todo const todo = new Yjs.Map(); -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); -
import * as Yjs from "yjs"; // initializing CRDT document
const doc = new Yjs.Doc(); const todoList = doc.getMap("todos"); // adding a todo const todo = new Yjs.Map(); todo.set("text", new Yjs.Text("wash the dishes")); todo.set("checked", false); todoList.set(generateId(), todo); todoList.set(generateId(), todo); -
doc.on("updateV2", (update) => { // send(update) }); Yjs.applyUpdateV2(doc, update); const
docAsUpdate = Yjs.encodeStateAsUpdateV2(doc) doc.on("updateV2", (update) => { // send(update) }); -
doc.on("updateV2", (update) => { // send(update) }); Yjs.applyUpdateV2(doc, update); const
docAsUpdate = Yjs.encodeStateAsUpdateV2(doc) Yjs.applyUpdateV2(doc, update); -
doc.on("updateV2", (update) => { // send(update) }); Yjs.applyUpdateV2(doc, update); const
docAsUpdate = Yjs.encodeStateAsUpdateV2(doc) const docAsUpdate = Yjs.encodeStateAsUpdateV2(doc) -
const yDocRef = useRef<Yjs.Doc>(new Yjs.Doc()); const [signatureKeyPair] = useState<KeyPair>(() =>
sodium.crypto_sign_keypair() ); useYjsSync({ yDoc: yDocRef.current, documentId: todoListId, websocketEndpoint: "ws://localhost:3030", getSnapshotKey: () => todoListKey, getNewSnapshotData: () => { return { key: todoListKey, data: Yjs.encodeStateAsUpdateV2(yDocRef.current), publicData: {}, }; }, shouldSendSnapshot: ({ snapshotUpdatesCount }) => snapshotUpdatesCount > 50, signatureKeyPair, isValidClient: () => true, sodium, }); -
useYjsSync({ yDoc: yDocRef.current, documentId: todoListId, key: todoListKey, websocketEndpoint: "ws://localhost:3030", });
websocketEndpoint: "ws://localhost:3030", -
key = "c0be" "a6ea178" = encrypt("my todo", key) key =
"c0be" "my todo" = decrypt("a6ea178", key) "a6ea178" "a6ea178" -
const lockerKey = '8-Aw_2UhSVrgKGp77jsnTF03DPBvjvdLSUwp4savq8Q'; const locker = encrypt({ lockerKey, content:
JSON.stringify({ "1": "aL1wBSONXU9eWD6oLdjCQ8H4jbFa762vbP6Iouk5A4U", "2": "mxKjG-qh-eg4y8N6B3cpGmC1uEn2c_YWi0s8T2H_WAo", }), }); const lockerKey = '8-Aw_2UhSVrgKGp77jsnTF03DPBvjvdLSUwp4savq8Q'; -
const lockerKey = '8-Aw_2UhSVrgKGp77jsnTF03DPBvjvdLSUwp4savq8Q'; const locker = encrypt({ lockerKey, content:
JSON.stringify({ "1": "aL1wBSONXU9eWD6oLdjCQ8H4jbFa762vbP6Iouk5A4U", "2": "mxKjG-qh-eg4y8N6B3cpGmC1uEn2c_YWi0s8T2H_WAo", }), }); const locker = encrypt({ }); -
const lockerKey = '8-Aw_2UhSVrgKGp77jsnTF03DPBvjvdLSUwp4savq8Q'; const locker = encrypt({ lockerKey, content:
JSON.stringify({ "1": "aL1wBSONXU9eWD6oLdjCQ8H4jbFa762vbP6Iouk5A4U", "2": "mxKjG-qh-eg4y8N6B3cpGmC1uEn2c_YWi0s8T2H_WAo", }), }); lockerKey, -
const lockerKey = '8-Aw_2UhSVrgKGp77jsnTF03DPBvjvdLSUwp4savq8Q'; const locker = encrypt({ lockerKey, content:
JSON.stringify({ "1": "aL1wBSONXU9eWD6oLdjCQ8H4jbFa762vbP6Iouk5A4U", "2": "mxKjG-qh-eg4y8N6B3cpGmC1uEn2c_YWi0s8T2H_WAo", }), }); content: JSON.stringify({ "1": "aL1wBSONXU9eWD6oLdjCQ8H4jbFa762vbP6Iouk5A4U", "2": "mxKjG-qh-eg4y8N6B3cpGmC1uEn2c_YWi0s8T2H_WAo", }), -
const { addItem, content } = useLocker(); await addItem({ documentId,
key }); const key = content[documentId]; const { addItem, content } = useLocker(); -
const { addItem, content } = useLocker(); await addItem({ documentId,
key }); const key = content[documentId]; await addItem({ documentId, key }); -
const { addItem, content } = useLocker(); await addItem({ documentId,
key }); const key = content[documentId]; const key = content[documentId]; -
const { register, isPending } = useRegister(); const result =
await register({ userIdentifier: username, password, }); result?.exportKey const { register, isPending } = useRegister(); -
const { register, isPending } = useRegister(); const result =
await register({ userIdentifier: username, password, }); result?.exportKey const result = await register({ userIdentifier: username, password, }); -
const { register, isPending } = useRegister(); const result =
await register({ userIdentifier: username, password, }); result?.exportKey result?.exportKey -
const { clientRegistrationState, registrationRequest } = opaque.startRegistration({ password }); const
{ registrationResponse } = await registerStartMutation.mutateAsync({ userIdentifier, registrationRequest, }); const { registrationRecord, exportKey } = opaque.finishRegistration({ clientRegistrationState, registrationResponse, password, }); await registerFinishMutation.mutateAsync({ userIdentifier, registrationRecord, }); const { clientRegistrationState, registrationRequest } = opaque.startRegistration({ password }); -
const { clientRegistrationState, registrationRequest } = opaque.startRegistration({ password }); const
{ registrationResponse } = await registerStartMutation.mutateAsync({ userIdentifier, registrationRequest, }); const { registrationRecord, exportKey } = opaque.finishRegistration({ clientRegistrationState, registrationResponse, password, }); await registerFinishMutation.mutateAsync({ userIdentifier, registrationRecord, }); const { registrationResponse } = await registerStartMutation.mutateAsync({ userIdentifier, registrationRequest, }); -
const { clientRegistrationState, registrationRequest } = opaque.startRegistration({ password }); const
{ registrationResponse } = await registerStartMutation.mutateAsync({ userIdentifier, registrationRequest, }); const { registrationRecord, exportKey } = opaque.finishRegistration({ clientRegistrationState, registrationResponse, password, }); await registerFinishMutation.mutateAsync({ userIdentifier, registrationRecord, }); const { registrationRecord, exportKey } = opaque.finishRegistration({ clientRegistrationState, registrationResponse, password, }); -
const { clientRegistrationState, registrationRequest } = opaque.startRegistration({ password }); const
{ registrationResponse } = await registerStartMutation.mutateAsync({ userIdentifier, registrationRequest, }); const { registrationRecord, exportKey } = opaque.finishRegistration({ clientRegistrationState, registrationResponse, password, }); await registerFinishMutation.mutateAsync({ userIdentifier, registrationRecord, }); await registerFinishMutation.mutateAsync({ userIdentifier, registrationRecord, }); -
const { login, isPending } = useLogin(); const result =
await login({ userIdentifier: username, password, }); result?.exportKey const { login, isPending } = useLogin(); -
const { login, isPending } = useLogin(); const result =
await login({ userIdentifier: username, password, }); result?.exportKey const result = await login({ userIdentifier: username, password, }); -
const { login, isPending } = useLogin(); const result =
await login({ userIdentifier: username, password, }); result?.exportKey result?.exportKey -
const { clientLoginState, startLoginRequest } = opaque.startLogin({ password, }); const
{ loginResponse } = await loginStartMutation.mutateAsync({ userIdentifier, startLoginRequest, }); const loginResult = opaque.finishLogin({ clientLoginState, loginResponse, password, }); if (!loginResult) { return null; } const { finishLoginRequest, exportKey } = loginResult; const { success } = await loginFinishMutation.mutateAsync({ finishLoginRequest, userIdentifier, }); const { clientLoginState, startLoginRequest } = opaque.startLogin({ password, }); -
const { clientLoginState, startLoginRequest } = opaque.startLogin({ password, }); const
{ loginResponse } = await loginStartMutation.mutateAsync({ userIdentifier, startLoginRequest, }); const loginResult = opaque.finishLogin({ clientLoginState, loginResponse, password, }); if (!loginResult) { return null; } const { finishLoginRequest, exportKey } = loginResult; const { success } = await loginFinishMutation.mutateAsync({ finishLoginRequest, userIdentifier, }); const { loginResponse } = await loginStartMutation.mutateAsync({ userIdentifier, startLoginRequest, }); -
const { clientLoginState, startLoginRequest } = opaque.startLogin({ password, }); const
{ loginResponse } = await loginStartMutation.mutateAsync({ userIdentifier, startLoginRequest, }); const loginResult = opaque.finishLogin({ clientLoginState, loginResponse, password, }); if (!loginResult) { return null; } const { finishLoginRequest, exportKey } = loginResult; const { success } = await loginFinishMutation.mutateAsync({ finishLoginRequest, userIdentifier, }); const loginResult = opaque.finishLogin({ clientLoginState, loginResponse, password, }); if (!loginResult) { return null; } const { finishLoginRequest, exportKey } = loginResult; -
const { clientLoginState, startLoginRequest } = opaque.startLogin({ password, }); const
{ loginResponse } = await loginStartMutation.mutateAsync({ userIdentifier, startLoginRequest, }); const loginResult = opaque.finishLogin({ clientLoginState, loginResponse, password, }); if (!loginResult) { return null; } const { finishLoginRequest, exportKey } = loginResult; const { success } = await loginFinishMutation.mutateAsync({ finishLoginRequest, userIdentifier, }); const { success } = await loginFinishMutation.mutateAsync({ finishLoginRequest, userIdentifier, }); -
const key = getHashParameter("key"); const data = await acceptDocumentInvitationMutation.mutateAsync({ token
}); if (data?.documentId) { await addItem({ documentId: data.documentId, key, }); router.navigate({ pathname: `/list/${data.documentId}` }); } const key = getHashParameter("key"); -
const key = getHashParameter("key"); const data = await acceptDocumentInvitationMutation.mutateAsync({ token
}); if (data?.documentId) { await addItem({ documentId: data.documentId, key, }); router.navigate({ pathname: `/list/${data.documentId}` }); } const data = await acceptDocumentInvitationMutation.mutateAsync({ token }); -
const key = getHashParameter("key"); const data = await acceptDocumentInvitationMutation.mutateAsync({ token
}); if (data?.documentId) { await addItem({ documentId: data.documentId, key, }); router.navigate({ pathname: `/list/${data.documentId}` }); } await addItem({ documentId: data.documentId, key, }); -
story for another time … … read my blog in
the coming months