Filter moderation-blocked slugs from /api/index#15
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds moderation-aware index filtering and an early title-moderation gate in page generation; introduces configurable article-vote and comment-creation rate limits with IP/subnet normalization, enforcement that throws 429-style errors, handler integration, and adds ipaddr.js. ChangesModeration and page-generation gating
Comment/article vote rate limiting
Sequence DiagramssequenceDiagram
participant Client
participant Worker
participant DB
Client->>Worker: GET /api/index
Worker->>DB: query article_moderation for slugs with banned/pending/checking
DB-->>Worker: moderation rows
Worker->>Client: return filtered items or 503 + items:[]
sequenceDiagram
participant Client
participant Worker
participant Moderation
participant RateLimiter
Client->>Worker: GET /api/page/:slug
Worker->>Worker: resolve client IP
Worker->>Worker: validate OPENROUTER_API_KEY presence
Worker->>Moderation: isTitleModerationApproved(title)
Moderation-->>Worker: approved / rejected
alt approved
Worker->>RateLimiter: check per-IP generation rate
RateLimiter-->>Worker: allowed / throttled
Worker->>Client: generate / return page
else rejected
Worker->>Client: 403 + topicRejectedMessage()
end
Possibly related issues
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/worker/index.ts`:
- Around line 151-153: The catch block currently logs the moderation error and
returns the original items (variable items), which reintroduces blocked content;
instead fail closed: remove "return items" and rethrow the caught error (throw
e) so the caller can surface a 503, or alternatively return a safe
empty/filtered set (e.g., []) and ensure the caller converts that to a 503
response; update the catch in the moderation/filtering code (the catch handling
e) accordingly and keep the console.error message with the error for
diagnostics.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Why this is necessaryWe observed scripted abuse creating offensive/zero-gibberish topics on live. Moving from reactive moderation to pre-generation gating prevents bad topics from reaching KV and cuts off attack surface and cost. What was changed
EvidenceScreenshot reference:
Related issue |
|
Added upvote-abuse protections in this same branch/PR: article and comment vote endpoints now use shared server-side rate limits to reduce upvote gaming (per-user/hour, per-user/minute burst, per-IP/hour, per-subnet/hour). Added helper in with configurable env vars and 429 retry-after responses. Commit: 5a1259a. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/worker/comments.ts`:
- Around line 544-545: The article vote POST handler bypasses the rate limiter;
call enforceArticleVoteRateLimits(c, c.env, user.id) at the start of the
app.post("/api/articles/:slug/vote", ...) handler (before any writes to
article_votes or articles) so the route is protected from burst abuse; also add
the same call in the other missing site around the article vote logic referenced
near the other call sites (the ones touching article_votes/articles) so both
spots invoke enforceArticleVoteRateLimits with the same c, c.env, and user.id
parameters.
- Around line 242-257: The ipToSubnet function currently uses string splitting
which breaks IPv6 compression semantics; replace the manual IPv6 logic in
ipToSubnet with a proper IPv6 parsing/normalization library (for example
ipaddr.js or ip6addr) to parse the input, handle IPv4-mapped IPv6 addresses, and
then produce a canonical /64 prefix for IPv6 and /24 for IPv4 while preserving
the "unknown" return. Locate ipToSubnet and: use the library to parse the IP
string, call its normalization/first-n-bits or subnet function to derive the /64
(for IPv6) or /24 (for IPv4) prefix, and return that canonical prefix string
instead of the current split-join result.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b6ce2387-d28b-4e85-b9d6-69891c552b3a
📒 Files selected for processing (1)
src/worker/comments.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/worker/index.ts`:
- Line 153: The function currently returns items when results is empty, which
skips the earlier permanent-block filtering; change the return to return
safeItems instead of items in the early-exit case (the branch that checks if
(!results || results.length === 0)) so that the isPermanentlyBlockedSlug filter
applied to produce safeItems is always respected; update the return at that
condition to return safeItems (referencing safeItems, items, results, and
isPermanentlyBlockedSlug to locate the code).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b86c643f-0e6a-4238-ad25-aab9d041b474
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
package.jsonsrc/worker/comments.tssrc/worker/index.ts
✅ Files skipped from review due to trivial changes (1)
- package.json
|
@coderabbitai please re-run review for the latest push |
|
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/worker/index.ts`:
- Around line 566-591: The rate limit logic should run before calling the
expensive moderation model to avoid wasting moderation calls; move the rateLimit
call (using rateLimit with kv: c.env.ARTICLES, bucket: "gen", ip, limit parsed
from c.env.GEN_PER_IP_PER_HOUR, windowSec: 3600) and its rl.ok check so it
executes prior to calling isTitleModerationApproved(title, c.env). Keep the same
response behavior when rl.ok is false (return the 429 JSON with retry-after and
x-robots-tag headers) and ensure ip and perHour parsing remain identical when
relocated.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/worker/comments.ts`:
- Around line 557-560: The comment route is incorrectly consuming the article
voting rate limit by calling enforceArticleVoteRateLimits during comment
creation; remove that call and instead implement and call a separate comment
creation limiter (e.g., enforceCommentCreationRateLimits) that reads its own env
knobs from c.env (like COMMENT_CREATION_LIMIT, COMMENT_CREATION_WINDOW) and
accepts the same user.id/context signature; update the try block to call
ensureUser(c, c.env) then await enforceCommentCreationRateLimits(c, c.env,
user.id) so comment publishing is throttled independently of voting.
- Around line 282-345: The current checks array constructs all rateLimit calls
up-front (result: rateLimit(...)), starting concurrent mutations that can
consume shared IP/subnet buckets even after an earlier check fails; change the
implementation so rateLimit is invoked lazily and sequentially: instead of
storing result: rateLimit(...) in each object, store a function (e.g., run: ()
=> rateLimit(...)) or move the rateLimit(...) calls into the for-loop and await
each call one-by-one, then preserve the existing error construction (err.status
= 429, err.retryAfter = result.retryAfter) when a check fails; update references
to check.result to call/await the function (e.g., const result = await
check.run()) and keep scope, parsePositiveInt and ARTICLE_VOTE_DEFAULTS usage
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 02b5c569-a038-4fdf-932d-35033cbd0b01
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
package.jsonsrc/worker/comments.tssrc/worker/index.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/worker/comments.ts`:
- Around line 617-619: Move the per-IP comment creation throttling call to run
after user identity resolution: call ensureUser(c, c.env) first to perform
identity-based rate checks and only then invoke
enforceCommentCreationRateLimits(c, c.env). In other words, swap the two calls
so ensureUser executes before enforceCommentCreationRateLimits (so identity
rejections don't consume the shared comment-create quota), keeping the same
error handling and awaits around both functions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a2100802-3c32-429f-ad60-bed2d876771a
📒 Files selected for processing (4)
README.mdsrc/worker/comments.tssrc/worker/index.tswrangler.toml
✅ Files skipped from review due to trivial changes (1)
- README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- src/worker/index.ts
|
Tried to run it locally but encountered such error: |
|
Huh. Nice. Okay, I'll take a look. |
…eration # Conflicts: # src/worker/comments.ts # src/worker/index.ts
What this PR fixes
Closes a content-safety gap in the public index endpoint.
Summary
GET /api/index.article_moderationand any slug with statuspending,checking, orbannedis excluded from responses.totalis reconciled when the first page contains the entire dataset so it reflects the filtered set instead of stale or pre-moderation counts.Validation notes
Related issues
Summary by CodeRabbit
Bug Fixes
New Features
Chores
Documentation