lint: stricter linting rules

This commit is contained in:
Adhiraj Singh
2022-03-01 16:32:14 +05:30
parent c00c3da313
commit de7d1002a9
39 changed files with 534 additions and 526 deletions

View File

@@ -128,10 +128,10 @@ export const useSingleFileAuthState = (filename: string, logger?: Logger): { sta
JSON.stringify({ creds, keys }, BufferJSON.replacer, 2)
)
}
if(existsSync(filename)) {
const result = JSON.parse(
readFileSync(filename, { encoding: 'utf-8' }),
readFileSync(filename, { encoding: 'utf-8' }),
BufferJSON.reviver
)
creds = result.creds
@@ -141,8 +141,8 @@ export const useSingleFileAuthState = (filename: string, logger?: Logger): { sta
keys = { }
}
return {
state: {
return {
state: {
creds,
keys: {
get: (type, ids) => {
@@ -172,7 +172,7 @@ export const useSingleFileAuthState = (filename: string, logger?: Logger): { sta
saveState()
}
}
},
saveState
},
saveState
}
}

View File

@@ -5,7 +5,7 @@ import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABina
import { aesDecrypt, aesEncrypt, hkdf, hmacSign } from './crypto'
import { toNumber } from './generics'
import { LT_HASH_ANTI_TAMPERING } from './lt-hash'
import { downloadContentFromMessage, } from './messages-media'
import { downloadContentFromMessage, } from './messages-media'
type FetchAppStateSyncKey = (keyId: string) => Promise<proto.IAppStateSyncKeyData> | proto.IAppStateSyncKeyData
@@ -39,7 +39,7 @@ const generateMac = (operation: proto.SyncdMutation.SyncdMutationSyncdOperation,
const keyData = getKeyData()
const last = Buffer.alloc(8) // 8 bytes
last.set([ keyData.length ], last.length-1)
last.set([ keyData.length ], last.length - 1)
const total = Buffer.concat([ keyData, data, last ])
const hmac = hmacSign(total, key, 'sha512')
@@ -180,7 +180,7 @@ export const encodeSyncdPatch = async(
}
export const decodeSyncdMutations = async(
msgMutations: (proto.ISyncdMutation | proto.ISyncdRecord)[],
msgMutations: (proto.ISyncdMutation | proto.ISyncdRecord)[],
initialState: LTHashState,
getAppStateSyncKey: FetchAppStateSyncKey,
validateMacs: boolean
@@ -214,7 +214,7 @@ export const decodeSyncdMutations = async(
// otherwise, if it's only a record -- it'll be a SET mutation
const operation = 'operation' in msgMutation ? msgMutation.operation : proto.SyncdMutation.SyncdMutationSyncdOperation.SET
const record = ('record' in msgMutation && !!msgMutation.record) ? msgMutation.record : msgMutation as proto.ISyncdRecord
const key = await getKey(record.keyId!.id!)
const content = Buffer.from(record.value!.blob!)
const encContent = content.slice(0, -32)
@@ -236,12 +236,12 @@ export const decodeSyncdMutations = async(
}
}
const indexStr = Buffer.from(syncAction.index).toString()
const indexStr = Buffer.from(syncAction.index).toString()
mutations.push({
syncAction,
index: JSON.parse(indexStr),
})
ltGenerator.mix({
ltGenerator.mix({
indexMac: record.index!.blob!,
valueMac: ogValueMac,
operation: operation
@@ -252,7 +252,7 @@ export const decodeSyncdMutations = async(
}
export const decodeSyncdPatch = async(
msg: proto.ISyncdPatch,
msg: proto.ISyncdPatch,
name: WAPatchName,
initialState: LTHashState,
getAppStateSyncKey: FetchAppStateSyncKey,
@@ -263,11 +263,11 @@ export const decodeSyncdPatch = async(
const mainKeyObj = await getAppStateSyncKey(base64Key)
const mainKey = mutationKeys(mainKeyObj.keyData!)
const mutationmacs = msg.mutations!.map(mutation => mutation.record!.value!.blob!.slice(-32))
const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version!.version), name, mainKey.patchMacKey)
if(Buffer.compare(patchMac, msg.patchMac) !== 0) {
throw new Boom('Invalid patch mac')
}
}
}
const result = await decodeSyncdMutations(msg!.mutations!, initialState, getAppStateSyncKey, validateMacs)
@@ -277,7 +277,7 @@ export const decodeSyncdPatch = async(
export const extractSyncdPatches = async(result: BinaryNode) => {
const syncNode = getBinaryNodeChild(result, 'sync')
const collectionNodes = getBinaryNodeChildren(syncNode, 'collection')
const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], hasMorePatches: boolean, snapshot?: proto.ISyncdSnapshot } }
await Promise.all(
collectionNodes.map(
@@ -291,7 +291,7 @@ export const extractSyncdPatches = async(result: BinaryNode) => {
const name = collectionNode.attrs.name as WAPatchName
const hasMorePatches = collectionNode.attrs.has_more_patches === 'true'
let snapshot: proto.ISyncdSnapshot | undefined = undefined
if(snapshotNode && !!snapshotNode.content) {
if(!Buffer.isBuffer(snapshotNode)) {
@@ -313,13 +313,13 @@ export const extractSyncdPatches = async(result: BinaryNode) => {
const syncd = proto.SyncdPatch.decode(content! as Uint8Array)
if(!syncd.version) {
syncd.version = { version: +collectionNode.attrs.version+1 }
syncd.version = { version: +collectionNode.attrs.version + 1 }
}
syncds.push(syncd)
}
}
final[name] = { patches: syncds, hasMorePatches, snapshot }
}
)
@@ -354,7 +354,7 @@ export const decodeSyncdSnapshot = async(
) => {
const newState = newLTHashState()
newState.version = toNumber(snapshot.version!.version!)
const { hash, indexValueMap, mutations } = await decodeSyncdMutations(snapshot.records!, newState, getAppStateSyncKey, validateMacs)
newState.hash = hash
newState.indexValueMap = indexValueMap
@@ -408,7 +408,7 @@ export const decodePatches = async(
}
const patchVersion = toNumber(version.version!)
newState.version = patchVersion
const decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, validateMacs)
@@ -418,7 +418,7 @@ export const decodePatches = async(
if(typeof minimumVersionNumber === 'undefined' || patchVersion > minimumVersionNumber) {
successfulMutations.push(...decodeResult.mutations)
}
if(validateMacs) {
const base64Key = Buffer.from(keyId!.id!).toString('base64')
const keyEnc = await getAppStateSyncKey(base64Key)
@@ -450,7 +450,7 @@ export const chatModificationToAppPatch = (
throw new Boom('Expected last message to be not from me', { statusCode: 400 })
}
const lastMsg = lastMessages[lastMessages.length-1]
const lastMsg = lastMessages[lastMessages.length - 1]
if(lastMsg.key.fromMe) {
throw new Boom('Expected last message in array to be not from me', { statusCode: 400 })
}

View File

@@ -29,7 +29,7 @@ export const signedKeyPair = (keyPair: KeyPair, keyId: number) => {
pubKey.set(signKeys.public, 1)
const signature = Curve.sign(keyPair.private, pubKey)
return { keyPair: signKeys, signature, keyId }
}
@@ -78,10 +78,10 @@ export function hkdf(buffer: Uint8Array, expandedLength: number, { info, salt }:
let prev = Buffer.from([])
const buffers = []
const num_blocks = Math.ceil(expandedLength / hashLength)
const infoBuff = Buffer.from(info || [])
for(var i=0; i<num_blocks; i++) {
for(var i = 0; i < num_blocks; i++) {
const hmac = createHmac(hashAlg, prk)
// XXX is there a more optimal way to build up buffers?
const input = Buffer.concat([

View File

@@ -62,7 +62,7 @@ export const decodeMessageStanza = (stanza: BinaryNode, auth: AuthenticationStat
const fromMe = isMe(stanza.attrs.participant || stanza.attrs.from)
const pushname = stanza.attrs.notify
const key: WAMessageKey = {
remoteJid: chatId,
fromMe,
@@ -83,21 +83,21 @@ export const decodeMessageStanza = (stanza: BinaryNode, auth: AuthenticationStat
return {
fullMessage,
decryptionTask: (async() => {
let decryptables = 0
let decryptables = 0
if(Array.isArray(stanza.content)) {
for(const { tag, attrs, content } of stanza.content) {
if(tag !== 'enc') {
continue
}
if(!(content instanceof Uint8Array)) {
continue
}
}
decryptables += 1
let msgBuffer: Buffer
try {
const e2eType = attrs.type
switch (e2eType) {
@@ -110,13 +110,13 @@ export const decodeMessageStanza = (stanza: BinaryNode, auth: AuthenticationStat
msgBuffer = await decryptSignalProto(user, e2eType, content as Buffer, auth)
break
}
let msg: proto.IMessage = proto.Message.decode(unpadRandomMax16(msgBuffer))
msg = msg.deviceSentMessage?.message || msg
if(msg.senderKeyDistributionMessage) {
await processSenderKeyMessage(author, msg.senderKeyDistributionMessage, auth)
}
if(fullMessage.message) {
Object.assign(fullMessage.message, msg)
} else {

View File

@@ -38,7 +38,7 @@ export const BufferJSON = {
}
return value
}
}
}
export const writeRandomPadMax16 = (e: Binary) => {
@@ -47,7 +47,7 @@ export const writeRandomPadMax16 = (e: Binary) => {
e.writeUint8(t)
}
}
var t = randomBytes(1)
r(e, 1 + (15 & t[0]))
return e
@@ -58,12 +58,12 @@ export const unpadRandomMax16 = (e: Uint8Array | Buffer) => {
if(0 === t.length) {
throw new Error('unpadPkcs7 given empty bytes')
}
var r = t[t.length - 1]
if(r > t.length) {
throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`)
}
return new Uint8Array(t.buffer, t.byteOffset, t.length - r)
}
@@ -88,7 +88,7 @@ export const encodeInt = (e: number, t: number) => {
return a
}
export const encodeBigEndian = (e: number, t=4) => {
export const encodeBigEndian = (e: number, t = 4) => {
let r = e
const a = new Uint8Array(t)
for(let i = t - 1; i >= 0; i--) {
@@ -121,7 +121,7 @@ export function shallowChanges <T>(old: T, current: T, { lookForDeletedKeys }: {
}
/** unix timestamp of a date in seconds */
export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime()/1000)
export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime() / 1000)
export type DebouncedTimeout = ReturnType<typeof debouncedTimeout>
@@ -175,7 +175,7 @@ export async function promiseTimeout<T>(ms: number, promise: (resolve: (v?: T)=>
const stack = new Error().stack
// Create a promise that rejects in <ms> milliseconds
const { delay, cancel } = delayCancellable (ms)
const { delay, cancel } = delayCancellable (ms)
const p = new Promise ((resolve, reject) => {
delay
.then(() => reject(
@@ -186,8 +186,8 @@ export async function promiseTimeout<T>(ms: number, promise: (resolve: (v?: T)=>
}
})
))
.catch (err => reject(err))
.catch (err => reject(err))
promise (resolve, reject)
})
.finally (cancel)
@@ -202,7 +202,7 @@ export const bindWaitForConnectionUpdate = (ev: CommonBaileysEventEmitter<any>)
let listener: (item: Partial<ConnectionState>) => void
await (
promiseTimeout(
timeoutMs,
timeoutMs,
(resolve, reject) => {
listener = (update) => {
if(check(update)) {
@@ -236,7 +236,7 @@ export const printQRIfNecessaryListener = (ev: CommonBaileysEventEmitter<any>, l
/**
* utility that fetches latest baileys version from the master branch.
* Use to ensure your WA connection is always on the latest version
* Use to ensure your WA connection is always on the latest version
*/
export const fetchLatestBaileysVersion = async() => {
const URL = 'https://raw.githubusercontent.com/adiwajshing/Baileys/master/src/Defaults/baileys-version.json'

View File

@@ -10,21 +10,21 @@ export const newLegacyAuthCreds = () => ({
}) as LegacyAuthenticationCreds
export const decodeWAMessage = (
message: Buffer | string,
auth: { macKey: Buffer, encKey: Buffer },
fromMe: boolean=false
message: Buffer | string,
auth: { macKey: Buffer, encKey: Buffer },
fromMe: boolean = false
) => {
let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message
if(commaIndex < 0) {
throw new Boom('invalid message', { data: message })
} // if there was no comma, then this message must be not be valid
if(message[commaIndex+1] === ',') {
if(message[commaIndex + 1] === ',') {
commaIndex += 1
}
let data = message.slice(commaIndex+1, message.length)
let data = message.slice(commaIndex + 1, message.length)
// get the message tag.
// If a query was done, the server will respond with the same message tag we sent the query with
const messageTag: string = message.slice(0, commaIndex).toString()
@@ -43,7 +43,7 @@ export const decodeWAMessage = (
throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession })
}
/*
/*
If the data recieved was not a JSON, then it must be an encrypted message.
Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys
*/
@@ -51,11 +51,11 @@ export const decodeWAMessage = (
tags = [data[0], data[1]]
data = data.slice(2, data.length)
}
const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message
data = data.slice(32, data.length) // the actual message
const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey
if(checksum.equals(computedChecksum)) {
// the checksum the server sent, must match the one we computed for the message to be valid
const decrypted = aesDecrypt(data, encKey) // decrypt using AES
@@ -73,7 +73,7 @@ export const decodeWAMessage = (
})
}
}
}
}
}
return [messageTag, json, tags] as const
@@ -85,7 +85,7 @@ export const decodeWAMessage = (
* @param json
*/
export const validateNewConnection = (
json: { [_: string]: any },
json: { [_: string]: any },
auth: LegacyAuthenticationCreds,
curveKeys: CurveKeyPair
) => {
@@ -164,7 +164,7 @@ export const useSingleFileLegacyAuthState = (file: string) => {
if(existsSync(file)) {
state = JSON.parse(
readFileSync(file, { encoding: 'utf-8' }),
readFileSync(file, { encoding: 'utf-8' }),
BufferJSON.reviver
)
if(typeof state.encKey === 'string') {

View File

@@ -2,7 +2,7 @@ import { hkdf } from './crypto'
/**
* LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
* if the same series of mutations was made sequentially.
*/

View File

@@ -54,7 +54,7 @@ export const hkdfInfoKey = (type: MediaType) => {
if(type === 'md-app-state') {
str = 'App State'
}
const hkdfInfo = str[0].toUpperCase() + str.slice(1)
return `WhatsApp ${hkdfInfo} Keys`
}
@@ -145,7 +145,7 @@ export const generateProfilePicture = async(mediaUpload: WAMediaUpload) => {
.resize(640, 640, RESIZE_BILINEAR)
.getBufferAsync(MIME_JPEG)
}
return {
img: await img,
}
@@ -207,8 +207,8 @@ export const getStream = async(item: WAMediaUpload) => {
/** generates a thumbnail for a given media, if required */
export async function generateThumbnail(
file: string,
mediaType: 'video' | 'image',
file: string,
mediaType: 'video' | 'image',
options: {
logger?: Logger
}
@@ -229,7 +229,7 @@ export async function generateThumbnail(
options.logger?.debug('could not generate video thumb: ' + err)
}
}
return thumbnail
}
@@ -238,9 +238,9 @@ export const getHttpStream = async(url: string | URL, options: AxiosRequestConfi
const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' })
return fetched.data as Readable
}
export const encryptedStream = async(
media: WAMediaUpload,
media: WAMediaUpload,
mediaType: MediaType,
saveOriginalFileIfRequired = true,
logger?: Logger
@@ -266,7 +266,7 @@ export const encryptedStream = async(
writeStream = createWriteStream(bodyPath)
didSaveToTmpPath = true
}
let fileLength = 0
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv)
let hmac = Crypto.createHmac('sha256', macKey).update(iv)
@@ -278,7 +278,7 @@ export const encryptedStream = async(
hmac = hmac.update(buff)
encWriteStream.push(buff)
}
try {
for await (const data of stream) {
fileLength += data.length
@@ -293,21 +293,21 @@ export const encryptedStream = async(
}
onChunk(aes.final())
const mac = hmac.digest().slice(0, 10)
sha256Enc = sha256Enc.update(mac)
const fileSha256 = sha256Plain.digest()
const fileEncSha256 = sha256Enc.digest()
encWriteStream.push(mac)
encWriteStream.push(null)
writeStream && writeStream.end()
stream.destroy()
logger?.debug('encrypted data successfully')
return {
mediaKey,
encWriteStream,
@@ -356,14 +356,14 @@ export const downloadContentFromMessage = async(
if(startByte) {
const chunk = toSmallestChunkSize(startByte || 0)
if(chunk) {
startChunk = chunk-AES_CHUNK_SIZE
startChunk = chunk - AES_CHUNK_SIZE
bytesFetched = chunk
firstBlockIsIV = true
}
}
const endChunk = endByte ? toSmallestChunkSize(endByte || 0)+AES_CHUNK_SIZE : undefined
const endChunk = endByte ? toSmallestChunkSize(endByte || 0) + AES_CHUNK_SIZE : undefined
const headers: { [_: string]: string } = {
Origin: DEFAULT_ORIGIN,
@@ -377,7 +377,7 @@ export const downloadContentFromMessage = async(
// download the message
const fetched = await getHttpStream(
downloadUrl,
downloadUrl,
{
headers,
maxBodyLength: Infinity,
@@ -392,11 +392,11 @@ export const downloadContentFromMessage = async(
const pushBytes = (bytes: Buffer, push: (bytes: Buffer) => void) => {
if(startByte || endByte) {
const start = bytesFetched >= startByte ? undefined : Math.max(startByte-bytesFetched, 0)
const end = bytesFetched+bytes.length < endByte ? undefined : Math.max(endByte-bytesFetched, 0)
const start = bytesFetched >= startByte ? undefined : Math.max(startByte - bytesFetched, 0)
const end = bytesFetched + bytes.length < endByte ? undefined : Math.max(endByte - bytesFetched, 0)
push(bytes.slice(start, end))
bytesFetched += bytes.length
} else {
push(bytes)
@@ -406,7 +406,7 @@ export const downloadContentFromMessage = async(
const output = new Transform({
transform(chunk, _, callback) {
let data = Buffer.concat([remainingBytes, chunk])
const decryptLength = toSmallestChunkSize(data.length)
remainingBytes = data.slice(decryptLength)
data = data.slice(0, decryptLength)
@@ -424,7 +424,7 @@ export const downloadContentFromMessage = async(
if(endByte) {
aes.setAutoPadding(false)
}
}
try {
@@ -432,7 +432,7 @@ export const downloadContentFromMessage = async(
callback()
} catch(error) {
callback(error)
}
}
},
final(callback) {
try {
@@ -451,14 +451,14 @@ export const downloadContentFromMessage = async(
* @param message the media message you want to decode
*/
export async function decryptMediaMessageBuffer(message: WAMessageContent): Promise<Readable> {
/*
/*
One can infer media type from the key in the message
it is usually written as [mediaType]Message. Eg. imageMessage, audioMessage etc.
*/
const type = Object.keys(message)[0] as MessageType
if(
!type ||
type === 'conversation' ||
type === 'conversation' ||
type === 'extendedTextMessage'
) {
throw new Boom(`no media message for "${type}"`, { statusCode: 400 })
@@ -492,8 +492,8 @@ export function extensionForMediaMessage(message: WAMessageContent) {
const type = Object.keys(message)[0] as MessageType
let extension: string
if(
type === 'locationMessage' ||
type === 'liveLocationMessage' ||
type === 'locationMessage' ||
type === 'liveLocationMessage' ||
type === 'productMessage'
) {
extension = '.jpeg'
@@ -539,8 +539,8 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C
const body = await axios.post(
url,
reqBody,
{
headers: {
{
headers: {
'Content-Type': 'application/octet-stream',
'Origin': DEFAULT_ORIGIN
},
@@ -552,7 +552,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C
}
)
result = body.data
if(result?.url || result?.directPath) {
urls = {
mediaUrl: result.url,
@@ -568,7 +568,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C
result = error.response?.data
}
const isLast = hostname === hosts[uploadInfo.hosts.length-1]?.hostname
const isLast = hostname === hosts[uploadInfo.hosts.length - 1]?.hostname
logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`)
}
}

View File

@@ -2,22 +2,22 @@ import { Boom } from '@hapi/boom'
import { promises as fs } from 'fs'
import { proto } from '../../WAProto'
import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults'
import {
AnyMediaMessageContent,
AnyMessageContent,
MediaGenerationOptions,
MediaType,
MessageContentGenerationOptions,
MessageGenerationOptions,
import {
AnyMediaMessageContent,
AnyMessageContent,
MediaGenerationOptions,
MediaType,
MessageContentGenerationOptions,
MessageGenerationOptions,
MessageGenerationOptionsFromContent,
MessageType,
MessageType,
MessageUserReceipt,
WAMediaUpload,
WAMessage,
WAMessageContent,
WAMediaUpload,
WAMessage,
WAMessageContent,
WAMessageStatus,
WAProto,
WATextMessage
WAProto,
WATextMessage
} from '../Types'
import { generateMessageID, unixTimestampSeconds } from './generics'
import { encryptedStream, generateThumbnail, getAudioDuration } from './messages-media'
@@ -54,7 +54,7 @@ const MessageTypeProto = {
const ButtonType = proto.ButtonsMessage.ButtonsMessageHeaderType
export const prepareWAMessageMedia = async(
message: AnyMediaMessageContent,
message: AnyMediaMessageContent,
options: MediaGenerationOptions
) => {
const logger = options.logger
@@ -66,15 +66,15 @@ export const prepareWAMessageMedia = async(
}
}
const uploadData: MediaUploadData = {
const uploadData: MediaUploadData = {
...message,
media: message[mediaType]
}
delete uploadData[mediaType]
// check if cacheable + generate cache key
const cacheableKey = typeof uploadData.media === 'object' &&
('url' in uploadData.media) &&
!!uploadData.media.url &&
const cacheableKey = typeof uploadData.media === 'object' &&
('url' in uploadData.media) &&
!!uploadData.media.url &&
!!options.mediaCache && (
// generate the key
mediaType + ':' + uploadData.media.url!.toString()
@@ -93,7 +93,7 @@ export const prepareWAMessageMedia = async(
const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey)
if(mediaBuff) {
logger?.debug({ cacheableKey }, 'got media cache hit')
const obj = WAProto.Message.decode(mediaBuff)
const key = `${mediaType}Message`
@@ -105,7 +105,7 @@ export const prepareWAMessageMedia = async(
}
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined'
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
(typeof uploadData['jpegThumbnail'] === 'undefined')
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation
const {
@@ -118,7 +118,7 @@ export const prepareWAMessageMedia = async(
didSaveToTmpPath
} = await encryptedStream(uploadData.media, mediaType, requiresOriginalForSomeProcessing)
// url safe Base64 encode the SHA256 hash of the body
const fileEncSha256B64 = encodeURIComponent(
const fileEncSha256B64 = encodeURIComponent(
fileEncSha256.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
@@ -239,7 +239,7 @@ export const generateForwardMessageContent = (
}
export const generateWAMessageContent = async(
message: AnyMessageContent,
message: AnyMessageContent,
options: MessageContentGenerationOptions
) => {
let m: WAMessageContent = {}
@@ -256,7 +256,7 @@ export const generateWAMessageContent = async(
extContent.previewType = 0
} catch(error) { // ignore if fails
options.logger?.warn({ trace: error.stack }, 'url generation failed')
}
}
}
m.extendedTextMessage = extContent
@@ -265,7 +265,7 @@ export const generateWAMessageContent = async(
if(!contactLen) {
throw new Boom('require atleast 1 contact', { statusCode: 400 })
}
if(contactLen === 1) {
m.contactMessage = WAProto.ContactMessage.fromObject(message.contacts.contacts[0])
} else {
@@ -284,7 +284,7 @@ export const generateWAMessageContent = async(
message.force
)
} else if('disappearingMessagesInChat' in message) {
const exp = typeof message.disappearingMessagesInChat === 'boolean' ?
const exp = typeof message.disappearingMessagesInChat === 'boolean' ?
(message.disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) :
message.disappearingMessagesInChat
m = prepareDisappearingMessageSettingContent(exp)
@@ -309,7 +309,7 @@ export const generateWAMessageContent = async(
const type = Object.keys(m)[0].replace('Message', '').toUpperCase()
buttonsMessage.headerType = ButtonType[type]
Object.assign(buttonsMessage, m)
}
@@ -324,7 +324,7 @@ export const generateWAMessageContent = async(
hydratedButtons: message.templateButtons
}
}
if('text' in message) {
templateMessage.hydratedTemplate.hydratedContentText = message.text
} else {
@@ -332,7 +332,7 @@ export const generateWAMessageContent = async(
if('caption' in message) {
templateMessage.hydratedTemplate.hydratedContentText = message.caption
}
Object.assign(templateMessage.hydratedTemplate, m)
}
@@ -342,7 +342,7 @@ export const generateWAMessageContent = async(
m = { templateMessage }
}
if('sections' in message && !!message.sections) {
const listMessage: proto.IListMessage = {
sections: message.sections,
@@ -370,8 +370,8 @@ export const generateWAMessageContent = async(
}
export const generateWAMessageFromContent = (
jid: string,
message: WAMessageContent,
jid: string,
message: WAMessageContent,
options: MessageGenerationOptionsFromContent
) => {
if(!options.timestamp) {
@@ -389,7 +389,7 @@ export const generateWAMessageFromContent = (
message[key].contextInfo.participant = participant
message[key].contextInfo.stanzaId = quoted.key.id
message[key].contextInfo.quotedMessage = quoted.message
// if a participant is quoted, then it must be a group
// hence, remoteJid of group must also be entered
if(quoted.key.participant || quoted.participant) {
@@ -403,7 +403,7 @@ export const generateWAMessageFromContent = (
// and it's not a protocol message -- delete, toggle disappear message
key !== 'protocolMessage' &&
// already not converted to disappearing message
key !== 'ephemeralMessage'
key !== 'ephemeralMessage'
) {
message[key].contextInfo = {
...(message[key].contextInfo || {}),
@@ -478,10 +478,10 @@ export const extractMessageContent = (content: WAMessageContent | undefined | nu
return { conversation: 'contentText' in msg ? msg.contentText : ('hydratedContentText' in msg ? msg.hydratedContentText : '') }
}
}
content = content?.ephemeralMessage?.message ||
content = content?.ephemeralMessage?.message ||
content?.viewOnceMessage?.message ||
content ||
content ||
undefined
if(content?.buttonsMessage) {

View File

@@ -30,7 +30,7 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
const result = Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()])
writeCounter += 1
authenticate(result)
return result
}
@@ -42,8 +42,8 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
const cipher = createDecipheriv('aes-256-gcm', decKey, iv)
// decrypt additional adata
const tagLength = 128 >> 3
const enc = ciphertext.slice(0, ciphertext.length-tagLength)
const tag = ciphertext.slice(ciphertext.length-tagLength)
const enc = ciphertext.slice(0, ciphertext.length - tagLength)
const tag = ciphertext.slice(ciphertext.length - tagLength)
// set additional data
cipher.setAAD(hash)
cipher.setAuthTag(tag)
@@ -55,7 +55,7 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
} else {
writeCounter += 1
}
authenticate(ciphertext)
return result
}
@@ -83,7 +83,7 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
writeCounter = 0
isFinished = true
}
const data = Binary.build(NOISE_MODE).readBuffer()
let hash = Buffer.from(data.byteLength === 32 ? data : sha256(Buffer.from(data)))
let salt = hash
@@ -109,19 +109,19 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => {
authenticate(serverHello!.ephemeral!)
mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral!))
const decStaticContent = decrypt(serverHello!.static!)
mixIntoKey(Curve.sharedKey(privateKey, decStaticContent))
const certDecoded = decrypt(serverHello!.payload!)
const { details: certDetails, signature: certSignature } = proto.NoiseCertificate.decode(certDecoded)
const { key: certKey } = proto.NoiseCertificateDetails.decode(certDetails)
if(Buffer.compare(decStaticContent, certKey) !== 0) {
throw new Boom('certification match failed', { statusCode: 400 })
}
const keyEnc = encrypt(noiseKey.public)
mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello!.ephemeral!))
@@ -135,16 +135,16 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
const introSize = sentIntro ? 0 : NOISE_WA_HEADER.length
outBinary.ensureAdditionalCapacity(introSize + 3 + data.byteLength)
if(!sentIntro) {
outBinary.writeByteArray(NOISE_WA_HEADER)
sentIntro = true
}
outBinary.writeUint8(data.byteLength >> 16)
outBinary.writeUint16(65535 & data.byteLength)
outBinary.write(data)
const bytes = outBinary.readByteArray()
return bytes as Uint8Array
},
@@ -175,5 +175,5 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key
inBinary.peek(peekSize)
}
}
}
}

View File

@@ -27,7 +27,7 @@ export const createSignalIdentity = (
wid: string,
accountSignatureKey: Uint8Array
): SignalIdentity => {
return {
return {
identifier: { name: wid, deviceId: 0 },
identifierKey: generateSignalPubKey(accountSignatureKey)
}
@@ -145,7 +145,7 @@ export const decryptGroupSignalProto = (group: string, user: string, msg: Buffer
export const processSenderKeyMessage = async(
authorJid: string,
item: proto.ISenderKeyDistributionMessage,
item: proto.ISenderKeyDistributionMessage,
auth: SignalAuthState
) => {
const builder = new GroupSessionBuilder(signalStorage(auth))
@@ -171,7 +171,7 @@ export const decryptSignalProto = async(user: string, type: 'pkmsg' | 'msg', msg
break
case 'msg':
result = await session.decryptWhisperMessage(msg)
break
break
}
return result
@@ -231,7 +231,7 @@ export const parseAndInjectE2ESessions = async(node: BinaryNode, auth: SignalAut
const identity = getBinaryNodeChildBuffer(node, 'identity')
const jid = node.attrs.jid
const registrationId = getBinaryNodeChildUInt(node, 'registration', 4)
const device = {
registrationId,
identityKey: generateSignalPubKey(identity),

View File

@@ -130,8 +130,8 @@ export const configureSuccessfulPairing = (
id: msgId,
},
content: [
{
tag: 'pair-device-sign',
{
tag: 'pair-device-sign',
attrs: { },
content: [
{ tag: 'device-identity', attrs: { 'key-index': `${keyIndex}` }, content: accountEnc }
@@ -141,9 +141,9 @@ export const configureSuccessfulPairing = (
}
const authUpdate: Partial<AuthenticationCreds> = {
account,
me: { id: jid, verifiedName },
signalIdentities: [...(signalIdentities || []), identity]
account,
me: { id: jid, verifiedName },
signalIdentities: [...(signalIdentities || []), identity]
}
return {
creds: authUpdate,