Files
2026-03-13 06:16:36 -05:00

116 lines
3.5 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { getApiUrlFromRequest, getPaymentConfig } from "@/config/services.config";
import {
findAnonymousUserIdForUser,
findLinkedMemberFromOrder,
findVipEmailLinkByAnonymousUserId,
findVipEmailLinkByUserId,
getAdminToken,
isAnonymousUserId,
upsertVipEmailLink,
} from "@/app/api/vip/_helpers";
function resolvePayApiUrl(request: NextRequest): string {
const payConfig = getPaymentConfig();
const hostHeader = request.headers.get("host") || request.headers.get("x-forwarded-host");
return (
(hostHeader ? getApiUrlFromRequest(hostHeader) : null) ||
payConfig.apiUrl
).replace(/\/$/, "");
}
async function getLinkedEmailFromPayjsapi(
request: NextRequest,
userId: string
): Promise<string | null> {
try {
const apiUrl = resolvePayApiUrl(request);
const res = await fetch(
`${apiUrl}/nomadvip/check_vip?user_id=${encodeURIComponent(userId)}`,
{ cache: "no-store", signal: AbortSignal.timeout(5000) }
);
if (!res.ok) {
return null;
}
const data = await res.json().catch(() => ({}));
const email =
typeof data?.email === "string" ? data.email.trim().toLowerCase() : "";
return data?.vip && email ? email : null;
} catch {
return null;
}
}
export async function GET(request: NextRequest) {
const userId = request.nextUrl.searchParams.get("user_id")?.trim() || "";
if (!userId) {
return NextResponse.json(
{ email: null, error: "缺少 user_id" },
{ status: 400 }
);
}
try {
const adminToken = await getAdminToken();
if (!adminToken) {
return NextResponse.json({ email: null }, { status: 500 });
}
const linkRecord = isAnonymousUserId(userId)
? await findVipEmailLinkByAnonymousUserId(adminToken, userId)
: await findVipEmailLinkByUserId(adminToken, userId);
const linkedEmail =
typeof linkRecord?.email === "string"
? linkRecord.email.trim().toLowerCase()
: "";
const anonymousUserId =
typeof linkRecord?.anonymous_user_id === "string" &&
isAnonymousUserId(linkRecord.anonymous_user_id.trim())
? linkRecord.anonymous_user_id.trim()
: !isAnonymousUserId(userId)
? await findAnonymousUserIdForUser(adminToken, userId)
: isAnonymousUserId(userId)
? userId
: null;
if (linkedEmail) {
return NextResponse.json({
email: linkedEmail,
anonymousUserId,
});
}
if (isAnonymousUserId(userId)) {
const linkedMember = await findLinkedMemberFromOrder(adminToken, userId);
if (linkedMember) {
await upsertVipEmailLink(
adminToken,
linkedMember.email,
linkedMember.userId,
userId
);
return NextResponse.json({
email: linkedMember.email,
anonymousUserId: userId,
});
}
}
const payjsEmail = await getLinkedEmailFromPayjsapi(request, userId);
if (payjsEmail) {
if (anonymousUserId && !isAnonymousUserId(userId)) {
await upsertVipEmailLink(adminToken, payjsEmail, userId, anonymousUserId);
}
return NextResponse.json({
email: payjsEmail,
anonymousUserId: anonymousUserId ?? (isAnonymousUserId(userId) ? userId : null),
});
}
return NextResponse.json({ email: null, anonymousUserId: anonymousUserId ?? null });
} catch (error) {
console.error("[linked-email] failed:", error);
return NextResponse.json({ email: null, anonymousUserId: null }, { status: 500 });
}
}