You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.4 KiB

11 months ago
  1. const { v4 } = require("uuid");
  2. const prisma = require("../utils/prisma");
  3. const bcrypt = require("bcrypt");
  4. const RecoveryCode = {
  5. tablename: "recovery_codes",
  6. writable: [],
  7. create: async function (userId, code) {
  8. try {
  9. const codeHash = await bcrypt.hash(code, 10);
  10. const recoveryCode = await prisma.recovery_codes.create({
  11. data: { user_id: userId, code_hash: codeHash },
  12. });
  13. return { recoveryCode, error: null };
  14. } catch (error) {
  15. console.error("FAILED TO CREATE RECOVERY CODE.", error.message);
  16. return { recoveryCode: null, error: error.message };
  17. }
  18. },
  19. createMany: async function (data) {
  20. try {
  21. const recoveryCodes = await prisma.$transaction(
  22. data.map((recoveryCode) =>
  23. prisma.recovery_codes.create({ data: recoveryCode })
  24. )
  25. );
  26. return { recoveryCodes, error: null };
  27. } catch (error) {
  28. console.error("FAILED TO CREATE RECOVERY CODES.", error.message);
  29. return { recoveryCodes: null, error: error.message };
  30. }
  31. },
  32. findFirst: async function (clause = {}) {
  33. try {
  34. const recoveryCode = await prisma.recovery_codes.findFirst({
  35. where: clause,
  36. });
  37. return recoveryCode;
  38. } catch (error) {
  39. console.error("FAILED TO FIND RECOVERY CODE.", error.message);
  40. return null;
  41. }
  42. },
  43. findMany: async function (clause = {}) {
  44. try {
  45. const recoveryCodes = await prisma.recovery_codes.findMany({
  46. where: clause,
  47. });
  48. return recoveryCodes;
  49. } catch (error) {
  50. console.error("FAILED TO FIND RECOVERY CODES.", error.message);
  51. return null;
  52. }
  53. },
  54. deleteMany: async function (clause = {}) {
  55. try {
  56. await prisma.recovery_codes.deleteMany({ where: clause });
  57. return true;
  58. } catch (error) {
  59. console.error("FAILED TO DELETE RECOVERY CODES.", error.message);
  60. return false;
  61. }
  62. },
  63. hashesForUser: async function (userId = null) {
  64. if (!userId) return [];
  65. return (await this.findMany({ user_id: userId })).map(
  66. (recovery) => recovery.code_hash
  67. );
  68. },
  69. };
  70. const PasswordResetToken = {
  71. tablename: "password_reset_tokens",
  72. resetExpiryMs: 600_000, // 10 minutes in ms;
  73. writable: [],
  74. calcExpiry: function () {
  75. return new Date(Date.now() + this.resetExpiryMs);
  76. },
  77. create: async function (userId) {
  78. try {
  79. const passwordResetToken = await prisma.password_reset_tokens.create({
  80. data: { user_id: userId, token: v4(), expiresAt: this.calcExpiry() },
  81. });
  82. return { passwordResetToken, error: null };
  83. } catch (error) {
  84. console.error("FAILED TO CREATE PASSWORD RESET TOKEN.", error.message);
  85. return { passwordResetToken: null, error: error.message };
  86. }
  87. },
  88. findUnique: async function (clause = {}) {
  89. try {
  90. const passwordResetToken = await prisma.password_reset_tokens.findUnique({
  91. where: clause,
  92. });
  93. return passwordResetToken;
  94. } catch (error) {
  95. console.error("FAILED TO FIND PASSWORD RESET TOKEN.", error.message);
  96. return null;
  97. }
  98. },
  99. deleteMany: async function (clause = {}) {
  100. try {
  101. await prisma.password_reset_tokens.deleteMany({ where: clause });
  102. return true;
  103. } catch (error) {
  104. console.error("FAILED TO DELETE PASSWORD RESET TOKEN.", error.message);
  105. return false;
  106. }
  107. },
  108. };
  109. module.exports = {
  110. RecoveryCode,
  111. PasswordResetToken,
  112. };