Files
page-builder/src/app/api/auth/me/route.ts
T
jaybe 87cdc1868b
CI / test (push) Failing after 13m23s
CI / e2e (push) Has been cancelled
CI / pr_and_merge (push) Has been cancelled
마이페이지, 리포트, 메일인증
2025-12-15 21:59:43 +09:00

57 lines
1.9 KiB
TypeScript

import { NextResponse } from "next/server";
import { PrismaClient } from "@prisma/client";
import { verifyAccessToken } from "@/features/auth/authCrypto";
// /api/auth/me
// - 요청 쿠키에 포함된 JWT(pb_access)를 검증하고,
// - 유효한 경우 JWT 의 sub(id) 를 기준으로 실제 DB(User) 에서 최신 유저 정보를 조회해 반환한다.
// - 이렇게 하면 emailVerified 와 같은 필드가 브라우저/세션에 관계없이 항상 DB 기준으로 일관되게 반영된다.
const prisma = new PrismaClient();
function extractTokenFromCookieHeader(cookieHeader: string | null): string | null {
if (!cookieHeader) return null;
const parts = cookieHeader.split(";");
for (const part of parts) {
const trimmed = part.trim();
if (trimmed.startsWith("pb_access=")) {
const value = trimmed.substring("pb_access=".length);
return decodeURIComponent(value);
}
}
return null;
}
export async function GET(request: Request) {
const cookieHeader = request.headers.get("cookie");
const token = extractTokenFromCookieHeader(cookieHeader);
if (!token) {
return NextResponse.json({ message: "인증 정보가 없습니다." }, { status: 401 });
}
const payload = await verifyAccessToken(token);
if (!payload) {
return NextResponse.json({ message: "유효하지 않은 토큰입니다." }, { status: 401 });
}
// JWT 에서 식별한 ID 를 기준으로 실제 User 를 조회해 최신 정보를 사용한다.
const dbUser = await prisma.user.findUnique({ where: { id: payload.sub } });
if (!dbUser) {
return NextResponse.json({ message: "사용자를 찾을 수 없습니다." }, { status: 401 });
}
const user = {
id: dbUser.id,
email: dbUser.email,
tokenVersion: (dbUser as any).tokenVersion,
emailVerified: (dbUser as any).emailVerified ?? false,
};
return NextResponse.json(user, { status: 200 });
}