mirror of
https://github.com/JetSprow/J-Board-Lite.git
synced 2026-05-01 01:14:10 +05:30
fix: rate limit email send actions
This commit is contained in:
@@ -6,6 +6,7 @@ import { headers } from "next/headers";
|
||||
import { randomBytes } from "crypto";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { rateLimit } from "@/lib/rate-limit";
|
||||
import { normalizeEmailAddress, sendEmailChangeConfirmation } from "@/services/email";
|
||||
import { requireAuth } from "@/lib/require-auth";
|
||||
|
||||
@@ -23,6 +24,28 @@ const emailChangeSchema = z.object({
|
||||
email: z.string().trim().email("请输入正确的新邮箱"),
|
||||
});
|
||||
|
||||
const EMAIL_CHANGE_LIMIT = 3;
|
||||
const EMAIL_CHANGE_WINDOW_SECONDS = 10 * 60;
|
||||
|
||||
async function assertEmailChangeRateLimit(userId: string, email: string) {
|
||||
const [userLimit, targetLimit] = await Promise.all([
|
||||
rateLimit(
|
||||
`ratelimit:account-email-change:user:${userId}`,
|
||||
EMAIL_CHANGE_LIMIT,
|
||||
EMAIL_CHANGE_WINDOW_SECONDS,
|
||||
),
|
||||
rateLimit(
|
||||
`ratelimit:account-email-change:email:${email}`,
|
||||
EMAIL_CHANGE_LIMIT,
|
||||
EMAIL_CHANGE_WINDOW_SECONDS,
|
||||
),
|
||||
]);
|
||||
|
||||
if (!userLimit.success || !targetLimit.success) {
|
||||
throw new Error("请求过于频繁,请稍后再试");
|
||||
}
|
||||
}
|
||||
|
||||
async function generateUniqueInviteCode(): Promise<string> {
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
const code = randomBytes(4).toString("hex").toUpperCase();
|
||||
@@ -71,6 +94,8 @@ export async function requestAccountEmailChange(formData: FormData) {
|
||||
throw new Error("这个邮箱已经被其他账户使用");
|
||||
}
|
||||
|
||||
await assertEmailChangeRateLimit(session.user.id, email);
|
||||
|
||||
const headerList = await headers();
|
||||
await sendEmailChangeConfirmation({
|
||||
userId: session.user.id,
|
||||
|
||||
Reference in New Issue
Block a user