feat: complete v0.5 operations foundation

This commit is contained in:
2026-07-19 03:58:03 +08:00
parent ca3f706cc1
commit d285f3e275
35 changed files with 248 additions and 39 deletions
+3 -3
View File
@@ -1,3 +1,3 @@
import { NextResponse } from "next/server"; import bcrypt from "bcryptjs"; import { db } from "@/lib/db"; import { createSession } from "@/lib/auth"; import { externalUrl } from "@/lib/http";
export async function POST(req: Request) { const form = await req.formData(); const username=String(form.get("username")||""); const password=String(form.get("password")||""); const user=db.prepare("SELECT id,username,password_hash,role,disabled FROM users WHERE username=?").get(username) as any;
if (!user || user.disabled || !(await bcrypt.compare(password,user.password_hash))) return NextResponse.redirect(externalUrl(req,"/login?error=invalid")); await createSession({id:user.id,username:user.username,role:user.role}); return NextResponse.redirect(externalUrl(req,"/dashboard")); }
import { NextResponse } from "next/server"; import bcrypt from "bcryptjs"; import { db } from "@/lib/db"; import { createSession } from "@/lib/auth"; import { externalUrl } from "@/lib/http"; import { withinRateLimit } from "@/lib/rate-limit"; import { clientIp, requireSameOrigin } from "@/lib/security";
export async function POST(req: Request) { try { requireSameOrigin(req); if (!withinRateLimit(`login:${clientIp(req)}`, 8, 15 * 60_000)) return NextResponse.redirect(externalUrl(req,"/login?error=rate-limited")); const form = await req.formData(); const username=String(form.get("username")||""); const password=String(form.get("password")||""); const user=db.prepare("SELECT id,username,password_hash,role,disabled FROM users WHERE username=?").get(username) as any;
if (!user || user.disabled || !(await bcrypt.compare(password,user.password_hash))) return NextResponse.redirect(externalUrl(req,"/login?error=invalid")); await createSession({id:user.id,username:user.username,role:user.role}); return NextResponse.redirect(externalUrl(req,"/dashboard")); } catch { return NextResponse.redirect(externalUrl(req,"/login?error=invalid")); } }