senlinyy commited on
Commit
bfb06d5
·
1 Parent(s): 815c966

fix: fix cookie issue

Browse files
frontend/app/admin/page.tsx CHANGED
@@ -17,7 +17,8 @@ export default function AdminPage() {
17
  useEffect(() => {
18
  (async () => {
19
  const r = await fetch("/api/admin/me", { credentials: "same-origin" });
20
- if (!r.ok) router.replace("/admin/login");
 
21
  else setChecking(false);
22
  })();
23
  }, [router]);
 
17
  useEffect(() => {
18
  (async () => {
19
  const r = await fetch("/api/admin/me", { credentials: "same-origin" });
20
+ const session = r.ok ? await r.json().catch(() => null) : null;
21
+ if (!session?.authenticated) router.replace("/admin/login");
22
  else setChecking(false);
23
  })();
24
  }, [router]);
frontend/app/api/admin/login/route.ts CHANGED
@@ -4,6 +4,16 @@ import { backendUrl } from "@/lib/backend-url";
4
  export const dynamic = "force-dynamic";
5
  export const runtime = "nodejs";
6
 
 
 
 
 
 
 
 
 
 
 
7
  export async function POST(request: NextRequest) {
8
  let response: Response;
9
  try {
@@ -21,14 +31,24 @@ export async function POST(request: NextRequest) {
21
  );
22
  }
23
 
24
- const headers = new Headers();
25
- headers.set("content-type", response.headers.get("content-type") ?? "application/json");
26
- const cookie = response.headers.get("set-cookie");
27
- if (cookie) headers.set("set-cookie", cookie);
28
-
29
- return new NextResponse(await response.text(), {
30
  status: response.status,
31
- headers,
 
 
32
  });
33
- }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  export const dynamic = "force-dynamic";
5
  export const runtime = "nodejs";
6
 
7
+ const ADMIN_COOKIE = "admin_session";
8
+ const SESSION_MAX_AGE = 60 * 60 * 12;
9
+
10
+ function sessionValue(setCookie: string | null) {
11
+ const pair = setCookie?.split(";")[0] ?? "";
12
+ const [name, ...valueParts] = pair.split("=");
13
+ if (name !== ADMIN_COOKIE || valueParts.length === 0) return null;
14
+ return valueParts.join("=");
15
+ }
16
+
17
  export async function POST(request: NextRequest) {
18
  let response: Response;
19
  try {
 
31
  );
32
  }
33
 
34
+ const body = response.ok ? JSON.stringify({ ok: true }) : await response.text();
35
+ const nextResponse = new NextResponse(body, {
 
 
 
 
36
  status: response.status,
37
+ headers: {
38
+ "content-type": response.headers.get("content-type") ?? "application/json",
39
+ },
40
  });
 
41
 
42
+ const value = sessionValue(response.headers.get("set-cookie"));
43
+ if (response.ok && value) {
44
+ nextResponse.cookies.set(ADMIN_COOKIE, value, {
45
+ httpOnly: true,
46
+ sameSite: "lax",
47
+ secure: request.nextUrl.protocol === "https:",
48
+ maxAge: SESSION_MAX_AGE,
49
+ path: "/",
50
+ });
51
+ }
52
+
53
+ return nextResponse;
54
+ }
frontend/app/api/admin/logout/route.ts CHANGED
@@ -4,6 +4,8 @@ import { backendUrl } from "@/lib/backend-url";
4
  export const dynamic = "force-dynamic";
5
  export const runtime = "nodejs";
6
 
 
 
7
  export async function POST(request: NextRequest) {
8
  let response: Response;
9
  try {
@@ -20,14 +22,19 @@ export async function POST(request: NextRequest) {
20
  );
21
  }
22
 
23
- const headers = new Headers();
24
- headers.set("content-type", response.headers.get("content-type") ?? "application/json");
25
- const cookie = response.headers.get("set-cookie");
26
- if (cookie) headers.set("set-cookie", cookie);
27
-
28
- return new NextResponse(await response.text(), {
29
  status: response.status,
30
- headers,
 
 
 
 
 
 
 
 
 
31
  });
32
- }
33
 
 
 
 
4
  export const dynamic = "force-dynamic";
5
  export const runtime = "nodejs";
6
 
7
+ const ADMIN_COOKIE = "admin_session";
8
+
9
  export async function POST(request: NextRequest) {
10
  let response: Response;
11
  try {
 
22
  );
23
  }
24
 
25
+ const nextResponse = new NextResponse(await response.text(), {
 
 
 
 
 
26
  status: response.status,
27
+ headers: {
28
+ "content-type": response.headers.get("content-type") ?? "application/json",
29
+ },
30
+ });
31
+ nextResponse.cookies.set(ADMIN_COOKIE, "", {
32
+ httpOnly: true,
33
+ sameSite: "lax",
34
+ secure: request.nextUrl.protocol === "https:",
35
+ maxAge: 0,
36
+ path: "/",
37
  });
 
38
 
39
+ return nextResponse;
40
+ }
frontend/app/api/admin/me/route.ts CHANGED
@@ -20,6 +20,13 @@ export async function GET(request: NextRequest) {
20
  );
21
  }
22
 
 
 
 
 
 
 
 
23
  return new NextResponse(await response.text(), {
24
  status: response.status,
25
  headers: {
@@ -28,4 +35,3 @@ export async function GET(request: NextRequest) {
28
  },
29
  });
30
  }
31
-
 
20
  );
21
  }
22
 
23
+ if (response.status === 401 || response.status === 403) {
24
+ return NextResponse.json(
25
+ { authenticated: false },
26
+ { status: 200, headers: { "cache-control": "no-store" } }
27
+ );
28
+ }
29
+
30
  return new NextResponse(await response.text(), {
31
  status: response.status,
32
  headers: {
 
35
  },
36
  });
37
  }