_ = require 'lodash' co = require 'co' errors = require '../commons/errors' wrap = require 'co-express' Promise = require 'bluebird' parse = require '../commons/parse' request = require 'request' mongoose = require 'mongoose' sendwithus = require '../sendwithus' User = require '../models/User' Classroom = require '../models/Classroom' module.exports = fetchByGPlusID: wrap (req, res, next) -> gpID = req.query.gplusID gpAT = req.query.gplusAccessToken return next() unless gpID and gpAT dbq = User.find() dbq.select(parse.getProjectFromReq(req)) url = "https://www.googleapis.com/oauth2/v2/userinfo?access_token=#{gpAT}" [googleRes, body] = yield request.getAsync(url, {json: true}) idsMatch = gpID is body.id throw new errors.UnprocessableEntity('Invalid G+ Access Token.') unless idsMatch user = yield User.findOne({gplusID: gpID}) throw new errors.NotFound('No user with that G+ ID') unless user res.status(200).send(user.toObject({req: req})) fetchByFacebookID: wrap (req, res, next) -> fbID = req.query.facebookID fbAT = req.query.facebookAccessToken return next() unless fbID and fbAT dbq = User.find() dbq.select(parse.getProjectFromReq(req)) url = "https://graph.facebook.com/me?access_token=#{fbAT}" [facebookRes, body] = yield request.getAsync(url, {json: true}) idsMatch = fbID is body.id throw new errors.UnprocessableEntity('Invalid Facebook Access Token.') unless idsMatch user = yield User.findOne({facebookID: fbID}) throw new errors.NotFound('No user with that Facebook ID') unless user res.status(200).send(user.toObject({req: req})) removeFromClassrooms: wrap (req, res, next) -> yield req.user.removeFromClassrooms() next() remainTeacher: wrap (req, res, next) -> yield req.user.removeFromClassrooms() user = yield User.findById req.user.id res.status(200).send(user.toObject({req: req})) becomeStudent: wrap (req, res, next) -> userID = mongoose.Types.ObjectId(req.user.id) yield Classroom.remove({ ownerID: userID }, false) userID = mongoose.Types.ObjectId(req.user.id) yield User.update({ _id: userID }, { $set: { "role": "student" } }) user = yield User.findById req.user.id res.status(200).send(user.toObject({req: req})) verifyEmailAddress: wrap (req, res, next) -> user = yield User.findOne({ _id: mongoose.Types.ObjectId(req.params.userID) }) [timestamp, hash] = req.params.verificationCode.split(':') unless user throw new errors.UnprocessableEntity('User not found') unless req.params.verificationCode is user.verificationCode(timestamp) throw new errors.UnprocessableEntity('Verification code does not match') yield User.update({ _id: user.id }, { emailVerified: true }) res.status(200).send({ role: user.get('role') }) resetEmailVerifiedFlag: wrap (req, res, next) -> newEmail = req.body.email _id = mongoose.Types.ObjectId(req.body._id) if newEmail user = yield User.findOne({ _id }) oldEmail = user.get('email') if newEmail isnt oldEmail yield User.update({ _id }, { $set: { emailVerified: false } }) next() sendVerificationEmail: wrap (req, res, next) -> user = yield User.findById(req.params.userID) timestamp = (new Date).getTime() if not user throw new errors.NotFound('User not found') context = email_id: sendwithus.templates.verify_email recipient: address: user.get('email') name: user.broadName() email_data: name: user.broadName() verify_link: "http://codecombat.com/user/#{user._id}/verify/#{user.verificationCode(timestamp)}" sendwithus.api.send context, (err, result) -> res.status(200).send({}) getStudents: wrap (req, res, next) -> throw new errors.Unauthorized('You must be an administrator.') unless req.user?.isAdmin() students = yield User.find({$and: [{schoolName: {$exists: true}}, {schoolName: {$ne: ''}}, {anonymous: false}]}).select('schoolName').lean() res.status(200).send(students) getTeachers: wrap (req, res, next) -> throw new errors.Unauthorized('You must be an administrator.') unless req.user?.isAdmin() teacherRoles = ['teacher', 'technology coordinator', 'advisor', 'principal', 'superintendent', 'parent'] teachers = yield User.find(anonymous: false, role: {$in: teacherRoles}).select('').lean() res.status(200).send(teachers)