@oxidezap/baileyrs 0.0.18 → 0.0.21
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/lib/Bridge/__tests__/adapt.test.js +41 -9
- package/lib/Bridge/__tests__/adapt.test.js.map +1 -1
- package/lib/Bridge/adapt.d.ts +10 -16
- package/lib/Bridge/adapt.d.ts.map +1 -1
- package/lib/Bridge/adapt.js +12 -515
- package/lib/Bridge/adapt.js.map +1 -1
- package/lib/Bridge/schema.d.ts +36 -0
- package/lib/Bridge/schema.d.ts.map +1 -0
- package/lib/Bridge/schema.js +773 -0
- package/lib/Bridge/schema.js.map +1 -0
- package/lib/Bridge/types.d.ts +257 -3
- package/lib/Bridge/types.d.ts.map +1 -1
- package/lib/Socket/events.d.ts +18 -9
- package/lib/Socket/events.d.ts.map +1 -1
- package/lib/Socket/events.js +520 -204
- package/lib/Socket/events.js.map +1 -1
- package/lib/Socket/group-notifications.d.ts +6 -0
- package/lib/Socket/group-notifications.d.ts.map +1 -1
- package/lib/Socket/group-notifications.js +123 -16
- package/lib/Socket/group-notifications.js.map +1 -1
- package/lib/Socket/groups.d.ts +10 -2
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +24 -30
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +31 -8
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +178 -13
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages.d.ts +13 -2
- package/lib/Socket/messages.d.ts.map +1 -1
- package/lib/Socket/messages.js +27 -6
- package/lib/Socket/messages.js.map +1 -1
- package/lib/Types/Call.d.ts +20 -0
- package/lib/Types/Call.d.ts.map +1 -1
- package/lib/Types/Contact.d.ts +3 -1
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +2 -0
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Utils/generics.d.ts +17 -0
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +31 -0
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/group-stub-params.d.ts +29 -0
- package/lib/Utils/group-stub-params.d.ts.map +1 -0
- package/lib/Utils/group-stub-params.js +45 -0
- package/lib/Utils/group-stub-params.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +1 -1
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +1 -1
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +4 -6
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/process-history-message.d.ts +30 -0
- package/lib/Utils/process-history-message.d.ts.map +1 -0
- package/lib/Utils/process-history-message.js +148 -0
- package/lib/Utils/process-history-message.js.map +1 -0
- package/lib/Utils/use-bridge-store.d.ts.map +1 -1
- package/lib/Utils/use-bridge-store.js +50 -6
- package/lib/Utils/use-bridge-store.js.map +1 -1
- package/lib/Utils/use-multi-file-auth-state.d.ts +7 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -1
- package/lib/Utils/use-multi-file-auth-state.js +11 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
- package/lib/Utils/wrap-legacy-store.d.ts.map +1 -1
- package/lib/Utils/wrap-legacy-store.js +110 -90
- package/lib/Utils/wrap-legacy-store.js.map +1 -1
- package/lib/WABinary/generic-utils.d.ts +17 -0
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +44 -0
- package/lib/WABinary/generic-utils.js.map +1 -0
- package/lib/WABinary/index.d.ts +1 -0
- package/lib/WABinary/index.d.ts.map +1 -1
- package/lib/WABinary/index.js +1 -0
- package/lib/WABinary/index.js.map +1 -1
- package/lib/WABinary/jid-utils.d.ts +4 -0
- package/lib/WABinary/jid-utils.d.ts.map +1 -1
- package/lib/WABinary/jid-utils.js +4 -0
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/__tests__/expect.d.ts +14 -0
- package/lib/__tests__/expect.d.ts.map +1 -1
- package/lib/__tests__/expect.js +42 -2
- package/lib/__tests__/expect.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-bridge-store.d.ts","sourceRoot":"","sources":["../../src/Utils/use-bridge-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"use-bridge-store.d.ts","sourceRoot":"","sources":["../../src/Utils/use-bridge-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAsC5D;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAsIvG"}
|
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
2
|
import { mkdir, readFile, unlink, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Stores whose loss on SIGKILL produces undecryptable messages or
|
|
6
|
+
* permanent app-state divergence. Each entry below carries a reason —
|
|
7
|
+
* promoting a store to "critical" doubles disk I/O, so don't add
|
|
8
|
+
* anything here that can be re-derived from the network.
|
|
9
|
+
*
|
|
10
|
+
* `session` / `identity` — Signal session ratchet steps. Lose
|
|
11
|
+
* one step → next inbound message from peer undecryptable.
|
|
12
|
+
* `device` — own device record (noiseKey, signedIdentityKey,
|
|
13
|
+
* adv_secret_key). Loss = forced re-pair.
|
|
14
|
+
* `prekey` — consumed prekey must be durably consumed; reuse
|
|
15
|
+
* on a different peer makes the server reject the bundle.
|
|
16
|
+
* `sync_key` — app-state HMAC key. Loss → permanent gap in
|
|
17
|
+
* app-state mutations until full re-sync.
|
|
18
|
+
* `sender_key` — group-message ratchet (same model as `session`,
|
|
19
|
+
* but per group). Lose a step → next inbound message from the
|
|
20
|
+
* same group undecryptable.
|
|
21
|
+
* `sync_version` — LTHash state per app-state collection
|
|
22
|
+
* (regular_high / regular_low / critical_block / etc.). Gates
|
|
23
|
+
* every mutation MAC verification — lose it and every
|
|
24
|
+
* subsequent app-state action throws "hash mismatch" until
|
|
25
|
+
* full re-sync.
|
|
26
|
+
* `mutation_mac` — replay-protection cache for app-state
|
|
27
|
+
* mutations. Loss can let a replayed mutation re-apply.
|
|
28
|
+
*/
|
|
29
|
+
const CRITICAL_STORES = new Set([
|
|
30
|
+
'session',
|
|
31
|
+
'identity',
|
|
32
|
+
'device',
|
|
33
|
+
'prekey',
|
|
34
|
+
'sync_key',
|
|
35
|
+
'sender_key',
|
|
36
|
+
'sync_version',
|
|
37
|
+
'mutation_mac'
|
|
38
|
+
]);
|
|
4
39
|
/**
|
|
5
40
|
* Creates a file-based store for the WASM bridge.
|
|
6
41
|
*
|
|
@@ -43,9 +78,21 @@ export async function useBridgeStore(folder) {
|
|
|
43
78
|
// Ignore — folder may have been deleted during cleanup
|
|
44
79
|
}
|
|
45
80
|
};
|
|
81
|
+
const FLUSH_MAX_PASSES = 32;
|
|
46
82
|
const flushAll = async () => {
|
|
47
|
-
|
|
48
|
-
|
|
83
|
+
// Drain in a loop because new sets can land while we're awaiting the
|
|
84
|
+
// previous batch's writeFile. Bounded so a caller emitting writes in
|
|
85
|
+
// a tight loop can't lock us forever — `Socket/index.ts.end()` waits
|
|
86
|
+
// on this and must always return. If the cap is hit with writes
|
|
87
|
+
// still pending, surface that to the caller — silently dropping
|
|
88
|
+
// them would lose Signal session steps and corrupt next decrypt.
|
|
89
|
+
for (let i = 0; i < FLUSH_MAX_PASSES && pendingWrites.size > 0; i++) {
|
|
90
|
+
const keys = [...pendingWrites.keys()];
|
|
91
|
+
await Promise.all(keys.map(flushWrite));
|
|
92
|
+
}
|
|
93
|
+
if (pendingWrites.size > 0) {
|
|
94
|
+
throw new Error(`use-bridge-store flushAll did not quiesce after ${FLUSH_MAX_PASSES} passes (${pendingWrites.size} pending writes remain)`);
|
|
95
|
+
}
|
|
49
96
|
};
|
|
50
97
|
return {
|
|
51
98
|
async get(store, key) {
|
|
@@ -75,10 +122,7 @@ export async function useBridgeStore(folder) {
|
|
|
75
122
|
return;
|
|
76
123
|
}
|
|
77
124
|
touchCache(cacheKey, value);
|
|
78
|
-
|
|
79
|
-
// losing a ratchet step on crash causes undecryptable messages.
|
|
80
|
-
const critical = store === 'session' || store === 'identity' || store === 'device';
|
|
81
|
-
if (critical) {
|
|
125
|
+
if (CRITICAL_STORES.has(store)) {
|
|
82
126
|
const existing = pendingWrites.get(cacheKey);
|
|
83
127
|
if (existing) {
|
|
84
128
|
clearTimeout(existing.timer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-bridge-store.js","sourceRoot":"","sources":["../../src/Utils/use-bridge-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IAClD,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAExC,wDAAwD;IACxD,MAAM,iBAAiB,GAAG,IAAI,CAAA;IAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;IAC3C,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,KAAiB,EAAE,EAAE;QACrD,0DAA0D;QAC1D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACjB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACrB,qCAAqC;QACrC,IAAI,KAAK,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAA;YACxC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;IACF,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAExG,4DAA4D;IAC5D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAqF,CAAA;IAClH,MAAM,cAAc,GAAG,EAAE,CAAA;IAEzB,MAAM,UAAU,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;QAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC3B,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC9B,IAAI,CAAC;YACJ,MAAM,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QAC7C,CAAC;QAAC,MAAM,CAAC;YACR,uDAAuD;QACxD,CAAC;IACF,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC3B,MAAM,IAAI,GAAG,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"use-bridge-store.js","sourceRoot":"","sources":["../../src/Utils/use-bridge-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC;IACpD,SAAS;IACT,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,cAAc;IACd,cAAc;CACd,CAAC,CAAA;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IAClD,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAExC,wDAAwD;IACxD,MAAM,iBAAiB,GAAG,IAAI,CAAA;IAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;IAC3C,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,KAAiB,EAAE,EAAE;QACrD,0DAA0D;QAC1D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACjB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACrB,qCAAqC;QACrC,IAAI,KAAK,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAA;YACxC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;IACF,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAExG,4DAA4D;IAC5D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAqF,CAAA;IAClH,MAAM,cAAc,GAAG,EAAE,CAAA;IAEzB,MAAM,UAAU,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;QAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC3B,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC9B,IAAI,CAAC;YACJ,MAAM,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QAC7C,CAAC;QAAC,MAAM,CAAC;YACR,uDAAuD;QACxD,CAAC;IACF,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,EAAE,CAAA;IAC3B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC3B,qEAAqE;QACrE,qEAAqE;QACrE,qEAAqE;QACrE,gEAAgE;QAChE,gEAAgE;QAChE,iEAAiE;QACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAA;YACtC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;QACxC,CAAC;QACD,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACd,mDAAmD,gBAAgB,YAAY,aAAa,CAAC,IAAI,yBAAyB,CAC1H,CAAA;QACF,CAAC;IACF,CAAC,CAAA;IAED,OAAO;QACN,KAAK,CAAC,GAAG,CAAC,KAAa,EAAE,GAAW;YACnC,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,GAAG,EAAE,CAAA;YAEnC,oBAAoB;YACpB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAClC,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAA;YAEzB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC3C,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAC,KAAK,CAAA;YAEjC,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;gBACjD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;gBACzE,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;gBACzB,OAAO,GAAG,CAAA;YACX,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,IAAI,CAAA;YACZ,CAAC;QACF,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,KAAiB;YACtD,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,GAAG,EAAE,CAAA;YAEnC,qDAAqD;YACrD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAChC,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC1D,OAAM;YACP,CAAC;YAED,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YAE3B,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBAC5C,IAAI,QAAQ,EAAE,CAAC;oBACd,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;oBAC5B,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;gBAC/B,CAAC;gBAED,IAAI,CAAC;oBACJ,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;gBAC7C,CAAC;gBAAC,MAAM,CAAC;oBACR,kDAAkD;gBACnD,CAAC;gBAED,OAAM;YACP,CAAC;YAED,6DAA6D;YAC7D,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACd,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YAC7B,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;YACjC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAA;YACzE,KAAK,CAAC,KAAK,EAAE,CAAA,CAAC,oDAAoD;YAClE,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;QACpD,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,GAAW;YACtC,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,GAAG,EAAE,CAAA;YACnC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAEtB,uBAAuB;YACvB,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACd,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBAC5B,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC/B,CAAC;YAED,IAAI,CAAC;gBACJ,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;YACnC,CAAC;YAAC,MAAM,CAAC;gBACR,+BAA+B;YAChC,CAAC;QACF,CAAC;QAED,KAAK,EAAE,QAAQ;KACf,CAAA;AACF,CAAC"}
|
|
@@ -5,9 +5,16 @@ import type { AuthenticationState } from '../Types/index.js';
|
|
|
5
5
|
* All crypto keys, sessions, and identity are managed by the Rust engine
|
|
6
6
|
* and persisted as `.bin` files via the bridge store. No `creds.json` needed.
|
|
7
7
|
*
|
|
8
|
+
* Returns a `saveCreds` no-op for upstream-Baileys API parity. Upstream
|
|
9
|
+
* bots wire `ev.on('creds.update', saveCreds)` as the persistence hook;
|
|
10
|
+
* in baileyrs the bridge auto-persists everything through the store, so
|
|
11
|
+
* the function is a stable shim that lets the same call sites keep
|
|
12
|
+
* working without changes.
|
|
13
|
+
*
|
|
8
14
|
* @param folder Directory to store bridge state files
|
|
9
15
|
*/
|
|
10
16
|
export declare const useMultiFileAuthState: (folder: string) => Promise<{
|
|
11
17
|
state: AuthenticationState;
|
|
18
|
+
saveCreds: () => Promise<void>;
|
|
12
19
|
}>;
|
|
13
20
|
//# sourceMappingURL=use-multi-file-auth-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-multi-file-auth-state.d.ts","sourceRoot":"","sources":["../../src/Utils/use-multi-file-auth-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAG5D
|
|
1
|
+
{"version":3,"file":"use-multi-file-auth-state.d.ts","sourceRoot":"","sources":["../../src/Utils/use-multi-file-auth-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAG5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GACjC,QAAQ,MAAM,KACZ,OAAO,CAAC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAqBxE,CAAA"}
|
|
@@ -6,6 +6,12 @@ import { useBridgeStore } from "./use-bridge-store.js";
|
|
|
6
6
|
* All crypto keys, sessions, and identity are managed by the Rust engine
|
|
7
7
|
* and persisted as `.bin` files via the bridge store. No `creds.json` needed.
|
|
8
8
|
*
|
|
9
|
+
* Returns a `saveCreds` no-op for upstream-Baileys API parity. Upstream
|
|
10
|
+
* bots wire `ev.on('creds.update', saveCreds)` as the persistence hook;
|
|
11
|
+
* in baileyrs the bridge auto-persists everything through the store, so
|
|
12
|
+
* the function is a stable shim that lets the same call sites keep
|
|
13
|
+
* working without changes.
|
|
14
|
+
*
|
|
9
15
|
* @param folder Directory to store bridge state files
|
|
10
16
|
*/
|
|
11
17
|
export const useMultiFileAuthState = async (folder) => {
|
|
@@ -20,7 +26,11 @@ export const useMultiFileAuthState = async (folder) => {
|
|
|
20
26
|
}
|
|
21
27
|
const store = await useBridgeStore(folder);
|
|
22
28
|
return {
|
|
23
|
-
state: { store }
|
|
29
|
+
state: { store },
|
|
30
|
+
saveCreds: async () => {
|
|
31
|
+
// no-op: bridge owns creds and writes them through `store.set('device', …)`.
|
|
32
|
+
// Kept on the surface so upstream-Baileys code paths keep type-checking.
|
|
33
|
+
}
|
|
24
34
|
};
|
|
25
35
|
};
|
|
26
36
|
//# sourceMappingURL=use-multi-file-auth-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-multi-file-auth-state.js","sourceRoot":"","sources":["../../src/Utils/use-multi-file-auth-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD
|
|
1
|
+
{"version":3,"file":"use-multi-file-auth-state.js","sourceRoot":"","sources":["../../src/Utils/use-multi-file-auth-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACzC,MAAc,EAC4D,EAAE;IAC5E,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACrD,IAAI,UAAU,EAAE,CAAC;QAChB,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACd,8CAA8C,MAAM,oDAAoD,CACxG,CAAA;QACF,CAAC;IACF,CAAC;SAAM,CAAC;QACP,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAA;IAE1C,OAAO;QACN,KAAK,EAAE,EAAE,KAAK,EAAE;QAChB,SAAS,EAAE,KAAK,IAAI,EAAE;YACrB,6EAA6E;YAC7E,yEAAyE;QAC1E,CAAC;KACD,CAAA;AACF,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-legacy-store.d.ts","sourceRoot":"","sources":["../../src/Utils/wrap-legacy-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,KAAK,EAAuB,mBAAmB,EAAkC,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"wrap-legacy-store.d.ts","sourceRoot":"","sources":["../../src/Utils/wrap-legacy-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,KAAK,EAAuB,mBAAmB,EAAkC,MAAM,mBAAmB,CAAA;AAuBjH,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,OAAO,IAAI,IAAI,CAAA;CACf;AAu+BD,wBAAsB,eAAe,CACpC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC9B,MAAM,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GACrD,OAAO,CAAC,kBAAkB,CAAC,CA+P7B;AASD;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAoEzE"}
|
|
@@ -15,6 +15,8 @@ import { createHmac } from 'node:crypto';
|
|
|
15
15
|
import { mkdir, readFile, stat, unlink, writeFile } from 'node:fs/promises';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import { proto } from 'whatsapp-rust-bridge/proto-types';
|
|
18
|
+
import { jidDecode } from "../WABinary/jid-utils.js";
|
|
19
|
+
import { BufferJSON } from "./generics.js";
|
|
18
20
|
const protoLookup = proto;
|
|
19
21
|
const ADVSignedDeviceIdentity = protoLookup.ADVSignedDeviceIdentity ?? protoLookup.AdvSignedDeviceIdentity;
|
|
20
22
|
function warn(msg, err) {
|
|
@@ -47,36 +49,32 @@ const STORE_MAP = {
|
|
|
47
49
|
mutation_mac: 'bridge-mutation-mac',
|
|
48
50
|
meta: 'bridge-meta'
|
|
49
51
|
};
|
|
50
|
-
// Stores
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
// • has a different value-byte encoding (proto / JSON / 32-vs-33-byte
|
|
55
|
-
// prefix), OR
|
|
56
|
-
// • both.
|
|
57
|
-
// Keeping the empty set as an extension point — future bridge stores that
|
|
58
|
-
// are byte-compatible with upstream can land here without a converter.
|
|
52
|
+
// Stores that are byte-compatible between bridge and upstream and so can
|
|
53
|
+
// be persisted unchanged. Currently empty — every Signal record needs
|
|
54
|
+
// either a key rewrite or a value-byte conversion, both handled by
|
|
55
|
+
// `converters` below.
|
|
59
56
|
const BINARY_STORES = new Set();
|
|
60
|
-
// Bridge-only stores — raw binary persisted through keys interface.
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// the
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
'
|
|
68
|
-
|
|
69
|
-
'sent_message',
|
|
70
|
-
'mutation_mac',
|
|
71
|
-
'meta'
|
|
72
|
-
]);
|
|
57
|
+
// Bridge-only stores — raw binary persisted through the keys interface.
|
|
58
|
+
// Derived from STORE_MAP: anything mapped to a `bridge-*` upstream type
|
|
59
|
+
// has no peer in upstream Baileys' SignalDataTypeMap and must round-trip
|
|
60
|
+
// as raw bytes. `lid_mapping` is mapped to upstream's `lid-mapping` type
|
|
61
|
+
// instead (its converter rewrites the key prefixes), so it's not
|
|
62
|
+
// bridge-only and is naturally excluded by the prefix filter.
|
|
63
|
+
const BRIDGE_ONLY_STORES = new Set(Object.entries(STORE_MAP)
|
|
64
|
+
.filter(([, upstreamType]) => upstreamType.startsWith('bridge-'))
|
|
65
|
+
.map(([bridgeName]) => bridgeName));
|
|
73
66
|
/** Reconstruct a JID string from the bridge's serialized Jid object.
|
|
74
|
-
* Format:
|
|
67
|
+
* Format: `user[_<agent>][:<device>]@<server>`. The agent suffix is
|
|
68
|
+
* required to round-trip hosted Business accounts (`5511_2@hosted`) —
|
|
69
|
+
* `credsToDeviceJson` stores it, so the load path must also emit it.
|
|
70
|
+
* Without this, `creds.me.id` would lose the `_<agent>` half on every
|
|
71
|
+
* reload and the next `credsToDeviceJson` save would zero `agent`. */
|
|
75
72
|
function bridgeJidToString(j) {
|
|
76
73
|
if (!j?.user || !j?.server)
|
|
77
74
|
return null;
|
|
75
|
+
const agent = j.agent ?? 0;
|
|
78
76
|
const device = j.device ?? 0;
|
|
79
|
-
return `${j.user}${device > 0 ? ':' + device : ''}@${j.server}`;
|
|
77
|
+
return `${j.user}${agent > 0 ? '_' + agent : ''}${device > 0 ? ':' + device : ''}@${j.server}`;
|
|
80
78
|
}
|
|
81
79
|
// ---- Helpers ----
|
|
82
80
|
const toJson = (v) => new TextEncoder().encode(JSON.stringify(v));
|
|
@@ -85,6 +83,24 @@ const toBuf = (v) => v instanceof Uint8Array ? v : Buffer.isBuffer(v) ? new Uint
|
|
|
85
83
|
/** Convert Buffer/Uint8Array to a plain number[] for JSON serialization.
|
|
86
84
|
* Matches Rust's serde_json Vec<u8> format: [byte, byte, ...] */
|
|
87
85
|
const bufToNumArray = (v) => Array.from(Buffer.from(v));
|
|
86
|
+
/**
|
|
87
|
+
* `true` when the key bytes are absent or all zeros. Used at the device-read
|
|
88
|
+
* boundary to detect a partially-hydrated creds object (e.g. migration
|
|
89
|
+
* remnants where only `me.id` survived) and tell the bridge to bootstrap
|
|
90
|
+
* fresh material instead of blowing up the noise handshake with `precondition-required`.
|
|
91
|
+
*/
|
|
92
|
+
const isZeroKey = (b) => {
|
|
93
|
+
if (!b)
|
|
94
|
+
return true;
|
|
95
|
+
// Buffer is a Uint8Array subclass at runtime, so this view is always safe.
|
|
96
|
+
const view = b;
|
|
97
|
+
if (view.length === 0)
|
|
98
|
+
return true;
|
|
99
|
+
for (let i = 0; i < view.length; i++)
|
|
100
|
+
if (view[i] !== 0)
|
|
101
|
+
return false;
|
|
102
|
+
return true;
|
|
103
|
+
};
|
|
88
104
|
/** Bridge uses hex-encoded key IDs for sync_key; upstream uses base64. Convert hex→base64. */
|
|
89
105
|
const hexToBase64 = (hex) => Buffer.from(hex, 'hex').toString('base64');
|
|
90
106
|
const converters = {
|
|
@@ -336,21 +352,6 @@ const converters = {
|
|
|
336
352
|
}
|
|
337
353
|
}
|
|
338
354
|
};
|
|
339
|
-
// BufferJSON-compatible replacer/reviver matching upstream `Utils/generics`.
|
|
340
|
-
const bufferJsonReplacer = (_k, v) => {
|
|
341
|
-
if (Buffer.isBuffer(v) || v instanceof Uint8Array || v?.type === 'Buffer') {
|
|
342
|
-
const data = v?.data ?? v;
|
|
343
|
-
return { type: 'Buffer', data: Buffer.from(data).toString('base64') };
|
|
344
|
-
}
|
|
345
|
-
return v;
|
|
346
|
-
};
|
|
347
|
-
const bufferJsonReviver = (_k, v) => {
|
|
348
|
-
const obj = v;
|
|
349
|
-
if (obj && typeof obj === 'object' && obj.type === 'Buffer' && typeof obj.data === 'string') {
|
|
350
|
-
return Buffer.from(obj.data, 'base64');
|
|
351
|
-
}
|
|
352
|
-
return v;
|
|
353
|
-
};
|
|
354
355
|
const sk_toBytes = (v) => v ? new Uint8Array(Buffer.from(v)) : new Uint8Array();
|
|
355
356
|
const sk_toBuffer = (v) => Buffer.from(v ?? new Uint8Array());
|
|
356
357
|
function bridgeSenderKeyProtoToJson(protoBytes) {
|
|
@@ -367,10 +368,10 @@ function bridgeSenderKeyProtoToJson(protoBytes) {
|
|
|
367
368
|
seed: sk_toBuffer(mk.seed)
|
|
368
369
|
}))
|
|
369
370
|
}));
|
|
370
|
-
return Buffer.from(JSON.stringify(states,
|
|
371
|
+
return Buffer.from(JSON.stringify(states, BufferJSON.replacer), 'utf-8');
|
|
371
372
|
}
|
|
372
373
|
function upstreamSenderKeyJsonToProto(jsonBuf) {
|
|
373
|
-
const states = JSON.parse(Buffer.from(jsonBuf).toString('utf-8'),
|
|
374
|
+
const states = JSON.parse(Buffer.from(jsonBuf).toString('utf-8'), BufferJSON.reviver);
|
|
374
375
|
const senderKeyStates = states.map(s => ({
|
|
375
376
|
senderKeyId: s.senderKeyId ?? 0,
|
|
376
377
|
senderChainKey: { iteration: s.senderChainKey?.iteration ?? 0, seed: sk_toBytes(s.senderChainKey?.seed) },
|
|
@@ -607,20 +608,27 @@ function upstreamSessionRecordToProto(record) {
|
|
|
607
608
|
// session/identity key translation: bridge `{user}[:dev]@{server}.{sig}`
|
|
608
609
|
// → upstream `{signalUser}.{deviceId}` via `bridgeAddrToBaileysAddr`.
|
|
609
610
|
// ---- Device/Creds ----
|
|
610
|
-
/**
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
611
|
+
/**
|
|
612
|
+
* Extract the literal `_<n>` agent suffix from a raw JID. `jidDecode`
|
|
613
|
+
* folds it into `domainType` only for plain `s.whatsapp.net`; for special
|
|
614
|
+
* servers (`hosted`, `hosted.lid`) it is parsed-then-discarded because
|
|
615
|
+
* `domainType` is taken from the server. The bridge's `Jid.agent`
|
|
616
|
+
* field needs the literal number, so recover it here.
|
|
617
|
+
*/
|
|
618
|
+
function jidAgent(rawJid) {
|
|
619
|
+
if (!rawJid)
|
|
620
|
+
return 0;
|
|
621
|
+
const atIdx = rawJid.indexOf('@');
|
|
615
622
|
if (atIdx < 0)
|
|
616
|
-
return
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
623
|
+
return 0;
|
|
624
|
+
const userPart = rawJid.slice(0, atIdx).split(':', 1)[0];
|
|
625
|
+
if (!userPart)
|
|
626
|
+
return 0;
|
|
627
|
+
const sepIdx = userPart.indexOf('_');
|
|
628
|
+
if (sepIdx < 0)
|
|
629
|
+
return 0;
|
|
630
|
+
const n = parseInt(userPart.slice(sepIdx + 1), 10);
|
|
631
|
+
return Number.isFinite(n) ? n : 0;
|
|
624
632
|
}
|
|
625
633
|
function credsToDeviceJson(creds) {
|
|
626
634
|
/** Serialize a key pair as [private(32) + public(32)] matching Rust key_pair_serde */
|
|
@@ -629,15 +637,19 @@ function credsToDeviceJson(creds) {
|
|
|
629
637
|
return Array(64).fill(0);
|
|
630
638
|
return bufToNumArray(Buffer.from(pair.private)).concat(bufToNumArray(Buffer.from(pair.public)));
|
|
631
639
|
};
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
640
|
+
const pnJid = jidDecode(creds.me?.id);
|
|
641
|
+
const lidJid = jidDecode(creds.me?.lid);
|
|
642
|
+
const deviceNum = pnJid?.device ?? lidJid?.device ?? 0;
|
|
643
|
+
const pnAgent = jidAgent(creds.me?.id);
|
|
644
|
+
const lidAgent = jidAgent(creds.me?.lid);
|
|
645
|
+
// Preserve `server` and recover the literal `_<n>` agent suffix so
|
|
646
|
+
// hosted / hosted.lid accounts (e.g. `5511_2@hosted`) survive a
|
|
647
|
+
// drop-in migration from upstream Baileys.
|
|
638
648
|
return toJson({
|
|
639
|
-
pn: pnJid ? { user: pnJid.user, server:
|
|
640
|
-
lid: lidJid
|
|
649
|
+
pn: pnJid ? { user: pnJid.user, server: pnJid.server, device: deviceNum, agent: pnAgent, integrator: 0 } : null,
|
|
650
|
+
lid: lidJid
|
|
651
|
+
? { user: lidJid.user, server: lidJid.server, device: lidJid.device ?? 0, agent: lidAgent, integrator: 0 }
|
|
652
|
+
: null,
|
|
641
653
|
registration_id: creds.registrationId ?? 0,
|
|
642
654
|
noise_key: kp(creds.noiseKey),
|
|
643
655
|
identity_key: kp(creds.signedIdentityKey),
|
|
@@ -879,7 +891,7 @@ export async function wrapLegacyStore(state, saveCreds, logger) {
|
|
|
879
891
|
clearTimeout(credsTimer);
|
|
880
892
|
credsTimer = setTimeout(() => {
|
|
881
893
|
credsTimer = null;
|
|
882
|
-
saveCreds().catch(
|
|
894
|
+
saveCreds().catch(err => warn('saveCreds failed', err));
|
|
883
895
|
}, 100);
|
|
884
896
|
};
|
|
885
897
|
/** Route a store to its handler */
|
|
@@ -980,6 +992,16 @@ export async function wrapLegacyStore(state, saveCreds, logger) {
|
|
|
980
992
|
// through `set('device', 'device', …)` on pair-success.
|
|
981
993
|
if (!creds.noiseKey && !creds.me?.id)
|
|
982
994
|
return null;
|
|
995
|
+
// Even when `noiseKey` is present as an object, the bytes
|
|
996
|
+
// can still be all-zero — happens after a partial migration
|
|
997
|
+
// from a legacy creds.json that only persisted `me.id`.
|
|
998
|
+
// `credsToDeviceJson` would happily emit zero-filled key
|
|
999
|
+
// slots, which the server rejects with the same 428. Treat
|
|
1000
|
+
// any zero-byte critical key as a bootstrap signal.
|
|
1001
|
+
if (isZeroKey(creds.noiseKey?.private) || isZeroKey(creds.signedIdentityKey?.private)) {
|
|
1002
|
+
warn('device read: noiseKey/signedIdentityKey is zero-valued; signaling bootstrap to bridge');
|
|
1003
|
+
return null;
|
|
1004
|
+
}
|
|
983
1005
|
return credsToDeviceJson(creds);
|
|
984
1006
|
}
|
|
985
1007
|
if (key === 'account') {
|
|
@@ -989,14 +1011,10 @@ export async function wrapLegacyStore(state, saveCreds, logger) {
|
|
|
989
1011
|
}
|
|
990
1012
|
return readBinary(type, key);
|
|
991
1013
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
// stores. No identity fallback needed: identity now goes
|
|
996
|
-
// through the converter, which handles both the address
|
|
997
|
-
// rewrite and the 32↔33-byte prefix.
|
|
1014
|
+
// `signal` route is currently unreachable (BINARY_STORES is empty);
|
|
1015
|
+
// kept for future byte-compatible stores.
|
|
1016
|
+
if (route === 'signal')
|
|
998
1017
|
return readBinary(type, key);
|
|
999
|
-
}
|
|
1000
1018
|
if (route === 'bridge-only')
|
|
1001
1019
|
return readBinary(type, key);
|
|
1002
1020
|
if (route === 'converter') {
|
|
@@ -1064,36 +1082,38 @@ export async function wrapLegacyStore(state, saveCreds, logger) {
|
|
|
1064
1082
|
}
|
|
1065
1083
|
},
|
|
1066
1084
|
async flush() {
|
|
1067
|
-
|
|
1085
|
+
// Drain in a loop because `set('device', ...)` calls landing
|
|
1086
|
+
// during `await saveCreds()` queue a fresh `credsTimer`. A
|
|
1087
|
+
// single-pass flush would leave the latest creds on the timer
|
|
1088
|
+
// — `dispose()` then fires saveCreds() but the orchestrator
|
|
1089
|
+
// has already moved on (`free()`), so the write is racing
|
|
1090
|
+
// against process exit. Looping until the timer is null after
|
|
1091
|
+
// a save closes the window deterministically. Bounded by a
|
|
1092
|
+
// small max-iterations guard so a saveCreds() that re-emits
|
|
1093
|
+
// credentials in a tight loop can't lock us forever.
|
|
1094
|
+
for (let i = 0; i < 32 && credsTimer; i++) {
|
|
1068
1095
|
clearTimeout(credsTimer);
|
|
1069
1096
|
credsTimer = null;
|
|
1070
1097
|
await saveCreds();
|
|
1071
1098
|
}
|
|
1099
|
+
if (credsTimer) {
|
|
1100
|
+
warn('flush hit max-iterations cap; pending credsTimer dropped — saveCreds may be re-emitting in a loop');
|
|
1101
|
+
clearTimeout(credsTimer);
|
|
1102
|
+
credsTimer = null;
|
|
1103
|
+
}
|
|
1072
1104
|
},
|
|
1073
1105
|
dispose() {
|
|
1074
1106
|
if (credsTimer) {
|
|
1075
1107
|
clearTimeout(credsTimer);
|
|
1076
|
-
saveCreds().catch(
|
|
1108
|
+
saveCreds().catch(err => warn('saveCreds failed during dispose', err));
|
|
1077
1109
|
}
|
|
1078
1110
|
}
|
|
1079
1111
|
};
|
|
1080
1112
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
(value.type === 'Buffer' || value.buffer === true)) {
|
|
1086
|
-
const data = value.data ?? value.value;
|
|
1087
|
-
return typeof data === 'string'
|
|
1088
|
-
? Buffer.from(data, 'base64')
|
|
1089
|
-
: Buffer.from((Array.isArray(data) ? data : []));
|
|
1090
|
-
}
|
|
1091
|
-
return value;
|
|
1092
|
-
};
|
|
1093
|
-
/** JSON replacer that serializes Buffer/Uint8Array → `{ type: "Buffer", data: "base64" }` */
|
|
1094
|
-
const bufferReplacer = (_, value) => value instanceof Uint8Array || Buffer.isBuffer(value)
|
|
1095
|
-
? { type: 'Buffer', data: Buffer.from(value).toString('base64') }
|
|
1096
|
-
: value;
|
|
1113
|
+
// ---- Legacy multi-file auth state loader ----
|
|
1114
|
+
// Reads upstream Baileys' creds.json + per-key .json files via the
|
|
1115
|
+
// shared `BufferJSON` codec (same as @whiskeysockets/baileys
|
|
1116
|
+
// useMultiFileAuthState).
|
|
1097
1117
|
const fixFileName = (file) => file?.replace(/\//g, '__')?.replace(/:/g, '-');
|
|
1098
1118
|
/**
|
|
1099
1119
|
* Loads an upstream Baileys session (creds.json + key .json files) and returns
|
|
@@ -1116,14 +1136,14 @@ export async function useLegacyMultiFileAuthState(folder) {
|
|
|
1116
1136
|
const readData = async (file) => {
|
|
1117
1137
|
try {
|
|
1118
1138
|
const data = await readFile(join(folder, fixFileName(file)), 'utf-8');
|
|
1119
|
-
return JSON.parse(data,
|
|
1139
|
+
return JSON.parse(data, BufferJSON.reviver);
|
|
1120
1140
|
}
|
|
1121
1141
|
catch {
|
|
1122
1142
|
return null;
|
|
1123
1143
|
}
|
|
1124
1144
|
};
|
|
1125
1145
|
const writeData = async (data, file) => {
|
|
1126
|
-
await writeFile(join(folder, fixFileName(file)), JSON.stringify(data,
|
|
1146
|
+
await writeFile(join(folder, fixFileName(file)), JSON.stringify(data, BufferJSON.replacer));
|
|
1127
1147
|
};
|
|
1128
1148
|
const removeData = async (file) => {
|
|
1129
1149
|
try {
|