package routes import ( "bssapp-backend/utils" "database/sql" "errors" "regexp" "strings" ) var simpleEmailRe = regexp.MustCompile(`^[^\s@]+@[^\s@]+\.[^\s@]+$`) // ensureMkMail makes sure the given email exists in mk_mail. // If it already exists (case-insensitive match), it is re-activated and normalized. // This is intentionally tolerant (no ON CONFLICT) to avoid relying on a specific unique constraint. func ensureMkMail(tx *sql.Tx, email string) error { mail := strings.ToLower(strings.TrimSpace(email)) if mail == "" { return nil } if !simpleEmailRe.MatchString(mail) { // user email field can be free-form; don't hard fail user save because of mk_mail bookkeeping return nil } var id string err := tx.QueryRow(` SELECT m.id::text FROM mk_mail m WHERE LOWER(TRIM(m.email)) = LOWER(TRIM($1)) LIMIT 1 `, mail).Scan(&id) if err != nil && !errors.Is(err, sql.ErrNoRows) { return err } if errors.Is(err, sql.ErrNoRows) { newID := utils.NewUUID() // Keep this insert intentionally minimal because mk_mail schema may vary between environments. // Only rely on columns we already SELECT elsewhere (id/email/display_name/is_active). _, err = tx.Exec(`INSERT INTO mk_mail (id, email, display_name, is_active) VALUES ($1, $2, '', true)`, newID, mail) return err } // Exists: normalize + activate. _, err = tx.Exec(` UPDATE mk_mail SET email = $2, display_name = COALESCE(display_name, ''), is_active = true WHERE id::text = $1 `, id, mail) return err }