mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-03 00:26:40 +08:00
merge
This commit is contained in:
parent
9ed72b8f47
commit
714ad21b74
@ -51,7 +51,22 @@ async function handle(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const count = result.length;
|
const count = result.length;
|
||||||
return NextResponse.json({ count: count, results: result });
|
return NextResponse.json({
|
||||||
|
count: count,
|
||||||
|
results: result.map((item) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
username: item.username,
|
||||||
|
gh_username: item.gh_username,
|
||||||
|
image: item.image,
|
||||||
|
email: item.email,
|
||||||
|
emailVerified: item.emailVerified,
|
||||||
|
createdAt: item.createdAt,
|
||||||
|
updatedAt: item.updatedAt,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
} catch {}
|
} catch {}
|
||||||
return NextResponse.json({ error: "未知错误" }, { status: 500 });
|
return NextResponse.json({ error: "未知错误" }, { status: 500 });
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,16 @@ export default function UserLoginButton() {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const nameInput = useRef<HTMLInputElement>(null);
|
const nameInput = useRef<HTMLInputElement>(null);
|
||||||
|
const passwordInput = useRef<HTMLInputElement>(null);
|
||||||
const emailInput = useRef<HTMLInputElement>(null);
|
const emailInput = useRef<HTMLInputElement>(null);
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
|
|
||||||
const handleComposition = (e: React.CompositionEvent<HTMLInputElement>) => {
|
const handleNameComposition = (
|
||||||
|
e: React.CompositionEvent<HTMLInputElement>,
|
||||||
|
) => {
|
||||||
if (e.type === "compositionend") {
|
if (e.type === "compositionend") {
|
||||||
setUsername(e.currentTarget.value);
|
setUsername(e.currentTarget.value);
|
||||||
}
|
}
|
||||||
@ -23,6 +28,12 @@ export default function UserLoginButton() {
|
|||||||
}
|
}
|
||||||
setUsername(e.target.value);
|
setUsername(e.target.value);
|
||||||
};
|
};
|
||||||
|
const onPasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if ((e.nativeEvent as InputEvent).isComposing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPassword(e.target.value);
|
||||||
|
};
|
||||||
const onSubmitHandler = async (e: React.FormEvent<HTMLFormElement>) => {
|
const onSubmitHandler = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
// handle yow submition
|
// handle yow submition
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@ -40,6 +51,7 @@ export default function UserLoginButton() {
|
|||||||
} else {
|
} else {
|
||||||
result = await signIn("credentials", {
|
result = await signIn("credentials", {
|
||||||
username: username,
|
username: username,
|
||||||
|
password: password,
|
||||||
redirect: false,
|
redirect: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -93,7 +105,7 @@ export default function UserLoginButton() {
|
|||||||
ref={nameInput}
|
ref={nameInput}
|
||||||
// value={username}
|
// value={username}
|
||||||
onCompositionStart={(e) => e.preventDefault()}
|
onCompositionStart={(e) => e.preventDefault()}
|
||||||
onCompositionEnd={handleComposition}
|
onCompositionEnd={handleNameComposition}
|
||||||
onChange={onNameChange}
|
onChange={onNameChange}
|
||||||
// required
|
// required
|
||||||
placeholder="输入姓名、拼音或邮箱"
|
placeholder="输入姓名、拼音或邮箱"
|
||||||
@ -109,6 +121,29 @@ export default function UserLoginButton() {
|
|||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
/>
|
/>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
ref={passwordInput}
|
||||||
|
value={password}
|
||||||
|
// onCompositionStart={(e) => e.preventDefault()}
|
||||||
|
// onCompositionEnd={handleComposition}
|
||||||
|
onChange={onPasswordChange}
|
||||||
|
// required
|
||||||
|
placeholder="密码验证,测试阶段"
|
||||||
|
className={`${
|
||||||
|
loading
|
||||||
|
? "cursor-not-allowed bg-stone-50 dark:bg-stone-800"
|
||||||
|
: "bg-white hover:bg-stone-50 active:bg-stone-100 dark:bg-black dark:hover:border-white dark:hover:bg-black"
|
||||||
|
} group my-2 flex h-10 w-full items-center justify-center space-x-2 rounded-md border border-stone-200 transition-colors duration-75 focus:outline-none dark:border-stone-700
|
||||||
|
${
|
||||||
|
error
|
||||||
|
? "focus:invalid:border-red-500 focus:invalid:ring-red-500"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
<input
|
<input
|
||||||
id="email"
|
id="email"
|
||||||
name="email"
|
name="email"
|
||||||
|
95
lib/auth.ts
95
lib/auth.ts
@ -7,7 +7,7 @@ import prisma from "@/lib/prisma";
|
|||||||
import { User } from "@prisma/client";
|
import { User } from "@prisma/client";
|
||||||
import {ADMIN_LIST, isEmail, isName} from "@/lib/auth_list";
|
import {ADMIN_LIST, isEmail, isName} from "@/lib/auth_list";
|
||||||
import {createTransport} from "nodemailer";
|
import {createTransport} from "nodemailer";
|
||||||
|
import { comparePassword, hashPassword } from "@/lib/utils";
|
||||||
const SECURE_COOKIES:boolean = !!process.env.SECURE_COOKIES;
|
const SECURE_COOKIES:boolean = !!process.env.SECURE_COOKIES;
|
||||||
|
|
||||||
|
|
||||||
@ -73,13 +73,14 @@ export const authOptions: NextAuthOptions = {
|
|||||||
// You can pass any HTML attribute to the <input> tag through the object.
|
// You can pass any HTML attribute to the <input> tag through the object.
|
||||||
credentials: {
|
credentials: {
|
||||||
username: { label: "Username", type: "text", placeholder: "输入姓名或邮箱" },
|
username: { label: "Username", type: "text", placeholder: "输入姓名或邮箱" },
|
||||||
// password: { label: "Password", type: "password" }
|
password: { label: "Password", type: "password", placeholder: "密码验证,测试阶段" }
|
||||||
},
|
},
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
async authorize(credential, req) {
|
async authorize(credential, req) {
|
||||||
const username = cleanUpString(`${credential?.username}`);
|
const username = cleanUpString(`${credential?.username}`);
|
||||||
|
const password = cleanPassword(`${credential?.password}`);
|
||||||
// 验证用户名
|
// 验证用户名
|
||||||
// console.log(credential, username, '==============3')
|
console.log(credential, 'p', password, '==============3')
|
||||||
// 判断姓名格式是否符合要求,不符合则拒绝
|
// 判断姓名格式是否符合要求,不符合则拒绝
|
||||||
if (username && isName(username)) {
|
if (username && isName(username)) {
|
||||||
// Any object returned will be saved in `user` property of the JWT
|
// Any object returned will be saved in `user` property of the JWT
|
||||||
@ -89,6 +90,12 @@ export const authOptions: NextAuthOptions = {
|
|||||||
} else {
|
} else {
|
||||||
user['name'] = username;
|
user['name'] = username;
|
||||||
}
|
}
|
||||||
|
if (password) {
|
||||||
|
user['password'] = password;
|
||||||
|
// 如果有密码,则启用密码验证,查询数据库,否则失败
|
||||||
|
return await validatePassword(user);
|
||||||
|
}
|
||||||
|
|
||||||
return await insertUser(user) ?? user
|
return await insertUser(user) ?? user
|
||||||
} else {
|
} else {
|
||||||
// If you return null then an error will be displayed advising the user to check their details.
|
// If you return null then an error will be displayed advising the user to check their details.
|
||||||
@ -183,62 +190,23 @@ export async function VerifiedAdminUser() {
|
|||||||
return !!(name && ADMIN_LIST.includes(name));
|
return !!(name && ADMIN_LIST.includes(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// export function withSiteAuth(action: any) {
|
export async function validatePassword(user: {[key: string]: string}): Promise<User | void> {
|
||||||
// return async (
|
|
||||||
// formData: FormData | null,
|
const existingUser = await existUser(user);
|
||||||
// siteId: string,
|
console.log('------', 'existUser', existUser)
|
||||||
// key: string | null,
|
|
||||||
// ) => {
|
if (!existingUser) {
|
||||||
// const session = await getSession();
|
throw new Error("用户名或密码不正确");
|
||||||
// if (!session) {
|
}
|
||||||
// return {
|
if (existingUser.password == null) {
|
||||||
// error: "Not authenticated",
|
throw new Error("未设置密码");
|
||||||
// };
|
}
|
||||||
// }
|
if (!comparePassword(user.passowrd, existingUser.password)) {
|
||||||
// const site = await prisma.site.findUnique({
|
throw new Error("用户名或密码不正确")
|
||||||
// where: {
|
} else {
|
||||||
// id: siteId,
|
return existingUser;
|
||||||
// },
|
}
|
||||||
// });
|
}
|
||||||
// if (!site || site.userId !== session.user.id) {
|
|
||||||
// return {
|
|
||||||
// error: "Not authorized",
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return action(formData, site, key);
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// export function withPostAuth(action: any) {
|
|
||||||
// return async (
|
|
||||||
// formData: FormData | null,
|
|
||||||
// postId: string,
|
|
||||||
// key: string | null,
|
|
||||||
// ) => {
|
|
||||||
// const session = await getSession();
|
|
||||||
// if (!session?.user.id) {
|
|
||||||
// return {
|
|
||||||
// error: "Not authenticated",
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// const post = await prisma.post.findUnique({
|
|
||||||
// where: {
|
|
||||||
// id: postId,
|
|
||||||
// },
|
|
||||||
// include: {
|
|
||||||
// site: true,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// if (!post || post.userId !== session.user.id) {
|
|
||||||
// return {
|
|
||||||
// error: "Post not found",
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return action(formData, post, key);
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function existUser(user: {[key: string]: string} | User ) {
|
async function existUser(user: {[key: string]: string} | User ) {
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
@ -287,6 +255,15 @@ function cleanUpString(input: string): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanPassword(input: string): string {
|
||||||
|
try {
|
||||||
|
// 去除前后空格
|
||||||
|
return input.trim()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user