absenat
Version:
dedicated messaging service core
272 lines (271 loc) • 8.81 kB
JavaScript
const pathLibrary = require('path');
const chunk_size = 100;
/**
*
* @param {*} contact_id
* @param {*} finished
* @param {*} on_success
*/
const validate_connection = (contact_id, finished, on_success) => {
db.getContact(contact_id,
contact => { // contact found
const socket = connections[contact.socket_id].socket;
if ((contact.last_time_connected < Date.now() - (config.max_timeout * 2)) || !socket) { // connection is lost
console.log(chalk.red('Err: contact is not connected. please connect again to contact'));
return finished();
} else { // connection is alive
on_success(contact, socket);
return finished();
}
},
() => { // contact not found
console.log(chalk.red(`Err: contact ${contact_id} not found`));
return finished();
}
);
}
/**
* @author mr-exception
* @description this method sends a text message to contact
* @param {array} arguments
* @param {function} finished
*/
const sendTextMessage = (arguments, finished) => {
const contact_id = arguments[0];
const text = arguments.slice(1).join(' ');
validate_connection(contact_id, finished, (contact, socket) => {
console.log(`sending message to ${contact_id}: ${text}`);
const chunks = [];
for (let i = 0; i < text.length; i += chunk_size) {
chunks.push(text.substring(i, i + chunk_size));
}
const contactPublicKeyNode = createPublicKey(contact.public_key);
const uuid = uuidv4();
chunks.forEach((message_text, index) => {
const cipher = contactPublicKeyNode.encrypt(JSON.stringify({
id: uuid,
length: chunks.length,
index,
message: message_text,
}));
socket.emit('text_message', config.public_key, cipher);
});
db.addSendingPrivateTextMessage(uuid, contact, text);
finished();
});
}
/**
* @author mr-exception
* @description this method sends an image message to contact
* @param {array} arguments
* @param {function} finished
*/
const sendImageMessage = (arguments, finished) => {
const contact_id = arguments[0];
const path = arguments[1];
const caption = arguments.slice(2).join(' ');
validate_connection(contact_id, finished, (contact, socket) => {
if (!fs.existsSync(path)) {
console.log(chalk.red(`Err: file ${path} not found`));
finished();
return;
}
const buffer = fs.readFileSync(path);
const chunks = [];
for (let i = 0; i < buffer.length; i += chunk_size) {
chunks.push(buffer.subarray(i, i + chunk_size));
}
console.log(`sending message to ${contact_id}: ${path} (${caption})`);
const contactPublicKeyNode = createPublicKey(contact.public_key);
const uuid = uuidv4();
chunks.forEach((buffer, index) => {
let cipher = {
id: uuid,
length: chunks.length,
index,
message: buffer,
};
if (index === chunks.length - 1) {
cipher.caption = caption;
cipher.filename = pathLibrary.basename(path);
}
cipher = contactPublicKeyNode.encrypt(JSON.stringify(cipher));
socket.emit('image_message', config.public_key, cipher);
});
db.addSendingPrivateImageMessage(uuid, contact, caption, path, 'NuLL');
finished();
});
}
/**
* @author mr-exception
* @description this method sends an file message to contact
* @param {array} arguments
* @param {function} finished
*/
const sendFileMessage = (arguments, finished) => {
const contact_id = arguments[0];
const path = arguments[1];
const caption = arguments.slice(2).join(' ');
validate_connection(contact_id, finished, (contact, socket) => {
if (!fs.existsSync(path)) {
console.log(chalk.red(`Err: file ${path} not found`));
finished();
return;
}
const buffer = fs.readFileSync(path);
const chunks = [];
for (let i = 0; i < buffer.length; i += chunk_size) {
chunks.push(buffer.subarray(i, i + chunk_size));
}
console.log(`sending message to ${contact_id}: ${path} (${caption})`);
const contactPublicKeyNode = createPublicKey(contact.public_key);
const uuid = uuidv4();
chunks.forEach((buffer, index) => {
let cipher = {
id: uuid,
length: chunks.length,
index,
message: buffer,
};
if (index === chunks.length - 1) {
cipher.caption = caption;
cipher.filename = pathLibrary.basename(path);
}
cipher = contactPublicKeyNode.encrypt(JSON.stringify(cipher));
socket.emit('file_message', config.public_key, cipher);
});
db.addSendingPrivateFileMessage(uuid, contact, caption, path, 'NuLL');
finished();
});
}
/**
* @author mr-exception
* @description this method sends an audio message to contact
* @param {array} arguments
* @param {function} finished
*/
const sendAudioMessage = (arguments, finished) => {
const contact_id = arguments[0];
const path = arguments[1];
const caption = arguments.slice(2).join(' ');
validate_connection(contact_id, finished, (contact, socket) => {
if (!fs.existsSync(path)) {
console.log(chalk.red(`Err: audio ${path} not found`));
finished();
return;
}
const buffer = fs.readFileSync(path);
const chunks = [];
for (let i = 0; i < buffer.length; i += chunk_size) {
chunks.push(buffer.subarray(i, i + chunk_size));
}
console.log(`sending message to ${contact_id}: ${path} (${caption})`);
const contactPublicKeyNode = createPublicKey(contact.public_key);
const uuid = uuidv4();
chunks.forEach((buffer, index) => {
let cipher = {
id: uuid,
length: chunks.length,
index,
message: buffer,
};
if (index === chunks.length - 1) {
cipher.caption = caption;
cipher.filename = pathLibrary.basename(path);
}
cipher = contactPublicKeyNode.encrypt(JSON.stringify(cipher));
socket.emit('audio_message', config.public_key, cipher);
});
db.addSendingPrivateAudioMessage(uuid, contact, caption, path, 'NuLL');
finished();
});
}
/**
* @author mr-exception
* @description this method sends an movie message to contact
* @param {array} arguments
* @param {function} finished
*/
const sendMovieMessage = (arguments, finished) => {
const contact_id = arguments[0];
const path = arguments[1];
const caption = arguments.slice(2).join(' ');
validate_connection(contact_id, finished, (contact, socket) => {
if (!fs.existsSync(path)) {
console.log(chalk.red(`Err: movie ${path} not found`));
finished();
return;
}
const buffer = fs.readFileSync(path);
const chunks = [];
for (let i = 0; i < buffer.length; i += chunk_size) {
chunks.push(buffer.subarray(i, i + chunk_size));
}
console.log(`sending message to ${contact_id}: ${path} (${caption})`);
const contactPublicKeyNode = createPublicKey(contact.public_key);
const uuid = uuidv4();
chunks.forEach((buffer, index) => {
let cipher = {
id: uuid,
length: chunks.length,
index,
message: buffer,
};
if (index === chunks.length - 1) {
cipher.caption = caption;
cipher.filename = pathLibrary.basename(path);
}
cipher = contactPublicKeyNode.encrypt(JSON.stringify(cipher));
socket.emit('movie_message', config.public_key, cipher);
});
db.addSendingPrivateMovieMessage(uuid, contact, caption, path, 'NuLL');
finished();
});
}
/**
* @author mr-exception
* @description this method shows a single channel
* @param {array} arguments
* @param {function} finished
*/
const showConversation = (arguments, finished) => {
const contact_id = arguments[0];
const offset = arguments[1];
const limit = arguments[2];
db.getContact(contact_id,
contact => { // contact found
db.getConversation(contact.id, 1, limit, offset, (messages) => {
for (let i = messages.length - 1; i > -1; i--) {
const message = messages[i];
if (message.contact_id === 0) {
console.log(`${chalk.yellow('you')}: ${message.content}`);
} else {
db.getContact(message.contact_id,
contact => {
console.log(`${chalk.blue(contact.nickname)}: ${message.content}`);
}, () => {
// not found
}
);
}
}
finished();
}, () => {
console.log(chalk.red('Err: conversation not found.'));
finished();
});
},
() => { // contact not found
console.log(chalk.red(`Err: contact ${contact_id} not found`));
finished();
}
);
}
module.exports = {
showConversation,
sendTextMessage,
sendImageMessage,
sendAudioMessage,
sendFileMessage,
sendMovieMessage,
}