UserSystem.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. const express = require('express');
  2. const path = require('path');
  3. const bcrypt = require('bcrypt');
  4. const util = require('util');
  5. const Actions = require('./ActionSystem');
  6. const RepositorySystem = require('./RepositorySystem');
  7. const RoutingSystem = require('./RoutingSystem');
  8. const Mail = require('./MailSystem');
  9. const Logger = require('./LoggerSystem');
  10. const Config = require('./config');
  11. let UserConfig = {
  12. fields: [
  13. {
  14. key: "email",
  15. type: "text"
  16. },
  17. {
  18. key: "username",
  19. type: "text"
  20. },
  21. {
  22. key:"password",
  23. type: "text"
  24. },
  25. {
  26. key:"token",
  27. type: "text"
  28. },
  29. {
  30. key:"role",
  31. type: "integer"
  32. },
  33. {
  34. key: "enable",
  35. type: "integer",
  36. defaultsTo: 0
  37. }
  38. ]
  39. }
  40. class UserSystem {
  41. constructor(){
  42. this.repository = RepositorySystem.create('Users', UserConfig);
  43. this.Middleware = this._middleware.bind(this);
  44. let mainroutes = [
  45. {
  46. type: 'custom',
  47. method: 'post',
  48. endpoint: '/login',
  49. customFn: (req, res) => this.login(req.body.username, req.body.password)
  50. .then((a) => res.send(a))
  51. .catch((e) => {
  52. if(e.message === "403")
  53. res.status(403).send();
  54. else
  55. res.sendStatus(400);
  56. })
  57. },
  58. {
  59. type: 'custom',
  60. method: 'get',
  61. endpoint: '/logout',
  62. customFn: (req, res) => this.logout(req)
  63. .then((a) => res.sendStatus(200))
  64. .catch((e) => res.sendStatus(400))
  65. },
  66. {
  67. type: 'custom',
  68. method: 'post',
  69. endpoint: '/register',
  70. customFn: (req, res) => this.register(req.body.email,req.body.username, req.body.password)
  71. .then((a) => res.send(a))
  72. .catch((e) => {
  73. console.log(e.message);
  74. if(e.message === "Converting circular structure to JSON"){
  75. return res.sendStatus(200);
  76. }
  77. return res.sendStatus(400);
  78. })
  79. },
  80. {
  81. type: 'custom',
  82. method: 'get',
  83. endpoint: '/verifyemail',
  84. customFn: (req, res) => this.verifyemail(req.query.id)
  85. .then((a) => res.sendStatus(200))
  86. .catch((e) => {
  87. console.log(e.message);
  88. if(e.message === "Converting circular structure to JSON"){
  89. return res.sendStatus(200);
  90. }
  91. return res.sendStatus(400);
  92. })
  93. },
  94. {
  95. type: 'custom',
  96. method: 'post',
  97. endpoint: '/changepass',
  98. customFn: (req, res) => this.changepass(req.user, req.body.cpass,req.body.npass)
  99. .then((a) => res.status(200).send())
  100. .catch((e) => {
  101. console.log(e.message);
  102. if(e.message === "Converting circular structure to JSON"){
  103. return res.sendStatus(200);
  104. }
  105. return res.sendStatus(400);
  106. })
  107. },
  108. {
  109. type: 'custom',
  110. method: 'get',
  111. endpoint: '/me',
  112. customFn: (req, res) => {
  113. Actions.emit('getUsers', req.user)
  114. .then((user) => res.send(user))
  115. }
  116. }
  117. ];
  118. RoutingSystem.loadRoutes(mainroutes, this.router, '/users');
  119. }
  120. logout(req) {
  121. let userID = req.user.id;
  122. if(userID) {
  123. return this.repository.update(userID, { token: '' }).catch((e) => console.log(e, userID));
  124. } else {
  125. return Promise.resolve('Logged out!');
  126. }
  127. }
  128. verifyemail(id) {
  129. return this.repository.raw().where('password', 'like', '____' + id + '%')
  130. .then((data) => {
  131. if(!data.length) {
  132. throw new Error("No such user with verification id : " + id);
  133. }
  134. console.log(data);
  135. let user = data[0];
  136. return this.repository.update(user.id, {enable: true});
  137. });
  138. }
  139. register(email, username,password, role = 1){
  140. let data = {
  141. email,
  142. username,
  143. role
  144. };
  145. return this.repository.get('username',username)
  146. .then((data) => {
  147. if(data.length > 0) {
  148. throw Error('Already registered');
  149. }
  150. return true;
  151. })
  152. .then(() => {
  153. let hash = bcrypt.hash(password, 10);
  154. return hash;
  155. })
  156. .then((hash) => {
  157. data.password = hash;
  158. return Actions.emit('postUsers', data);
  159. })
  160. .then((data) => {
  161. return this.repository.insert(data).then(() => data);
  162. })
  163. .then((data) => {
  164. let {
  165. email,
  166. username,
  167. password
  168. } = data;
  169. let token = password.slice(4,20);
  170. Mail.send(
  171. email,
  172. Config.MAIL_WELCOME_SUBJECT.replace("{username}",username),
  173. Config.MAIL_WELCOME_TXT.replace("{token}", token),
  174. Config.MAIL_WELCOME_HTML.replace("{token}", token)
  175. )
  176. });
  177. }
  178. login(username,password){
  179. let id = -1;
  180. return this.repository.get('username', username)
  181. .then((data) => {
  182. if(data.length == 0){
  183. throw Error('no such user');
  184. }
  185. return data[0];
  186. })
  187. .then((user) =>{
  188. if(user.enable !== 1) {
  189. throw Error("403");
  190. }
  191. id = user.id;
  192. return bcrypt.compare(password,user.password)
  193. })
  194. .then((isPassCorrect) => {
  195. if(!isPassCorrect)
  196. throw Error('Wrong password');
  197. return bcrypt.genSaltSync(10);
  198. })
  199. .then((token) => this.repository.update(id, {token}).then(() => token))
  200. .then((token) => this.getByToken(token))
  201. .then((user) => Actions.emit("getUsers", user));
  202. }
  203. changepass(user, cpass, npass) {
  204. if(!user) {
  205. return Promise.reject('No user');
  206. }
  207. console.log(user, cpass, npass)
  208. return this.repository.get('id', user.id)
  209. .then((data) => {
  210. let user = data[0];
  211. if(!user) throw new Error("No user with id " + user.id);
  212. let p = user.password;
  213. return bcrypt.compare(cpass,p);
  214. })
  215. .then((isPassCorrect) => {
  216. if(!isPassCorrect)
  217. throw Error('Wrong password');
  218. return bcrypt.hash(npass, 10);
  219. })
  220. .then((hash) => {
  221. console.log("HASH : " , hash);
  222. return this.repository.update(user.id, {password: hash})
  223. });
  224. }
  225. getByToken(token){
  226. let user = null;
  227. return this.repository.get('token', token).then((data) => data[0]);
  228. }
  229. role(req, res, role) {
  230. // Need middleware on load
  231. if(req.user.role === undefined || req.user.role < role){
  232. //res.sendStatus(401);
  233. let e = new Error("401");
  234. e.status = 401;
  235. console.log(req.user)
  236. throw e;
  237. }
  238. }
  239. _middleware(req, res, next) {
  240. const token = req.headers.token;
  241. if(!token || token.length < 5){
  242. req.user = {
  243. ip : req.connection.remoteAddress,
  244. role: 0
  245. };
  246. return next();
  247. } else {
  248. this.repository.get('token',token)
  249. .then((data)=> {
  250. req.user = data[0] || {role: 0};
  251. req.user.ip = req.connection.remoteAddress;
  252. next();
  253. }).catch((error)=> {
  254. console.log("Cannot parseToken");
  255. Logger.error(error);
  256. res.status(401).send({message:"Cannot parse token. Access denied!"});
  257. });
  258. }
  259. }
  260. }
  261. module.exports = new UserSystem()