Fix new-home login reliability and set modal backdrop to 85%
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-02-14 02:15:03 +08:00
parent 5933d57246
commit aa98663ce8
6 changed files with 28 additions and 16 deletions

View File

@ -44,9 +44,10 @@ export const login = async (
email: formData.get("email"),
password: formData.get("password"),
});
const normalizedEmail = validatedData.email.trim().toLowerCase();
await signIn("credentials", {
email: validatedData.email,
email: normalizedEmail,
password: validatedData.password,
redirect: false,
});
@ -86,15 +87,16 @@ export const register = async (
email: formData.get("email"),
password: formData.get("password"),
});
const normalizedEmail = validatedData.email.trim().toLowerCase();
const [user] = await getUser(validatedData.email);
const [user] = await getUser(normalizedEmail);
if (user) {
return { status: "user_exists" } as RegisterActionState;
}
await createUser(validatedData.email, validatedData.password);
await createUser(normalizedEmail, validatedData.password);
await signIn("credentials", {
email: validatedData.email,
email: normalizedEmail,
password: validatedData.password,
redirect: false,
});

View File

@ -1,13 +1,10 @@
import type { NextAuthConfig } from "next-auth";
import { isIP } from "node:net";
export function buildAuthConfig(authUrl?: string | null): NextAuthConfig {
const resolvedAuthUrl = authUrl || process.env.AUTH_URL || "";
const isSecure = resolvedAuthUrl.startsWith("https://");
const hostName = resolvedAuthUrl ? new URL(resolvedAuthUrl).hostname : undefined;
// Browsers may reject `Domain` cookies for IP hosts; keep them host-only in that case.
const cookieDomain =
hostName && hostName !== "localhost" && isIP(hostName) === 0 ? hostName : undefined;
// Use host-only cookies to avoid cross-domain login issues in multi-domain deployments.
const cookieDomain = undefined;
return {
trustHost: true,

View File

@ -115,7 +115,14 @@ function createBaseProviders(googleClientId?: string, googleClientSecret?: strin
}
// 2. 邮箱密码登录逻辑
const { email, password } = credentials;
const email = String(credentials?.email || "").trim().toLowerCase();
const password = String(credentials?.password || "");
if (!email || !password) {
await compare(password || "", DUMMY_PASSWORD);
return null;
}
const users = await getUser(email);
if (users.length === 0) {

View File

@ -548,7 +548,7 @@ export default function Page() {
{/* 钉钉登录 iframe 弹窗 / 多组织选择 */}
{showDingTalkModal && (
<div
className="fixed inset-0 bg-black/95 flex items-center justify-center z-50 backdrop-blur-sm"
className="fixed inset-0 bg-black/85 flex items-center justify-center z-50 backdrop-blur-sm"
onClick={(e) => {
if (e.target === e.currentTarget) closeDingTalkModal();
}}

View File

@ -594,7 +594,7 @@ export function LovartHome({
};
const handleEmailLogin = async () => {
const email = loginEmail.trim();
const email = loginEmail.trim().toLowerCase();
if (!email || !loginPassword) {
toast.error("请输入邮箱和密码");
return;
@ -608,7 +608,7 @@ export function LovartHome({
redirect: false,
});
if (result?.error) {
if (!result || result.error || result.ok === false) {
toast.error("登录失败,请检查账号密码");
return;
}
@ -1235,7 +1235,7 @@ export function LovartHome({
{loginDialogOpen ? (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/95 p-4 backdrop-blur-[1px]"
className="fixed inset-0 z-50 flex items-center justify-center bg-black/85 p-4 backdrop-blur-[1px]"
onClick={() => setLoginDialogOpen(false)}
>
<div

View File

@ -65,11 +65,16 @@ import { db } from "@/lib/db";
export async function getUser(email: string): Promise<User[]> {
const normalizedEmail = email.trim().toLowerCase();
if (!normalizedEmail) {
return [];
}
try {
return await db
.select()
.from(user)
.where(eq(user.email, email))
.where(sql`lower(${user.email}) = ${normalizedEmail}`)
.orderBy(desc(user.createdAt));
} catch (_error) {
throw new ChatSDKError(
@ -81,9 +86,10 @@ export async function getUser(email: string): Promise<User[]> {
export async function createUser(email: string, password: string) {
const hashedPassword = generateHashedPassword(password);
const normalizedEmail = email.trim().toLowerCase();
try {
return await db.insert(user).values({ email, password: hashedPassword });
return await db.insert(user).values({ email: normalizedEmail, password: hashedPassword });
} catch (_error) {
throw new ChatSDKError("bad_request:database", "Failed to create user");
}