/** * 修改密码 - 用于 meetup 支付成功后强制修改默认密码 */ import { NextRequest, NextResponse } from "next/server"; import { getPocketBaseConfig } from "@/config/services.config"; import { getAdminToken } from "@/app/lib/pocketbase/admin"; const COOKIE_NAME = "pb_session"; const COOKIE_NEEDS_PW = "meetup_needs_password_change"; function getAuthFromCookie(request: NextRequest): { userId: string; token: string } | null { const cookie = request.cookies.get(COOKIE_NAME)?.value; if (!cookie) return null; try { const payload = JSON.parse(Buffer.from(cookie, "base64url").toString("utf-8")); if (payload?.userId && payload?.token) return { userId: payload.userId, token: payload.token }; return null; } catch { return null; } } export async function POST(request: NextRequest) { try { const body = await request.json().catch(() => ({})); const newPassword = String(body?.newPassword || "").trim(); const passwordConfirm = String(body?.passwordConfirm || "").trim(); if (newPassword.length < 8) { return NextResponse.json({ ok: false, error: "密码至少 8 位" }, { status: 400 }); } if (newPassword !== passwordConfirm) { return NextResponse.json({ ok: false, error: "两次密码不一致" }, { status: 400 }); } const auth = getAuthFromCookie(request); if (!auth) { return NextResponse.json({ ok: false, error: "请先登录" }, { status: 401 }); } const pb = getPocketBaseConfig(); const patchBody = { password: newPassword, passwordConfirm }; let res = await fetch(`${pb.url}/api/collections/users/records/${auth.userId}`, { method: "PATCH", headers: { "Content-Type": "application/json", Authorization: `Bearer ${auth.token}`, }, body: JSON.stringify(patchBody), }); if (!res.ok) { const adminToken = await getAdminToken(); if (adminToken) { res = await fetch(`${pb.url}/api/collections/users/records/${auth.userId}`, { method: "PATCH", headers: { "Content-Type": "application/json", Authorization: `Bearer ${adminToken}`, }, body: JSON.stringify(patchBody), }); } } if (!res.ok) { const err = await res.json().catch(() => ({})); const msg = err?.message || (err?.data && typeof err.data === "object" && Object.values(err.data)[0] && (Object.values(err.data)[0] as { message?: string })?.message) || "修改失败"; return NextResponse.json({ ok: false, error: msg }, { status: 400 }); } const r = NextResponse.json({ ok: true }); r.cookies.set(COOKIE_NEEDS_PW, "", { path: "/", maxAge: 0 }); return r; } catch (e) { console.error("change-password error:", e); return NextResponse.json({ ok: false, error: "操作失败" }, { status: 500 }); } }