diff --git a/src/app/api/referrals/route.test.ts b/src/app/api/referrals/route.test.ts index 3af21063..8a8d7426 100644 --- a/src/app/api/referrals/route.test.ts +++ b/src/app/api/referrals/route.test.ts @@ -147,6 +147,20 @@ describe("POST /api/referrals", () => { expect(body.error).toContain("Maximum 20"); }); + it("should return 400 when any invite email is not a string", async () => { + mockGetAuthContext.mockResolvedValue({ + user: { id: "user1" }, + supabase: mockSupabase, + }); + + const res = await POST(makePostRequest({ emails: ["friend@test.com", 42] })); + + expect(res.status).toBe(400); + const body = await res.json(); + expect(body.error).toBe("All invite emails must be strings"); + expect(mockCreateServiceClient).not.toHaveBeenCalled(); + }); + it("should create referrals for valid emails", async () => { mockGetAuthContext.mockResolvedValue({ user: { id: "user1" }, diff --git a/src/app/api/referrals/route.ts b/src/app/api/referrals/route.ts index 50099975..89aaa4b0 100644 --- a/src/app/api/referrals/route.ts +++ b/src/app/api/referrals/route.ts @@ -62,6 +62,13 @@ export async function POST(request: NextRequest) { ); } + if (!emails.every((email) => typeof email === "string")) { + return NextResponse.json( + { error: "All invite emails must be strings" }, + { status: 400 } + ); + } + if (emails.length > 20) { return NextResponse.json( { error: "Maximum 20 invites at a time" },