A11yWatch/a11ywatch-core

View on GitHub
src/core/controllers/users/update/confirm-email.ts

Summary

Maintainability
A
40 mins
Test Coverage
import { addMinutes } from "date-fns";
import { config } from "../../../../config";
import { EMAIL_ERROR, GENERAL_ERROR, SUCCESS } from "../../../strings";
import {
  transporter,
  mailOptions,
  sendMailCallback,
  asyncRandomGenerate,
} from "../../../utils";
import { getUser } from "../find";
import { User } from "../../../../types/schema";

const { ROOT_URL } = config;

export const sendEmailConfirmation = async (user: User, collection) => {
  const emailConfirmCode = await asyncRandomGenerate();
  const confirmLink = `${ROOT_URL}/api/confirmEmail?code=${emailConfirmCode}`;
  const emailExpDate = addMinutes(Date.now(), 30);
  await collection.findOneAndUpdate(
    { id: user.id },
    { $set: { emailConfirmCode, emailExpDate } }
  );
  transporter.sendMail(
    {
      ...mailOptions,
      to: user.email,
      subject: `A11yWatch - Email Confirmation.`,
      html: `
          <h1>Click on this link to confirm your email for A11yWatch.</h1>
          <p>Confirmation code will expire in 30 minutes or you have to get a new link.</p>
          <div style="padding-top: 20px; padding-bottom: 40px">
            <a href="${confirmLink}" aria-label="Confirm your email for A11yWatch" style="margin-top: 8px; margin-bottom: 4px; color: #3f3d56; padding: 8px 15px; border: 1px solid rgba(63, 61, 86, 0.5); text-decoration: none; border-radius: 2px">CONFIRM EMAIL</a>
          </div>
          <p style="font-size: 12px; margin-top: 20px">Please do not reply back to this email, it will not be read</p>
          `,
    },
    sendMailCallback
  );
};

export const confirmEmail = async ({ keyid: id }) => {
  if (typeof id === "undefined") {
    throw new Error(EMAIL_ERROR);
  }
  const [user, collection] = await getUser({ id });

  if (user) {
    await sendEmailConfirmation(user, collection);
  } else {
    throw new Error(GENERAL_ERROR);
  }
  return { code: 200, success: true, message: SUCCESS };
};