Add login gate, calculation history, and AI markdown download.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-13 09:39:38 +08:00
parent abf78cbbb5
commit 462bec2739
23 changed files with 878 additions and 74 deletions
+41
View File
@@ -0,0 +1,41 @@
import { NextResponse } from "next/server";
import {
isAuthEnabled,
verifyCredentials,
} from "@/lib/auth/config";
import {
createSessionToken,
SESSION_COOKIE,
SESSION_MAX_AGE_SEC,
} from "@/lib/auth/session";
export async function POST(req: Request) {
if (!isAuthEnabled()) {
return NextResponse.json({ ok: true, authEnabled: false });
}
let body: { username?: string; password?: string };
try {
body = await req.json();
} catch {
return NextResponse.json({ error: "请求格式错误" }, { status: 400 });
}
const username = body.username?.trim() ?? "";
const password = body.password ?? "";
if (!verifyCredentials(username, password)) {
return NextResponse.json({ error: "用户名或密码错误" }, { status: 401 });
}
const token = await createSessionToken(username);
const res = NextResponse.json({ ok: true, username });
res.cookies.set(SESSION_COOKIE, token, {
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
path: "/",
maxAge: SESSION_MAX_AGE_SEC,
});
return res;
}
+14
View File
@@ -0,0 +1,14 @@
import { NextResponse } from "next/server";
import { SESSION_COOKIE } from "@/lib/auth/session";
export async function POST() {
const res = NextResponse.json({ ok: true });
res.cookies.set(SESSION_COOKIE, "", {
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
path: "/",
maxAge: 0,
});
return res;
}
+19
View File
@@ -0,0 +1,19 @@
import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { isAuthEnabled } from "@/lib/auth/config";
import { getSessionUsername, SESSION_COOKIE } from "@/lib/auth/session";
export async function GET() {
if (!isAuthEnabled()) {
return NextResponse.json({ authEnabled: false, loggedIn: true });
}
const token = (await cookies()).get(SESSION_COOKIE)?.value;
const username = await getSessionUsername(token);
return NextResponse.json({
authEnabled: true,
loggedIn: !!username,
username: username ?? undefined,
});
}