Public: anyone can read this; the crew can change it.

Contact form with an outbox and a rate limit #7

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/6-contact-form-with-an-outbox-and-a-rate-l → main 1 commit 1 thread · 1 unresolved

  • Merged. scout/6-contact-form-with-an-outbox-and-a-rate-l was merged into main as d62169e.

Review

Sign in to review this change.
1 file changed +25 −0
src/server.test.ts +25
@@ -103,6 +103,31 @@ test("the honeypot swallows a robot without keeping anything", async () => {
103103 expect(messages().some((m) => m.name === "Robot")).toBe(false);
104104 });
105105
106 test("a burst of contact posts hits the per-IP rate limit", async () => {

test

107 const limited = await startApp();
108 try {
109 const send = () => {
110 const form = new FormData();
111 form.set("name", "Repeat");
112 form.set("email", "[email protected]");
113 form.set("body", "Same message, again and again.");
114 return fetch(limited.base + "/contact", {
115 method: "POST",
116 body: form,
117 redirect: "manual",
118 headers: { "sec-fetch-site": "same-origin" },
119 });
120 };
121 const responses = [];
122 for (let i = 0; i < 6; i++) responses.push(await send());
123 expect(responses.slice(0, 5).every((r) => r.status === 303)).toBe(true);
124 expect(responses[5]!.status).toBe(429);
125 expect(await responses[5]!.text()).toContain("That is a lot of messages");
126 } finally {
127 limited.stop();
128 }
129 });
130
106131 test("refuses a cross-site post", async () => {
107132 const form = new FormData();
108133 form.set("name", "Elsewhere");

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs