Browse Source

feat(email): add nodemailer type definitions and enhance comment email test logging

- Added TypeScript definitions for nodemailer to improve type safety in email handling.
- Refactored comment email test handler to utilize a dedicated logger for better error tracking and debugging.
- Simplified email configuration retrieval by consolidating it into a single object for clarity and maintainability.

This update enhances the email notification system's robustness and developer experience.
main
npmrun 3 weeks ago
parent
commit
3704675445
  1. 3
      bun.lock
  2. 1
      package.json
  3. BIN
      packages/drizzle-pkg/db.sqlite
  4. 27
      server/api/config/global/comment-email-test.post.ts
  5. 8
      server/service/comment-notify/index.ts

3
bun.lock

@ -37,6 +37,7 @@
"@types/better-sqlite3": "7.6.13",
"@types/markdown-it": "14.1.2",
"@types/multer": "2.1.0",
"@types/nodemailer": "^8.0.0",
"@types/pg": "8.20.0",
"bun-types": "1.3.12",
"drizzle-kit": "0.31.10",
@ -857,6 +858,8 @@
"@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
"@types/nodemailer": ["@types/nodemailer@8.0.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-fyf8jWULsCo0d0BuoQ75i6IeoHs47qcqxWc7yUdUcV0pOZGjUTTOvwdG1PRXUDqN/8A64yQdQdnA2pZgcdi+cA=="],
"@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="],
"@types/qs": ["@types/qs@6.15.0", "", {}, "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow=="],

1
package.json

@ -51,6 +51,7 @@
"@types/better-sqlite3": "7.6.13",
"@types/markdown-it": "14.1.2",
"@types/multer": "2.1.0",
"@types/nodemailer": "^8.0.0",
"@types/pg": "8.20.0",
"bun-types": "1.3.12",
"drizzle-kit": "0.31.10",

BIN
packages/drizzle-pkg/db.sqlite

Binary file not shown.

27
server/api/config/global/comment-email-test.post.ts

@ -1,3 +1,4 @@
import log4js from "logger";
import { dbGlobal } from "drizzle-pkg/lib/db";
import { users } from "drizzle-pkg/lib/schema/auth";
import { eq } from "drizzle-orm";
@ -9,6 +10,8 @@ import {
sendCommentEmailTestMail,
} from "#server/service/comment-email/test-mail";
const logger = log4js.getLogger("COMMENT_EMAIL_TEST");
export default defineWrappedResponseHandler(async (event) => {
const ip = getRequestIP(event, { xForwardedFor: true }) ?? "unknown";
assertUnderRateLimit(`admin-config-comment-email-test:${ip}`, 5, 60_000);
@ -21,11 +24,7 @@ export default defineWrappedResponseHandler(async (event) => {
.where(eq(users.id, admin.id))
.limit(1);
try {
await sendCommentEmailTestMail({
toEmail: adminRow?.email ?? "",
requestedBy: admin.username,
config: {
const commentEmailConfig = {
enabled: await event.context.config.getGlobal("commentEmailNotifyEnabled"),
fromEmail: await event.context.config.getGlobal("commentMailFromEmail"),
smtpHost: await event.context.config.getGlobal("commentSmtpHost"),
@ -33,7 +32,13 @@ export default defineWrappedResponseHandler(async (event) => {
smtpSecure: await event.context.config.getGlobal("commentSmtpSecure"),
smtpUser: await event.context.config.getGlobal("commentSmtpUser"),
smtpPass: await event.context.config.getGlobal("commentSmtpPass"),
},
};
try {
await sendCommentEmailTestMail({
toEmail: adminRow?.email ?? "",
requestedBy: admin.username,
config: commentEmailConfig,
});
return R.success({
message: "测试邮件发送成功,请检查管理员邮箱",
@ -45,6 +50,16 @@ export default defineWrappedResponseHandler(async (event) => {
statusMessage: error.message,
});
}
logger.error(
"[send-test-mail-failed]",
`adminId=${admin.id}`,
`adminUsername=${admin.username}`,
`smtpHost=${commentEmailConfig.smtpHost}`,
`smtpPort=${commentEmailConfig.smtpPort}`,
`smtpSecure=${commentEmailConfig.smtpSecure}`,
error instanceof Error ? error.message : String(error),
error instanceof Error ? (error.stack ?? "") : "",
);
throw createError({
statusCode: 502,
statusMessage: "测试邮件发送失败,请检查 SMTP 配置或稍后重试",

8
server/service/comment-notify/index.ts

@ -42,6 +42,13 @@ function getReason(error: unknown): string {
return "unknown";
}
function getStack(error: unknown): string {
if (error instanceof Error && hasValue(error.stack ?? "")) {
return error.stack ?? "";
}
return "";
}
function isValidEmail(value: string): boolean {
return EMAIL_REGEX.test(value.trim());
}
@ -205,6 +212,7 @@ export async function notifyReplyCommentCreated(
commentId: input.commentId,
receiverUserId,
reason: getReason(error),
stack: getStack(error),
});
}
}

Loading…
Cancel
Save