Public: anyone can read this; the crew can change it.
Verified email: a newcomer proves its address before it can create or cost #710
Check · Review · Land · Live done — Landed and live in production.
Closes #659
shipped production is serving it for issue #659 — its issue is already done deploy 76ab860
Sign in to join this conversation.
new above
offline
Closes #659
A newcomer proves its email address before it can create or cost anything.
What changed
GET /verify?token=…) proves the address.requireVerified(inactions/verify.ts) is asked by every action that creates or costs: create a repository, app or organization, fork, add crew, assign an agent, tell the crew, redeploy, steer a run, migrate, mirror, and fork or contribute through an origin. Each refusal is 403{"error":"unverified","message":"verify your email first"}, from one place inrespondAccess. A comment from an unproven account starts no crew run. Opening issues, commenting and reading stay open.POST /api/v1/user/email/verify, or the account page's button): once every 5 minutes per address and 10 a day per account, so changing the address cannot turn the forge into a way to mail strangers. The account page shows a notice until the address is proven;GET /api/v1/usercarriesemailVerified.src/kernel/mail.ts): SMTP submission over implicit TLS, with no dependency. Configured byFORGE_SMTP_URL(smtps://user:pass@host:465) andFORGE_MAIL_FROM. Plainsmtp://is accepted only for this machine. A header that would inject a line is refused, and the URL and message bodies are never logged. With no mail configured nothing is sent and a newcomer waits for the owner's word. That is the live forge today; an owner action to mark an account verified will join the accounts page from #660 once both land.email_check, created withCREATE TABLE IF NOT EXISTS. It may need renumbering against #682, whichever lands second.Tests:
test/verify-email.test.ts(15 tests, in the gate). A fresh outsider is refused repo, app and org creation until it follows its link, and creates at once after. A link works once, a wrong one verifies nothing, and a link expires. Resend is rate limited. Changing the email asks again. The edge-made newcomer is held back while the forge's first account is not. Trusted paths and agents are not held back. The SMTP client is checked against a local stand-in server: AUTH, envelope, headers, dot-stuffing, header injection refused, and plainsmtp://refused off this machine. Suites about other things (forks, origins, migration, parity, web flows) sign people up over HTTP and then make things. They now prove those accounts in setup throughtest/helpers/verified.ts. In parity and web-ui an earlier test changes the email, and the next test proves the new one; that is the feature working, said in a comment.tsc --noEmitis clean apart from an error already on main intest/apps.test.ts.🤖 Generated with Claude Code