Serialize email verification and resend to preserve registration state
This commit is contained in:
@@ -112,6 +112,9 @@ func (s *service) registerEmail(w http.ResponseWriter, r *http.Request, project,
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
if _, err = tx.ExecContext(r.Context(), "SELECT pg_advisory_xact_lock(hashtextextended($1,0))", "email:"+project+":"+email); err != nil {
|
||||
return err
|
||||
}
|
||||
verification := token()
|
||||
result, err := tx.ExecContext(r.Context(), `
|
||||
INSERT INTO email_registrations(project,email,password_hash,token_hash,expires_at)
|
||||
@@ -167,6 +170,16 @@ func (s *service) verifyEmail(w http.ResponseWriter, r *http.Request, project st
|
||||
}
|
||||
defer tx.Rollback()
|
||||
var email, hash string
|
||||
err = tx.QueryRowContext(r.Context(), "SELECT email FROM email_registrations WHERE project=$1 AND token_hash=$2 AND expires_at>now()", project, digest(input.Token)).Scan(&email)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return reject(w, 400, "invalid_verification")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = tx.ExecContext(r.Context(), "SELECT pg_advisory_xact_lock(hashtextextended($1,0))", "email:"+project+":"+email); err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.QueryRowContext(r.Context(), `
|
||||
DELETE FROM email_registrations WHERE project=$1 AND token_hash=$2 AND expires_at>now() RETURNING email,password_hash
|
||||
`, project, digest(input.Token)).Scan(&email, &hash)
|
||||
|
||||
Reference in New Issue
Block a user