'use strict'; /** * Module dependencies */ var _ = require('lodash'), fs = require('fs'), path = require('path'), errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), moment = require('moment'), scoreLib = require(path.resolve('./config/lib/score')), mongoose = require('mongoose'), multer = require('multer'), multerS3 = require('multer-s3'), aws = require('aws-sdk'), amazonS3URI = require('amazon-s3-uri'), config = require(path.resolve('./config/config')), User = mongoose.model('User'), validator = require('validator'), scoreUpdate = require(path.resolve('./config/lib/score')).update, traceLogCreate = require(path.resolve('./config/lib/tracelog')).create; var whitelistedFields = ['firstName', 'lastName', 'email', 'username', 'hideMoreDetail']; var mtDebug = require(path.resolve('./config/lib/debug')); var signConfig = config.meanTorrentConfig.sign; var traceConfig = config.meanTorrentConfig.trace; var scoreConfig = config.meanTorrentConfig.score; var useS3Storage = config.uploads.storage === 's3' && config.aws.s3; var s3; if (useS3Storage) { aws.config.update({ accessKeyId: config.aws.s3.accessKeyId, secretAccessKey: config.aws.s3.secretAccessKey }); s3 = new aws.S3(); } /** * Update user details */ exports.update = function (req, res) { // Init Variables var user = req.user; if (user) { // Update whitelisted fields only user = _.extend(user, _.pick(req.body, whitelistedFields)); user.updated = Date.now(); user.displayName = user.firstName + ' ' + user.lastName; user.save(function (err) { if (err) { return res.status(422).send({ message: errorHandler.getErrorMessage(err) }); } else { req.login(user, function (err) { if (err) { res.status(400).send(err); } else { res.json(user); } }); } }); } else { res.status(401).send({ message: 'User is not signed in' }); } }; /** * Update profile picture */ exports.changeProfilePicture = function (req, res) { var user = req.user; var existingImageUrl; var multerConfig; if (useS3Storage) { multerConfig = { storage: multerS3({ s3: s3, bucket: config.aws.s3.bucket, acl: 'public-read' }) }; } else { multerConfig = config.uploads.profile.image; } // Filtering to upload only images multerConfig.fileFilter = require(path.resolve('./config/lib/multer')).imageFileFilter; var upload = multer(multerConfig).single('newProfilePicture'); if (user) { existingImageUrl = user.profileImageURL; uploadImage() .then(updateUser) .then(deleteOldImage) .then(login) .then(function () { res.json(user); }) .catch(function (err) { res.status(422).send(err); }); } else { res.status(401).send({ message: 'User is not signed in' }); } function uploadImage() { return new Promise(function (resolve, reject) { upload(req, res, function (uploadError) { if (uploadError) { reject(errorHandler.getErrorMessage(uploadError)); } else { resolve(); } }); }); } function updateUser() { return new Promise(function (resolve, reject) { user.profileImageURL = config.uploads.storage === 's3' && config.aws.s3 ? req.file.location : '/' + req.file.path; user.save(function (err, theuser) { if (err) { reject(err); } else { resolve(); } }); }); } function deleteOldImage() { return new Promise(function (resolve, reject) { if (existingImageUrl !== User.schema.path('profileImageURL').defaultValue) { if (useS3Storage) { try { var {region, bucket, key} = amazonS3URI(existingImageUrl); var params = { Bucket: config.aws.s3.bucket, Key: key }; s3.deleteObject(params, function (err) { if (err) { mtDebug.debugRed('Error occurred while deleting old profile picture.'); mtDebug.debugRed('Check if you have sufficient permissions : ' + err); } resolve(); }); } catch (err) { console.warn('${existingImageUrl} is not a valid S3 uri'); return resolve(); } } else { fs.unlink(path.resolve('.' + existingImageUrl), function (unlinkError) { if (unlinkError) { // If file didn't exist, no need to reject promise if (unlinkError.code === 'ENOENT') { mtDebug.debugRed('Removing profile image failed because file did not exist.'); return resolve(); } console.error(unlinkError); reject({ message: 'Error occurred while deleting old profile picture' }); } else { resolve(); } }); } } else { resolve(); } }); } function login() { return new Promise(function (resolve, reject) { req.login(user, function (err) { if (err) { res.status(400).send(err); } else { resolve(); } }); }); } }; /** * Send User */ exports.me = function (req, res) { // Sanitize the user - short term solution. Copied from core.server.controller.js // TODO create proper passport mock: See https://gist.github.com/mweibel/5219403 var safeUserObject = null; if (req.user) { safeUserObject = { displayName: validator.escape(req.user.displayName), provider: validator.escape(req.user.provider), username: validator.escape(req.user.username), created: req.user.created.toString(), roles: req.user.roles, hnr_warning: req.user.hnr_warning, profileImageURL: req.user.profileImageURL, email: validator.escape(req.user.email), lastName: validator.escape(req.user.lastName), firstName: validator.escape(req.user.firstName), additionalProvidersData: req.user.additionalProvidersData }; } res.json(safeUserObject || null); }; /** * warningNumber * @param req * @param res * @param next */ exports.warningNumber = function (req, res, next) { if (req.user) { res.json({ hnr_warning: req.user.hnr_warning }); } else { res.status(401).send({ message: 'User is not signed in' }); } }; /** * unIdle * @param req * @param res * @param next */ exports.unIdle = function (req, res, next) { var user = req.user; if (user) { var days = (moment(Date.now()) - moment(user.last_idled) - signConfig.idle.accountIdleForTime) / (60 * 60 * 1000 * 24); var daysScore = Math.floor(days) * signConfig.idle.activeMoreScorePerDay; var level = scoreLib.getLevelByScore(user); var levelScore = level.currLevel * signConfig.idle.activeMoreScorePerLevel; var totalScore = signConfig.idle.activeIdleAccountBasicScore + daysScore + levelScore; if (user.score < totalScore) { return res.status(422).send({ message: 'SERVER.SCORE_NOT_ENOUGH' }); } else { //update score scoreUpdate(req, user, scoreConfig.action.activeIdleAccount, -(totalScore)); user.update({ status: 'normal', last_idled: null }).exec(); user.status = 'normal'; req.login(user, function (err) { if (err) { res.status(400).send(err); } else { res.json(user); } }); //create trace log traceLogCreate(req, traceConfig.action.userUnIdle, { user: req.user._id, basicScore: signConfig.idle.activeIdleAccountBasicScore, daysScore: daysScore, levelScore: levelScore, totalScore: totalScore }); } } else { res.status(401).send({ message: 'User is not signed in' }); } }; /** * getMyIp * @param req * @param res */ exports.getMyIp = function (req, res) { res.status(200).send({ ip: req.cf_ip }); };