diff --git a/packages/server/modules/core/repositories/users.ts b/packages/server/modules/core/repositories/users.ts index 1dc7bfbcb..2fed1706a 100644 --- a/packages/server/modules/core/repositories/users.ts +++ b/packages/server/modules/core/repositories/users.ts @@ -8,6 +8,7 @@ import { Knex } from 'knex' import { Roles, ServerRoles } from '@speckle/shared' import { updateUserEmailFactory } from '@/modules/user-emails/repositories/userEmails' import knexInstance from '@/db/knex' +import { markUserEmailAsVerifiedFactory } from '@/modules/user-emails/services/verification' export type UserWithOptionalRole = User & { /** @@ -163,6 +164,10 @@ export async function markUserAsVerified(email: string) { [UserCols.verified]: true }) + await markUserEmailAsVerifiedFactory({ + updateUserEmail: updateUserEmailFactory({ db: knexInstance }) + })(email.toLowerCase().trim()) + return !!(await q) } diff --git a/packages/server/modules/core/tests/integration/user-emails.spec.ts b/packages/server/modules/core/tests/integration/user-emails.spec.ts index 46fb7cc3f..afb2a089a 100644 --- a/packages/server/modules/core/tests/integration/user-emails.spec.ts +++ b/packages/server/modules/core/tests/integration/user-emails.spec.ts @@ -2,10 +2,13 @@ import { before } from 'mocha' import { createUser } from '@/modules/core/services/users' import { beforeEachContext } from '@/test/hooks' import { expect } from 'chai' -import { getUserByEmail } from '@/modules/core/repositories/users' +import { getUserByEmail, markUserAsVerified } from '@/modules/core/repositories/users' import { deleteUserEmailFactory } from '@/modules/user-emails/repositories/userEmails' import knexInstance from '@/db/knex' import { createRandomEmail, createRandomPassword } from '../../helpers/test-helpers' +import { USER_EMAILS_TABLE_NAME } from '@/modules/user-emails/constants' + +const userEmailTable = knexInstance(USER_EMAILS_TABLE_NAME) describe('Core @user-emails', () => { before(async () => { @@ -34,4 +37,20 @@ describe('Core @user-emails', () => { expect(user.email).to.eq(email) }) }) + + describe('markUserEmailAsVerified', () => { + it('should mark user email as verified', async () => { + const email = createRandomEmail() + await createUser({ + name: 'John Doe', + email, + password: createRandomPassword() + }) + + await markUserAsVerified(email) + + const userEmail = await userEmailTable.where({ email }).first() + expect(userEmail.verified).to.be.true + }) + }) }) diff --git a/packages/server/modules/user-emails/domain/operations.ts b/packages/server/modules/user-emails/domain/operations.ts index 5dc16a962..878aed458 100644 --- a/packages/server/modules/user-emails/domain/operations.ts +++ b/packages/server/modules/user-emails/domain/operations.ts @@ -6,9 +6,9 @@ export type CreateUserEmail = ( export type UpdateUserEmail = ( query: - | (Pick & { primary?: boolean }) + | (Pick & { primary?: boolean }) | (Pick & { primary: true }), - update: Pick, 'email' | 'primary'> + update: Pick, 'email' | 'primary' | 'verified'> ) => Promise export type DeleteUserEmail = ({ @@ -18,3 +18,5 @@ export type DeleteUserEmail = ({ userId: string email: string }) => Promise + +export type MarkUserEmailAsVerified = (email: string) => Promise diff --git a/packages/server/modules/user-emails/services/verification.ts b/packages/server/modules/user-emails/services/verification.ts new file mode 100644 index 000000000..6b7726fe1 --- /dev/null +++ b/packages/server/modules/user-emails/services/verification.ts @@ -0,0 +1,10 @@ +import { MarkUserEmailAsVerified, UpdateUserEmail } from '../domain/operations' + +export const markUserEmailAsVerifiedFactory = + ({ + updateUserEmail + }: { + updateUserEmail: UpdateUserEmail + }): MarkUserEmailAsVerified => + async (email) => + updateUserEmail({ email }, { verified: true }) diff --git a/packages/server/modules/user-emails/tests/integration/verification.spec.ts b/packages/server/modules/user-emails/tests/integration/verification.spec.ts new file mode 100644 index 000000000..0bb872805 --- /dev/null +++ b/packages/server/modules/user-emails/tests/integration/verification.spec.ts @@ -0,0 +1,32 @@ +import { describe } from 'mocha' +import { updateUserEmailFactory } from '../../repositories/userEmails' +import knexInstance from '@/db/knex' +import { createUser } from '@/modules/core/services/users' +import { + createRandomEmail, + createRandomPassword +} from '@/modules/core/helpers/test-helpers' +import { USER_EMAILS_TABLE_NAME } from '../../constants' +import { markUserEmailAsVerifiedFactory } from '../../services/verification' +import { expect } from 'chai' + +const userEmailTable = knexInstance(USER_EMAILS_TABLE_NAME) + +describe('Verification @user-emails', () => { + it('should mark user email as verified', async () => { + const email = createRandomEmail() + + await createUser({ + name: 'John', + email, + password: createRandomPassword() + }) + + await markUserEmailAsVerifiedFactory({ + updateUserEmail: updateUserEmailFactory({ db: knexInstance }) + })(email) + + const userEmail = await userEmailTable.where({ email }).first() + expect(userEmail.verified).to.be.true + }) +})