From 6469ac42034ba6e49504f407cd208cc03d9f855c Mon Sep 17 00:00:00 2001 From: Justin Nguyen Date: Tue, 30 Apr 2024 21:33:18 -0700 Subject: [PATCH 1/3] feat: hashed emails with sha-256 before being stored --- packages/server/controllers/auth.js | 16 +++++++++++++--- packages/server/controllers/users.js | 11 +++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/server/controllers/auth.js b/packages/server/controllers/auth.js index 2ad2e072..4cec297f 100644 --- a/packages/server/controllers/auth.js +++ b/packages/server/controllers/auth.js @@ -5,6 +5,7 @@ const token = require("../utils/token"); const bcrypt = require("bcrypt"); const client = new OAuth2Client(process.env.WEB_CLIENT_ID); const nodemailer = require("nodemailer"); +const crypto = require("node:crypto"); const NAMESPACE = "7af17462-8078-4703-adda-be2143a4d93a"; @@ -13,6 +14,9 @@ async function create(accessToken, refreshToken, profile, callback) { let { sub, given_name, family_name, picture, email } = profile._json; picture = picture.replace("=s96-c", ""); const googleUUID = uuidv5(sub, NAMESPACE); + const hash = crypto.createHash("sha256"); + hash.update(email); + const emailHash = hash.digest("hex"); const user = await prisma.user.findUniqueOrThrow({ where: { userId: googleUUID, @@ -22,7 +26,7 @@ async function create(accessToken, refreshToken, profile, callback) { const newUser = await prisma.user.create({ data: { userId: googleUUID, - email: email, + email: emailHash, avatar: picture, firstName: given_name, lastName: family_name, @@ -82,6 +86,9 @@ async function register(newUser) { const salt = await bcrypt.genSalt(saltRounds); const passwordHash = await bcrypt.hash(newUser.password, salt); const userId = uuidv4(); + const hash = crypto.createHash("sha256"); + hash.update(newUser.email); + const emailHash = hash.digest("hex"); // placeholder names until new user puts in their names in onboarding screen return await prisma.user.create({ @@ -89,7 +96,7 @@ async function register(newUser) { userId, firstName: "New", lastName: "User", - email: newUser.email, + email: emailHash, password: passwordHash, }, }); @@ -191,9 +198,12 @@ async function authenticate(request, response, next) { } async function isUserEmail(email) { + const hash = crypto.createHash("sha256"); + hash.update(email); + const emailHash = hash.digest("hex"); const result = await prisma.user.findUnique({ where: { - email: email, + email: emailHash, }, }); diff --git a/packages/server/controllers/users.js b/packages/server/controllers/users.js index 7bb090ff..28a73a68 100644 --- a/packages/server/controllers/users.js +++ b/packages/server/controllers/users.js @@ -1,4 +1,5 @@ const prisma = require("../prisma/prisma"); +const crypto = require("node:crypto"); async function getAllUsers() { const query = await prisma.user.findMany(); @@ -24,18 +25,24 @@ async function getUserEmail(userId) { } async function getUserByEmail(email) { + const hash = crypto.createHash("sha256"); + hash.update(email); + const emailHash = hash.digest("hex"); const query = await prisma.user.findUnique({ where: { - email: email, + email: emailHash, }, }); return query; } async function getUserIdByEmail(email) { + const hash = crypto.createHash("sha256"); + hash.update(email); + const emailHash = hash.digest("hex"); const query = await prisma.user.findUnique({ where: { - email: email, + email: emailHash, }, }); return query.userId; From b504778667ccd815dcd0b92d10d657f947b76238 Mon Sep 17 00:00:00 2001 From: Justin Nguyen Date: Sat, 4 May 2024 11:19:07 -0700 Subject: [PATCH 2/3] fix: created a function to hash emails that can be called --- packages/server/controllers/auth.js | 14 ++++---------- packages/server/controllers/users.js | 16 ++++++++++------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/server/controllers/auth.js b/packages/server/controllers/auth.js index 4cec297f..2457774e 100644 --- a/packages/server/controllers/auth.js +++ b/packages/server/controllers/auth.js @@ -5,7 +5,7 @@ const token = require("../utils/token"); const bcrypt = require("bcrypt"); const client = new OAuth2Client(process.env.WEB_CLIENT_ID); const nodemailer = require("nodemailer"); -const crypto = require("node:crypto"); +const UserController = require("../../controllers/users"); const NAMESPACE = "7af17462-8078-4703-adda-be2143a4d93a"; @@ -14,9 +14,7 @@ async function create(accessToken, refreshToken, profile, callback) { let { sub, given_name, family_name, picture, email } = profile._json; picture = picture.replace("=s96-c", ""); const googleUUID = uuidv5(sub, NAMESPACE); - const hash = crypto.createHash("sha256"); - hash.update(email); - const emailHash = hash.digest("hex"); + const emailHash = await UserController.hashUserEmail(email); const user = await prisma.user.findUniqueOrThrow({ where: { userId: googleUUID, @@ -86,9 +84,7 @@ async function register(newUser) { const salt = await bcrypt.genSalt(saltRounds); const passwordHash = await bcrypt.hash(newUser.password, salt); const userId = uuidv4(); - const hash = crypto.createHash("sha256"); - hash.update(newUser.email); - const emailHash = hash.digest("hex"); + const emailHash = await UserController.hashUserEmail(newUser.email); // placeholder names until new user puts in their names in onboarding screen return await prisma.user.create({ @@ -198,9 +194,7 @@ async function authenticate(request, response, next) { } async function isUserEmail(email) { - const hash = crypto.createHash("sha256"); - hash.update(email); - const emailHash = hash.digest("hex"); + const emailHash = await UserController.hashUserEmail(email); const result = await prisma.user.findUnique({ where: { email: emailHash, diff --git a/packages/server/controllers/users.js b/packages/server/controllers/users.js index 28a73a68..7185f7f5 100644 --- a/packages/server/controllers/users.js +++ b/packages/server/controllers/users.js @@ -25,9 +25,7 @@ async function getUserEmail(userId) { } async function getUserByEmail(email) { - const hash = crypto.createHash("sha256"); - hash.update(email); - const emailHash = hash.digest("hex"); + const emailHash = hashUserEmail(email); const query = await prisma.user.findUnique({ where: { email: emailHash, @@ -37,9 +35,7 @@ async function getUserByEmail(email) { } async function getUserIdByEmail(email) { - const hash = crypto.createHash("sha256"); - hash.update(email); - const emailHash = hash.digest("hex"); + const emailHash = hashUserEmail(email); const query = await prisma.user.findUnique({ where: { email: emailHash, @@ -69,6 +65,13 @@ async function getGuildsForUser(userId) { return guilds; } +async function hashUserEmail(email) { + const hash = crypto.createHash("sha256"); + hash.update(email); + const emailHash = hash.digest("hex"); + return emailHash; +} + module.exports = { getUser, getAllUsers, @@ -76,4 +79,5 @@ module.exports = { getGuildsForUser, getUserIdByEmail, getUserEmail, + hashUserEmail, }; From 3353e0c65e9bd30bfeaa7e315ae3ca719acf2ceb Mon Sep 17 00:00:00 2001 From: Justin Nguyen Date: Thu, 16 May 2024 16:04:40 -0700 Subject: [PATCH 3/3] fix: updated changes to check against email hash --- packages/server/controllers/auth.js | 14 +++----------- packages/server/controllers/users.js | 14 ++++---------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/packages/server/controllers/auth.js b/packages/server/controllers/auth.js index 2457774e..2cc2ac56 100644 --- a/packages/server/controllers/auth.js +++ b/packages/server/controllers/auth.js @@ -5,7 +5,7 @@ const token = require("../utils/token"); const bcrypt = require("bcrypt"); const client = new OAuth2Client(process.env.WEB_CLIENT_ID); const nodemailer = require("nodemailer"); -const UserController = require("../../controllers/users"); +const UserController = require("./users"); const NAMESPACE = "7af17462-8078-4703-adda-be2143a4d93a"; @@ -194,16 +194,8 @@ async function authenticate(request, response, next) { } async function isUserEmail(email) { - const emailHash = await UserController.hashUserEmail(email); - const result = await prisma.user.findUnique({ - where: { - email: emailHash, - }, - }); - - if (result === null) return false; - - return true; + const user = await UserController.getUserByEmail(email); + return !!user; } async function isGoogleAccount(userId) { diff --git a/packages/server/controllers/users.js b/packages/server/controllers/users.js index 7185f7f5..839a5942 100644 --- a/packages/server/controllers/users.js +++ b/packages/server/controllers/users.js @@ -25,23 +25,17 @@ async function getUserEmail(userId) { } async function getUserByEmail(email) { - const emailHash = hashUserEmail(email); - const query = await prisma.user.findUnique({ + const emailHash = await hashUserEmail(email); + return prisma.user.findUnique({ where: { email: emailHash, }, }); - return query; } async function getUserIdByEmail(email) { - const emailHash = hashUserEmail(email); - const query = await prisma.user.findUnique({ - where: { - email: emailHash, - }, - }); - return query.userId; + const user = await getUserByEmail(email); + return user ? user.userId : null; } async function getGuildsForUser(userId) {