Fix new-home login reliability and set modal backdrop to 85%
This commit is contained in:
parent
5933d57246
commit
aa98663ce8
@ -44,9 +44,10 @@ export const login = async (
|
|||||||
email: formData.get("email"),
|
email: formData.get("email"),
|
||||||
password: formData.get("password"),
|
password: formData.get("password"),
|
||||||
});
|
});
|
||||||
|
const normalizedEmail = validatedData.email.trim().toLowerCase();
|
||||||
|
|
||||||
await signIn("credentials", {
|
await signIn("credentials", {
|
||||||
email: validatedData.email,
|
email: normalizedEmail,
|
||||||
password: validatedData.password,
|
password: validatedData.password,
|
||||||
redirect: false,
|
redirect: false,
|
||||||
});
|
});
|
||||||
@ -86,15 +87,16 @@ export const register = async (
|
|||||||
email: formData.get("email"),
|
email: formData.get("email"),
|
||||||
password: formData.get("password"),
|
password: formData.get("password"),
|
||||||
});
|
});
|
||||||
|
const normalizedEmail = validatedData.email.trim().toLowerCase();
|
||||||
|
|
||||||
const [user] = await getUser(validatedData.email);
|
const [user] = await getUser(normalizedEmail);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
return { status: "user_exists" } as RegisterActionState;
|
return { status: "user_exists" } as RegisterActionState;
|
||||||
}
|
}
|
||||||
await createUser(validatedData.email, validatedData.password);
|
await createUser(normalizedEmail, validatedData.password);
|
||||||
await signIn("credentials", {
|
await signIn("credentials", {
|
||||||
email: validatedData.email,
|
email: normalizedEmail,
|
||||||
password: validatedData.password,
|
password: validatedData.password,
|
||||||
redirect: false,
|
redirect: false,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
import type { NextAuthConfig } from "next-auth";
|
import type { NextAuthConfig } from "next-auth";
|
||||||
import { isIP } from "node:net";
|
|
||||||
|
|
||||||
export function buildAuthConfig(authUrl?: string | null): NextAuthConfig {
|
export function buildAuthConfig(authUrl?: string | null): NextAuthConfig {
|
||||||
const resolvedAuthUrl = authUrl || process.env.AUTH_URL || "";
|
const resolvedAuthUrl = authUrl || process.env.AUTH_URL || "";
|
||||||
const isSecure = resolvedAuthUrl.startsWith("https://");
|
const isSecure = resolvedAuthUrl.startsWith("https://");
|
||||||
const hostName = resolvedAuthUrl ? new URL(resolvedAuthUrl).hostname : undefined;
|
// Use host-only cookies to avoid cross-domain login issues in multi-domain deployments.
|
||||||
// Browsers may reject `Domain` cookies for IP hosts; keep them host-only in that case.
|
const cookieDomain = undefined;
|
||||||
const cookieDomain =
|
|
||||||
hostName && hostName !== "localhost" && isIP(hostName) === 0 ? hostName : undefined;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
trustHost: true,
|
trustHost: true,
|
||||||
|
|||||||
@ -115,7 +115,14 @@ function createBaseProviders(googleClientId?: string, googleClientSecret?: strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 邮箱密码登录逻辑
|
// 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);
|
const users = await getUser(email);
|
||||||
|
|
||||||
if (users.length === 0) {
|
if (users.length === 0) {
|
||||||
|
|||||||
@ -548,7 +548,7 @@ export default function Page() {
|
|||||||
{/* 钉钉登录 iframe 弹窗 / 多组织选择 */}
|
{/* 钉钉登录 iframe 弹窗 / 多组织选择 */}
|
||||||
{showDingTalkModal && (
|
{showDingTalkModal && (
|
||||||
<div
|
<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) => {
|
onClick={(e) => {
|
||||||
if (e.target === e.currentTarget) closeDingTalkModal();
|
if (e.target === e.currentTarget) closeDingTalkModal();
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -594,7 +594,7 @@ export function LovartHome({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleEmailLogin = async () => {
|
const handleEmailLogin = async () => {
|
||||||
const email = loginEmail.trim();
|
const email = loginEmail.trim().toLowerCase();
|
||||||
if (!email || !loginPassword) {
|
if (!email || !loginPassword) {
|
||||||
toast.error("请输入邮箱和密码");
|
toast.error("请输入邮箱和密码");
|
||||||
return;
|
return;
|
||||||
@ -608,7 +608,7 @@ export function LovartHome({
|
|||||||
redirect: false,
|
redirect: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result?.error) {
|
if (!result || result.error || result.ok === false) {
|
||||||
toast.error("登录失败,请检查账号密码");
|
toast.error("登录失败,请检查账号密码");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1235,7 +1235,7 @@ export function LovartHome({
|
|||||||
|
|
||||||
{loginDialogOpen ? (
|
{loginDialogOpen ? (
|
||||||
<div
|
<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)}
|
onClick={() => setLoginDialogOpen(false)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -65,11 +65,16 @@ import { db } from "@/lib/db";
|
|||||||
|
|
||||||
|
|
||||||
export async function getUser(email: string): Promise<User[]> {
|
export async function getUser(email: string): Promise<User[]> {
|
||||||
|
const normalizedEmail = email.trim().toLowerCase();
|
||||||
|
if (!normalizedEmail) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await db
|
return await db
|
||||||
.select()
|
.select()
|
||||||
.from(user)
|
.from(user)
|
||||||
.where(eq(user.email, email))
|
.where(sql`lower(${user.email}) = ${normalizedEmail}`)
|
||||||
.orderBy(desc(user.createdAt));
|
.orderBy(desc(user.createdAt));
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
throw new ChatSDKError(
|
throw new ChatSDKError(
|
||||||
@ -81,9 +86,10 @@ export async function getUser(email: string): Promise<User[]> {
|
|||||||
|
|
||||||
export async function createUser(email: string, password: string) {
|
export async function createUser(email: string, password: string) {
|
||||||
const hashedPassword = generateHashedPassword(password);
|
const hashedPassword = generateHashedPassword(password);
|
||||||
|
const normalizedEmail = email.trim().toLowerCase();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await db.insert(user).values({ email, password: hashedPassword });
|
return await db.insert(user).values({ email: normalizedEmail, password: hashedPassword });
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
throw new ChatSDKError("bad_request:database", "Failed to create user");
|
throw new ChatSDKError("bad_request:database", "Failed to create user");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user