86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
|
|
import { NextResponse } from "next/server";
|
|||
|
|
import { getActiveAccountProfile } from "@/lib/account-context";
|
|||
|
|
import { assertAccountOwnedByUser } from "@/lib/auth/accounts";
|
|||
|
|
import { authErrorResponse } from "@/lib/auth/api";
|
|||
|
|
import { requireSessionUser } from "@/lib/auth/session";
|
|||
|
|
import {
|
|||
|
|
normalizeStorageStateInput,
|
|||
|
|
type PlaywrightStorageState,
|
|||
|
|
} from "@/lib/threads-browser/storage-state";
|
|||
|
|
import { probeSession, saveAccountSession } from "@/lib/threads-browser";
|
|||
|
|
|
|||
|
|
export const maxDuration = 120;
|
|||
|
|
|
|||
|
|
export async function POST(request: Request) {
|
|||
|
|
try {
|
|||
|
|
const user = await requireSessionUser();
|
|||
|
|
|
|||
|
|
const body = (await request.json()) as {
|
|||
|
|
storageState?: string | PlaywrightStorageState;
|
|||
|
|
accountId?: string;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!body.storageState) {
|
|||
|
|
return NextResponse.json({ error: "缺少 storageState" }, { status: 400 });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const normalized = normalizeStorageStateInput(body.storageState);
|
|||
|
|
if (!normalized.ok) {
|
|||
|
|
return NextResponse.json({ error: normalized.error }, { status: 400 });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const account = body.accountId
|
|||
|
|
? await assertAccountOwnedByUser(user.id, body.accountId)
|
|||
|
|
: await getActiveAccountProfile();
|
|||
|
|
if (!account) {
|
|||
|
|
return NextResponse.json(
|
|||
|
|
{ error: "請先在側欄選擇或建立經營帳號,再匯入 session" },
|
|||
|
|
{ status: 400 }
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await saveAccountSession(account.id, normalized.storageState, { valid: true });
|
|||
|
|
|
|||
|
|
return NextResponse.json({
|
|||
|
|
success: true,
|
|||
|
|
valid: true,
|
|||
|
|
synced: true,
|
|||
|
|
username: account.username,
|
|||
|
|
message: account.username
|
|||
|
|
? `Session 已同步:@${account.username}`
|
|||
|
|
: "Session 已同步到 server",
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
const authRes = authErrorResponse(error);
|
|||
|
|
if (authRes) return authRes;
|
|||
|
|
const message = error instanceof Error ? error.message : "匯入 session 失敗";
|
|||
|
|
return NextResponse.json({ success: false, valid: false, message }, { status: 500 });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 不啟動瀏覽器,僅檢查 JSON 格式(供 UI 預覽用)。 */
|
|||
|
|
export async function PUT(request: Request) {
|
|||
|
|
try {
|
|||
|
|
await requireSessionUser();
|
|||
|
|
const body = (await request.json()) as {
|
|||
|
|
storageState?: string | PlaywrightStorageState;
|
|||
|
|
};
|
|||
|
|
if (!body.storageState) {
|
|||
|
|
return NextResponse.json({ error: "缺少 storageState" }, { status: 400 });
|
|||
|
|
}
|
|||
|
|
const normalized = normalizeStorageStateInput(body.storageState);
|
|||
|
|
if (!normalized.ok) {
|
|||
|
|
return NextResponse.json({ valid: false, message: normalized.error }, { status: 400 });
|
|||
|
|
}
|
|||
|
|
const valid = await probeSession(normalized.storageState);
|
|||
|
|
return NextResponse.json({
|
|||
|
|
valid,
|
|||
|
|
message: valid ? "格式正確,Threads session 有效" : "格式正確,但 Threads session 已失效",
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
const authRes = authErrorResponse(error);
|
|||
|
|
if (authRes) return authRes;
|
|||
|
|
const message = error instanceof Error ? error.message : "驗證失敗";
|
|||
|
|
return NextResponse.json({ valid: false, message }, { status: 500 });
|
|||
|
|
}
|
|||
|
|
}
|