🔐 fix: token not using webcrypto (#4005)

* fix: token

* style: auth pages updated `|` color
This commit is contained in:
Marco Beretta 2024-09-11 22:25:14 -04:00 committed by GitHub
parent aea01f0bc5
commit c3dc03b063
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 23 additions and 14 deletions

View file

@ -1,6 +1,5 @@
const crypto = require('crypto');
const bcrypt = require('bcryptjs');
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const { getRandomValues, hashToken } = require('~/server/utils/crypto');
const { createToken, findToken } = require('./Token'); const { createToken, findToken } = require('./Token');
const logger = require('~/config/winston'); const logger = require('~/config/winston');
@ -18,8 +17,8 @@ const logger = require('~/config/winston');
*/ */
const createInvite = async (email) => { const createInvite = async (email) => {
try { try {
let token = crypto.randomBytes(32).toString('hex'); const token = await getRandomValues(32);
const hash = bcrypt.hashSync(token, 10); const hash = await hashToken(token);
const encodedToken = encodeURIComponent(token); const encodedToken = encodeURIComponent(token);
const fakeUserId = new mongoose.Types.ObjectId(); const fakeUserId = new mongoose.Types.ObjectId();
@ -50,7 +49,7 @@ const createInvite = async (email) => {
const getInvite = async (encodedToken, email) => { const getInvite = async (encodedToken, email) => {
try { try {
const token = decodeURIComponent(encodedToken); const token = decodeURIComponent(encodedToken);
const hash = bcrypt.hashSync(token, 10); const hash = await hashToken(token);
const invite = await findToken({ token: hash, email }); const invite = await findToken({ token: hash, email });
if (!invite) { if (!invite) {
@ -59,7 +58,7 @@ const getInvite = async (encodedToken, email) => {
return invite; return invite;
} catch (error) { } catch (error) {
logger.error('[getInvite] Error getting invite', error); logger.error('[getInvite] Error getting invite:', error);
return { error: true, message: error.message }; return { error: true, message: error.message };
} }
}; };

View file

@ -102,4 +102,14 @@ async function hashToken(str) {
return Buffer.from(hashBuffer).toString('hex'); 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 };

View file

@ -99,8 +99,8 @@ const LoginForm: React.FC<TLoginFormProps> = ({ onSubmit, startupConfig, error,
aria-invalid={!!errors.email} aria-invalid={!!errors.email}
className=" className="
webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light 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=" " placeholder=" "
/> />
<label <label
@ -134,7 +134,7 @@ const LoginForm: React.FC<TLoginFormProps> = ({ onSubmit, startupConfig, error,
aria-invalid={!!errors.password} aria-invalid={!!errors.password}
className=" className="
webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light 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=" " placeholder=" "
/> />

View file

@ -71,7 +71,7 @@ const Registration: React.FC = () => {
aria-invalid={!!errors[id]} aria-invalid={!!errors[id]}
className=" className="
webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light 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=" " placeholder=" "
data-testid={id} data-testid={id}

View file

@ -106,7 +106,7 @@ function RequestPasswordReset() {
aria-invalid={!!errors.email} aria-invalid={!!errors.email}
className=" className="
webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light 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=" " placeholder=" "
/> />

View file

@ -91,7 +91,7 @@ function ResetPassword() {
aria-invalid={!!errors.password} aria-invalid={!!errors.password}
className=" className="
webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light 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=" " placeholder=" "
/> />
@ -126,7 +126,7 @@ function ResetPassword() {
aria-invalid={!!errors.confirm_password} aria-invalid={!!errors.confirm_password}
className=" className="
webkit-dark-styles transition-color peer w-full rounded-2xl border border-border-light 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=" " placeholder=" "
/> />