- Shipped
- November 13, 2026 at 8:16 AM UTC
- Author
- Kamo
- Commit
- b6b8812
The borrower portal marked every typed address verified on sign-up and sent nothing. Typing an address twice proves the spelling, not the mailbox — and owning an account shows its loans, so taking over the account holding an address (now done by **************** kamo-shared-library a6d39dc5) must rest on proof. - /portal/account/register no longer marks the address verified. Once the sign-up commits, a six-digit code goes to it, in the lender's name, with a link back to the lender's portal (https://myloan.<lender domain>/verify-email?t=…) instead of a Kamo register host. - /portal/account/verify {email, code}: the code. Five wrong codes an hour per person (CodeAttemptLimiter) — 429 with retryAfterSeconds after that. - /portal/account/verify/resend {email}: a fresh code; VerificationResendRateLimiter; answers the same whoever holds the address, and never mails an already-proven one. - /portal/account/verify-token {token}: the letter's link. - /portal/account/prepare-signin answers verificationRequired:true (and mails a code) for someone who never proved their address, so the portal asks for the code before signing in. - No Kamo "welcome to the workspace" letter for a portal borrower (EmailVerificationService sendWelcome=false overloads; every existing caller unchanged). - **************** delegates to accountForMember: a proven borrower takes over the unowned account holding their address (e.g. the one the Arive loan sync made); otherwise their own account, as before. Unguarded-endpoint baseline: verify, resend, verifyToken are public by design (no session yet), listed with the reason.
