UNPKG

neroxbailx

Version:

baileys whatsapp-api

222 lines (216 loc) 7.04 kB
"use strict" var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k var desc = Object.getOwnPropertyDescriptor(m, k) if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k] } } } Object.defineProperty(o, k2, desc) }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k o[k2] = m[k] })) var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }) }) : function(o, v) { o["default"] = v }) var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod var result = {} if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k) __setModuleDefault(result, mod) return result } Object.defineProperty(exports, "__esModule", { value: true }) const libsignal = __importStar(require("libsignal")) const WASignalGroup_1 = require("../../WASignalGroup") const Utils_1 = require("../Utils") const WABinary_1 = require("../WABinary") const { makeSessionErrorHandler } = require("../Utils/session-error-handler") function makeLibSignalRepository(auth) { const storage = signalStorage(auth) // Initialize session error handler (will be set up later with dependencies) let sessionErrorHandler = null // Setup session error handler when dependencies are available const setupSessionErrorHandler = (dependencies) => { if (!sessionErrorHandler && dependencies) { sessionErrorHandler = makeSessionErrorHandler(dependencies) } return sessionErrorHandler } return { // Add setupSessionErrorHandler method setupSessionErrorHandler, decryptGroupMessage({ group, authorJid, msg }) { const senderName = jidToSignalSenderKeyName(group, authorJid) const cipher = new WASignalGroup_1.GroupCipher(storage, senderName) return cipher.decrypt(msg) }, async processSenderKeyDistributionMessage({ item, authorJid }) { try { const builder = new WASignalGroup_1.GroupSessionBuilder(storage) const senderName = jidToSignalSenderKeyName(item.groupId, authorJid) const senderMsg = new WASignalGroup_1.SenderKeyDistributionMessage(null, null, null, null, item.axolotlSenderKeyDistributionMessage) const { [senderName]: senderKey } = await auth.keys.get('sender-key', [senderName]) if (!senderKey) { await storage.storeSenderKey(senderName, new WASignalGroup_1.SenderKeyRecord()) } await builder.process(senderName, senderMsg) return { success: true, senderName } } catch (error) { console.error(`❌ Failed to process sender key distribution:`, { authorJid, groupId: item.groupId, error: error.message }); throw error; } }, async decryptMessage({ jid, type, ciphertext }) { const addr = jidToSignalProtocolAddress(jid) const session = new libsignal.SessionCipher(storage, addr) let result try { switch (type) { case 'pkmsg': result = await session.decryptPreKeyWhisperMessage(ciphertext) break case 'msg': result = await session.decryptWhisperMessage(ciphertext) break } return result } catch (error) { // Handle session errors with recovery if (sessionErrorHandler && (error.message?.includes('No sessions') || error.message?.includes('SessionError'))) { return await sessionErrorHandler.handleSessionError( error, jid, async () => { const newSession = new libsignal.SessionCipher(storage, addr) switch (type) { case 'pkmsg': return await newSession.decryptPreKeyWhisperMessage(ciphertext) case 'msg': return await newSession.decryptWhisperMessage(ciphertext) } } ) } throw error } }, async encryptMessage({ jid, data }) { const addr = jidToSignalProtocolAddress(jid) const cipher = new libsignal.SessionCipher(storage, addr) try { const { type: sigType, body } = await cipher.encrypt(data) const type = sigType === 3 ? 'pkmsg' : 'msg' return { type, ciphertext: Buffer.from(body, 'binary') } } catch (error) { // Handle session errors with recovery if (sessionErrorHandler && (error.message?.includes('No sessions') || error.message?.includes('SessionError'))) { return await sessionErrorHandler.handleSessionError( error, jid, async () => { const newCipher = new libsignal.SessionCipher(storage, addr) const { type: sigType, body } = await newCipher.encrypt(data) const type = sigType === 3 ? 'pkmsg' : 'msg' return { type, ciphertext: Buffer.from(body, 'binary') } } ) } throw error } }, async encryptGroupMessage({ group, meId, data }) { const senderName = jidToSignalSenderKeyName(group, meId) const builder = new WASignalGroup_1.GroupSessionBuilder(storage) const { [senderName]: senderKey } = await auth.keys.get('sender-key', [senderName]) if (!senderKey) { await storage.storeSenderKey(senderName, new WASignalGroup_1.SenderKeyRecord()) } const senderKeyDistributionMessage = await builder.create(senderName) const session = new WASignalGroup_1.GroupCipher(storage, senderName) const ciphertext = await session.encrypt(data) return { ciphertext, senderKeyDistributionMessage: senderKeyDistributionMessage.serialize(), } }, async injectE2ESession({ jid, session }) { const cipher = new libsignal.SessionBuilder(storage, jidToSignalProtocolAddress(jid)) await cipher.initOutgoing(session) }, jidToSignalProtocolAddress(jid) { return jidToSignalProtocolAddress(jid).toString() }, } } const jidToSignalProtocolAddress = (jid) => { const { user, device } = WABinary_1.jidDecode(jid) return new libsignal.ProtocolAddress(user, device || 0) } const jidToSignalSenderKeyName = (group, user) => { return new WASignalGroup_1.SenderKeyName(group, jidToSignalProtocolAddress(user)).toString() } function signalStorage({ creds, keys }) { return { loadSession: async (id) => { const { [id]: sess } = await keys.get('session', [id]) if (sess) { return libsignal.SessionRecord.deserialize(sess) } }, storeSession: async (id, session) => { await keys.set({ 'session': { [id]: session.serialize() } }) }, isTrustedIdentity: () => { return true }, loadPreKey: async (id) => { const keyId = id.toString() const { [keyId]: key } = await keys.get('pre-key', [keyId]) if (key) { return { privKey: Buffer.from(key.private), pubKey: Buffer.from(key.public) } } }, removePreKey: (id) => keys.set({ 'pre-key': { [id]: null } }), loadSignedPreKey: () => { const key = creds.signedPreKey return { privKey: Buffer.from(key.keyPair.private), pubKey: Buffer.from(key.keyPair.public) } }, loadSenderKey: async (keyId) => { const { [keyId]: key } = await keys.get('sender-key', [keyId]) if (key) { return new WASignalGroup_1.SenderKeyRecord(key) } }, storeSenderKey: async (keyId, key) => { await keys.set({ 'sender-key': { [keyId]: key.serialize() } }) }, getOurRegistrationId: () => (creds.registrationId), getOurIdentity: () => { const { signedIdentityKey } = creds return { privKey: Buffer.from(signedIdentityKey.private), pubKey: Utils_1.generateSignalPubKey(signedIdentityKey.public), } } } } module.exports = { makeLibSignalRepository }