fix: respect email verification setting

This commit is contained in:
JetSprow
2026-04-29 15:20:23 +10:00
parent cf658ac026
commit 9f1bc9c0ce
4 changed files with 11 additions and 4 deletions

View File

@@ -133,7 +133,7 @@ enum SupportTicketPriority {
model User { model User {
id String @id @default(cuid()) id String @id @default(cuid())
email String @unique email String @unique
emailVerifiedAt DateTime? @default(now()) emailVerifiedAt DateTime?
password String password String
name String? name String?
role Role @default(USER) role Role @default(USER)

View File

@@ -26,7 +26,7 @@ export async function createUser(formData: FormData) {
const data = createUserSchema.parse(Object.fromEntries(formData)); const data = createUserSchema.parse(Object.fromEntries(formData));
const hashed = await bcrypt.hash(data.password, 12); const hashed = await bcrypt.hash(data.password, 12);
const user = await prisma.user.create({ const user = await prisma.user.create({
data: { email: data.email, password: hashed, name: data.name || null, role: data.role }, data: { email: data.email, emailVerifiedAt: new Date(), password: hashed, name: data.name || null, role: data.role },
}); });
await recordAuditLog({ await recordAuditLog({
actor: actorFromSession(session), actor: actorFromSession(session),

View File

@@ -230,7 +230,7 @@ export function SettingsForm({ config, coupons }: { config: AppConfig; coupons:
<option value="false"></option> <option value="false"></option>
<option value="true"></option> <option value="true"></option>
</select> </select>
<p className="text-xs leading-5 text-muted-foreground"></p> <p className="text-xs leading-5 text-muted-foreground"></p>
</div> </div>
</div> </div>
</section> </section>

View File

@@ -5,7 +5,7 @@ import { z } from "zod";
import { getAppConfig } from "@/services/app-config"; import { getAppConfig } from "@/services/app-config";
import { verifyTurnstile } from "@/lib/turnstile"; import { verifyTurnstile } from "@/lib/turnstile";
import { rateLimit } from "@/lib/rate-limit"; import { rateLimit } from "@/lib/rate-limit";
import { normalizeEmailAddress, sendRegistrationVerificationEmail } from "@/services/email"; import { isSmtpConfigured, normalizeEmailAddress, sendRegistrationVerificationEmail } from "@/services/email";
const schema = z.object({ const schema = z.object({
email: z.string().email("邮箱格式不正确"), email: z.string().email("邮箱格式不正确"),
@@ -52,6 +52,13 @@ export async function POST(req: Request) {
const email = normalizeEmailAddress(parsed.data.email); const email = normalizeEmailAddress(parsed.data.email);
const config = await getAppConfig(); const config = await getAppConfig();
if (config.emailVerificationRequired && !isSmtpConfigured(config)) {
return NextResponse.json(
{ error: "注册暂不可用:管理员已开启邮箱验证,但站点尚未配置 SMTP 邮件服务,无法发送验证邮件" },
{ status: 503 },
);
}
if (config.turnstileSecretKey) { if (config.turnstileSecretKey) {
if (!turnstileToken || !(await verifyTurnstile(turnstileToken, config.turnstileSecretKey))) { if (!turnstileToken || !(await verifyTurnstile(turnstileToken, config.turnstileSecretKey))) {
return NextResponse.json({ error: "人机验证失败Turnstile token 缺失、已过期或校验未通过" }, { status: 403 }); return NextResponse.json({ error: "人机验证失败Turnstile token 缺失、已过期或校验未通过" }, { status: 403 });