users.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. "use strict";
  2. var config = require('config');
  3. const db = require('../../models/db');
  4. const uuidv4 = require('uuid/v4');
  5. const os = require('os');
  6. var mailer = require('../../helpers/mailer');
  7. var uploader = require('../../helpers/uploader');
  8. var importer = require('../../helpers/importer');
  9. var bcrypt = require('bcryptjs');
  10. var crypto = require('crypto');
  11. var swig = require('swig');
  12. var async = require('async');
  13. var _ = require('underscore');
  14. var fs = require('fs');
  15. var request = require('request');
  16. var gm = require('gm');
  17. var validator = require('validator');
  18. var URL = require('url').URL;
  19. var express = require('express');
  20. var router = express.Router();
  21. var glob = require('glob');
  22. router.get('/current', function(req, res, next) {
  23. if (req.user) {
  24. var u = _.clone(req.user.dataValues);
  25. delete u.password_hash;
  26. delete u.password_reset_token;
  27. delete u.confirmation_token;
  28. u.token = req.cookies['sdsession'];
  29. console.log(u);
  30. res.status(200).json(u);
  31. } else {
  32. res.status(401).json({"error":"user_not_found"});
  33. }
  34. });
  35. // create user
  36. router.post('/', function(req, res) {
  37. if (!req.body["email"] || !req.body["password"]) {
  38. res.status(400).json({"error":"email or password missing"});
  39. return;
  40. }
  41. var email = req.body["email"].toLowerCase();
  42. var nickname = req.body["nickname"];
  43. var password = req.body["password"];
  44. var password_confirmation = req.body["password_confirmation"];
  45. if (password_confirmation != password) {
  46. res.status(400).json({"error":"password_confirmation"});
  47. return;
  48. }
  49. if (!validator.isEmail(email)) {
  50. res.status(400).json({"error":"email_invalid"});
  51. return;
  52. }
  53. var createUser = function() {
  54. bcrypt.genSalt(10, function(err, salt) {
  55. bcrypt.hash(password, salt, function(err, hash) {
  56. crypto.randomBytes(16, function(ex, buf) {
  57. var token = buf.toString('hex');
  58. var u = {
  59. _id: uuidv4(),
  60. email: email,
  61. account_type: "email",
  62. nickname: nickname,
  63. password_hash: hash,
  64. prefs_language: req.i18n.locale,
  65. confirmation_token: token
  66. };
  67. db.User.create(u)
  68. .error(err => {
  69. res.sendStatus(400);
  70. })
  71. .then(u => {
  72. var homeSpace = {
  73. _id: uuidv4(),
  74. name: req.i18n.__("home"),
  75. space_type: "folder",
  76. creator_id: u._id
  77. };
  78. db.Space.create(homeSpace)
  79. .error(err => {
  80. res.sendStatus(400);
  81. })
  82. .then(homeSpace => {
  83. u.home_folder_id = homeSpace._id;
  84. u.save()
  85. .then(() => {
  86. res.status(201).json({});
  87. mailer.sendMail(u.email, req.i18n.__("confirm_subject"), req.i18n.__("confirm_body"), {
  88. action: {
  89. link: config.endpoint + "/confirm/" + u.confirmation_token,
  90. name: req.i18n.__("confirm_action")
  91. }
  92. });
  93. })
  94. .error(err => {
  95. res.status(400).json(err);
  96. });
  97. })
  98. });
  99. });
  100. });
  101. });
  102. };
  103. db.User.findAll({where: {email: email}})
  104. .then(users => {
  105. if (users.length == 0) {
  106. //var domain = email.slice(email.lastIndexOf('@')+1);
  107. createUser();
  108. } else {
  109. res.status(400).json({"error":"user_email_already_used"});
  110. }
  111. })
  112. });
  113. router.get('/current', function(req, res, next) {
  114. if (req.user) {
  115. res.status(200).json(req.user);
  116. } else {
  117. res.status(401).json({"error":"user_not_found"});
  118. }
  119. });
  120. router.put('/:id', function(req, res, next) {
  121. // TODO explicit whitelisting
  122. var user = req.user;
  123. if (user._id == req.params.id) {
  124. var newAttr = req.body;
  125. newAttr.updated_at = new Date();
  126. delete newAttr['_id'];
  127. db.User.update(newAttr, {where: {"_id": user._id}}).then(function(updatedUser) {
  128. res.status(200).json(newAttr);
  129. });
  130. } else {
  131. res.sendStatus(403);
  132. }
  133. });
  134. router.post('/:id/password', function(req, res, next) {
  135. var user = req.user;
  136. var old_password = req.body.old_password;
  137. var pass = req.body.new_password;
  138. if (pass.length >= 6) {
  139. if (user._id == req.params.id) {
  140. if (bcrypt.compareSync(old_password, user.password_hash)) {
  141. bcrypt.genSalt(10, function(err, salt) {
  142. bcrypt.hash(pass, salt, function(err, hash) {
  143. user.password_hash = hash;
  144. user.save().then(function() {
  145. res.sendStatus(204);
  146. });
  147. });
  148. });
  149. } else {
  150. res.status(403).json({"error": "old password wrong"});
  151. }
  152. } else {
  153. res.status(403).json({"error": "wrong user"});
  154. }
  155. } else {
  156. res.status(400).json({"error": "password_to_short"});
  157. }
  158. });
  159. router.delete('/:id', (req, res, next) => {
  160. const user = req.user;
  161. if(user._id == req.params.id) {
  162. if (user.account_type == 'email') {
  163. if (bcrypt.compareSync(req.query.password, user.password_hash)) {
  164. user.remove((err) => {
  165. if(err)res.status(400).json(err);
  166. else res.sendStatus(204);
  167. });
  168. } else {
  169. res.bad_request("password_incorrect");
  170. }
  171. } else {
  172. user.remove((err) => {
  173. if (err) res.status(400).json(err);
  174. else res.sendStatus(204);
  175. });
  176. }
  177. }
  178. else res.status(403).json({error: ""});
  179. });
  180. router.put('/:user_id/confirm', (req, res) => {
  181. const token = req.body.token;
  182. const user = req.user;
  183. if (user.confirmation_token === token) {
  184. user.confirmation_token = null;
  185. user.confirmed_at = new Date();
  186. user.save(function(err, updatedUser) {
  187. if(err) {
  188. res.sendStatus(400);
  189. } else {
  190. res.status(200).json(updatedUser);
  191. }
  192. });
  193. } else {
  194. res.sendStatus(400);
  195. }
  196. });
  197. router.post('/:user_id/avatar', (req, res, next) => {
  198. const user = req.user;
  199. const filename = "u"+req.user._id+"_"+(new Date().getTime())+".jpeg"
  200. const localFilePath = os.tmpdir()+"/"+filename;
  201. const localResizedFilePath = os.tmpdir()+"/resized_"+filename;
  202. const writeStream = fs.createWriteStream(localFilePath);
  203. const stream = req.pipe(writeStream);
  204. req.on('end', function() {
  205. gm(localFilePath).resize(200, 200).autoOrient().write(localResizedFilePath, (err) => {
  206. if (err) res.status(400).json(err);
  207. else {
  208. uploader.uploadFile(filename, "image/jpeg", localResizedFilePath, (err, url) => {
  209. if (err) res.status(400).json(err);
  210. else {
  211. user.avatar_thumb_uri = url;
  212. user.save().then(() => {
  213. fs.unlink(localResizedFilePath, (err) => {
  214. if (err) {
  215. console.error(err);
  216. res.status(400).json(err);
  217. } else {
  218. res.status(200).json(user);
  219. }
  220. });
  221. });
  222. }
  223. });
  224. }
  225. });
  226. });
  227. });
  228. router.post('/feedback', function(req, res, next) {
  229. var text = req.body.text;
  230. // FIXME
  231. mailer.sendMail("support@example.org", "Support Request by " + req.user.email, text, {reply_to: req.user.email});
  232. res.sendStatus(201);
  233. });
  234. router.post('/password_reset_requests', (req, res, next) => {
  235. const email = req.query.email;
  236. db.User.findOne({where: {"email": email}}).then((user) => {
  237. if (user) {
  238. crypto.randomBytes(16, (ex, buf) => {
  239. user.password_reset_token = buf.toString('hex');
  240. user.save().then(updatedUser => {
  241. mailer.sendMail(email, req.i18n.__("password_reset_subject"), req.i18n.__("password_reset_body"), {action: {
  242. link: config.endpoint + "/password-confirm/" + user.password_reset_token,
  243. name: req.i18n.__("password_reset_action")
  244. }});
  245. res.status(201).json({});
  246. });
  247. });
  248. } else {
  249. res.status(404).json({"error": "error_unknown_email"});
  250. }
  251. });
  252. });
  253. router.post('/password_reset_requests/:confirm_token/confirm', function(req, res, next) {
  254. var password = req.body.password;
  255. db.User
  256. .findOne({where: {"password_reset_token": req.params.confirm_token}})
  257. .then((user) => {
  258. if (user) {
  259. bcrypt.genSalt(10, (err, salt) => {
  260. bcrypt.hash(password, salt, function(err, hash) {
  261. user.password_hash = hash;
  262. user.password_token = null;
  263. user.save(function(err, updatedUser){
  264. if (err) {
  265. res.sendStatus(400);
  266. } else {
  267. res.sendStatus(201);
  268. }
  269. });
  270. });
  271. });
  272. } else {
  273. res.sendStatus(404);
  274. }
  275. });
  276. });
  277. router.post('/:user_id/confirm', function(req, res, next) {
  278. mailer.sendMail(req.user.email, req.i18n.__("confirm_subject"), req.i18n.__("confirm_body"), { action:{
  279. link: config.endpoint + "/confirm/" + req.user.confirmation_token,
  280. name: req.i18n.__("confirm_action")
  281. }});
  282. res.sendStatus(201);
  283. });
  284. router.get('/:user_id/importables', function(req, res, next) {
  285. glob('*.zip', function(err, files) {
  286. res.status(200).json(files);
  287. });
  288. });
  289. router.get('/:user_id/import', function(req, res, next) {
  290. if (req.query.zip) {
  291. res.send("importing");
  292. importer.importZIP(req.user, req.query.zip);
  293. } else {
  294. res.sendStatus(400);
  295. }
  296. });
  297. module.exports = router;