/**
*T his controller is in charge of handling requests relating to users friend system
* @module FriendsControler
* @category Backend
* @subcategory Controllers
*/
const {User, Notification} = require("../models/user");
var notification = require('../Notification/notification')
var notificationController = require('../controllers/notificationController')
const {emitReloadNotifications} = require("../sockets/sockets")
const SEND_FRIEND_REQUEST = 0;
const ANSWER_FRIEND_REQUEST = 1;
const UNFRIEND_REQUEST = 2;
function cmpIdsInList(list, user) {
if (list.filter(function(e) { return e.memberId === user._id; }).length > 0) {
return true;
}
return false;
}
// temporary function - delete later.
function assignImage(user){
if(!user) return "";
if(user.image) return user.image;
if(user.twitchData && user.twitchData.profile_image_url) return user.twitchData.profile_image_url;
if(user.facebookData && user.facebookData.photos) return user.facebookData.photos[0].value;
if(user.googleData && user.googleData.photos) return user.googleData.photos[0].value;
return "";
}
/**
* @brief handles friends related requests by delegating to appropriate methods/
* This function sends true if request was successfully processed, otherwise false.
*
* @param {*} req
* @param {*} res
*/
exports.handleFriendsRequest = function(req, res){
const fun = async() => {
const action = req.body.action;
console.log("Received friends request of type : " + action);
let status = false;
if( action == SEND_FRIEND_REQUEST )
{
status = await handleSendFriendRequest( req );
}
else if( action == ANSWER_FRIEND_REQUEST )
{
status = await handleAnswerFriendRequest2( req );
}
else if( action == UNFRIEND_REQUEST)
{
status = await handleUnfriendRequest( req );
}
else
{
console.log( "Unkown friends action type" );
status = false;
}
return status;
}
fun().then( status => {res.send(status);} )
}
async function handleSendFriendRequest( req )
{
let [fromUser, toUser] = await getUsersFromRequest( req );
console.log("Handling sendFriendRequest from users : " + fromUser.username + ", " + toUser.username)
// now check if fromUser already has toUser as friends or has pending request - verified only one side
if( cmpIdsInList( fromUser.friendsData.friendsList, toUser ) ||
cmpIdsInList( fromUser.friendsData.friendsList, toUser ) ) {
/* console.log("Cannot send request to this user, you already sent a request or he is your friend");*/
return false;
}
// now update fromUser and toUser data
try {
await User.updateOne(
{ _id: fromUser._id },
{ $push: { "friendsData.sentRequests": {
userId: toUser._id,
username: toUser.username,
} } }
).exec();
await User.updateOne(
{ _id: toUser._id },
{ $push: { "friendsData.receivedRequests": {
userId: fromUser._id,
username: fromUser.username
} } }
).exec();
}
catch (error) {
console.log("error occured in : <handleSendFriendRequest>")
console.log(error)
return false;
}
// update the client that he got unfriended
notification.notifyReceivedFriendRequest(fromUser, toUser)
// send on screen notification to client
const notificationData = new Notification({
type: "friendRequestReceived",
clearable: false,
data: {
userId: fromUser._id,
username: fromUser.username,
userImage: assignImage(fromUser)
}
})
notificationController.addNotificationToUser(toUser._id, notificationData, `Received friend request from ${fromUser.username}.` )
emitReloadNotifications(toUser._id, "");
emitReloadNotifications(fromUser._id, "")
return true;
}
async function handleAnswerFriendRequest2( req )
{
let [fromUser, toUser] = await getUsersFromRequest( req );
console.log("Handling handleAnswerFriendRequest from users : " + fromUser.username + ", " + toUser.username)
//console.log(fromUser)
//console.log(toUser)
// verify that toUser has a friend request from fromUser - verified only one side
//if( !(toUser.friendsData.receivedRequests.find(el=>toString(el.id)==toString(fromUser._id)) != undefined) ) {
if( cmpIdsInList( toUser.friendsData.friendsList, fromUser) ) {
console.log("Cant accept/reject someone who is not in received requests list");
return false;
}
// now update toUser and fromUser
if( req.body.accepted ) {
try {
await User.updateOne(
{ _id: fromUser._id },
{ $pull: { "friendsData.sentRequests": { userId: toUser._id } },
$push: { "friendsData.friendsList": {
value: toUser.username,
memberId: toUser._id,
youtubeId: toUser.youtubeId,
twitchId: toUser.twitchId,
displayName : toUser.username,
userImage : assignImage(toUser),
label: toUser.username,
/*
id: toUser._id,
username: toUser.username,*/
}}}
).exec();
await User.updateOne(
{ _id: toUser._id },
{ $pull: { "friendsData.receivedRequests": { userId: fromUser._id } },
$push: { "friendsData.friendsList": {
value: fromUser.username,
memberId: fromUser._id,
youtubeId: fromUser.youtubeId,
twitchId: fromUser.twitchId,
displayName : fromUser.username,
userImage : assignImage(fromUser),
label: fromUser.username,
/*id: fromUser._id,
username: fromUser.username,*/
}} }
).exec();
}
catch (error) {
console.log("error occured in : <handleAnswerFriendRequest>")
console.log(error)
return false;
}
// update the client that he got unfriended
notification.notifyFriendRequestAccepted(fromUser, toUser)
// send on screen notification that client got accepted
const notificationData = new Notification({
type: "friendRequestAccepted",
clearable: true,
data: {
userId: toUser._id,
username: toUser.username,
userImage: assignImage(toUser)
}
})
notificationController.addNotificationToUser(fromUser._id, notificationData, `${toUser.username} accepted your friend request.` )
}
else {
try {
await User.updateOne(
{ _id: fromUser._id },
{ $pull: { "friendsData.sentRequests": { userId: toUser._id } } }
).exec();
await User.updateOne(
{ _id: toUser._id },
{ $pull: { "friendsData.receivedRequests": { userId: fromUser._id } } }
).exec();
}
catch (error) {
console.log("error occured in : <handleAnswerFriendRequest>")
console.log(error)
return false;
}
// update the client that he got unfriended
notification.notifyFriendRequestDeclined(fromUser, toUser)
}
emitReloadNotifications(toUser._id, "");
emitReloadNotifications(fromUser._id, "")
return true;
}
async function handleUnfriendRequest( req )
{
let [fromUser, toUser] = await getUsersFromRequest( req );
console.log("Handling handleUnfriendRequest from users : " + fromUser.username + ", " + toUser.username)
//console.log(fromUser)
//console.log(toUser)
// verify that fromUser has toUser as a friend - verified only one side
if( !(fromUser.friendsData.friendsList.find(el=>toString(el.memberId)==toString(toUser._id)) != undefined) ) {
console.log("cant remove someone who is not a friend");
return false;
}
// update fromUser and toUser
try {
await User.updateOne(
{ _id: fromUser._id },
{ $pull: { "friendsData.friendsList": { memberId: toUser._id } } }
).exec();
await User.updateOne(
{ _id: toUser._id },
{ $pull: { "friendsData.friendsList": { memberId: fromUser._id } } }
).exec();
}
catch (error) {
console.log("error occured in : <handleUnfriendRequest>")
console.log(error)
return false;
}
// update the client that he got unfriended
notification.notifyUnfriendFriend(fromUser, toUser)
emitReloadNotifications(toUser._id, "");
emitReloadNotifications(fromUser._id, "")
return true;
}
async function getUsersFromRequest( req )
{
// get sender user
let fromUser = null;
let toUser = null;
try {
fromUser = await User.findOne({_id: req.body.fromUser}).exec();
}
catch (error) {
console.log("error occured in : <handleUnfriendRequest>")
return [fromUser, toUser];
}
// no need to call second query if one is bad
if( fromUser == null ) {
return [fromUser, toUser];
}
// get receiver user
try {
toUser = await User.findOne({_id: req.body.toUser}).exec();
}
catch (error) {
console.log("error occured in : <handleSendFriendRequest>")
return [fromUser, toUser];
}
return [fromUser, toUser];
}
Source