You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
2.6 KiB

import * as path from 'path'
import RNCryptor from '../utils/rncryptor'
import * as fetch from 'node-fetch'
import {parseLDAT} from '../utils/ldat'
import * as rsa from '../crypto/rsa'
import * as crypto from 'crypto'
import * as meme from '../utils/meme'
import * as FormData from 'form-data'
const constants = require(path.join(__dirname,'../../config/constants.json'))
const msgtypes = constants.message_types
export async function modifyPayload(payload, chat) {
if(payload.type===msgtypes.attachment) {
const mt = payload.message && payload.message.mediaToken
const key = payload.message && payload.message.mediaKey
const typ = payload.message && payload.message.mediaType
if(!mt || !key) return payload
const terms = parseLDAT(mt)
if(!terms.host) return payload
try {
const r = await fetch(`https://${terms.host}/file/${mt}`, {
headers: {'Authorization': `Bearer ${meme.mediaToken}`}
})
const buf = await r.buffer()
const decMediaKey = rsa.decrypt(chat.groupPrivateKey, key)
const imgBase64 = RNCryptor.Decrypt(decMediaKey, buf.toString('base64'))
const newKey = crypto.randomBytes(20).toString('hex')
const encImg = RNCryptor.Encrypt(newKey, imgBase64)
var encImgBuffer = Buffer.from(encImg,'base64');
const form = new FormData()
form.append('file', encImgBuffer, {
contentType: typ||'image/jpg',
filename: 'Image.jpg',
knownLength:encImgBuffer.length,
})
const formHeaders = form.getHeaders()
const resp = await fetch(`https://${terms.host}/file`, {
method: 'POST',
headers: {
...formHeaders, // THIS IS REQUIRED!!!
'Authorization': `Bearer ${meme.mediaToken}`,
},
body:form
})
let json = await resp.json()
if(!json.muid) return payload
// PUT NEW TERMS, to finish in personalizeMessage
const amt = terms.meta&&terms.meta.amt
const ttl = terms.meta&&terms.meta.ttl
const mediaTerms: {[k:string]:any} = {
muid:json.muid, ttl:ttl||31536000,
meta:{...amt && {amt}},
skipSigning: amt ? true : false // only sign if its free
}
const encKey = rsa.encrypt(chat.groupKey, newKey)
return fillmsg(payload, {mediaTerms,mediaKey:encKey}) // key is re-encrypted later
} catch(e) {
console.log("[modify] error", e)
return payload
}
// how to link w og msg? ogMediaToken?
} else {
return payload
}
}
function fillmsg(full, props){
return {
...full, message: {
...full.message,
...props,
}
}
}