2026-05-25: 等级体系升级(20级)+论坛二级分类+会员空间
This commit is contained in:
@@ -4,6 +4,22 @@ import GithubProvider from "next-auth/providers/github";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const loginAttempts = new Map<string, { count: number; resetAt: number }>();
|
||||
const MAX_LOGIN_ATTEMPTS = 7;
|
||||
const LOGIN_WINDOW_MS = 60_000;
|
||||
|
||||
function checkLoginRateLimit(email: string): boolean {
|
||||
const now = Date.now();
|
||||
const record = loginAttempts.get(email);
|
||||
if (!record || now > record.resetAt) {
|
||||
loginAttempts.set(email, { count: 1, resetAt: now + LOGIN_WINDOW_MS });
|
||||
return true;
|
||||
}
|
||||
if (record.count >= MAX_LOGIN_ATTEMPTS) return false;
|
||||
record.count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
export const authOptions = {
|
||||
providers: [
|
||||
CredentialsProvider({
|
||||
@@ -15,6 +31,10 @@ export const authOptions = {
|
||||
async authorize(credentials) {
|
||||
if (!credentials?.email || !credentials?.password) return null;
|
||||
|
||||
if (!checkLoginRateLimit(credentials.email)) {
|
||||
throw new Error("登录尝试过于频繁,请1分钟后再试");
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email: credentials.email },
|
||||
});
|
||||
@@ -27,11 +47,15 @@ export const authOptions = {
|
||||
);
|
||||
if (!isValid) return null;
|
||||
|
||||
loginAttempts.delete(credentials.email);
|
||||
|
||||
return {
|
||||
id: user.id.toString(),
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
role: user.role,
|
||||
level: user.level,
|
||||
points: user.points,
|
||||
};
|
||||
},
|
||||
}),
|
||||
@@ -79,6 +103,8 @@ export const authOptions = {
|
||||
if (user) {
|
||||
token.id = user.id;
|
||||
token.role = user.role;
|
||||
token.level = user.level;
|
||||
token.points = user.points;
|
||||
}
|
||||
return token;
|
||||
},
|
||||
@@ -86,6 +112,8 @@ export const authOptions = {
|
||||
if (session.user) {
|
||||
session.user.id = token.id;
|
||||
session.user.role = token.role;
|
||||
session.user.level = token.level;
|
||||
session.user.points = token.points;
|
||||
}
|
||||
return session;
|
||||
},
|
||||
@@ -95,6 +123,7 @@ export const authOptions = {
|
||||
},
|
||||
session: {
|
||||
strategy: "jwt" as const,
|
||||
maxAge: 30 * 24 * 60 * 60,
|
||||
},
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user