user.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. const bcrypt = require('bcryptjs');
  2. const nanoid = require('nanoid');
  3. const driver = require('./neo4j');
  4. exports.getUser = ({ email = '', apikey = '' }) =>
  5. new Promise((resolve, reject) => {
  6. const session = driver.session();
  7. session
  8. .readTransaction(tx =>
  9. tx.run(
  10. 'MATCH (u:USER) WHERE u.email = $email OR u.apikey = $apikey ' +
  11. 'OPTIONAL MATCH (u)-[:OWNS]->(l) RETURN u, l',
  12. {
  13. apikey,
  14. email,
  15. }
  16. )
  17. )
  18. .then(res => {
  19. session.close();
  20. const user = res.records.length && res.records[0].get('u').properties;
  21. const domainProps = res.records.length && res.records[0].get('l');
  22. const domain = domainProps ? domainProps.properties.name : '';
  23. return resolve(user && { ...user, domain });
  24. })
  25. .catch(err => reject(err));
  26. });
  27. exports.createUser = ({ email, password }) =>
  28. new Promise(async (resolve, reject) => {
  29. const session = driver.session();
  30. const salt = await bcrypt.genSalt(12);
  31. const hash = await bcrypt.hash(password, salt);
  32. const verificationToken = nanoid(40);
  33. session
  34. .writeTransaction(tx =>
  35. tx.run(
  36. 'MERGE (u:USER { email: $email }) ' +
  37. 'SET u.password = $hash , u.verified = $verified , ' +
  38. 'u.verificationToken = $verificationToken , u.createdAt = $createdAt ' +
  39. 'RETURN u',
  40. {
  41. email,
  42. hash,
  43. createdAt: new Date().toJSON(),
  44. verified: false,
  45. verificationToken,
  46. }
  47. )
  48. )
  49. .then(res => {
  50. session.close();
  51. const user = res.records[0].get('u').properties;
  52. return resolve(user);
  53. })
  54. .catch(err => reject(err));
  55. });
  56. exports.verifyUser = ({ verificationToken }) =>
  57. new Promise((resolve, reject) => {
  58. const session = driver.session();
  59. session
  60. .writeTransaction(tx =>
  61. tx.run(
  62. 'MATCH (u:USER { verificationToken: $verificationToken })' +
  63. 'SET u.verified = true SET u.verificationToken = NULL RETURN u',
  64. {
  65. verificationToken,
  66. }
  67. )
  68. )
  69. .then(({ records }) => {
  70. session.close();
  71. const user = records.length && records[0].get('u').properties;
  72. return resolve(user);
  73. })
  74. .catch(err => reject(err));
  75. });
  76. exports.changePassword = ({ email, password }) =>
  77. new Promise(async (resolve, reject) => {
  78. const session = driver.session();
  79. const salt = await bcrypt.genSalt(12);
  80. const hash = await bcrypt.hash(password, salt);
  81. session
  82. .writeTransaction(tx =>
  83. tx.run('MATCH (u:USER { email: $email }) SET u.password = $password RETURN u', {
  84. email,
  85. password: hash,
  86. })
  87. )
  88. .then(res => {
  89. session.close();
  90. const user = res.records.length && res.records[0].get('u').properties;
  91. return resolve(user);
  92. })
  93. .catch(() => session.close() && reject);
  94. });
  95. exports.generateApiKey = ({ email }) =>
  96. new Promise(async (resolve, reject) => {
  97. const session = driver.session();
  98. const apikey = nanoid(40);
  99. session
  100. .writeTransaction(tx =>
  101. tx.run('MATCH (u:USER { email: $email }) SET u.apikey = $apikey RETURN u', {
  102. email,
  103. apikey,
  104. })
  105. )
  106. .then(res => {
  107. session.close();
  108. const newApikey = res.records.length && res.records[0].get('u').properties.apikey;
  109. return resolve({ apikey: newApikey });
  110. })
  111. .catch(() => session.close() && reject);
  112. });
  113. exports.requestPasswordReset = ({ email }) =>
  114. new Promise(async (resolve, reject) => {
  115. const session = driver.session();
  116. const resetPasswordExprie = Date.now() + 3600000;
  117. const resetPasswordToken = nanoid(40);
  118. session
  119. .writeTransaction(tx =>
  120. tx.run(
  121. 'MATCH (u:USER { email: $email }) ' +
  122. 'SET u.resetPasswordToken = $resetPasswordToken ' +
  123. 'SET u.resetPasswordExprie = $resetPasswordExprie ' +
  124. 'RETURN u',
  125. {
  126. email,
  127. resetPasswordExprie,
  128. resetPasswordToken,
  129. }
  130. )
  131. )
  132. .then(res => {
  133. session.close();
  134. const user = res.records.length && res.records[0].get('u').properties;
  135. return resolve(user);
  136. })
  137. .catch(() => session.close() && reject);
  138. });
  139. exports.resetPassword = ({ resetPasswordToken }) =>
  140. new Promise((resolve, reject) => {
  141. const session = driver.session();
  142. session
  143. .writeTransaction(tx =>
  144. tx.run(
  145. 'MATCH (u:USER { resetPasswordToken: $resetPasswordToken })' +
  146. 'SET u.resetPasswordExprie = NULL SET u.resetPasswordToken = NULL RETURN u',
  147. {
  148. resetPasswordToken,
  149. }
  150. )
  151. )
  152. .then(({ records }) => {
  153. session.close();
  154. const user = records.length && records[0].get('u').properties;
  155. return resolve(user);
  156. })
  157. .catch(err => reject(err));
  158. });
  159. exports.addCooldown = ({ email }) =>
  160. new Promise((resolve, reject) => {
  161. const session = driver.session();
  162. session
  163. .writeTransaction(tx =>
  164. tx.run(
  165. 'MATCH (u:USER { email: $email }) ' +
  166. 'MERGE (u)-[r:RECEIVED]->(c:COOLDOWN { date: $date }) ' +
  167. 'RETURN COUNT(r) as count',
  168. {
  169. date: new Date().toJSON(),
  170. email,
  171. }
  172. )
  173. )
  174. .then(({ records }) => {
  175. session.close();
  176. const count = records.length && records[0].get('count').toNumber();
  177. return resolve({ count });
  178. })
  179. .catch(err => reject(err));
  180. });
  181. exports.getCooldowns = ({ email }) =>
  182. new Promise((resolve, reject) => {
  183. const session = driver.session();
  184. session
  185. .writeTransaction(tx =>
  186. tx.run(
  187. 'MATCH (u:USER { email: $email }) MATCH (u)-[r:RECEIVED]->(c) RETURN c.date as date',
  188. {
  189. date: new Date().toJSON(),
  190. email,
  191. }
  192. )
  193. )
  194. .then(({ records = [] }) => {
  195. session.close();
  196. const cooldowns = records.map(record => record.get('date'));
  197. return resolve({ cooldowns });
  198. })
  199. .catch(err => reject(err));
  200. });
  201. exports.banUser = ({ email }) =>
  202. new Promise((resolve, reject) => {
  203. const session = driver.session();
  204. session
  205. .writeTransaction(tx =>
  206. tx.run('MATCH (u:USER { email: $email }) SET u.banned = true RETURN u', {
  207. email,
  208. })
  209. )
  210. .then(({ records = [] }) => {
  211. session.close();
  212. const user = records.length && records[0].get('u');
  213. return resolve({ user });
  214. })
  215. .catch(err => reject(err));
  216. });