chore: Add additional validation to SMTP_SERVICE env (#9506)

Related #9505
This commit is contained in:
Tom Moor
2025-06-29 04:34:47 -04:00
committed by GitHub
parent 3347101c84
commit 8e56f58102
3 changed files with 72 additions and 3 deletions

View File

@@ -3,6 +3,7 @@ import nodemailer, { Transporter } from "nodemailer";
import SMTPTransport from "nodemailer/lib/smtp-transport";
import Oy from "oy-vey";
import env from "@server/env";
import { InternalError } from "@server/errors";
import Logger from "@server/logging/Logger";
import { trace } from "@server/logging/tracing";
import { baseStyles } from "./templates/components/EmailLayout";
@@ -65,9 +66,10 @@ export class Mailer {
dir = "ltr" /* https://www.w3.org/TR/html4/struct/dirlang.html#blocklevel-bidi */,
}: Oy.CustomTemplateRenderOptions) => {
if (!title) {
throw new Error("`title` is a required option for `renderTemplate`");
} else if (!bodyContent) {
throw new Error(
throw InternalError("`title` is a required option for `renderTemplate`");
}
if (!bodyContent) {
throw InternalError(
"`bodyContent` is a required option for `renderTemplate`"
);
}

View File

@@ -20,6 +20,7 @@ import {
CannotUseWith,
CannotUseWithout,
CannotUseWithAny,
IsInCaseInsensitive,
} from "@server/utils/validators";
import Deprecated from "./models/decorators/Deprecated";
import { getArg } from "./utils/args";
@@ -349,6 +350,37 @@ export class Environment {
* See https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/
*/
@CannotUseWith("SMTP_HOST")
@IsInCaseInsensitive([
"1und1",
"AOL",
"DebugMail.io",
"DynectEmail",
"FastMail",
"GandiMail",
"Gmail",
"Godaddy",
"GodaddyAsia",
"GodaddyEurope",
"hot.ee",
"Hotmail",
"iCloud",
"mail.ee",
"Mail.ru",
"Mailgun",
"Mailjet",
"Mandrill",
"Naver",
"Postmark",
"QQ",
"QQex",
"SendCloud",
"SendGrid",
"SES",
"Sparkpost",
"Yahoo",
"Yandex",
"Zoho",
])
public SMTP_SERVICE = this.toOptionalString(environment.SMTP_SERVICE);
@Public

View File

@@ -86,3 +86,38 @@ export function CannotUseWithAny(
});
};
}
export function IsInCaseInsensitive(
allowedValues: string[],
validationOptions?: ValidationOptions
) {
return function (object: object, propertyName: string) {
registerDecorator({
name: "isInCaseInsensitive",
target: object.constructor,
propertyName,
constraints: [allowedValues],
options: validationOptions,
validator: {
validate<T>(value: T, args: ValidationArguments) {
if (value === undefined || value === null) {
return true;
}
if (typeof value !== "string") {
return false;
}
const av = args.constraints[0] as string[];
return av.some(
(allowedValue) => allowedValue.toLowerCase() === value.toLowerCase()
);
},
defaultMessage(args: ValidationArguments) {
const av = args.constraints[0] as string[];
return `${propertyName} must be one of: ${av.join(
", "
)} (case insensitive).`;
},
},
});
};
}