2016-04-07 17:55:42 -04:00
|
|
|
_ = require 'lodash'
|
|
|
|
co = require 'co'
|
2016-06-29 18:01:01 -04:00
|
|
|
countryList = require('country-list')()
|
2016-02-25 18:24:16 -05:00
|
|
|
errors = require '../commons/errors'
|
2016-06-29 18:01:01 -04:00
|
|
|
geoip = require 'geoip-lite'
|
2016-02-25 18:24:16 -05:00
|
|
|
wrap = require 'co-express'
|
|
|
|
Promise = require 'bluebird'
|
|
|
|
parse = require '../commons/parse'
|
|
|
|
request = require 'request'
|
2016-04-07 17:55:42 -04:00
|
|
|
mongoose = require 'mongoose'
|
2016-05-11 17:39:26 -04:00
|
|
|
sendwithus = require '../sendwithus'
|
2016-04-06 13:56:06 -04:00
|
|
|
User = require '../models/User'
|
2016-04-07 17:55:42 -04:00
|
|
|
Classroom = require '../models/Classroom'
|
2016-02-25 18:24:16 -05:00
|
|
|
|
|
|
|
module.exports =
|
|
|
|
fetchByGPlusID: wrap (req, res, next) ->
|
|
|
|
gpID = req.query.gplusID
|
|
|
|
gpAT = req.query.gplusAccessToken
|
2016-04-19 13:20:56 -04:00
|
|
|
return next() unless gpID and gpAT
|
2016-02-25 18:24:16 -05:00
|
|
|
|
|
|
|
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
|
2016-04-11 19:51:51 -04:00
|
|
|
res.status(200).send(user.toObject({req: req}))
|
2016-05-16 17:33:20 -04:00
|
|
|
|
2016-02-25 18:24:16 -05:00
|
|
|
fetchByFacebookID: wrap (req, res, next) ->
|
|
|
|
fbID = req.query.facebookID
|
|
|
|
fbAT = req.query.facebookAccessToken
|
2016-04-19 13:20:56 -04:00
|
|
|
return next() unless fbID and fbAT
|
2016-02-25 18:24:16 -05:00
|
|
|
|
|
|
|
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
|
2016-04-11 19:51:51 -04:00
|
|
|
res.status(200).send(user.toObject({req: req}))
|
2016-04-07 17:55:42 -04:00
|
|
|
|
|
|
|
removeFromClassrooms: wrap (req, res, next) ->
|
2016-05-16 17:33:20 -04:00
|
|
|
yield req.user.removeFromClassrooms()
|
2016-04-07 17:55:42 -04:00
|
|
|
next()
|
2016-05-16 17:33:20 -04:00
|
|
|
|
|
|
|
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}))
|
2016-05-11 17:39:26 -04:00
|
|
|
|
|
|
|
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 =
|
2016-06-06 19:53:05 -04:00
|
|
|
email_id: sendwithus.templates.verify_email
|
2016-05-11 17:39:26 -04:00
|
|
|
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({})
|
2016-06-21 12:29:41 -04:00
|
|
|
|
|
|
|
getStudents: wrap (req, res, next) ->
|
|
|
|
throw new errors.Unauthorized('You must be an administrator.') unless req.user?.isAdmin()
|
2016-06-29 18:01:01 -04:00
|
|
|
query = $or: [{role: 'student'}, {$and: [{schoolName: {$exists: true}}, {schoolName: {$ne: ''}}, {anonymous: false}]}]
|
|
|
|
users = yield User.find(query).select('lastIP schoolName').lean()
|
|
|
|
for user in users
|
|
|
|
if ip = user.lastIP
|
|
|
|
user.geo = geoip.lookup(ip)
|
|
|
|
if country = user.geo?.country
|
|
|
|
user.geo.countryName = countryList.getName(country)
|
|
|
|
res.status(200).send(users)
|
2016-06-21 12:29:41 -04:00
|
|
|
|
|
|
|
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']
|
2016-06-29 18:01:01 -04:00
|
|
|
users = yield User.find(anonymous: false, role: {$in: teacherRoles}).select('lastIP').lean()
|
|
|
|
for user in users
|
|
|
|
if ip = user.lastIP
|
|
|
|
user.geo = geoip.lookup(ip)
|
|
|
|
if country = user.geo?.country
|
|
|
|
user.geo.countryName = countryList.getName(country)
|
|
|
|
res.status(200).send(users)
|