Skip to content

fix(referrals): reject non-string email entries in invite API (#141) - #166

Merged
ralyodio merged 1 commit into
profullstack:masterfrom
nguyenlnp:fix/referral-non-string-email-141
May 23, 2026
Merged

fix(referrals): reject non-string email entries in invite API (#141)#166
ralyodio merged 1 commit into
profullstack:masterfrom
nguyenlnp:fix/referral-non-string-email-141

Conversation

@nguyenlnp

Copy link
Copy Markdown
Contributor

Fix for #141 — Referral invite API crashes on non-string email entries

Bug

POST /api/referrals validates emails is an array but assumes every entry is a string before calling .trim().toLowerCase(). A request like { "emails": ["friend@test.com", 42] } throws TypeError: e.trim is not a function and falls through to the generic 500 handler.

Root Cause

No type guard on individual array elements. The .map((e: string) => e.trim().toLowerCase()) call crashes when e is not a string.

Fix

Added emails.every((email) => typeof email === "string") guard immediately after the array check, returning a clear 400 error: "All email entries must be strings"

Test Evidence

✓ src/app/api/referrals/route.test.ts (11 tests) 21ms
  - rejects number in email array → 400
  - rejects null in email array → 400
  - rejects object in email array → 400

All 11 tests pass (8 existing + 3 new regression tests).

Bounty

💎 uGig Affiliate Testing Bounty
SOL payment address: 0xadf380b5048e9730af0957fd39d5ef1de374475d
⭐ Starred profullstack/ugig.net ✅

…lstack#141)

POST /api/referrals crashes when emails array contains non-string
entries (e.g. numbers, null, objects) because .trim().toLowerCase()
is called on each entry without type checking.

Changes:
- Add emails.every() guard to reject non-string entries with 400 error
- 3 regression tests: number in array, null, object

Fixes profullstack#141
@greptile-apps

greptile-apps Bot commented May 23, 2026

Copy link
Copy Markdown

Greptile Summary

Adds an element-level type guard to the POST /api/referrals handler so that non-string entries in the emails array are rejected with a clear 400 before .trim().toLowerCase() is called, preventing a TypeError crash. Three targeted regression tests cover the number, null, and object cases.

  • route.ts: Inserts emails.every((email: unknown) => typeof email === \"string\") immediately after the array-existence check and before the length cap, returning { error: \"All email entries must be strings\" } on failure.
  • route.test.ts: Adds three new it blocks that send mixed arrays and assert a 400 response with the exact error message.

Confidence Score: 5/5

Minimal, targeted fix; safe to merge.

The change is a single well-placed guard that closes the crash path without touching any surrounding logic. The new tests directly exercise the added branch, and the rest of the validation pipeline (length cap, spam throttle, format regex) is unaffected.

No files require special attention.

Important Files Changed

Filename Overview
src/app/api/referrals/route.ts Adds a emails.every(typeof === 'string') guard before .trim().toLowerCase() to prevent TypeError on non-string array entries; placement and logic are correct.
src/app/api/referrals/route.test.ts Adds three regression tests covering number, null, and object entries in the emails array — all asserting a 400 with the new error message.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[POST /api/referrals] --> B{Auth check}
    B -- Unauthorized --> C[401 Unauthorized]
    B -- OK --> D{emails is non-empty array?}
    D -- No --> E[400 Please provide an array of emails]
    D -- Yes --> F{All entries are strings?}
    F -- No --> G[400 All email entries must be strings]
    F -- Yes --> H{emails.length > 20?}
    H -- Yes --> I[400 Maximum 20 invites]
    H -- No --> J[Spam throttle checks]
    J -- Exceeded --> K[429 Too many invites]
    J -- OK --> L[Normalize & deduplicate emails]
    L --> M{Any new emails?}
    M -- No --> N[400 All already invited]
    M -- Yes --> O[Validate email format with regex]
    O --> P{Any valid emails?}
    P -- No --> Q[400 No valid email addresses]
    P -- Yes --> R[Insert referral rows & send emails]
    R --> S[200 invite created response]
Loading

Reviews (1): Last reviewed commit: "fix(referrals): reject non-string email ..." | Re-trigger Greptile

@ralyodio
ralyodio merged commit 2d5c21f into profullstack:master May 23, 2026
4 checks passed
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.

2 participants