@kangwifi-pro/waliwa 1.0.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/LICENSE +21 -0
- package/README.md +600 -0
- package/dist/advanced/features.d.ts +211 -0
- package/dist/advanced/features.d.ts.map +1 -0
- package/dist/advanced/features.js +671 -0
- package/dist/advanced/features.js.map +1 -0
- package/dist/auth/auth-state.d.ts +89 -0
- package/dist/auth/auth-state.d.ts.map +1 -0
- package/dist/auth/auth-state.js +330 -0
- package/dist/auth/auth-state.js.map +1 -0
- package/dist/auth/pairing-code.d.ts +78 -0
- package/dist/auth/pairing-code.d.ts.map +1 -0
- package/dist/auth/pairing-code.js +191 -0
- package/dist/auth/pairing-code.js.map +1 -0
- package/dist/auth/qr-code.d.ts +60 -0
- package/dist/auth/qr-code.d.ts.map +1 -0
- package/dist/auth/qr-code.js +151 -0
- package/dist/auth/qr-code.js.map +1 -0
- package/dist/calls/handler.d.ts +61 -0
- package/dist/calls/handler.d.ts.map +1 -0
- package/dist/calls/handler.js +117 -0
- package/dist/calls/handler.js.map +1 -0
- package/dist/core/binary.d.ts +74 -0
- package/dist/core/binary.d.ts.map +1 -0
- package/dist/core/binary.js +448 -0
- package/dist/core/binary.js.map +1 -0
- package/dist/core/crypto.d.ts +60 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +170 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/core/noise.d.ts +106 -0
- package/dist/core/noise.d.ts.map +1 -0
- package/dist/core/noise.js +307 -0
- package/dist/core/noise.js.map +1 -0
- package/dist/events/emitter.d.ts +44 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +79 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/features/index.d.ts +342 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +755 -0
- package/dist/features/index.js.map +1 -0
- package/dist/fixes/index.d.ts +333 -0
- package/dist/fixes/index.d.ts.map +1 -0
- package/dist/fixes/index.js +762 -0
- package/dist/fixes/index.js.map +1 -0
- package/dist/groups/management.d.ts +86 -0
- package/dist/groups/management.d.ts.map +1 -0
- package/dist/groups/management.js +443 -0
- package/dist/groups/management.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +236 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/media.d.ts +93 -0
- package/dist/messages/media.d.ts.map +1 -0
- package/dist/messages/media.js +252 -0
- package/dist/messages/media.js.map +1 -0
- package/dist/messages/message-encoder.d.ts +70 -0
- package/dist/messages/message-encoder.d.ts.map +1 -0
- package/dist/messages/message-encoder.js +453 -0
- package/dist/messages/message-encoder.js.map +1 -0
- package/dist/messages/send.d.ts +101 -0
- package/dist/messages/send.d.ts.map +1 -0
- package/dist/messages/send.js +409 -0
- package/dist/messages/send.js.map +1 -0
- package/dist/recovery/index.d.ts +125 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +584 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/skdm/index.d.ts +220 -0
- package/dist/skdm/index.d.ts.map +1 -0
- package/dist/skdm/index.js +600 -0
- package/dist/skdm/index.js.map +1 -0
- package/dist/socket/hybrid.d.ts +118 -0
- package/dist/socket/hybrid.d.ts.map +1 -0
- package/dist/socket/hybrid.js +352 -0
- package/dist/socket/hybrid.js.map +1 -0
- package/dist/socket/wa-socket.d.ts +300 -0
- package/dist/socket/wa-socket.d.ts.map +1 -0
- package/dist/socket/wa-socket.js +1094 -0
- package/dist/socket/wa-socket.js.map +1 -0
- package/dist/socket/ws-socket.d.ts +96 -0
- package/dist/socket/ws-socket.d.ts.map +1 -0
- package/dist/socket/ws-socket.js +302 -0
- package/dist/socket/ws-socket.js.map +1 -0
- package/dist/types/index.d.ts +444 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/jid.d.ts +46 -0
- package/dist/utils/jid.d.ts.map +1 -0
- package/dist/utils/jid.js +152 -0
- package/dist/utils/jid.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +79 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retry.d.ts +43 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +175 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/API.md +745 -0
- package/docs/ARCHITECTURE.md +307 -0
- package/docs/BAILEYS_FIXES.md +360 -0
- package/docs/FEATURES.md +532 -0
- package/docs/PROTOCOL.md +489 -0
- package/docs/RECOVERY.md +409 -0
- package/docs/SKDM.md +233 -0
- package/examples/ai-bot/index.ts +479 -0
- package/examples/ai-bot/package.json +17 -0
- package/examples/echo-bot/index.ts +171 -0
- package/examples/echo-bot/package.json +18 -0
- package/examples/group-bot/index.ts +557 -0
- package/examples/group-bot/package.json +17 -0
- package/examples/rest-gateway/index.ts +499 -0
- package/examples/rest-gateway/package.json +19 -0
- package/package.json +75 -0
- package/src/advanced/features.ts +817 -0
- package/src/auth/auth-state.ts +342 -0
- package/src/auth/pairing-code.ts +246 -0
- package/src/auth/qr-code.ts +191 -0
- package/src/calls/handler.ts +153 -0
- package/src/core/binary.ts +464 -0
- package/src/core/crypto.ts +189 -0
- package/src/core/noise.ts +406 -0
- package/src/events/emitter.ts +88 -0
- package/src/features/index.ts +921 -0
- package/src/fixes/index.ts +882 -0
- package/src/groups/management.ts +497 -0
- package/src/index.ts +274 -0
- package/src/messages/media.ts +372 -0
- package/src/messages/message-encoder.ts +520 -0
- package/src/messages/send.ts +521 -0
- package/src/recovery/index.ts +704 -0
- package/src/skdm/index.ts +693 -0
- package/src/socket/hybrid.ts +414 -0
- package/src/socket/wa-socket.ts +1347 -0
- package/src/socket/ws-socket.ts +355 -0
- package/src/types/index.ts +457 -0
- package/src/utils/jid.ts +156 -0
- package/src/utils/logger.ts +84 -0
- package/src/utils/retry.ts +205 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Waliwa - SKDM (Store Key Data Manager)
|
|
4
|
+
*
|
|
5
|
+
* Subsystem cerdas untuk manage Signal protocol keys:
|
|
6
|
+
* - Auto-regenerate pre-keys saat hampir habis (prevents Baileys pre-key exhaustion)
|
|
7
|
+
* - LRU cache untuk sessions (RAM efficient)
|
|
8
|
+
* - Atomic writes untuk prevent corruption saat disconnect (Baileys issue)
|
|
9
|
+
* - Pre-key rotation policy dengan background jobs
|
|
10
|
+
* - Session cleanup untuk orphaned sessions
|
|
11
|
+
* - Key prefetching untuk known conversations (fix decryption failures)
|
|
12
|
+
*
|
|
13
|
+
* Fixes yang addressed:
|
|
14
|
+
* - Baileys issue: pre-key exhaustion → pre-keys habis gak auto-regenerate
|
|
15
|
+
* - Baileys issue: session corruption on disconnect → atomic write
|
|
16
|
+
* - Baileys issue: decryption failure for old messages → key prefetch
|
|
17
|
+
* - Baileys issue: memory leak dari sessions lama → LRU eviction
|
|
18
|
+
*/
|
|
19
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
26
|
+
}) : (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
o[k2] = m[k];
|
|
29
|
+
}));
|
|
30
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
32
|
+
}) : function(o, v) {
|
|
33
|
+
o["default"] = v;
|
|
34
|
+
});
|
|
35
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
36
|
+
var ownKeys = function(o) {
|
|
37
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
38
|
+
var ar = [];
|
|
39
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
+
return ar;
|
|
41
|
+
};
|
|
42
|
+
return ownKeys(o);
|
|
43
|
+
};
|
|
44
|
+
return function (mod) {
|
|
45
|
+
if (mod && mod.__esModule) return mod;
|
|
46
|
+
var result = {};
|
|
47
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
48
|
+
__setModuleDefault(result, mod);
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
})();
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.SKDM = exports.IdentityKeyManager = exports.AppStateKeyManager = exports.SessionManager = exports.PreKeyManager = exports.AtomicFileWriter = exports.LRUCache = void 0;
|
|
54
|
+
const fs_1 = require("fs");
|
|
55
|
+
const path = __importStar(require("path"));
|
|
56
|
+
const promises_1 = require("fs/promises");
|
|
57
|
+
const crypto_js_1 = require("../core/crypto.js");
|
|
58
|
+
const retry_js_1 = require("../utils/retry.js");
|
|
59
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
60
|
+
// ============== LRU Cache (RAM efficient) ==============
|
|
61
|
+
/**
|
|
62
|
+
* LRU cache dengan O(1) operations, manual implementation untuk RAM efficiency.
|
|
63
|
+
* Used untuk caching sessions dan senderKeys.
|
|
64
|
+
*/
|
|
65
|
+
class LRUCache {
|
|
66
|
+
cache;
|
|
67
|
+
maxSize;
|
|
68
|
+
hits = 0;
|
|
69
|
+
misses = 0;
|
|
70
|
+
constructor(maxSize = 500) {
|
|
71
|
+
this.cache = new Map();
|
|
72
|
+
this.maxSize = maxSize;
|
|
73
|
+
}
|
|
74
|
+
get(key) {
|
|
75
|
+
const value = this.cache.get(key);
|
|
76
|
+
if (value !== undefined) {
|
|
77
|
+
// Move to end (most recent)
|
|
78
|
+
this.cache.delete(key);
|
|
79
|
+
this.cache.set(key, value);
|
|
80
|
+
this.hits++;
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
this.misses++;
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
set(key, value) {
|
|
87
|
+
if (this.cache.has(key)) {
|
|
88
|
+
// Update existing - move to end
|
|
89
|
+
this.cache.delete(key);
|
|
90
|
+
}
|
|
91
|
+
else if (this.cache.size >= this.maxSize) {
|
|
92
|
+
// Evict oldest
|
|
93
|
+
const firstKey = this.cache.keys().next().value;
|
|
94
|
+
if (firstKey !== undefined) {
|
|
95
|
+
this.cache.delete(firstKey);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
this.cache.set(key, value);
|
|
99
|
+
}
|
|
100
|
+
has(key) {
|
|
101
|
+
return this.cache.has(key);
|
|
102
|
+
}
|
|
103
|
+
delete(key) {
|
|
104
|
+
return this.cache.delete(key);
|
|
105
|
+
}
|
|
106
|
+
clear() {
|
|
107
|
+
this.cache.clear();
|
|
108
|
+
this.hits = 0;
|
|
109
|
+
this.misses = 0;
|
|
110
|
+
}
|
|
111
|
+
size() {
|
|
112
|
+
return this.cache.size;
|
|
113
|
+
}
|
|
114
|
+
getStats() {
|
|
115
|
+
const total = this.hits + this.misses;
|
|
116
|
+
return {
|
|
117
|
+
size: this.cache.size,
|
|
118
|
+
hits: this.hits,
|
|
119
|
+
misses: this.misses,
|
|
120
|
+
hitRate: total === 0 ? 0 : this.hits / total
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.LRUCache = LRUCache;
|
|
125
|
+
// ============== Atomic File Writer ==============
|
|
126
|
+
/**
|
|
127
|
+
* Atomic file writer - prevents corruption saat disconnect/power failure.
|
|
128
|
+
* Baileys issue: session files corrupt jika process kill saat write.
|
|
129
|
+
*
|
|
130
|
+
* Strategy: write to .tmp file, then rename (atomic on POSIX systems).
|
|
131
|
+
*/
|
|
132
|
+
class AtomicFileWriter {
|
|
133
|
+
static writeLocks = new Map();
|
|
134
|
+
static async writeFile(filePath, data, encoding = 'utf-8') {
|
|
135
|
+
// Serialize writes per file (prevent concurrent writes)
|
|
136
|
+
const existingLock = AtomicFileWriter.writeLocks.get(filePath);
|
|
137
|
+
const newPromise = (existingLock ?? Promise.resolve())
|
|
138
|
+
.then(() => AtomicFileWriter.performWrite(filePath, data, encoding));
|
|
139
|
+
AtomicFileWriter.writeLocks.set(filePath, newPromise);
|
|
140
|
+
try {
|
|
141
|
+
await newPromise;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
if (AtomicFileWriter.writeLocks.get(filePath) === newPromise) {
|
|
145
|
+
AtomicFileWriter.writeLocks.delete(filePath);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
static async performWrite(filePath, data, encoding) {
|
|
150
|
+
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
151
|
+
await fs_1.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
152
|
+
if (encoding === 'utf-8') {
|
|
153
|
+
await fs_1.promises.writeFile(tmpPath, data, 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
await fs_1.promises.writeFile(tmpPath, data);
|
|
157
|
+
}
|
|
158
|
+
// Atomic rename (POSIX)
|
|
159
|
+
await (0, promises_1.rename)(tmpPath, filePath);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.AtomicFileWriter = AtomicFileWriter;
|
|
163
|
+
// ============== Pre-Key Manager ==============
|
|
164
|
+
/**
|
|
165
|
+
* Pre-key manager - auto-regenerate saat low, prevents exhaustion.
|
|
166
|
+
* Fix Baileys issue: pre-keys habis tanpa warning.
|
|
167
|
+
*/
|
|
168
|
+
class PreKeyManager {
|
|
169
|
+
creds;
|
|
170
|
+
keys;
|
|
171
|
+
minPreKeys;
|
|
172
|
+
maxBatch;
|
|
173
|
+
targetCount;
|
|
174
|
+
logger;
|
|
175
|
+
isRegenerating = false;
|
|
176
|
+
lastRegenTime = 0;
|
|
177
|
+
regenDebounce = null;
|
|
178
|
+
constructor(creds, keys, config) {
|
|
179
|
+
this.creds = creds;
|
|
180
|
+
this.keys = keys;
|
|
181
|
+
this.minPreKeys = config.minPreKeys ?? 5;
|
|
182
|
+
this.maxBatch = config.maxPreKeysBatch ?? 50;
|
|
183
|
+
this.targetCount = config.targetPreKeyCount ?? 100;
|
|
184
|
+
this.logger = config.logger ?? new logger_js_1.SilentLogger();
|
|
185
|
+
}
|
|
186
|
+
needsRegeneration() {
|
|
187
|
+
return this.getPreKeyCount() < this.minPreKeys;
|
|
188
|
+
}
|
|
189
|
+
getPreKeyCount() {
|
|
190
|
+
return Object.keys(this.keys.preKeys).length;
|
|
191
|
+
}
|
|
192
|
+
getNextPreKeyId() {
|
|
193
|
+
return this.creds.nextPreKeyId ?? 1;
|
|
194
|
+
}
|
|
195
|
+
getPreKey(id) {
|
|
196
|
+
return this.keys.preKeys[id];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Consume a pre-key (mark as used)
|
|
200
|
+
* Returns true jika key consumed, false jika tidak ada
|
|
201
|
+
*/
|
|
202
|
+
consumePreKey(id) {
|
|
203
|
+
const key = this.keys.preKeys[id];
|
|
204
|
+
if (!key)
|
|
205
|
+
return false;
|
|
206
|
+
delete this.keys.preKeys[id];
|
|
207
|
+
this.logger.debug(`Consumed pre-key ${id}, ${this.getPreKeyCount()} remaining`);
|
|
208
|
+
if (this.needsRegeneration()) {
|
|
209
|
+
this.scheduleRegeneration();
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
scheduleRegeneration() {
|
|
214
|
+
if (this.regenDebounce)
|
|
215
|
+
clearTimeout(this.regenDebounce);
|
|
216
|
+
this.regenDebounce = setTimeout(() => {
|
|
217
|
+
this.regeneratePreKeys().catch(err => {
|
|
218
|
+
this.logger.error(`Pre-key regeneration failed: ${err.message}`);
|
|
219
|
+
});
|
|
220
|
+
}, 2000);
|
|
221
|
+
}
|
|
222
|
+
async regeneratePreKeys() {
|
|
223
|
+
if (this.isRegenerating) {
|
|
224
|
+
this.logger.debug('Pre-key regeneration already in progress');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
this.isRegenerating = true;
|
|
228
|
+
const currentCount = this.getPreKeyCount();
|
|
229
|
+
const needed = this.targetCount - currentCount;
|
|
230
|
+
const toGenerate = Math.min(needed, this.maxBatch);
|
|
231
|
+
if (toGenerate <= 0) {
|
|
232
|
+
this.isRegenerating = false;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this.logger.info(`Regenerating ${toGenerate} pre-keys (current: ${currentCount})`);
|
|
236
|
+
let nextId = this.getNextPreKeyId();
|
|
237
|
+
for (let i = 0; i < toGenerate; i++) {
|
|
238
|
+
const keyPair = (0, crypto_js_1.generateCurveKeyPair)();
|
|
239
|
+
this.keys.preKeys[nextId] = keyPair;
|
|
240
|
+
nextId++;
|
|
241
|
+
}
|
|
242
|
+
this.creds.nextPreKeyId = nextId;
|
|
243
|
+
this.lastRegenTime = Date.now();
|
|
244
|
+
this.logger.info(`Pre-keys regenerated. Total: ${this.getPreKeyCount()}`);
|
|
245
|
+
this.isRegenerating = false;
|
|
246
|
+
}
|
|
247
|
+
startBackgroundRotation(intervalMs = 60 * 60 * 1000) {
|
|
248
|
+
return setInterval(() => {
|
|
249
|
+
if (this.needsRegeneration()) {
|
|
250
|
+
this.regeneratePreKeys().catch(err => {
|
|
251
|
+
this.logger.error(`Background pre-key regen failed: ${err.message}`);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}, intervalMs);
|
|
255
|
+
}
|
|
256
|
+
getStats() {
|
|
257
|
+
return {
|
|
258
|
+
total: this.getPreKeyCount(),
|
|
259
|
+
nextId: this.creds.nextPreKeyId ?? 1,
|
|
260
|
+
lastRegenTime: this.lastRegenTime,
|
|
261
|
+
needsRegen: this.needsRegeneration()
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.PreKeyManager = PreKeyManager;
|
|
266
|
+
// ============== Session Manager ==============
|
|
267
|
+
/**
|
|
268
|
+
* Session manager dengan LRU cache untuk RAM efficiency.
|
|
269
|
+
* Fix Baileys issue: memory leak dari sessions lama.
|
|
270
|
+
*/
|
|
271
|
+
class SessionManager {
|
|
272
|
+
keys;
|
|
273
|
+
cache;
|
|
274
|
+
maxCacheSize;
|
|
275
|
+
logger;
|
|
276
|
+
sessionExpiryMs;
|
|
277
|
+
lastAccess = new Map();
|
|
278
|
+
constructor(keys, config) {
|
|
279
|
+
this.keys = keys;
|
|
280
|
+
this.maxCacheSize = config.maxSessionCacheSize ?? 500;
|
|
281
|
+
this.cache = new LRUCache(this.maxCacheSize);
|
|
282
|
+
this.logger = config.logger ?? new logger_js_1.SilentLogger();
|
|
283
|
+
this.sessionExpiryMs = config.sessionExpiryMs ?? 30 * 24 * 60 * 60 * 1000;
|
|
284
|
+
}
|
|
285
|
+
getSession(jid) {
|
|
286
|
+
const cached = this.cache.get(jid);
|
|
287
|
+
if (cached !== undefined)
|
|
288
|
+
return cached;
|
|
289
|
+
const session = this.keys.sessions[jid];
|
|
290
|
+
if (session) {
|
|
291
|
+
this.cache.set(jid, session);
|
|
292
|
+
this.lastAccess.set(jid, Date.now());
|
|
293
|
+
}
|
|
294
|
+
return session;
|
|
295
|
+
}
|
|
296
|
+
setSession(jid, session) {
|
|
297
|
+
this.cache.set(jid, session);
|
|
298
|
+
this.keys.sessions[jid] = session;
|
|
299
|
+
this.lastAccess.set(jid, Date.now());
|
|
300
|
+
}
|
|
301
|
+
deleteSession(jid) {
|
|
302
|
+
this.cache.delete(jid);
|
|
303
|
+
delete this.keys.sessions[jid];
|
|
304
|
+
this.lastAccess.delete(jid);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Cleanup expired sessions (untuk free RAM)
|
|
308
|
+
* Returns count of cleaned sessions
|
|
309
|
+
*/
|
|
310
|
+
cleanupExpiredSessions() {
|
|
311
|
+
const now = Date.now();
|
|
312
|
+
let cleaned = 0;
|
|
313
|
+
const toDelete = [];
|
|
314
|
+
for (const [jid, lastTime] of this.lastAccess.entries()) {
|
|
315
|
+
if (now - lastTime > this.sessionExpiryMs) {
|
|
316
|
+
toDelete.push(jid);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
for (const jid of toDelete) {
|
|
320
|
+
this.deleteSession(jid);
|
|
321
|
+
cleaned++;
|
|
322
|
+
}
|
|
323
|
+
if (cleaned > 0) {
|
|
324
|
+
this.logger.info(`Cleaned ${cleaned} expired sessions`);
|
|
325
|
+
}
|
|
326
|
+
return cleaned;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Prefetch sessions untuk multiple JIDs (fix decryption failure)
|
|
330
|
+
* Bulk load sessions sebelum decrypt group messages
|
|
331
|
+
*/
|
|
332
|
+
prefetchSessions(jids) {
|
|
333
|
+
for (const jid of jids) {
|
|
334
|
+
if (!this.cache.has(jid) && this.keys.sessions[jid]) {
|
|
335
|
+
this.cache.set(jid, this.keys.sessions[jid]);
|
|
336
|
+
this.lastAccess.set(jid, Date.now());
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
getStats() {
|
|
341
|
+
return {
|
|
342
|
+
...this.cache.getStats(),
|
|
343
|
+
totalSessions: Object.keys(this.keys.sessions).length,
|
|
344
|
+
expiredSessions: Array.from(this.lastAccess.values())
|
|
345
|
+
.filter(t => Date.now() - t > this.sessionExpiryMs).length
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
exports.SessionManager = SessionManager;
|
|
350
|
+
// ============== AppState Key Manager ==============
|
|
351
|
+
/**
|
|
352
|
+
* AppState key manager - manage app state sync keys dengan deduplication.
|
|
353
|
+
* Fix Baileys issue: app state sync keys bertumpuk tanpa cleanup.
|
|
354
|
+
*/
|
|
355
|
+
class AppStateKeyManager {
|
|
356
|
+
keys;
|
|
357
|
+
logger;
|
|
358
|
+
cache;
|
|
359
|
+
constructor(keys, logger) {
|
|
360
|
+
this.keys = keys;
|
|
361
|
+
this.logger = logger ?? new logger_js_1.SilentLogger();
|
|
362
|
+
this.cache = new LRUCache(100);
|
|
363
|
+
}
|
|
364
|
+
get(keyId) {
|
|
365
|
+
const cached = this.cache.get(keyId);
|
|
366
|
+
if (cached)
|
|
367
|
+
return cached;
|
|
368
|
+
const stored = this.keys.appStateSyncKeys[keyId];
|
|
369
|
+
if (stored) {
|
|
370
|
+
this.cache.set(keyId, stored);
|
|
371
|
+
return stored;
|
|
372
|
+
}
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
set(keyId, key) {
|
|
376
|
+
this.cache.set(keyId, key);
|
|
377
|
+
this.keys.appStateSyncKeys[keyId] = key;
|
|
378
|
+
}
|
|
379
|
+
cleanup(maxKeep = 50) {
|
|
380
|
+
const allKeys = Object.keys(this.keys.appStateSyncKeys);
|
|
381
|
+
if (allKeys.length <= maxKeep)
|
|
382
|
+
return 0;
|
|
383
|
+
const toDelete = allKeys.slice(0, allKeys.length - maxKeep);
|
|
384
|
+
for (const keyId of toDelete) {
|
|
385
|
+
delete this.keys.appStateSyncKeys[keyId];
|
|
386
|
+
this.cache.delete(keyId);
|
|
387
|
+
}
|
|
388
|
+
this.logger.debug(`Cleaned ${toDelete.length} old app state keys`);
|
|
389
|
+
return toDelete.length;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
exports.AppStateKeyManager = AppStateKeyManager;
|
|
393
|
+
// ============== Identity Key Manager ==============
|
|
394
|
+
/**
|
|
395
|
+
* Identity key manager dengan verification.
|
|
396
|
+
* Fix Baileys issue: identity changes gak tracked properly.
|
|
397
|
+
*/
|
|
398
|
+
class IdentityKeyManager {
|
|
399
|
+
keys;
|
|
400
|
+
logger;
|
|
401
|
+
trustedIdentities = new Map();
|
|
402
|
+
changedIdentities = new Set();
|
|
403
|
+
constructor(keys, logger) {
|
|
404
|
+
this.keys = keys;
|
|
405
|
+
this.logger = logger ?? new logger_js_1.SilentLogger();
|
|
406
|
+
for (const [jid, keyPair] of Object.entries(keys.identityKeys)) {
|
|
407
|
+
if (keyPair?.public) {
|
|
408
|
+
this.trustedIdentities.set(jid, keyPair.public);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
get(jid) {
|
|
413
|
+
return this.trustedIdentities.get(jid) ?? this.keys.identityKeys[jid]?.public;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Save identity key, detect changes
|
|
417
|
+
* Returns true jika identity CHANGED (security concern)
|
|
418
|
+
*/
|
|
419
|
+
save(jid, identity) {
|
|
420
|
+
const existing = this.trustedIdentities.get(jid);
|
|
421
|
+
const changed = existing !== undefined && !this.bytesEqual(existing, identity);
|
|
422
|
+
this.trustedIdentities.set(jid, identity);
|
|
423
|
+
this.keys.identityKeys[jid] = { private: new Uint8Array(0), public: identity };
|
|
424
|
+
if (changed) {
|
|
425
|
+
this.changedIdentities.add(jid);
|
|
426
|
+
this.logger.warn(`Identity changed for ${jid} - possible security issue!`);
|
|
427
|
+
}
|
|
428
|
+
return changed;
|
|
429
|
+
}
|
|
430
|
+
getChangedIdentities() {
|
|
431
|
+
return Array.from(this.changedIdentities);
|
|
432
|
+
}
|
|
433
|
+
acknowledge(jid) {
|
|
434
|
+
this.changedIdentities.delete(jid);
|
|
435
|
+
}
|
|
436
|
+
trust(jid) {
|
|
437
|
+
this.changedIdentities.delete(jid);
|
|
438
|
+
}
|
|
439
|
+
bytesEqual(a, b) {
|
|
440
|
+
if (a.length !== b.length)
|
|
441
|
+
return false;
|
|
442
|
+
let diff = 0;
|
|
443
|
+
for (let i = 0; i < a.length; i++)
|
|
444
|
+
diff |= a[i] ^ b[i];
|
|
445
|
+
return diff === 0;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
exports.IdentityKeyManager = IdentityKeyManager;
|
|
449
|
+
// ============== Main SKDM Class ==============
|
|
450
|
+
/**
|
|
451
|
+
* SKDM - Store Key Data Manager
|
|
452
|
+
* Single entry point untuk semua key management operations.
|
|
453
|
+
*/
|
|
454
|
+
class SKDM {
|
|
455
|
+
config;
|
|
456
|
+
logger;
|
|
457
|
+
creds;
|
|
458
|
+
keys;
|
|
459
|
+
preKeyManager;
|
|
460
|
+
sessionManager;
|
|
461
|
+
identityManager;
|
|
462
|
+
appStateManager;
|
|
463
|
+
dirty = { creds: false, keys: false };
|
|
464
|
+
saveCredsDebounced;
|
|
465
|
+
saveKeysDebounced;
|
|
466
|
+
backgroundJobs = [];
|
|
467
|
+
isInitialized = false;
|
|
468
|
+
constructor(creds, keys, config) {
|
|
469
|
+
this.creds = creds;
|
|
470
|
+
this.keys = keys;
|
|
471
|
+
this.config = config;
|
|
472
|
+
this.logger = config.logger ?? new logger_js_1.SilentLogger();
|
|
473
|
+
this.preKeyManager = new PreKeyManager(creds, keys, config);
|
|
474
|
+
this.sessionManager = new SessionManager(keys, config);
|
|
475
|
+
this.identityManager = new IdentityKeyManager(keys, this.logger);
|
|
476
|
+
this.appStateManager = new AppStateKeyManager(keys, this.logger);
|
|
477
|
+
const debounceMs = 100;
|
|
478
|
+
this.saveCredsDebounced = (0, retry_js_1.debounce)(() => this.flushCreds(), debounceMs);
|
|
479
|
+
this.saveKeysDebounced = (0, retry_js_1.debounce)(() => this.flushKeys(), debounceMs);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Initialize SKDM - load state, start background jobs
|
|
483
|
+
*/
|
|
484
|
+
async initialize() {
|
|
485
|
+
if (this.isInitialized)
|
|
486
|
+
return;
|
|
487
|
+
this.logger.info('Initializing SKDM...');
|
|
488
|
+
if (this.preKeyManager.needsRegeneration()) {
|
|
489
|
+
await this.preKeyManager.regeneratePreKeys();
|
|
490
|
+
}
|
|
491
|
+
if (this.config.enableKeyRotation !== false) {
|
|
492
|
+
const preKeyJob = this.preKeyManager.startBackgroundRotation(60 * 60 * 1000);
|
|
493
|
+
this.backgroundJobs.push(preKeyJob);
|
|
494
|
+
}
|
|
495
|
+
const sessionCleanupJob = setInterval(() => {
|
|
496
|
+
const cleaned = this.sessionManager.cleanupExpiredSessions();
|
|
497
|
+
if (cleaned > 0)
|
|
498
|
+
this.markKeysDirty();
|
|
499
|
+
}, 6 * 60 * 60 * 1000);
|
|
500
|
+
this.backgroundJobs.push(sessionCleanupJob);
|
|
501
|
+
const appStateCleanupJob = setInterval(() => {
|
|
502
|
+
const cleaned = this.appStateManager.cleanup(50);
|
|
503
|
+
if (cleaned > 0)
|
|
504
|
+
this.markKeysDirty();
|
|
505
|
+
}, 24 * 60 * 60 * 1000);
|
|
506
|
+
this.backgroundJobs.push(appStateCleanupJob);
|
|
507
|
+
this.isInitialized = true;
|
|
508
|
+
this.logger.info('SKDM initialized successfully');
|
|
509
|
+
}
|
|
510
|
+
markCredsDirty() {
|
|
511
|
+
this.dirty.creds = true;
|
|
512
|
+
this.saveCredsDebounced();
|
|
513
|
+
}
|
|
514
|
+
markKeysDirty() {
|
|
515
|
+
this.dirty.keys = true;
|
|
516
|
+
this.saveKeysDebounced();
|
|
517
|
+
}
|
|
518
|
+
async flushCreds() {
|
|
519
|
+
if (!this.dirty.creds)
|
|
520
|
+
return;
|
|
521
|
+
this.dirty.creds = false;
|
|
522
|
+
const data = JSON.stringify(this.creds, (key, value) => {
|
|
523
|
+
if (value instanceof Uint8Array) {
|
|
524
|
+
return { type: 'Uint8Array', data: Array.from(value) };
|
|
525
|
+
}
|
|
526
|
+
if (typeof value === 'object' && value !== null && 'private' in value && 'public' in value &&
|
|
527
|
+
value.private instanceof Uint8Array) {
|
|
528
|
+
return {
|
|
529
|
+
type: 'KeyPair',
|
|
530
|
+
private: Array.from(value.private),
|
|
531
|
+
public: Array.from(value.public)
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
return value;
|
|
535
|
+
});
|
|
536
|
+
const filePath = path.join(this.config.storageFolder, `${this.config.prefix ?? 'waliwa'}-creds.json`);
|
|
537
|
+
try {
|
|
538
|
+
await AtomicFileWriter.writeFile(filePath, data, 'utf-8');
|
|
539
|
+
this.logger.debug('Credentials saved (atomic)');
|
|
540
|
+
}
|
|
541
|
+
catch (err) {
|
|
542
|
+
this.logger.error(`Failed to save creds: ${err.message}`);
|
|
543
|
+
this.dirty.creds = true;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
async flushKeys() {
|
|
547
|
+
if (!this.dirty.keys)
|
|
548
|
+
return;
|
|
549
|
+
this.dirty.keys = false;
|
|
550
|
+
const data = JSON.stringify(this.keys, (key, value) => {
|
|
551
|
+
if (value instanceof Uint8Array) {
|
|
552
|
+
return { type: 'Uint8Array', data: Array.from(value) };
|
|
553
|
+
}
|
|
554
|
+
if (typeof value === 'object' && value !== null && 'private' in value && 'public' in value &&
|
|
555
|
+
value.private instanceof Uint8Array) {
|
|
556
|
+
return {
|
|
557
|
+
type: 'KeyPair',
|
|
558
|
+
private: Array.from(value.private),
|
|
559
|
+
public: Array.from(value.public)
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
return value;
|
|
563
|
+
});
|
|
564
|
+
const filePath = path.join(this.config.storageFolder, `${this.config.prefix ?? 'waliwa'}-keys.json`);
|
|
565
|
+
try {
|
|
566
|
+
await AtomicFileWriter.writeFile(filePath, data, 'utf-8');
|
|
567
|
+
this.logger.debug('Keys saved (atomic)');
|
|
568
|
+
}
|
|
569
|
+
catch (err) {
|
|
570
|
+
this.logger.error(`Failed to save keys: ${err.message}`);
|
|
571
|
+
this.dirty.keys = true;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
async flush() {
|
|
575
|
+
await Promise.all([this.flushCreds(), this.flushKeys()]);
|
|
576
|
+
}
|
|
577
|
+
getStats() {
|
|
578
|
+
return {
|
|
579
|
+
preKeys: this.preKeyManager.getStats(),
|
|
580
|
+
sessions: this.sessionManager.getStats(),
|
|
581
|
+
identities: {
|
|
582
|
+
total: this.identityManager['trustedIdentities'].size,
|
|
583
|
+
changed: this.identityManager.getChangedIdentities().length
|
|
584
|
+
},
|
|
585
|
+
appStateKeys: Object.keys(this.keys.appStateSyncKeys).length,
|
|
586
|
+
pendingSaves: (this.dirty.creds ? 1 : 0) + (this.dirty.keys ? 1 : 0)
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
async destroy() {
|
|
590
|
+
for (const job of this.backgroundJobs) {
|
|
591
|
+
clearInterval(job);
|
|
592
|
+
}
|
|
593
|
+
this.backgroundJobs = [];
|
|
594
|
+
await this.flush();
|
|
595
|
+
this.isInitialized = false;
|
|
596
|
+
this.logger.info('SKDM destroyed');
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
exports.SKDM = SKDM;
|
|
600
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skdm/index.ts"],"names":[],"mappings":"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"}
|