Skip to content

Discussion on best practices for extending the mail functionality #141

Description

@silverbackdan

I'd like to implement recaptcha with this plugin. Currently I have to create a new plugin to use:

import { useFetch } from "#app";
import { FetchError } from "ofetch";
import SMTPTransport from "nodemailer/lib/smtp-transport";

export default defineNuxtPlugin(() => {
  const send = async (config: SMTPTransport) => {
    try {
      await useFetch("/mail-send", {
        body: config,
        method: "POST",
      });
    } catch (error) {
      if (error instanceof FetchError) {
        throw new Error(error.response?._data || "Unknown fetch error");
      }
      throw error;
    }
  };
  return {
    provide: {
      appMail: {
        send
      },
    },
  };
});

and so I can use a new server route, as my own one did not seem to override this module's. My server route looks something like

import { createError, defineEventHandler, readBody } from "h3";
import nodemailer from "nodemailer";

import options from "#mail/options.js";
import send from "#mail/send.js";
// @ts-ignore
import omit from "@dword-design/functions/dist/omit.js";

const transport = nodemailer.createTransport(options.smtp);

export default defineEventHandler(async (event) => {
  const body = await readBody(event);

  // IMPLEMENT RECAPTCHA LOGIC HERE

  try {
    await send(omit(["recaptcha"])(body), options, transport);
  } catch (error) {
    if (error instanceof Error) {
      throw createError({ statusCode: 500, statusMessage: error.message });
    }
    throw createError({
      statusCode: 500,
      statusMessage: "An unknown error occurred",
    });
  }

  return "ok";
});

I'm wondering what the best way to achieve this may be. Bdcause I still end up with a redundant server route that could be exploited as well.

It seems like it'd be good to be able to configure the middleware route path perhaps, or perhaps I would need to be able to disable it by setting to false/null.

Then perhaps there could be a simpler way to call the functionality to send the mail just by passing the event in my own middleware.

Perhaps we could post all additional data as a specific post parameter that we could omit by default.

I'm not really sure what the best way to achieve this is, so it's just a discussion on how this module could best be adapted to make it easier to implement functionality such as recaptcha, or perhaps even a user would want to save the message to a database first etc.

Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions