1 2 /** 3 * Function to return a JSON object containing the express router properties. 4 * @param {Object} req The express routing HTTP client request object. 5 * @param {Object} res The express routing HTTP client response object. 6 * @param {callback} next The express routing callback function to invoke next middleware in the stack. 7 * @return {Object} A JSON object that holds req, res, and next. 8 */ 9 var routerProperties = function(req, res, next) { 10 return { 11 req: req, 12 res: res, 13 next: next 14 }; 15 } 16 17 /** 18 * Function to search for all users meeting a criteria. 19 * The server returns a 404 error if no users matching criteria are found. 20 * @param {Object} properties JSON object containing the express router properties. 21 * @param {Object} criteria JSON object to determine the search criteria for the user(s) we wish to find. 22 * @param {callback} processUsers A callback function to be invoked on the resulting set of users found. 23 * @return {Void} 24 */ 25 var searchUsers = function(properties, criteria, results, processUsers) { 26 let req = properties.req; 27 let res = properties.res; 28 let next = properties.next; 29 30 let db = req.app.locals.db; 31 const userCollection = db.collection("Users"); 32 33 userCollection.find(criteria).toArray(function(err, users) { 34 if (err) { 35 next(err); 36 return; 37 } 38 if (users.length === 0) { 39 res.status(404).send(`Unable to find users that met search criteria`); 40 return; 41 } 42 processUsers(users, results); 43 }); 44 } 45 46 // var searchEvents = function(properties, criteria, processEvents) { 47 // let req = properties.req; 48 // let res = properties.res; 49 // let next = properties.next; 50 51 // let db = req.app.locals.db; 52 // const eventCollection = db.collection("Events"); 53 54 // eventCollection.find(criteria).toArray(function(err, events) { 55 // if (err) { 56 // next(err); 57 // return; 58 // } 59 // if (events.length === 0) { 60 // res.status(404).send(`Unable to find events that met search criteria`); 61 // return; 62 // } 63 // processEvents(events); 64 // }); 65 // } 66 67 // var searchActivities = function(properties, criteria, processActivities) { 68 // let req = properties.req; 69 // let res = properties.res; 70 // let next = properties.next; 71 72 // let db = req.app.locals.db; 73 // const activityCollection = db.collection("Activities"); 74 75 // activityCollection.find(criteria).toArray(function(err, activities) { 76 // if (err) { 77 // next(err); 78 // return; 79 // } 80 // if (activities.length === 0) { 81 // //res.status(404).send(`Unable to find activities that met search criteria`); 82 // return; 83 // } 84 // processActivities(activities); 85 // }); 86 // } 87 88 /** 89 * Function to return update a user's data in Users collection in MongoDB. 90 * The server returns a 404 error if unable to find a matching user in the database. 91 * Returns a 201 if it succesfully updates user data. 92 * @param {Object} properties JSON object containing the express router properties. 93 * @param {string} email The email of the user whose fields we wish to update. 94 * @param {Object} updateSet JSON object containing the data we wish to update. 95 * @return {Void} 96 */ 97 var updateUser = function(properties, email, updateSet) { 98 let req = properties.req; 99 let res = properties.res; 100 let next = properties.next; 101 102 let db = req.app.locals.db; 103 const userCollection = db.collection("Users"); 104 105 userCollection.findOne({"email": email}, function(err, resultUser) { 106 if (err) { 107 next(err); 108 return; 109 } 110 if (result.length === 0) { 111 res.status(404).send(`Unable to find user with email`); 112 return; 113 } 114 userCollection.updateOne({"email": email}, updateSet, function(err, updateResult) { 115 if (err) { 116 next(err); 117 return; 118 } 119 res.status(201).send(`Successfully updated user data`); 120 return; 121 }); 122 }); 123 } 124 125 /** 126 * Function to insert a new user into the Users collection in MongoDB. 127 * The server returns a 404 error if the email in the request body is already in use. 128 * Otherwise it creates a new user with the given userID and hashed password, 129 * default availabilities, and no activities or events, and adds it to the MongoDB database, 130 * returning a 201 status code. 131 * @param {Object} properties JSON object containing the express router properties. 132 * @param {string} name The name of the new user. 133 * @param {string} email The email of the new user. 134 * @param {string} password The password of the new user that is encrypted with bcrypt. 135 * @return {Void} 136 */ 137 var insertUser = function(properties, name, email, password) { 138 let req = properties.req; 139 let res = properties.res; 140 let next = properties.next; 141 142 let db = req.app.locals.db; 143 const userCollection = db.collection("Users"); 144 const valuesCollection = db.collection("Values"); 145 146 userCollection.find({"email": email}).toArray( 147 function(err, result) { 148 if (err) { 149 next(err); 150 return; 151 } 152 if (result.length !== 0) { 153 // res.status(404).send(`Email already in use`); 154 res.status(404).render('register', {err: 'Email already in use.'}); 155 return; 156 } 157 158 valuesCollection.find({"name": "Users"}).toArray(function(err, resId) { 159 if (err) { 160 next(err); 161 return; 162 } 163 let maxUserId = resId[0].maxUserId; 164 165 let defaultAvailability = []; 166 for (let i = 0; i < 7; i++) { 167 let week = []; 168 for (let j = 0; j < 48; j++) { 169 week.push(false); 170 } 171 defaultAvailability.push(week); 172 } 173 174 let newUser = { 175 userId: maxUserId, 176 name: name, 177 email: email, 178 password: password, 179 rating: { "scoreSum": 0, "numRatings": 0}, 180 activities: [], 181 availability: defaultAvailability, 182 events: [] 183 }; 184 userCollection.insertOne(newUser, function (err, insertResult) { 185 if (err) { 186 next(err); 187 return; 188 } 189 let newValue = {$set: {"maxUserId": maxUserId + 1}}; // this is buggy 190 valuesCollection.updateOne({"name": "Users"}, newValue, function(err, updateResult) { 191 if (err) { 192 next(err); 193 return; 194 } 195 196 res.redirect(`/active/profile/${newUser.userId}`); 197 return; 198 }); 199 }); 200 }); 201 return; 202 } 203 ); 204 } 205 206 207 208 /** 209 * Function to insert a new event into the Events collection in MongoDB. 210 * The server returns a 404 error if the event in the request body is already in use. 211 * Otherwise it creates a new event with the given , 212 * and adds it to the MongoDB database, 213 * returning a 201 status code. 214 * @param {Object} properties JSON object containing the express router properties. 215 * @param {string} email The email of the new user. 216 * @param {string} password The password of the new user that is encrypted with bcrypt. 217 * @return {Void} 218 */ 219 var insertEvent = function(properties, myUserId, friendUserId, activity, startTime, endTime, location) { 220 let req = properties.req; 221 let res = properties.res; 222 let next = properties.next; 223 224 let db = req.app.locals.db; 225 const eventCollection = db.collection("Events"); 226 const valuesCollection = db.collection("Values"); 227 228 var invitedIds = [myUserId, friendUserId]; 229 invitedIds.sort(); 230 231 232 eventCollection.find({"invitedIds": invitedIds, "activity": activity, "startTime": startTime, "endTime": endTime}).toArray( //check invitedIds, activity, startTime, endTime aren't in 233 function(err, result) { 234 if (err) { 235 next(err); 236 return; 237 } 238 if (result.length !== 0) { //event already exists 239 //res.status(404).send(`Event already in use`); 240 res.status(404).render('register', {err: 'Event already in use.'}); 241 return; 242 } 243 244 245 //console.log(valuesCollection); 246 valuesCollection.find({"name": "Users"}).toArray(function(err, resId) { //to get maxEventId for new eventId 247 if (err) { 248 next(err); 249 return; 250 } 251 console.log(resId); 252 // console.log(resId); 253 254 let maxEventId = resId[0].maxEventId; //grab maxEventId from Values collection 255 256 let newEvent = { 257 eventId: maxEventId, 258 acceptedIds: [], 259 invitedIds: invitedIds, 260 activity: activity, 261 startTime: startTime, 262 endTime: endTime, 263 status: "matched", 264 location: location 265 }; 266 eventCollection.insertOne(newEvent, function (err, insertResult) { //insert event to db 267 if (err) { 268 next(err); 269 return; 270 } 271 let newValue = {$set: {"maxEventId": maxEventId + 1}}; // this is buggy? 272 valuesCollection.updateOne({"name": "Events"}, newValue, function(err, updateResult) { //update maxEventId in Values collection 273 if (err) { 274 next(err); 275 return; 276 } 277 278 next(); 279 //res.redirect(`/active/match/${myUserId}`); 280 281 // res.status(201).render('match', { 282 // newEvent 283 // }); 284 return; 285 }); 286 }); 287 }); 288 return; 289 } 290 ); 291 } 292 293 294 295 module.exports = { 296 insertUser: insertUser, 297 insertEvent: insertEvent, 298 updateUser: updateUser, 299 searchUsers: searchUsers, 300 // searchActivities: searchActivities, 301 routerProperties: routerProperties 302 }; 303