-
-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): Added support for changing email of users
- Loading branch information
1 parent
11244a2
commit adc623a
Showing
5 changed files
with
321 additions
and
1 deletion.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
apps/api/src/prisma/migrations/20240519122223_add_user_email_change/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
-- CreateTable | ||
CREATE TABLE "UserEmailChange" ( | ||
"id" TEXT NOT NULL, | ||
"userId" TEXT NOT NULL, | ||
"newEmail" TEXT NOT NULL, | ||
"otp" TEXT NOT NULL, | ||
"createdOn" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
|
||
CONSTRAINT "UserEmailChange_pkey" PRIMARY KEY ("id") | ||
); | ||
|
||
-- CreateIndex | ||
CREATE UNIQUE INDEX "UserEmailChange_userId_key" ON "UserEmailChange"("userId"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -321,6 +321,176 @@ describe('User Controller Tests', () => { | |
expect(result.statusCode).toEqual(204) | ||
}) | ||
|
||
it('should send otp when user changes email', async () => { | ||
const result = await app.inject({ | ||
method: 'PUT', | ||
url: `/user`, | ||
headers: { | ||
'x-e2e-user-email': regularUser.email | ||
}, | ||
payload: { | ||
email: '[email protected]' | ||
} | ||
}) | ||
|
||
expect(result.statusCode).toEqual(200) | ||
expect(JSON.parse(result.body)).toEqual({ | ||
...regularUser | ||
}) | ||
|
||
const userEmailChange = await prisma.userEmailChange.findMany({ | ||
where: { | ||
userId: regularUser.id, | ||
newEmail: '[email protected]' | ||
} | ||
}) | ||
|
||
expect(userEmailChange.length).toEqual(1) | ||
}) | ||
|
||
it('should send otp when admin changes an user email', async () => { | ||
const result = await app.inject({ | ||
method: 'PUT', | ||
url: `/user/${regularUser.id}`, | ||
headers: { | ||
'x-e2e-user-email': adminUser.email | ||
}, | ||
payload: { | ||
email: '[email protected]' | ||
} | ||
}) | ||
|
||
expect(result.statusCode).toEqual(200) | ||
expect(JSON.parse(result.body)).toEqual({ | ||
...regularUser | ||
}) | ||
|
||
const userEmailChange = await prisma.userEmailChange.findMany({ | ||
where: { | ||
userId: regularUser.id, | ||
newEmail: '[email protected]' | ||
} | ||
}) | ||
|
||
expect(userEmailChange.length).toEqual(1) | ||
}) | ||
|
||
it('should give error when new email is used by an existing user', async () => { | ||
const result = await app.inject({ | ||
method: 'PUT', | ||
url: `/user`, | ||
headers: { | ||
'x-e2e-user-email': regularUser.email | ||
}, | ||
payload: { | ||
email: '[email protected]' | ||
} | ||
}) | ||
|
||
expect(result.statusCode).toEqual(409) | ||
}) | ||
|
||
it('should validate OTP successfully', async () => { | ||
await prisma.userEmailChange.create({ | ||
data: { | ||
newEmail: '[email protected]', | ||
userId: regularUser.id, | ||
otp: '123456' | ||
} | ||
}) | ||
|
||
const result = await app.inject({ | ||
method: 'POST', | ||
url: `/user/validate-otp/${regularUser.id}`, | ||
query: { | ||
otp: '123456' | ||
}, | ||
headers: { | ||
'x-e2e-user-email': regularUser.email | ||
} | ||
}) | ||
|
||
expect(result.statusCode).toEqual(201) | ||
expect(JSON.parse(result.body)).toEqual({ | ||
...regularUser, | ||
email: '[email protected]' | ||
}) | ||
|
||
const updatedUser = await prisma.user.findUnique({ | ||
where: { | ||
id: regularUser.id | ||
} | ||
}) | ||
|
||
expect(updatedUser.email).toEqual('[email protected]') | ||
}) | ||
|
||
it('should fail to validate expired or invalid OTP', async () => { | ||
await prisma.userEmailChange.create({ | ||
data: { | ||
newEmail: '[email protected]', | ||
userId: regularUser.id, | ||
otp: '123456', | ||
createdOn: new Date(new Date().getTime() - (5 * 60 * 1000 + 1)) // Expired OTP | ||
} | ||
}) | ||
|
||
const result = await app.inject({ | ||
method: 'POST', | ||
url: `/user/validate-otp/${regularUser.id}`, | ||
query: { | ||
otp: '123456' | ||
}, | ||
headers: { | ||
'x-e2e-user-email': regularUser.email | ||
} | ||
}) | ||
|
||
expect(result.statusCode).toEqual(401) | ||
expect(JSON.parse(result.body)).toEqual({ | ||
message: 'Invalid or expired OTP', | ||
error: 'Unauthorized', | ||
statusCode: 401 | ||
}) | ||
|
||
const nonUpdatedUser = await prisma.user.findUnique({ | ||
where: { | ||
id: regularUser.id | ||
} | ||
}) | ||
|
||
expect(nonUpdatedUser.email).toEqual('[email protected]') | ||
}) | ||
|
||
it('should resend OTP successfully', async () => { | ||
await prisma.userEmailChange.create({ | ||
data: { | ||
newEmail: '[email protected]', | ||
userId: regularUser.id, | ||
otp: '123456' | ||
} | ||
}) | ||
|
||
const result = await app.inject({ | ||
method: 'POST', | ||
url: `/user/resend-otp/${regularUser.id}`, | ||
headers: { | ||
'x-e2e-user-email': regularUser.email | ||
} | ||
}) | ||
|
||
expect(result.statusCode).toEqual(201) | ||
|
||
const updatedEmailChange = await prisma.userEmailChange.findFirst({ | ||
where: { | ||
userId: regularUser.id, | ||
newEmail: '[email protected]' | ||
} | ||
}) | ||
|
||
expect(updatedEmailChange.otp).not.toEqual('123456') | ||
}) | ||
|
||
// test('user should be able to delete their own account', async () => { | ||
// const result = await app.inject({ | ||
// method: 'DELETE', | ||
|