Files
speckle-server/packages/server/modules/core/services/userEmails.ts
T
2024-09-10 14:00:13 +03:00

54 lines
1.7 KiB
TypeScript

import {
CreateUserEmail,
FindEmail,
ValidateAndCreateUserEmail
} from '@/modules/core/domain/userEmails/operations'
import { ensureNoPrimaryEmailForUserFactory } from '@/modules/core/repositories/userEmails'
import { UserEmailAlreadyExistsError } from '@/modules/core/errors/userEmails'
import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing'
import { RequestNewEmailVerification } from '@/modules/emails/domain/operations'
export const validateAndCreateUserEmailFactory =
(deps: {
createUserEmail: CreateUserEmail
ensureNoPrimaryEmailForUser: ReturnType<typeof ensureNoPrimaryEmailForUserFactory>
findEmail: FindEmail
updateEmailInvites: ReturnType<typeof finalizeInvitedServerRegistrationFactory>
requestNewEmailVerification: RequestNewEmailVerification
}): ValidateAndCreateUserEmail =>
async (params) => {
const { userEmail } = params
const { email, userId, primary } = userEmail
const validationPromises: Array<Promise<unknown>> = []
if (primary) {
validationPromises.push(deps.ensureNoPrimaryEmailForUser({ userId }))
}
validationPromises.push(
(async () => {
const existingEmail = await deps.findEmail({
email
})
if (existingEmail) {
throw new UserEmailAlreadyExistsError()
}
})()
)
await Promise.all(validationPromises)
const result = await deps.createUserEmail({ userEmail })
// Update all invites referencing the email, to point to the user
await deps.updateEmailInvites(result.email, result.userId)
// Request email verification (if needed)
if (!userEmail.verified) {
await deps.requestNewEmailVerification(result.id)
}
return result
}