diff --git a/app/app/(auth)/login/loginByGithub.tsx b/app/app/(auth)/login/loginByGithub.tsx
index d9a30a853..91ea2d7f3 100644
--- a/app/app/(auth)/login/loginByGithub.tsx
+++ b/app/app/(auth)/login/loginByGithub.tsx
@@ -9,7 +9,7 @@ export default function LoginByGithub() {
return (
>
);
diff --git a/app/app/(auth)/login/user-login-core.tsx b/app/app/(auth)/login/user-login-core.tsx
index 3c92b3891..f81f9ac48 100644
--- a/app/app/(auth)/login/user-login-core.tsx
+++ b/app/app/(auth)/login/user-login-core.tsx
@@ -14,6 +14,7 @@ import { UserOutlined, MailOutlined, LoadingOutlined } from "@ant-design/icons";
import type { FormProps } from "antd";
import { SignInOptions } from "next-auth/react";
import { getSession } from "next-auth/react";
+import { useSearchParams } from "next/navigation";
export default function UserLoginCore() {
const [loading, setLoading] = useState(false);
@@ -24,6 +25,27 @@ export default function UserLoginCore() {
const [notification, notificationContextHolder] =
notificationModule.useNotification();
+ const searchParams = useSearchParams();
+ const error = searchParams.get("error");
+
+ useEffect(() => {
+ switch (error) {
+ case "AccessDenied":
+ openNotification("error", {
+ message: "登录失败",
+ description: (
+
+ 无权限,仅提供给熟人使用
+
+ 请主动联系管理员解锁
+
+ ),
+ });
+ break;
+ default:
+ break;
+ }
+ });
const openNotification = (level: string, arms: NotificationArgsProps) => {
if (level === "error") {
notification.error({
@@ -119,6 +141,7 @@ export default function UserLoginCore() {
}
signIn(loginProvider, signInOptions).then((result) => {
setLoading(false);
+ console.log("[auth log]", result);
if (!result?.error) {
// 如果没有密码,且登录成功了,说明需要设置密码
let result_url =
diff --git a/lib/auth.ts b/lib/auth.ts
index 7562a60a8..f579a7783 100644
--- a/lib/auth.ts
+++ b/lib/auth.ts
@@ -1,7 +1,8 @@
import {getServerSession, type NextAuthOptions, Theme} from "next-auth";
-import GitHubProvider from "next-auth/providers/github";
-import EmailProvider from "next-auth/providers/email";
-import CredentialsProvider from "next-auth/providers/credentials";
+import Github from "next-auth/providers/github";
+import Email from "next-auth/providers/email";
+import Credentials from "next-auth/providers/credentials";
+import Google from "next-auth/providers/google"
import {PrismaAdapter} from "@next-auth/prisma-adapter";
import prisma from "@/lib/prisma";
import { User } from "@prisma/client";
@@ -23,7 +24,7 @@ export const authOptions: NextAuthOptions = {
useSecureCookies: SECURE_COOKIES,
secret: process.env.NEXTAUTH_SECRET,
providers: [
- GitHubProvider({
+ Github({
clientId: process.env.AUTH_GITHUB_ID as string,
clientSecret: process.env.AUTH_GITHUB_SECRET as string,
profile(profile) {
@@ -37,9 +38,10 @@ export const authOptions: NextAuthOptions = {
},
httpOptions: {
timeout: 50000,
- }
+ },
+ allowDangerousEmailAccountLinking: true,
}),
- EmailProvider({
+ Email({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: parseInt(process.env.EMAIL_SERVER_PORT ?? "0"),
@@ -83,7 +85,7 @@ export const authOptions: NextAuthOptions = {
}
},
}),
- CredentialsProvider({
+ Credentials({
// The name to display on the sign in form (e.g. "Sign in with...")
name: "Credentials",
// `credentials` is used to generate a form on the sign in page.
@@ -110,7 +112,7 @@ export const authOptions: NextAuthOptions = {
user['name'] = username;
}
// 目前用户不存在,则会创建新用户。
- let existingUser = await existUser(user); // await insertUser(user)
+ let existingUser = await existUser(user);
if (!existingUser) {
user['allowToLogin'] = !!await getSetting("allowNewUser");
existingUser = await insertUser(user);
@@ -125,7 +127,12 @@ export const authOptions: NextAuthOptions = {
// You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter
}
}
- })
+ }),
+ Google({
+ clientId: process.env.GOOGLE_CLIENT_ID,
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
+ allowDangerousEmailAccountLinking: true,
+ }),
],
pages: {
signIn: `/login`,
@@ -180,13 +187,18 @@ export const authOptions: NextAuthOptions = {
},
// 过滤不存在的用户
async signIn({ user, account, profile, email, credentials }) {
- const existingUser = await existUser(user as User);
+ let existingUser = await existUser(user as User);
+ if (!existingUser) {
+ user['allowToLogin'] = !!await getSetting("allowNewUser");
+ existingUser = await insertUser(user)
+ }
// console.log('---', user, 'account', account, 'email', email, 'exist', existingUser)
// 顺便过滤掉不允许登录的用户
- return !!existingUser && existingUser.allowToLogin;
+ return existingUser.allowToLogin;
},
// 重定向
async redirect({ url, baseUrl }) {
+ console.log('---------', url, new URL(url), baseUrl)
return baseUrl;
}
},
diff --git a/middleware.ts b/middleware.ts
index 745b4314f..2f215acc3 100644
--- a/middleware.ts
+++ b/middleware.ts
@@ -24,11 +24,11 @@ export default async function middleware(req: NextRequest) {
if (!isAdminUser) return NextResponse.json({error: '无管理员授权'}, { status: 401 });
}
// 不是用户且页面不是登录页
- if (!isUser && path !== "/login" ) {
+ if (!isUser && !path.startsWith("/login") ) {
return NextResponse.redirect(new URL("/login", req.url));
}
// 如果登录了且页面是登录页面
- if (isUser && path == "/login") {
+ if (isUser && path.startsWith("/login")) {
return NextResponse.redirect(new URL("/", req.url))
}
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index b63668732..19b88ad51 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -18,24 +18,24 @@ generator client {
}
model User {
- id String @id @default(cuid())
- name String?
+ id String @id @default(cuid())
+ name String?
// if you are using Github OAuth, you can get rid of the username attribute (that is for Twitter OAuth)
- username String? @unique
- gh_username String? @unique
- email String? @unique
- emailVerified DateTime?
- image String?
- password String?
+ username String? @unique
+ gh_username String? @unique
+ email String? @unique
+ emailVerified DateTime?
+ image String?
+ password String?
// 默认每人每天限额20k,但数据库存储0
- everyLimitToken Int? @default(0)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- allowToLogin Boolean @default(true)
- isAdmin Boolean? @default(false)
- accounts Account[]
- sessions Session[]
- logs LogEntry[]
+ everyLimitToken Int? @default(0)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ allowToLogin Boolean @default(false)
+ isAdmin Boolean? @default(false)
+ accounts Account[]
+ sessions Session[]
+ logs LogEntry[]
}
model Account {
@@ -46,11 +46,11 @@ model Account {
providerAccountId String
refresh_token String?
refresh_token_expires_in Int?
- access_token String?
+ access_token String? @db.VarChar(512)
expires_at Int?
token_type String?
scope String?
- id_token String?
+ id_token String? @db.Text
session_state String?
oauth_token_secret String?
oauth_token String?