diff --git a/api/models/inviteUser.js b/api/models/inviteUser.js index c04bd9467a..6cd699fd66 100644 --- a/api/models/inviteUser.js +++ b/api/models/inviteUser.js @@ -1,6 +1,5 @@ -const crypto = require('crypto'); -const bcrypt = require('bcryptjs'); const mongoose = require('mongoose'); +const { getRandomValues, hashToken } = require('~/server/utils/crypto'); const { createToken, findToken } = require('./Token'); const logger = require('~/config/winston'); @@ -18,8 +17,8 @@ const logger = require('~/config/winston'); */ const createInvite = async (email) => { try { - let token = crypto.randomBytes(32).toString('hex'); - const hash = bcrypt.hashSync(token, 10); + const token = await getRandomValues(32); + const hash = await hashToken(token); const encodedToken = encodeURIComponent(token); const fakeUserId = new mongoose.Types.ObjectId(); @@ -50,7 +49,7 @@ const createInvite = async (email) => { const getInvite = async (encodedToken, email) => { try { const token = decodeURIComponent(encodedToken); - const hash = bcrypt.hashSync(token, 10); + const hash = await hashToken(token); const invite = await findToken({ token: hash, email }); if (!invite) { @@ -59,7 +58,7 @@ const getInvite = async (encodedToken, email) => { return invite; } catch (error) { - logger.error('[getInvite] Error getting invite', error); + logger.error('[getInvite] Error getting invite:', error); return { error: true, message: error.message }; } }; diff --git a/api/server/utils/crypto.js b/api/server/utils/crypto.js index c143506cc5..ea71df51ad 100644 --- a/api/server/utils/crypto.js +++ b/api/server/utils/crypto.js @@ -102,4 +102,14 @@ async function hashToken(str) { return Buffer.from(hashBuffer).toString('hex'); } -module.exports = { encrypt, decrypt, encryptV2, decryptV2, hashToken }; +async function getRandomValues(length) { + if (!Number.isInteger(length) || length <= 0) { + throw new Error('Length must be a positive integer'); + } + + const randomValues = new Uint8Array(length); + webcrypto.getRandomValues(randomValues); + return Buffer.from(randomValues).toString('hex'); +} + +module.exports = { encrypt, decrypt, encryptV2, decryptV2, hashToken, getRandomValues }; diff --git a/client/src/components/Auth/LoginForm.tsx b/client/src/components/Auth/LoginForm.tsx index fea8a61406..3404a78729 100644 --- a/client/src/components/Auth/LoginForm.tsx +++ b/client/src/components/Auth/LoginForm.tsx @@ -99,8 +99,8 @@ const LoginForm: React.FC = ({ onSubmit, startupConfig, error, aria-invalid={!!errors.email} className=" webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light - bg-surface-primary px-3.5 pb-2.5 pt-3 duration-200 focus:border-green-500 focus:outline-none - " + bg-surface-primary px-3.5 pb-2.5 pt-3 text-text-primary duration-200 focus:border-green-500 focus:outline-none + " placeholder=" " />