user.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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(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(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(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. });