Skip to content

fix(notifications): cap pagination offsets#343

Open
Jorel97 wants to merge 3 commits into
profullstack:masterfrom
Jorel97:codex/fix-notifications-offset-cap-342
Open

fix(notifications): cap pagination offsets#343
Jorel97 wants to merge 3 commits into
profullstack:masterfrom
Jorel97:codex/fix-notifications-offset-cap-342

Conversation

@Jorel97
Copy link
Copy Markdown
Contributor

@Jorel97 Jorel97 commented May 30, 2026

Summary

  • add a MAX_NOTIFICATION_OFFSET guard for notification pagination
  • clamp huge offsets before building the Supabase .range() call
  • add regression coverage for malformed, negative, and oversized offsets

Fixes #342.

Verification

  • Not run locally: this workspace can read the repo, but node.exe returns access denied and npm/pnpm are not available in PATH.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR guards the notifications pagination endpoint against offset abuse by clamping any parsed offset to [0, MAX_NOTIFICATION_OFFSET] (100,000) before it reaches the Supabase .range() call, and adds a new test file with regression coverage.

  • route.ts: introduces MAX_NOTIFICATION_OFFSET = 100_000 and wraps the existing Math.max(parsedOffset, 0) floor with Math.min(..., MAX_NOTIFICATION_OFFSET) — a one-line surgical change with no behavioural side effects for normal offsets.
  • route.test.ts: new test file with four cases (unauthenticated, malformed offset, negative offset, oversized offset); the mock chain now includes a third mockReturnValueOnce to cover the fire-and-forget from("profiles") update, which addresses the previously flagged gap.

Confidence Score: 5/5

Safe to merge — the change is a small, well-tested guard with no side effects on normal offset values.

The route change is a single-expression clamp that only affects offsets above 100,000; all existing behaviour for valid inputs is unchanged. The new test file correctly mocks all three Supabase calls (including the previously missing profiles update), and the three regression cases verify the exact boundary values produced by the clamping logic.

No files require special attention.

Important Files Changed

Filename Overview
src/app/api/notifications/route.ts Adds MAX_NOTIFICATION_OFFSET constant (100,000) and clamps parsed offset with Math.min/Math.max before building the Supabase .range() call; no other logic changed.
src/app/api/notifications/route.test.ts New test file covering 401 on unauthenticated access, malformed offsets, negative offsets, and oversized offsets; mock chain correctly models all three supabase.from() calls including the fire-and-forget profiles update.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[GET /api/notifications] --> B{auth?}
    B -- no --> C[401 Unauthorized]
    B -- yes --> D[fire-and-forget: update profiles last_active_at]
    D --> E[parse limit and offset from query params]
    E --> F{Number.isFinite parsedOffset?}
    F -- no --> G[offset = 0]
    F -- yes --> H[offset = clamp to 0..MAX_NOTIFICATION_OFFSET]
    G --> I[build Supabase query with range]
    H --> I
    I --> J{unreadOnly?}
    J -- yes --> K[add is read_at null filter]
    J -- no --> L[execute query]
    K --> L
    L --> M{error?}
    M -- yes --> N[400 Bad Request]
    M -- no --> O[fetch unread count]
    O --> P[200 JSON response]
Loading

Reviews (2): Last reviewed commit: "test(notifications): mock last-active up..." | Re-trigger Greptile

Comment thread src/app/api/notifications/route.test.ts
@Jorel97
Copy link
Copy Markdown
Contributor Author

Jorel97 commented May 30, 2026

Addressed the Greptile test-harness note in the latest commit.

The notification route does a fire-and-forget profiles.update(...).eq(...).then(...) before the notification query, so the test mock now provides that first Supabase chain before the notifications and unread-count chains. The route fix itself is unchanged.

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.

Cap huge notification offsets before querying Supabase

1 participant