user.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. var async = require('async');
  2. var crypto = require('crypto');
  3. var nodemailer = require('nodemailer');
  4. var passport = require('passport');
  5. var User = require('../models/User');
  6. /**
  7. * GET /login
  8. */
  9. exports.loginGet = function(req, res) {
  10. if (req.user) {
  11. return res.redirect('/');
  12. }
  13. res.render('account/login', {
  14. title: 'Log in'
  15. });
  16. };
  17. /**
  18. * POST /login
  19. */
  20. exports.loginPost = function(req, res, next) {
  21. req.assert('email', 'O e-mail inserido não é válido').isEmail();
  22. req.assert('email', 'O e-mail não pode ficar em branco').notEmpty();
  23. req.assert('password', 'A senha não pode ficar em branco').notEmpty();
  24. req.sanitize('email').normalizeEmail({ remove_dots: false });
  25. var errors = req.validationErrors();
  26. if (errors) {
  27. req.flash('error', errors);
  28. return res.redirect('/login');
  29. }
  30. passport.authenticate('local', function(err, user, info) {
  31. if (!user) {
  32. req.flash('error', info);
  33. return res.redirect('/login')
  34. }
  35. req.logIn(user, function(err) {
  36. res.redirect('/');
  37. });
  38. })(req, res, next);
  39. };
  40. /**
  41. * GET /logout
  42. */
  43. exports.logout = function(req, res) {
  44. req.logout();
  45. res.redirect('/');
  46. };
  47. /**
  48. * GET /signup
  49. */
  50. exports.signupGet = function(req, res) {
  51. if (req.user) {
  52. return res.redirect('/');
  53. }
  54. res.render('account/signup', {
  55. title: 'Criar conta'
  56. });
  57. };
  58. /**
  59. * POST /signup
  60. */
  61. exports.signupPost = function(req, res, next) {
  62. req.assert('name', 'O nome não pode ficar em branco').notEmpty();
  63. req.assert('email', 'O e-mail inserido não é válido').isEmail();
  64. req.assert('email', 'O e-mail não pode ficar em branco').notEmpty();
  65. req.assert('password', 'A senha precisa ter pelo menos 4 caracteres').len(4);
  66. req.sanitize('email').normalizeEmail({ remove_dots: false });
  67. var errors = req.validationErrors();
  68. if (errors) {
  69. req.flash('error', errors);
  70. return res.redirect('/signup');
  71. }
  72. User.findOne({ email: req.body.email }, function(err, user) {
  73. if (user) {
  74. req.flash('error', { msg: 'O e-mail inserido já está associado com outra conta.' });
  75. return res.redirect('/signup');
  76. }
  77. user = new User({
  78. name: req.body.name,
  79. username: req.body.username,
  80. email: req.body.email,
  81. password: req.body.password
  82. });
  83. user.save(function(err) {
  84. req.logIn(user, function(err) {
  85. res.redirect('/');
  86. });
  87. });
  88. });
  89. };
  90. /**
  91. * GET /account
  92. */
  93. exports.accountGet = function(req, res) {
  94. res.render('account/profile', {
  95. title: 'Minha Conta'
  96. });
  97. };
  98. /**
  99. * PUT /account
  100. * Update profile information OR change password.
  101. */
  102. exports.accountPut = function(req, res, next) {
  103. if ('password' in req.body) {
  104. req.assert('password', 'A senha precisa ter pelo menos 4 caracteres.').len(4);
  105. req.assert('confirm', 'As senhas inseridas não conferem.').equals(req.body.password);
  106. } else {
  107. req.assert('email', 'Este e-mail não é válido.').isEmail();
  108. req.assert('email', 'O campo "Email" precisa ser preenchido.').notEmpty();
  109. req.sanitize('email').normalizeEmail({ remove_dots: false });
  110. }
  111. var errors = req.validationErrors();
  112. if (errors) {
  113. req.flash('error', errors);
  114. return res.redirect('/account');
  115. }
  116. User.findById(req.user.id, function(err, user) {
  117. if ('password' in req.body) {
  118. user.password = req.body.password;
  119. } else {
  120. user.email = req.body.email;
  121. user.username = req.body.username;
  122. user.name = req.body.name;
  123. user.gender = req.body.gender;
  124. user.location = req.body.location;
  125. user.website = req.body.website;
  126. user.cover_picture = req.body.cover_picture;
  127. }
  128. user.save(function(err) {
  129. if ('password' in req.body) {
  130. req.flash('success', { msg: 'Sua senha foi redefinida com sucesso.' });
  131. } else if (err && err.code === 11000) {
  132. req.flash('error', { msg: 'E-mail ou username inseridos já estão associados com outra conta.' });
  133. } else {
  134. req.flash('success', { msg: 'Suas informações foram alteradas com sucesso.' });
  135. }
  136. res.redirect('/account');
  137. });
  138. });
  139. };
  140. /**
  141. * DELETE /account
  142. */
  143. exports.accountDelete = function(req, res, next) {
  144. User.remove({ _id: req.user.id }, function(err) {
  145. req.logout();
  146. req.flash('info', { msg: 'Sua conta foi foi excluída com sucesso.' });
  147. res.redirect('/');
  148. });
  149. };
  150. /**
  151. * GET /unlink/:provider
  152. */
  153. exports.unlink = function(req, res, next) {
  154. User.findById(req.user.id, function(err, user) {
  155. switch (req.params.provider) {
  156. case 'facebook':
  157. user.facebook = undefined;
  158. break;
  159. case 'google':
  160. user.google = undefined;
  161. break;
  162. case 'twitter':
  163. user.twitter = undefined;
  164. break;
  165. case 'vk':
  166. user.vk = undefined;
  167. break;
  168. case 'github':
  169. user.github = undefined;
  170. break;
  171. default:
  172. req.flash('error', { msg: 'Invalid OAuth Provider' });
  173. return res.redirect('/account');
  174. }
  175. user.save(function(err) {
  176. req.flash('success', { msg: 'Your account has been unlinked.' });
  177. res.redirect('/account');
  178. });
  179. });
  180. };
  181. /**
  182. * GET /forgot
  183. */
  184. exports.forgotGet = function(req, res) {
  185. if (req.isAuthenticated()) {
  186. return res.redirect('/');
  187. }
  188. res.render('account/forgot', {
  189. title: 'Forgot Password'
  190. });
  191. };
  192. /**
  193. * POST /forgot
  194. */
  195. exports.forgotPost = function(req, res, next) {
  196. req.assert('email', 'O e-mail não é válido').isEmail();
  197. req.assert('email', ' e-mail não pode ficar em branco').notEmpty();
  198. req.sanitize('email').normalizeEmail({ remove_dots: false });
  199. var errors = req.validationErrors();
  200. if (errors) {
  201. req.flash('error', errors);
  202. return res.redirect('/forgot');
  203. }
  204. async.waterfall([
  205. function(done) {
  206. crypto.randomBytes(16, function(err, buf) {
  207. var token = buf.toString('hex');
  208. done(err, token);
  209. });
  210. },
  211. function(token, done) {
  212. User.findOne({ email: req.body.email }, function(err, user) {
  213. if (!user) {
  214. req.flash('error', { msg: 'O endereço de e-mail ' + req.body.email + ' não está associado com nenhuma conta.' });
  215. return res.redirect('/forgot');
  216. }
  217. user.passwordResetToken = token;
  218. user.passwordResetExpires = Date.now() + 3600000; // expire in 1 hour
  219. user.save(function(err) {
  220. done(err, token, user);
  221. });
  222. });
  223. },
  224. function(token, user, done) {
  225. var transporter = nodemailer.createTransport({
  226. service: 'Mailgun',
  227. auth: {
  228. user: process.env.MAILGUN_USERNAME,
  229. pass: process.env.MAILGUN_PASSWORD
  230. }
  231. });
  232. var mailOptions = {
  233. to: user.email,
  234. from: 'Libreflix@openmailbox.org',
  235. subject: 'Redefinir sua senha no Libreflix',
  236. text: 'Oi, tudo bem?\n\n Você está recebendo esse email porque pediu para redefenir a senha da sua conta no Libreflix.\n\n' +
  237. 'Por favor, clique no link a seguir, ou cole no seu navegador para completar esse processo:\n\n' +
  238. 'https://' + req.headers.host + '/reset/' + token + '\n\n' +
  239. 'Se você não pediu essa redefinição, por favor ignore este e-mail e a sua senha não sofrerá nenhuma alteração.\n' +
  240. '\nAbraços Libres! <3\n\nTime Libreflix\n\n'
  241. };
  242. transporter.sendMail(mailOptions, function(err) {
  243. req.flash('info', { msg: 'Um e-mail foi enviado para ' + user.email + ' com mais informações.' });
  244. res.redirect('/forgot');
  245. });
  246. }
  247. ]);
  248. };
  249. /**
  250. * GET /reset
  251. */
  252. exports.resetGet = function(req, res) {
  253. if (req.isAuthenticated()) {
  254. return res.redirect('/');
  255. }
  256. User.findOne({ passwordResetToken: req.params.token })
  257. .where('passwordResetExpires').gt(Date.now())
  258. .exec(function(err, user) {
  259. if (!user) {
  260. req.flash('error', { msg: 'Password reset token is invalid or has expired.' });
  261. return res.redirect('/forgot');
  262. }
  263. res.render('account/reset', {
  264. title: 'Redefinir Senha'
  265. });
  266. });
  267. };
  268. /**
  269. * POST /reset
  270. */
  271. exports.resetPost = function(req, res, next) {
  272. req.assert('password', 'A senha precisa ter ao menos 4 caracteres').len(4);
  273. req.assert('confirm', 'A senhas não são iguais').equals(req.body.password);
  274. var errors = req.validationErrors();
  275. if (errors) {
  276. req.flash('error', errors);
  277. return res.redirect('back');
  278. }
  279. async.waterfall([
  280. function(done) {
  281. User.findOne({ passwordResetToken: req.params.token })
  282. .where('passwordResetExpires').gt(Date.now())
  283. .exec(function(err, user) {
  284. if (!user) {
  285. req.flash('error', { msg: 'Password reset token is invalid or has expired.' });
  286. return res.redirect('back');
  287. }
  288. user.password = req.body.password;
  289. user.passwordResetToken = undefined;
  290. user.passwordResetExpires = undefined;
  291. user.save(function(err) {
  292. req.logIn(user, function(err) {
  293. done(err, user);
  294. });
  295. });
  296. });
  297. },
  298. function(user, done) {
  299. var transporter = nodemailer.createTransport({
  300. service: 'Mailgun',
  301. auth: {
  302. user: process.env.MAILGUN_USERNAME,
  303. pass: process.env.MAILGUN_PASSWORD
  304. }
  305. });
  306. var mailOptions = {
  307. from: 'Libreflix@openmailbox.org',
  308. to: user.email,
  309. subject: 'Sua senha no Libreflix foi alterada',
  310. text: 'Olá! Tudo bem? \n\n' +
  311. 'Este e-mail é uma confirmação que a senha da sua conta no Libreflix (' + user.email + ') foi alterada recentemente.\n\nAbraços Libres! <3\n\nTime Libreflix\n\n'
  312. };
  313. transporter.sendMail(mailOptions, function(err) {
  314. req.flash('success', { msg: 'Sua senha foi alterada com sucesso.' });
  315. res.redirect('/account');
  316. });
  317. }
  318. ]);
  319. };