Browse Source

Merge pull request #43 from stakwork/msg-uid

Msg uid
feature/dockerfile-arm v0.9.9
Evan Feenstra 5 years ago
committed by GitHub
parent
commit
916e2cfdb0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      api/controllers/chats.ts
  2. 6
      api/controllers/invoices.ts
  3. 33
      api/controllers/media.ts
  4. 10
      api/controllers/messages.ts
  5. 8
      api/controllers/payment.ts
  6. 4
      api/helpers.ts
  7. 4
      api/hub.ts
  8. 6
      api/models/ts/mediaKey.ts
  9. 6
      api/models/ts/message.ts
  10. 273
      api/network/modify.ts
  11. 72
      api/network/receive.ts
  12. 7
      api/utils/setup.ts
  13. 2
      dist/api/controllers/chats.js.map
  14. 5
      dist/api/controllers/invoices.js
  15. 2
      dist/api/controllers/invoices.js.map
  16. 32
      dist/api/controllers/media.js
  17. 2
      dist/api/controllers/media.js.map
  18. 10
      dist/api/controllers/messages.js
  19. 2
      dist/api/controllers/messages.js.map
  20. 8
      dist/api/controllers/payment.js
  21. 2
      dist/api/controllers/payment.js.map
  22. 4
      dist/api/helpers.js
  23. 2
      dist/api/helpers.js.map
  24. 4
      dist/api/hub.js
  25. 2
      dist/api/hub.js.map
  26. 8
      dist/api/models/ts/mediaKey.js
  27. 2
      dist/api/models/ts/mediaKey.js.map
  28. 8
      dist/api/models/ts/message.js
  29. 2
      dist/api/models/ts/message.js.map
  30. 245
      dist/api/network/modify.js
  31. 2
      dist/api/network/modify.js.map
  32. 81
      dist/api/network/receive.js
  33. 2
      dist/api/network/receive.js.map
  34. 5
      dist/api/utils/setup.js
  35. 2
      dist/api/utils/setup.js.map

2
api/controllers/chats.ts

@ -196,8 +196,6 @@ const deleteChat = async (req, res) => {
success(res, { chat_id: id })
}
async function receiveGroupJoin(payload) {
console.log('=> receiveGroupJoin')
const { sender_pub_key, sender_alias, chat_uuid, chat_members, chat_type, isTribeOwner } = await helpers.parseReceiveParams(payload)

6
api/controllers/invoices.ts

@ -9,6 +9,7 @@ import { success } from '../utils/res'
import {sendConfirmation} from './confirmations'
import * as path from 'path'
import * as network from '../network'
import * as short from 'short-uuid'
const constants = require(path.join(__dirname,'../../config/constants.json'))
@ -74,7 +75,6 @@ const payInvoice = async (req, res) => {
call.write({ payment_request })
};
const cancelInvoice = (req, res) => {
res.status(200);
res.json({ success: false });
@ -139,6 +139,7 @@ const createInvoice = async (req, res) => {
} else {
const message = await models.Message.create({
chatId: chat.id,
uuid: short.generate(),
sender: owner.id,
type: constants.message_types.invoice,
amount: parseInt(invoice.num_satoshis),
@ -203,7 +204,7 @@ const receiveInvoice = async (payload) => {
var date = new Date();
date.setMilliseconds(0)
const { owner, sender, chat, msg_id, chat_type, sender_alias } = await helpers.parseReceiveParams(payload)
const { owner, sender, chat, msg_id, chat_type, sender_alias, msg_uuid } = await helpers.parseReceiveParams(payload)
if (!owner || !sender || !chat) {
return console.log('=> no group chat!')
}
@ -212,6 +213,7 @@ const receiveInvoice = async (payload) => {
const msg:{[k:string]:any} = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.invoice,
sender: sender.id,
amount: sat,

33
api/controllers/media.ts

@ -15,6 +15,7 @@ import {sendConfirmation} from './confirmations'
import * as path from 'path'
import * as network from '../network'
import * as meme from '../utils/meme'
import * as short from 'short-uuid'
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname,'../../config/app.json'))[env]
@ -88,8 +89,10 @@ const sendAttachmentMessage = async (req, res) => {
const mediaType = media_type || ''
const remoteMessageContent = remote_text_map?JSON.stringify(remote_text_map) : remote_text
const uuid = short.generate()
const message = await models.Message.create({
chatId: chat.id,
uuid: uuid,
sender: owner.id,
type: constants.message_types.attachment,
status: constants.statuses.pending,
@ -103,7 +106,7 @@ const sendAttachmentMessage = async (req, res) => {
updatedAt: date
})
saveMediaKeys(muid, media_key_map, chat.id, message.id)
saveMediaKeys(muid, media_key_map, chat.id, message.id, mediaType)
const mediaTerms: {[k:string]:any} = {
muid, ttl:TTL,
@ -113,6 +116,7 @@ const sendAttachmentMessage = async (req, res) => {
const msg: {[k:string]:any} = {
mediaTerms, // this gets converted to mediaToken
id: message.id,
uuid: uuid,
content: remote_text_map||remote_text||text||file_name||'',
mediaKey: media_key_map,
mediaType: mediaType,
@ -130,7 +134,7 @@ const sendAttachmentMessage = async (req, res) => {
})
}
function saveMediaKeys(muid, mediaKeyMap, chatId, messageId){
function saveMediaKeys(muid, mediaKeyMap, chatId, messageId, mediaType){
if (typeof mediaKeyMap!=='object'){
console.log('wrong type for mediaKeyMap')
return
@ -144,6 +148,7 @@ function saveMediaKeys(muid, mediaKeyMap, chatId, messageId){
muid, chatId, key, messageId,
receiver: receiverID,
createdAt: date,
mediaType
})
}
}
@ -175,8 +180,10 @@ const purchase = async (req, res) => {
const message = await models.Message.create({
chatId: chat.id,
uuid: short.generate(),
sender: owner.id,
type: constants.message_types.purchase,
amount: amount||0,
mediaToken: media_token,
date: date,
createdAt: date,
@ -184,7 +191,7 @@ const purchase = async (req, res) => {
})
const msg={
amount, mediaToken:media_token, id:message.id,
amount, mediaToken:media_token, id:message.id, uuid:message.uuid,
}
network.sendMessage({
chat: {...chat.dataValues, contactIds:[contact_id]},
@ -208,15 +215,17 @@ const receivePurchase = async (payload) => {
var date = new Date();
date.setMilliseconds(0)
const {owner, sender, chat, amount, mediaToken} = await helpers.parseReceiveParams(payload)
const {owner, sender, chat, amount, mediaToken, msg_uuid, chat_type} = await helpers.parseReceiveParams(payload)
if(!owner || !sender || !chat) {
return console.log('=> group chat not found!')
}
const message = await models.Message.create({
chatId: chat.id,
uuid: msg_uuid,
sender: sender.id,
type: constants.message_types.purchase,
amount: amount||0,
mediaToken: mediaToken,
date: date,
createdAt: date,
@ -238,11 +247,15 @@ const receivePurchase = async (payload) => {
if (!ogMessage){
return console.log('no original message')
}
const isTribe = chat_type===constants.chat_types.tribe
// find mediaKey for who sent
const mediaKey = await models.MediaKey.findOne({where:{
muid, receiver: sender.id,
muid, receiver: isTribe?0:sender.id,
}})
console.log('mediaKey found!',mediaKey)
// console.log('mediaKey found!',mediaKey.dataValues)
if(!mediaKey) return // this is from another person (admin is forwarding)
const terms = parseLDAT(mediaToken)
// get info
@ -321,7 +334,7 @@ const receivePurchaseAccept = async (payload) => {
var date = new Date();
date.setMilliseconds(0)
const {owner, sender, chat, mediaToken, mediaKey, mediaType} = await helpers.parseReceiveParams(payload)
const {owner, sender, chat, mediaToken, mediaKey, mediaType, originalMuid} = await helpers.parseReceiveParams(payload)
if(!owner || !sender || !chat) {
return console.log('=> no group chat!')
}
@ -350,6 +363,7 @@ const receivePurchaseAccept = async (payload) => {
mediaToken,
mediaKey,
mediaType,
originalMuid:originalMuid||'',
date: date,
createdAt: date,
updatedAt: date
@ -388,18 +402,19 @@ const receivePurchaseDeny = async (payload) => {
}
const receiveAttachment = async (payload) => {
console.log('received attachment', { payload })
// console.log('received attachment', { payload })
var date = new Date();
date.setMilliseconds(0)
const {owner, sender, chat, mediaToken, mediaKey, mediaType, content, msg_id, chat_type, sender_alias} = await helpers.parseReceiveParams(payload)
const {owner, sender, chat, mediaToken, mediaKey, mediaType, content, msg_id, chat_type, sender_alias, msg_uuid} = await helpers.parseReceiveParams(payload)
if(!owner || !sender || !chat) {
return console.log('=> no group chat!')
}
const msg: {[k:string]:any} = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.attachment,
sender: sender.id,
date: date,

10
api/controllers/messages.ts

@ -9,6 +9,7 @@ import { success } from '../utils/res'
import {sendConfirmation} from './confirmations'
import * as path from 'path'
import * as network from '../network'
import * as short from 'short-uuid'
const constants = require(path.join(__dirname,'../../config/constants.json'))
@ -122,6 +123,7 @@ const sendMessage = async (req, res) => {
const remoteMessageContent = remote_text_map?JSON.stringify(remote_text_map) : remote_text
const msg={
chatId: chat.id,
uuid: short.generate(),
type: constants.message_types.message,
sender: owner.id,
amount: amount||0,
@ -144,19 +146,20 @@ const sendMessage = async (req, res) => {
type: constants.message_types.message,
message: {
id: message.id,
uuid: message.uuid,
content: remote_text_map || remote_text || text
}
})
}
const receiveMessage = async (payload) => {
console.log('received message', { payload })
// console.log('received message', { payload })
var date = new Date();
date.setMilliseconds(0)
const total_spent = 1
const {owner, sender, chat, content, remote_content, msg_id, chat_type, sender_alias} = await helpers.parseReceiveParams(payload)
const {owner, sender, chat, content, remote_content, msg_id, chat_type, sender_alias, msg_uuid} = await helpers.parseReceiveParams(payload)
if(!owner || !sender || !chat) {
return console.log('=> no group chat!')
}
@ -164,6 +167,7 @@ const receiveMessage = async (payload) => {
const msg:{[k:string]:any} = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.message,
asciiEncodedTotal: total_spent,
sender: sender.id,
@ -179,7 +183,7 @@ const receiveMessage = async (payload) => {
}
const message = await models.Message.create(msg)
console.log('saved message', message.dataValues)
// console.log('saved message', message.dataValues)
socket.sendJson({
type: 'message',

8
api/controllers/payment.ts

@ -8,6 +8,7 @@ import * as lightning from '../utils/lightning'
import {tokenFromTerms} from '../utils/ldat'
import * as constants from '../../config/constants.json'
import * as network from '../network'
import * as short from 'short-uuid'
const sendPayment = async (req, res) => {
const {
@ -57,6 +58,7 @@ const sendPayment = async (req, res) => {
const msg: {[k:string]:any} = {
chatId: chat.id,
uuid: short.generate(),
sender: owner.id,
type: constants.message_types.direct_payment,
amount: amount,
@ -82,6 +84,7 @@ const sendPayment = async (req, res) => {
const msgToSend: {[k:string]:any} = {
id:message.id,
uuid:message.uuid,
amount,
}
if(muid) {
@ -125,13 +128,14 @@ const receivePayment = async (payload) => {
var date = new Date();
date.setMilliseconds(0)
const {owner, sender, chat, amount, content, mediaType, mediaToken, chat_type, sender_alias} = await helpers.parseReceiveParams(payload)
const {owner, sender, chat, amount, content, mediaType, mediaToken, chat_type, sender_alias, msg_uuid} = await helpers.parseReceiveParams(payload)
if(!owner || !sender || !chat) {
return console.log('=> no group chat!')
}
const msg: {[k:string]:any} = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.direct_payment,
sender: sender.id,
amount: amount,
@ -149,7 +153,7 @@ const receivePayment = async (payload) => {
const message = await models.Message.create(msg)
console.log('saved message', message.dataValues)
// console.log('saved message', message.dataValues)
socket.sendJson({
type: 'direct_payment',

4
api/helpers.ts

@ -145,7 +145,9 @@ async function parseReceiveParams(payload) {
const content = dat.message.content
const remote_content = dat.message.remoteContent
const mediaToken = dat.message.mediaToken
const originalMuid = dat.message.originalMuid
const msg_id = dat.message.id||0
const msg_uuid = dat.message.uuid||''
const mediaKey = dat.message.mediaKey
const mediaType = dat.message.mediaType
const isTribeOwner = dat.isTribeOwner?true:false
@ -170,7 +172,7 @@ async function parseReceiveParams(payload) {
}
chat = await models.Chat.findOne({ where: { uuid: chat_uuid } })
}
return { owner, sender, chat, sender_pub_key, sender_alias, isTribeOwner, chat_uuid, amount, content, mediaToken, mediaKey, mediaType, chat_type, msg_id, chat_members, chat_name, chat_host, chat_key, remote_content }
return { owner, sender, chat, sender_pub_key, sender_alias, isTribeOwner, chat_uuid, amount, content, mediaToken, mediaKey, mediaType, originalMuid, chat_type, msg_id, chat_members, chat_name, chat_host, chat_key, remote_content, msg_uuid }
}
export {

4
api/hub.ts

@ -238,7 +238,9 @@ const sendNotification = async (chat, name, type) => {
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(json => console.log('[hub notification]', json))
.then(json => {
// console.log('[hub notification]', json)
})
}
export {

6
api/models/ts/mediaKey.ts

@ -37,7 +37,13 @@ export default class MediaKey extends Model<MediaKey> {
@Column
createdAt: Date
@Column
mediaType: string
@Column(DataType.BIGINT)
sender: number // for tribe, remember the sender
@Column
originalMuid: string // for tribe, remember the og muid, so second time someone buys it, can just send it
}

6
api/models/ts/message.ts

@ -11,6 +11,9 @@ export default class Message extends Model<Message> {
})
id: number
@Column
uuid: string
@Column(DataType.BIGINT)
chatId: number
@ -83,4 +86,7 @@ export default class Message extends Model<Message> {
@Column
senderAlias: string // for tribes, no "sender" id maybe
@Column
originalMuid: string // for tribe, remember the og muid
}

273
api/network/modify.ts

@ -5,101 +5,124 @@ import * as rsa from '../crypto/rsa'
import * as crypto from 'crypto'
import * as meme from '../utils/meme'
import * as FormData from 'form-data'
// import { models } from '../models'
import { models } from '../models'
import * as RNCryptor from 'jscryptor'
import {sendMessage} from './send'
import { Op } from 'sequelize'
const constants = require(path.join(__dirname,'../../config/constants.json'))
const msgtypes = constants.message_types
export async function modifyPayloadAndSaveMediaKey(payload, chat, sender) {
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 imgBuf = RNCryptor.Decrypt(buf.toString('base64'), decMediaKey)
const newKey = crypto.randomBytes(20).toString('hex')
const encImgBase64 = RNCryptor.Encrypt(imgBuf, newKey)
var encImgBuffer = Buffer.from(encImgBase64,'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, host:'',
meta:{...amt && {amt}},
skipSigning: amt ? true : false // only sign if its free
}
const encKey = rsa.encrypt(chat.groupKey, newKey.slice())
var date = new Date();
date.setMilliseconds(0)
console.log('[modify] save media key!',{
muid:json.muid,
chatId:chat.id,
key: encKey,
messageId: (payload.message&&payload.message.id)||0,
receiver: 0,
sender: sender.id, // the og sender
createdAt: date,
})
// await sleep(1)
// await models.MediaKey.create({
// muid:json.muid,
// chatId:chat.id,
// key:encKey,
// messageId: (payload.message&&payload.message.id)||0,
// receiver: 0,
// sender: sender.id, // the og sender
// createdAt: date,
// })
return fillmsg(payload, {mediaTerms,mediaKey:encKey}) // key is re-encrypted later
} catch(e) {
console.log("[modify] error", e)
return payload
if(payload.type!==msgtypes.attachment) return payload
try{
const ret = await downloadAndUploadAndSaveReturningTermsAndKey(payload,chat,sender)
return fillmsg(payload, ret) // key is re-encrypted later
} catch(e) {
console.log("[modify] error", e)
return payload
}
}
// "purchase" type
export async function purchaseFromOriginalSender(payload, chat, purchaser){
if(payload.type!==msgtypes.purchase) return
const mt = payload.message && payload.message.mediaToken
const amount = payload.message.amount
const muid = mt && mt.split('.').length && mt.split('.')[1]
if(!muid) return
const mediaKey = await models.MediaKey.findOne({where:{originalMuid:muid}})
const terms = parseLDAT(mt)
let price = terms.meta && terms.meta.amt
if(amount<price) return // not enough sats
const owner = await models.Contact.findOne({where: {isOwner:true}})
if(mediaKey) { // ALREADY BEEN PURHCASED! simply send
// send back the new mediaToken and key
const mediaTerms: {[k:string]:any} = {
muid:mediaKey.muid, ttl:31536000, host:'',
meta:{...amount && {amt:amount}},
}
// how to link w og msg? ogMediaToken?
// send full new key and token
const msg = {
mediaTerms,
mediaKey:mediaKey.key,
originalMuid:mediaKey.originalMuid,
mediaType:mediaKey.mediaType
}
sendMessage({
chat: {...chat.dataValues, contactIds:[purchaser.id]},
sender: owner,
type: constants.message_types.purchase_accept,
message: msg,
success: ()=>{},
failure: ()=>{}
})
} else {
return payload
const ogmsg = await models.Message.findOne({where:{chatId:chat.id,mediaToken:mt}})
// purchase it from creator (send "purchase")
const msg={amount, mediaToken:mt}
sendMessage({
chat: {...chat.dataValues, contactIds:[ogmsg.sender]},
sender: {
...owner.dataValues,
...purchaser&&purchaser.alias && {alias:purchaser.alias}
},
type: constants.message_types.purchase,
message: msg,
amount: amount,
success: ()=>{},
failure: ()=>{}
})
}
}
export async function sendFinalMemeIfFirstPurchaser(payload, chat, sender){
if(payload.type!==msgtypes.purchase_accept) return
const mt = payload.message && payload.message.mediaToken
const typ = payload.message && payload.message.mediaType
if(!mt) return
const muid = mt && mt.split('.').length && mt.split('.')[1]
if(!muid) return
const existingMediaKey = await models.MediaKey.findOne({where:{muid}})
if(existingMediaKey) return // no need, its already been sent
const host = mt.split('.')[0]
const ogPurchaseMessage = await models.Message.findOne({where:{
mediaToken: {[Op.like]: `${host}.${muid}%`},
type: msgtypes.purchase,
}})
const termsAndKey = await downloadAndUploadAndSaveReturningTermsAndKey(payload,chat,sender,ogPurchaseMessage.amount)
// send it to the purchaser
const owner = await models.Contact.findOne({where: {isOwner:true}})
sendMessage({
sender: {
...owner.dataValues,
...sender&&sender.alias && {alias:sender.alias}
},
chat:{
...chat.dataValues,
contactIds:[ogPurchaseMessage.sender],
},
type:msgtypes.purchase_accept,
message:{
...termsAndKey,
mediaType: typ,
originalMuid:muid,
},
success: ()=>{},
receive: ()=>{}
})
}
function fillmsg(full, props){
return {
...full, message: {
@ -109,6 +132,82 @@ function fillmsg(full, props){
}
}
// async function sleep(ms) {
// return new Promise(resolve => setTimeout(resolve, ms))
// }
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
export async function downloadAndUploadAndSaveReturningTermsAndKey(payload, chat, sender, injectedAmount?:number){
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 // save anyway??????????
const ogmuid = mt && mt.split('.').length && mt.split('.')[1]
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 imgBuf = RNCryptor.Decrypt(buf.toString('base64'), decMediaKey)
const newKey = crypto.randomBytes(20).toString('hex')
const encImgBase64 = RNCryptor.Encrypt(imgBuf, newKey)
var encImgBuffer = Buffer.from(encImgBase64,'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) throw new Error('no muid')
// PUT NEW TERMS, to finish in personalizeMessage
const amt = (terms.meta&&terms.meta.amt)||injectedAmount
const ttl = terms.meta&&terms.meta.ttl
const mediaTerms: {[k:string]:any} = {
muid:json.muid, ttl:ttl||31536000, host:'',
meta:{...amt && {amt}},
}
const encKey = rsa.encrypt(chat.groupKey, newKey.slice())
var date = new Date()
date.setMilliseconds(0)
await sleep(1)
await models.MediaKey.create({
muid:json.muid,
chatId:chat.id,
key:encKey,
messageId: (payload.message&&payload.message.id)||0,
receiver: 0,
sender: sender.id, // the og sender
createdAt: date,
originalMuid: ogmuid,
mediaType:typ,
})
return {mediaTerms,mediaKey:encKey}
} catch(e) {
throw e
}
}

72
api/network/receive.ts

@ -6,8 +6,10 @@ import * as tribes from '../utils/tribes'
import {SPHINX_CUSTOM_RECORD_KEY, verifyAscii} from '../utils/lightning'
import { models } from '../models'
import {sendMessage} from './send'
import {modifyPayloadAndSaveMediaKey} from './modify'
import {modifyPayloadAndSaveMediaKey,purchaseFromOriginalSender,sendFinalMemeIfFirstPurchaser} from './modify'
// import {modifyPayloadAndSaveMediaKey} from './modify'
import {decryptMessage,encryptTribeBroadcast} from '../utils/msg'
import { Op } from 'sequelize'
const constants = require(path.join(__dirname,'../../config/constants.json'))
const msgtypes = constants.message_types
@ -29,29 +31,57 @@ async function onReceive(payload){
let doAction = true
const toAddIn:{[k:string]:any} = {}
const isTribe = payload.chat && payload.chat.type===constants.chat_types.tribe
if(isTribe && typesToForward.includes(payload.type)){
const needsPricePerJoin = typesThatNeedPricePerMessage.includes(payload.type)
const chat = await models.Chat.findOne({where:{uuid:payload.chat.uuid}})
let isTribeOwner = false
const chat = await models.Chat.findOne({where:{uuid:payload.chat.uuid}})
if(isTribe) {
const tribeOwnerPubKey = chat && chat.ownerPubkey
const owner = await models.Contact.findOne({where: {isOwner:true}})
if(owner.publicKey===tribeOwnerPubKey){
toAddIn.isTribeOwner = true
// CHECK THEY ARE IN THE GROUP if message
isTribeOwner = owner.publicKey===tribeOwnerPubKey
}
if(isTribeOwner) toAddIn.isTribeOwner = true
if(isTribeOwner && typesToForward.includes(payload.type)){
const needsPricePerJoin = typesThatNeedPricePerMessage.includes(payload.type)
// CHECK THEY ARE IN THE GROUP if message
const senderContact = await models.Contact.findOne({where:{publicKey:payload.sender.pub_key}})
if(needsPricePerJoin) {
const senderMember = senderContact && await models.ChatMember.findOne({where:{contactId:senderContact.id, chatId:chat.id}})
if(!senderMember) doAction=false
}
// CHECK PRICES
if(needsPricePerJoin) {
if(payload.message.amount<chat.pricePerMessage) doAction=false
}
// check price to join
if(payload.type===msgtypes.group_join) {
if(payload.message.amount<chat.priceToJoin) doAction=false
}
if(doAction) forwardMessageToTribe(payload, senderContact)
else console.log('=> insufficient payment for this action')
}
if(isTribeOwner && payload.type===msgtypes.purchase) {
const mt = payload.message.mediaToken
const myMediaMessage = await models.Message.findOne({ where:{
mediaToken: mt, sender: 1, type:msgtypes.attachment
} })
if(!myMediaMessage) { // someone else's attachment
const senderContact = await models.Contact.findOne({where:{publicKey:payload.sender.pub_key}})
if(needsPricePerJoin) {
const senderMember = senderContact && await models.ChatMember.findOne({where:{contactId:senderContact.id, chatId:chat.id}})
if(!senderMember) doAction=false
}
// CHECK PRICES
if(needsPricePerJoin) {
if(payload.message.amount<chat.pricePerMessage) doAction=false
}
// check price to join
if(payload.type===msgtypes.group_join) {
if(payload.message.amount<chat.priceToJoin) doAction=false
}
if(doAction) forwardMessageToTribe(payload, senderContact)
else console.log('=> insufficient payment for this action')
purchaseFromOriginalSender(payload, chat, senderContact)
// we do pass thru, to store... so that we know who the og purchaser was
}
}
if(isTribeOwner && payload.type===msgtypes.purchase_accept) {
const mt = payload.message.mediaToken
const host = mt && mt.split('.').length && mt.split('.')[0]
const muid = mt && mt.split('.').length && mt.split('.')[1]
const ogPurchaseMessage = await models.Message.findOne({where:{
mediaToken: {[Op.like]: `${host}.${muid}%`},
type: msgtypes.purchase,
sender: 1,
}})
if(!ogPurchaseMessage) { // for someone else
const senderContact = await models.Contact.findOne({where:{publicKey:payload.sender.pub_key}})
sendFinalMemeIfFirstPurchaser(payload, chat, senderContact)
doAction = false // skip this! we dont need it
}
}
if(doAction) doTheAction({...payload, ...toAddIn})

7
api/utils/setup.ts

@ -31,6 +31,13 @@ async function setVersion(){
}
async function migrate(){
addTableColumn('sphinx_media_keys', 'media_type')
addTableColumn('sphinx_media_keys', 'original_muid')
addTableColumn('sphinx_messages', 'original_muid')
addTableColumn('sphinx_messages', 'uuid')
addTableColumn('sphinx_messages', 'reply_uuid')
addTableColumn('sphinx_media_keys', 'sender', 'BIGINT')
addTableColumn('sphinx_chats', 'group_key')

2
dist/api/controllers/chats.js.map

File diff suppressed because one or more lines are too long

5
dist/api/controllers/invoices.js

@ -20,6 +20,7 @@ const res_1 = require("../utils/res");
const confirmations_1 = require("./confirmations");
const path = require("path");
const network = require("../network");
const short = require("short-uuid");
const constants = require(path.join(__dirname, '../../config/constants.json'));
function stripLightningPrefix(s) {
if (s.toLowerCase().startsWith('lightning:'))
@ -124,6 +125,7 @@ const createInvoice = (req, res) => __awaiter(void 0, void 0, void 0, function*
else {
const message = yield models_1.models.Message.create({
chatId: chat.id,
uuid: short.generate(),
sender: owner.id,
type: constants.message_types.invoice,
amount: parseInt(invoice.num_satoshis),
@ -187,13 +189,14 @@ const receiveInvoice = (payload) => __awaiter(void 0, void 0, void 0, function*
const payment_request = dat.message.invoice;
var date = new Date();
date.setMilliseconds(0);
const { owner, sender, chat, msg_id, chat_type, sender_alias } = yield helpers.parseReceiveParams(payload);
const { owner, sender, chat, msg_id, chat_type, sender_alias, msg_uuid } = yield helpers.parseReceiveParams(payload);
if (!owner || !sender || !chat) {
return console.log('=> no group chat!');
}
const { memo, sat, msat, paymentHash, invoiceDate, expirationSeconds } = decodePaymentRequest(payment_request);
const msg = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.invoice,
sender: sender.id,
amount: sat,

2
dist/api/controllers/invoices.js.map

File diff suppressed because one or more lines are too long

32
dist/api/controllers/media.js

@ -26,6 +26,7 @@ const confirmations_1 = require("./confirmations");
const path = require("path");
const network = require("../network");
const meme = require("../utils/meme");
const short = require("short-uuid");
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '../../config/app.json'))[env];
const constants = require(path.join(__dirname, '../../config/constants.json'));
@ -78,8 +79,10 @@ const sendAttachmentMessage = (req, res) => __awaiter(void 0, void 0, void 0, fu
const myMediaKey = (media_key_map && media_key_map[owner.id]) || '';
const mediaType = media_type || '';
const remoteMessageContent = remote_text_map ? JSON.stringify(remote_text_map) : remote_text;
const uuid = short.generate();
const message = yield models_1.models.Message.create({
chatId: chat.id,
uuid: uuid,
sender: owner.id,
type: constants.message_types.attachment,
status: constants.statuses.pending,
@ -92,7 +95,7 @@ const sendAttachmentMessage = (req, res) => __awaiter(void 0, void 0, void 0, fu
createdAt: date,
updatedAt: date
});
saveMediaKeys(muid, media_key_map, chat.id, message.id);
saveMediaKeys(muid, media_key_map, chat.id, message.id, mediaType);
const mediaTerms = {
muid, ttl: TTL,
meta: Object.assign({}, amt && { amt }),
@ -101,6 +104,7 @@ const sendAttachmentMessage = (req, res) => __awaiter(void 0, void 0, void 0, fu
const msg = {
mediaTerms,
id: message.id,
uuid: uuid,
content: remote_text_map || remote_text || text || file_name || '',
mediaKey: media_key_map,
mediaType: mediaType,
@ -118,7 +122,7 @@ const sendAttachmentMessage = (req, res) => __awaiter(void 0, void 0, void 0, fu
});
});
exports.sendAttachmentMessage = sendAttachmentMessage;
function saveMediaKeys(muid, mediaKeyMap, chatId, messageId) {
function saveMediaKeys(muid, mediaKeyMap, chatId, messageId, mediaType) {
if (typeof mediaKeyMap !== 'object') {
console.log('wrong type for mediaKeyMap');
return;
@ -132,6 +136,7 @@ function saveMediaKeys(muid, mediaKeyMap, chatId, messageId) {
muid, chatId, key, messageId,
receiver: receiverID,
createdAt: date,
mediaType
});
}
}
@ -155,15 +160,17 @@ const purchase = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
});
const message = yield models_1.models.Message.create({
chatId: chat.id,
uuid: short.generate(),
sender: owner.id,
type: constants.message_types.purchase,
amount: amount || 0,
mediaToken: media_token,
date: date,
createdAt: date,
updatedAt: date
});
const msg = {
amount, mediaToken: media_token, id: message.id,
amount, mediaToken: media_token, id: message.id, uuid: message.uuid,
};
network.sendMessage({
chat: Object.assign(Object.assign({}, chat.dataValues), { contactIds: [contact_id] }),
@ -184,14 +191,16 @@ const receivePurchase = (payload) => __awaiter(void 0, void 0, void 0, function*
console.log('=> received purchase', { payload });
var date = new Date();
date.setMilliseconds(0);
const { owner, sender, chat, amount, mediaToken } = yield helpers.parseReceiveParams(payload);
const { owner, sender, chat, amount, mediaToken, msg_uuid, chat_type } = yield helpers.parseReceiveParams(payload);
if (!owner || !sender || !chat) {
return console.log('=> group chat not found!');
}
const message = yield models_1.models.Message.create({
chatId: chat.id,
uuid: msg_uuid,
sender: sender.id,
type: constants.message_types.purchase,
amount: amount || 0,
mediaToken: mediaToken,
date: date,
createdAt: date,
@ -211,11 +220,14 @@ const receivePurchase = (payload) => __awaiter(void 0, void 0, void 0, function*
if (!ogMessage) {
return console.log('no original message');
}
const isTribe = chat_type === constants.chat_types.tribe;
// find mediaKey for who sent
const mediaKey = yield models_1.models.MediaKey.findOne({ where: {
muid, receiver: sender.id,
muid, receiver: isTribe ? 0 : sender.id,
} });
console.log('mediaKey found!', mediaKey);
// console.log('mediaKey found!',mediaKey.dataValues)
if (!mediaKey)
return; // this is from another person (admin is forwarding)
const terms = ldat_1.parseLDAT(mediaToken);
// get info
let TTL = terms.meta && terms.meta.ttl;
@ -292,7 +304,7 @@ const receivePurchaseAccept = (payload) => __awaiter(void 0, void 0, void 0, fun
console.log('=> receivePurchaseAccept');
var date = new Date();
date.setMilliseconds(0);
const { owner, sender, chat, mediaToken, mediaKey, mediaType } = yield helpers.parseReceiveParams(payload);
const { owner, sender, chat, mediaToken, mediaKey, mediaType, originalMuid } = yield helpers.parseReceiveParams(payload);
if (!owner || !sender || !chat) {
return console.log('=> no group chat!');
}
@ -319,6 +331,7 @@ const receivePurchaseAccept = (payload) => __awaiter(void 0, void 0, void 0, fun
mediaToken,
mediaKey,
mediaType,
originalMuid: originalMuid || '',
date: date,
createdAt: date,
updatedAt: date
@ -357,15 +370,16 @@ const receivePurchaseDeny = (payload) => __awaiter(void 0, void 0, void 0, funct
});
exports.receivePurchaseDeny = receivePurchaseDeny;
const receiveAttachment = (payload) => __awaiter(void 0, void 0, void 0, function* () {
console.log('received attachment', { payload });
// console.log('received attachment', { payload })
var date = new Date();
date.setMilliseconds(0);
const { owner, sender, chat, mediaToken, mediaKey, mediaType, content, msg_id, chat_type, sender_alias } = yield helpers.parseReceiveParams(payload);
const { owner, sender, chat, mediaToken, mediaKey, mediaType, content, msg_id, chat_type, sender_alias, msg_uuid } = yield helpers.parseReceiveParams(payload);
if (!owner || !sender || !chat) {
return console.log('=> no group chat!');
}
const msg = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.attachment,
sender: sender.id,
date: date,

2
dist/api/controllers/media.js.map

File diff suppressed because one or more lines are too long

10
dist/api/controllers/messages.js

@ -20,6 +20,7 @@ const res_1 = require("../utils/res");
const confirmations_1 = require("./confirmations");
const path = require("path");
const network = require("../network");
const short = require("short-uuid");
const constants = require(path.join(__dirname, '../../config/constants.json'));
const getMessages = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
const dateToReturn = req.query.date;
@ -109,6 +110,7 @@ const sendMessage = (req, res) => __awaiter(void 0, void 0, void 0, function* ()
const remoteMessageContent = remote_text_map ? JSON.stringify(remote_text_map) : remote_text;
const msg = {
chatId: chat.id,
uuid: short.generate(),
type: constants.message_types.message,
sender: owner.id,
amount: amount || 0,
@ -129,23 +131,25 @@ const sendMessage = (req, res) => __awaiter(void 0, void 0, void 0, function* ()
type: constants.message_types.message,
message: {
id: message.id,
uuid: message.uuid,
content: remote_text_map || remote_text || text
}
});
});
exports.sendMessage = sendMessage;
const receiveMessage = (payload) => __awaiter(void 0, void 0, void 0, function* () {
console.log('received message', { payload });
// console.log('received message', { payload })
var date = new Date();
date.setMilliseconds(0);
const total_spent = 1;
const { owner, sender, chat, content, remote_content, msg_id, chat_type, sender_alias } = yield helpers.parseReceiveParams(payload);
const { owner, sender, chat, content, remote_content, msg_id, chat_type, sender_alias, msg_uuid } = yield helpers.parseReceiveParams(payload);
if (!owner || !sender || !chat) {
return console.log('=> no group chat!');
}
const text = content;
const msg = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.message,
asciiEncodedTotal: total_spent,
sender: sender.id,
@ -161,7 +165,7 @@ const receiveMessage = (payload) => __awaiter(void 0, void 0, void 0, function*
msg.remoteMessageContent = remote_content;
}
const message = yield models_1.models.Message.create(msg);
console.log('saved message', message.dataValues);
// console.log('saved message', message.dataValues)
socket.sendJson({
type: 'message',
response: jsonUtils.messageToJson(message, chat, sender)

2
dist/api/controllers/messages.js.map

File diff suppressed because one or more lines are too long

8
dist/api/controllers/payment.js

@ -19,6 +19,7 @@ const lightning = require("../utils/lightning");
const ldat_1 = require("../utils/ldat");
const constants = require("../../config/constants.json");
const network = require("../network");
const short = require("short-uuid");
const sendPayment = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
const { amount, chat_id, contact_id, destination_key, media_type, muid, text, remote_text, dimensions, remote_text_map, contact_ids, } = req.body;
console.log('[send payment]', req.body);
@ -49,6 +50,7 @@ const sendPayment = (req, res) => __awaiter(void 0, void 0, void 0, function* ()
date.setMilliseconds(0);
const msg = {
chatId: chat.id,
uuid: short.generate(),
sender: owner.id,
type: constants.message_types.direct_payment,
amount: amount,
@ -73,6 +75,7 @@ const sendPayment = (req, res) => __awaiter(void 0, void 0, void 0, function* ()
const message = yield models_1.models.Message.create(msg);
const msgToSend = {
id: message.id,
uuid: message.uuid,
amount,
};
if (muid) {
@ -115,12 +118,13 @@ const receivePayment = (payload) => __awaiter(void 0, void 0, void 0, function*
console.log('received payment', { payload });
var date = new Date();
date.setMilliseconds(0);
const { owner, sender, chat, amount, content, mediaType, mediaToken, chat_type, sender_alias } = yield helpers.parseReceiveParams(payload);
const { owner, sender, chat, amount, content, mediaType, mediaToken, chat_type, sender_alias, msg_uuid } = yield helpers.parseReceiveParams(payload);
if (!owner || !sender || !chat) {
return console.log('=> no group chat!');
}
const msg = {
chatId: chat.id,
uuid: msg_uuid,
type: constants.message_types.direct_payment,
sender: sender.id,
amount: amount,
@ -139,7 +143,7 @@ const receivePayment = (payload) => __awaiter(void 0, void 0, void 0, function*
msg.senderAlias = sender_alias;
}
const message = yield models_1.models.Message.create(msg);
console.log('saved message', message.dataValues);
// console.log('saved message', message.dataValues)
socket.sendJson({
type: 'direct_payment',
response: jsonUtils.messageToJson(message, chat, sender)

2
dist/api/controllers/payment.js.map

File diff suppressed because one or more lines are too long

4
dist/api/helpers.js

@ -161,7 +161,9 @@ function parseReceiveParams(payload) {
const content = dat.message.content;
const remote_content = dat.message.remoteContent;
const mediaToken = dat.message.mediaToken;
const originalMuid = dat.message.originalMuid;
const msg_id = dat.message.id || 0;
const msg_uuid = dat.message.uuid || '';
const mediaKey = dat.message.mediaKey;
const mediaType = dat.message.mediaType;
const isTribeOwner = dat.isTribeOwner ? true : false;
@ -184,7 +186,7 @@ function parseReceiveParams(payload) {
}
chat = yield models_1.models.Chat.findOne({ where: { uuid: chat_uuid } });
}
return { owner, sender, chat, sender_pub_key, sender_alias, isTribeOwner, chat_uuid, amount, content, mediaToken, mediaKey, mediaType, chat_type, msg_id, chat_members, chat_name, chat_host, chat_key, remote_content };
return { owner, sender, chat, sender_pub_key, sender_alias, isTribeOwner, chat_uuid, amount, content, mediaToken, mediaKey, mediaType, originalMuid, chat_type, msg_id, chat_members, chat_name, chat_host, chat_key, remote_content, msg_uuid };
});
}
exports.parseReceiveParams = parseReceiveParams;

2
dist/api/helpers.js.map

File diff suppressed because one or more lines are too long

4
dist/api/hub.js

@ -228,7 +228,9 @@ const sendNotification = (chat, name, type) => __awaiter(void 0, void 0, void 0,
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(json => console.log('[hub notification]', json));
.then(json => {
// console.log('[hub notification]', json)
});
});
exports.sendNotification = sendNotification;
//# sourceMappingURL=hub.js.map

2
dist/api/hub.js.map

File diff suppressed because one or more lines are too long

8
dist/api/models/ts/mediaKey.js

@ -52,10 +52,18 @@ __decorate([
sequelize_typescript_1.Column,
__metadata("design:type", Date)
], MediaKey.prototype, "createdAt", void 0);
__decorate([
sequelize_typescript_1.Column,
__metadata("design:type", String)
], MediaKey.prototype, "mediaType", void 0);
__decorate([
sequelize_typescript_1.Column(sequelize_typescript_1.DataType.BIGINT),
__metadata("design:type", Number)
], MediaKey.prototype, "sender", void 0);
__decorate([
sequelize_typescript_1.Column,
__metadata("design:type", String)
], MediaKey.prototype, "originalMuid", void 0);
MediaKey = __decorate([
sequelize_typescript_1.Table({ tableName: 'sphinx_media_keys', underscored: true })
], MediaKey);

2
dist/api/models/ts/mediaKey.js.map

@ -1 +1 @@
{"version":3,"file":"mediaKey.js","sourceRoot":"","sources":["../../../../api/models/ts/mediaKey.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAAsE;AAEtE;;;;;;EAME;AAGF,IAAqB,QAAQ,GAA7B,MAAqB,QAAS,SAAQ,4BAAe;CA+BpD,CAAA;AAvBC;IANC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC;;oCACQ;AAGV;IADC,6BAAM;;sCACK;AAGZ;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;wCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;0CACR;AAGhB;IADC,6BAAM;;qCACI;AAGX;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;2CACP;AAGjB;IADC,6BAAM;8BACI,IAAI;2CAAA;AAGf;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;wCACV;AA7BK,QAAQ;IAD5B,4BAAK,CAAC,EAAC,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,IAAI,EAAC,CAAC;GACtC,QAAQ,CA+B5B;kBA/BoB,QAAQ"}
{"version":3,"file":"mediaKey.js","sourceRoot":"","sources":["../../../../api/models/ts/mediaKey.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAAsE;AAEtE;;;;;;EAME;AAGF,IAAqB,QAAQ,GAA7B,MAAqB,QAAS,SAAQ,4BAAe;CAqCpD,CAAA;AA7BC;IANC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC;;oCACQ;AAGV;IADC,6BAAM;;sCACK;AAGZ;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;wCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;0CACR;AAGhB;IADC,6BAAM;;qCACI;AAGX;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;2CACP;AAGjB;IADC,6BAAM;8BACI,IAAI;2CAAA;AAGf;IADC,6BAAM;;2CACU;AAGjB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;wCACV;AAGd;IADC,6BAAM;;8CACa;AAnCD,QAAQ;IAD5B,4BAAK,CAAC,EAAC,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,IAAI,EAAC,CAAC;GACtC,QAAQ,CAqC5B;kBArCoB,QAAQ"}

8
dist/api/models/ts/message.js

@ -21,6 +21,10 @@ __decorate([
}),
__metadata("design:type", Number)
], Message.prototype, "id", void 0);
__decorate([
sequelize_typescript_1.Column,
__metadata("design:type", String)
], Message.prototype, "uuid", void 0);
__decorate([
sequelize_typescript_1.Column(sequelize_typescript_1.DataType.BIGINT),
__metadata("design:type", Number)
@ -117,6 +121,10 @@ __decorate([
sequelize_typescript_1.Column,
__metadata("design:type", String)
], Message.prototype, "senderAlias", void 0);
__decorate([
sequelize_typescript_1.Column,
__metadata("design:type", String)
], Message.prototype, "originalMuid", void 0);
Message = __decorate([
sequelize_typescript_1.Table({ tableName: 'sphinx_messages', underscored: true })
], Message);

2
dist/api/models/ts/message.js.map

@ -1 +1 @@
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../../api/models/ts/message.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAAsE;AAGtE,IAAqB,OAAO,GAA5B,MAAqB,OAAQ,SAAQ,4BAAc;CAkFlD,CAAA;AA1EC;IANC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC;;mCACQ;AAGV;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;uCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;qCACZ;AAGZ;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;uCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;yCACR;AAGhB;IADC,6BAAM,CAAC,+BAAQ,CAAC,OAAO,CAAC;;uCACX;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,OAAO,CAAC;;2CACP;AAGlB;IADC,6BAAM;;4CACY;AAGnB;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;+CACA;AAGtB;IADC,6BAAM;8BACD,IAAI;qCAAA;AAGV;IADC,6BAAM;8BACS,IAAI;+CAAA;AAGpB;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;+CACA;AAGtB;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;qDACM;AAG5B;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;uCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;0CACL;AAGjB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;yCACR;AAGhB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;+CACF;AAGtB;IADC,6BAAM;;yCACS;AAGhB;IADC,6BAAM;;0CACU;AAGjB;IADC,6BAAM;;2CACW;AAOlB;IALC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,KAAK;KACjB,CAAC;;qCACW;AAGb;IADC,6BAAM;8BACI,IAAI;0CAAA;AAGf;IADC,6BAAM;8BACI,IAAI;0CAAA;AAGf;IADC,6BAAM;;4CACY;AAjFA,OAAO;IAD3B,4BAAK,CAAC,EAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,IAAI,EAAC,CAAC;GACpC,OAAO,CAkF3B;kBAlFoB,OAAO"}
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../../api/models/ts/message.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAAsE;AAGtE,IAAqB,OAAO,GAA5B,MAAqB,OAAQ,SAAQ,4BAAc;CAwFlD,CAAA;AAhFC;IANC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC;;mCACQ;AAGV;IADC,6BAAM;;qCACK;AAGZ;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;uCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;qCACZ;AAGZ;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;uCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;yCACR;AAGhB;IADC,6BAAM,CAAC,+BAAQ,CAAC,OAAO,CAAC;;uCACX;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,OAAO,CAAC;;2CACP;AAGlB;IADC,6BAAM;;4CACY;AAGnB;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;+CACA;AAGtB;IADC,6BAAM;8BACD,IAAI;qCAAA;AAGV;IADC,6BAAM;8BACS,IAAI;+CAAA;AAGpB;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;+CACA;AAGtB;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;qDACM;AAG5B;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;uCACV;AAGd;IADC,6BAAM,CAAC,+BAAQ,CAAC,IAAI,CAAC;;0CACL;AAGjB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;yCACR;AAGhB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;+CACF;AAGtB;IADC,6BAAM;;yCACS;AAGhB;IADC,6BAAM;;0CACU;AAGjB;IADC,6BAAM;;2CACW;AAOlB;IALC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,KAAK;KACjB,CAAC;;qCACW;AAGb;IADC,6BAAM;8BACI,IAAI;0CAAA;AAGf;IADC,6BAAM;8BACI,IAAI;0CAAA;AAGf;IADC,6BAAM;;4CACY;AAGnB;IADC,6BAAM;;6CACa;AAvFD,OAAO;IAD3B,4BAAK,CAAC,EAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,IAAI,EAAC,CAAC;GACpC,OAAO,CAwF3B;kBAxFoB,OAAO"}

245
dist/api/network/modify.js

@ -16,94 +16,187 @@ const rsa = require("../crypto/rsa");
const crypto = require("crypto");
const meme = require("../utils/meme");
const FormData = require("form-data");
// import { models } from '../models'
const models_1 = require("../models");
const RNCryptor = require("jscryptor");
const send_1 = require("./send");
const sequelize_1 = require("sequelize");
const constants = require(path.join(__dirname, '../../config/constants.json'));
const msgtypes = constants.message_types;
function modifyPayloadAndSaveMediaKey(payload, chat, sender) {
return __awaiter(this, void 0, void 0, function* () {
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 = ldat_1.parseLDAT(mt);
if (!terms.host)
return payload;
try {
const r = yield fetch(`https://${terms.host}/file/${mt}`, {
headers: { 'Authorization': `Bearer ${meme.mediaToken}` }
});
const buf = yield r.buffer();
const decMediaKey = rsa.decrypt(chat.groupPrivateKey, key);
const imgBuf = RNCryptor.Decrypt(buf.toString('base64'), decMediaKey);
const newKey = crypto.randomBytes(20).toString('hex');
const encImgBase64 = RNCryptor.Encrypt(imgBuf, newKey);
var encImgBuffer = Buffer.from(encImgBase64, '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 = yield fetch(`https://${terms.host}/file`, {
method: 'POST',
headers: Object.assign(Object.assign({}, formHeaders), { 'Authorization': `Bearer ${meme.mediaToken}` }),
body: form
});
let json = yield 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 = {
muid: json.muid, ttl: ttl || 31536000, host: '',
meta: Object.assign({}, amt && { amt }),
skipSigning: amt ? true : false // only sign if its free
};
const encKey = rsa.encrypt(chat.groupKey, newKey.slice());
var date = new Date();
date.setMilliseconds(0);
console.log('[modify] save media key!', {
muid: json.muid,
chatId: chat.id,
key: encKey,
messageId: (payload.message && payload.message.id) || 0,
receiver: 0,
sender: sender.id,
createdAt: date,
});
// await sleep(1)
// await models.MediaKey.create({
// muid:json.muid,
// chatId:chat.id,
// key:encKey,
// messageId: (payload.message&&payload.message.id)||0,
// receiver: 0,
// sender: sender.id, // the og sender
// createdAt: date,
// })
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?
if (payload.type !== msgtypes.attachment)
return payload;
try {
const ret = yield downloadAndUploadAndSaveReturningTermsAndKey(payload, chat, sender);
return fillmsg(payload, ret); // key is re-encrypted later
}
else {
catch (e) {
console.log("[modify] error", e);
return payload;
}
});
}
exports.modifyPayloadAndSaveMediaKey = modifyPayloadAndSaveMediaKey;
// "purchase" type
function purchaseFromOriginalSender(payload, chat, purchaser) {
return __awaiter(this, void 0, void 0, function* () {
if (payload.type !== msgtypes.purchase)
return;
const mt = payload.message && payload.message.mediaToken;
const amount = payload.message.amount;
const muid = mt && mt.split('.').length && mt.split('.')[1];
if (!muid)
return;
const mediaKey = yield models_1.models.MediaKey.findOne({ where: { originalMuid: muid } });
const terms = ldat_1.parseLDAT(mt);
let price = terms.meta && terms.meta.amt;
if (amount < price)
return; // not enough sats
const owner = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
if (mediaKey) { // ALREADY BEEN PURHCASED! simply send
// send back the new mediaToken and key
const mediaTerms = {
muid: mediaKey.muid, ttl: 31536000, host: '',
meta: Object.assign({}, amount && { amt: amount }),
};
// send full new key and token
const msg = {
mediaTerms,
mediaKey: mediaKey.key,
originalMuid: mediaKey.originalMuid,
mediaType: mediaKey.mediaType
};
send_1.sendMessage({
chat: Object.assign(Object.assign({}, chat.dataValues), { contactIds: [purchaser.id] }),
sender: owner,
type: constants.message_types.purchase_accept,
message: msg,
success: () => { },
failure: () => { }
});
}
else {
const ogmsg = yield models_1.models.Message.findOne({ where: { chatId: chat.id, mediaToken: mt } });
// purchase it from creator (send "purchase")
const msg = { amount, mediaToken: mt };
send_1.sendMessage({
chat: Object.assign(Object.assign({}, chat.dataValues), { contactIds: [ogmsg.sender] }),
sender: Object.assign(Object.assign({}, owner.dataValues), purchaser && purchaser.alias && { alias: purchaser.alias }),
type: constants.message_types.purchase,
message: msg,
amount: amount,
success: () => { },
failure: () => { }
});
}
});
}
exports.purchaseFromOriginalSender = purchaseFromOriginalSender;
function sendFinalMemeIfFirstPurchaser(payload, chat, sender) {
return __awaiter(this, void 0, void 0, function* () {
if (payload.type !== msgtypes.purchase_accept)
return;
const mt = payload.message && payload.message.mediaToken;
const typ = payload.message && payload.message.mediaType;
if (!mt)
return;
const muid = mt && mt.split('.').length && mt.split('.')[1];
if (!muid)
return;
const existingMediaKey = yield models_1.models.MediaKey.findOne({ where: { muid } });
if (existingMediaKey)
return; // no need, its already been sent
const host = mt.split('.')[0];
const ogPurchaseMessage = yield models_1.models.Message.findOne({ where: {
mediaToken: { [sequelize_1.Op.like]: `${host}.${muid}%` },
type: msgtypes.purchase,
} });
const termsAndKey = yield downloadAndUploadAndSaveReturningTermsAndKey(payload, chat, sender, ogPurchaseMessage.amount);
// send it to the purchaser
const owner = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
send_1.sendMessage({
sender: Object.assign(Object.assign({}, owner.dataValues), sender && sender.alias && { alias: sender.alias }),
chat: Object.assign(Object.assign({}, chat.dataValues), { contactIds: [ogPurchaseMessage.sender] }),
type: msgtypes.purchase_accept,
message: Object.assign(Object.assign({}, termsAndKey), { mediaType: typ, originalMuid: muid }),
success: () => { },
receive: () => { }
});
});
}
exports.sendFinalMemeIfFirstPurchaser = sendFinalMemeIfFirstPurchaser;
function fillmsg(full, props) {
return Object.assign(Object.assign({}, full), { message: Object.assign(Object.assign({}, full.message), props) });
}
// async function sleep(ms) {
// return new Promise(resolve => setTimeout(resolve, ms))
// }
function sleep(ms) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise(resolve => setTimeout(resolve, ms));
});
}
function downloadAndUploadAndSaveReturningTermsAndKey(payload, chat, sender, injectedAmount) {
return __awaiter(this, void 0, void 0, function* () {
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; // save anyway??????????
const ogmuid = mt && mt.split('.').length && mt.split('.')[1];
const terms = ldat_1.parseLDAT(mt);
if (!terms.host)
return payload;
try {
const r = yield fetch(`https://${terms.host}/file/${mt}`, {
headers: { 'Authorization': `Bearer ${meme.mediaToken}` }
});
const buf = yield r.buffer();
const decMediaKey = rsa.decrypt(chat.groupPrivateKey, key);
const imgBuf = RNCryptor.Decrypt(buf.toString('base64'), decMediaKey);
const newKey = crypto.randomBytes(20).toString('hex');
const encImgBase64 = RNCryptor.Encrypt(imgBuf, newKey);
var encImgBuffer = Buffer.from(encImgBase64, '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 = yield fetch(`https://${terms.host}/file`, {
method: 'POST',
headers: Object.assign(Object.assign({}, formHeaders), { 'Authorization': `Bearer ${meme.mediaToken}` }),
body: form
});
let json = yield resp.json();
if (!json.muid)
throw new Error('no muid');
// PUT NEW TERMS, to finish in personalizeMessage
const amt = (terms.meta && terms.meta.amt) || injectedAmount;
const ttl = terms.meta && terms.meta.ttl;
const mediaTerms = {
muid: json.muid, ttl: ttl || 31536000, host: '',
meta: Object.assign({}, amt && { amt }),
};
const encKey = rsa.encrypt(chat.groupKey, newKey.slice());
var date = new Date();
date.setMilliseconds(0);
yield sleep(1);
yield models_1.models.MediaKey.create({
muid: json.muid,
chatId: chat.id,
key: encKey,
messageId: (payload.message && payload.message.id) || 0,
receiver: 0,
sender: sender.id,
createdAt: date,
originalMuid: ogmuid,
mediaType: typ,
});
return { mediaTerms, mediaKey: encKey };
}
catch (e) {
throw e;
}
});
}
exports.downloadAndUploadAndSaveReturningTermsAndKey = downloadAndUploadAndSaveReturningTermsAndKey;
//# sourceMappingURL=modify.js.map

2
dist/api/network/modify.js.map

File diff suppressed because one or more lines are too long

81
dist/api/network/receive.js

@ -18,7 +18,9 @@ const lightning_2 = require("../utils/lightning");
const models_1 = require("../models");
const send_1 = require("./send");
const modify_1 = require("./modify");
// import {modifyPayloadAndSaveMediaKey} from './modify'
const msg_1 = require("../utils/msg");
const sequelize_1 = require("sequelize");
const constants = require(path.join(__dirname, '../../config/constants.json'));
const msgtypes = constants.message_types;
exports.typesToForward = [
@ -39,34 +41,63 @@ function onReceive(payload) {
let doAction = true;
const toAddIn = {};
const isTribe = payload.chat && payload.chat.type === constants.chat_types.tribe;
if (isTribe && exports.typesToForward.includes(payload.type)) {
const needsPricePerJoin = typesThatNeedPricePerMessage.includes(payload.type);
const chat = yield models_1.models.Chat.findOne({ where: { uuid: payload.chat.uuid } });
let isTribeOwner = false;
const chat = yield models_1.models.Chat.findOne({ where: { uuid: payload.chat.uuid } });
if (isTribe) {
const tribeOwnerPubKey = chat && chat.ownerPubkey;
const owner = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
if (owner.publicKey === tribeOwnerPubKey) {
toAddIn.isTribeOwner = true;
// CHECK THEY ARE IN THE GROUP if message
isTribeOwner = owner.publicKey === tribeOwnerPubKey;
}
if (isTribeOwner)
toAddIn.isTribeOwner = true;
if (isTribeOwner && exports.typesToForward.includes(payload.type)) {
const needsPricePerJoin = typesThatNeedPricePerMessage.includes(payload.type);
// CHECK THEY ARE IN THE GROUP if message
const senderContact = yield models_1.models.Contact.findOne({ where: { publicKey: payload.sender.pub_key } });
if (needsPricePerJoin) {
const senderMember = senderContact && (yield models_1.models.ChatMember.findOne({ where: { contactId: senderContact.id, chatId: chat.id } }));
if (!senderMember)
doAction = false;
}
// CHECK PRICES
if (needsPricePerJoin) {
if (payload.message.amount < chat.pricePerMessage)
doAction = false;
}
// check price to join
if (payload.type === msgtypes.group_join) {
if (payload.message.amount < chat.priceToJoin)
doAction = false;
}
if (doAction)
forwardMessageToTribe(payload, senderContact);
else
console.log('=> insufficient payment for this action');
}
if (isTribeOwner && payload.type === msgtypes.purchase) {
const mt = payload.message.mediaToken;
const myMediaMessage = yield models_1.models.Message.findOne({ where: {
mediaToken: mt, sender: 1, type: msgtypes.attachment
} });
if (!myMediaMessage) { // someone else's attachment
const senderContact = yield models_1.models.Contact.findOne({ where: { publicKey: payload.sender.pub_key } });
if (needsPricePerJoin) {
const senderMember = senderContact && (yield models_1.models.ChatMember.findOne({ where: { contactId: senderContact.id, chatId: chat.id } }));
if (!senderMember)
doAction = false;
}
// CHECK PRICES
if (needsPricePerJoin) {
if (payload.message.amount < chat.pricePerMessage)
doAction = false;
}
// check price to join
if (payload.type === msgtypes.group_join) {
if (payload.message.amount < chat.priceToJoin)
doAction = false;
}
if (doAction)
forwardMessageToTribe(payload, senderContact);
else
console.log('=> insufficient payment for this action');
modify_1.purchaseFromOriginalSender(payload, chat, senderContact);
// we do pass thru, to store... so that we know who the og purchaser was
}
}
if (isTribeOwner && payload.type === msgtypes.purchase_accept) {
const mt = payload.message.mediaToken;
const host = mt && mt.split('.').length && mt.split('.')[0];
const muid = mt && mt.split('.').length && mt.split('.')[1];
const ogPurchaseMessage = yield models_1.models.Message.findOne({ where: {
mediaToken: { [sequelize_1.Op.like]: `${host}.${muid}%` },
type: msgtypes.purchase,
sender: 1,
} });
if (!ogPurchaseMessage) { // for someone else
const senderContact = yield models_1.models.Contact.findOne({ where: { publicKey: payload.sender.pub_key } });
modify_1.sendFinalMemeIfFirstPurchaser(payload, chat, senderContact);
doAction = false; // skip this! we dont need it
}
}
if (doAction)

2
dist/api/network/receive.js.map

File diff suppressed because one or more lines are too long

5
dist/api/utils/setup.js

@ -44,6 +44,11 @@ function setVersion() {
}
function migrate() {
return __awaiter(this, void 0, void 0, function* () {
addTableColumn('sphinx_media_keys', 'media_type');
addTableColumn('sphinx_media_keys', 'original_muid');
addTableColumn('sphinx_messages', 'original_muid');
addTableColumn('sphinx_messages', 'uuid');
addTableColumn('sphinx_messages', 'reply_uuid');
addTableColumn('sphinx_media_keys', 'sender', 'BIGINT');
addTableColumn('sphinx_chats', 'group_key');
addTableColumn('sphinx_chats', 'group_private_key');

2
dist/api/utils/setup.js.map

@ -1 +1 @@
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../api/utils/setup.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../api/utils/setup.ts"],"names":[],"mappings":"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"}
Loading…
Cancel
Save