Enhance session and profile handling with validation and error handling improvements
This commit is contained in:
@@ -15,7 +15,7 @@ userDB = (DB) => {
|
|||||||
DB.removeProfile = (profileid) => {
|
DB.removeProfile = (profileid) => {
|
||||||
const _id = DB.ObjectID(profileid);
|
const _id = DB.ObjectID(profileid);
|
||||||
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
||||||
return DB.profileCols.deleteOne({_id}).catch((err)=>{
|
return DB.profileCols.deleteOne({ _id }).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -23,7 +23,7 @@ userDB = (DB) => {
|
|||||||
|
|
||||||
DB.updateProfile = async (profileid, profileObj) => {
|
DB.updateProfile = async (profileid, profileObj) => {
|
||||||
let tempProfile = profileObj.toObj();
|
let tempProfile = profileObj.toObj();
|
||||||
const query = {_id: profileid};
|
const query = { _id: profileid };
|
||||||
const update = {
|
const update = {
|
||||||
$set: {
|
$set: {
|
||||||
profile: tempProfile.profile,
|
profile: tempProfile.profile,
|
||||||
@@ -39,8 +39,8 @@ userDB = (DB) => {
|
|||||||
|
|
||||||
DB.getProfile = async (profileId) => {
|
DB.getProfile = async (profileId) => {
|
||||||
//if (userProfileCache[profileId] && !userProfileCache[profileId].isGroup) return userProfileCache[profileId];
|
//if (userProfileCache[profileId] && !userProfileCache[profileId].isGroup) return userProfileCache[profileId];
|
||||||
if(!profileId) return false;
|
if (!profileId) return false;
|
||||||
try{
|
try {
|
||||||
const _id = DB.ObjectID(profileId);
|
const _id = DB.ObjectID(profileId);
|
||||||
let r = await DB.profileCols.findOne({ _id }).catch((err) => {
|
let r = await DB.profileCols.findOne({ _id }).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -48,7 +48,7 @@ userDB = (DB) => {
|
|||||||
});
|
});
|
||||||
if (r) userProfileCache[profileId] = r;
|
if (r) userProfileCache[profileId] = r;
|
||||||
return r;
|
return r;
|
||||||
}catch(_){
|
} catch (_) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,16 +56,16 @@ userDB = (DB) => {
|
|||||||
DB.getPopularProfiles = async (limit = 10) => {
|
DB.getPopularProfiles = async (limit = 10) => {
|
||||||
return DB.profileCols.aggregate([
|
return DB.profileCols.aggregate([
|
||||||
{
|
{
|
||||||
$match: {isGroup: {$ne: true}}
|
$match: { isGroup: { $ne: true } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$addFields: { subscribed_count: {$size: { "$ifNull": [ "$following", [] ] } } }
|
$addFields: { subscribed_count: { $size: { "$ifNull": ["$following", []] } } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$sort: {"subscribed_count":-1}
|
$sort: { "subscribed_count": -1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$project: {_id: 1, "subscribed_count": 1}
|
$project: { _id: 1, "subscribed_count": 1 }
|
||||||
}
|
}
|
||||||
]).limit(limit).toArray().catch((err) => {
|
]).limit(limit).toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -76,16 +76,16 @@ userDB = (DB) => {
|
|||||||
DB.getPopularGroups = async (limit = 10) => {
|
DB.getPopularGroups = async (limit = 10) => {
|
||||||
return DB.profileCols.aggregate([
|
return DB.profileCols.aggregate([
|
||||||
{
|
{
|
||||||
$match: {isGroup: true, isPrivate: {$ne: true}, isCourse: {$ne: true}}
|
$match: { isGroup: true, isPrivate: { $ne: true }, isCourse: { $ne: true } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$addFields: { subscribed_count: {$size: { "$ifNull": [ {"$objectToArray" : "$subscribed"}, [] ] } } }
|
$addFields: { subscribed_count: { $size: { "$ifNull": [{ "$objectToArray": "$subscribed" }, []] } } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$sort: {"subscribed_count":-1}
|
$sort: { "subscribed_count": -1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$project: {_id: 1, "subscribed_count": 1}
|
$project: { _id: 1, "subscribed_count": 1 }
|
||||||
}
|
}
|
||||||
]).limit(limit).toArray().catch((err) => {
|
]).limit(limit).toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -95,19 +95,19 @@ userDB = (DB) => {
|
|||||||
|
|
||||||
DB.getFriendsFriends = async (profileId, limit = 10) => {
|
DB.getFriendsFriends = async (profileId, limit = 10) => {
|
||||||
const profile = await DB.getProfile(profileId);
|
const profile = await DB.getProfile(profileId);
|
||||||
if(!profile) return [];
|
if (!profile) return [];
|
||||||
let ids = profile.following.map((id)=>DB.ObjectID(id));
|
let ids = profile.following.map((id) => DB.ObjectID(id));
|
||||||
let alreadyFollowingMap = {};
|
let alreadyFollowingMap = {};
|
||||||
alreadyFollowingMap[profileId] = 1; //skip that profile
|
alreadyFollowingMap[profileId] = 1; //skip that profile
|
||||||
profile.following.forEach(id => {
|
profile.following.forEach(id => {
|
||||||
if(!alreadyFollowingMap[id]) alreadyFollowingMap[id] = 1;
|
if (!alreadyFollowingMap[id]) alreadyFollowingMap[id] = 1;
|
||||||
})
|
})
|
||||||
return DB.profileCols.find({_id:{$in: ids}}).project({following: 1}).limit(limit).toArray().then(profiles => {
|
return DB.profileCols.find({ _id: { $in: ids } }).project({ following: 1 }).limit(limit).toArray().then(profiles => {
|
||||||
let friendsOfFriendsMap = {};
|
let friendsOfFriendsMap = {};
|
||||||
profiles.forEach(p => {
|
profiles.forEach(p => {
|
||||||
p.following.forEach(followingId => {
|
p.following.forEach(followingId => {
|
||||||
if(alreadyFollowingMap[followingId]) return 0;
|
if (alreadyFollowingMap[followingId]) return 0;
|
||||||
if(!friendsOfFriendsMap[followingId]) friendsOfFriendsMap[followingId] = 0;
|
if (!friendsOfFriendsMap[followingId]) friendsOfFriendsMap[followingId] = 0;
|
||||||
friendsOfFriendsMap[followingId] = friendsOfFriendsMap[followingId] + 1;
|
friendsOfFriendsMap[followingId] = friendsOfFriendsMap[followingId] + 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -124,24 +124,38 @@ userDB = (DB) => {
|
|||||||
return DB.getProfile(profileId);
|
return DB.getProfile(profileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DB.getProfileCache = async (profileId) => {
|
||||||
|
const cachedProfile = userProfileCache[profileId];
|
||||||
|
if (cachedProfile?.isGroup === false) {
|
||||||
|
return cachedProfile;
|
||||||
|
}
|
||||||
|
return await DB.getProfile(profileId);
|
||||||
|
};
|
||||||
|
|
||||||
DB.searchProfile = async (queryStr) => {
|
DB.searchProfile = async (queryStr) => {
|
||||||
let regEx = new RegExp(queryStr, 'i');
|
let regEx = new RegExp(queryStr, 'i');
|
||||||
let query = {
|
let query = {
|
||||||
isGroup: false,
|
isGroup: false,
|
||||||
isChat: {$ne: true},
|
isChat: { $ne: true },
|
||||||
$or: [
|
$or: [
|
||||||
{"profile.firstName": {
|
{
|
||||||
|
"profile.firstName": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}},
|
}
|
||||||
{"profile.lastName": {
|
},
|
||||||
|
{
|
||||||
|
"profile.lastName": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}},
|
}
|
||||||
{"profile.description": {
|
},
|
||||||
|
{
|
||||||
|
"profile.description": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}},
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
let r = await DB.profileCols.find(queryStr ? query : {isGroup: false, isChat: {$ne: true}})
|
let r = await DB.profileCols.find(queryStr ? query : { isGroup: false, isChat: { $ne: true } })
|
||||||
.sort({ lastUpdate: -1 }).limit(20)
|
.sort({ lastUpdate: -1 }).limit(20)
|
||||||
.toArray().catch((err) => {
|
.toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -154,7 +168,7 @@ userDB = (DB) => {
|
|||||||
const userid = DB.ObjectID(userId);
|
const userid = DB.ObjectID(userId);
|
||||||
return await DB.profileCols.find({ userid }).toArray().catch((err) => {
|
return await DB.profileCols.find({ userid }).toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return [];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,32 +181,32 @@ userDB = (DB) => {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
let index = 0;
|
let index = 0;
|
||||||
while(r[index].isGroup || r[index].isChat) index += 1;
|
while (r[index].isGroup || r[index].isChat) index += 1;
|
||||||
if (r[index]) userProfileCache[r[index]._id] = r[index];
|
if (r[index]) userProfileCache[r[index]._id] = r[index];
|
||||||
return r[index];
|
return r[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
DB.followProfile = async (profileId, followProfileId)=>{
|
DB.followProfile = async (profileId, followProfileId) => {
|
||||||
const _id = DB.ObjectID(profileId);
|
const _id = DB.ObjectID(profileId);
|
||||||
let update = {
|
let update = {
|
||||||
$addToSet:{
|
$addToSet: {
|
||||||
following: followProfileId + '' //converts to str
|
following: followProfileId + '' //converts to str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DB.unfollowProfile = async (profileId, followProfileId)=>{
|
DB.unfollowProfile = async (profileId, followProfileId) => {
|
||||||
const _id = DB.ObjectID(profileId);
|
const _id = DB.ObjectID(profileId);
|
||||||
let update = {
|
let update = {
|
||||||
$pull:{
|
$pull: {
|
||||||
following: followProfileId + '' //converts to str
|
following: followProfileId + '' //converts to str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -200,7 +214,7 @@ userDB = (DB) => {
|
|||||||
|
|
||||||
DB.getFollowingTheProfile = async (profileId) => {
|
DB.getFollowingTheProfile = async (profileId) => {
|
||||||
//const profile_id = DB.ObjectID(profileId);
|
//const profile_id = DB.ObjectID(profileId);
|
||||||
let r = await DB.profileCols.find({ following: (profileId+'') })
|
let r = await DB.profileCols.find({ following: (profileId + '') })
|
||||||
.toArray().catch((err) => {
|
.toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return [];
|
return [];
|
||||||
@@ -216,40 +230,40 @@ userDB = (DB) => {
|
|||||||
DB.setData = async (profileid, key, value) => {
|
DB.setData = async (profileid, key, value) => {
|
||||||
const _id = DB.ObjectID(profileid);
|
const _id = DB.ObjectID(profileid);
|
||||||
let update = {
|
let update = {
|
||||||
$set:{
|
$set: {
|
||||||
["data." + key]: value
|
["data." + key]: value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DB.setProfileToken = (profileid, token)=>{
|
DB.setProfileToken = (profileid, token) => {
|
||||||
if(!token) return false;
|
if (!token) return false;
|
||||||
const _id = DB.ObjectID(profileid);
|
const _id = DB.ObjectID(profileid);
|
||||||
let update = {
|
let update = {
|
||||||
$addToSet:{
|
$addToSet: {
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DB.setWebSubscription = (profileid, webSubscription)=>{
|
DB.setWebSubscription = (profileid, webSubscription) => {
|
||||||
const _id = DB.ObjectID(profileid);
|
const _id = DB.ObjectID(profileid);
|
||||||
let update = {
|
let update = {
|
||||||
$set:{
|
$set: {
|
||||||
webSubscription
|
webSubscription
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -258,7 +272,7 @@ userDB = (DB) => {
|
|||||||
DB.addNotification = async (profileid, message, postid, commentIndx, actorid) => {
|
DB.addNotification = async (profileid, message, postid, commentIndx, actorid) => {
|
||||||
const _id = DB.ObjectID(profileid);
|
const _id = DB.ObjectID(profileid);
|
||||||
let update = {
|
let update = {
|
||||||
$push:{
|
$push: {
|
||||||
notifications: {
|
notifications: {
|
||||||
ts: new Date(),
|
ts: new Date(),
|
||||||
body: message,
|
body: message,
|
||||||
@@ -268,7 +282,7 @@ userDB = (DB) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -283,10 +297,10 @@ userDB = (DB) => {
|
|||||||
DB.getGroups = async (excludePrivate = false) => {
|
DB.getGroups = async (excludePrivate = false) => {
|
||||||
let query = {
|
let query = {
|
||||||
isGroup: true,
|
isGroup: true,
|
||||||
isCourse: {$ne: true},
|
isCourse: { $ne: true },
|
||||||
isChat: {$ne: true},
|
isChat: { $ne: true },
|
||||||
};
|
};
|
||||||
if(excludePrivate) query.isPrivate = false;
|
if (excludePrivate) query.isPrivate = false;
|
||||||
let r = await DB.profileCols.find(query).sort({ lastUpdate: -1 }).limit(10)
|
let r = await DB.profileCols.find(query).sort({ lastUpdate: -1 }).limit(10)
|
||||||
.toArray().catch((err) => {
|
.toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -298,21 +312,21 @@ userDB = (DB) => {
|
|||||||
DB.getFollowingGroups = async (profileid) => {
|
DB.getFollowingGroups = async (profileid) => {
|
||||||
const profile = await DB.getProfile(profileid);
|
const profile = await DB.getProfile(profileid);
|
||||||
let ids = [];
|
let ids = [];
|
||||||
for(id in profile.following){
|
for (id in profile.following) {
|
||||||
try{
|
try {
|
||||||
let oId = DB.ObjectID(profile.following[id]);
|
let oId = DB.ObjectID(profile.following[id]);
|
||||||
let checkProfile = await DB.getProfileCache(oId)
|
let checkProfile = await DB.getProfileCache(oId)
|
||||||
if(checkProfile && checkProfile.isGroup && !checkProfile.isChat){
|
if (checkProfile && checkProfile.isGroup && !checkProfile.isChat) {
|
||||||
ids.push(oId)
|
ids.push(oId)
|
||||||
}
|
}
|
||||||
}catch{
|
} catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let query = {
|
let query = {
|
||||||
isGroup: true,
|
isGroup: true,
|
||||||
isCourse: {$ne: true},
|
isCourse: { $ne: true },
|
||||||
isChat: {$ne: true},
|
isChat: { $ne: true },
|
||||||
_id: {
|
_id: {
|
||||||
$in: ids
|
$in: ids
|
||||||
}
|
}
|
||||||
@@ -329,23 +343,31 @@ userDB = (DB) => {
|
|||||||
let regEx = new RegExp(queryStr, 'i');
|
let regEx = new RegExp(queryStr, 'i');
|
||||||
let query = queryStr ? {
|
let query = queryStr ? {
|
||||||
isGroup: true,
|
isGroup: true,
|
||||||
isChat: {$ne: true},
|
isChat: { $ne: true },
|
||||||
isCourse: coursesB,
|
isCourse: coursesB,
|
||||||
$or: [
|
$or: [
|
||||||
{"profile.firstName": {
|
{
|
||||||
|
"profile.firstName": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}},
|
}
|
||||||
{"profile.lastName": {
|
},
|
||||||
|
{
|
||||||
|
"profile.lastName": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}},
|
}
|
||||||
{"profile.description": {
|
},
|
||||||
|
{
|
||||||
|
"profile.description": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}},
|
}
|
||||||
{"data.author": {
|
},
|
||||||
|
{
|
||||||
|
"data.author": {
|
||||||
$regex: regEx
|
$regex: regEx
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
} : {isGroup: true, isChat: {$ne: true}, isCourse: coursesB};
|
} : { isGroup: true, isChat: { $ne: true }, isCourse: coursesB };
|
||||||
let r = await DB.profileCols.find(query)
|
let r = await DB.profileCols.find(query)
|
||||||
.sort({ lastUpdate: -1 }).limit(20)
|
.sort({ lastUpdate: -1 }).limit(20)
|
||||||
.toArray().catch((err) => {
|
.toArray().catch((err) => {
|
||||||
@@ -357,13 +379,13 @@ userDB = (DB) => {
|
|||||||
|
|
||||||
let privateGroupsCache = {};
|
let privateGroupsCache = {};
|
||||||
DB.isGroupPrivate = async (groupid) => {
|
DB.isGroupPrivate = async (groupid) => {
|
||||||
if(userProfileCache[groupid]) return userProfileCache[groupid].isPrivate;
|
if (userProfileCache[groupid]) return userProfileCache[groupid].isPrivate;
|
||||||
let g = await DB.getGroup(groupid);
|
let g = await DB.getGroup(groupid);
|
||||||
return g ? g.isPrivate : false;
|
return g ? g.isPrivate : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DB.isGroupNewsOnly = async (groupid) => {
|
DB.isGroupNewsOnly = async (groupid) => {
|
||||||
if(userProfileCache[groupid]) return userProfileCache[groupid].newsOnly;
|
if (userProfileCache[groupid]) return userProfileCache[groupid].newsOnly;
|
||||||
let g = await DB.getGroup(groupid);
|
let g = await DB.getGroup(groupid);
|
||||||
return g ? g.newsOnly : false;
|
return g ? g.newsOnly : false;
|
||||||
}
|
}
|
||||||
@@ -377,7 +399,7 @@ userDB = (DB) => {
|
|||||||
DB.getGroup = async (groupid) => {
|
DB.getGroup = async (groupid) => {
|
||||||
const _id = DB.ObjectID(groupid);
|
const _id = DB.ObjectID(groupid);
|
||||||
//if(userProfileCache[groupid]) return userProfileCache[groupid];
|
//if(userProfileCache[groupid]) return userProfileCache[groupid];
|
||||||
let r = await DB.profileCols.findOne({_id, isGroup: true, isChat: {$ne: true},}).catch((err) => {
|
let r = await DB.profileCols.findOne({ _id, isGroup: true, isChat: { $ne: true }, }).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -389,13 +411,13 @@ userDB = (DB) => {
|
|||||||
const _id = DB.ObjectID(groupid);
|
const _id = DB.ObjectID(groupid);
|
||||||
const subOrRequest = reqSubscription ? "pending." : "subscribed.";
|
const subOrRequest = reqSubscription ? "pending." : "subscribed.";
|
||||||
let update = {
|
let update = {
|
||||||
$set:{
|
$set: {
|
||||||
[subOrRequest + profileid]: new Date()
|
[subOrRequest + profileid]: new Date()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!reqSubscription) DB.followProfile(profileid, groupid);
|
if (!reqSubscription) DB.followProfile(profileid, groupid);
|
||||||
delete userProfileCache[groupid];
|
delete userProfileCache[groupid];
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -404,16 +426,16 @@ userDB = (DB) => {
|
|||||||
DB.acceptGroupJoinReq = async (profileid, groupid) => {
|
DB.acceptGroupJoinReq = async (profileid, groupid) => {
|
||||||
const _id = DB.ObjectID(groupid);
|
const _id = DB.ObjectID(groupid);
|
||||||
let update = {
|
let update = {
|
||||||
$set:{
|
$set: {
|
||||||
["subscribed." + profileid]: new Date()
|
["subscribed." + profileid]: new Date()
|
||||||
},
|
},
|
||||||
$unset:{
|
$unset: {
|
||||||
["pending." + profileid]: ""
|
["pending." + profileid]: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DB.followProfile(profileid, groupid);
|
DB.followProfile(profileid, groupid);
|
||||||
delete userProfileCache[groupid];
|
delete userProfileCache[groupid];
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -422,12 +444,12 @@ userDB = (DB) => {
|
|||||||
DB.rejectGroupJoinReq = async (profileid, groupid) => {
|
DB.rejectGroupJoinReq = async (profileid, groupid) => {
|
||||||
const _id = DB.ObjectID(groupid);
|
const _id = DB.ObjectID(groupid);
|
||||||
let update = {
|
let update = {
|
||||||
$unset:{
|
$unset: {
|
||||||
["pending." + profileid]: ""
|
["pending." + profileid]: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete userProfileCache[groupid];
|
delete userProfileCache[groupid];
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -436,12 +458,12 @@ userDB = (DB) => {
|
|||||||
DB.unsubscribeToGroup = async (profileid, groupid) => {
|
DB.unsubscribeToGroup = async (profileid, groupid) => {
|
||||||
const _id = DB.ObjectID(groupid);
|
const _id = DB.ObjectID(groupid);
|
||||||
let update = {
|
let update = {
|
||||||
$unset:{
|
$unset: {
|
||||||
["subscribed." + profileid]: "",
|
["subscribed." + profileid]: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DB.unfollowProfile(profileid, groupid)
|
DB.unfollowProfile(profileid, groupid)
|
||||||
return DB.profileCols.updateOne({_id}, update).catch((err)=>{
|
return DB.profileCols.updateOne({ _id }, update).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -449,7 +471,7 @@ userDB = (DB) => {
|
|||||||
|
|
||||||
//Courses
|
//Courses
|
||||||
DB.getCourses = async () => {
|
DB.getCourses = async () => {
|
||||||
let r = await DB.profileCols.find({isGroup: true, isCourse: true, isChat: {$ne: true}})
|
let r = await DB.profileCols.find({ isGroup: true, isCourse: true, isChat: { $ne: true } })
|
||||||
.sort({ lastUpdate: -1 }).limit(20)
|
.sort({ lastUpdate: -1 }).limit(20)
|
||||||
.toArray().catch((err) => {
|
.toArray().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
class User {
|
class User {
|
||||||
constructor(info){
|
constructor(info){
|
||||||
if(!info || !info.userid) throw "Can not construct empty profile";
|
if(!info || !info.userid) throw new Error("Cannot construct empty profile");
|
||||||
this.userid = info.userid;
|
this.userid = info.userid;
|
||||||
this.profile = {
|
this.profile = {
|
||||||
firstName: info.profile && info.profile.firstName || '',
|
firstName: info.profile?.firstName || '',
|
||||||
lastName: info.profile && info.profile.lastName || '',
|
lastName: info.profile?.lastName || '',
|
||||||
photo: info.profile && info.profile.photo || '',
|
photo: info.profile?.photo || '',
|
||||||
location: info.profile && info.profile.location || 'USA',
|
location: info.profile?.location || 'USA',
|
||||||
language: info.profile && info.profile.language || 'en',
|
language: info.profile?.language || 'en',
|
||||||
status: info.profile && info.profile.status || '',
|
status: info.profile?.status || '',
|
||||||
description: info.profile && info.profile.description || '',
|
description: info.profile?.description || '',
|
||||||
};
|
};
|
||||||
this.data = info.data || {};
|
this.data = info.data || {};
|
||||||
this.username = info.username || '';
|
this.username = info.username || '';
|
||||||
@@ -23,8 +23,8 @@ class User {
|
|||||||
this.isCourse = info.isCourse || false;
|
this.isCourse = info.isCourse || false;
|
||||||
this.isPrivate = info.isPrivate || false;
|
this.isPrivate = info.isPrivate || false;
|
||||||
this.isChat = info.isChat || false;
|
this.isChat = info.isChat || false;
|
||||||
this.subscribed = info.subscribed || {}; //Subscribed user to groups
|
this.subscribed = JSON.parse(JSON.stringify(info.subscribed || {})); //Subscribed user to groups
|
||||||
this.pending = info.pending || {}; //Private groups require authorization
|
this.pending = JSON.parse(JSON.stringify(info.pending || {})); //Private groups require authorization
|
||||||
}
|
}
|
||||||
|
|
||||||
toObj(){
|
toObj(){
|
||||||
|
|||||||
@@ -4,26 +4,18 @@ var router = express.Router()
|
|||||||
const DB = require("../mongoDB.js");
|
const DB = require("../mongoDB.js");
|
||||||
const Profile = require("../def/profile.js");
|
const Profile = require("../def/profile.js");
|
||||||
const Notifications = require("./../notifications.js");
|
const Notifications = require("./../notifications.js");
|
||||||
|
const { getSessionId, getUserId, getProfileId } = require("./../utils/sessionUtils.js");
|
||||||
|
|
||||||
DB.getDB.then((DB)=>{
|
DB.getDB.then((DB) => {
|
||||||
|
|
||||||
const getUserId = function(req){
|
|
||||||
const user_sid = req.cookies.user_sid || req.query.user_sid || req.body.user_sid;
|
|
||||||
return DB.ObjectID(user_sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
const getProfileId = (req)=>{
|
|
||||||
return DB.ObjectID(req.cookies.profile_id || req.query.profile_id || req.body.profile_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const profileBelongsToUser = async (profileid, userid) => {
|
const profileBelongsToUser = async (profileid, userid) => {
|
||||||
const profile = await DB.getProfileCache(profileid);
|
const profile = await DB.getProfileCache(profileid);
|
||||||
if(!profile) return false;
|
if (!profile) return false;
|
||||||
return profile.userid == (userid + '');
|
return profile.userid === String(userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
router.get("/mine", async (req, res) => {
|
router.get("/mine", async (req, res) => {
|
||||||
let userid = req.cookies.user_sid;
|
let userid = getUserId(req);
|
||||||
let profiles = await DB.getUserProfiles(userid);
|
let profiles = await DB.getUserProfiles(userid);
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "ok",
|
status: "ok",
|
||||||
@@ -34,59 +26,84 @@ DB.getDB.then((DB)=>{
|
|||||||
router.get("/new", async (req, res) => { //Deprecated please use route post("/")
|
router.get("/new", async (req, res) => { //Deprecated please use route post("/")
|
||||||
let profile = {
|
let profile = {
|
||||||
userid: getUserId(req),
|
userid: getUserId(req),
|
||||||
... req.query.content
|
...req.query.content
|
||||||
};
|
};
|
||||||
let profileObj = new Profile(profile);
|
let profileObj = new Profile(profile);
|
||||||
let r = await DB.newProfile(profileObj);
|
let r = await DB.newProfile(profileObj);
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "ok",
|
status: "ok",
|
||||||
... profileObj.toObj()
|
...profileObj.toObj()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/", async (req, res) => {
|
router.post("/", async (req, res) => {
|
||||||
let profile = {
|
let profile = {
|
||||||
userid: getUserId(req),
|
userid: getUserId(req),
|
||||||
... req.body.content
|
...req.body.content
|
||||||
};
|
};
|
||||||
|
try {
|
||||||
let profileObj = new Profile(profile);
|
let profileObj = new Profile(profile);
|
||||||
let r = await DB.newProfile(profileObj);
|
let r = await DB.newProfile(profileObj);
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "ok",
|
status: "ok",
|
||||||
... profileObj.toObj()
|
...profileObj.toObj()
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating profile", error);
|
||||||
|
return res.json({
|
||||||
|
status: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/invite", async (req, res) => {
|
router.post("/invite", async (req, res) => {
|
||||||
|
try {
|
||||||
const userid = getUserId(req);
|
const userid = getUserId(req);
|
||||||
const name = req.body.name;
|
let { name, email } = req.body; // Destructuring for clarity
|
||||||
const email = req.body.email;
|
// Validate required fields
|
||||||
//validate email?
|
if (!name || !email) {
|
||||||
if(!name || !email) return res.json({status: "incomplete request"});
|
return res.status(400).json({ status: "Name and email are required" });
|
||||||
|
}
|
||||||
|
// Validate email format
|
||||||
|
email = email.trim().toLowerCase()
|
||||||
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
if (!emailRegex.test(email)) {
|
||||||
|
return res.status(400).json({ status: "Invalid email format" });
|
||||||
|
}
|
||||||
|
// Create new invitation, this returns a string if failed
|
||||||
let r = await DB.newInvitation(userid, name, email);
|
let r = await DB.newInvitation(userid, name, email);
|
||||||
if(!r.toLowerCase){
|
if (r instanceof String) {
|
||||||
//send email invitation
|
// Handle failure response from DB.newInvitation
|
||||||
let senderProfile = await DB.getProfile(getProfileId(req));
|
return res.status(400).json({
|
||||||
Notifications.youHaveAnInvitation(name, email, senderProfile);
|
status: r,
|
||||||
return res.json({
|
message: `Failed to send invitation: ${r}`
|
||||||
status: "ok"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.json({
|
// Handle response from DB.newInvitation
|
||||||
status: r
|
// Send email invitation
|
||||||
|
let senderProfile = await DB.getProfile(getProfileId(req));
|
||||||
|
Notifications.youHaveAnInvitation(name, email, senderProfile);
|
||||||
|
return res.status(200).json({
|
||||||
|
status: "ok",
|
||||||
|
message: `Invitation sent to ${name} (${email})`
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error during invitation process:", error);
|
||||||
|
return res.status(500).json({ status: "error", message: "Something went wrong, please try again later" });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/invite/:email", async (req, res) => {
|
router.get("/invite/:email", async (req, res) => {
|
||||||
const userid = getUserId(req);
|
const userid = getUserId(req);
|
||||||
const email = req.params.email;
|
const email = req.params.email;
|
||||||
//validate email?
|
//validate email?
|
||||||
if(!email) return res.json({status: "provide valid email"});
|
if (!email) return res.json({ status: "provide valid email" });
|
||||||
let r = await DB.getInvitation(email);
|
let r = await DB.getInvitation(email);
|
||||||
if(!r) return res.json({status: "no invitation found with that email"});
|
if (!r) return res.json({ status: "no invitation found with that email" });
|
||||||
let isUserAlreadyRegistered = await DB.getUser(email);
|
let isUserAlreadyRegistered = await DB.getUser(email);
|
||||||
if(isUserAlreadyRegistered && isUserAlreadyRegistered._id) return res.json({status: "This user is already registered"});
|
if (isUserAlreadyRegistered && isUserAlreadyRegistered._id) return res.json({ status: "This user is already registered" });
|
||||||
return res.json({status: "ok", ... r});
|
return res.json({ status: "ok", ...r });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/groups", async (req, res) => {
|
router.get("/groups", async (req, res) => {
|
||||||
@@ -110,13 +127,13 @@ DB.getDB.then((DB)=>{
|
|||||||
let profile = {
|
let profile = {
|
||||||
userid: getUserId(req),
|
userid: getUserId(req),
|
||||||
isGroup: true,
|
isGroup: true,
|
||||||
... req.body
|
...req.body
|
||||||
};
|
};
|
||||||
let profileObj = new Profile(profile);
|
let profileObj = new Profile(profile);
|
||||||
DB.newProfile(profileObj)
|
DB.newProfile(profileObj)
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "ok",
|
status: "ok",
|
||||||
... profileObj.toObj()
|
...profileObj.toObj()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -133,7 +150,7 @@ DB.getDB.then((DB)=>{
|
|||||||
//of an user that attempt to join a private group.
|
//of an user that attempt to join a private group.
|
||||||
const groupid = getProfileId(req); //It needs to have this profile context
|
const groupid = getProfileId(req); //It needs to have this profile context
|
||||||
const groupidBody = req.body.groupid ? DB.ObjectID(req.body.groupid) : undefined;
|
const groupidBody = req.body.groupid ? DB.ObjectID(req.body.groupid) : undefined;
|
||||||
if(groupidBody && groupid != groupidBody && !DB.isOwnerOfGroup(groupid, groupidBody)){
|
if (groupidBody && groupid != groupidBody && !DB.isOwnerOfGroup(groupid, groupidBody)) {
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "Only group owner can accept new subscribers"
|
status: "Only group owner can accept new subscribers"
|
||||||
});
|
});
|
||||||
@@ -152,7 +169,7 @@ DB.getDB.then((DB)=>{
|
|||||||
//of an user that attempt to join a private group.
|
//of an user that attempt to join a private group.
|
||||||
const groupid = getProfileId(req); //It needs to have this profile context
|
const groupid = getProfileId(req); //It needs to have this profile context
|
||||||
const groupidBody = req.body.groupid ? DB.ObjectID(req.body.groupid) : undefined;
|
const groupidBody = req.body.groupid ? DB.ObjectID(req.body.groupid) : undefined;
|
||||||
if(groupidBody && groupid != groupidBody && !DB.isOwnerOfGroup(groupid, groupidBody)){
|
if (groupidBody && groupid != groupidBody && !DB.isOwnerOfGroup(groupid, groupidBody)) {
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "Only group owner can reject new subscribers"
|
status: "Only group owner can reject new subscribers"
|
||||||
});
|
});
|
||||||
@@ -191,7 +208,7 @@ DB.getDB.then((DB)=>{
|
|||||||
const isPrivate = await DB.isGroupPrivate(groupid);
|
const isPrivate = await DB.isGroupPrivate(groupid);
|
||||||
DB.subscribeToGroup(profileid, groupid, isPrivate);
|
DB.subscribeToGroup(profileid, groupid, isPrivate);
|
||||||
//Add notification to group owner
|
//Add notification to group owner
|
||||||
if(isPrivate) Notifications.yourGroupHasARequest(profileid, groupid)
|
if (isPrivate) Notifications.yourGroupHasARequest(profileid, groupid)
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "ok"
|
status: "ok"
|
||||||
});
|
});
|
||||||
@@ -244,14 +261,14 @@ DB.getDB.then((DB)=>{
|
|||||||
let profile = await DB.getProfile(profileId);
|
let profile = await DB.getProfile(profileId);
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "ok",
|
status: "ok",
|
||||||
... profile
|
...profile
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.delete("/:id", async (req, res) => {
|
router.delete("/:id", async (req, res) => {
|
||||||
const profileId = req.params.id;
|
const profileId = req.params.id;
|
||||||
const userid = getUserId(req);
|
const userid = getUserId(req);
|
||||||
if(!await profileBelongsToUser(profileId, userid))
|
if (!await profileBelongsToUser(profileId, userid))
|
||||||
return res.json({
|
return res.json({
|
||||||
status: "This profile is not yours."
|
status: "This profile is not yours."
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,31 @@
|
|||||||
|
const { ObjectId } = require("mongodb");
|
||||||
|
|
||||||
|
const isValidObjectId = (id) => ObjectId.isValid(id);
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
const getSessionId = function (req) {
|
const getSessionId = function (req) {
|
||||||
const session_id = req.cookies.session_id || req.query.session_id || req.body.session_id;
|
const session_id = req.cookies.session_id || req.query.session_id || req.body.session_id;
|
||||||
|
if(isValidObjectId(session_id)) {
|
||||||
|
return session_id;
|
||||||
|
}
|
||||||
|
console.error("Invalid session_id format: ", session_id);
|
||||||
return session_id;
|
return session_id;
|
||||||
}
|
}
|
||||||
const getUserId = function (req) {
|
const getUserId = function (req) {
|
||||||
const user_sid = req.cookies.user_sid || req.query.user_sid || req.body.user_sid;
|
const user_sid = req.cookies.user_sid || req.query.user_sid || req.body.user_sid;
|
||||||
|
// validate user_sid
|
||||||
|
if(isValidObjectId(user_sid)) {
|
||||||
|
return user_sid;
|
||||||
|
}
|
||||||
|
console.error("Invalid user_sid format: ", user_sid);
|
||||||
return user_sid;
|
return user_sid;
|
||||||
}
|
}
|
||||||
const getProfileId = function (req) {
|
const getProfileId = function (req) {
|
||||||
const profile_id = req.cookies.profile_id || req.query.profile_id || req.body.profile_id;
|
const profile_id = req.cookies.profile_id || req.query.profile_id || req.body.profile_id;
|
||||||
|
if(isValidObjectId(profile_id)) {
|
||||||
|
return profile_id;
|
||||||
|
}
|
||||||
|
console.error("Invalid profile_id format: ", profile_id);
|
||||||
return profile_id;
|
return profile_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user