From deddb51c42e8c80a42953ce5398201dcb3d78a7d Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 12 Jan 2024 11:45:28 +0800 Subject: [PATCH 1/3] fix: change user email address after user deleted account --- packages/api/src/resolvers/user/index.ts | 4 +++- packages/api/test/resolvers/user.test.ts | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/api/src/resolvers/user/index.ts b/packages/api/src/resolvers/user/index.ts index 38b0111e2..dad2a13fa 100644 --- a/packages/api/src/resolvers/user/index.ts +++ b/packages/api/src/resolvers/user/index.ts @@ -320,9 +320,11 @@ export const deleteAccountResolver = authorized< DeleteAccountError, MutationDeleteAccountArgs >(async (_, { userID }, { log }) => { - // soft delete user + // soft delete user and change email address for user to sign up again const result = await updateUser(userID, { status: StatusType.Deleted, + email: `deleted_user_${userID}@omnivore.app`, + sourceUserId: `deleted_user_${userID}`, }) if (!result.affected) { log.error('Error deleting user account') diff --git a/packages/api/test/resolvers/user.test.ts b/packages/api/test/resolvers/user.test.ts index d3ac7ea4f..5e19f714a 100644 --- a/packages/api/test/resolvers/user.test.ts +++ b/packages/api/test/resolvers/user.test.ts @@ -1,10 +1,11 @@ import { expect } from 'chai' import 'mocha' -import { User } from '../../src/entity/user' +import { StatusType, User } from '../../src/entity/user' import { UpdateUserErrorCode, UpdateUserProfileErrorCode, } from '../../src/generated/graphql' +import { userRepository } from '../../src/repository/user' import { findProfile } from '../../src/services/profile' import { deleteUser, findActiveUser } from '../../src/services/user' import { hashPassword } from '../../src/utils/auth' @@ -272,11 +273,15 @@ describe('User API', () => { }) context('when user id is valid', () => { - it('deletes user and responds with 200', async () => { + it('deletes user and changes email address', async () => { const response = await graphqlRequest(query(userId), authToken).expect( 200 ) expect(response.body.data.deleteAccount.userID).to.eql(userId) + + const user = await userRepository.findOneBy({ id: userId }) + expect(user?.status).to.eql(StatusType.Deleted) + expect(user?.email).to.eql(`deleted_user_${userId}@omnivore.app`) }) }) From bd612bd3107de63bf33a814a808425597a12aecb Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 15 Jan 2024 11:23:01 +0800 Subject: [PATCH 2/3] replace username too --- packages/api/src/resolvers/user/index.ts | 8 ++------ packages/api/src/services/user.ts | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/api/src/resolvers/user/index.ts b/packages/api/src/resolvers/user/index.ts index dad2a13fa..c15000a66 100644 --- a/packages/api/src/resolvers/user/index.ts +++ b/packages/api/src/resolvers/user/index.ts @@ -42,7 +42,7 @@ import { import { userRepository } from '../../repository/user' import { createUser } from '../../services/create_user' import { sendVerificationEmail } from '../../services/send_emails' -import { updateUser } from '../../services/user' +import { softDeleteUser } from '../../services/user' import { authorized, userDataToUser } from '../../utils/helpers' import { validateUsername } from '../../utils/usernamePolicy' import { WithDataSourcesContext } from '../types' @@ -321,11 +321,7 @@ export const deleteAccountResolver = authorized< MutationDeleteAccountArgs >(async (_, { userID }, { log }) => { // soft delete user and change email address for user to sign up again - const result = await updateUser(userID, { - status: StatusType.Deleted, - email: `deleted_user_${userID}@omnivore.app`, - sourceUserId: `deleted_user_${userID}`, - }) + const result = await softDeleteUser(userID) if (!result.affected) { log.error('Error deleting user account') diff --git a/packages/api/src/services/user.ts b/packages/api/src/services/user.ts index d7f9fa0d3..4d0580c88 100644 --- a/packages/api/src/services/user.ts +++ b/packages/api/src/services/user.ts @@ -1,4 +1,5 @@ import { DeepPartial, FindOptionsWhere, In } from 'typeorm' +import { Profile } from '../entity/profile' import { StatusType, User } from '../entity/user' import { authTrx, getRepository, queryBuilderToRawSql } from '../repository' import { userRepository } from '../repository/user' @@ -14,9 +15,27 @@ export const deleteUser = async (userId: string) => { ) } -export const updateUser = async (userId: string, update: Partial) => { +export const softDeleteUser = async (userId: string) => { return authTrx( - async (t) => t.getRepository(User).update(userId, update), + async (t) => { + // change email address and username for user to sign up again + await t.getRepository(Profile).update( + { + user: { + id: userId, + }, + }, + { + username: `deleted_user_${userId}`, + } + ) + + return t.getRepository(User).update(userId, { + status: StatusType.Deleted, + email: `deleted_user_${userId}@omnivore.app`, + sourceUserId: `deleted_user_${userId}`, + }) + }, undefined, userId ) From 06067c1d661179b912245587351f64660a490da7 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 15 Jan 2024 11:26:40 +0800 Subject: [PATCH 3/3] fix tests --- packages/api/src/services/user.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/api/src/services/user.ts b/packages/api/src/services/user.ts index 4d0580c88..1a4dc58d1 100644 --- a/packages/api/src/services/user.ts +++ b/packages/api/src/services/user.ts @@ -15,6 +15,14 @@ export const deleteUser = async (userId: string) => { ) } +export const updateUser = async (userId: string, update: Partial) => { + return authTrx( + async (t) => t.getRepository(User).update(userId, update), + undefined, + userId + ) +} + export const softDeleteUser = async (userId: string) => { return authTrx( async (t) => {