neroxbailx
Version:
baileys whatsapp-api
222 lines (216 loc) • 7.04 kB
JavaScript
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
}