UpdateUser updates mutable user fields.
(id string, input models.UserUpdate)
| 160 | |
| 161 | // UpdateUser updates mutable user fields. |
| 162 | func (s *Store) UpdateUser(id string, input models.UserUpdate) (*models.User, error) { |
| 163 | var sets []string |
| 164 | var args []interface{} |
| 165 | |
| 166 | if input.Name != nil { |
| 167 | sets = append(sets, "name = ?") |
| 168 | args = append(args, strings.TrimSpace(*input.Name)) |
| 169 | } |
| 170 | if input.Username != nil { |
| 171 | sets = append(sets, "username = ?") |
| 172 | args = append(args, strings.TrimSpace(*input.Username)) |
| 173 | } |
| 174 | if input.Password != nil { |
| 175 | hash, err := bcrypt.GenerateFromPassword([]byte(*input.Password), bcryptCost) |
| 176 | if err != nil { |
| 177 | return nil, fmt.Errorf("hash password: %w", err) |
| 178 | } |
| 179 | sets = append(sets, "password_hash = ?") |
| 180 | args = append(args, string(hash)) |
| 181 | // Explicit password change — mark the user as having a usable password |
| 182 | // (clears the OAuth placeholder-hash state set by CreateOAuthUser). |
| 183 | sets = append(sets, "password_set = ?") |
| 184 | args = append(args, true) |
| 185 | } |
| 186 | if input.AvatarURL != nil { |
| 187 | sets = append(sets, "avatar_url = ?") |
| 188 | args = append(args, *input.AvatarURL) |
| 189 | } |
| 190 | |
| 191 | if len(sets) == 0 { |
| 192 | return s.GetUser(id) |
| 193 | } |
| 194 | |
| 195 | sets = append(sets, "updated_at = ?") |
| 196 | args = append(args, now()) |
| 197 | args = append(args, id) |
| 198 | |
| 199 | query := fmt.Sprintf("UPDATE users SET %s WHERE id = ?", strings.Join(sets, ", ")) |
| 200 | result, err := s.db.Exec(s.q(query), args...) |
| 201 | if err != nil { |
| 202 | return nil, fmt.Errorf("update user: %w", err) |
| 203 | } |
| 204 | n, _ := result.RowsAffected() |
| 205 | if n == 0 { |
| 206 | return nil, sql.ErrNoRows |
| 207 | } |
| 208 | |
| 209 | return s.GetUser(id) |
| 210 | } |
| 211 | |
| 212 | // ValidatePassword checks an email/password combination. Returns the user |
| 213 | // if valid, nil if the credentials are wrong (not an error). |