Public: anyone can read this; the crew can change it.
A test pins resending the email-verification link: throttled, capped, and honest when already verified #7040
Check · Review · Land · Live done — Landed and live in production.
`POST /settings/email/verify` now has a test, `test/settings-email-verify.test.ts`, and the test found one bug, which this pull also fixes. The new test and `bun x tsc --noEmit` pass here. I did not run the rest of the suite; the forge's check does that on push.
shipped production is serving it deploy 2fa0c24
POST /settings/email/verify now has a test, test/settings-email-verify.test.ts, and the test found one bug, which this pull also fixes. The new test and bun x tsc --noEmit pass here. I did not run the rest of the suite; the forge's check does that on push.
The fix. A signed-out press used to redirect to /settings with the flash "The link could not be sent. Try again." resendVerifyLink in src/web/pages/account.ts was the only handler in that file that skipped the signInFirst(ctx) guard its siblings use. It now has the guard, so a signed-out press redirects to /signin?next=….
What the test covers. Each case posts an empty urlencoded form the way the page does, with the forge_session cookie and a same-origin Origin header.
- Unverified: an unverified person gets "A new link is on its way." and one mail goes out. A second press at once gets the
too_soonmessage, and no second mail is sent. - Verified: a verified person gets "Your email is already verified." and no mail is sent.
- No mail set up: a second app with no mailer answers "This forge sends no mail yet. Ask its owner to verify you."
- Refused: a signed-out press goes to sign-in and no mail is sent. A cross-origin post gets 403 and no mail is sent.
Left out. The capped and failed messages have no case, because the issue didn't ask for them.
I did not run scripts/design-lint.ts, because nothing under src/web/ that renders changed.
Approved. The guard matches its sibling handlers, and the preview shows it: a signed-out POST to /settings/email/verify with a same-origin Origin answers 303 to /signin?next=%2Fsettings%2Femail%2Fverify. The test would fail without the fix, because the old flash would be set, and it also covers unverified, throttled, already-verified, no-mailer and cross-origin. No src/web markup changed, so the design system is untouched.
Two things I would do next:
- Make the sign-in
nextfor a POST-only path land somewhere that renders (/settings). After sign-in,next=/settings/email/verifybecomes a GET on a POST-only route. - Add
cappedandfailedcases so every message in resendVerifyLink is pinned.
POST /settings/email/verifynow has a test,test/settings-email-verify.test.ts, and the test found one bug, which this pull also fixes. The new test andbun x tsc --noEmitpass here. I did not run the rest of the suite; the forge's check does that on push.The fix. A signed-out press used to redirect to
/settingswith the flash "The link could not be sent. Try again."resendVerifyLinkinsrc/web/pages/account.tswas the only handler in that file that skipped thesignInFirst(ctx)guard its siblings use. It now has the guard, so a signed-out press redirects to/signin?next=….What the test covers. Each case posts an empty urlencoded form the way the page does, with the
forge_sessioncookie and a same-originOriginheader.too_soonmessage, and no second mail is sent.Left out. The
cappedandfailedmessages have no case, because the issue didn't ask for them.I did not run
scripts/design-lint.ts, because nothing undersrc/web/that renders changed.Closes #7025