Repository navigation
Conversation
Fenrir Realm now gates free chapters behind a Cloudflare Turnstile check and the chapter API returns empty content with content_format "locked" until the reader has a verified session, so the plugin silently returned empty chapters. - When a chapter is locked, mint a read token with the existing (WebView verified) session and refetch it, as the site's own reader does. - Otherwise throw a clear error asking to complete the check in WebView instead of returning an empty chapter, carrying the read-token HTTP status (403 without a session); also throw on non-2xx chapter responses. - Volume chapter slugs now include the volume, so resolveUrl collapses the repeated volume segment; the WebView URL no longer 404s.
…on-blocking API errors
[Medium impact] Adds verification handling for gated chapters in a content plugin. The PR appears safe to merge, with a non-blocking gap in the chapter URL correction. Findings
SummaryUpdates the Fenrir Realm plugin to version
RibatTRW acknowledges that playground screenshots are missing and must still be supplied. Reviews (1) · Last reviewed commit: "no-mistakes(review): fix(english/fenrirr..." · Reviewed by Greptile |
|
|
||
| // Fallback or old method | ||
| const url = `${this.site}/series/${chapterPath.split('~~')[0]}`; | ||
| const url = this.resolveUrl(chapterPath); |
There was a problem hiding this comment.
Chapter fallback keeps wrong URL
The URL correction only reaches the HTML request. For novel/vol1/vol1/1~~123, that request now uses the corrected path. But if the page has no matching paragraphs, jsonUrl still requests the duplicated path and the chapter can return empty. Build jsonUrl from the corrected url so both fallbacks use the same chapter page.
Knowledge Base Used: English source plugins
There was a problem hiding this comment.
Fixed in e0f3c39: the SvelteKit __data.json fallback now builds its URL from this.resolveUrl(chapterPath), so it gets the same duplicated-volume-segment correction as the HTML fallback and both request the same chapter page (e.g. …/vol1/1/__data.json instead of …/vol1/vol1/1/__data.json).
…pter`. On the runner, the series list request came back as a non-2xx block page, and the code replaced it with a generic error that had no status. The live check couldn't classify that, so it reported FAIL. I changed `popularNovels` in `plugins/english/fenrirrealm.ts` so that a non-OK response now throws the same user-facing "open it in WebView" message with `error.status` set to the real HTTP status. A JSON parse failure on a 2xx response still throws the same message with no status, so a genuine parsing problem still reports as a failure. I didn't edit `scripts/live-check-plugin.js` or the workflow. The `parseChapter` paths already carried real statuses. The read-token 403 and the chapter API's 401/403/429/503 responses both set `error.status`. In the earlier run `parseChapter` never ran, because the check stopped at `popularNovels`. Prettier and ESLint pass. A local `node scripts/live-check-plugin.js plugins/english/fenrirrealm.ts` gave PASS for `popularNovels`, `searchNovels` and `parseNovel`, and INCONCLUSIVE for `parseChapter` with HTTP 403. Locally the list request wasn't blocked, so I couldn't reproduce the runner's `popularNovels` failure. I haven't confirmed that the runner's response was a 403 or 503. If it was a different non-2xx status, the check will still report FAIL. I made no version change here; the file is at 1.1.4
…llback The __data.json fallback still built its URL from the raw chapter path, so volume chapters requested novel/vol1/vol1/1. Build it from resolveUrl so it hits the same chapter page as the HTML fallback.
Summary
Fenrir Realm now puts a Cloudflare Turnstile "Confirm you're human to continue reading" check in front of every free chapter. Without a verified session, the chapter API (
/api/new/v2/chapters/{id}) still answers HTTP 200 but withcontent: ""andcontent_format: "locked", so the plugin silently returned an empty chapter (#2672). I sampled the first and last free chapter of 8 popular novels and all werelocked, so this affects every novel, not only the one in the issue. Paid chapters are unaffected (they returncontent_format: "text"with a teaser).The site's reader unlocks a chapter by solving Turnstile and calling
POST /api/read-token, which sets a short-lived (~10 min), chapter-scopedfr_readcookie. With a live session, the same endpoint mints a token for the next chapter without a new challenge; without one it returns 403.A second problem hid this: chapter slugs from the API now include the volume (
vol1/1), so the plugin's chapter paths becamenovel/vol1/vol1/1and the WebView URL was a 404. Users sent to WebView could not reach the page that shows the check.The plugin does not try to solve or bypass Turnstile. The user passes the check once in WebView, and the plugin then uses that session like the site's own reader does.
What Changed
parseChapter: when the API returnscontent_format: "locked", callPOST /api/read-tokenfor the chapter with the existing (WebView-verified) session and refetch the chapter with the minted token. If it is still locked, throw "Fenrir Realm requires a human verification check to read this chapter. Open it in WebView, complete the check, then try again." instead of returning an empty chapter. The error carries the real read-token HTTP status (403 without a session).popularNovels: a non-OK list response now throws the existing "open it in WebView" error with the real HTTP status attached.resolveUrldrops a repeated volume segment (novel/vol1/vol1/1→novel/vol1/1), so "Open in WebView" lands on the real chapter page. Stored chapter paths are unchanged, so existing libraries keep their read progress. The HTML fallback usesresolveUrltoo.__data.jsonfallback also builds its URL fromresolveUrl, so both fallbacks request the same corrected chapter page.Closes #2672
This PR was written with an AI agent (Claude Code); please weight your review accordingly.
Testing
POST /api/read-token200 → content.POST /api/read-token403 → the verify-in-WebView error.npm run check:plugin(local) passedpopularNovels,searchNovelsandparseNovel.parseChapterwas INCONCLUSIVE with HTTP 403, as expected without a verified session. Because the thrown errors carry the site's real HTTP status,scripts/live-check-plugin.jsclassifies the 403 as an anti-bot block through its existing status check. The checker and workflow are not modified. On the GitHub runner the site also answers the series list with 403, which the check now reports as INCONCLUSIVE instead of FAIL.Plugin playground
The issue's chapter with no verified session now shows a clear error instead of an empty chapter:
The same chapter after passing the check in a browser. The playground proxy does not store
Set-Cookie, so I gave it the session cookies as the app's cookie jar holds them after the plugin mints this chapter's read token:Novel details and the chapter list, with Vol 1 Chapter 1 from the issue:
Popular listing:
The corrected WebView URL (
…/vol1/1) opens the real chapter page on the site; before this change it was…/vol1/vol1/1, a 404: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 cinode scripts/live-check-plugin.js plugins/english/fenrirrealm.tsReproduced the path-correction regex used by resolveUrl for the __data.json URL✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.