diff --git a/app/client/src/services/UserService.js b/app/client/src/services/UserService.js index 23f5092c2..dfa2c1d01 100644 --- a/app/client/src/services/UserService.js +++ b/app/client/src/services/UserService.js @@ -1,105 +1,107 @@ -angular.module('reg') - .factory('UserService', [ - '$http', - 'Session', - function($http, Session){ - - var users = '/api/users'; - var base = users + '/'; +angular.module("reg").factory("UserService", [ + "$http", + "Session", + function($http, Session) { + var users = "/api/users"; + var base = users + "/"; return { - // ---------------------- // Basic Actions // ---------------------- - getCurrentUser: function(){ - return Session.getUserId() ? $http.get(base + Session.getUserId()) : ''; + getCurrentUser: function() { + return Session.getUserId() ? $http.get(base + Session.getUserId()) : ""; }, - get: function(id){ + get: function(id) { return $http.get(base + id); }, - getAll: function(){ + getByEmail: function(email) { + return $http.get(base + "email/" + email); + }, + + getAll: function() { return $http.get(base); }, - getPage: function(page, size, text){ - return $http.get(users + '?' + $.param( - { - text: text, - page: page ? page : 0, - size: size ? size : 50 - }) + getPage: function(page, size, text) { + return $http.get( + users + + "?" + + $.param({ + text: text, + page: page ? page : 0, + size: size ? size : 50 + }) ); }, - updateProfile: function(id, profile){ - profile.name = profile.firstname + ' ' + profile.lastname; - - return $http.put(base + id + '/profile', { + updateProfile: function(id, profile) { + profile.name = profile.firstname + " " + profile.lastname; + + return $http.put(base + id + "/profile", { profile: profile }); }, - updateConfirmation: function(id, confirmation){ - return $http.put(base + id + '/confirm', { + updateConfirmation: function(id, confirmation) { + return $http.put(base + id + "/confirm", { confirmation: confirmation }); }, - declineAdmission: function(id){ - return $http.post(base + id + '/decline'); + declineAdmission: function(id) { + return $http.post(base + id + "/decline"); }, // ------------------------- // Admin Only // ------------------------- - getStats: function(){ - return $http.get(base + 'stats'); + getStats: function() { + return $http.get(base + "stats"); }, - getQueue: function(){ - return $http.get(base + 'viewQueue'); + getQueue: function() { + return $http.get(base + "viewQueue"); }, - addQueue: function(id){ - return $http.post(base + id + '/queue') - }, - - removeQueue: function(id){ - return $http.delete(base + id + '/queue'); + addQueue: function(id) { + return $http.post(base + id + "/queue"); }, - admitQueue: function(id){ - return $http.post(base + 'acceptQueue'); + removeQueue: function(id) { + return $http.delete(base + id + "/queue"); }, - - admitUser: function(id){ - return $http.post(base + id + '/admit'); + + admitQueue: function(id) { + return $http.post(base + "acceptQueue"); }, - checkIn: function(id){ - return $http.post(base + id + '/checkin'); + admitUser: function(id) { + return $http.post(base + id + "/admit"); }, - checkOut: function(id){ - return $http.post(base + id + '/checkout'); + checkIn: function(id) { + return $http.post(base + id + "/checkin"); }, - markWaiverAsSigned: function(id){ - return $http.post(base + id + '/sign'); + checkOut: function(id) { + return $http.post(base + id + "/checkout"); }, - sendAdmittedEmail: function(){ - return $http.post(base + 'emailAdmitted'); + markWaiverAsSigned: function(id) { + return $http.post(base + id + "/sign"); }, - sendWaiverEmail: function(id){ - return $http.post(base + id + '/sendwaiver'); + sendAdmittedEmail: function() { + return $http.post(base + "emailAdmitted"); }, + sendWaiverEmail: function(id) { + return $http.post(base + id + "/sendwaiver"); + } }; } - ]); +]); diff --git a/app/client/views/admin/queue/adminQueueCtrl.js b/app/client/views/admin/queue/adminQueueCtrl.js index 9eb94277e..f738e6282 100644 --- a/app/client/views/admin/queue/adminQueueCtrl.js +++ b/app/client/views/admin/queue/adminQueueCtrl.js @@ -1,54 +1,52 @@ -angular.module('reg') - .controller('AdminQueueCtrl',[ - '$scope', - '$state', - '$stateParams', - 'UserService', - '$http', - '$window', - function($scope, $state, $stateParams, UserService, $http, $window){ - $scope.stats = []; - $scope.users = []; - $scope.displayedUsers = []; - $scope.queryText = ""; - - // Semantic-UI moves modal content into a dimmer at the top level. - // While this is usually nice, it means that with our routing will generate - // multiple modals if you change state. Kill the top level dimmer node on initial load - // to prevent this. - $('.ui.dimmer').remove(); +angular.module("reg").controller("AdminQueueCtrl", [ + "$scope", + "$state", + "$stateParams", + "UserService", + "$http", + "$window", + function($scope, $state, $stateParams, UserService, $http, $window) { + $scope.stats = []; + $scope.users = []; + $scope.displayedUsers = []; + $scope.queryText = ""; - $scope.$watch("queryText", function(queryText) { - $scope.filterUsers(queryText); - }) + // Semantic-UI moves modal content into a dimmer at the top level. + // While this is usually nice, it means that with our routing will generate + // multiple modals if you change state. Kill the top level dimmer node on initial load + // to prevent this. + $(".ui.dimmer").remove(); - $scope.filterUsers = function(queryText) { - $scope.displayedUsers = [] + $scope.$watch("queryText", function(queryText) { + $scope.filterUsers(queryText); + }); - if (queryText === "") { - $scope.displayedUsers = $scope.users; - return; - } + $scope.filterUsers = function(queryText) { + $scope.displayedUsers = []; - $scope.users.forEach(function(user) { - var queryLowerCase = queryText.toLowerCase(); - var nameLowerCase = user.profile.name.toLowerCase(); - if(nameLowerCase.indexOf(queryLowerCase) > -1) { - $scope.displayedUsers.push(user); - } - }); + if (queryText === "") { + $scope.displayedUsers = $scope.users; + return; } - UserService - .getQueue() - .success(function(data) { - $scope.stats = data.stats; - $scope.users = data.users; - $scope.displayedUsers = $scope.users; - }); + $scope.users.forEach(function(user) { + var queryLowerCase = queryText.toLowerCase(); + var nameLowerCase = user.profile.name.toLowerCase(); + if (nameLowerCase.indexOf(queryLowerCase) > -1) { + $scope.displayedUsers.push(user); + } + }); + }; - $scope.acceptAllFromQueue = function($event, user, index) { - swal({ + UserService.getQueue().success(function(data) { + $scope.stats = data.stats; + $scope.users = data.users; + $scope.displayedUsers = $scope.users; + }); + + $scope.acceptAllFromQueue = function($event, user, index) { + swal( + { title: "Whoa, wait a minute!", text: "You are about to accept all users from the queue!", type: "warning", @@ -56,57 +54,132 @@ angular.module('reg') confirmButtonColor: "#DD6B55", confirmButtonText: "Yes, accept them.", closeOnConfirm: false - }, function() { - - swal({ + }, + function() { + swal( + { title: "Are you sure?", - text: "Your account will be logged as having accepted all users from the queue. " + + text: + "Your account will be logged as having accepted all users from the queue. " + "Remember, this power is a privilege.", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText: "Yes, accept the queued users.", closeOnConfirm: false - }, function() { - - UserService - .admitQueue() - .success(function(user) { - $scope.users[index] = user; - swal("Accepted", "All queued users have been accepted!", "success"); - }); - + }, + function() { + UserService.admitQueue().success(function(user) { + $scope.users[index] = user; + swal( + "Accepted", + "All queued users have been accepted!", + "success" + ); }); + } + ); + } + ); + }; - }); - } - - $scope.removeFromQueue = function($event, user, index) { - $event.stopPropagation(); + $scope.removeFromQueue = function($event, user, index) { + $event.stopPropagation(); - swal({ + swal( + { title: "Whoa, wait a minute!", - text: "You are about to remove " + user.profile.name + " from the queue!", + text: + "You are about to remove " + user.profile.name + " from the queue!", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText: "Yes, remove them.", closeOnConfirm: false - }, function() { - UserService - .removeQueue(user._id) - .success(function(user) { - $scope.users[index] = user; - swal("Removed", user.profile.name + ' has been removed from the queue.', "success"); - }); + }, + function() { + UserService.removeQueue(user._id).success(function(user) { + $scope.users[index] = user; + swal( + "Removed", + user.profile.name + " has been removed from the queue.", + "success" + ); }); - } + } + ); + }; - $scope.goUser = function($event, user) { - $event.stopPropagation(); + $scope.goUser = function($event, user) { + $event.stopPropagation(); - $state.go('app.admin.user', { - id: user._id + $state.go("app.admin.user", { + id: user._id + }); + }; + + $scope.addToQueue = function() { + if (!$scope.queuelist || $scope.queuelist === "") { + return; + } + var emailList = $scope.queuelist.split("\n"); + var getEmailPromises = []; + var addQueuePromises = []; + + for (index in emailList) { + const email = emailList[index]; + const getEmailPromise = UserService.getByEmail(email).then(function( + response + ) { + return response.data; + }); + getEmailPromises.push(getEmailPromise); + } + Promise.all(getEmailPromises) + .then(function(values) { + for (index in values) { + const user = values[index]; + const addQueuePromise = UserService.addQueue(user._id).then( + returnUser => { + if (returnUser.data === null) { + throw { + message: "User not verified", + email: user.email + }; + } + } + ); + addQueuePromises.push(addQueuePromise); + } + }) + .then(() => { + return Promise.all(addQueuePromises) + .then(function() { + swal({ + title: "Queued", + text: "All users have been queued!", + type: "success", + timer: 500 + }); + }) + .catch(errorData => { + swal({ + title: errorData.email + " failed to be queued", + text: errorData.message, + type: "error", + timer: 750 + }); + }); + }) + .catch(errorData => { + swal({ + title: errorData.data.email + " not found", + text: errorData.data.message, + type: "error", + timer: 1000 + }); + return errorData; }); - }; - }]); \ No newline at end of file + }; + } +]); diff --git a/app/client/views/admin/queue/queue.html b/app/client/views/admin/queue/queue.html index c2c556ac1..2290cd149 100644 --- a/app/client/views/admin/queue/queue.html +++ b/app/client/views/admin/queue/queue.html @@ -57,6 +57,28 @@ +
+
+
+ Multi Queue +
+
+
+ +
+
+
+ Add +
+
+
+
+
diff --git a/app/server/controllers/UserController.js b/app/server/controllers/UserController.js index faf83eda8..77531933d 100644 --- a/app/server/controllers/UserController.js +++ b/app/server/controllers/UserController.js @@ -1,17 +1,17 @@ -var _ = require('underscore'); -var User = require('../models/User'); -var Settings = require('../models/Settings'); -var Mailer = require('../services/sendgrid_email'); -var Stats = require('../services/stats'); +var _ = require("underscore"); +var User = require("../models/User"); +var Settings = require("../models/Settings"); +var Mailer = require("../services/sendgrid_email"); +var Stats = require("../services/stats"); // var Waiver = require('../services/waiver'); -var validator = require('validator'); -var moment = require('moment'); +var validator = require("validator"); +var moment = require("moment"); var UserController = {}; // Tests a string if it ends with target s -function endsWith(s, test){ +function endsWith(s, test) { return test.indexOf(s, test.length - s.length) !== -1; } @@ -21,27 +21,30 @@ function endsWith(s, test){ * @param {Function} callback args(err, true, false) * @return {[type]} [description] */ -function canRegister(email, password, callback){ - - if (!password || password.length < 6){ - return callback({ message: "Password must be 6 or more characters."}, false); +function canRegister(email, password, callback) { + if (!password || password.length < 6) { + return callback( + { message: "Password must be 6 or more characters." }, + false + ); } // Check if its within the registration window. - Settings.getRegistrationTimes(function(err, times){ + Settings.getRegistrationTimes(function(err, times) { if (err) { callback(err); } var now = Date.now(); - if (now < times.timeOpen){ + if (now < times.timeOpen) { return callback({ - message: "Registration opens in " + moment(times.timeOpen).fromNow() + "!" + message: + "Registration opens in " + moment(times.timeOpen).fromNow() + "!" }); } - if (now > times.timeClose){ + if (now > times.timeClose) { return callback({ message: "Sorry, registration is closed." }); @@ -49,7 +52,7 @@ function canRegister(email, password, callback){ if (!validator.isEmail(email)) { return callback({ - message: 'Not a valid email.' + message: "Not a valid email." }); } @@ -62,8 +65,8 @@ function canRegister(email, password, callback){ * @param {String} token auth token * @param {Function} callback args(err, token, user) */ -UserController.loginWithToken = function(token, callback){ - User.getByToken(token, function(err, user){ +UserController.loginWithToken = function(token, callback) { + User.getByToken(token, function(err, user) { return callback(err, token, user); }); }; @@ -74,24 +77,22 @@ UserController.loginWithToken = function(token, callback){ * @param {String} password Password * @param {Function} callback args(err, token, user) */ -UserController.loginWithPassword = function(email, password, callback){ - - if (!password || password.length === 0){ +UserController.loginWithPassword = function(email, password, callback) { + if (!password || password.length === 0) { return callback({ - message: 'Please enter a password' + message: "Please enter a password" }); } - if (!validator.isEmail(email)){ + if (!validator.isEmail(email)) { return callback({ - message: 'Invalid email' + message: "Invalid email" }); } - User - .findOneByEmail(email) - .select('+password') - .exec(function(err, user){ + User.findOneByEmail(email) + .select("+password") + .exec(function(err, user) { if (err) { return callback(err); } @@ -114,7 +115,7 @@ UserController.loginWithPassword = function(email, password, callback){ delete u.password; return callback(null, token, u); - }); + }); }; /** @@ -124,14 +125,14 @@ UserController.loginWithPassword = function(email, password, callback){ * @param {Object} profile Profile object * @param {Function} callback args(err, user) */ -UserController.createValidUser = function(email, password, profile, callback){ - User.validateProfile(profile, function(err){ - if (err){ - return callback({message: 'invalid profile'}); +UserController.createValidUser = function(email, password, profile, callback) { + User.validateProfile(profile, function(err) { + if (err) { + return callback({ message: "invalid profile" }); } UserController.createUser(email, password, profile, callback); }); -}; +}; /** * Create a new user given an email and a password. @@ -140,8 +141,7 @@ UserController.createValidUser = function(email, password, profile, callback){ * @param {Function} callback args(err, user) */ UserController.createUser = function(email, password, profile, callback) { - - if (typeof email !== "string"){ + if (typeof email !== "string") { return callback({ message: "Email must be a string." }); @@ -150,9 +150,8 @@ UserController.createUser = function(email, password, profile, callback) { email = email.toLowerCase(); // Check that there isn't a user with this email already. - canRegister(email, password, function(err, valid){ - - if (err || !valid){ + canRegister(email, password, function(err, valid) { + if (err || !valid) { return callback(err); } @@ -162,12 +161,15 @@ UserController.createUser = function(email, password, profile, callback) { u.lastUpdated = Date.now(); u.profile = profile; u.status.completedProfile = true; - u.save(function(err){ - if (err){ + u.save(function(err) { + if (err) { // Duplicate key error codes - if (err.name === 'MongoError' && (err.code === 11000 || err.code === 11001)) { + if ( + err.name === "MongoError" && + (err.code === 11000 || err.code === 11001) + ) { return callback({ - message: 'An account for this email already exists.' + message: "An account for this email already exists." }); } @@ -180,29 +182,40 @@ UserController.createUser = function(email, password, profile, callback) { var verificationToken = u.generateEmailVerificationToken(); Mailer.sendVerificationEmail(email, verificationToken); - return callback( - null, - { - token: token, - user: u - } - ); + return callback(null, { + token: token, + user: u + }); } - }); }); }; -UserController.getByToken = function (token, callback) { +UserController.getByToken = function(token, callback) { User.getByToken(token, callback); }; +UserController.getByEmail = function(email, callback) { + User.findOneByEmail(email).exec(function(err, user) { + if (err) { + return callback({ err }); + } + if (!user) { + return callback({ + email: email, + message: "We couldn't find you!" + }); + } + return callback(null, user); + }); +}; + /** * Get all users. * It's going to be a lot of data, so make sure you want to do this. * @param {Function} callback args(err, user) */ -UserController.getAll = function (callback) { +UserController.getAll = function(callback) { User.find({}, callback); }; @@ -212,38 +225,36 @@ UserController.getAll = function (callback) { * @param {[type]} size size of the page * @param {Function} callback args(err, {users, page, totalPages}) */ -UserController.getPage = function(query, callback){ +UserController.getPage = function(query, callback) { var page = query.page; var size = parseInt(query.size); var searchText = query.text; var findQuery = {}; - if (searchText.length > 0){ + if (searchText.length > 0) { var queries = []; - var re = new RegExp(searchText, 'i'); + var re = new RegExp(searchText, "i"); queries.push({ email: re }); - queries.push({ 'profile.name': re }); - queries.push({ 'profile.school': re }); + queries.push({ "profile.name": re }); + queries.push({ "profile.school": re }); findQuery.$or = queries; } - User - .find(findQuery) + User.find(findQuery) .sort({ - 'profile.name': 'asc' + "profile.name": "asc" }) - .select('+status.admittedBy') + .select("+status.admittedBy") .skip(page * size) .limit(size) - .exec(function (err, users){ - if (err || !users){ + .exec(function(err, users) { + if (err || !users) { return callback(err); } - User.count(findQuery).exec(function(err, count){ - - if (err){ + User.count(findQuery).exec(function(err, count) { + if (err) { return callback(err); } @@ -255,7 +266,6 @@ UserController.getPage = function(query, callback){ totalPages: Math.ceil(count / size) }); }); - }); }; @@ -264,7 +274,7 @@ UserController.getPage = function(query, callback){ * @param {String} id User id * @param {Function} callback args(err, user) */ -UserController.getById = function (id, callback){ +UserController.getById = function(id, callback) { User.findById(id, callback); }; @@ -275,52 +285,52 @@ UserController.getById = function (id, callback){ * @param {Object} profile Profile object * @param {Function} callback Callback with args (err, user) */ -UserController.updateProfileById = function (id, profile, callback){ - +UserController.updateProfileById = function(id, profile, callback) { // Validate the user profile, and mark the user as profile completed // when successful. - User.validateProfile(profile, function(err){ - - if (err){ - return callback({message: 'invalid profile'}); + User.validateProfile(profile, function(err) { + if (err) { + return callback({ message: "invalid profile" }); } // Check if its within the registration window. - Settings.getRegistrationTimes(function(err, times){ + Settings.getRegistrationTimes(function(err, times) { if (err) { callback(err); } var now = Date.now(); - if (now < times.timeOpen){ + if (now < times.timeOpen) { return callback({ - message: "Registration opens in " + moment(times.timeOpen).fromNow() + "!" + message: + "Registration opens in " + moment(times.timeOpen).fromNow() + "!" }); } - if (now > times.timeClose){ + if (now > times.timeClose) { return callback({ message: "Sorry, registration is closed." }); } }); - User.findOneAndUpdate({ - _id: id - }, + User.findOneAndUpdate( + { + _id: id + }, { $set: { - 'lastUpdated': Date.now(), - 'profile': profile, - 'status.completedProfile': true + lastUpdated: Date.now(), + profile: profile, + "status.completedProfile": true } }, { new: true }, - callback); - + callback + ); }); }; @@ -331,61 +341,73 @@ UserController.updateProfileById = function (id, profile, callback){ * @param {Object} confirmation Confirmation object * @param {Function} callback Callback with args (err, user) */ -UserController.updateConfirmationById = function (id, confirmation, callback){ - - User.findById(id, function(err, user){ - - if(err || !user){ +UserController.updateConfirmationById = function(id, confirmation, callback) { + User.findById(id, function(err, user) { + if (err || !user) { return callback(err); } // Make sure that the user followed the deadline, but if they're already confirmed // that's okay. - if (Date.now() >= user.status.confirmBy && !user.status.confirmed){ + if (Date.now() >= user.status.confirmBy && !user.status.confirmed) { return callback({ message: "You've missed the confirmation deadline." }); } // You can only confirm acceptance if you're admitted and haven't declined. - User.findOneAndUpdate({ - '_id': id, - 'status.admitted': true, - 'status.declined': {$ne: true} - }, + User.findOneAndUpdate( + { + _id: id, + "status.admitted": true, + "status.declined": { $ne: true } + }, { $set: { - 'lastUpdated': Date.now(), - 'confirmation': confirmation, - 'status.confirmed': true, + lastUpdated: Date.now(), + confirmation: confirmation, + "status.confirmed": true } - }, { + }, + { new: true - }, function(err, user){ - if (!err && user && typeof user.confirmation.signatureLiability === 'undefined') { - Mailer.sendWaiverEmail(user.email, user.profile.firstname, (err, info) => { - if (!err) { - User.findOneAndUpdate({ - '_id': id - }, - { - $set: { - 'lastUpdated': Date.now(), - 'confirmation.signatureLiability': '' - } - }, { - new: true - }, - callback); - } else { - return callback(err, user); + }, + function(err, user) { + if ( + !err && + user && + typeof user.confirmation.signatureLiability === "undefined" + ) { + Mailer.sendWaiverEmail( + user.email, + user.profile.firstname, + (err, info) => { + if (!err) { + User.findOneAndUpdate( + { + _id: id + }, + { + $set: { + lastUpdated: Date.now(), + "confirmation.signatureLiability": "" + } + }, + { + new: true + }, + callback + ); + } else { + return callback(err, user); + } } - }); + ); } else { return callback(err, user); } - }); - + } + ); }); }; @@ -395,25 +417,27 @@ UserController.updateConfirmationById = function (id, confirmation, callback){ * @param {String} id Id of the user * @param {Function} callback Callback with args (err, user) */ -UserController.declineById = function (id, callback){ - +UserController.declineById = function(id, callback) { // You can only decline if you've been accepted. - User.findOneAndUpdate({ - '_id': id, - 'verified': true, - 'status.admitted': true, - 'status.declined': false - }, + User.findOneAndUpdate( + { + _id: id, + verified: true, + "status.admitted": true, + "status.declined": false + }, { $set: { - 'lastUpdated': Date.now(), - 'status.confirmed': false, - 'status.declined': true + lastUpdated: Date.now(), + "status.confirmed": false, + "status.declined": true } - }, { + }, + { new: true }, - callback); + callback + ); }; /** @@ -421,19 +445,23 @@ UserController.declineById = function (id, callback){ * @param {[type]} token token * @param {Function} callback args(err, user) */ -UserController.verifyByToken = function(token, callback){ - User.verifyEmailVerificationToken(token, function(err, email){ +UserController.verifyByToken = function(token, callback) { + User.verifyEmailVerificationToken(token, function(err, email) { if (email) { - User.findOneAndUpdate({ - email: email.toLowerCase() - },{ - $set: { - 'verified': true - } - }, { - new: true - }, - callback); + User.findOneAndUpdate( + { + email: email.toLowerCase() + }, + { + $set: { + verified: true + } + }, + { + new: true + }, + callback + ); } }); }; @@ -441,20 +469,21 @@ UserController.verifyByToken = function(token, callback){ /** * Resend an email verification email given a user id. */ -UserController.sendVerificationEmailById = function(id, callback){ +UserController.sendVerificationEmailById = function(id, callback) { User.findOne( { _id: id, verified: false }, - function(err, user){ - if (err || !user){ + function(err, user) { + if (err || !user) { return callback(err); } var token = user.generateEmailVerificationToken(); Mailer.sendVerificationEmail(user.email, token); return callback(err, user); - }); + } + ); }; /** @@ -463,17 +492,20 @@ UserController.sendVerificationEmailById = function(id, callback){ * @param {Function} callback [description] * @return {[type]} [description] */ -UserController.sendPasswordResetEmail = function(email, callback){ - User - .findOneByEmail(email) - .exec(function(err, user){ - if (err || !user){ - return callback(err); - } +UserController.sendPasswordResetEmail = function(email, callback) { + User.findOneByEmail(email).exec(function(err, user) { + if (err || !user) { + return callback(err); + } - var token = user.generateTempAuthToken(); - Mailer.sendPasswordResetEmail(email, user.profile.firstname, token, callback); - }); + var token = user.generateTempAuthToken(); + Mailer.sendPasswordResetEmail( + email, + user.profile.firstname, + token, + callback + ); + }); }; /** @@ -485,31 +517,39 @@ UserController.sendPasswordResetEmail = function(email, callback){ * @param {[type]} newPassword new password * @param {Function} callback args(err, user) */ -UserController.changePassword = function(id, oldPassword, newPassword, callback){ - if (!id || !oldPassword || !newPassword){ +UserController.changePassword = function( + id, + oldPassword, + newPassword, + callback +) { + if (!id || !oldPassword || !newPassword) { return callback({ - message: 'Bad arguments.' + message: "Bad arguments." }); } - User - .findById(id) - .select('password') - .exec(function(err, user){ + User.findById(id) + .select("password") + .exec(function(err, user) { if (user.checkPassword(oldPassword)) { - User.findOneAndUpdate({ - _id: id - },{ - $set: { - password: User.generateHash(newPassword) - } - }, { - new: true - }, - callback); + User.findOneAndUpdate( + { + _id: id + }, + { + $set: { + password: User.generateHash(newPassword) + } + }, + { + new: true + }, + callback + ); } else { return callback({ - message: 'Incorrect password' + message: "Incorrect password" }); } }); @@ -521,42 +561,44 @@ UserController.changePassword = function(id, oldPassword, newPassword, callback) * @param {String} password New Password * @param {Function} callback args(err, user) */ -UserController.resetPassword = function(token, password, callback){ - if (!password || !token){ +UserController.resetPassword = function(token, password, callback) { + if (!password || !token) { return callback({ - message: 'Bad arguments' + message: "Bad arguments" }); } - if (password.length < 6){ + if (password.length < 6) { return callback({ - message: 'Password must be 6 or more characters.' + message: "Password must be 6 or more characters." }); } - User.verifyTempAuthToken(token, function(err, id){ - - if(err || !id){ + User.verifyTempAuthToken(token, function(err, id) { + if (err || !id) { return callback(err); } - User - .findOneAndUpdate({ + User.findOneAndUpdate( + { _id: id - },{ + }, + { $set: { password: User.generateHash(password) } - }, function(err, user){ - if (err || !user){ + }, + function(err, user) { + if (err || !user) { return callback(err); } Mailer.sendPasswordChangedEmail(user.email, user.profile.firstname); return callback(null, { - message: 'Password successfully reset!' + message: "Password successfully reset!" }); - }); + } + ); }); }; @@ -568,21 +610,24 @@ UserController.resetPassword = function(token, password, callback){ * @param {String} user User doing the admitting * @param {Function} callback args(err, user) */ -UserController.admitUser = function(id, user, callback){ - Settings.getRegistrationTimes(function(err, times){ - User - .findOneAndUpdate({ +UserController.admitUser = function(id, user, callback) { + Settings.getRegistrationTimes(function(err, times) { + User.findOneAndUpdate( + { _id: id - },{ + }, + { $set: { - 'status.admitted': true, - 'status.admittedBy': user.email, - 'status.confirmBy': times.timeConfirm + "status.admitted": true, + "status.admittedBy": user.email, + "status.confirmBy": times.timeConfirm } - }, { + }, + { new: true }, - callback); + callback + ); }); }; @@ -594,21 +639,24 @@ UserController.admitUser = function(id, user, callback){ * @param {String} user User doing the admitting * @param {Function} callback args(err, user) */ -UserController.admitUserByEmail = function(email, user, callback){ - Settings.getRegistrationTimes(function(err, times){ - User - .findOneAndUpdate({ +UserController.admitUserByEmail = function(email, user, callback) { + Settings.getRegistrationTimes(function(err, times) { + User.findOneAndUpdate( + { email: email - },{ + }, + { $set: { - 'status.admitted': true, - 'status.admittedBy': user.email, - 'status.confirmBy': times.timeConfirm + "status.admitted": true, + "status.admittedBy": user.email, + "status.confirmBy": times.timeConfirm } - }, { + }, + { new: true }, - callback); + callback + ); }); }; @@ -620,18 +668,22 @@ UserController.admitUserByEmail = function(email, user, callback){ * @param {String} user User checking in this person. * @param {Function} callback args(err, user) */ -UserController.checkInById = function(id, user, callback){ - User.findOneAndUpdate({ - _id: id - },{ - $set: { - 'status.checkedIn': true, - 'status.checkInTime': Date.now() - } - }, { - new: true - }, - callback); +UserController.checkInById = function(id, user, callback) { + User.findOneAndUpdate( + { + _id: id + }, + { + $set: { + "status.checkedIn": true, + "status.checkInTime": Date.now() + } + }, + { + new: true + }, + callback + ); }; /** @@ -642,242 +694,280 @@ UserController.checkInById = function(id, user, callback){ * @param {String} user User checking in this person. * @param {Function} callback args(err, user) */ -UserController.checkOutById = function(id, user, callback){ - User.findOneAndUpdate({ - _id: id - },{ - $set: { - 'status.checkedIn': false - } - }, { - new: true - }, - callback); +UserController.checkOutById = function(id, user, callback) { + User.findOneAndUpdate( + { + _id: id + }, + { + $set: { + "status.checkedIn": false + } + }, + { + new: true + }, + callback + ); }; - /** * [ADMIN ONLY] */ - /** - * Send the acceptance email to the participant by their ID. - * @param {[type]} ID [description] - * @param {Function} callback [description] - */ +/** + * Send the acceptance email to the participant by their ID. + * @param {[type]} ID [description] + * @param {Function} callback [description] + */ UserController.sendAcceptanceEmailById = function(id, callback) { - User.findOne( - { - _id: id, - verified: true - }, - function(err, user) { - if (err || !user) { - return callback(err); - } - Mailer.sendAcceptanceEmail(user.email, user.profile.firstname, user.status.confirmBy, callback); - return callback(err, user); - }); - }; - - /** + User.findOne( + { + _id: id, + verified: true + }, + function(err, user) { + if (err || !user) { + return callback(err); + } + Mailer.sendAcceptanceEmail( + user.email, + user.profile.firstname, + user.status.confirmBy, + callback + ); + return callback(err, user); + } + ); +}; + +/** * [ADMIN ONLY] */ - /** - * Send the acceptance email to the participant by their email. - * @param {[type]} ID [description] - * @param {Function} callback [description] - */ +/** + * Send the acceptance email to the participant by their email. + * @param {[type]} ID [description] + * @param {Function} callback [description] + */ UserController.sendAcceptanceEmailByEmail = function(email, callback) { - email = email.toLowerCase(); - User.findOne( - { - email: email - }, - function(err, user) { - if (err || !user) { - return callback(err || 'no user'); - } - Mailer.sendAcceptanceEmail(email, user.profile.firstname, user.status.confirmBy, callback); - }); - }; + email = email.toLowerCase(); + User.findOne( + { + email: email + }, + function(err, user) { + if (err || !user) { + return callback(err || "no user"); + } + Mailer.sendAcceptanceEmail( + email, + user.profile.firstname, + user.status.confirmBy, + callback + ); + } + ); +}; UserController.markWaiverAsSigned = function(email, callback) { - User.findOneAndUpdate({ - 'email': email, - 'status.admitted': true - },{ - $set: { - 'lastUpdated': Date.now(), - 'confirmation.signatureLiability': Date.now() - } - }, { - new: true - }, - callback); + User.findOneAndUpdate( + { + email: email, + "status.admitted": true + }, + { + $set: { + lastUpdated: Date.now(), + "confirmation.signatureLiability": Date.now() + } + }, + { + new: true + }, + callback + ); }; UserController.sendWaiverEmail = function(id, callback) { - User.findById(id, function(err, user){ - - if(err || !user){ + User.findById(id, function(err, user) { + if (err || !user) { return callback(err); } - if (typeof user.confirmation.signatureLiability === 'undefined') { - Mailer.sendWaiverEmail(user.email, user.profile.firstname, (err, info) => { - if (!err) { - User.findOneAndUpdate({ - '_id': id - }, - { - $set: { - 'lastUpdated': Date.now(), - 'confirmation.signatureLiability': '' - } - }, { - new: true - }, - callback); - } else { - return callback(err); + if (typeof user.confirmation.signatureLiability === "undefined") { + Mailer.sendWaiverEmail( + user.email, + user.profile.firstname, + (err, info) => { + if (!err) { + User.findOneAndUpdate( + { + _id: id + }, + { + $set: { + lastUpdated: Date.now(), + "confirmation.signatureLiability": "" + } + }, + { + new: true + }, + callback + ); + } else { + return callback(err); + } } - }); + ); } else { - Mailer.sendWaiverEmail(user.email, user.profile.firstname, (err, info) => { - return callback(err, info); - }); + Mailer.sendWaiverEmail( + user.email, + user.profile.firstname, + (err, info) => { + return callback(err, info); + } + ); } - }); }; -UserController.getStats = function(callback){ +UserController.getStats = function(callback) { return callback(null, Stats.getUserStats()); }; -UserController.addUserAcceptedQueue = function(id, callback){ - User.findOneAndUpdate({ - _id: id, - 'verified': true, - 'status.admitted': false, - 'status.completedProfile': true, - 'status.queued': { $in : [0, null]} - },{ - $set: { - 'status.queued': Date.now(), - } - }, - { - new: true - }, - callback); +UserController.addUserAcceptedQueue = function(id, callback) { + User.findOneAndUpdate( + { + _id: id, + verified: true, + "status.admitted": false, + "status.completedProfile": true, + "status.queued": { $in: [0, null] } + }, + { + $set: { + "status.queued": Date.now() + } + }, + { + new: true + }, + callback + ); }; -UserController.removeUserAcceptedQueue = function(id, callback){ - User.findOneAndUpdate({ - _id: id, - 'status.queued' : {$gt: 0} - },{ - $set: { - 'status.queued': 0 - } - }, - { - new: true - }, - callback); +UserController.removeUserAcceptedQueue = function(id, callback) { + User.findOneAndUpdate( + { + _id: id, + "status.queued": { $gt: 0 } + }, + { + $set: { + "status.queued": 0 + } + }, + { + new: true + }, + callback + ); }; -UserController.emailAcceptanceToAdmitted = function(callback){ - User - .find({ - 'status.admitted': true, - 'status.notified': false, - 'status.declined': false, - 'status.confirmed': false - }) - .exec(function (err, users){ - if (err || !users){ +UserController.emailAcceptanceToAdmitted = function(callback) { + User.find({ + "status.admitted": true, + "status.notified": false, + "status.declined": false, + "status.confirmed": false + }).exec(function(err, users) { + if (err || !users) { return callback(err); } - users.forEach(function(user){ - Mailer.sendAcceptanceEmail(user.email, user.profile.firstname, user.status.confirmBy, function(err, data){ - if(err){ - return callback(err,{user}); - } - user.status.notified = true; - user.markModified('status'); - user.save(function(err){ - if(err){ - return callback(err,{user}); + users.forEach(function(user) { + Mailer.sendAcceptanceEmail( + user.email, + user.profile.firstname, + user.status.confirmBy, + function(err, data) { + if (err) { + return callback(err, { user }); } - }); - }); + user.status.notified = true; + user.markModified("status"); + user.save(function(err) { + if (err) { + return callback(err, { user }); + } + }); + } + ); }); - return callback(null, {users}); + return callback(null, { users }); }); }; -UserController.acceptAllInAcceptedQueue = function(admitterEmail, callback){ - Settings.getRegistrationTimes(function(err, times){ - User - .updateMany({ - 'status.queued' : {$gt: 0}, - 'status.admitted' : false, - 'status.completedProfile': true - },{ - $set: { - 'status.admitted': true, - 'status.admittedBy': admitterEmail, - 'status.confirmBy': times.timeConfirm, - 'status.queued': 0, - 'status.notified': false - } - }, - callback); +UserController.acceptAllInAcceptedQueue = function(admitterEmail, callback) { + Settings.getRegistrationTimes(function(err, times) { + User.updateMany( + { + "status.queued": { $gt: 0 }, + "status.admitted": false, + "status.completedProfile": true + }, + { + $set: { + "status.admitted": true, + "status.admittedBy": admitterEmail, + "status.confirmBy": times.timeConfirm, + "status.queued": 0, + "status.notified": false + } + }, + callback + ); }); }; -UserController.viewAcceptedQueue = function(callback){ - User - .find({ - 'status.queued' : {$gt: 0}, - 'status.admitted' : false - }) - .sort({ - 'status.queued': 'asc' +UserController.viewAcceptedQueue = function(callback) { + User.find({ + "status.queued": { $gt: 0 }, + "status.admitted": false }) - .exec(function (err, users){ - if (err || !users){ - return callback(err); - } - queueStats = { - gender: {}, - school: {}, - year: {} - }; - users.forEach(function(user){ - if(user.profile.gender in queueStats.gender){ - queueStats.gender[user.profile.gender] += 1; - } else { - queueStats.gender[user.profile.gender] = 1; - } - if(user.profile.school in queueStats.school){ - queueStats.school[user.profile.school] += 1; - } else { - queueStats.school[user.profile.school] = 1; - } - if(user.profile.graduationYear in queueStats.year){ - queueStats.year[user.profile.graduationYear] += 1; - } else { - queueStats.year[user.profile.graduationYear] = 1; + .sort({ + "status.queued": "asc" + }) + .exec(function(err, users) { + if (err || !users) { + return callback(err); } + queueStats = { + gender: {}, + school: {}, + year: {} + }; + users.forEach(function(user) { + if (user.profile.gender in queueStats.gender) { + queueStats.gender[user.profile.gender] += 1; + } else { + queueStats.gender[user.profile.gender] = 1; + } + if (user.profile.school in queueStats.school) { + queueStats.school[user.profile.school] += 1; + } else { + queueStats.school[user.profile.school] = 1; + } + if (user.profile.graduationYear in queueStats.year) { + queueStats.year[user.profile.graduationYear] += 1; + } else { + queueStats.year[user.profile.graduationYear] = 1; + } + }); + return callback(null, { + users, + stats: queueStats + }); }); - return callback(null, { - users, - stats: queueStats - }); - }); }; module.exports = UserController; diff --git a/app/server/routes/api.js b/app/server/routes/api.js index 09253799c..ec6b18ee2 100644 --- a/app/server/routes/api.js +++ b/app/server/routes/api.js @@ -1,64 +1,60 @@ -var UserController = require('../controllers/UserController'); -var SettingsController = require('../controllers/SettingsController'); -var request = require('request'); +var UserController = require("../controllers/UserController"); +var SettingsController = require("../controllers/SettingsController"); +var request = require("request"); -jwt = require('jsonwebtoken'); +jwt = require("jsonwebtoken"); JWT_SECRET = process.env.JWT_SECRET; -var aws = require('aws-sdk'); +var aws = require("aws-sdk"); aws.config.update({ - region: 'us-west-1', + region: "us-west-1", accessKeyId: process.env.AWS_ACCESS, secretAccessKey: process.env.AWS_SECRET }); var s3 = new aws.S3(); var s3BucketName = process.env.AWS_S3_BUCKET; -var multer = require('multer') -var multerS3 = require('multer-s3') -var uuidv4 = require('uuid/v4'); +var multer = require("multer"); +var multerS3 = require("multer-s3"); +var uuidv4 = require("uuid/v4"); -const google = require('googleapis') -const sheets = google.sheets('v4') +const google = require("googleapis"); +const sheets = google.sheets("v4"); -var hellosign = require('hellosign-sdk')({key: process.env.HELLOSIGN_KEY}); +var hellosign = require("hellosign-sdk")({ key: process.env.HELLOSIGN_KEY }); const oauth2Client = new google.auth.OAuth2( process.env.GOOGLE_ID, process.env.GOOGLE_SECRET -) +); -oauth2Client.credentials.refresh_token = process.env.GOOGLE_REFRESH_TOKEN +oauth2Client.credentials.refresh_token = process.env.GOOGLE_REFRESH_TOKEN; module.exports = function(router) { - - function getToken(req){ - return req.headers['x-access-token']; + function getToken(req) { + return req.headers["x-access-token"]; } /** * Using the access token provided, check to make sure that * you are, indeed, an admin. */ - function isAdmin(req, res, next){ - + function isAdmin(req, res, next) { var token = getToken(req); - UserController.getByToken(token, function(err, user){ - + UserController.getByToken(token, function(err, user) { if (err) { return res.status(500).send(err); } - if (user && user.admin){ + if (user && user.admin) { req.user = user; return next(); } return res.status(401).send({ - message: 'Get outta here, punk!' + message: "Get outta here, punk!" }); - }); } @@ -71,21 +67,20 @@ module.exports = function(router) { * That, or you're the admin, so you can do whatever you * want I suppose! */ - function isOwnerOrAdmin(req, res, next){ + function isOwnerOrAdmin(req, res, next) { var token = getToken(req); var userId = req.params.id; - UserController.getByToken(token, function(err, user){ - + UserController.getByToken(token, function(err, user) { if (err || !user) { return res.status(500).send(err); } - if (user._id == userId || user.admin){ + if (user._id == userId || user.admin) { return next(); } return res.status(400).send({ - message: 'Token does not match user id.' + message: "Token does not match user id." }); }); } @@ -95,20 +90,22 @@ module.exports = function(router) { * @param {[type]} res [description] * @return {[type]} [description] */ - function defaultResponse(req, res){ - return function(err, data){ - if (err){ + function defaultResponse(req, res) { + return function(err, data) { + if (err) { // SLACK ALERT! - if (process.env.NODE_ENV === 'production'){ - request - .post(process.env.SLACK_HOOK, - { - form: { - payload: JSON.stringify({ - "text": + if (process.env.NODE_ENV === "production") { + request.post( + process.env.SLACK_HOOK, + { + form: { + payload: JSON.stringify({ + text: "``` \n" + "Request: \n " + - req.method + ' ' + req.url + + req.method + + " " + + req.url + "\n ------------------------------------ \n" + "Body: \n " + JSON.stringify(req.body, null, 2) + @@ -116,15 +113,15 @@ module.exports = function(router) { "\nError:\n" + JSON.stringify(err, null, 2) + "``` \n" - }) - } - }, - function (error, response, body) { - return res.status(500).send({ - message: "Your error has been recorded, we'll get right on it!" - }); + }) } - ); + }, + function(error, response, body) { + return res.status(500).send({ + message: "Your error has been recorded, we'll get right on it!" + }); + } + ); } else { return res.status(500).send(err); } @@ -148,82 +145,83 @@ module.exports = function(router) { * GET - Get all users, or a page at a time. * ex. Paginate with ?page=0&size=100 */ - router.get('/users', isAdmin, function(req, res){ + router.get("/users", isAdmin, function(req, res) { var query = req.query; - if (query.page && query.size){ - + if (query.page && query.size) { UserController.getPage(query, defaultResponse(req, res)); - } else { - UserController.getAll(defaultResponse(req, res)); - } }); /** * [ADMIN ONLY] */ - router.get('/users/stats', isAdmin, function(req, res){ + router.get("/users/stats", isAdmin, function(req, res) { UserController.getStats(defaultResponse(req, res)); }); - router.get('/users/waiver', (req, res) => { + router.get("/users/waiver", (req, res) => { var token = getToken(req); - UserController.getByToken(token, function(err, user){ + UserController.getByToken(token, function(err, user) { if (err) { return res.status(500).send(err); } - + email = user.email; - hellosign.signatureRequest.list({ - query: email - }) - .then(function(response){ - if(response.signature_requests.length) { - signatureExists = response.signature_requests[0].signatures.find(signature => signature.signer_email_address === email) - if(signatureExists) { - res.send(200); + hellosign.signatureRequest + .list({ + query: email + }) + .then(function(response) { + if (response.signature_requests.length) { + signatureExists = response.signature_requests[0].signatures.find( + signature => signature.signer_email_address === email + ); + if (signatureExists) { + res.send(200); + } else { + res.send(404); + } } else { res.send(404); } - } else { - res.send(404) - } - - }) - .catch(function(err){ - return res.status(500).send(err); - }); + }) + .catch(function(err) { + return res.status(500).send(err); + }); }); }); /** * Accept all users in acceptance queue - */ - router.post('/users/acceptQueue', isAdmin, function(req,res){ + */ + router.post("/users/acceptQueue", isAdmin, function(req, res) { var token = getToken(req); - UserController.getByToken(token, function(err, user){ + UserController.getByToken(token, function(err, user) { if (err) { return res.status(500).send(err); } - UserController.acceptAllInAcceptedQueue(user.email, defaultResponse(req, res)); + UserController.acceptAllInAcceptedQueue( + user.email, + defaultResponse(req, res) + ); }); }); /** * View all users and stats in acceptance queue - */ - router.get('/users/viewQueue', isAdmin, function(req,res){ + */ + router.get("/users/viewQueue", isAdmin, function(req, res) { UserController.viewAcceptedQueue(defaultResponse(req, res)); }); /* Send acceptance email to each newly admitted user */ - router.post('/users/emailAdmitted', isAdmin, function(req,res){ + router.post("/users/emailAdmitted", isAdmin, function(req, res) { UserController.emailAcceptanceToAdmitted(defaultResponse(req, res)); }); /** @@ -231,20 +229,34 @@ module.exports = function(router) { * * GET - Get a specific user. */ - router.get('/users/:id', isOwnerOrAdmin, function(req, res){ + router.get("/users/:id", isOwnerOrAdmin, function(req, res) { UserController.getById(req.params.id, defaultResponse(req, res)); }); + /** + * [OWNER/ADMIN] + * + * GET - Get a specific user by email. + */ + router.get("/users/email/:email", isOwnerOrAdmin, function(req, res) { + UserController.getByEmail(req.params.email, function(err, user) { + if (err) { + return res.status(400).send(err); + } + return res.json(user); + }); + }); + /** * [OWNER/ADMIN] * * PUT - Update a specific user's profile. */ - router.put('/users/:id/profile', isOwnerOrAdmin, function(req, res){ + router.put("/users/:id/profile", isOwnerOrAdmin, function(req, res) { var profile = req.body.profile; var id = req.params.id; - UserController.updateProfileById(id, profile , defaultResponse(req, res)); + UserController.updateProfileById(id, profile, defaultResponse(req, res)); }); /** @@ -252,99 +264,127 @@ module.exports = function(router) { * * PUT - Update a specific user's confirmation information. */ - router.put('/users/:id/confirm', isOwnerOrAdmin, function(req, res){ + router.put("/users/:id/confirm", isOwnerOrAdmin, function(req, res) { var confirmation = req.body.confirmation; var id = req.params.id; if (confirmation.needsReimbursement) { oauth2Client.refreshAccessToken((err, tokens) => { - if (err) return console.error(err) + if (err) return console.error(err); oauth2Client.credentials.access_token = tokens.access_token; - var sheet = 'default'; + var sheet = "default"; var sheetId = 197870237; // sets which sheet to insert to var email = UserController.getById(id, (error, user) => { - if (user.profile.school === 'University of California-Los Angeles' || - user.profile.school === 'The University of California, Los Angeles' || - user.profile.school === 'UCLA') { - sheet = 'UCLA' - sheetId = 925052505 - } else if (user.profile.school === 'University of California-San Diego' || - user.profile.school === 'The University of California, San Diego') { - sheet = 'UCSD' - sheetId = 698367773 - } else if (user.profile.school === 'University of Southern California') { - sheet = 'USC' - sheetId = 723023891 + if ( + user.profile.school === "University of California-Los Angeles" || + user.profile.school === + "The University of California, Los Angeles" || + user.profile.school === "UCLA" + ) { + sheet = "UCLA"; + sheetId = 925052505; + } else if ( + user.profile.school === "University of California-San Diego" || + user.profile.school === "The University of California, San Diego" + ) { + sheet = "UCSD"; + sheetId = 698367773; + } else if ( + user.profile.school === "University of Southern California" + ) { + sheet = "USC"; + sheetId = 723023891; } // get all emails to check for duplicates - sheets.spreadsheets.values.get({ - spreadsheetId: process.env.GOOGLE_SPREADSHEET_ID, - range: sheet + '!B:B', - auth: oauth2Client - }, (err, result) => { - if (err) return console.error(err) - - // add to waitlist iff the user needs transportation and isn't on the waitlist - if (confirmation.needsReimbursement === '1' && !result.values.some((value) => { - return JSON.stringify(value) === JSON.stringify(user.email.split()) - })) { - sheets.spreadsheets.values.append({ - spreadsheetId: process.env.GOOGLE_SPREADSHEET_ID, - range: sheet + '!A1:B1', - valueInputOption: 'RAW', - insertDataOption: 'INSERT_ROWS', - resource: { - values: [ - [new Date().toString(), user.email] - ] - }, - auth: oauth2Client - }, (err, response) => { - if (err) return console.error(err) - }) - } else if (confirmation.needsReimbursement === '0' && result.values.some((value) => { - return JSON.stringify(value) === JSON.stringify(user.email.split()) - })) { - // otherwise remove from waitlist if the user doesn't need transporation but is on the waitlist - // first find the index of the row - for (var i = 0; i < result.values.length; i++) { - if (result.values[i][0] === user.email) { - // when found, send a delete request - sheets.spreadsheets.batchUpdate({ + sheets.spreadsheets.values.get( + { + spreadsheetId: process.env.GOOGLE_SPREADSHEET_ID, + range: sheet + "!B:B", + auth: oauth2Client + }, + (err, result) => { + if (err) return console.error(err); + + // add to waitlist iff the user needs transportation and isn't on the waitlist + if ( + confirmation.needsReimbursement === "1" && + !result.values.some(value => { + return ( + JSON.stringify(value) === JSON.stringify(user.email.split()) + ); + }) + ) { + sheets.spreadsheets.values.append( + { spreadsheetId: process.env.GOOGLE_SPREADSHEET_ID, + range: sheet + "!A1:B1", + valueInputOption: "RAW", + insertDataOption: "INSERT_ROWS", resource: { - requests: [ - { - deleteDimension: { - range: { - sheetId: sheetId, - dimension: "ROWS", - startIndex: i, - endIndex: i + 1 - } - } - } - ] + values: [[new Date().toString(), user.email]] }, auth: oauth2Client - }, (err, response) => { - if (err) return console.error(err) - }) - - break; + }, + (err, response) => { + if (err) return console.error(err); + } + ); + } else if ( + confirmation.needsReimbursement === "0" && + result.values.some(value => { + return ( + JSON.stringify(value) === JSON.stringify(user.email.split()) + ); + }) + ) { + // otherwise remove from waitlist if the user doesn't need transporation but is on the waitlist + // first find the index of the row + for (var i = 0; i < result.values.length; i++) { + if (result.values[i][0] === user.email) { + // when found, send a delete request + sheets.spreadsheets.batchUpdate( + { + spreadsheetId: process.env.GOOGLE_SPREADSHEET_ID, + resource: { + requests: [ + { + deleteDimension: { + range: { + sheetId: sheetId, + dimension: "ROWS", + startIndex: i, + endIndex: i + 1 + } + } + } + ] + }, + auth: oauth2Client + }, + (err, response) => { + if (err) return console.error(err); + } + ); + + break; + } } } } - }) - }) + ); + }); }); } - UserController.updateConfirmationById(id, confirmation, defaultResponse(req, res)); + UserController.updateConfirmationById( + id, + confirmation, + defaultResponse(req, res) + ); }); /** @@ -352,7 +392,7 @@ module.exports = function(router) { * * POST - Decline an acceptance. */ - router.post('/users/:id/decline', isOwnerOrAdmin, function(req, res){ + router.post("/users/:id/decline", isOwnerOrAdmin, function(req, res) { var confirmation = req.body.confirmation; var id = req.params.id; @@ -366,7 +406,7 @@ module.exports = function(router) { * newPassword: STRING * } */ - router.put('/users/:id/password', isOwnerOrAdmin, function(req, res){ + router.put("/users/:id/password", isOwnerOrAdmin, function(req, res) { return res.status(304).send(); // Currently disable. // var id = req.params.id; @@ -386,7 +426,7 @@ module.exports = function(router) { * * Also attaches the user who did the admitting, for liabaility. */ - router.post('/users/:id/admit', isAdmin, function(req, res){ + router.post("/users/:id/admit", isAdmin, function(req, res) { // Accept the hacker. Admin only var id = req.params.id; var user = req.user; @@ -396,7 +436,7 @@ module.exports = function(router) { /** * Check in a user. ADMIN ONLY, DUH */ - router.post('/users/:id/checkin', isAdmin, function(req, res){ + router.post("/users/:id/checkin", isAdmin, function(req, res) { var id = req.params.id; var user = req.user; UserController.checkInById(id, user, defaultResponse(req, res)); @@ -405,7 +445,7 @@ module.exports = function(router) { /** * Check in a user. ADMIN ONLY, DUH */ - router.post('/users/:id/checkout', isAdmin, function(req, res){ + router.post("/users/:id/checkout", isAdmin, function(req, res) { var id = req.params.id; var user = req.user; UserController.checkOutById(id, user, defaultResponse(req, res)); @@ -414,17 +454,17 @@ module.exports = function(router) { /** * Mark a user's waiver documents as signed. */ - router.post('/users/:id/sign', isAdmin, function(req, res){ + router.post("/users/:id/sign", isAdmin, function(req, res) { var id = req.params.id; UserController.getById(id, (error, user) => { - UserController.markWaiverAsSigned(user.email, defaultResponse(req, res)); + UserController.markWaiverAsSigned(user.email, defaultResponse(req, res)); }); }); /** * Send waiver email to the user. */ - router.post('/users/:id/sendwaiver', isAdmin, function(req, res){ + router.post("/users/:id/sendwaiver", isAdmin, function(req, res) { var id = req.params.id; UserController.sendWaiverEmail(id, defaultResponse(req, res)); }); @@ -432,7 +472,7 @@ module.exports = function(router) { /** * Add user to acceptance queue. */ - router.post('/users/:id/queue', isAdmin, function(req,res){ + router.post("/users/:id/queue", isAdmin, function(req, res) { var id = req.params.id; UserController.addUserAcceptedQueue(id, defaultResponse(req, res)); }); @@ -440,7 +480,7 @@ module.exports = function(router) { /** * Remove user from acceptance queue. */ - router.delete('/users/:id/queue', isAdmin, function(req,res){ + router.delete("/users/:id/queue", isAdmin, function(req, res) { var id = req.params.id; UserController.removeUserAcceptedQueue(id, defaultResponse(req, res)); }); @@ -460,7 +500,7 @@ module.exports = function(router) { * allowMinors: Boolean * } */ - router.get('/settings', function(req, res){ + router.get("/settings", function(req, res) { SettingsController.getPublicSettings(defaultResponse(req, res)); }); @@ -470,9 +510,13 @@ module.exports = function(router) { * text: String * } */ - router.put('/settings/waitlist', isAdmin, function(req, res){ + router.put("/settings/waitlist", isAdmin, function(req, res) { var text = req.body.text; - SettingsController.updateField('waitlistText', text, defaultResponse(req, res)); + SettingsController.updateField( + "waitlistText", + text, + defaultResponse(req, res) + ); }); /** @@ -481,9 +525,13 @@ module.exports = function(router) { * text: String * } */ - router.put('/settings/acceptance', isAdmin, function(req, res){ + router.put("/settings/acceptance", isAdmin, function(req, res) { var text = req.body.text; - SettingsController.updateField('acceptanceText', text, defaultResponse(req, res)); + SettingsController.updateField( + "acceptanceText", + text, + defaultResponse(req, res) + ); }); /** @@ -492,9 +540,13 @@ module.exports = function(router) { * text: String * } */ - router.put('/settings/confirmation', isAdmin, function(req, res){ + router.put("/settings/confirmation", isAdmin, function(req, res) { var text = req.body.text; - SettingsController.updateField('confirmationText', text, defaultResponse(req, res)); + SettingsController.updateField( + "confirmationText", + text, + defaultResponse(req, res) + ); }); /** @@ -503,9 +555,13 @@ module.exports = function(router) { * time: Number * } */ - router.put('/settings/confirm-by', isAdmin, function(req, res){ + router.put("/settings/confirm-by", isAdmin, function(req, res) { var time = req.body.time; - SettingsController.updateField('timeConfirm', time, defaultResponse(req, res)); + SettingsController.updateField( + "timeConfirm", + time, + defaultResponse(req, res) + ); }); /** @@ -515,10 +571,14 @@ module.exports = function(router) { * timeClose: Number * } */ - router.put('/settings/times', isAdmin, function(req, res){ + router.put("/settings/times", isAdmin, function(req, res) { var open = req.body.timeOpen; var close = req.body.timeClose; - SettingsController.updateRegistrationTimes(open, close, defaultResponse(req, res)); + SettingsController.updateRegistrationTimes( + open, + close, + defaultResponse(req, res) + ); }); /** @@ -528,7 +588,7 @@ module.exports = function(router) { * emails: [String] * } */ - router.get('/settings/whitelist', isAdmin, function(req, res){ + router.get("/settings/whitelist", isAdmin, function(req, res) { SettingsController.getWhitelistedEmails(defaultResponse(req, res)); }); @@ -540,15 +600,18 @@ module.exports = function(router) { * res: Settings * */ - router.put('/settings/whitelist', isAdmin, function(req, res){ + router.put("/settings/whitelist", isAdmin, function(req, res) { var emails = req.body.emails; - SettingsController.updateWhitelistedEmails(emails, defaultResponse(req, res)); + SettingsController.updateWhitelistedEmails( + emails, + defaultResponse(req, res) + ); }); /** * Ping route for elastic load balancer */ - router.get('/ping', (req, res) => { + router.get("/ping", (req, res) => { res.sendStatus(200); }); @@ -557,31 +620,31 @@ module.exports = function(router) { storage: multerS3({ s3: s3, bucket: s3BucketName, - key: function (req, file, cb) { - var authToken = req.headers['x-access-token']; + key: function(req, file, cb) { + var authToken = req.headers["x-access-token"]; jwt.verify(authToken, JWT_SECRET, (err, id) => { - cb(err, id + '.pdf'); + cb(err, id + ".pdf"); }); }, limits: { - fileSize: 512 * 1024, // max upload size is 512kb + fileSize: 512 * 1024 // max upload size is 512kb } }) }); // upload the resume to AWS S3 using the multer object defined above - router.post('/resume/upload', upload.single('file'), (req, res) => { + router.post("/resume/upload", upload.single("file"), (req, res) => { res.send(200); }); // get the resume of a given user - router.get('/resume/:id', isOwnerOrAdmin, (req, res) => { + router.get("/resume/:id", isOwnerOrAdmin, (req, res) => { // check to see if you can access this shiz and // check if the file exists in s3 anddd // take the id and put it in a jwt with 30 seconds of validity - var id = req.params.id; - var fileName = id + '.pdf'; + var id = req.params.id; + var fileName = id + ".pdf"; var s3Params = { Bucket: s3BucketName, @@ -592,7 +655,9 @@ module.exports = function(router) { if (err) { res.sendStatus(404); } else { - var token = jwt.sign({fileName: fileName}, JWT_SECRET, {expiresIn: '30s'}); + var token = jwt.sign({ fileName: fileName }, JWT_SECRET, { + expiresIn: "30s" + }); res.json({ token: token }); @@ -600,25 +665,26 @@ module.exports = function(router) { }); }); - router.get('/resume/view/:token', (req, res) => { + router.get("/resume/view/:token", (req, res) => { // get a token returned by the above object // extract the filename then return the file - var token = req.params.token + var token = req.params.token; jwt.verify(token, JWT_SECRET, (err, data) => { - if (err) { - res.sendStatus(401) + res.sendStatus(401); } else { var s3Params = { Bucket: s3BucketName, Key: data.fileName }; - res.setHeader('Content-type', 'application/pdf'); - s3.getObject(s3Params).createReadStream().pipe(res); + res.setHeader("Content-type", "application/pdf"); + s3.getObject(s3Params) + .createReadStream() + .pipe(res); } - }) + }); }); /* [ADMIN ONLY] @@ -628,9 +694,12 @@ module.exports = function(router) { * res: Settings * */ - router.put('/settings/minors', isAdmin, function(req, res){ + router.put("/settings/minors", isAdmin, function(req, res) { var allowMinors = req.body.allowMinors; - SettingsController.updateField('allowMinors', allowMinors, defaultResponse(req, res)); + SettingsController.updateField( + "allowMinors", + allowMinors, + defaultResponse(req, res) + ); }); - };