diff --git a/src/util/util/email/clients/SMTPTransport.ts b/src/util/util/email/clients/SMTPTransport.ts
new file mode 100644
index 000000000..828c4a3e4
--- /dev/null
+++ b/src/util/util/email/clients/SMTPTransport.ts
@@ -0,0 +1,63 @@
+import { BaseEmailClient, IEmail } from "./IEmailClient";
+import { Config } from "@spacebar/util*";
+
+export class SMTPTransport extends BaseEmailClient {
+ // sendGrid?: unknown;
+ nodemailer?: typeof import("nodemailer");
+ transporter: import("nodemailer").Transporter;
+ override async init(): Promise<void> {
+ try {
+ // try to import the transporter package
+ this.nodemailer = (await import("nodemailer")).default;
+ } catch {
+ // if the package is not installed, log an error and return void so we don't set the transporter
+ console.error("[Email] nodemailer is not installed. Please run `npm install nodemailer --save-optional` to install it.");
+ return;
+ }
+ // get configuration
+ const { host, port, secure, username, password } = Config.get().email.smtp;
+
+ // ensure all required configuration values are set
+ if (!host || !port || secure === null || !username || !password) return console.error("[Email] SMTP has not been configured correctly.");
+
+ if (!Config.get().email.senderAddress && !Config.get().general.correspondenceEmail)
+ return console.error(
+ '[Email] You have to configure either "email_senderAddress" or "general_correspondenceEmail" for emails to work. The configured value is used as the sender address.',
+ );
+
+ // construct the transporter
+ const transporter = this.nodemailer.createTransport({
+ host,
+ port,
+ secure,
+ auth: {
+ user: username,
+ pass: password,
+ },
+ });
+
+ // verify connection configuration
+ const verified = await transporter.verify().catch((err) => {
+ console.error("[Email] SMTP verification failed:", err);
+ return;
+ });
+
+ // if verification failed, return void and don't set transporter
+ if (!verified) return;
+
+ this.transporter = transporter;
+ }
+
+ override async sendMail(email: IEmail): Promise<void> {
+ if (!this.nodemailer) throw new Error("nodemailer not initialized");
+ if (!this.transporter) throw new Error("nodemailer transporter not initialized");
+
+ await this.transporter.sendMail({
+ to: email.to,
+ from: email.from,
+ subject: email.subject,
+ text: email.text,
+ html: email.html,
+ });
+ }
+}
diff --git a/src/util/util/email/clients/SendGridEmailClient.ts b/src/util/util/email/clients/SendGridEmailClient.ts
index cb30ea8ba..e3006e495 100644
--- a/src/util/util/email/clients/SendGridEmailClient.ts
+++ b/src/util/util/email/clients/SendGridEmailClient.ts
@@ -2,34 +2,34 @@ import { BaseEmailClient, IEmail } from "./IEmailClient";
import { Config } from "@spacebar/util*";
export class SendGridEmailClient extends BaseEmailClient {
- // sendGrid?: unknown;
- sendGrid?: typeof import("@sendgrid/mail");
+ sendGrid?: unknown;
+ // sendGrid?: typeof import("@sendgrid/mail"); // for development - doesn't work if package isn't installed
override async init(): Promise<void> {
// get configuration
const { apiKey } = Config.get().email.sendgrid;
// ensure all required configuration values are set
- if (!apiKey)
- return console.error(
- "[Email] SendGrid has not been configured correctly.",
- );
+ if (!apiKey) return console.error("[Email] SendGrid has not been configured correctly.");
try {
// try to import the transporter package
this.sendGrid = (await import("@sendgrid/mail")).default;
} catch {
// if the package is not installed, log an error and return void so we don't set the transporter
- console.error(
- "[Email] SendGrid transport is not installed. Please run `npm install Maria-Golomb/nodemailer-sendgrid-transport --save-optional` to install it.",
- );
+ console.error("[Email] SendGrid transport is not installed. Please run `npm install @sendgrid/mail --save-optional` to install it.");
return;
}
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
this.sendGrid.setApiKey(apiKey);
}
override async sendMail(email: IEmail): Promise<void> {
if (!this.sendGrid) throw new Error("SendGrid not initialized");
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
await this.sendGrid.send({
to: email.to,
from: email.from,
@@ -38,4 +38,4 @@ export class SendGridEmailClient extends BaseEmailClient {
html: email.html,
});
}
-}
\ No newline at end of file
+}
diff --git a/src/util/util/email/index.ts b/src/util/util/email/index.ts
index 64acc3cc5..8223fa55b 100644
--- a/src/util/util/email/index.ts
+++ b/src/util/util/email/index.ts
@@ -24,6 +24,7 @@ import { Config } from "../Config";
import { generateToken } from "../Token";
import { BaseEmailClient, IEmail, IEmailClient } from "./clients/IEmailClient";
import { SendGridEmailClient } from "./clients/SendGridEmailClient";
+import { SMTPTransport } from "./clients/SMTPTransport";
const ASSET_FOLDER_PATH = path.join(
__dirname,
@@ -78,7 +79,7 @@ export const Email: {
switch (provider) {
case "smtp":
- this.transporter = new BaseEmailClient();
+ this.transporter = new SMTPTransport();
break;
case "sendgrid":
this.transporter = new SendGridEmailClient();
diff --git a/src/util/util/email/transports/SMTP.ts b/src/util/util/email/transports/SMTP.ts
deleted file mode 100644
index e3031943b..000000000
--- a/src/util/util/email/transports/SMTP.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-*/
-
-import { Config } from "@spacebar/util";
-import nodemailer from "nodemailer";
-
-export default async function () {
- // get configuration
- const { host, port, secure, username, password } = Config.get().email.smtp;
-
- // ensure all required configuration values are set
- if (!host || !port || secure === null || !username || !password)
- return console.error("[Email] SMTP has not been configured correctly.");
-
- if (
- !Config.get().email.senderAddress &&
- !Config.get().general.correspondenceEmail
- )
- return console.error(
- '[Email] You have to configure either "email_senderAddress" or "general_correspondenceEmail" for emails to work. The configured value is used as the sender address.',
- );
-
- // construct the transporter
- const transporter = nodemailer.createTransport({
- host,
- port,
- secure,
- auth: {
- user: username,
- pass: password,
- },
- });
-
- // verify connection configuration
- const verified = await transporter.verify().catch((err) => {
- console.error("[Email] SMTP verification failed:", err);
- return;
- });
-
- // if verification failed, return void and don't set transporter
- if (!verified) return;
-
- return transporter;
-}
diff --git a/src/util/util/email/transports/index.ts b/src/util/util/email/transports/index.ts
deleted file mode 100644
index 4d40f9ccc..000000000
--- a/src/util/util/email/transports/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-*/
-
-export * from "./SMTP";
|