const crs = require('crypto-random-string') const knex = require('@/db/knex') const Verifications = () => knex('email_verifications') const { getServerInfo } = require('@/modules/core/services/generic') const { sendEmail } = require('@/modules/emails') const sendEmailVerification = async ({ recipient }) => { // we need to validate email here, since we'll send it out, // even if technically there is no chance ATM that an incorrect addr comes in const serverInfo = await getServerInfo() const existingVerifications = await Verifications().where({ email: recipient }) if (existingVerifications.some((ver) => isVerificationValid(ver))) throw new Error( 'You already have a valid verification message, please check your inbox' ) const verificationId = await createEmailVerification({ email: recipient }) const verificationLink = new URL( `auth/verifyemail?t=${verificationId}`, process.env.CANONICAL_URL ) const { text, html, subject } = await prepareMessage({ verificationLink, serverInfo }) return await sendEmail({ to: recipient, subject, text, html }) } const isVerificationValid = ({ createdAt }) => { const timeDiff = Math.abs(Date.now() - new Date(createdAt)) return timeDiff < 8.64e7 } const prepareMessage = async ({ verificationLink, serverInfo }) => { const subject = `Speckle Server ${serverInfo.name} email verification` const text = ` Hello! You have just registered to ${serverInfo.name} Speckle Server, or initiated the email verification process manually. To finalize the verification process, follow the link below: ${verificationLink} Warm regards, Speckle --- This email was sent from ${serverInfo.name} at ${process.env.CANONICAL_URL}, deployed and managed by ${serverInfo.company}. ` const html = ` Hello!

You have just registered to ${serverInfo.name} Speckle Server, or initiated the email verification process manually.

To finalize the verification process, please click here!

Warm regards,
Speckle



This email was sent from the ${serverInfo.name}, deployed and managed by ${serverInfo.company}. ` return { text, html, subject } } const createEmailVerification = async ({ email }) => { const verification = { id: crs({ length: 20 }), email } await Verifications().insert(verification) return verification.id } module.exports = { sendEmailVerification, isVerificationValid }