From d657f4091ab4b7193370d35b3825cf6edb472af6 Mon Sep 17 00:00:00 2001 From: forehalo Date: Mon, 6 May 2024 11:11:56 +0000 Subject: [PATCH] fix(server): do not allow registration through gql (#6775) --- .../backend/server/src/core/auth/resolver.ts | 35 --------------- .../backend/server/src/core/user/service.ts | 35 ++++++++++----- packages/backend/server/tests/utils/user.ts | 43 ++++++------------- 3 files changed, 39 insertions(+), 74 deletions(-) diff --git a/packages/backend/server/src/core/auth/resolver.ts b/packages/backend/server/src/core/auth/resolver.ts index 3231a1d083..74e13e3e96 100644 --- a/packages/backend/server/src/core/auth/resolver.ts +++ b/packages/backend/server/src/core/auth/resolver.ts @@ -1,7 +1,6 @@ import { BadRequestException, ForbiddenException } from '@nestjs/common'; import { Args, - Context, Field, Mutation, ObjectType, @@ -10,7 +9,6 @@ import { ResolveField, Resolver, } from '@nestjs/graphql'; -import type { Request, Response } from 'express'; import { Config, SkipThrottle, Throttle } from '../../fundamentals'; import { UserService } from '../user'; @@ -79,39 +77,6 @@ export class AuthResolver { }; } - @Public() - @Mutation(() => UserType) - async signUp( - @Context() ctx: { req: Request; res: Response }, - @Args('name') name: string, - @Args('email') email: string, - @Args('password') password: string - ) { - if (!this.config.auth.allowSignup) { - throw new ForbiddenException('You are not allowed to sign up.'); - } - - validators.assertValidCredential({ email, password }); - const user = await this.auth.signUp(name, email, password); - await this.auth.setCookie(ctx.req, ctx.res, user); - ctx.req.user = user; - return user; - } - - @Public() - @Mutation(() => UserType) - async signIn( - @Context() ctx: { req: Request; res: Response }, - @Args('email') email: string, - @Args('password') password: string - ) { - validators.assertValidEmail(email); - const user = await this.auth.signIn(email, password); - await this.auth.setCookie(ctx.req, ctx.res, user); - ctx.req.user = user; - return user; - } - @Mutation(() => UserType) async changePassword( @CurrentUser() user: CurrentUser, diff --git a/packages/backend/server/src/core/user/service.ts b/packages/backend/server/src/core/user/service.ts index a85aaac37f..cc1e263846 100644 --- a/packages/backend/server/src/core/user/service.ts +++ b/packages/backend/server/src/core/user/service.ts @@ -35,6 +35,7 @@ export class UserService { async createUser(data: Prisma.UserCreateInput) { return this.prisma.user.create({ + select: this.defaultUserSelect, data: { ...this.userCreatingData, ...data, @@ -113,18 +114,32 @@ export class UserService { Pick > ) { - return this.prisma.user.upsert({ - select: this.defaultUserSelect, - where: { - email, - }, - update: data, - create: { - email, + const user = await this.findUserByEmail(email); + if (!user) { + return this.createUser({ ...this.userCreatingData, + email, + name: email.split('@')[0], ...data, - }, - }); + }); + } else { + if (user.registered) { + delete data.registered; + } + if (user.emailVerifiedAt) { + delete data.emailVerifiedAt; + } + + if (Object.keys(data).length) { + return await this.prisma.user.update({ + select: this.defaultUserSelect, + where: { id: user.id }, + data, + }); + } + } + + return user; } async deleteUser(id: string) { diff --git a/packages/backend/server/tests/utils/user.ts b/packages/backend/server/tests/utils/user.ts index feb807d3d4..dbc8465bd5 100644 --- a/packages/backend/server/tests/utils/user.ts +++ b/packages/backend/server/tests/utils/user.ts @@ -1,5 +1,5 @@ import type { INestApplication } from '@nestjs/common'; -import { PrismaClient } from '@prisma/client'; +import { hashSync } from '@node-rs/argon2'; import request, { type Response } from 'supertest'; import { @@ -7,7 +7,8 @@ import { type ClientTokenType, type CurrentUser, } from '../../src/core/auth'; -import type { UserType } from '../../src/core/user'; +import { sessionUser } from '../../src/core/auth/service'; +import { UserService, type UserType } from '../../src/core/user'; import { gql } from './common'; export async function internalSignIn(app: INestApplication, userId: string) { @@ -50,34 +51,18 @@ export async function signUp( password: string, autoVerifyEmail = true ): Promise { - const res = await request(app.getHttpServer()) - .post(gql) - .set({ 'x-request-id': 'test', 'x-operation-name': 'test' }) - .send({ - query: ` - mutation { - signUp(name: "${name}", email: "${email}", password: "${password}") { - id, name, email, token { token } - } - } - `, - }) - .expect(200); - - if (autoVerifyEmail) { - await setEmailVerified(app, email); - } - - return res.body.data.signUp; -} - -async function setEmailVerified(app: INestApplication, email: string) { - await app.get(PrismaClient).user.update({ - where: { email }, - data: { - emailVerifiedAt: new Date(), - }, + const user = await app.get(UserService).createUser({ + name, + email, + password: hashSync(password), + emailVerifiedAt: autoVerifyEmail ? new Date() : null, }); + const { sessionId } = await app.get(AuthService).createUserSession(user); + + return { + ...sessionUser(user), + token: { token: sessionId, refresh: '' }, + }; } export async function currentUser(app: INestApplication, token: string) {