Skip to content

fix(facebook/search): preserve query identity + drop redirect shims (#2090) - #2194

Merged
jackwener merged 2 commits into
jackwener:mainfrom
LeoLin990405:fix/facebook-search-query-identity
Jul 29, 2026
Merged

fix(facebook/search): preserve query identity + drop redirect shims (#2090)#2194
jackwener merged 2 commits into
jackwener:mainfrom
LeoLin990405:fix/facebook-search-query-identity

Conversation

@LeoLin990405

Copy link
Copy Markdown
Contributor

Follow-up to the merged #2126 facebook-search rewrite. Two residual defects, both confirmed by offline JSDOM reproduction against the current code:

1. Query-identity collision (correctness bug)

The extractor deduped and reported result URLs as origin + pathname, dropping the query string. For query-identity destinations — permalink.php?story_fbid=…, story.php?…, watch/?v=… — the query is the identity, so two different posts/videos collapse into one row and only the first survives dedup:

permalink.php?story_fbid=1001  ┐
permalink.php?story_fbid=2002  ┴─►  1 row  (https://www.facebook.com/permalink.php)

Fix: entityKey(u) keeps only the identity params (story_fbid, fbid, id, v, story_id) and strips FB's per-render tracking nonces (__cft__, __tn__, ref). Distinct posts stay distinct; the same post rendered twice with different nonces still dedupes to one row. Vanity paths without identity params keep collapsing to the bare pathname (existing dedup test unchanged).

2. Outbound-redirect shim leak

l.facebook.com / lm.facebook.com /l.php?u=… wrappers passed the host regex (^|\.)facebook\.com$ and the vanity path catch-all, so external-link redirects showed up as "search results." Added a host guard rejecting the l. / lm. shims (m.facebook.com is intentionally not matched).

Tests

buildSearchExtractScript is exercised via JSDOM (same harness as the existing tests). Added regression tests for distinct permalink/watch identities, nonce dedup, and the redirect-shim guard.

npx vitest run clis/facebook/search.test.js   # 11 passed
npm run typecheck                              # clean
npm run check:typed-error-lint                 # new=0
npm run check:silent-column-drop               # new=0

This supersedes my earlier #2132 (which predated #2126 and overlapped its role=feed rewrite) — closing that in favor of this focused delta.

LeoLin990405 and others added 2 commits July 29, 2026 19:46
…ackwener#2090)

The jackwener#2126 extractor deduped and reported result URLs as `origin + pathname`,
dropping the query string. But `permalink.php?story_fbid=…`, `story.php?…` and
`watch/?v=…` carry their identity in the query — so two *different* posts or
videos collapsed into a single row and only the first survived dedup.

Add `entityKey(u)` that keeps only the identity params (story_fbid, fbid, id, v,
story_id) and strips FB's per-render tracking nonces (__cft__, __tn__, ref).
Distinct posts now stay distinct, while the same post rendered twice with
different nonces still dedupes to one row. Vanity paths without identity params
keep collapsing to the bare pathname (unchanged).

Also reject `l.` / `lm.` `facebook.com` hosts: their `/l.php?u=…` outbound-link
wrappers passed the host regex and the vanity path catch-all, leaking external
redirect shims into the results.

Adds offline regression tests for distinct permalink/watch identities, nonce
dedup, and the redirect-shim guard.
@jackwener
jackwener force-pushed the fix/facebook-search-query-identity branch from 842e3ce to e22cef0 Compare July 29, 2026 11:46
@jackwener
jackwener merged commit a8dddcb into jackwener:main Jul 29, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants