From d3e36544ae7bfcf83f8d4244fcc5df8cb1b5c5f7 Mon Sep 17 00:00:00 2001 From: Ishaan Gupta Date: Sat, 9 May 2026 20:44:56 +0530 Subject: [PATCH] fix loose verification --- apps/web/app/(app)/onboarding/page.tsx | 15 ++++-- .../api/onboarding/account-status/route.ts | 50 ++++++++++++++++++- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/apps/web/app/(app)/onboarding/page.tsx b/apps/web/app/(app)/onboarding/page.tsx index 6a1f744a..c214d972 100644 --- a/apps/web/app/(app)/onboarding/page.tsx +++ b/apps/web/app/(app)/onboarding/page.tsx @@ -475,14 +475,10 @@ export default function OnboardingPage() { if (response.ok && data.found === true) { const account = source === "x" && data.handle ? ` @${data.handle}` : "" - const message = - source === "linkedin" && data.verified === false - ? "LinkedIn profile link looks valid - press Enter to continue" - : `${SOURCE_NAME[source]} account${account} found - press Enter to continue` setAccountLookup({ source, status: "found", - message, + message: `${SOURCE_NAME[source]} account${account} found - press Enter to continue`, }) return } @@ -499,6 +495,15 @@ export default function OnboardingPage() { return } + if (response.ok && data.verified === false) { + setAccountLookup({ + source, + status: "error", + message: `Could not verify ${SOURCE_NAME[source]} account. You can still continue.`, + }) + return + } + setAccountLookup({ source, status: "error", diff --git a/apps/web/app/api/onboarding/account-status/route.ts b/apps/web/app/api/onboarding/account-status/route.ts index d2f639a5..3b3eac0c 100644 --- a/apps/web/app/api/onboarding/account-status/route.ts +++ b/apps/web/app/api/onboarding/account-status/route.ts @@ -87,15 +87,57 @@ function looksUnavailable(source: AccountSource, html: string) { function linkedinFallback(account: ParsedAccount, status?: number) { return Response.json({ - found: true, + found: null, verified: false, - reason: "valid_linkedin_profile_url", + reason: "unable_to_verify_linkedin", handle: account.handle, status, url: account.url, }) } +async function verifyXAccount(account: ParsedAccount, signal: AbortSignal) { + const oembedUrl = new URL("https://publish.twitter.com/oembed") + oembedUrl.searchParams.set("url", account.url) + + const response = await fetch(oembedUrl, { + signal, + headers: { + Accept: "application/json", + "User-Agent": + "Mozilla/5.0 (compatible; SuperMemory/1.0; +https://supermemory.ai)", + }, + }) + + if (response.status === 404 || response.status === 410) { + return Response.json({ + found: false, + handle: account.handle, + status: response.status, + url: account.url, + }) + } + + if (!response.ok) { + return Response.json( + { + error: "Unable to verify account", + handle: account.handle, + status: response.status, + url: account.url, + }, + { status: 502 }, + ) + } + + return Response.json({ + found: true, + handle: account.handle, + status: response.status, + url: account.url, + }) +} + export async function GET(request: Request) { const { searchParams } = new URL(request.url) const source = searchParams.get("source") @@ -118,6 +160,10 @@ export async function GET(request: Request) { const timeoutId = setTimeout(() => controller.abort(), 7000) try { + if (source === "x") { + return await verifyXAccount(account, controller.signal) + } + const response = await fetch(account.url, { signal: controller.signal, redirect: "follow",