's'
This commit is contained in:
@@ -32,6 +32,9 @@ type RecoveryResult = {
|
||||
source?: string;
|
||||
};
|
||||
|
||||
const PAYJS_CHECK_BY_EMAIL_TIMEOUT =
|
||||
Number(process.env.PAYJSAPI_CHECK_BY_EMAIL_TIMEOUT) || 5000;
|
||||
|
||||
function resolvePayApiUrl(request: NextRequest): string {
|
||||
const payConfig = getPaymentConfig();
|
||||
const hostHeader = request.headers.get("host") || request.headers.get("x-forwarded-host");
|
||||
@@ -58,7 +61,7 @@ async function checkVipByEmailFromPayjsapi(
|
||||
...(userId ? { user_id: userId } : {}),
|
||||
}),
|
||||
cache: "no-store",
|
||||
signal: AbortSignal.timeout(15000),
|
||||
signal: AbortSignal.timeout(PAYJS_CHECK_BY_EMAIL_TIMEOUT),
|
||||
});
|
||||
if (!res.ok) {
|
||||
return null;
|
||||
@@ -121,10 +124,9 @@ async function resolveRecovery(
|
||||
requestedAnonymousUserId?: string,
|
||||
payjsResult?: PayjsVipEmailResult | null
|
||||
): Promise<RecoveryResult> {
|
||||
if (
|
||||
isAnonymousUserId(requestedAnonymousUserId) &&
|
||||
(await hasVipByUserId(adminToken, requestedAnonymousUserId))
|
||||
) {
|
||||
if (isAnonymousUserId(requestedAnonymousUserId)) {
|
||||
const requestUserHasVip = await hasVipByUserId(adminToken, requestedAnonymousUserId);
|
||||
if (requestUserHasVip) {
|
||||
return {
|
||||
vip: true,
|
||||
matchedUserId: requestedAnonymousUserId,
|
||||
@@ -132,12 +134,16 @@ async function resolveRecovery(
|
||||
source: "request_user_id",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const linkRecord = await findVipEmailLinkByEmail(adminToken, email);
|
||||
const [linkRecord, fallbackAnonymousUserId] = await Promise.all([
|
||||
findVipEmailLinkByEmail(adminToken, email),
|
||||
findAnonymousUserIdForUser(adminToken, pbUserId),
|
||||
]);
|
||||
const linkedAnonymousUserId =
|
||||
typeof linkRecord?.anonymous_user_id === "string"
|
||||
? linkRecord.anonymous_user_id.trim()
|
||||
: (await findAnonymousUserIdForUser(adminToken, pbUserId)) ?? "";
|
||||
: fallbackAnonymousUserId ?? "";
|
||||
const linkedIds = Array.from(
|
||||
new Set(
|
||||
[
|
||||
@@ -148,24 +154,30 @@ async function resolveRecovery(
|
||||
)
|
||||
);
|
||||
|
||||
for (const linkedId of linkedIds) {
|
||||
if (!(await hasVipByUserId(adminToken, linkedId))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (linkedIds.length) {
|
||||
const linkedVipChecks = await Promise.all(
|
||||
linkedIds.map(async (linkedId) => ({
|
||||
linkedId,
|
||||
vip: await hasVipByUserId(adminToken, linkedId),
|
||||
}))
|
||||
);
|
||||
const hit = linkedVipChecks.find((item) => item.vip);
|
||||
if (hit) {
|
||||
return {
|
||||
vip: true,
|
||||
matchedUserId: linkedId,
|
||||
matchedUserId: hit.linkedId,
|
||||
anonymousUserId: isAnonymousUserId(linkedAnonymousUserId)
|
||||
? linkedAnonymousUserId
|
||||
: isAnonymousUserId(linkedId)
|
||||
? linkedId
|
||||
: isAnonymousUserId(hit.linkedId)
|
||||
? hit.linkedId
|
||||
: undefined,
|
||||
source: "vip_email_link",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (await hasVipByUserId(adminToken, pbUserId)) {
|
||||
const pbUserHasVip = await hasVipByUserId(adminToken, pbUserId);
|
||||
if (pbUserHasVip) {
|
||||
return {
|
||||
vip: true,
|
||||
matchedUserId: pbUserId,
|
||||
@@ -186,16 +198,20 @@ async function resolveRecovery(
|
||||
)
|
||||
);
|
||||
|
||||
for (const candidate of payjsCandidates) {
|
||||
if (!(await hasVipByUserId(adminToken, candidate))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (payjsCandidates.length) {
|
||||
const payjsVipChecks = await Promise.all(
|
||||
payjsCandidates.map(async (candidate) => ({
|
||||
candidate,
|
||||
vip: await hasVipByUserId(adminToken, candidate),
|
||||
}))
|
||||
);
|
||||
const hit = payjsVipChecks.find((item) => item.vip);
|
||||
if (hit) {
|
||||
return {
|
||||
vip: true,
|
||||
matchedUserId: candidate,
|
||||
anonymousUserId: isAnonymousUserId(candidate)
|
||||
? candidate
|
||||
matchedUserId: hit.candidate,
|
||||
anonymousUserId: isAnonymousUserId(hit.candidate)
|
||||
? hit.candidate
|
||||
: typeof payjsResult?.anonymousUserId === "string" &&
|
||||
isAnonymousUserId(payjsResult.anonymousUserId.trim())
|
||||
? payjsResult.anonymousUserId.trim()
|
||||
@@ -203,6 +219,7 @@ async function resolveRecovery(
|
||||
source: "payjsapi",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { vip: false };
|
||||
}
|
||||
@@ -229,8 +246,10 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
|
||||
try {
|
||||
const authData = await loginPocketBaseUser(email, password);
|
||||
const adminToken = await getAdminToken();
|
||||
const [authData, adminToken] = await Promise.all([
|
||||
loginPocketBaseUser(email, password),
|
||||
getAdminToken(),
|
||||
]);
|
||||
if (!adminToken) {
|
||||
return NextResponse.json(
|
||||
{ ok: false, vip: false, error: "PocketBase 管理员认证失败" },
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
:root,
|
||||
.light {
|
||||
--font-geist-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji";
|
||||
--font-geist-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace;
|
||||
--background: #fafafa;
|
||||
--foreground: #171717;
|
||||
--card: #ffffff;
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import type { Metadata } from "next";
|
||||
import { GeistSans } from "geist/font/sans";
|
||||
import { GeistMono } from "geist/font/mono";
|
||||
import "./globals.css";
|
||||
import { ThemeProvider } from "./providers/ThemeProvider";
|
||||
import { themeInitScript } from "./theme-init";
|
||||
|
||||
const geistSans = GeistSans;
|
||||
const geistMono = GeistMono;
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "异度星球",
|
||||
description: "数字游民社群",
|
||||
@@ -20,9 +15,7 @@ export default function RootLayout({
|
||||
}>) {
|
||||
return (
|
||||
<html lang="zh-CN" suppressHydrationWarning>
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<body className="antialiased">
|
||||
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
|
||||
<ThemeProvider>{children}</ThemeProvider>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user