Skip to content

fix(english): handle Cloudflare-protected chapters in fenrirrealm - #2703

Open
RibatTRW wants to merge 10 commits into
lnreader:masterfrom
RibatTRW:fm/lnreader-fenrir-empty-chapter-2672
Open

RibatTRW wants to merge 10 commits into
lnreader:masterfrom
RibatTRW:fm/lnreader-fenrir-empty-chapter-2672

Conversation

@RibatTRW

@RibatTRW RibatTRW commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fenrir Realm gates free chapters behind a Cloudflare Turnstile check, so chapters such as the one in #2672 came back empty. Upstream #2773 has since landed read-token rotation and chapter decryption. This PR adds only what that change still lacks, on top of current master.

What Changed

  • resolveUrl drops a repeated volume segment (novel/vol1/vol1/1 becomes novel/vol1/1), because chapter slugs from the API now include the volume. The HTML fallback and the SvelteKit __data.json fallback in parseChapter both build their URLs through it, which addresses the Greptile finding on this PR. Stored chapter paths are unchanged, so read progress is kept, and "Open in WebView" now lands on the real chapter page instead of a 404.
  • The "protected by Cloudflare Turnstile" error now carries the real HTTP status only where a non-2xx response was observed (read-token POST or chapter API 401/403/429/503). A 200 response with locked content carries no status. A stale mint refusal is cleared after a successful mint.
  • popularNovels: a non-OK series list response throws the existing "open it in WebView" error with the real HTTP status attached, so the live check reports a block page as INCONCLUSIVE instead of FAIL.
  • Version 1.1.4 to 1.1.5.

Closes #2672

This PR was written with an AI agent (Claude Code); please weight your review accordingly.

Testing

  • Live, against fenrirealm.com: npm run check:plugin -- plugins/english/fenrirrealm.ts passed popularNovels, searchNovels and parseNovel. parseChapter was INCONCLUSIVE with HTTP 403 (anti-bot), as expected without a verified session.
  • Live: resolveUrl checked directly: novel/vol1/vol1/1 gives novel/vol1/1; normal paths are unchanged.
  • Not exercised live (the real site cannot be made to refuse or serve locked content on demand, so these ran only against a mocked fetch): read-token POST and chapter API both 403 keeps the real status; mint succeeds and the API replies 200 with locked content carries no status; chapter API 500 falls back to the HTML page and __data.json with the deduplicated path; chapter API 503, or 403 after a successful mint, keeps that status.
  • Not tested in the LNReader app.

Plugin playground

Novel details and chapter list, including Vol 1 Chapter 1 from the issue:

Plugin playground: Parse Novel for the issue's novel

Plugin playground: chapter list including Vol 1 Chapter 1

Popular listing:

Plugin playground: popular novels

The corrected WebView URL (.../vol1/1) opens the real chapter page; before it was .../vol1/vol1/1, a 404:

Fenrir Realm chapter page opened from the plugin's corrected WebView URL

Pipeline

Updates from git push no-mistakes

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.
@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[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

  1. P2 Chapter fallback keeps wrong URL ▶

Summary

Updates the Fenrir Realm plugin to version 1.1.4.

  • Fenrir Realm can retry verification-gated chapters with a read token.
  • Fenrir Realm chapter pages use a cleaned volume path.

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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@RibatTRW RibatTRW changed the title fix(english): handle verification-gated Fenrir Realm chapters fix(english): handle Cloudflare-gated Fenrir Realm chapters Oct 18, 2026
@RibatTRW RibatTRW changed the title fix(english): handle Cloudflare-gated Fenrir Realm chapters fix(english): handle Cloudflare-protected chapters in fenrirrealm Oct 27, 2026
…ks after base refresh") as instructed, with no file changes. I did not push it or run any checks; the push is for the outer executor, and it should trigger a fresh pull_request run. From the CI log and the earlier diff, the only file this PR changes is plugins/english/fenrirrealm.ts. The log shows it as INCONCLUSIVE (HTTP 403, likely anti-bot block), not FAIL. The FAIL rows are all in plugins this PR doesn't touch: hexnovels, seanovel, novelhi, royalroad, ficbook, zelluloza and topliba.broken. They come from the live sites or runner blocking, so a fresh run on the refreshed file list should only exercise fenrirrealm

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant