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

244 lines
6.8 KiB

import {models} from '../models'
import * as crypto from 'crypto'
import * as socket from '../utils/socket'
import * as helpers from '../helpers'
import * as jsonUtils from '../utils/json'
import {success, failure} from '../utils/res'
import password from '../utils/password'
const constants = require(__dirname + '/../../config/constants.json')
const getContacts = async (req, res) => {
const contacts = await models.Contact.findAll({ where:{deleted:false}, raw: true })
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 contactsResponse = contacts.map(contact => {
let contactJson = jsonUtils.contactToJson(contact)
let invite = invites.find(invite => invite.contactId == contact.id)
if (invite) {
contactJson.invite = jsonUtils.inviteToJson(invite)
}
return contactJson
});
const subsResponse = subscriptions.map(s=> jsonUtils.subscriptionToJson(s,null))
const chatsResponse = chats.map(chat => jsonUtils.chatToJson(chat))
success(res, {
contacts: contactsResponse,
chats: chatsResponse,
subscriptions: subsResponse
})
}
const generateToken = async (req, res) => {
console.log('=> generateToken called', { body: req.body, params: req.params, query: req.query })
const owner = await models.Contact.findOne({ where: { isOwner: true, authToken: null }})
if (owner) {
const hash = crypto.createHash('sha256').update(req.body['token']).digest('base64');
console.log("req.params['token']", req.params['token']);
console.log("hash", hash);
owner.update({ authToken: hash })
success(res,{})
} else {
failure(res,{})
}
}
const updateContact = async (req, res) => {
console.log('=> updateContact called', { body: req.body, params: req.params, query: req.query })
let attrs = extractAttrs(req.body)
const contact = await models.Contact.findOne({ where: { id: req.params.id }})
let shouldUpdateContactKey = (contact.isOwner && contact.contactKey == null && attrs["contact_key"] != null)
const pwd = password
if(process.env.USE_PASSWORD==='true'){
if(pwd!==req.params['pwd']) {
failure(res, 'Wrong Password')
return
}
}
const owner = await contact.update(jsonUtils.jsonToContact(attrs))
success(res, jsonUtils.contactToJson(owner))
if (!shouldUpdateContactKey) return
const contactIds = await models.Contact.findAll({where:{deleted:false}}).map(c => c.id)
if (contactIds.length == 0) return
helpers.sendContactKeys({
contactIds: contactIds,
sender: owner,
type: constants.message_types.contact_key,
})
}
const exchangeKeys = async (req, res) => {
console.log('=> exchangeKeys called', { body: req.body, params: req.params, query: req.query })
const contact = await models.Contact.findOne({ where: { id: req.params.id }})
const owner = await models.Contact.findOne({ where: { isOwner: true }})
success(res, jsonUtils.contactToJson(contact))
helpers.sendContactKeys({
contactIds: [contact.id],
sender: owner,
type: constants.message_types.contact_key,
})
}
const createContact = async (req, res) => {
console.log('=> createContact called', { body: req.body, params: req.params, query: req.query })
let attrs = extractAttrs(req.body)
const owner = await models.Contact.findOne({ where: { isOwner: true }})
const createdContact = await models.Contact.create(attrs)
const contact = await createdContact.update(jsonUtils.jsonToContact(attrs))
success(res, jsonUtils.contactToJson(contact))
helpers.sendContactKeys({
contactIds: [contact.id],
sender: owner,
type: constants.message_types.contact_key,
})
}
const deleteContact = async (req, res) => {
const id = parseInt(req.params.id||'0')
if(!id || id===1) {
failure(res, 'Cannot delete self')
return
}
const contact = await models.Contact.findOne({ where: { id } })
await contact.update({
deleted:true,
publicKey:'',
photoUrl:'',
alias:'Unknown',
contactKey:'',
})
// find and destroy chat & messages
const chats = await models.Chat.findAll({where:{deleted:false}})
chats.map(async chat => {
if (chat.type === constants.chat_types.conversation) {
const contactIds = JSON.parse(chat.contactIds)
if (contactIds.includes(id)) {
await chat.update({
deleted: true,
uuid:'',
contactIds:'[]',
name:''
})
await models.Message.destroy({ where: { chatId: chat.id } })
}
}
})
await models.Invite.destroy({ where: { contactId: id } })
await models.Subscription.destroy({ where: { contactId: id } })
success(res, {})
}
const receiveConfirmContactKey = async (payload) => {
console.log('=> confirm contact key', { payload })
const dat = payload.content || payload
const sender_pub_key = dat.sender.pub_key
const sender_contact_key = dat.sender.contact_key
const sender_alias = dat.sender.alias || 'Unknown'
const sender_photo_url = dat.sender.photoUrl
if(sender_photo_url){
// download and store photo locally
}
const sender = await models.Contact.findOne({ where: { publicKey: sender_pub_key, status: constants.contact_statuses.confirmed }})
if (sender_contact_key && sender) {
if(!sender.alias || sender.alias==='Unknown') {
sender.update({ contactKey: sender_contact_key, alias: sender_alias })
} else {
sender.update({ contactKey: sender_contact_key })
}
socket.sendJson({
type: 'contact',
response: jsonUtils.contactToJson(sender)
})
}
}
const receiveContactKey = async (payload) => {
console.log('=> received contact key', JSON.stringify(payload))
const dat = payload.content || payload
const sender_pub_key = dat.sender.pub_key
const sender_contact_key = dat.sender.contact_key
const sender_alias = dat.sender.alias || 'Unknown'
const sender_photo_url = dat.sender.photoUrl
if(sender_photo_url){
// download and store photo locally
}
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 }})
if (sender_contact_key && sender) {
if(!sender.alias || sender.alias==='Unknown') {
sender.update({ contactKey: sender_contact_key, alias: sender_alias })
} else {
sender.update({ contactKey: sender_contact_key })
}
socket.sendJson({
type: 'contact',
response: jsonUtils.contactToJson(sender)
})
}
helpers.sendContactKeys({
contactPubKey: sender_pub_key,
sender: owner,
type: constants.message_types.contact_key_confirmation,
})
}
const extractAttrs = body => {
let fields_to_update = ["public_key", "node_alias", "alias", "photo_url", "device_id", "status", "contact_key"]
let attrs = {}
Object.keys(body).forEach(key => {
if (fields_to_update.includes(key)) {
attrs[key] = body[key]
}
})
return attrs
}
export {
generateToken,
exchangeKeys,
getContacts,
updateContact,
createContact,
deleteContact,
receiveContactKey,
receiveConfirmContactKey
}