mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
186 lines
4.3 KiB
TypeScript
186 lines
4.3 KiB
TypeScript
import { makeLibSignalRepository } from '../Signal/libsignal'
|
|
import { SignalAuthState, SignalDataTypeMap } from '../Types'
|
|
import { Curve, generateRegistrationId, generateSignalPubKey, signedKeyPair } from '../Utils'
|
|
|
|
describe('Signal Tests', () => {
|
|
|
|
it('should correctly encrypt/decrypt 1 message', async() => {
|
|
const user1 = makeUser()
|
|
const user2 = makeUser()
|
|
|
|
const msg = Buffer.from('hello there!')
|
|
|
|
await prepareForSendingMessage(user1, user2)
|
|
|
|
const result = await user1.repository.encryptMessage(
|
|
{ jid: user2.jid, data: msg }
|
|
)
|
|
|
|
const dec = await user2.repository.decryptMessage(
|
|
{ jid: user1.jid, ...result }
|
|
)
|
|
|
|
expect(dec).toEqual(msg)
|
|
})
|
|
|
|
it('should correctly override a session', async() => {
|
|
const user1 = makeUser()
|
|
const user2 = makeUser()
|
|
|
|
const msg = Buffer.from('hello there!')
|
|
|
|
for(let preKeyId = 2; preKeyId <= 3;preKeyId++) {
|
|
await prepareForSendingMessage(user1, user2, preKeyId)
|
|
|
|
const result = await user1.repository.encryptMessage(
|
|
{ jid: user2.jid, data: msg }
|
|
)
|
|
|
|
const dec = await user2.repository.decryptMessage(
|
|
{ jid: user1.jid, ...result }
|
|
)
|
|
|
|
expect(dec).toEqual(msg)
|
|
}
|
|
})
|
|
|
|
it('should correctly encrypt/decrypt multiple messages', async() => {
|
|
const user1 = makeUser()
|
|
const user2 = makeUser()
|
|
|
|
const msg = Buffer.from('hello there!')
|
|
|
|
await prepareForSendingMessage(user1, user2)
|
|
|
|
for(let i = 0;i < 10;i++) {
|
|
const result = await user1.repository.encryptMessage(
|
|
{ jid: user2.jid, data: msg }
|
|
)
|
|
|
|
const dec = await user2.repository.decryptMessage(
|
|
{ jid: user1.jid, ...result }
|
|
)
|
|
|
|
expect(dec).toEqual(msg)
|
|
}
|
|
})
|
|
|
|
it('should encrypt/decrypt messages from group', async() => {
|
|
const groupId = '123456@g.us'
|
|
const participants = [...Array(5)].map(makeUser)
|
|
|
|
const msg = Buffer.from('hello there!')
|
|
|
|
const sender = participants[0]
|
|
const enc = await sender.repository.encryptGroupMessage(
|
|
{
|
|
group: groupId,
|
|
meId: sender.jid,
|
|
data: msg
|
|
}
|
|
)
|
|
|
|
for(const participant of participants) {
|
|
if(participant === sender) {
|
|
continue
|
|
}
|
|
|
|
await participant.repository.processSenderKeyDistributionMessage(
|
|
{
|
|
item: {
|
|
groupId,
|
|
axolotlSenderKeyDistributionMessage: enc.senderKeyDistributionMessage
|
|
},
|
|
authorJid: sender.jid
|
|
}
|
|
)
|
|
|
|
const dec = await participant.repository.decryptGroupMessage(
|
|
{
|
|
group: groupId,
|
|
authorJid: sender.jid,
|
|
msg: enc.ciphertext
|
|
}
|
|
)
|
|
expect(dec).toEqual(msg)
|
|
}
|
|
})
|
|
})
|
|
|
|
type User = ReturnType<typeof makeUser>
|
|
|
|
function makeUser() {
|
|
const store = makeTestAuthState()
|
|
const jid = `${Math.random().toString().replace('.', '')}@s.whatsapp.net`
|
|
const repository = makeLibSignalRepository(store)
|
|
return { store, jid, repository }
|
|
}
|
|
|
|
async function prepareForSendingMessage(
|
|
sender: User,
|
|
receiver: User,
|
|
preKeyId = 2
|
|
) {
|
|
const preKey = Curve.generateKeyPair()
|
|
await sender.repository.injectE2ESession(
|
|
{
|
|
jid: receiver.jid,
|
|
session: {
|
|
registrationId: receiver.store.creds.registrationId,
|
|
identityKey: generateSignalPubKey(receiver.store.creds.signedIdentityKey.public),
|
|
signedPreKey: {
|
|
keyId: receiver.store.creds.signedPreKey.keyId,
|
|
publicKey: generateSignalPubKey(receiver.store.creds.signedPreKey.keyPair.public),
|
|
signature: receiver.store.creds.signedPreKey.signature,
|
|
},
|
|
preKey: {
|
|
keyId: preKeyId,
|
|
publicKey: generateSignalPubKey(preKey.public),
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
await receiver.store.keys.set({
|
|
'pre-key': {
|
|
[preKeyId]: preKey
|
|
}
|
|
})
|
|
}
|
|
|
|
function makeTestAuthState(): SignalAuthState {
|
|
const identityKey = Curve.generateKeyPair()
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const store: { [_: string]: any } = {}
|
|
return {
|
|
creds: {
|
|
signedIdentityKey: identityKey,
|
|
registrationId: generateRegistrationId(),
|
|
signedPreKey: signedKeyPair(identityKey, 1),
|
|
},
|
|
keys: {
|
|
get(type, ids) {
|
|
const data: { [_: string]: SignalDataTypeMap[typeof type] } = { }
|
|
for(const id of ids) {
|
|
const item = store[getUniqueId(type, id)]
|
|
if(typeof item !== 'undefined') {
|
|
data[id] = item
|
|
}
|
|
}
|
|
|
|
return data
|
|
},
|
|
set(data) {
|
|
for(const type in data) {
|
|
for(const id in data[type]) {
|
|
store[getUniqueId(type, id)] = data[type][id]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
function getUniqueId(type: string, id: string) {
|
|
return `${type}.${id}`
|
|
}
|
|
} |