diff --git a/server/.github/test.conf.json5 b/server/.github/test.conf.json5 index f874fecd4..9fa254e07 100644 --- a/server/.github/test.conf.json5 +++ b/server/.github/test.conf.json5 @@ -25,9 +25,6 @@ RUN_OWN_CDN: true, CDN_WEB_LOCATION: "/cdn", OUR_URL: "https://example.com", - EMAIL_CONFIG: { - FROM: "test ", - }, INVITE_CODE_CONFIG: { BATCH_SIZE: 2, INVITE_CAP: 100, diff --git a/server/src/lib/email/client.ts b/server/src/lib/email/client.ts index ca67501e3..5063a60ce 100644 --- a/server/src/lib/email/client.ts +++ b/server/src/lib/email/client.ts @@ -12,18 +12,17 @@ if (ServerConfig.EMAIL_CONFIG) { const conf = ServerConfig.EMAIL_CONFIG; try { - transporter = nodemailer.createTransport({ - // @ts-expect-error There's a bug in nodemailers types - // where it thinks that sendmail cannot be true while - // debug or logging are enabled. - sendmail: true, - newline: "unix", - path: conf.SENDMAIL_BIN ?? "/usr/bin/sendmail", - debug: !!ServerConfig.EMAIL_CONFIG?.DEBUG, - logger: ServerConfig.EMAIL_CONFIG.DEBUG - ? bunyan.createLogger({ name: "Email Logger" }) - : undefined, - }); + transporter = nodemailer.createTransport( + Object.assign( + { + newline: "unix", + logger: conf.TRANSPORT_OPS?.debug + ? bunyan.createLogger({ name: "Email Logger" }) + : undefined, + }, + conf.TRANSPORT_OPS ?? {} + ) + ); transporter.verify((err) => { if (err) { diff --git a/server/src/lib/score-import/import-types/common/api-kai/sdvx/converter.test.ts b/server/src/lib/score-import/import-types/common/api-kai/sdvx/converter.test.ts index a8da3df1e..239172d75 100644 --- a/server/src/lib/score-import/import-types/common/api-kai/sdvx/converter.test.ts +++ b/server/src/lib/score-import/import-types/common/api-kai/sdvx/converter.test.ts @@ -121,8 +121,8 @@ t.test("#ResolveKaiLamp", (t) => { t.equal(ResolveKaiLamp(3), "EXCESSIVE CLEAR"); t.equal(ResolveKaiLamp(4), "ULTIMATE CHAIN"); t.equal(ResolveKaiLamp(5), "PERFECT ULTIMATE CHAIN"); - t.throws(() => ConvertDifficulty(6)); - t.throws(() => ConvertDifficulty(0)); + t.throws(() => ResolveKaiLamp(6)); + t.throws(() => ResolveKaiLamp(0)); t.end(); }); diff --git a/server/src/lib/setup/config.ts b/server/src/lib/setup/config.ts index 6adad179a..667bddddf 100644 --- a/server/src/lib/setup/config.ts +++ b/server/src/lib/setup/config.ts @@ -1,11 +1,11 @@ // barrel file for re-exporting env variables. import dotenv from "dotenv"; -import JSON5 from "json5"; import fs from "fs"; -import p from "prudence"; -import { FormatPrError } from "utils/prudence"; -import { integer, StaticConfig } from "tachi-common"; +import JSON5 from "json5"; import { SendMailOptions } from "nodemailer"; +import p from "prudence"; +import { integer, StaticConfig } from "tachi-common"; +import { FormatPrError } from "utils/prudence"; dotenv.config(); // imports things like NODE_ENV from a local .env file if one is present. @@ -69,9 +69,13 @@ export interface TachiConfig { NO_CONSOLE?: boolean; EMAIL_CONFIG?: { FROM: string; - SENDMAIL_BIN?: string; DKIM?: SendMailOptions["dkim"]; - DEBUG?: boolean; + // @warning This is explicitly allowed to be any + // As nodemailer doesnt properly export the types we care about + // This should be set to SMTPTransport.Options, but it is + // inaccessible. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + TRANSPORT_OPS: any; }; USC_QUEUE_SIZE: integer; BEATORAJA_QUEUE_SIZE: integer; @@ -115,9 +119,11 @@ const err = p(config, { NO_CONSOLE: "*boolean", EMAIL_CONFIG: p.optional({ FROM: "string", - SENDMAIL_BIN: "*string", DKIM: "*object", - DEBUG: "*boolean", + // WARN: This validation is improper and lazy. + // The actual content is just some wacky options object. + // I'm not going to assert this properly. + TRANSPORT_OPS: "*object", }), USC_QUEUE_SIZE: p.optional(p.gteInt(2)), BEATORAJA_QUEUE_SIZE: p.optional(p.gteInt(2)), @@ -152,10 +158,6 @@ tachiConfig.OAUTH_CLIENT_CAP ??= 15; tachiConfig.USC_QUEUE_SIZE ??= 3; tachiConfig.BEATORAJA_QUEUE_SIZE ??= 3; -if (tachiConfig.EMAIL_CONFIG) { - tachiConfig.EMAIL_CONFIG.SENDMAIL_BIN ??= "/usr/bin/sendmail"; -} - export const ServerTypeInfo = tachiConfig.SERVER_TYPE_INFO; export const ServerConfig = tachiConfig; diff --git a/server/src/server/router/api/v1/auth/router.ts b/server/src/server/router/api/v1/auth/router.ts index 40d452293..dccc3493b 100644 --- a/server/src/server/router/api/v1/auth/router.ts +++ b/server/src/server/router/api/v1/auth/router.ts @@ -420,7 +420,7 @@ router.post("/logout", (req, res) => { * @name POST /api/v1/auth/forgot-password */ router.post("/forgot-password", prValidate({ email: "string" }), async (req, res) => { - if (!ServerConfig.EMAIL_CONFIG) { + if (!ServerConfig.EMAIL_CONFIG && Environment.nodeEnv !== "test") { return res.status(501).json({ success: false, description: `This server does not support password resets.`,