3 files changed,
56 insertions(+),
15 deletions(-)
Author:
Smirnov Oleksandr
ss2316544@gmail.com
Committed by:
GitHub
noreply@github.com
Committed at:
2025-06-05 19:49:32 +0300
Parent:
9f5c654
M
e2e/apiv1_auth_test.go
@@ -4,6 +4,7 @@ import (
"net/http" "github.com/gofrs/uuid/v5" + "github.com/olexsmir/onasty/internal/hasher" "github.com/olexsmir/onasty/internal/models" )@@ -298,7 +299,7 @@ sessionDB = e.getLastSessionByUserID(uid)
e.Empty(sessionDB.RefreshToken) } -type apiv1AtuhChangePasswordRequest struct { +type apiv1AuthChangePasswordRequest struct { CurrentPassword string `json:"current_password"` NewPassword string `json:"new_password"` }@@ -312,7 +313,7 @@
httpResp := e.httpRequest( http.MethodPost, "/api/v1/auth/change-password", - e.jsonify(apiv1AtuhChangePasswordRequest{ + e.jsonify(apiv1AuthChangePasswordRequest{ CurrentPassword: password, NewPassword: newPassword, }),@@ -323,6 +324,30 @@ e.Equal(httpResp.Code, http.StatusOK)
userDB := e.getUserByEmail(email) e.NoError(e.hasher.Compare(userDB.Password, newPassword)) +} + +func (e *AppTestSuite) TestAuthV1_ChangePassword_wrongPassword() { + password := e.uuid() + newPassword := e.uuid() + email := e.uuid() + "@test.com" + _, toks := e.createAndSingIn(email, password) + + httpResp := e.httpRequest( + http.MethodPost, + "/api/v1/auth/change-password", + e.jsonify(apiv1AuthChangePasswordRequest{ + CurrentPassword: e.uuid(), + NewPassword: newPassword, + }), + toks.AccessToken, + ) + + e.Equal(http.StatusBadRequest, httpResp.Code) + + userDB := e.getUserByEmail(email) + + err := e.hasher.Compare(userDB.Password, newPassword) + e.ErrorIs(err, hasher.ErrMismatchedHashes) } type (
M
internal/service/usersrv/usersrv.go
@@ -188,24 +188,26 @@ ctx context.Context,
userID uuid.UUID, inp dtos.ChangeUserPassword, ) error { - // TODO: compare current password with providede, and assert on mismatch - //nolint:exhaustruct if err := (models.User{Password: inp.NewPassword}).ValidatePassword(); err != nil { return err } - oldPass, err := u.hasher.Hash(inp.CurrentPassword) + user, err := u.userstore.GetByID(ctx, userID) if err != nil { return err } + if err = u.hasher.Compare(user.Password, inp.CurrentPassword); err != nil { + return errors.Join(err, models.ErrUserInvalidPassword) + } + newPass, err := u.hasher.Hash(inp.NewPassword) if err != nil { return err } - if err := u.userstore.ChangePassword(ctx, userID, oldPass, newPass); err != nil { + if err := u.userstore.ChangePassword(ctx, userID, newPass); err != nil { return err }
M
internal/store/psql/userepo/userepo.go
@@ -14,16 +14,17 @@
type UserStorer interface { Create(ctx context.Context, inp models.User) (uuid.UUID, error) - // GetUserByCredentials returns user by email and password + // GetByEmail returns user by email and password // the password should be hashed GetByEmail(ctx context.Context, email string) (models.User, error) + GetUserIDByEmail(ctx context.Context, email string) (uuid.UUID, error) + GetByID(ctx context.Context, userID uuid.UUID) (models.User, error) - GetUserIDByEmail(ctx context.Context, email string) (uuid.UUID, error) MarkUserAsActivated(ctx context.Context, id uuid.UUID) error // ChangePassword changes user password from oldPassword to newPassword // and oldPassword and newPassword should be hashed - ChangePassword(ctx context.Context, userID uuid.UUID, oldPassword, newPassword string) error + ChangePassword(ctx context.Context, userID uuid.UUID, newPassword string) error // SetPassword sets new password for user by their id // password should be hashed@@ -112,6 +113,22 @@
return id, err } +func (r *UserRepo) GetByID(ctx context.Context, userID uuid.UUID) (models.User, error) { + query := `--sql +select id, email, password, activated, created_at, last_login_at +from users +where id = $1` + + var user models.User + err := r.db.QueryRow(ctx, query, userID). + Scan(&user.ID, &user.Email, &user.Password, &user.Activated, &user.CreatedAt, &user.LastLoginAt) + if errors.Is(err, pgx.ErrNoRows) { + return models.User{}, models.ErrUserNotFound + } + + return user, err +} + func (r *UserRepo) GetByOAuthID( ctx context.Context, provider, providerID string,@@ -164,15 +181,12 @@
func (r *UserRepo) ChangePassword( ctx context.Context, userID uuid.UUID, - oldPass, newPass string, + newPasswd string, ) error { query, args, err := pgq. Update("users"). - Set("password", newPass). - Where(pgq.Eq{ - "id": userID.String(), - "password": oldPass, - }). + Set("password", newPasswd). + Where(pgq.Eq{"id": userID.String()}). SQL() if err != nil { return err