From e6706ff950f067d715d74d03a5f42d0f38211f87 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Wed, 19 Feb 2020 16:05:53 +0100 Subject: [PATCH 1/3] Fix registration not using sCrypt for registration --- CHANGELOG.md | 1 + src/lib/dataAccess.ts | 39 +++++++++++++------------- src/routes/graphql/MutationResolver.ts | 6 +++- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef6c72..5c2e477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - sendRequest allowing duplicates - upload throwing an error when the old picture doesn't exist - extension of uploaded videos doesn't have a dot +- registration with empty username or password is possible ## [0.9] - 2019-10-29 diff --git a/src/lib/dataAccess.ts b/src/lib/dataAccess.ts index ffc860a..d339eb2 100644 --- a/src/lib/dataAccess.ts +++ b/src/lib/dataAccess.ts @@ -29,8 +29,9 @@ const scrKeyLength = 64; /** * Creates a random salt. */ -function generateSalt(): Buffer { - return crypto.randomBytes(32); +function generateSalt(): string { + const salt = crypto.randomBytes(32); + return Buffer.from(salt).toString("hex"); } /** @@ -58,11 +59,11 @@ function sha512HashPassword(password: string) { * Generates a new handle from the username and a base64 string of the current time. * @param username */ -async function generateHandle(username: string) { +async function generateHandle(username: string): Promise { username = username.toLowerCase().replace(/\s/g, "_"); const count = await models.User.count({where: {handle: {[sqz.Op.like]: `%${username}%`}}}); if (count > 0) { - return `${username}${count}`; + return await generateHandle(`${username}${count}`); } else { return username; } @@ -149,19 +150,18 @@ namespace dataaccess { */ export async function getUserByLogin(email: string, password: string): Promise { const user = await models.User.findOne({where: {email}}); - if (!user.salt) { - const hashPassword = sha512HashPassword(password); - if (hashPassword === user.password) { - const salt = generateSalt(); - user.salt = Buffer.from(salt).toString("hex"); - user.password = await scryptHashPassword(password, Buffer.from(user.salt)); - await user.save(); - password = user.password; - } - } else { - password = await scryptHashPassword(password, Buffer.from(user.salt)); - } if (user) { + if (!user.salt) { + const hashPassword = sha512HashPassword(password); + if (hashPassword === user.password) { + user.salt = generateSalt(); + user.password = await scryptHashPassword(password, Buffer.from(user.salt)); + await user.save(); + password = user.password; + } + } else { + password = await scryptHashPassword(password, Buffer.from(user.salt)); + } if (user.password === password) { return user; } else { @@ -191,13 +191,12 @@ namespace dataaccess { if (blacklisted.length > 0) { throw new BlacklistedError(blacklisted.map((p) => p.phrase), "username"); } - const hash = crypto.createHash("sha512"); - hash.update(password); - password = hash.digest("hex"); const existResult = !!(await models.User.findOne({where: {email}})); const handle = await generateHandle(username); if (!existResult) { - return models.User.create({username, email, password, handle}); + const salt = generateSalt(); + password = await scryptHashPassword(password, Buffer.from(salt)); + return models.User.create({username, email, password, handle, salt}); } else { throw new EmailAlreadyRegisteredError(email); } diff --git a/src/routes/graphql/MutationResolver.ts b/src/routes/graphql/MutationResolver.ts index 6e19237..52f400b 100644 --- a/src/routes/graphql/MutationResolver.ts +++ b/src/routes/graphql/MutationResolver.ts @@ -31,6 +31,7 @@ import { } from "../../lib/models"; import {Report} from "../../lib/models"; import {ReportReason} from "../../lib/models"; +import {is} from "../../lib/regex"; import {UploadManager} from "../../lib/UploadManager"; import {BaseResolver} from "./BaseResolver"; @@ -99,7 +100,10 @@ export class MutationResolver extends BaseResolver { */ public async register({username, email, passwordHash}: { username: string, email: string, passwordHash: string }, request: any): Promise { - let mailValid = isEmail(email); + if (username?.length === 0 || email?.length === 0 || passwordHash?.length === 0) { + throw new GraphQLError("No username or email or password given."); + } + let mailValid = is.email(email); if (mailValid) { try { mailValid = (await legit(email)).isValid; From fe75393ab0f0fca7ea410a34d9c50ff0b2363635 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Wed, 19 Feb 2020 16:06:47 +0100 Subject: [PATCH 2/3] Fix friend count --- src/lib/models/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/models/User.ts b/src/lib/models/User.ts index 56578b0..0457d02 100644 --- a/src/lib/models/User.ts +++ b/src/lib/models/User.ts @@ -312,7 +312,7 @@ export class User extends Model { * The total number of the users friends. */ public async friendCount(): Promise { - return await this.$count("rFriends") + await this.$count("rFriendOf"); + return this.$count("rFriends"); } /** From 3debe85daaa9654a535cbb384fdca1007782e822 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Wed, 19 Feb 2020 16:11:40 +0100 Subject: [PATCH 3/3] Fix tslint error --- src/routes/graphql/QueryResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/graphql/QueryResolver.ts b/src/routes/graphql/QueryResolver.ts index e5bd3ee..4df5664 100644 --- a/src/routes/graphql/QueryResolver.ts +++ b/src/routes/graphql/QueryResolver.ts @@ -17,7 +17,7 @@ import { Post, Report, ReportReason, Request, - User + User, } from "../../lib/models"; import {BlacklistedResult} from "./BlacklistedResult"; import {MutationResolver} from "./MutationResolver";