diff --git a/auth.go b/auth.go index 0daf866..ec00f15 100644 --- a/auth.go +++ b/auth.go @@ -11,7 +11,6 @@ import ( "log" "math/big" "net/http" - "net/url" "os" "strings" "time" @@ -94,18 +93,10 @@ func (s *Server) handleLoginSubmit(w http.ResponseWriter, r *http.Request) { return } - var identifier string - var method string // "email" or "phone" - if isEmail(raw) { - identifier = strings.ToLower(raw) - method = "email" - } else { - identifier = normalizePhone(raw) - method = "phone" - if identifier == "" { - http.Redirect(w, r, "/login", http.StatusSeeOther) - return - } + identifier := strings.ToLower(raw) + if !isEmail(identifier) { + http.Redirect(w, r, "/login", http.StatusSeeOther) + return } code := generateCode() @@ -116,32 +107,19 @@ func (s *Server) handleLoginSubmit(w http.ResponseWriter, r *http.Request) { ExpiresAt: expiresAt, }) - if method == "email" { - if err := sendVerificationEmail(identifier, code); err != nil { - log.Printf("failed to send verification email to %s: %v", identifier, err) - } - } else { - s.q.CreateSmsConsent(r.Context(), db.CreateSmsConsentParams{ - Phone: identifier, - IpAddress: r.RemoteAddr, - UserAgent: r.UserAgent(), - }) - if err := sendVerificationSMS(identifier, code); err != nil { - log.Printf("failed to send verification SMS to %s: %v", identifier, err) - } + if err := sendVerificationEmail(identifier, code); err != nil { + log.Printf("failed to send verification email to %s: %v", identifier, err) } pageTmpl["login"].ExecuteTemplate(w, "layout", map[string]any{ "Step": "code", "Identifier": identifier, - "Method": method, "AuthEnabled": true, }) } func (s *Server) handleVerifyCode(w http.ResponseWriter, r *http.Request) { identifier := strings.TrimSpace(r.FormValue("identifier")) - method := r.FormValue("method") code := strings.TrimSpace(r.FormValue("code")) vc, err := s.q.GetVerificationCode(r.Context(), db.GetVerificationCodeParams{ @@ -152,7 +130,6 @@ func (s *Server) handleVerifyCode(w http.ResponseWriter, r *http.Request) { pageTmpl["login"].ExecuteTemplate(w, "layout", map[string]any{ "Step": "code", "Identifier": identifier, - "Method": method, "Error": "Invalid or expired code. Try again.", "AuthEnabled": true, }) @@ -163,16 +140,9 @@ func (s *Server) handleVerifyCode(w http.ResponseWriter, r *http.Request) { // Get or create user var user db.User - if method == "email" { - user, err = s.q.GetUserByEmail(r.Context(), sql.NullString{String: identifier, Valid: true}) - if err == sql.ErrNoRows { - user, err = s.q.CreateUserByEmail(r.Context(), sql.NullString{String: identifier, Valid: true}) - } - } else { - user, err = s.q.GetUserByPhone(r.Context(), sql.NullString{String: identifier, Valid: true}) - if err == sql.ErrNoRows { - user, err = s.q.CreateUserByPhone(r.Context(), sql.NullString{String: identifier, Valid: true}) - } + user, err = s.q.GetUserByEmail(r.Context(), sql.NullString{String: identifier, Valid: true}) + if err == sql.ErrNoRows { + user, err = s.q.CreateUserByEmail(r.Context(), sql.NullString{String: identifier, Valid: true}) } if err != nil { log.Printf("user lookup/create: %v", err) @@ -270,58 +240,6 @@ func generateSessionToken() string { return hex.EncodeToString(b) } -// normalizePhone strips non-digit chars and prepends +1 if no country code. -func normalizePhone(raw string) string { - var digits strings.Builder - for _, c := range strings.TrimSpace(raw) { - if c >= '0' && c <= '9' { - digits.WriteRune(c) - } - } - d := digits.String() - if d == "" { - return "" - } - // If 10 digits, assume US and prepend 1 - if len(d) == 10 { - d = "1" + d - } - return "+" + d -} - -func sendVerificationSMS(to, code string) error { - sid := os.Getenv("TWILIO_ACCOUNT_SID") - token := os.Getenv("TWILIO_AUTH_TOKEN") - from := os.Getenv("TWILIO_FROM_NUMBER") - - if sid == "" || token == "" || from == "" { - log.Printf("Twilio not configured — code for %s is: %s", to, code) - return nil - } - - body := fmt.Sprintf("Your bbq login code: %s", code) - apiURL := fmt.Sprintf("https://api.twilio.com/2010-04-01/Accounts/%s/Messages.json", sid) - - data := url.Values{} - data.Set("To", to) - data.Set("From", from) - data.Set("Body", body) - - req, _ := http.NewRequest("POST", apiURL, strings.NewReader(data.Encode())) - req.SetBasicAuth(sid, token) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - if resp.StatusCode >= 400 { - return fmt.Errorf("twilio API returned %d", resp.StatusCode) - } - return nil -} - func sendVerificationEmail(to, code string) error { apiKey := os.Getenv("RESEND_API_KEY") if apiKey == "" { diff --git a/templates/login.html b/templates/login.html index 990cb36..1debbbb 100644 --- a/templates/login.html +++ b/templates/login.html @@ -7,7 +7,7 @@
Account

Log in

- Enter your email or phone number to receive a login code. + Enter your email to receive a login code.

@@ -15,18 +15,14 @@ {{if eq .Step "identify"}}
- - + +
-

- By entering a phone number, you consent to receive a one-time verification code via SMS. Msg & data rates may apply. No marketing messages will be sent. -

{{else}}
-

Code sent to {{.Identifier}}