From 6bb1a5a5a0a2594cce4f4e11f0b68f7876218f4a Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 02:59:20 +0800 Subject: [PATCH 01/44] fix: set trustHost --- auth.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/auth.ts b/auth.ts index d53aeae..dea71d1 100644 --- a/auth.ts +++ b/auth.ts @@ -5,6 +5,7 @@ import getEnv from "./lib/env-entry"; export const { handlers, signIn, signOut, auth } = NextAuth({ secret: "this_is_nezha_dash_web_secret", + trustHost: true, providers: [ Credentials({ credentials: { From 1a46cec6620dba5c10c0738bdeb87325a3e500cb Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 10:13:00 +0800 Subject: [PATCH 02/44] refactor: auth page --- app/[locale]/(main)/header.tsx | 6 ++-- app/[locale]/(main)/layout.tsx | 8 ++--- auth.ts | 9 ++--- components/SignIn.tsx | 66 ++++++++++++++++++++++++++++++++++ components/sign-in.tsx | 45 ----------------------- messages/en.json | 5 +++ messages/ja.json | 5 +++ messages/zh-t.json | 5 +++ messages/zh.json | 5 +++ next.config.mjs | 5 --- 10 files changed, 97 insertions(+), 62 deletions(-) create mode 100644 components/SignIn.tsx delete mode 100644 components/sign-in.tsx diff --git a/app/[locale]/(main)/header.tsx b/app/[locale]/(main)/header.tsx index cb335a9..82177d0 100644 --- a/app/[locale]/(main)/header.tsx +++ b/app/[locale]/(main)/header.tsx @@ -63,7 +63,7 @@ function Header() { // https://github.com/streamich/react-use/blob/master/src/useInterval.ts const useInterval = (callback: Function, delay?: number | null) => { - const savedCallback = useRef(() => { }); + const savedCallback = useRef(() => {}); useEffect(() => { savedCallback.current = callback; }); @@ -98,7 +98,9 @@ function Overview() {

{mouted ? (

{timeString}

- ) : } + ) : ( + + )} ); diff --git a/app/[locale]/(main)/layout.tsx b/app/[locale]/(main)/layout.tsx index bb2a8de..e60a237 100644 --- a/app/[locale]/(main)/layout.tsx +++ b/app/[locale]/(main)/layout.tsx @@ -1,7 +1,7 @@ import Footer from "@/app/[locale]/(main)/footer"; import Header from "@/app/[locale]/(main)/header"; import { auth } from "@/auth"; -import { SignIn } from "@/components/sign-in"; +import { SignIn } from "@/components/SignIn"; import getEnv from "@/lib/env-entry"; import { redirect } from "next/navigation"; import React from "react"; @@ -13,11 +13,7 @@ export default async function MainLayout({ children }: DashboardProps) { const session = await auth(); if (!session && getEnv("SitePassword")) { - if (getEnv("CF_PAGES")) { - redirect("/api/auth/signin"); - } else { - return ; - } + return ; } return ( diff --git a/auth.ts b/auth.ts index dea71d1..dc90f57 100644 --- a/auth.ts +++ b/auth.ts @@ -6,14 +6,15 @@ import getEnv from "./lib/env-entry"; export const { handlers, signIn, signOut, auth } = NextAuth({ secret: "this_is_nezha_dash_web_secret", trustHost: true, + pages: { + signIn: "/", + }, providers: [ Credentials({ - credentials: { - password: {}, - }, + credentials: { password: { label: "Password", type: "password" } }, authorize: async (credentials) => { if (credentials.password === getEnv("SitePassword")) { - return { id: "0" }; + return { id: "nezha-dash-auth" }; } return null; }, diff --git a/components/SignIn.tsx b/components/SignIn.tsx new file mode 100644 index 0000000..272c47c --- /dev/null +++ b/components/SignIn.tsx @@ -0,0 +1,66 @@ +"use client"; + +import Footer from "@/app/[locale]/(main)/footer"; +import Header from "@/app/[locale]/(main)/header"; +import { getCsrfToken } from "next-auth/react"; +import { useTranslations } from "next-intl"; +import { useSearchParams } from "next/navigation"; +import { useEffect, useState } from "react"; + +export function SignIn({}) { + const t = useTranslations("SignIn"); + + const [csrfToken, setCsrfToken] = useState(""); + const [errorState, setErrorState] = useState(false); + + const search = useSearchParams(); + const error = search.get("error"); + + useEffect(() => { + if (error) { + setErrorState(true); + } + }, [error]); + + useEffect(() => { + async function loadProviders() { + const csrf = await getCsrfToken(); + setCsrfToken(csrf); + } + loadProviders(); + }, []); + + return ( +
+
+
+
+ +
+ + +
+
+
+
+
+ ); +} diff --git a/components/sign-in.tsx b/components/sign-in.tsx deleted file mode 100644 index c8adbea..0000000 --- a/components/sign-in.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import Footer from "@/app/[locale]/(main)/footer"; -import Header from "@/app/[locale]/(main)/header"; -import { signIn } from "@/auth"; -import { useLocale } from "next-intl"; -import { redirect } from "next/navigation"; - -export function SignIn() { - const locale = useLocale(); - - async function handleSubmit(formData: FormData) { - "use server"; - try { - await signIn("credentials", formData); - } catch (error) { - redirect(`/${locale}`); - } - } - - return ( -
-
-
-
-
- - -
-
-
-
-
- ); -} diff --git a/messages/en.json b/messages/en.json index 0fe32f9..49e7536 100644 --- a/messages/en.json +++ b/messages/en.json @@ -23,6 +23,11 @@ "Detail": "Detail", "Network": "Network" }, + "SignIn": { + "SignInMessage": "Please enter the password", + "Submit": "Login", + "ErrorMessage": "Invalid password" + }, "ServerCardPopover": { "System": "System", "CPU": "CPU", diff --git a/messages/ja.json b/messages/ja.json index 02aef43..d89e131 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -23,6 +23,11 @@ "Detail": "詳細", "Network": "ネットワーク" }, + "SignIn": { + "SignInMessage": "パスワードを入力してください", + "Submit": "ログイン", + "ErrorMessage": "パスワードが間違っています" + }, "ServerCardPopover": { "System": "システム", "CPU": "CPU", diff --git a/messages/zh-t.json b/messages/zh-t.json index ffead2a..b1bee23 100644 --- a/messages/zh-t.json +++ b/messages/zh-t.json @@ -23,6 +23,11 @@ "Detail": "詳細", "Network": "網路" }, + "SignIn": { + "SignInMessage": "請輸入密碼", + "Submit": "登入", + "ErrorMessage": "密碼錯誤" + }, "ServerCardPopover": { "System": "系統", "CPU": "CPU", diff --git a/messages/zh.json b/messages/zh.json index ed853f0..2786dad 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -23,6 +23,11 @@ "Detail": "详情", "Network": "网络" }, + "SignIn": { + "SignInMessage": "请输入密码", + "Submit": "登录", + "ErrorMessage": "密码错误" + }, "ServerCardPopover": { "System": "系统", "CPU": "CPU", diff --git a/next.config.mjs b/next.config.mjs index a68be47..86bfbf5 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -23,11 +23,6 @@ const withPWA = withPWAInit({ const nextConfig = { output: "standalone", reactStrictMode: true, - experimental: { - serverActions: { - allowedOrigins: ["*"], - }, - }, logging: { fetches: { fullUrl: true, From f42cc026acb39bd0683136f9856dc5abffa573de Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 10:25:00 +0800 Subject: [PATCH 03/44] feat: add api auth redirect --- app/[locale]/(main)/layout.tsx | 1 - app/api/detail/route.ts | 3 ++- app/api/monitor/route.ts | 3 ++- app/api/server/route.ts | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/[locale]/(main)/layout.tsx b/app/[locale]/(main)/layout.tsx index e60a237..e11be35 100644 --- a/app/[locale]/(main)/layout.tsx +++ b/app/[locale]/(main)/layout.tsx @@ -3,7 +3,6 @@ import Header from "@/app/[locale]/(main)/header"; import { auth } from "@/auth"; import { SignIn } from "@/components/SignIn"; import getEnv from "@/lib/env-entry"; -import { redirect } from "next/navigation"; import React from "react"; type DashboardProps = { diff --git a/app/api/detail/route.ts b/app/api/detail/route.ts index 8ee895f..a123e22 100644 --- a/app/api/detail/route.ts +++ b/app/api/detail/route.ts @@ -2,6 +2,7 @@ import { NezhaAPISafe } from "@/app/[locale]/types/nezha-api"; import { auth } from "@/auth"; import getEnv from "@/lib/env-entry"; import { GetServerDetail } from "@/lib/serverFetch"; +import { redirect } from "next/navigation"; import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; @@ -13,7 +14,7 @@ interface NezhaDataResponse { export const GET = auth(async function GET(req) { if (!req.auth && getEnv("SitePassword")) { - return NextResponse.json({ message: "Not authenticated" }, { status: 401 }); + redirect("/api/auth/signin"); } const { searchParams } = new URL(req.url); diff --git a/app/api/monitor/route.ts b/app/api/monitor/route.ts index 8f9f561..7757825 100644 --- a/app/api/monitor/route.ts +++ b/app/api/monitor/route.ts @@ -2,6 +2,7 @@ import { ServerMonitorChart } from "@/app/[locale]/types/nezha-api"; import { auth } from "@/auth"; import getEnv from "@/lib/env-entry"; import { GetServerMonitor } from "@/lib/serverFetch"; +import { redirect } from "next/navigation"; import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; @@ -13,7 +14,7 @@ interface NezhaDataResponse { export const GET = auth(async function GET(req) { if (!req.auth && getEnv("SitePassword")) { - return NextResponse.json({ message: "Not authenticated" }, { status: 401 }); + redirect("/api/auth/signin"); } const { searchParams } = new URL(req.url); diff --git a/app/api/server/route.ts b/app/api/server/route.ts index 80a65f9..a203212 100644 --- a/app/api/server/route.ts +++ b/app/api/server/route.ts @@ -2,6 +2,7 @@ import { ServerApi } from "@/app/[locale]/types/nezha-api"; import { auth } from "@/auth"; import getEnv from "@/lib/env-entry"; import { GetNezhaData } from "@/lib/serverFetch"; +import { redirect } from "next/navigation"; import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; @@ -13,7 +14,7 @@ interface NezhaDataResponse { export const GET = auth(async function GET(req) { if (!req.auth && getEnv("SitePassword")) { - return NextResponse.json({ message: "Not authenticated" }, { status: 401 }); + redirect("/api/auth/signin"); } const response = (await GetNezhaData()) as NezhaDataResponse; From 9ad5c1f2895f800133ad006e017d928f0ee69a9f Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 10:32:12 +0800 Subject: [PATCH 04/44] refactor: auth component --- app/[locale]/(main)/layout.tsx | 6 +--- components/SignIn.tsx | 60 +++++++++++++++------------------- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/app/[locale]/(main)/layout.tsx b/app/[locale]/(main)/layout.tsx index e11be35..c237dc7 100644 --- a/app/[locale]/(main)/layout.tsx +++ b/app/[locale]/(main)/layout.tsx @@ -11,15 +11,11 @@ type DashboardProps = { export default async function MainLayout({ children }: DashboardProps) { const session = await auth(); - if (!session && getEnv("SitePassword")) { - return ; - } - return (
- {children} + {!session && getEnv("SitePassword") ? : children}
diff --git a/components/SignIn.tsx b/components/SignIn.tsx index 272c47c..1bcca2d 100644 --- a/components/SignIn.tsx +++ b/components/SignIn.tsx @@ -1,13 +1,11 @@ "use client"; -import Footer from "@/app/[locale]/(main)/footer"; -import Header from "@/app/[locale]/(main)/header"; import { getCsrfToken } from "next-auth/react"; import { useTranslations } from "next-intl"; import { useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; -export function SignIn({}) { +export function SignIn() { const t = useTranslations("SignIn"); const [csrfToken, setCsrfToken] = useState(""); @@ -31,36 +29,30 @@ export function SignIn({}) { }, []); return ( -
-
-
-
- -
- - -
-
-
-
-
+
+ +
+ + +
+
); } From 9a0b65a3ab6247517de9ad545ba9fd9ec20b18f1 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 10:57:13 +0800 Subject: [PATCH 05/44] fix: docker callback url --- app/api/auth/[...nextauth]/route.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts index 87f6488..4ddc1da 100644 --- a/app/api/auth/[...nextauth]/route.ts +++ b/app/api/auth/[...nextauth]/route.ts @@ -1,4 +1,22 @@ import { handlers } from "@/auth"; +import { NextRequest } from "next/server"; -// Referring to the auth.ts we just created -export const { GET, POST } = handlers; +const reqWithTrustedOrigin = (req: NextRequest): NextRequest => { + const proto = req.headers.get("x-forwarded-proto"); + const host = req.headers.get("x-forwarded-host"); + if (!proto || !host) { + console.warn("Missing x-forwarded-proto or x-forwarded-host headers."); + return req; + } + const envOrigin = `${proto}://${host}`; + const { href, origin } = req.nextUrl; + return new NextRequest(href.replace(origin, envOrigin), req); +}; + +export const GET = (req: NextRequest) => { + return handlers.GET(reqWithTrustedOrigin(req)); +}; + +export const POST = (req: NextRequest) => { + return handlers.POST(reqWithTrustedOrigin(req)); +}; From ca0f12774be3083e596a8ff8c2c465d205175432 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 11:28:44 +0800 Subject: [PATCH 06/44] fix: docker auth_url --- app/api/auth/[...nextauth]/route.ts | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts index 4ddc1da..86c9f3d 100644 --- a/app/api/auth/[...nextauth]/route.ts +++ b/app/api/auth/[...nextauth]/route.ts @@ -1,22 +1,3 @@ import { handlers } from "@/auth"; -import { NextRequest } from "next/server"; -const reqWithTrustedOrigin = (req: NextRequest): NextRequest => { - const proto = req.headers.get("x-forwarded-proto"); - const host = req.headers.get("x-forwarded-host"); - if (!proto || !host) { - console.warn("Missing x-forwarded-proto or x-forwarded-host headers."); - return req; - } - const envOrigin = `${proto}://${host}`; - const { href, origin } = req.nextUrl; - return new NextRequest(href.replace(origin, envOrigin), req); -}; - -export const GET = (req: NextRequest) => { - return handlers.GET(reqWithTrustedOrigin(req)); -}; - -export const POST = (req: NextRequest) => { - return handlers.POST(reqWithTrustedOrigin(req)); -}; +export const { GET, POST } = handlers; From b7085f3d41b0838112a676ad6403290529100a56 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 11:39:10 +0800 Subject: [PATCH 07/44] feat: add auth env --- auth.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auth.ts b/auth.ts index dc90f57..71604fb 100644 --- a/auth.ts +++ b/auth.ts @@ -4,8 +4,8 @@ import Credentials from "next-auth/providers/credentials"; import getEnv from "./lib/env-entry"; export const { handlers, signIn, signOut, auth } = NextAuth({ - secret: "this_is_nezha_dash_web_secret", - trustHost: true, + secret: process.env.AUTH_SECRET ?? "this_is_nezha_dash_web_secret", + trustHost: process.env.AUTH_TRUST_HOST as boolean | undefined ?? true, pages: { signIn: "/", }, From 667ae590bb15e2b200aacf3e5d44081b79da504e Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 12:20:50 +0800 Subject: [PATCH 08/44] refactor: signin logic --- components/SignIn.tsx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/components/SignIn.tsx b/components/SignIn.tsx index 1bcca2d..e17507d 100644 --- a/components/SignIn.tsx +++ b/components/SignIn.tsx @@ -1,8 +1,8 @@ "use client"; -import { getCsrfToken } from "next-auth/react"; +import { getCsrfToken, signIn } from "next-auth/react"; import { useTranslations } from "next-intl"; -import { useSearchParams } from "next/navigation"; +import { useSearchParams, useRouter } from "next/navigation"; import { useEffect, useState } from "react"; export function SignIn() { @@ -13,6 +13,7 @@ export function SignIn() { const search = useSearchParams(); const error = search.get("error"); + const router = useRouter(); useEffect(() => { if (error) { @@ -28,11 +29,26 @@ export function SignIn() { loadProviders(); }, []); + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const formData = new FormData(e.currentTarget); + const password = formData.get("password"); + const res = await signIn("credentials", { + password, + redirect: false, + }); + if (res?.error) { + setErrorState(true); + } else { + router.push("/"); + router.refresh(); + } + }; + return (
From 8e5ddd6de80f89aa1e17127dc51ee4a2870504f2 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 12:32:29 +0800 Subject: [PATCH 09/44] feat: add success state --- auth.ts | 2 +- components/SignIn.tsx | 21 +++++++++++++++++++-- messages/en.json | 3 ++- messages/ja.json | 3 ++- messages/zh-t.json | 3 ++- messages/zh.json | 3 ++- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/auth.ts b/auth.ts index 71604fb..1b7c8f1 100644 --- a/auth.ts +++ b/auth.ts @@ -5,7 +5,7 @@ import getEnv from "./lib/env-entry"; export const { handlers, signIn, signOut, auth } = NextAuth({ secret: process.env.AUTH_SECRET ?? "this_is_nezha_dash_web_secret", - trustHost: process.env.AUTH_TRUST_HOST as boolean | undefined ?? true, + trustHost: (process.env.AUTH_TRUST_HOST as boolean | undefined) ?? true, pages: { signIn: "/", }, diff --git a/components/SignIn.tsx b/components/SignIn.tsx index e17507d..31e6913 100644 --- a/components/SignIn.tsx +++ b/components/SignIn.tsx @@ -2,14 +2,18 @@ import { getCsrfToken, signIn } from "next-auth/react"; import { useTranslations } from "next-intl"; -import { useSearchParams, useRouter } from "next/navigation"; +import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; +import { Loader } from "./loading/Loader"; + export function SignIn() { const t = useTranslations("SignIn"); const [csrfToken, setCsrfToken] = useState(""); const [errorState, setErrorState] = useState(false); + const [loading, setLoading] = useState(false); + const [successState, setSuccessState] = useState(false); const search = useSearchParams(); const error = search.get("error"); @@ -31,6 +35,7 @@ export function SignIn() { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); + setLoading(true); const formData = new FormData(e.currentTarget); const password = formData.get("password"); const res = await signIn("credentials", { @@ -40,9 +45,12 @@ export function SignIn() { if (res?.error) { setErrorState(true); } else { + setErrorState(false); + setSuccessState(true); router.push("/"); router.refresh(); } + setLoading(false); }; return ( @@ -58,6 +66,11 @@ export function SignIn() { {t("ErrorMessage")}

)} + {successState && ( +

+ {t("SuccessMessage")} +

+ )}

{t("SignInMessage")}

-
diff --git a/messages/en.json b/messages/en.json index 49e7536..93ea985 100644 --- a/messages/en.json +++ b/messages/en.json @@ -26,7 +26,8 @@ "SignIn": { "SignInMessage": "Please enter the password", "Submit": "Login", - "ErrorMessage": "Invalid password" + "ErrorMessage": "Invalid password", + "SuccessMessage": "Login successful" }, "ServerCardPopover": { "System": "System", diff --git a/messages/ja.json b/messages/ja.json index d89e131..e7c1fb8 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -26,7 +26,8 @@ "SignIn": { "SignInMessage": "パスワードを入力してください", "Submit": "ログイン", - "ErrorMessage": "パスワードが間違っています" + "ErrorMessage": "パスワードが間違っています", + "SuccessMessage": "ログイン成功" }, "ServerCardPopover": { "System": "システム", diff --git a/messages/zh-t.json b/messages/zh-t.json index b1bee23..2681dd8 100644 --- a/messages/zh-t.json +++ b/messages/zh-t.json @@ -26,7 +26,8 @@ "SignIn": { "SignInMessage": "請輸入密碼", "Submit": "登入", - "ErrorMessage": "密碼錯誤" + "ErrorMessage": "密碼錯誤", + "SuccessMessage": "登入成功" }, "ServerCardPopover": { "System": "系統", diff --git a/messages/zh.json b/messages/zh.json index 2786dad..4fb89e7 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -26,7 +26,8 @@ "SignIn": { "SignInMessage": "请输入密码", "Submit": "登录", - "ErrorMessage": "密码错误" + "ErrorMessage": "密码错误", + "SuccessMessage": "登录成功" }, "ServerCardPopover": { "System": "系统", From a7b12bbf6432bb0c8d09bb2e001a3bc78f1e1f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=93=E9=BC=A0?= <71394853+hamster1963@users.noreply.github.com> Date: Mon, 21 Oct 2024 12:47:23 +0800 Subject: [PATCH 10/44] doc: update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12dc995..8a55a7e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ | 一键部署到 Vercel-推荐 | Docker部署 | Cloudflare部署 | 如何更新? | | ----------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------- | | [部署简易教程](https://buycoffee.top/blog/tech/nezha) | [Docker 部署教程](https://buycoffee.top/blog/tech/nezha-docker) | [Cloudflare 部署教程](https://buycoffee.top/blog/tech/nezha-cloudflare) | [更新教程](https://buycoffee.top/blog/tech/nezha-upgrade) | -| [Vercel-demo](https://nezha-vercel.buycoffee.top) | [Docker-demo](https://nezha-docker.buycoffee.tech) | [Cloudflare-demo](https://nezha-cloudflare.buycoffee.tech) | +| [Vercel-demo](https://nezha-vercel.buycoffee.top) | [Docker-demo](https://nezha-docker.buycoffee.tech) | [Cloudflare-demo](https://nezha-cloudflare.buycoffee.tech) [密码: nezhadash] | #### 环境变量 From dd05154be2e70a76082f37434c61f31de387fa98 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 13:10:59 +0800 Subject: [PATCH 11/44] feat: client side auth --- components/SignIn.tsx | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/components/SignIn.tsx b/components/SignIn.tsx index 31e6913..e49da09 100644 --- a/components/SignIn.tsx +++ b/components/SignIn.tsx @@ -6,6 +6,7 @@ import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; import { Loader } from "./loading/Loader"; +import { auth } from "@/auth"; export function SignIn() { const t = useTranslations("SignIn"); @@ -37,20 +38,35 @@ export function SignIn() { e.preventDefault(); setLoading(true); const formData = new FormData(e.currentTarget); - const password = formData.get("password"); - const res = await signIn("credentials", { - password, - redirect: false, + + + // 直接构建 URL 编码的字符串 + const urlEncodedData = [ + `csrfToken=${encodeURIComponent(csrfToken)}`, + `redirect=false`, + `password=${encodeURIComponent(formData.get('password') as string)}`, + ].join('&'); + + await fetch("/api/auth/callback/credentials", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: urlEncodedData, }); - if (res?.error) { - setErrorState(true); - } else { - setErrorState(false); + + const session = await auth(); + + + if (session) { setSuccessState(true); - router.push("/"); - router.refresh(); + } else { + setErrorState(true); } - setLoading(false); + + setLoading(false) + router.push("/"); + router.refresh(); }; return ( From 117ea33382fac945a25ceee797451b89433798c5 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Mon, 21 Oct 2024 13:41:23 +0800 Subject: [PATCH 12/44] perf: remove error state --- components/SignIn.tsx | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/components/SignIn.tsx b/components/SignIn.tsx index e49da09..bb69b8d 100644 --- a/components/SignIn.tsx +++ b/components/SignIn.tsx @@ -1,31 +1,20 @@ "use client"; -import { getCsrfToken, signIn } from "next-auth/react"; +import { getCsrfToken } from "next-auth/react"; import { useTranslations } from "next-intl"; -import { useRouter, useSearchParams } from "next/navigation"; +import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { Loader } from "./loading/Loader"; -import { auth } from "@/auth"; export function SignIn() { const t = useTranslations("SignIn"); const [csrfToken, setCsrfToken] = useState(""); - const [errorState, setErrorState] = useState(false); const [loading, setLoading] = useState(false); - const [successState, setSuccessState] = useState(false); - const search = useSearchParams(); - const error = search.get("error"); const router = useRouter(); - useEffect(() => { - if (error) { - setErrorState(true); - } - }, [error]); - useEffect(() => { async function loadProviders() { const csrf = await getCsrfToken(); @@ -54,19 +43,9 @@ export function SignIn() { }, body: urlEncodedData, }); - - const session = await auth(); - - - if (session) { - setSuccessState(true); - } else { - setErrorState(true); - } - - setLoading(false) router.push("/"); router.refresh(); + setLoading(false) }; return ( @@ -77,16 +56,6 @@ export function SignIn() {