user.js 9.6 KB

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