user.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import bcrypt from 'bcryptjs';
  2. import { Types } from 'mongoose';
  3. import nanoid from 'nanoid';
  4. import uuid from 'uuid/v4';
  5. import addMinutes from 'date-fns/add_minutes';
  6. import User from '../models/user';
  7. import * as redis from '../redis';
  8. export const getUser = async (emailOrKey: string = '') => {
  9. const cachedUser = await redis.get(emailOrKey);
  10. if (cachedUser) return JSON.parse(cachedUser);
  11. const user = await User.findOne({
  12. $or: [{ email: emailOrKey }, { apikey: emailOrKey }],
  13. })
  14. .populate('domain')
  15. .lean();
  16. redis.set(emailOrKey, JSON.parse(user), 'EX', 60 * 60 * 1);
  17. return user;
  18. };
  19. export const createUser = async (email: string, password: string) => {
  20. const salt = await bcrypt.genSalt(12);
  21. const hashedPassword = await bcrypt.hash(password, salt);
  22. const user = await User.findOneAndUpdate(
  23. { email },
  24. {
  25. email,
  26. password: hashedPassword,
  27. verificationToken: uuid(),
  28. verificationExpires: addMinutes(new Date(), 60),
  29. },
  30. { new: true, upsert: true, runValidators: true, setDefaultsOnInsert: true }
  31. );
  32. redis.del(user.email);
  33. return user;
  34. };
  35. export const verifyUser = async (verificationToken: string) => {
  36. const user = await User.findOneAndUpdate(
  37. { verificationToken, verificationExpires: { $gt: new Date() } },
  38. {
  39. verified: true,
  40. verificationToken: undefined,
  41. verificationExpires: undefined,
  42. },
  43. { new: true }
  44. );
  45. redis.del(user.email);
  46. return user;
  47. };
  48. export const changePassword = async (
  49. id: Types.ObjectId,
  50. newPassword: string
  51. ) => {
  52. const salt = await bcrypt.genSalt(12);
  53. const password = await bcrypt.hash(newPassword, salt);
  54. const user = await User.findByIdAndUpdate(id, { password }, { new: true });
  55. redis.del(user.email);
  56. redis.del(user.apikey);
  57. return user;
  58. };
  59. export const generateApiKey = async (id: Types.ObjectId) => {
  60. const apikey = nanoid(40);
  61. const user = await User.findByIdAndUpdate(id, { apikey });
  62. redis.del(user.email);
  63. redis.del(user.apikey);
  64. return { ...user, apikey };
  65. };
  66. export const requestPasswordReset = async (email: string) => {
  67. const resetPasswordToken = uuid();
  68. const user = await User.findOneAndUpdate(
  69. { email },
  70. {
  71. resetPasswordToken,
  72. resetPasswordExpires: addMinutes(new Date(), 30),
  73. },
  74. { new: true }
  75. );
  76. redis.del(user.email);
  77. redis.del(user.apikey);
  78. return user;
  79. };
  80. export const resetPassword = async (resetPasswordToken: string) => {
  81. const user = await User.findOneAndUpdate(
  82. { resetPasswordToken, resetPasswordExpires: { $gt: new Date() } },
  83. { resetPasswordExpires: undefined, resetPasswordToken: undefined },
  84. { new: true }
  85. );
  86. redis.del(user.email);
  87. redis.del(user.apikey);
  88. return user;
  89. };
  90. export const addCooldown = async (id: Types.ObjectId) => {
  91. const user = await User.findByIdAndUpdate(
  92. id,
  93. { $push: { cooldowns: new Date() } },
  94. { new: true }
  95. );
  96. redis.del(user.email);
  97. redis.del(user.apikey);
  98. return user;
  99. };
  100. export const banUser = async (
  101. id: Types.ObjectId,
  102. bannedBy?: Types.ObjectId
  103. ) => {
  104. const user = await User.findByIdAndUpdate(
  105. id,
  106. {
  107. banned: true,
  108. bannedBy,
  109. },
  110. { new: true }
  111. );
  112. redis.del(user.email);
  113. redis.del(user.apikey);
  114. return user;
  115. };