Harden email verification resend against abuse

Add a per-address confirmation-email cooldown and disable the
resend/forgot-password submit buttons while the mutation is in
flight so callers cannot flood the mail queue or double-submit.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-07-28 10:35:12 +02:00
parent 5d0882778f
commit 82a62005f8
5 changed files with 66 additions and 12 deletions

View File

@@ -319,6 +319,39 @@ WHERE id = @id
return err
}
// ExistsByRecipientSubjectCreatedAfter reports whether an email with the given
// recipient and subject was created at or after createdAfter.
func ExistsByRecipientSubjectCreatedAfter(
ctx context.Context,
conn pg.Querier,
recipientEmail mail.Addr,
subject string,
createdAfter time.Time,
) (bool, error) {
q := `
SELECT EXISTS (
SELECT 1
FROM emails
WHERE recipient_email = @recipient_email
AND subject = @subject
AND created_at >= @created_after
)
`
args := pgx.StrictNamedArgs{
"recipient_email": recipientEmail.String(),
"subject": subject,
"created_after": createdAfter,
}
var exists bool
if err := conn.QueryRow(ctx, q, args).Scan(&exists); err != nil {
return false, fmt.Errorf("cannot check recent email: %w", err)
}
return exists, nil
}
func ResetStaleProcessingEmails(
ctx context.Context,
conn pg.Querier,