Repository navigation
Conversation
WTR-LAB now answers every request (pages, _next/data, /api) with a Cloudflare managed challenge (HTTP 403, cf-mitigated: challenge) until it is solved in WebView. The plugin parsed that "Just a moment..." page as site markup, so browse/search threw "Could not find __NEXT_DATA__ on novel finder page", Latest threw a JSON syntax error and parseNovel returned an empty novel, hiding the real remedy. Route the page/data fetches that read __NEXT_DATA__ (and the Latest feed) through a fetchSite helper that throws a WebView hint on 403/503. Once the challenge is cleared, the existing parsing works unchanged.
|
| if (res.status === 403 || res.status === 503) { | ||
| throw new Error( | ||
| `Cloudflare protection detected (HTTP ${res.status}). Please open the plugin in WebView to solve the challenge, then try again.`, |
There was a problem hiding this comment.
fetchSite labels every HTTP 403 or 503 as a Cloudflare challenge. If the server returns a normal access denial or temporary outage, users are told to solve a challenge in WebView, which cannot fix that response. Check cf-mitigated: challenge, as parseChapter already does, before showing the Cloudflare message. Report other failed responses separately.
There was a problem hiding this comment.
Changed in a0bcfa1 (head is now 3f70416):
- Detection now uses one rule: the
cf-mitigated: challengeheader, in a sharedassertNotChallengedcheck. This is the same checkparseChapterused. fetchSiteshows theWebViewerror message only for that marked response. Other failed responses throwRequest failed (HTTP <status>): <url>. Both errors keep the HTTP status.- The other wtr-lab.com requests that already handle a failed response use only the challenge check. These are the tokens page, key scripts, reader API,
content_url, sign-in and session check. Their other failure handling does not change. - Tested on the live site: a novel that does not exist now gives
Request failed (HTTP 404): …, not theWebViewerror message.
(Reply written by an AI agent.)
…lenge fetchSite labelled every 403/503 as a Cloudflare challenge, so a plain origin denial or outage told the user to solve a challenge in WebView. Detect the challenge with one rule, Cloudflare's own `cf-mitigated: challenge` marker, in a shared assertNotChallenged helper, and have fetchSite report any other failed response as a plain error naming the HTTP status and URL. Both errors carry the status. Every remaining fetch to wtr-lab.com now applies the same check: - fetchSite (page or data with nothing to parse on failure): finder, _next/data, Latest, novel page, chapter page fallbacks, chapter list. - challenge check only, keeping their existing failure handling: tokens page (non-fatal), key scripts (falls through to the next script), reader API (per-mode fallback), content_url payload (null fallback), sign-in redeem and session check (status notes). The Google translate call is not a wtr-lab.com request and is unchanged. The LNReader app's fetchApi returns React Native's fetch Response unchanged, so response headers such as cf-mitigated reach the plugin.
Intent
Can we do a plugin PR for https://wtr-lab.com/ - the previous PRs submitted by other users did some, seems to fix the issue, let's do our own fix; the older PRs can be referenced for help.
The problem: when the WTR-LAB plugin is opened in the LNReader app, a log reports "Could not find NEXT_DATA on novel finder page".
https://wtr-lab.com/en - this should be the correct website where all the books are hosted.
Follow-up on the PR: show the WebView hint only when Cloudflare's own marker is in the response, instead of on every 403 or 503 (the recommended option, chosen with: "lets do the recommended").
Summary
When a user opens WTR-LAB, the plugin shows the error message "Could not find NEXT_DATA on novel finder page".
The cause is a Cloudflare challenge page. The plugin reads this page as the novel finder page.
This PR shows a clear error message when Cloudflare sends a challenge. This error message tells the user to open WTR-LAB in
WebView.For other failed responses, the plugin shows a plain HTTP error message.
This PR does not bypass the challenge.
Root cause
wtr-lab.com uses a Cloudflare managed challenge.
In our tests, each request got
HTTP 403with the headercf-mitigated: challenge.The plugin did not examine the response. It read the challenge page as site data.
The site pages did not change. With a browser
cf_clearancecookie, the old code (v1.2.5) loads all pages correctly.Changes
assertNotChallenged, finds thecf-mitigated: challengeheader. Then it shows theWebViewerror message.fetchSiteuses this check. For other failed responses, it showsRequest failed (HTTP <status>): <url>.fetchSite. These are the novel finder, Latest, the novel page, the chapter list and the chapter page.Each request to wtr-lab.com and its check
_next/dataJSONfetchSiteapi/home/recent)fetchSitefetchSiteapi/chapters)fetchSite__NEXT_DATA__fallback, key page)fetchSiteapi/reader/get)content_url)The
translaterequest goes to Google, not to wtr-lab.com. It does not use the check.Testing
WebViewerror message.cf_clearancecookieHTTP 403, andHTTP 403withcf-mitigated: challengeHTTP 403gives the HTTP error message. Only the marked response gives theWebViewerror message. Run by the no-mistakes Test step.cf_clearancecookieRequest failed (HTTP 404): <url>, not theWebViewerror message.cf_clearancecookienpm run check:plugin -- plugins/english/wtrlab.tsHTTP 403. The result on master is the same.npx prettier --check,npm run build:compilewtrlab.tsno-explicit-anywarnings are also on master. Refer to Notes.Notes
parseNovel(from fix(english): resolve debrand tokens for WTR-LAB #2644). These changes are format only. They do not change behavior.no-control-regexerror on the token regex inresolveTokens(from fix(english): resolve debrand tokens for WTR-LAB #2644). This error is also on master. This PR adds oneeslint-disable-next-linecomment above that line. The regex does not change, so behavior does not change.cf-mitigated: challengeheader. The appfetchApireturns the React Nativefetchresponse without changes, so the header is available. We did not test this in the app.An AI agent (Claude Code) wrote this PR and validated it with no-mistakes. No person reviewed or tested it beyond the items in this description.
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
npm cinpm run check:plugin -- plugins/english/wtrlab.ts(stopped at siteReachability: HTTP 403 Cloudflare, INCONCLUSIVE)Bundled the plugin with esbuild and called popularNovels, latest, parseNovel and parseChapter against live https://wtr-lab.comSame plugin pointed at a local HTTP server returning a plain 403 and a 403 with cf-mitigated: challenge✅ **Document** - passed
✅ No issues found.
🔧 **Lint** - 1 issue found → auto-fixed ✅
plugins/english/wtrlab.ts:38- Pre-existing no-control-regex ESLint error at line 38 (control-character range in the macro-token regex). It was not introduced by this change, and fixing it would need a behavior-affecting regex edit.🔧 Fix applied.
✅ Re-checked - no issues remain.
✅ **Push** - passed
✅ No issues found.