@agora-sdk/secure-chat-core 0.6.5 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/content/builders.d.ts +40 -0
- package/dist/cjs/content/builders.js +85 -0
- package/dist/cjs/content/builders.js.map +1 -0
- package/dist/cjs/content/cbor.d.ts +48 -0
- package/dist/cjs/content/cbor.js +298 -0
- package/dist/cjs/content/cbor.js.map +1 -0
- package/dist/cjs/content/frame.d.ts +24 -0
- package/dist/cjs/content/frame.js +39 -0
- package/dist/cjs/content/frame.js.map +1 -0
- package/dist/cjs/content/mimi-content.d.ts +194 -0
- package/dist/cjs/content/mimi-content.js +289 -0
- package/dist/cjs/content/mimi-content.js.map +1 -0
- package/dist/cjs/context/secure-chat-context.d.ts +19 -3
- package/dist/cjs/context/secure-chat-context.js +53 -13
- package/dist/cjs/context/secure-chat-context.js.map +1 -1
- package/dist/cjs/hooks/message-fold.d.ts +91 -0
- package/dist/cjs/hooks/message-fold.js +218 -0
- package/dist/cjs/hooks/message-fold.js.map +1 -0
- package/dist/cjs/hooks/useSecureConversations.js +11 -0
- package/dist/cjs/hooks/useSecureConversations.js.map +1 -1
- package/dist/cjs/hooks/useSecureDevice.js +15 -1
- package/dist/cjs/hooks/useSecureDevice.js.map +1 -1
- package/dist/cjs/hooks/useSecureHandshakes.js +36 -2
- package/dist/cjs/hooks/useSecureHandshakes.js.map +1 -1
- package/dist/cjs/hooks/useSecureMessages.d.ts +30 -18
- package/dist/cjs/hooks/useSecureMessages.js +197 -130
- package/dist/cjs/hooks/useSecureMessages.js.map +1 -1
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +30 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/persistence/repository.d.ts +24 -0
- package/dist/cjs/persistence/repository.js +35 -0
- package/dist/cjs/persistence/repository.js.map +1 -1
- package/dist/cjs/persistence/store.js +11 -0
- package/dist/cjs/persistence/store.js.map +1 -1
- package/dist/cjs/transport/rest.d.ts +2 -2
- package/dist/cjs/transport/rest.js +2 -2
- package/dist/cjs/transport/rest.js.map +1 -1
- package/dist/cjs/transport/socket.d.ts +1 -1
- package/dist/cjs/transport/socket.js +17 -1
- package/dist/cjs/transport/socket.js.map +1 -1
- package/dist/cjs/version.d.ts +13 -0
- package/dist/cjs/version.js +19 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/esm/content/builders.d.ts +40 -0
- package/dist/esm/content/builders.js +77 -0
- package/dist/esm/content/builders.js.map +1 -0
- package/dist/esm/content/cbor.d.ts +48 -0
- package/dist/esm/content/cbor.js +292 -0
- package/dist/esm/content/cbor.js.map +1 -0
- package/dist/esm/content/frame.d.ts +24 -0
- package/dist/esm/content/frame.js +34 -0
- package/dist/esm/content/frame.js.map +1 -0
- package/dist/esm/content/mimi-content.d.ts +194 -0
- package/dist/esm/content/mimi-content.js +283 -0
- package/dist/esm/content/mimi-content.js.map +1 -0
- package/dist/esm/context/secure-chat-context.d.ts +19 -3
- package/dist/esm/context/secure-chat-context.js +53 -13
- package/dist/esm/context/secure-chat-context.js.map +1 -1
- package/dist/esm/hooks/message-fold.d.ts +91 -0
- package/dist/esm/hooks/message-fold.js +214 -0
- package/dist/esm/hooks/message-fold.js.map +1 -0
- package/dist/esm/hooks/useSecureConversations.js +11 -0
- package/dist/esm/hooks/useSecureConversations.js.map +1 -1
- package/dist/esm/hooks/useSecureDevice.js +15 -1
- package/dist/esm/hooks/useSecureDevice.js.map +1 -1
- package/dist/esm/hooks/useSecureHandshakes.js +36 -2
- package/dist/esm/hooks/useSecureHandshakes.js.map +1 -1
- package/dist/esm/hooks/useSecureMessages.d.ts +30 -18
- package/dist/esm/hooks/useSecureMessages.js +199 -132
- package/dist/esm/hooks/useSecureMessages.js.map +1 -1
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/persistence/repository.d.ts +24 -0
- package/dist/esm/persistence/repository.js +35 -0
- package/dist/esm/persistence/repository.js.map +1 -1
- package/dist/esm/persistence/store.js +11 -0
- package/dist/esm/persistence/store.js.map +1 -1
- package/dist/esm/transport/rest.d.ts +2 -2
- package/dist/esm/transport/rest.js +2 -2
- package/dist/esm/transport/rest.js.map +1 -1
- package/dist/esm/transport/socket.d.ts +1 -1
- package/dist/esm/transport/socket.js +17 -1
- package/dist/esm/transport/socket.js.map +1 -1
- package/dist/esm/version.d.ts +13 -0
- package/dist/esm/version.js +16 -0
- package/dist/esm/version.js.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secure-chat-context.js","sourceRoot":"","sources":["../../../src/context/secure-chat-context.tsx"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"secure-chat-context.js","sourceRoot":"","sources":["../../../src/context/secure-chat-context.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type MimiContent } from "../content/mimi-content.js";
|
|
2
|
+
/** A decoded, content-hashed message handed to the fold (the hook computes these post-decrypt). */
|
|
3
|
+
export interface DecodedContentMessage {
|
|
4
|
+
/** Server message id (storage/order/dedup key). */
|
|
5
|
+
messageId: string;
|
|
6
|
+
/** Server createdAt (ISO) — used to stamp `editedAt` and for the hook's ordering. */
|
|
7
|
+
createdAt: string;
|
|
8
|
+
/** Authenticated MLS sender device id. */
|
|
9
|
+
senderDeviceId: string;
|
|
10
|
+
/** SHA-256 over the canonical MimiContent bytes (the reference key). */
|
|
11
|
+
contentHash: Uint8Array;
|
|
12
|
+
/** The decoded content. */
|
|
13
|
+
mimi: MimiContent;
|
|
14
|
+
}
|
|
15
|
+
/** The Tier-2 projection of a rendered (post/reply) message after folding mutations in. */
|
|
16
|
+
export interface RenderedContent {
|
|
17
|
+
/** Markdown body, or `null` when deleted (tombstone) or non-text. */
|
|
18
|
+
body: string | null;
|
|
19
|
+
/** The replied-to message's content-hash, or `null`. */
|
|
20
|
+
replyTo: Uint8Array | null;
|
|
21
|
+
/** ISO timestamp of the last applied edit, or `null`. */
|
|
22
|
+
editedAt: string | null;
|
|
23
|
+
/** True when a delete tombstone has folded in. */
|
|
24
|
+
deleted: boolean;
|
|
25
|
+
/** token → count (distinct reaction messages bearing that token). */
|
|
26
|
+
reactions: Record<string, number>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Stateful fold over decoded content messages. Feed every decoded message via {@link MessageFold.apply};
|
|
30
|
+
* read the rendered projection of a post/reply via {@link MessageFold.getContent}. Mutation messages
|
|
31
|
+
* (edit/delete/reaction/un-react) fold onto their target and are reported non-renderable.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const fold = new MessageFold();
|
|
36
|
+
* const { renderable } = fold.apply(decoded); // false for a reaction/edit/delete
|
|
37
|
+
* const content = fold.getContent(decoded.messageId); // post/reply projection or null
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class MessageFold {
|
|
41
|
+
private rows;
|
|
42
|
+
private idByHash;
|
|
43
|
+
private reactionReg;
|
|
44
|
+
private pending;
|
|
45
|
+
/** Drop all state (e.g. on conversation switch or full reload before re-folding). */
|
|
46
|
+
reset(): void;
|
|
47
|
+
/**
|
|
48
|
+
* True if `messageId` produced a visible (post/reply) row.
|
|
49
|
+
* @param messageId - The server message id to test.
|
|
50
|
+
* @returns Whether a rendered row exists for it.
|
|
51
|
+
*/
|
|
52
|
+
isRenderable(messageId: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* The rendered projection for a post/reply, or `null` for a folded mutation / unknown id.
|
|
55
|
+
* @param messageId - The server message id to project.
|
|
56
|
+
* @returns A fresh {@link RenderedContent} snapshot, or `null` when the id is not a rendered row.
|
|
57
|
+
*/
|
|
58
|
+
getContent(messageId: string): RenderedContent | null;
|
|
59
|
+
/**
|
|
60
|
+
* Apply one decoded message. Buffers a mutation whose target is unknown.
|
|
61
|
+
*
|
|
62
|
+
* Idempotent on a strict immediate re-apply of the same `messageId`, but NOT across an interleaved
|
|
63
|
+
* re-delivery: re-applying an already-withdrawn reaction id resurrects it (the replayed reaction
|
|
64
|
+
* re-adds itself to the now-empty token set and the prior un-react is not re-triggered). The CONSUMER
|
|
65
|
+
* (the hook) MUST dedup by `messageId` and apply each id at most once — do not re-feed an
|
|
66
|
+
* already-applied message.
|
|
67
|
+
* @param msg - The decoded, content-hashed message to fold in.
|
|
68
|
+
* @returns `{ renderable }` — whether this id is a standalone (post/reply) row.
|
|
69
|
+
*/
|
|
70
|
+
apply(msg: DecodedContentMessage): {
|
|
71
|
+
renderable: boolean;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Resolve the rendered row a content-hash points at, if it has been decoded.
|
|
75
|
+
* @param targetHash - The referenced message's content-hash.
|
|
76
|
+
* @returns The {@link Row}, or `undefined` if the target is unknown or not a rendered row.
|
|
77
|
+
*/
|
|
78
|
+
private resolveRow;
|
|
79
|
+
/**
|
|
80
|
+
* Buffer a mutation against the hex of its (not-yet-decoded) target; replayed by {@link MessageFold.drain}.
|
|
81
|
+
* @param targetHash - The target content-hash to key the buffer under.
|
|
82
|
+
* @param msg - The mutation to defer.
|
|
83
|
+
* @returns `{ renderable: false }` — a buffered mutation is never a standalone row.
|
|
84
|
+
*/
|
|
85
|
+
private buffer;
|
|
86
|
+
/**
|
|
87
|
+
* Replay every mutation buffered against a content-hash that has just been decoded.
|
|
88
|
+
* @param hashHex - The hex content-hash that just appeared (a post/reply or a now-applied reaction).
|
|
89
|
+
*/
|
|
90
|
+
private drain;
|
|
91
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Fold reducer — collapses reaction/edit/delete/un-react MimiContent messages onto their target post.
|
|
3
|
+
//
|
|
4
|
+
// The hybrid reference model: messages REFERENCE each other by MIMI content-hash (resolved here through
|
|
5
|
+
// an in-memory hex(contentHash) → messageId index), while the hook keys STORAGE/ordering/dedup by the
|
|
6
|
+
// server messageId. A mutation whose target hasn't been decoded yet (MLS delivery isn't globally
|
|
7
|
+
// ordered — a reaction can arrive before its message) is BUFFERED by target-hash and applied the moment
|
|
8
|
+
// the target lands ("buffer, never silently drop" — the same fail-closed discipline used for epoch
|
|
9
|
+
// ordering). On reload the index rebuilds for free by recomputing contentHash from the stored canonical
|
|
10
|
+
// bytes, so no hash→id index is persisted. Pure: no React, no crypto, no I/O.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MessageFold = void 0;
|
|
13
|
+
const mimi_content_js_1 = require("../content/mimi-content.js");
|
|
14
|
+
const hex = (b) => {
|
|
15
|
+
let s = "";
|
|
16
|
+
for (const x of b)
|
|
17
|
+
s += x.toString(16).padStart(2, "0");
|
|
18
|
+
return s;
|
|
19
|
+
};
|
|
20
|
+
function textBody(p) {
|
|
21
|
+
if (p.cardinality === mimi_content_js_1.Cardinality.Single)
|
|
22
|
+
return new TextDecoder().decode(p.content);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function classify(m) {
|
|
26
|
+
const isNull = m.nestedPart.cardinality === mimi_content_js_1.Cardinality.Null;
|
|
27
|
+
const isReaction = m.nestedPart.cardinality === mimi_content_js_1.Cardinality.Single &&
|
|
28
|
+
m.nestedPart.disposition === mimi_content_js_1.Disposition.Reaction;
|
|
29
|
+
if (m.replaces) {
|
|
30
|
+
if (isNull)
|
|
31
|
+
return { kind: "delete-or-unreact", target: m.replaces };
|
|
32
|
+
return { kind: "edit", target: m.replaces, body: textBody(m.nestedPart) };
|
|
33
|
+
}
|
|
34
|
+
if (m.inReplyTo) {
|
|
35
|
+
if (isReaction)
|
|
36
|
+
return { kind: "reaction", target: m.inReplyTo, token: textBody(m.nestedPart) ?? "" };
|
|
37
|
+
return { kind: "reply", body: textBody(m.nestedPart), replyTo: m.inReplyTo };
|
|
38
|
+
}
|
|
39
|
+
return { kind: "post", body: textBody(m.nestedPart), replyTo: null };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Stateful fold over decoded content messages. Feed every decoded message via {@link MessageFold.apply};
|
|
43
|
+
* read the rendered projection of a post/reply via {@link MessageFold.getContent}. Mutation messages
|
|
44
|
+
* (edit/delete/reaction/un-react) fold onto their target and are reported non-renderable.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const fold = new MessageFold();
|
|
49
|
+
* const { renderable } = fold.apply(decoded); // false for a reaction/edit/delete
|
|
50
|
+
* const content = fold.getContent(decoded.messageId); // post/reply projection or null
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
class MessageFold {
|
|
54
|
+
constructor() {
|
|
55
|
+
this.rows = new Map(); // messageId → rendered row (post/reply only)
|
|
56
|
+
this.idByHash = new Map(); // hex(contentHash) → messageId (ALL content messages)
|
|
57
|
+
this.reactionReg = new Map(); // reactionMsgId → …
|
|
58
|
+
this.pending = new Map(); // hex(targetHash) → buffered mutations
|
|
59
|
+
}
|
|
60
|
+
/** Drop all state (e.g. on conversation switch or full reload before re-folding). */
|
|
61
|
+
reset() {
|
|
62
|
+
this.rows.clear();
|
|
63
|
+
this.idByHash.clear();
|
|
64
|
+
this.reactionReg.clear();
|
|
65
|
+
this.pending.clear();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* True if `messageId` produced a visible (post/reply) row.
|
|
69
|
+
* @param messageId - The server message id to test.
|
|
70
|
+
* @returns Whether a rendered row exists for it.
|
|
71
|
+
*/
|
|
72
|
+
isRenderable(messageId) {
|
|
73
|
+
return this.rows.has(messageId);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The rendered projection for a post/reply, or `null` for a folded mutation / unknown id.
|
|
77
|
+
* @param messageId - The server message id to project.
|
|
78
|
+
* @returns A fresh {@link RenderedContent} snapshot, or `null` when the id is not a rendered row.
|
|
79
|
+
*/
|
|
80
|
+
getContent(messageId) {
|
|
81
|
+
const r = this.rows.get(messageId);
|
|
82
|
+
if (!r)
|
|
83
|
+
return null;
|
|
84
|
+
const reactions = {};
|
|
85
|
+
for (const [token, set] of r.reactions)
|
|
86
|
+
if (set.size > 0)
|
|
87
|
+
reactions[token] = set.size;
|
|
88
|
+
// Copy `replyTo` so a caller can't mutate the fold's internal hash bytes (body is a string — immutable).
|
|
89
|
+
return { body: r.body, replyTo: r.replyTo ? r.replyTo.slice() : null, editedAt: r.editedAt, deleted: r.deleted, reactions };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Apply one decoded message. Buffers a mutation whose target is unknown.
|
|
93
|
+
*
|
|
94
|
+
* Idempotent on a strict immediate re-apply of the same `messageId`, but NOT across an interleaved
|
|
95
|
+
* re-delivery: re-applying an already-withdrawn reaction id resurrects it (the replayed reaction
|
|
96
|
+
* re-adds itself to the now-empty token set and the prior un-react is not re-triggered). The CONSUMER
|
|
97
|
+
* (the hook) MUST dedup by `messageId` and apply each id at most once — do not re-feed an
|
|
98
|
+
* already-applied message.
|
|
99
|
+
* @param msg - The decoded, content-hashed message to fold in.
|
|
100
|
+
* @returns `{ renderable }` — whether this id is a standalone (post/reply) row.
|
|
101
|
+
*/
|
|
102
|
+
apply(msg) {
|
|
103
|
+
const selfHex = hex(msg.contentHash);
|
|
104
|
+
this.idByHash.set(selfHex, msg.messageId);
|
|
105
|
+
const op = classify(msg.mimi);
|
|
106
|
+
if (op.kind === "post" || op.kind === "reply") {
|
|
107
|
+
const existing = this.rows.get(msg.messageId);
|
|
108
|
+
const row = existing ?? {
|
|
109
|
+
messageId: msg.messageId,
|
|
110
|
+
createdAt: msg.createdAt,
|
|
111
|
+
senderDeviceId: msg.senderDeviceId,
|
|
112
|
+
body: op.body,
|
|
113
|
+
replyTo: op.kind === "reply" ? op.replyTo : null,
|
|
114
|
+
editedAt: null,
|
|
115
|
+
deleted: false,
|
|
116
|
+
reactions: new Map(),
|
|
117
|
+
};
|
|
118
|
+
if (!existing)
|
|
119
|
+
this.rows.set(msg.messageId, row);
|
|
120
|
+
this.drain(selfHex); // a target just appeared → apply anything buffered against it
|
|
121
|
+
return { renderable: true };
|
|
122
|
+
}
|
|
123
|
+
// Mutations resolve a target by content-hash; buffer if the target isn't present yet.
|
|
124
|
+
if (op.kind === "edit") {
|
|
125
|
+
const row = this.resolveRow(op.target);
|
|
126
|
+
if (!row)
|
|
127
|
+
return this.buffer(op.target, msg);
|
|
128
|
+
row.body = op.body;
|
|
129
|
+
row.editedAt = msg.createdAt;
|
|
130
|
+
return { renderable: false };
|
|
131
|
+
}
|
|
132
|
+
if (op.kind === "reaction") {
|
|
133
|
+
const row = this.resolveRow(op.target);
|
|
134
|
+
if (!row)
|
|
135
|
+
return this.buffer(op.target, msg);
|
|
136
|
+
let set = row.reactions.get(op.token);
|
|
137
|
+
if (!set)
|
|
138
|
+
row.reactions.set(op.token, (set = new Set()));
|
|
139
|
+
set.add(msg.messageId);
|
|
140
|
+
this.reactionReg.set(msg.messageId, { targetHash: hex(op.target), token: op.token });
|
|
141
|
+
this.drain(selfHex); // a pending un-react of THIS reaction can now apply
|
|
142
|
+
return { renderable: false };
|
|
143
|
+
}
|
|
144
|
+
// delete-or-unreact: distinguish by whether `replaces` points at a known reaction message.
|
|
145
|
+
if (op.kind === "delete-or-unreact") {
|
|
146
|
+
const targetId = this.idByHash.get(hex(op.target));
|
|
147
|
+
const reaction = targetId ? this.reactionReg.get(targetId) : undefined;
|
|
148
|
+
if (reaction) {
|
|
149
|
+
// Un-react: drop exactly the one reaction message from its target's token set.
|
|
150
|
+
const row = this.resolveRow(fromHex(reaction.targetHash) ?? new Uint8Array());
|
|
151
|
+
row?.reactions.get(reaction.token)?.delete(targetId);
|
|
152
|
+
return { renderable: false };
|
|
153
|
+
}
|
|
154
|
+
// Un-react-before-reaction guard: the reaction message was INDEXED on first sight (so `targetId`
|
|
155
|
+
// resolves) but BUFFERED, not applied — hence no `reactionReg` entry yet AND no rendered row for
|
|
156
|
+
// it. Treat this as an un-react of an as-yet-unapplied reaction: buffer it under the reaction's
|
|
157
|
+
// hash so the reaction branch's `drain(selfHex)` replays the un-react after the reaction folds in.
|
|
158
|
+
// Without this guard the delete path below would tombstone a non-row target as a no-op, then the
|
|
159
|
+
// replayed reaction would survive — net wrong. Fail closed: buffer, never silently drop.
|
|
160
|
+
if (targetId && !this.rows.has(targetId))
|
|
161
|
+
return this.buffer(op.target, msg);
|
|
162
|
+
const row = this.resolveRow(op.target);
|
|
163
|
+
if (!row)
|
|
164
|
+
return this.buffer(op.target, msg); // a delete of an as-yet-unseen post → buffer it
|
|
165
|
+
row.deleted = true;
|
|
166
|
+
row.body = null;
|
|
167
|
+
return { renderable: false };
|
|
168
|
+
}
|
|
169
|
+
// Unreachable: `classify` is exhaustive over Op.kind; satisfies the compiler's return analysis.
|
|
170
|
+
return { renderable: false };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Resolve the rendered row a content-hash points at, if it has been decoded.
|
|
174
|
+
* @param targetHash - The referenced message's content-hash.
|
|
175
|
+
* @returns The {@link Row}, or `undefined` if the target is unknown or not a rendered row.
|
|
176
|
+
*/
|
|
177
|
+
resolveRow(targetHash) {
|
|
178
|
+
const id = this.idByHash.get(hex(targetHash));
|
|
179
|
+
return id ? this.rows.get(id) : undefined;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Buffer a mutation against the hex of its (not-yet-decoded) target; replayed by {@link MessageFold.drain}.
|
|
183
|
+
* @param targetHash - The target content-hash to key the buffer under.
|
|
184
|
+
* @param msg - The mutation to defer.
|
|
185
|
+
* @returns `{ renderable: false }` — a buffered mutation is never a standalone row.
|
|
186
|
+
*/
|
|
187
|
+
buffer(targetHash, msg) {
|
|
188
|
+
const key = hex(targetHash);
|
|
189
|
+
const list = this.pending.get(key) ?? [];
|
|
190
|
+
list.push(msg);
|
|
191
|
+
this.pending.set(key, list);
|
|
192
|
+
return { renderable: false };
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Replay every mutation buffered against a content-hash that has just been decoded.
|
|
196
|
+
* @param hashHex - The hex content-hash that just appeared (a post/reply or a now-applied reaction).
|
|
197
|
+
*/
|
|
198
|
+
drain(hashHex) {
|
|
199
|
+
const list = this.pending.get(hashHex);
|
|
200
|
+
if (!list)
|
|
201
|
+
return;
|
|
202
|
+
this.pending.delete(hashHex);
|
|
203
|
+
for (const m of list)
|
|
204
|
+
this.apply(m);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
exports.MessageFold = MessageFold;
|
|
208
|
+
// Map a hex key back to bytes (for resolving a reaction's stored target-hash). Kept local — the fold is
|
|
209
|
+
// the only place that round-trips hash hex.
|
|
210
|
+
function fromHex(h) {
|
|
211
|
+
if (h.length % 2 !== 0)
|
|
212
|
+
return null;
|
|
213
|
+
const out = new Uint8Array(h.length / 2);
|
|
214
|
+
for (let i = 0; i < out.length; i++)
|
|
215
|
+
out[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=message-fold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-fold.js","sourceRoot":"","sources":["../../../src/hooks/message-fold.ts"],"names":[],"mappings":"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"}
|
|
@@ -94,7 +94,17 @@ function useSecureConversations() {
|
|
|
94
94
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
95
95
|
}, []);
|
|
96
96
|
// Light realtime refresh on membership changes (metadata-only signals).
|
|
97
|
+
//
|
|
98
|
+
// `secure:welcome` is what surfaces a *brand-new* conversation to its recipient: the server emits it
|
|
99
|
+
// (only) to this device's room when someone starts a DM with us (POST /conversations) — there is no
|
|
100
|
+
// `secure:member:joined` on that path (that fires only when a member is added to an *existing* group).
|
|
101
|
+
// Without this listener the recipient's list stays stale until a remount/reload even though the
|
|
102
|
+
// handshake drain already joined the group. The event reaches only our own device room, so it's a
|
|
103
|
+
// precise "a conversation I'm now a member of just appeared" trigger; no payload inspection needed.
|
|
97
104
|
(0, react_1.useEffect)(() => {
|
|
105
|
+
const offWelcome = socket.on("secure:welcome", () => {
|
|
106
|
+
refresh().catch(setError);
|
|
107
|
+
});
|
|
98
108
|
const offJoined = socket.on("secure:member:joined", () => {
|
|
99
109
|
refresh().catch(setError);
|
|
100
110
|
});
|
|
@@ -102,6 +112,7 @@ function useSecureConversations() {
|
|
|
102
112
|
refresh().catch(setError);
|
|
103
113
|
});
|
|
104
114
|
return () => {
|
|
115
|
+
offWelcome();
|
|
105
116
|
offJoined();
|
|
106
117
|
offLeft();
|
|
107
118
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSecureConversations.js","sourceRoot":"","sources":["../../../src/hooks/useSecureConversations.tsx"],"names":[],"mappings":";AAAA,qFAAqF;AACrF,EAAE;AACF,iGAAiG;AACjG,oGAAoG;AACpG,0DAA0D;;AAyC1D,
|
|
1
|
+
{"version":3,"file":"useSecureConversations.js","sourceRoot":"","sources":["../../../src/hooks/useSecureConversations.tsx"],"names":[],"mappings":"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"}
|
|
@@ -156,8 +156,22 @@ function useSecureDevice(options = {}) {
|
|
|
156
156
|
expiresAt: b.expiresAt,
|
|
157
157
|
})),
|
|
158
158
|
});
|
|
159
|
+
// CRITICAL: generateKeyPackages put these KeyPackages' PRIVATE keys into the crypto's in-memory
|
|
160
|
+
// store; only the PUBLIC halves went to the server. Persist the updated device state NOW so those
|
|
161
|
+
// private keys survive a reload. Without this, a peer who claims one of these KeyPackages and
|
|
162
|
+
// builds a Welcome from it can never be joined in a later session: on reload importDeviceState
|
|
163
|
+
// rehydrates the device-state snapshot taken at register() time (before any KeyPackages existed),
|
|
164
|
+
// so processWelcome finds "no matching KeyPackage" and the recipient is stranded on "waiting for
|
|
165
|
+
// key update" forever. register() persists once, but KeyPackages are minted here, after — so this
|
|
166
|
+
// is the only place that captures them. The blob is identity + pending KeyPackages only (no group
|
|
167
|
+
// secrets), so re-exporting on each replenish is cheap.
|
|
168
|
+
await repo.saveDevice({
|
|
169
|
+
deviceId: deviceIdRef.current,
|
|
170
|
+
deviceState: await crypto.exportDeviceState(),
|
|
171
|
+
device,
|
|
172
|
+
});
|
|
159
173
|
return published;
|
|
160
|
-
}, [crypto, rest, device, keyPackageTarget]);
|
|
174
|
+
}, [crypto, rest, repo, device, keyPackageTarget]);
|
|
161
175
|
const refreshKeyPackageCount = (0, react_1.useCallback)(async () => {
|
|
162
176
|
if (!device)
|
|
163
177
|
throw new Error("Register the device before checking KeyPackage count.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSecureDevice.js","sourceRoot":"","sources":["../../../src/hooks/useSecureDevice.tsx"],"names":[],"mappings":";AAAA,qGAAqG;AACrG,yBAAyB;AACzB,EAAE;AACF,kFAAkF;AAClF,sGAAsG;AACtG,+BAA+B;AAC/B,EAAE;AACF,uGAAuG;AACvG,qGAAqG;AACrG,uGAAuG;AACvG,2FAA2F;AAC3F,qGAAqG;AACrG,8DAA8D;;AA0F9D,
|
|
1
|
+
{"version":3,"file":"useSecureDevice.js","sourceRoot":"","sources":["../../../src/hooks/useSecureDevice.tsx"],"names":[],"mappings":";AAAA,qGAAqG;AACrG,yBAAyB;AACzB,EAAE;AACF,kFAAkF;AAClF,sGAAsG;AACtG,+BAA+B;AAC/B,EAAE;AACF,uGAAuG;AACvG,qGAAqG;AACrG,uGAAuG;AACvG,2FAA2F;AAC3F,qGAAqG;AACrG,8DAA8D;;AA0F9D,0CAyQC;AAjWD,iCAAiE;AAEjE,iDAA6C;AAC7C,+CAAqD;AACrD,8EAAkE;AAElE,MAAM,GAAG,GAAG,IAAA,4BAAiB,EAAC,QAAQ,CAAC,CAAC;AAExC;;;;;GAKG;AACH,SAAS,WAAW;IAClB,MAAM,CAAC,GAAI,UAAyD,CAAC,MAAM,CAAC;IAC5E,IAAI,CAAC,EAAE,UAAU;QAAE,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IACzC,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC;AAuDD;;;;;;;;;;;;;;GAcG;AACH,SAAgB,eAAe,CAAC,UAAkC,EAAE;IAClE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,sCAAa,GAAE,CAAC;IACvD,MAAM,EAAE,WAAW,EAAE,gBAAgB,GAAG,EAAE,EAAE,aAAa,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAC7E,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;IAEzF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAA2B,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAU,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,IAAA,gBAAQ,EAAgB,IAAI,CAAC,CAAC;IAEtF,MAAM,WAAW,GAAG,IAAA,cAAM,EAAS,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC,CAAC;IACtE,MAAM,kBAAkB,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAC;IACzC,mGAAmG;IACnG,MAAM,mBAAmB,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAC;IAE1C,6FAA6F;IAC7F,uCAAuC;IACvC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,CAAC,KAAK,IAAI,EAAE;YACV,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1C,4FAA4F;YAC5F,kGAAkG;YAClG,gGAAgG;YAChG,2FAA2F;YAC3F,+FAA+F;YAC/F,6FAA6F;YAC7F,+FAA+F;YAC/F,6FAA6F;YAC7F,8EAA8E;YAC9E,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,0FAA0F;YAC1F,kEAAkE;YAClE,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;gBAC/B,UAAU,CAAC,KAAK,CAAC,CAAC;gBAClB,OAAO;YACT,CAAC;YACD,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;gBAClC,8FAA8F;gBAC9F,+FAA+F;gBAC/F,+FAA+F;gBAC/F,8FAA8F;gBAC9F,8FAA8F;gBAC9F,iGAAiG;gBACjG,0FAA0F;gBAC1F,gGAAgG;gBAChG,IAAI,eAAe,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC;oBACH,eAAe,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACjE,CAAC;gBAAC,OAAO,QAAQ,EAAE,CAAC;oBAClB,GAAG,CAAC,KAAK,CAAC,wEAAwE,EAAE;wBAClF,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;qBACxB,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,KAAK;oBAAE,OAAO;gBACnB,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;oBAC/B,UAAU,CAAC,KAAK,CAAC,CAAC;oBAClB,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,GAAG,CAAC,KAAK,CAAC,+EAA+E,EAAE;wBACzF,QAAQ,EAAE,SAAS,CAAC,QAAQ;qBAC7B,CAAC,CAAC;oBACH,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACtB,IAAI,CAAC,KAAK;wBAAE,OAAO;oBACnB,GAAG,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;gBACzD,CAAC;qBAAM,CAAC;oBACN,MAAM,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;oBACtD,6FAA6F;oBAC7F,2EAA2E;oBAC3E,IAAI,CAAC,KAAK;wBAAE,OAAO;oBACnB,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;wBAC/B,UAAU,CAAC,KAAK,CAAC,CAAC;wBAClB,OAAO;oBACT,CAAC;oBACD,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC;oBACzC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;oBAC5B,GAAG,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YACzD,CAAC;YACD,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACjB,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,QAAQ,CAAC,GAAG,CAAC,CAAC;YACd,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEzB,MAAM,kBAAkB,GAAG,IAAA,mBAAW,EACpC,KAAK,EAAE,QAAgB,gBAAgB,EAAmB,EAAE;QAC1D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACnF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE;YACzD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,UAAU,EAAE,IAAA,oBAAQ,EAAC,CAAC,CAAC,UAAU,CAAC;gBAClC,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;aACvB,CAAC,CAAC;SACJ,CAAC,CAAC;QACH,gGAAgG;QAChG,kGAAkG;QAClG,8FAA8F;QAC9F,+FAA+F;QAC/F,kGAAkG;QAClG,iGAAiG;QACjG,kGAAkG;QAClG,kGAAkG;QAClG,wDAAwD;QACxD,MAAM,IAAI,CAAC,UAAU,CAAC;YACpB,QAAQ,EAAE,WAAW,CAAC,OAAO;YAC7B,WAAW,EAAE,MAAM,MAAM,CAAC,iBAAiB,EAAE;YAC7C,MAAM;SACP,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC,EACD,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAC/C,CAAC;IAEF,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAqB,EAAE;QACrE,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,uBAAuB,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,SAAS,CAAC;IACnB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnB,8FAA8F;IAC9F,sGAAsG;IACtG,2EAA2E;IAC3E,MAAM,iBAAiB,GAAG,IAAA,mBAAW,EACnC,KAAK,EAAE,SAAiB,EAAmB,EAAE;QAC3C,MAAM,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAAC;QAC7C,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;YACjB,GAAG,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAC/F,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACpD,uBAAuB,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;QAC/C,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE;YACpC,SAAS;YACT,MAAM,EAAE,gBAAgB;YACxB,OAAO;YACP,SAAS;SACV,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC,EACD,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CACvC,CAAC;IAEF,MAAM,iBAAiB,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAqB,EAAE;QAChE,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,CAAC,kEAAkE;QACzF,MAAM,SAAS,GAAG,MAAM,sBAAsB,EAAE,CAAC;QACjD,IAAI,SAAS,IAAI,kBAAkB;YAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,EAAE,CAAC,MAAM,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE5E,MAAM,QAAQ,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAgC,EAAE;QAClE,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAC;QAClC,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,uFAAuF;YACvF,+FAA+F;YAC/F,+FAA+F;YAC/F,kGAAkG;YAClG,iGAAiG;YACjG,kGAAkG;YAClG,8FAA8F;YAC9F,2EAA2E;YAC3E,kGAAkG;YAClG,iGAAiG;YACjG,4FAA4F;YAC5F,kGAAkG;YAClG,+FAA+F;YAC/F,8DAA8D;YAC9D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1C,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;gBAClC,IAAI,eAAe,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC;oBACH,eAAe,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACjE,CAAC;gBAAC,OAAO,QAAQ,EAAE,CAAC;oBAClB,GAAG,CAAC,KAAK,CAAC,uEAAuE,EAAE;wBACjF,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;qBACxB,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,eAAe,EAAE,CAAC;oBACpB,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;wBACtD,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC;wBACzC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;wBAC5B,GAAG,CAAC,KAAK,CAAC,gDAAgD,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;wBAC9F,OAAO,SAAS,CAAC,MAAM,CAAC;oBAC1B,CAAC;oBAAC,OAAO,SAAS,EAAE,CAAC;wBACnB,GAAG,CAAC,KAAK,CAAC,+CAA+C,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;oBAC3F,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,KAAK,CAAC,gFAAgF,EAAE;wBAC1F,QAAQ,EAAE,SAAS,CAAC,QAAQ;qBAC7B,CAAC,CAAC;oBACH,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACxB,CAAC;YACH,CAAC;YACD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC;gBACvD,QAAQ,EAAE,WAAW,CAAC,OAAO;gBAC7B,WAAW;aACZ,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;gBAC3C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,kBAAkB,EAAE,IAAA,oBAAQ,EAAC,QAAQ,CAAC,kBAAkB,CAAC;gBACzD,UAAU,EAAE,IAAA,oBAAQ,EAAC,QAAQ,CAAC,UAAU,CAAC;gBACzC,WAAW,EAAE,QAAQ,CAAC,WAAW;aAClC,CAAC,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACrD,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACxF,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC;YACxC,SAAS,CAAC,UAAU,CAAC,CAAC;YACtB,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;YACnG,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAEtC,qGAAqG;IACrG,gGAAgG;IAChG,mEAAmE;IACnE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM;YAAE,OAAO;QACtC,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1D,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE;gBAAE,OAAO,CAAC,mDAAmD;YAC9F,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACrG,uBAAuB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC1C,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAEvD,oGAAoG;IACpG,qFAAqF;IACrF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,IAAI,mBAAmB,CAAC,OAAO;YAAE,OAAO;QACrE,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC;QACnC,iBAAiB,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE/C,OAAO;QACL,MAAM;QACN,OAAO;QACP,WAAW;QACX,KAAK;QACL,oBAAoB;QACpB,QAAQ;QACR,kBAAkB;QAClB,sBAAsB;QACtB,iBAAiB;KAClB,CAAC;AACJ,CAAC"}
|
|
@@ -81,6 +81,17 @@ function useSecureHandshakes(options = {}) {
|
|
|
81
81
|
const liveBuffer = [];
|
|
82
82
|
let queue = Promise.resolve();
|
|
83
83
|
let deviceId;
|
|
84
|
+
// A Welcome addressed to US that throws is RETRYABLE — not a poison blob. The usual cause is that
|
|
85
|
+
// its KeyPackage private key isn't in the crypto store yet (device-state rehydration mid-flight),
|
|
86
|
+
// which clears on the next drain/reload. So we must NOT advance the cursor past it (that would skip
|
|
87
|
+
// it forever, stranding the recipient on "waiting for key update"). `blocked` holds the cursor for
|
|
88
|
+
// the rest of THIS drain once we're holding — later rows must not advance past the held Welcome —
|
|
89
|
+
// and is reset at the start of each runCatchUp so the next drain re-fetches `since=cursor` and
|
|
90
|
+
// retries. `attempts` bounds per-seq retries so a genuinely-poison for-us Welcome can't wedge the
|
|
91
|
+
// inbox forever: after the cap we advance (surfaced via onError) like any other skippable row.
|
|
92
|
+
let blocked = false;
|
|
93
|
+
const attempts = new Map();
|
|
94
|
+
const MAX_WELCOME_RETRIES = 3;
|
|
84
95
|
const report = (err, h) => {
|
|
85
96
|
if (alive)
|
|
86
97
|
setError(err);
|
|
@@ -147,16 +158,38 @@ function useSecureHandshakes(options = {}) {
|
|
|
147
158
|
log.trace("dedupe — already past cursor", { seq: h.seq, cursor: cursorRef.current });
|
|
148
159
|
return;
|
|
149
160
|
}
|
|
161
|
+
// Holding a retryable for-us Welcome earlier in the stream: don't advance past it this drain (a
|
|
162
|
+
// later row advancing the cursor would skip the held Welcome on the next catch-up). Resume next.
|
|
163
|
+
if (blocked)
|
|
164
|
+
return;
|
|
150
165
|
try {
|
|
151
166
|
await dispatchByKind(h);
|
|
152
167
|
}
|
|
153
168
|
catch (err) {
|
|
154
|
-
|
|
169
|
+
report(err, h);
|
|
170
|
+
// A Welcome addressed to us that failed is retryable (see the `blocked`/`attempts` note above):
|
|
171
|
+
// hold the cursor so the next catch-up re-attempts, up to MAX_WELCOME_RETRIES this session.
|
|
172
|
+
// Everything else — a Welcome not for us, a Commit for an unknown group, a malformed blob we
|
|
173
|
+
// can never use — stays skippable so a poison row can't wedge the inbox.
|
|
174
|
+
const forUsWelcome = h.kind === "welcome" && (!h.targetDeviceId || h.targetDeviceId === deviceId);
|
|
175
|
+
const tries = (attempts.get(h.seq) ?? 0) + 1;
|
|
176
|
+
attempts.set(h.seq, tries);
|
|
177
|
+
if (forUsWelcome && tries < MAX_WELCOME_RETRIES) {
|
|
178
|
+
blocked = true;
|
|
179
|
+
log.debug("for-us welcome failed — holding cursor for retry on next catch-up", {
|
|
180
|
+
seq: h.seq,
|
|
181
|
+
attempt: tries,
|
|
182
|
+
error: err instanceof Error ? err.message : String(err),
|
|
183
|
+
});
|
|
184
|
+
return; // leave the cursor untouched: the next catch-up re-fetches `since=cursor` and retries
|
|
185
|
+
}
|
|
186
|
+
log.debug("dispatch failed — advancing cursor past row", {
|
|
155
187
|
seq: h.seq,
|
|
156
188
|
kind: h.kind,
|
|
189
|
+
forUsWelcome,
|
|
190
|
+
attempts: tries,
|
|
157
191
|
error: err instanceof Error ? err.message : String(err),
|
|
158
192
|
});
|
|
159
|
-
report(err, h);
|
|
160
193
|
}
|
|
161
194
|
cursorRef.current = h.seq;
|
|
162
195
|
await repo.saveHandshakeCursor(deviceId, h.seq);
|
|
@@ -190,6 +223,7 @@ function useSecureHandshakes(options = {}) {
|
|
|
190
223
|
return catchUpInFlight;
|
|
191
224
|
catchUpInFlight = (async () => {
|
|
192
225
|
catchingUpRef.current = true;
|
|
226
|
+
blocked = false; // a fresh drain re-attempts any for-us Welcome held in a prior drain
|
|
193
227
|
log.debug("catch-up start", { deviceId, fromCursor: cursorRef.current, pageSize });
|
|
194
228
|
let pages = 0;
|
|
195
229
|
let fetched = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSecureHandshakes.js","sourceRoot":"","sources":["../../../src/hooks/useSecureHandshakes.tsx"],"names":[],"mappings":";AAAA,kGAAkG;AAClG,EAAE;AACF,oGAAoG;AACpG,6FAA6F;AAC7F,oGAAoG;AACpG,sGAAsG;AACtG,sGAAsG;AACtG,4FAA4F;AAC5F,mBAAmB;AACnB,EAAE;AACF,mGAAmG;AACnG,uGAAuG;AACvG,yDAAyD;;AAgFzD,
|
|
1
|
+
{"version":3,"file":"useSecureHandshakes.js","sourceRoot":"","sources":["../../../src/hooks/useSecureHandshakes.tsx"],"names":[],"mappings":"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"}
|