Browse Source

Merge pull request #67 from stakwork/private

Private
push-params v0.10.3
Evan Feenstra 5 years ago
committed by GitHub
parent
commit
a778be1bdd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 239
      api/controllers/chatTribes.ts
  2. 33
      api/controllers/chats.ts
  3. 12
      api/controllers/contacts.ts
  4. 4
      api/controllers/index.ts
  5. 5
      api/hub.ts
  6. 6
      api/models/ts/chatMember.ts
  7. 11
      api/network/receive.ts
  8. 2
      api/network/send.ts
  9. 7
      api/utils/setup.ts
  10. 6
      api/utils/tribes.ts
  11. 7
      config/constants.json
  12. 230
      dist/api/controllers/chatTribes.js
  13. 2
      dist/api/controllers/chatTribes.js.map
  14. 31
      dist/api/controllers/chats.js
  15. 2
      dist/api/controllers/chats.js.map
  16. 13
      dist/api/controllers/contacts.js
  17. 2
      dist/api/controllers/contacts.js.map
  18. 4
      dist/api/controllers/index.js
  19. 2
      dist/api/controllers/index.js.map
  20. 3
      dist/api/hub.js
  21. 2
      dist/api/hub.js.map
  22. 8
      dist/api/models/ts/chatMember.js
  23. 2
      dist/api/models/ts/chatMember.js.map
  24. 11
      dist/api/network/receive.js
  25. 2
      dist/api/network/receive.js.map
  26. 1
      dist/api/network/send.js
  27. 2
      dist/api/network/send.js.map
  28. 6
      dist/api/utils/setup.js
  29. 2
      dist/api/utils/setup.js.map
  30. 6
      dist/api/utils/tribes.js
  31. 2
      dist/api/utils/tribes.js.map
  32. 10
      dist/config/constants.json

239
api/controllers/chatTribes.ts

@ -3,8 +3,11 @@ import * as jsonUtils from '../utils/json'
import { success, failure } from '../utils/res'
import * as network from '../network'
import * as rsa from '../crypto/rsa'
import * as helpers from '../helpers'
import * as socket from '../utils/socket'
import * as tribes from '../utils/tribes'
import * as path from 'path'
import { sendNotification } from '../hub'
import {personalizeMessage, decryptMessage} from '../utils/msg'
import { Op } from 'sequelize'
@ -13,6 +16,7 @@ const constants = require(path.join(__dirname,'../../config/constants.json'))
export async function joinTribe(req, res){
console.log('=> joinTribe')
const { uuid, group_key, name, host, amount, img, owner_pubkey, owner_alias } = req.body
const is_private = req.body.private
const existing = await models.Chat.findOne({where:{uuid}})
if(existing) {
@ -51,6 +55,9 @@ export async function joinTribe(req, res){
let date = new Date()
date.setMilliseconds(0)
const chatStatus = is_private ?
constants.chat_statuses.pending :
constants.chat_statuses.approved
const chatParams = {
uuid: uuid,
contactIds: JSON.stringify(contactIds),
@ -62,11 +69,24 @@ export async function joinTribe(req, res){
host: host || tribes.getHost(),
groupKey: group_key,
ownerPubkey: owner_pubkey,
private: is_private||false,
status: chatStatus,
priceToJoin: amount||0,
}
const typeToSend = is_private ?
constants.message_types.member_request :
constants.message_types.group_join
const contactIdsToSend = is_private ?
[theTribeOwner.id] : // ONLY SEND TO TRIBE OWNER IF ITS A REQUEST
chatParams.contactIds
console.log('=> joinTribe: typeToSend', typeToSend)
console.log('=> joinTribe: contactIdsToSend', contactIdsToSend)
network.sendMessage({ // send my data to tribe owner
chat: {
...chatParams, members: {
...chatParams,
contactIds: contactIdsToSend,
members: {
[owner.publicKey]: {
key: owner.contactKey,
alias: owner.alias||''
@ -76,7 +96,7 @@ export async function joinTribe(req, res){
amount:amount||0,
sender: owner,
message: {},
type: constants.message_types.group_join,
type: typeToSend,
failure: function (e) {
failure(res, e)
},
@ -87,12 +107,79 @@ export async function joinTribe(req, res){
chatId: chat.id,
role: constants.chat_roles.owner,
lastActive: date,
status: constants.chat_statuses.approved
})
success(res, jsonUtils.chatToJson(chat))
}
})
}
export async function receiveMemberRequest(payload) {
console.log('=> receiveMemberRequest')
const { sender_pub_key, sender_alias, chat_uuid, chat_members, chat_type, isTribeOwner } = await helpers.parseReceiveParams(payload)
const chat = await models.Chat.findOne({ where: { uuid: chat_uuid } })
if (!chat) return console.log('no chat')
const isTribe = chat_type===constants.chat_types.tribe
if(!isTribe || !isTribeOwner) return console.log('not a tribe')
var date = new Date()
date.setMilliseconds(0)
let theSender: any = null
const member = chat_members[sender_pub_key]
const senderAlias = sender_alias || (member && member.alias) || 'Unknown'
const sender = await models.Contact.findOne({ where: { publicKey: sender_pub_key } })
if (sender) {
theSender = sender // might already include??
} else {
if(member && member.key) {
const createdContact = await models.Contact.create({
publicKey: sender_pub_key,
contactKey: member.key,
alias: senderAlias,
status: 1,
fromGroup: true,
})
theSender = createdContact
}
}
if(!theSender) return console.log('no sender') // fail (no contact key?)
await models.ChatMember.upsert({
contactId: theSender.id,
chatId: chat.id,
role: constants.chat_roles.reader,
status: constants.chat_statuses.pending,
lastActive: date,
})
const msg:{[k:string]:any} = {
chatId: chat.id,
type: constants.message_types.member_request,
sender: (theSender && theSender.id) || 0,
messageContent:'', remoteMessageContent:'',
status: constants.statuses.confirmed,
date: date, createdAt: date, updatedAt: date
}
if(isTribe) {
msg.senderAlias = sender_alias
}
const message = await models.Message.create(msg)
const theChat = await addPendingContactIdsToChat(chat)
socket.sendJson({
type: 'member_request',
response: {
contact: jsonUtils.contactToJson(theSender||{}),
chat: jsonUtils.chatToJson(theChat),
message: jsonUtils.messageToJson(message, theChat)
}
})
}
export async function editTribe(req, res) {
const {
name,
@ -131,6 +218,7 @@ export async function editTribe(req, res) {
img,
owner_alias: owner.alias,
unlisted,
is_private: req.body.private
})
} catch(e) {
okToUpdate = false
@ -145,6 +233,7 @@ export async function editTribe(req, res) {
escrowAmount: escrow_amount||0,
escrowMillis: escrow_millis||0,
unlisted: unlisted||false,
private: req.body.private||false,
})
success(res, jsonUtils.chatToJson(chat))
} else {
@ -152,6 +241,134 @@ export async function editTribe(req, res) {
}
}
export async function approveOrRejectMember(req,res) {
console.log('=> approve or reject tribe member')
const msgId = parseInt(req.params['messageId'])
const contactId = parseInt(req.params['contactId'])
const status = req.params['status']
const msg = await models.Message.findOne({ where: { id:msgId } })
if (!msg) return failure(res, 'no message')
const chatId = msg.chatId
const chat = await models.Chat.findOne({ where: { id:chatId } })
if (!chat) return failure(res, 'no chat')
if(!msgId || !contactId || !(status==='approved'||status==='rejected')) {
return failure(res, 'incorrect status')
}
let memberStatus = constants.chat_statuses.rejected
let msgType = constants.message_types.member_reject
if(status==='approved') {
memberStatus = constants.chat_statuses.approved
msgType = constants.message_types.member_approve
const contactIds = JSON.parse(chat.contactIds || '[]')
if(!contactIds.includes(contactId)) contactIds.push(contactId)
await chat.update({ contactIds: JSON.stringify(contactIds) })
}
await msg.update({type:msgType})
const member = await models.ChatMember.findOne({where:{contactId, chatId}})
if(!member) {
return failure(res, 'cant find chat member')
}
// update ChatMember status
await member.update({status:memberStatus})
const owner = await models.Contact.findOne({ where: { isOwner: true } })
const chatToSend = chat.dataValues||chat
network.sendMessage({ // send to the requester
chat: { ...chatToSend, contactIds: [member.contactId], },
amount: 0,
sender: owner,
message: {},
type: msgType,
})
const theChat = await addPendingContactIdsToChat(chat)
success(res, {
chat: jsonUtils.chatToJson(theChat),
message: jsonUtils.messageToJson(msg, theChat)
})
}
export async function receiveMemberApprove(payload) {
console.log('=> receiveMemberApprove')
const { owner, chat, chat_name, sender } = await helpers.parseReceiveParams(payload)
if(!chat) return console.log('no chat')
await chat.update({status: constants.chat_statuses.approved})
let date = new Date()
date.setMilliseconds(0)
const msg:{[k:string]:any} = {
chatId: chat.id,
type: constants.message_types.member_approve,
sender: (sender && sender.id) || 0,
messageContent:'', remoteMessageContent:'',
status: constants.statuses.confirmed,
date: date, createdAt: date, updatedAt: date
}
const message = await models.Message.create(msg)
socket.sendJson({
type: 'member_approve',
response: {
message: jsonUtils.messageToJson(message, chat),
chat: jsonUtils.chatToJson(chat),
}
})
const amount = chat.priceToJoin||0
const theChat = chat.dataValues||chat
// send JOIN and my info to all
network.sendMessage({
chat: { ...theChat,
members: {
[owner.publicKey]: {
key: owner.contactKey,
alias: owner.alias||''
}
}
},
amount,
sender: owner,
message: {},
type: constants.message_types.group_join,
})
sendNotification(chat, chat_name, 'group')
}
export async function receiveMemberReject(payload) {
console.log('=> receiveMemberReject')
const { chat, sender, chat_name } = await helpers.parseReceiveParams(payload)
if(!chat) return console.log('no chat')
await chat.update({status: constants.chat_statuses.rejected})
// dang.. nothing really to do here?
let date = new Date()
date.setMilliseconds(0)
const msg:{[k:string]:any} = {
chatId: chat.id,
type: constants.message_types.member_reject,
sender: (sender && sender.id) || 0,
messageContent:'', remoteMessageContent:'',
status: constants.statuses.confirmed,
date: date, createdAt: date, updatedAt: date
}
const message = await models.Message.create(msg)
socket.sendJson({
type: 'member_reject',
response: {
message: jsonUtils.messageToJson(message, chat),
chat: jsonUtils.chatToJson(chat),
}
})
sendNotification(chat, chat_name, 'reject')
}
export async function replayChatHistory(chat, contact) {
if(!(chat&&chat.id&&contact&&contact.id)){
return console.log('[tribes] cant replay history')
@ -206,7 +423,7 @@ export async function replayChatHistory(chat, contact) {
})
}
export async function createTribeChatParams(owner, contactIds, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted): Promise<{[k:string]:any}> {
export async function createTribeChatParams(owner, contactIds, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted, is_private): Promise<{[k:string]:any}> {
let date = new Date()
date.setMilliseconds(0)
if (!(owner && contactIds && Array.isArray(contactIds))) {
@ -234,6 +451,21 @@ export async function createTribeChatParams(owner, contactIds, name, img, price_
escrowMillis: escrow_millis||0,
escrowAmount: escrow_amount||0,
unlisted: unlisted||false,
private: is_private||false,
}
}
export async function addPendingContactIdsToChat(achat){
const members = await models.ChatMember.findAll({where:{
chatId: achat.id,
status: constants.chat_statuses.pending // only pending
}})
if (!members) return achat
const pendingContactIds:number[] = members.map(m=>m.contactId)
const chat = achat.dataValues||achat
return {
...chat,
pendingContactIds,
}
}
@ -243,3 +475,4 @@ async function asyncForEach(array, callback) {
}
}

33
api/controllers/chats.ts

@ -9,7 +9,7 @@ import * as md5 from 'md5'
import * as path from 'path'
import * as tribes from '../utils/tribes'
import * as timers from '../utils/timers'
import {replayChatHistory,createTribeChatParams} from './chatTribes'
import {replayChatHistory,createTribeChatParams,addPendingContactIdsToChat} from './chatTribes'
const constants = require(path.join(__dirname,'../../config/constants.json'))
@ -165,7 +165,7 @@ export async function createGroupChat(req, res) {
let chatParams:any = null
let okToCreate = true
if(is_tribe){
chatParams = await createTribeChatParams(owner, contact_ids, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted)
chatParams = await createTribeChatParams(owner, contact_ids, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted, req.body.private)
if(chatParams.uuid){
// publish to tribe server
try {
@ -182,6 +182,7 @@ export async function createGroupChat(req, res) {
owner_pubkey: owner.publicKey,
owner_alias: owner.alias,
unlisted: unlisted||false,
is_private: req.body.private||false,
})
} catch(e) {
okToCreate = false
@ -212,6 +213,7 @@ export async function createGroupChat(req, res) {
contactId: owner.id,
chatId: chat.id,
role: constants.chat_roles.owner,
status: constants.chat_statuses.approved
})
}
success(res, jsonUtils.chatToJson(chat))
@ -274,12 +276,16 @@ export const deleteChat = async (req, res) => {
return failure(res, "cannot leave your own tribe")
}
network.sendMessage({
chat,
sender: owner,
message: {},
type: constants.message_types.group_leave,
})
const isPending = chat.status===constants.chat_statuses.pending
const isRejected = chat.status===constants.chat_statuses.rejected
if(!isPending && !isRejected) { // dont send if pending
network.sendMessage({
chat,
sender: owner,
message: {},
type: constants.message_types.group_leave,
})
}
await chat.update({
deleted: true,
@ -312,7 +318,7 @@ export async function receiveGroupJoin(payload) {
const member = chat_members[sender_pub_key]
const senderAlias = sender_alias || (member && member.alias) || 'Unknown'
if(!isTribe || isTribeOwner) { // dont need to create contacts for these
if(!isTribe || isTribeOwner) {
const sender = await models.Contact.findOne({ where: { publicKey: sender_pub_key } })
const contactIds = JSON.parse(chat.contactIds || '[]')
if (sender) {
@ -341,12 +347,13 @@ export async function receiveGroupJoin(payload) {
await chat.update({ contactIds: JSON.stringify(contactIds) })
if(isTribeOwner){ // IF TRIBE, ADD TO XREF
models.ChatMember.create({
if(isTribeOwner){ // IF TRIBE, ADD new member TO XREF
models.ChatMember.upsert({
contactId: theSender.id,
chatId: chat.id,
role: constants.chat_roles.reader,
lastActive: date,
status: constants.chat_statuses.approved
})
replayChatHistory(chat, theSender)
tribes.putstats({
@ -370,11 +377,12 @@ export async function receiveGroupJoin(payload) {
}
const message = await models.Message.create(msg)
const theChat = addPendingContactIdsToChat(chat)
socket.sendJson({
type: 'group_join',
response: {
contact: jsonUtils.contactToJson(theSender||{}),
chat: jsonUtils.chatToJson(chat),
chat: jsonUtils.chatToJson(theChat),
message: jsonUtils.messageToJson(message, null)
}
})
@ -508,6 +516,7 @@ export async function receiveGroupCreateOrInvite(payload) {
chatId: chat.id,
role: c.role||constants.chat_roles.reader,
lastActive: date,
status: constants.chat_statuses.approved
})
})
}

12
api/controllers/contacts.ts

@ -15,6 +15,9 @@ export const getContacts = async (req, res) => {
const invites = await models.Invite.findAll({ raw: true })
const chats = await models.Chat.findAll({ where:{deleted:false}, raw: true })
const subscriptions = await models.Subscription.findAll({ raw: true })
const pendingMembers = await models.ChatMember.findAll({where:{
status: constants.chat_statuses.pending
}})
const contactsResponse = contacts.map(contact => {
let contactJson = jsonUtils.contactToJson(contact)
@ -28,7 +31,13 @@ export const getContacts = async (req, res) => {
});
const subsResponse = subscriptions.map(s=> jsonUtils.subscriptionToJson(s,null))
const chatsResponse = chats.map(chat => jsonUtils.chatToJson(chat))
const chatsResponse = chats.map(chat=> {
const theChat = chat.dataValues||chat
if(!pendingMembers) return jsonUtils.chatToJson(theChat)
const membs = pendingMembers.filter(m=>m.chatId===chat.id) || []
theChat.pendingContactIds = membs.map(m=>m.contactId)
return jsonUtils.chatToJson(theChat)
})
success(res, {
contacts: contactsResponse,
@ -208,7 +217,6 @@ export const receiveContactKey = async (payload) => {
const owner = await models.Contact.findOne({ where: { isOwner: true }})
const sender = await models.Contact.findOne({ where: { publicKey: sender_pub_key, status: constants.contact_statuses.confirmed }})
console.log("FOUND SENDER",sender&&sender.dataValue)
if (sender_contact_key && sender) {
const objToUpdate:{[k:string]:any} = {contactKey: sender_contact_key}
if(sender_alias) objToUpdate.alias = sender_alias

4
api/controllers/index.ts

@ -41,6 +41,7 @@ export async function set(app) {
app.put('/chat/:id', chats.addGroupMembers)
app.put('/kick/:chat_id/:contact_id', chats.kickChatMember)
app.post('/tribe', chatTribes.joinTribe)
app.put('/member/:contactId/:status/:messageId', chatTribes.approveOrRejectMember)
app.put('/group/:id', chatTribes.editTribe)
app.post('/upload', uploads.avatarUpload.single('file'), uploads.uploadFile)
@ -136,4 +137,7 @@ export const ACTIONS = {
[msgtypes.group_kick]: chats.receiveGroupKick,
[msgtypes.delete]: messages.receiveDeleteMessage,
[msgtypes.repayment]: ()=>{},
[msgtypes.member_request]: chatTribes.receiveMemberRequest,
[msgtypes.member_approve]: chatTribes.receiveMemberApprove,
[msgtypes.member_reject]: chatTribes.receiveMemberReject,
}

5
api/hub.ts

@ -188,7 +188,7 @@ const createInviteInHub = (params, onSuccess, onFailure) => {
})
}
type NotificationType = 'group' | 'badge' | 'invite' | 'message'
type NotificationType = 'group' | 'badge' | 'invite' | 'message' | 'reject'
const sendNotification = async (chat, name, type:NotificationType) => {
@ -199,6 +199,9 @@ const sendNotification = async (chat, name, type:NotificationType) => {
if(type==='group'){
message = `You have been added to group ${name}`
}
if(type==='reject') {
message = `The admin has declined your request to join "${name}"`
}
if(type==='message' && chat.type==constants.chat_types.group && chat.name && chat.name.length){
message += ` on ${chat.name}`

6
api/models/ts/chatMember.ts

@ -1,6 +1,8 @@
import { Table, Column, Model } from 'sequelize-typescript';
@Table({tableName: 'sphinx_chat_members', underscored: true})
@Table({tableName: 'sphinx_chat_members', underscored: true, indexes:[
{unique:true, fields:['chat_id','contact_id']}
]})
export default class ChatMember extends Model<ChatMember> {
@Column
@ -22,6 +24,6 @@ export default class ChatMember extends Model<ChatMember> {
lastActive: Date
@Column
approved: boolean
status: number
}

11
api/network/receive.ts

@ -34,13 +34,14 @@ export const typesToReplay=[ // should match typesToForward
msgtypes.message, msgtypes.group_join, msgtypes.group_leave
]
async function onReceive(payload){
// console.log("=> ON RECEIVE",payload)
// if tribe, owner must forward to MQTT
let doAction = true
const toAddIn:{[k:string]:any} = {}
let isTribe = false
let isTribeOwner = false
let chat
if(payload.chat) {
if(payload.chat&&payload.chat.uuid) {
isTribe = payload.chat.type===constants.chat_types.tribe
chat = await models.Chat.findOne({where:{uuid:payload.chat.uuid}})
if(chat) chat.update({seen:false})
@ -72,9 +73,15 @@ async function onReceive(payload){
})
}
}
// check price to join
// check price to join AND private chat
if(payload.type===msgtypes.group_join) {
if(payload.message.amount<chat.priceToJoin) doAction=false
if(chat.private) { // check if has been approved
const senderMember = senderContact && await models.ChatMember.findOne({where:{contactId:senderContact.id, chatId:chat.id}})
if(!(senderMember && senderMember.status===constants.chat_statuses.approved)){
doAction=false // dont let if private and not approved
}
}
}
// check that the sender is the og poster
if(payload.type===msgtypes.delete) {

2
api/network/send.ts

@ -15,6 +15,8 @@ export async function sendMessage(params) {
const { type, chat, message, sender, amount, success, failure, skipPubKey } = params
let msg = newmsg(type, chat, sender, message)
// console.log("=> MSG TO SEND",msg)
// console.log(type,message)
if(!(sender&&sender.publicKey)) {
console.log("NO SENDER?????")

7
api/utils/setup.ts

@ -31,9 +31,14 @@ async function setVersion(){
}
async function migrate(){
try{
await sequelize.query(`CREATE UNIQUE INDEX chat_member_index ON sphinx_chat_members(chat_id, contact_id);`)
}catch(e){}
addTableColumn('sphinx_chats', 'private', 'BOOLEAN')
addTableColumn('sphinx_chats', 'unlisted', 'BOOLEAN')
addTableColumn('sphinx_chat_members', 'approved', 'BOOLEAN')
addTableColumn('sphinx_chat_members', 'status', 'BIGINT')
addTableColumn('sphinx_chats', 'seen', 'BOOLEAN')

6
api/utils/tribes.ts

@ -72,7 +72,7 @@ export function publish(topic, msg, cb) {
})
}
export async function declare({ uuid, name, description, tags, img, group_key, host, price_per_message, price_to_join, owner_alias, owner_pubkey, escrow_amount, escrow_millis, unlisted }) {
export async function declare({ uuid, name, description, tags, img, group_key, host, price_per_message, price_to_join, owner_alias, owner_pubkey, escrow_amount, escrow_millis, unlisted, is_private }) {
try {
await fetch('https://' + host + '/tribes', {
method: 'POST',
@ -85,6 +85,7 @@ export async function declare({ uuid, name, description, tags, img, group_key, h
escrow_amount: escrow_amount || 0,
escrow_millis: escrow_millis || 0,
unlisted: unlisted||false,
private: is_private||false,
}),
headers: { 'Content-Type': 'application/json' }
})
@ -95,7 +96,7 @@ export async function declare({ uuid, name, description, tags, img, group_key, h
}
}
export async function edit({ uuid, host, name, description, tags, img, price_per_message, price_to_join, owner_alias, escrow_amount, escrow_millis, unlisted }) {
export async function edit({ uuid, host, name, description, tags, img, price_per_message, price_to_join, owner_alias, escrow_amount, escrow_millis, unlisted, is_private }) {
try {
const token = await genSignedTimestamp()
await fetch('https://' + host + '/tribe?token=' + token, {
@ -109,6 +110,7 @@ export async function edit({ uuid, host, name, description, tags, img, price_per
escrow_millis: escrow_millis || 0,
owner_alias,
unlisted: unlisted||false,
private: is_private||false,
}),
headers: { 'Content-Type': 'application/json' }
})

7
config/constants.json

@ -21,7 +21,7 @@
"deleted": 5
},
"chat_statuses": {
"active": 0,
"approved": 0,
"pending": 1,
"rejected": 2
},
@ -45,8 +45,9 @@
"group_kick": 16,
"delete": 17,
"repayment": 18,
"member_approve": 19,
"member_reject": 20
"member_request": 19,
"member_approve": 20,
"member_reject": 21
},
"payment_errors": {
"timeout": "Timed Out",

230
dist/api/controllers/chatTribes.js

@ -14,8 +14,11 @@ const jsonUtils = require("../utils/json");
const res_1 = require("../utils/res");
const network = require("../network");
const rsa = require("../crypto/rsa");
const helpers = require("../helpers");
const socket = require("../utils/socket");
const tribes = require("../utils/tribes");
const path = require("path");
const hub_1 = require("../hub");
const msg_1 = require("../utils/msg");
const sequelize_1 = require("sequelize");
const constants = require(path.join(__dirname, '../../config/constants.json'));
@ -23,6 +26,7 @@ function joinTribe(req, res) {
return __awaiter(this, void 0, void 0, function* () {
console.log('=> joinTribe');
const { uuid, group_key, name, host, amount, img, owner_pubkey, owner_alias } = req.body;
const is_private = req.body.private;
const existing = yield models_1.models.Chat.findOne({ where: { uuid } });
if (existing) {
console.log('[tribes] u are already in this tribe');
@ -56,6 +60,9 @@ function joinTribe(req, res) {
}
let date = new Date();
date.setMilliseconds(0);
const chatStatus = is_private ?
constants.chat_statuses.pending :
constants.chat_statuses.approved;
const chatParams = {
uuid: uuid,
contactIds: JSON.stringify(contactIds),
@ -67,9 +74,20 @@ function joinTribe(req, res) {
host: host || tribes.getHost(),
groupKey: group_key,
ownerPubkey: owner_pubkey,
private: is_private || false,
status: chatStatus,
priceToJoin: amount || 0,
};
const typeToSend = is_private ?
constants.message_types.member_request :
constants.message_types.group_join;
const contactIdsToSend = is_private ?
[theTribeOwner.id] : // ONLY SEND TO TRIBE OWNER IF ITS A REQUEST
chatParams.contactIds;
console.log('=> joinTribe: typeToSend', typeToSend);
console.log('=> joinTribe: contactIdsToSend', contactIdsToSend);
network.sendMessage({
chat: Object.assign(Object.assign({}, chatParams), { members: {
chat: Object.assign(Object.assign({}, chatParams), { contactIds: contactIdsToSend, members: {
[owner.publicKey]: {
key: owner.contactKey,
alias: owner.alias || ''
@ -78,7 +96,7 @@ function joinTribe(req, res) {
amount: amount || 0,
sender: owner,
message: {},
type: constants.message_types.group_join,
type: typeToSend,
failure: function (e) {
res_1.failure(res, e);
},
@ -90,6 +108,7 @@ function joinTribe(req, res) {
chatId: chat.id,
role: constants.chat_roles.owner,
lastActive: date,
status: constants.chat_statuses.approved
});
res_1.success(res, jsonUtils.chatToJson(chat));
});
@ -98,6 +117,70 @@ function joinTribe(req, res) {
});
}
exports.joinTribe = joinTribe;
function receiveMemberRequest(payload) {
return __awaiter(this, void 0, void 0, function* () {
console.log('=> receiveMemberRequest');
const { sender_pub_key, sender_alias, chat_uuid, chat_members, chat_type, isTribeOwner } = yield helpers.parseReceiveParams(payload);
const chat = yield models_1.models.Chat.findOne({ where: { uuid: chat_uuid } });
if (!chat)
return console.log('no chat');
const isTribe = chat_type === constants.chat_types.tribe;
if (!isTribe || !isTribeOwner)
return console.log('not a tribe');
var date = new Date();
date.setMilliseconds(0);
let theSender = null;
const member = chat_members[sender_pub_key];
const senderAlias = sender_alias || (member && member.alias) || 'Unknown';
const sender = yield models_1.models.Contact.findOne({ where: { publicKey: sender_pub_key } });
if (sender) {
theSender = sender; // might already include??
}
else {
if (member && member.key) {
const createdContact = yield models_1.models.Contact.create({
publicKey: sender_pub_key,
contactKey: member.key,
alias: senderAlias,
status: 1,
fromGroup: true,
});
theSender = createdContact;
}
}
if (!theSender)
return console.log('no sender'); // fail (no contact key?)
models_1.models.ChatMember.upsert({
contactId: theSender.id,
chatId: chat.id,
role: constants.chat_roles.reader,
status: constants.chat_statuses.pending,
lastActive: date,
});
const msg = {
chatId: chat.id,
type: constants.message_types.member_request,
sender: (theSender && theSender.id) || 0,
messageContent: '', remoteMessageContent: '',
status: constants.statuses.confirmed,
date: date, createdAt: date, updatedAt: date
};
if (isTribe) {
msg.senderAlias = sender_alias;
}
const message = yield models_1.models.Message.create(msg);
const theChat = yield addPendingContactIdsToChat(chat);
socket.sendJson({
type: 'member_request',
response: {
contact: jsonUtils.contactToJson(theSender || {}),
chat: jsonUtils.chatToJson(theChat),
message: jsonUtils.messageToJson(message, theChat)
}
});
});
}
exports.receiveMemberRequest = receiveMemberRequest;
function editTribe(req, res) {
return __awaiter(this, void 0, void 0, function* () {
const { name, price_per_message, price_to_join, escrow_amount, escrow_millis, img, description, tags, unlisted, } = req.body;
@ -124,6 +207,7 @@ function editTribe(req, res) {
img,
owner_alias: owner.alias,
unlisted,
is_private: req.body.private
});
}
catch (e) {
@ -138,6 +222,7 @@ function editTribe(req, res) {
escrowAmount: escrow_amount || 0,
escrowMillis: escrow_millis || 0,
unlisted: unlisted || false,
private: req.body.private || false,
});
res_1.success(res, jsonUtils.chatToJson(chat));
}
@ -147,6 +232,130 @@ function editTribe(req, res) {
});
}
exports.editTribe = editTribe;
function approveOrRejectMember(req, res) {
return __awaiter(this, void 0, void 0, function* () {
console.log('=> approve or reject tribe member');
const msgId = parseInt(req.params['messageId']);
const contactId = parseInt(req.params['contactId']);
const status = req.params['status'];
const msg = yield models_1.models.Message.findOne({ where: { id: msgId } });
if (!msg)
return res_1.failure(res, 'no message');
const chatId = msg.chatId;
const chat = yield models_1.models.Chat.findOne({ where: { id: chatId } });
if (!chat)
return res_1.failure(res, 'no chat');
if (!msgId || !contactId || !(status === 'approved' || status === 'rejected')) {
return res_1.failure(res, 'incorrect status');
}
let memberStatus = constants.chat_statuses.rejected;
let msgType = constants.message_types.member_reject;
if (status === 'approved') {
memberStatus = constants.chat_statuses.approved;
msgType = constants.message_types.member_approve;
const contactIds = JSON.parse(chat.contactIds || '[]');
if (!contactIds.includes(contactId))
contactIds.push(contactId);
yield chat.update({ contactIds: JSON.stringify(contactIds) });
}
yield msg.update({ type: msgType });
const member = yield models_1.models.ChatMember.findOne({ where: { contactId, chatId } });
if (!member) {
return res_1.failure(res, 'cant find chat member');
}
// update ChatMember status
yield member.update({ status: memberStatus });
const owner = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
const chatToSend = chat.dataValues || chat;
network.sendMessage({
chat: Object.assign(Object.assign({}, chatToSend), { contactIds: [member.contactId] }),
amount: 0,
sender: owner,
message: {},
type: msgType,
});
const theChat = yield addPendingContactIdsToChat(chat);
res_1.success(res, {
chat: jsonUtils.chatToJson(theChat),
message: jsonUtils.messageToJson(msg, theChat)
});
});
}
exports.approveOrRejectMember = approveOrRejectMember;
function receiveMemberApprove(payload) {
return __awaiter(this, void 0, void 0, function* () {
console.log('=> receiveMemberApprove');
const { owner, chat, chat_name, sender } = yield helpers.parseReceiveParams(payload);
if (!chat)
return console.log('no chat');
yield chat.update({ status: constants.chat_statuses.approved });
let date = new Date();
date.setMilliseconds(0);
const msg = {
chatId: chat.id,
type: constants.message_types.member_approve,
sender: (sender && sender.id) || 0,
messageContent: '', remoteMessageContent: '',
status: constants.statuses.confirmed,
date: date, createdAt: date, updatedAt: date
};
const message = yield models_1.models.Message.create(msg);
socket.sendJson({
type: 'member_approve',
response: {
message: jsonUtils.messageToJson(message, chat),
chat: jsonUtils.chatToJson(chat),
}
});
const amount = chat.priceToJoin || 0;
const theChat = chat.dataValues || chat;
// send JOIN and my info to all
network.sendMessage({
chat: Object.assign(Object.assign({}, theChat), { members: {
[owner.publicKey]: {
key: owner.contactKey,
alias: owner.alias || ''
}
} }),
amount,
sender: owner,
message: {},
type: constants.message_types.group_join,
});
hub_1.sendNotification(chat, chat_name, 'group');
});
}
exports.receiveMemberApprove = receiveMemberApprove;
function receiveMemberReject(payload) {
return __awaiter(this, void 0, void 0, function* () {
console.log('=> receiveMemberReject');
const { chat, sender, chat_name } = yield helpers.parseReceiveParams(payload);
if (!chat)
return console.log('no chat');
yield chat.update({ status: constants.chat_statuses.rejected });
// dang.. nothing really to do here?
let date = new Date();
date.setMilliseconds(0);
const msg = {
chatId: chat.id,
type: constants.message_types.member_reject,
sender: (sender && sender.id) || 0,
messageContent: '', remoteMessageContent: '',
status: constants.statuses.confirmed,
date: date, createdAt: date, updatedAt: date
};
const message = yield models_1.models.Message.create(msg);
socket.sendJson({
type: 'member_reject',
response: {
message: jsonUtils.messageToJson(message, chat),
chat: jsonUtils.chatToJson(chat),
}
});
hub_1.sendNotification(chat, chat_name, 'reject');
});
}
exports.receiveMemberReject = receiveMemberReject;
function replayChatHistory(chat, contact) {
return __awaiter(this, void 0, void 0, function* () {
if (!(chat && chat.id && contact && contact.id)) {
@ -197,7 +406,7 @@ function replayChatHistory(chat, contact) {
});
}
exports.replayChatHistory = replayChatHistory;
function createTribeChatParams(owner, contactIds, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted) {
function createTribeChatParams(owner, contactIds, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted, is_private) {
return __awaiter(this, void 0, void 0, function* () {
let date = new Date();
date.setMilliseconds(0);
@ -225,10 +434,25 @@ function createTribeChatParams(owner, contactIds, name, img, price_per_message,
escrowMillis: escrow_millis || 0,
escrowAmount: escrow_amount || 0,
unlisted: unlisted || false,
private: is_private || false,
};
});
}
exports.createTribeChatParams = createTribeChatParams;
function addPendingContactIdsToChat(achat) {
return __awaiter(this, void 0, void 0, function* () {
const members = yield models_1.models.ChatMember.findAll({ where: {
chatId: achat.id,
status: constants.chat_statuses.pending // only pending
} });
if (!members)
return achat;
const pendingContactIds = members.map(m => m.contactId);
const chat = achat.dataValues || achat;
return Object.assign(Object.assign({}, chat), { pendingContactIds });
});
}
exports.addPendingContactIdsToChat = addPendingContactIdsToChat;
function asyncForEach(array, callback) {
return __awaiter(this, void 0, void 0, function* () {
for (let index = 0; index < array.length; index++) {

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

File diff suppressed because one or more lines are too long

31
dist/api/controllers/chats.js

@ -161,7 +161,7 @@ function createGroupChat(req, res) {
let chatParams = null;
let okToCreate = true;
if (is_tribe) {
chatParams = yield chatTribes_1.createTribeChatParams(owner, contact_ids, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted);
chatParams = yield chatTribes_1.createTribeChatParams(owner, contact_ids, name, img, price_per_message, price_to_join, escrow_amount, escrow_millis, unlisted, req.body.private);
if (chatParams.uuid) {
// publish to tribe server
try {
@ -178,6 +178,7 @@ function createGroupChat(req, res) {
owner_pubkey: owner.publicKey,
owner_alias: owner.alias,
unlisted: unlisted || false,
is_private: req.body.private || false,
});
}
catch (e) {
@ -209,6 +210,7 @@ function createGroupChat(req, res) {
contactId: owner.id,
chatId: chat.id,
role: constants.chat_roles.owner,
status: constants.chat_statuses.approved
});
}
res_1.success(res, jsonUtils.chatToJson(chat));
@ -268,12 +270,16 @@ exports.deleteChat = (req, res) => __awaiter(void 0, void 0, void 0, function* (
if (owner.publicKey === tribeOwnerPubKey) {
return res_1.failure(res, "cannot leave your own tribe");
}
network.sendMessage({
chat,
sender: owner,
message: {},
type: constants.message_types.group_leave,
});
const isPending = chat.status === constants.chat_statuses.pending;
const isRejected = chat.status === constants.chat_statuses.rejected;
if (!isPending && !isRejected) { // dont send if pending
network.sendMessage({
chat,
sender: owner,
message: {},
type: constants.message_types.group_leave,
});
}
yield chat.update({
deleted: true,
uuid: '',
@ -301,7 +307,7 @@ function receiveGroupJoin(payload) {
let theSender = null;
const member = chat_members[sender_pub_key];
const senderAlias = sender_alias || (member && member.alias) || 'Unknown';
if (!isTribe || isTribeOwner) { // dont need to create contacts for these
if (!isTribe || isTribeOwner) {
const sender = yield models_1.models.Contact.findOne({ where: { publicKey: sender_pub_key } });
const contactIds = JSON.parse(chat.contactIds || '[]');
if (sender) {
@ -331,12 +337,13 @@ function receiveGroupJoin(payload) {
if (!theSender)
return console.log('no sender'); // fail (no contact key?)
yield chat.update({ contactIds: JSON.stringify(contactIds) });
if (isTribeOwner) { // IF TRIBE, ADD TO XREF
models_1.models.ChatMember.create({
if (isTribeOwner) { // IF TRIBE, ADD new member TO XREF
models_1.models.ChatMember.upsert({
contactId: theSender.id,
chatId: chat.id,
role: constants.chat_roles.reader,
lastActive: date,
status: constants.chat_statuses.approved
});
chatTribes_1.replayChatHistory(chat, theSender);
tribes.putstats({
@ -358,11 +365,12 @@ function receiveGroupJoin(payload) {
msg.senderAlias = sender_alias;
}
const message = yield models_1.models.Message.create(msg);
const theChat = chatTribes_1.addPendingContactIdsToChat(chat);
socket.sendJson({
type: 'group_join',
response: {
contact: jsonUtils.contactToJson(theSender || {}),
chat: jsonUtils.chatToJson(chat),
chat: jsonUtils.chatToJson(theChat),
message: jsonUtils.messageToJson(message, null)
}
});
@ -491,6 +499,7 @@ function receiveGroupCreateOrInvite(payload) {
chatId: chat.id,
role: c.role || constants.chat_roles.reader,
lastActive: date,
status: constants.chat_statuses.approved
});
});
}

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

File diff suppressed because one or more lines are too long

13
dist/api/controllers/contacts.js

@ -24,6 +24,9 @@ exports.getContacts = (req, res) => __awaiter(void 0, void 0, void 0, function*
const invites = yield models_1.models.Invite.findAll({ raw: true });
const chats = yield models_1.models.Chat.findAll({ where: { deleted: false }, raw: true });
const subscriptions = yield models_1.models.Subscription.findAll({ raw: true });
const pendingMembers = yield models_1.models.ChatMember.findAll({ where: {
status: constants.chat_statuses.pending
} });
const contactsResponse = contacts.map(contact => {
let contactJson = jsonUtils.contactToJson(contact);
let invite = invites.find(invite => invite.contactId == contact.id);
@ -33,7 +36,14 @@ exports.getContacts = (req, res) => __awaiter(void 0, void 0, void 0, function*
return contactJson;
});
const subsResponse = subscriptions.map(s => jsonUtils.subscriptionToJson(s, null));
const chatsResponse = chats.map(chat => jsonUtils.chatToJson(chat));
const chatsResponse = chats.map(chat => {
const theChat = chat.dataValues || chat;
if (!pendingMembers)
return jsonUtils.chatToJson(theChat);
const membs = pendingMembers.filter(m => m.chatId === chat.id) || [];
theChat.pendingContactIds = membs.map(m => m.contactId);
return jsonUtils.chatToJson(theChat);
});
res_1.success(res, {
contacts: contactsResponse,
chats: chatsResponse,
@ -184,7 +194,6 @@ exports.receiveContactKey = (payload) => __awaiter(void 0, void 0, void 0, funct
}
const owner = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
const sender = yield models_1.models.Contact.findOne({ where: { publicKey: sender_pub_key, status: constants.contact_statuses.confirmed } });
console.log("FOUND SENDER", sender && sender.dataValue);
if (sender_contact_key && sender) {
const objToUpdate = { contactKey: sender_contact_key };
if (sender_alias)

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

File diff suppressed because one or more lines are too long

4
dist/api/controllers/index.js

@ -48,6 +48,7 @@ function set(app) {
app.put('/chat/:id', chats.addGroupMembers);
app.put('/kick/:chat_id/:contact_id', chats.kickChatMember);
app.post('/tribe', chatTribes.joinTribe);
app.put('/member/:contactId/:status/:messageId', chatTribes.approveOrRejectMember);
app.put('/group/:id', chatTribes.editTribe);
app.post('/upload', uploads.avatarUpload.single('file'), uploads.uploadFile);
app.post('/invites', invites.createInvite);
@ -134,5 +135,8 @@ exports.ACTIONS = {
[msgtypes.group_kick]: chats.receiveGroupKick,
[msgtypes.delete]: messages.receiveDeleteMessage,
[msgtypes.repayment]: () => { },
[msgtypes.member_request]: chatTribes.receiveMemberRequest,
[msgtypes.member_approve]: chatTribes.receiveMemberApprove,
[msgtypes.member_reject]: chatTribes.receiveMemberReject,
};
//# sourceMappingURL=index.js.map

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

File diff suppressed because one or more lines are too long

3
dist/api/hub.js

@ -195,6 +195,9 @@ const sendNotification = (chat, name, type) => __awaiter(void 0, void 0, void 0,
if (type === 'group') {
message = `You have been added to group ${name}`;
}
if (type === 'reject') {
message = `The admin has declined your request to join "${name}"`;
}
if (type === 'message' && chat.type == constants.chat_types.group && chat.name && chat.name.length) {
message += ` on ${chat.name}`;
}

2
dist/api/hub.js.map

File diff suppressed because one or more lines are too long

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

@ -38,10 +38,12 @@ __decorate([
], ChatMember.prototype, "lastActive", void 0);
__decorate([
sequelize_typescript_1.Column,
__metadata("design:type", Boolean)
], ChatMember.prototype, "approved", void 0);
__metadata("design:type", Number)
], ChatMember.prototype, "status", void 0);
ChatMember = __decorate([
sequelize_typescript_1.Table({ tableName: 'sphinx_chat_members', underscored: true })
sequelize_typescript_1.Table({ tableName: 'sphinx_chat_members', underscored: true, indexes: [
{ unique: true, fields: ['chat_id', 'contact_id'] }
] })
], ChatMember);
exports.default = ChatMember;
//# sourceMappingURL=chatMember.js.map

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

@ -1 +1 @@
{"version":3,"file":"chatMember.js","sourceRoot":"","sources":["../../../../api/models/ts/chatMember.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAA4D;AAG5D,IAAqB,UAAU,GAA/B,MAAqB,UAAW,SAAQ,4BAAiB;CAuBxD,CAAA;AApBC;IADC,6BAAM;;0CACO;AAGd;IADC,6BAAM;;6CACU;AAGjB;IADC,6BAAM;;wCACK;AAGZ;IADC,6BAAM;;8CACW;AAGlB;IADC,6BAAM;;iDACc;AAGrB;IADC,6BAAM;8BACK,IAAI;8CAAA;AAGhB;IADC,6BAAM;;4CACU;AArBE,UAAU;IAD9B,4BAAK,CAAC,EAAC,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,IAAI,EAAC,CAAC;GACxC,UAAU,CAuB9B;kBAvBoB,UAAU"}
{"version":3,"file":"chatMember.js","sourceRoot":"","sources":["../../../../api/models/ts/chatMember.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAA4D;AAK5D,IAAqB,UAAU,GAA/B,MAAqB,UAAW,SAAQ,4BAAiB;CAuBxD,CAAA;AApBC;IADC,6BAAM;;0CACO;AAGd;IADC,6BAAM;;6CACU;AAGjB;IADC,6BAAM;;wCACK;AAGZ;IADC,6BAAM;;8CACW;AAGlB;IADC,6BAAM;;iDACc;AAGrB;IADC,6BAAM;8BACK,IAAI;8CAAA;AAGhB;IADC,6BAAM;;0CACO;AArBK,UAAU;IAH9B,4BAAK,CAAC,EAAC,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAC;YACnE,EAAC,MAAM,EAAC,IAAI,EAAE,MAAM,EAAC,CAAC,SAAS,EAAC,YAAY,CAAC,EAAC;SAC/C,EAAC,CAAC;GACkB,UAAU,CAuB9B;kBAvBoB,UAAU"}

11
dist/api/network/receive.js

@ -43,13 +43,14 @@ exports.typesToReplay = [
];
function onReceive(payload) {
return __awaiter(this, void 0, void 0, function* () {
// console.log("=> ON RECEIVE",payload)
// if tribe, owner must forward to MQTT
let doAction = true;
const toAddIn = {};
let isTribe = false;
let isTribeOwner = false;
let chat;
if (payload.chat) {
if (payload.chat && payload.chat.uuid) {
isTribe = payload.chat.type === constants.chat_types.tribe;
chat = yield models_1.models.Chat.findOne({ where: { uuid: payload.chat.uuid } });
if (chat)
@ -85,10 +86,16 @@ function onReceive(payload) {
});
}
}
// check price to join
// check price to join AND private chat
if (payload.type === msgtypes.group_join) {
if (payload.message.amount < chat.priceToJoin)
doAction = false;
if (chat.private) { // check if has been approved
const senderMember = senderContact && (yield models_1.models.ChatMember.findOne({ where: { contactId: senderContact.id, chatId: chat.id } }));
if (!(senderMember && senderMember.status === constants.chat_statuses.approved)) {
doAction = false; // dont let if private and not approved
}
}
}
// check that the sender is the og poster
if (payload.type === msgtypes.delete) {

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

File diff suppressed because one or more lines are too long

1
dist/api/network/send.js

@ -22,6 +22,7 @@ function sendMessage(params) {
return __awaiter(this, void 0, void 0, function* () {
const { type, chat, message, sender, amount, success, failure, skipPubKey } = params;
let msg = newmsg(type, chat, sender, message);
// console.log("=> MSG TO SEND",msg)
// console.log(type,message)
if (!(sender && sender.publicKey)) {
console.log("NO SENDER?????");

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

File diff suppressed because one or more lines are too long

6
dist/api/utils/setup.js

@ -44,9 +44,13 @@ function setVersion() {
}
function migrate() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield models_1.sequelize.query(`CREATE UNIQUE INDEX chat_member_index ON sphinx_chat_members(chat_id, contact_id);`);
}
catch (e) { }
addTableColumn('sphinx_chats', 'private', 'BOOLEAN');
addTableColumn('sphinx_chats', 'unlisted', 'BOOLEAN');
addTableColumn('sphinx_chat_members', 'approved', 'BOOLEAN');
addTableColumn('sphinx_chat_members', 'status', 'BIGINT');
addTableColumn('sphinx_chats', 'seen', 'BOOLEAN');
try {
yield models_1.sequelize.query(`CREATE INDEX idx_messages_sender ON sphinx_messages (sender);`);

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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"}

6
dist/api/utils/tribes.js

@ -89,7 +89,7 @@ function publish(topic, msg, cb) {
});
}
exports.publish = publish;
function declare({ uuid, name, description, tags, img, group_key, host, price_per_message, price_to_join, owner_alias, owner_pubkey, escrow_amount, escrow_millis, unlisted }) {
function declare({ uuid, name, description, tags, img, group_key, host, price_per_message, price_to_join, owner_alias, owner_pubkey, escrow_amount, escrow_millis, unlisted, is_private }) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield fetch('https://' + host + '/tribes', {
@ -103,6 +103,7 @@ function declare({ uuid, name, description, tags, img, group_key, host, price_pe
escrow_amount: escrow_amount || 0,
escrow_millis: escrow_millis || 0,
unlisted: unlisted || false,
private: is_private || false,
}),
headers: { 'Content-Type': 'application/json' }
});
@ -115,7 +116,7 @@ function declare({ uuid, name, description, tags, img, group_key, host, price_pe
});
}
exports.declare = declare;
function edit({ uuid, host, name, description, tags, img, price_per_message, price_to_join, owner_alias, escrow_amount, escrow_millis, unlisted }) {
function edit({ uuid, host, name, description, tags, img, price_per_message, price_to_join, owner_alias, escrow_amount, escrow_millis, unlisted, is_private }) {
return __awaiter(this, void 0, void 0, function* () {
try {
const token = yield genSignedTimestamp();
@ -130,6 +131,7 @@ function edit({ uuid, host, name, description, tags, img, price_per_message, pri
escrow_millis: escrow_millis || 0,
owner_alias,
unlisted: unlisted || false,
private: is_private || false,
}),
headers: { 'Content-Type': 'application/json' }
});

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

File diff suppressed because one or more lines are too long

10
dist/config/constants.json

@ -20,6 +20,11 @@
"failed": 4,
"deleted": 5
},
"chat_statuses": {
"approved": 0,
"pending": 1,
"rejected": 2
},
"message_types": {
"message": 0,
"confirmation": 1,
@ -40,8 +45,9 @@
"group_kick": 16,
"delete": 17,
"repayment": 18,
"member_approve": 19,
"member_reject": 20
"member_request": 19,
"member_approve": 20,
"member_reject": 21
},
"payment_errors": {
"timeout": "Timed Out",

Loading…
Cancel
Save