user.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. user.allowNewsletter = req.body.allow_newsletter;
  128. }
  129. user.save(function(err) {
  130. if ('password' in req.body) {
  131. req.flash('success', { msg: 'Sua senha foi redefinida com sucesso.' });
  132. } else if (err && err.code === 11000) {
  133. req.flash('error', { msg: 'E-mail ou username inseridos já estão associados com outra conta.' });
  134. } else {
  135. req.flash('success', { msg: 'Suas informações foram alteradas com sucesso.' });
  136. }
  137. res.redirect('/account');
  138. });
  139. });
  140. };
  141. /**
  142. * DELETE /account
  143. */
  144. exports.accountDelete = function(req, res, next) {
  145. User.remove({ _id: req.user.id }, function(err) {
  146. req.logout();
  147. req.flash('info', { msg: 'Sua conta foi foi excluída com sucesso.' });
  148. res.redirect('/');
  149. });
  150. };
  151. /**
  152. * GET /unlink/:provider
  153. */
  154. exports.unlink = function(req, res, next) {
  155. User.findById(req.user.id, function(err, user) {
  156. switch (req.params.provider) {
  157. case 'facebook':
  158. user.facebook = undefined;
  159. break;
  160. case 'google':
  161. user.google = undefined;
  162. break;
  163. case 'twitter':
  164. user.twitter = undefined;
  165. break;
  166. case 'vk':
  167. user.vk = undefined;
  168. break;
  169. case 'github':
  170. user.github = undefined;
  171. break;
  172. default:
  173. req.flash('error', { msg: 'Invalid OAuth Provider' });
  174. return res.redirect('/account');
  175. }
  176. user.save(function(err) {
  177. req.flash('success', { msg: 'Your account has been unlinked.' });
  178. res.redirect('/account');
  179. });
  180. });
  181. };
  182. /**
  183. * GET /forgot
  184. */
  185. exports.forgotGet = function(req, res) {
  186. if (req.isAuthenticated()) {
  187. return res.redirect('/');
  188. }
  189. res.render('account/forgot', {
  190. title: 'Forgot Password'
  191. });
  192. };
  193. /**
  194. * POST /forgot
  195. */
  196. exports.forgotPost = function(req, res, next) {
  197. req.assert('email', 'O e-mail não é válido').isEmail();
  198. req.assert('email', ' e-mail não pode ficar em branco').notEmpty();
  199. req.sanitize('email').normalizeEmail({ remove_dots: false });
  200. var errors = req.validationErrors();
  201. if (errors) {
  202. req.flash('error', errors);
  203. return res.redirect('/forgot');
  204. }
  205. async.waterfall([
  206. function(done) {
  207. crypto.randomBytes(16, function(err, buf) {
  208. var token = buf.toString('hex');
  209. done(err, token);
  210. });
  211. },
  212. function(token, done) {
  213. User.findOne({ email: req.body.email }, function(err, user) {
  214. if (!user) {
  215. req.flash('error', { msg: 'O endereço de e-mail ' + req.body.email + ' não está associado com nenhuma conta.' });
  216. return res.redirect('/forgot');
  217. }
  218. user.passwordResetToken = token;
  219. user.passwordResetExpires = Date.now() + 3600000; // expire in 1 hour
  220. user.save(function(err) {
  221. done(err, token, user);
  222. });
  223. });
  224. },
  225. function(token, user, done) {
  226. var transporter = nodemailer.createTransport({
  227. service: 'Mailgun',
  228. auth: {
  229. user: process.env.MAILGUN_USERNAME,
  230. pass: process.env.MAILGUN_PASSWORD
  231. }
  232. });
  233. var mailOptions = {
  234. to: user.email,
  235. from: 'libreflix@protonmail.com',
  236. subject: 'Redefinir sua senha no Libreflix',
  237. text: 'Oi, tudo bem?\n\n Você está recebendo esse email porque pediu para redefenir a senha da sua conta no Libreflix.\n\n' +
  238. 'Por favor, clique no link a seguir, ou cole no seu navegador para completar esse processo:\n\n' +
  239. 'https://' + req.headers.host + '/reset/' + token + '\n\n' +
  240. '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' +
  241. '\nAbraços Libres! <3\n\nTime Libreflix\n\n'
  242. };
  243. transporter.sendMail(mailOptions, function(err) {
  244. req.flash('info', { msg: 'Um e-mail foi enviado para ' + user.email + ' com mais informações.' });
  245. res.redirect('/forgot');
  246. });
  247. }
  248. ]);
  249. };
  250. /**
  251. * GET /reset
  252. */
  253. exports.resetGet = function(req, res) {
  254. if (req.isAuthenticated()) {
  255. return res.redirect('/');
  256. }
  257. User.findOne({ passwordResetToken: req.params.token })
  258. .where('passwordResetExpires').gt(Date.now())
  259. .exec(function(err, user) {
  260. if (!user) {
  261. req.flash('error', { msg: 'Password reset token is invalid or has expired.' });
  262. return res.redirect('/forgot');
  263. }
  264. res.render('account/reset', {
  265. title: 'Redefinir Senha'
  266. });
  267. });
  268. };
  269. /**
  270. * POST /reset
  271. */
  272. exports.resetPost = function(req, res, next) {
  273. req.assert('password', 'A senha precisa ter ao menos 4 caracteres').len(4);
  274. req.assert('confirm', 'A senhas não são iguais').equals(req.body.password);
  275. var errors = req.validationErrors();
  276. if (errors) {
  277. req.flash('error', errors);
  278. return res.redirect('back');
  279. }
  280. async.waterfall([
  281. function(done) {
  282. User.findOne({ passwordResetToken: req.params.token })
  283. .where('passwordResetExpires').gt(Date.now())
  284. .exec(function(err, user) {
  285. if (!user) {
  286. req.flash('error', { msg: 'Password reset token is invalid or has expired.' });
  287. return res.redirect('back');
  288. }
  289. user.password = req.body.password;
  290. user.passwordResetToken = undefined;
  291. user.passwordResetExpires = undefined;
  292. user.save(function(err) {
  293. req.logIn(user, function(err) {
  294. done(err, user);
  295. });
  296. });
  297. });
  298. },
  299. function(user, done) {
  300. var transporter = nodemailer.createTransport({
  301. service: 'Mailgun',
  302. auth: {
  303. user: process.env.MAILGUN_USERNAME,
  304. pass: process.env.MAILGUN_PASSWORD
  305. }
  306. });
  307. var mailOptions = {
  308. from: 'libreflix@protonmail.com',
  309. to: user.email,
  310. subject: 'Sua senha no Libreflix foi alterada',
  311. text: 'Olá! Tudo bem? \n\n' +
  312. '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'
  313. };
  314. transporter.sendMail(mailOptions, function(err) {
  315. req.flash('success', { msg: 'Sua senha foi alterada com sucesso.' });
  316. res.redirect('/account');
  317. });
  318. }
  319. ]);
  320. };