all repos

onasty @ d309c75

a one-time notes service
6 files changed, 30 insertions(+), 35 deletions(-)
refactor: require only email for resending verification email (#165)

* refactor(api): require only email to resend verification email

* refactor(web): upgrade to new api requirements

* test: fix e2e api tests for new requirements
Author: Olexandr Smirnov ss2316544@gmail.com
Committed by: GitHub noreply@github.com
Committed at: 2025-07-10 18:37:54 +0300
Parent: 4137dee
M e2e/apiv1_auth_test.go
···
        97
        97
         	e.Equal(user.Activated, true)

      
        98
        98
         }

      
        99
        99
         

      
        
        100
        +type apiv1AuthResendVerificationEmailRequest struct {

      
        
        101
        +	Email string `json:"email"`

      
        
        102
        +}

      
        
        103
        +

      
        100
        104
         func (e *AppTestSuite) TestAuthV1_ResendVerificationEmail() {

      
        101
        105
         	email, password := e.uuid()+"email@email.com", e.uuid()

      
        102
        106
         

      ···
        116
        120
         	httpResp := e.httpRequest(

      
        117
        121
         		http.MethodPost,

      
        118
        122
         		"/api/v1/auth/resend-verification-email",

      
        119
        
        -		e.jsonify(apiv1AuthSignInRequest{

      
        120
        
        -			Email:    email,

      
        121
        
        -			Password: password,

      
        
        123
        +		e.jsonify(apiv1AuthResendVerificationEmailRequest{

      
        
        124
        +			Email: email,

      
        122
        125
         		}),

      
        123
        126
         	)

      
        124
        127
         

      ···
        133
        136
         	tests := []struct {

      
        134
        137
         		name         string

      
        135
        138
         		email        string

      
        136
        
        -		password     string

      
        137
        139
         		expectedCode int

      
        138
        140
         		expectedMsg  string

      
        139
        141
         	}{

      
        140
        142
         		{

      
        141
        
        -			name:         "already activated account",

      
        
        143
        +			name:         "already verified account",

      
        142
        144
         			email:        email,

      
        143
        
        -			password:     password,

      
        144
        145
         			expectedCode: http.StatusBadRequest,

      
        145
        146
         			expectedMsg:  models.ErrUserIsAlreadyVerified.Error(),

      
        146
        147
         		},

      
        147
        148
         		{

      
        148
        
        -			name:         "wrong credentials",

      
        149
        
        -			email:        email,

      
        150
        
        -			password:     e.uuid(),

      
        
        149
        +			name:         "user not found",

      
        
        150
        +			email:        e.uuid() + "@at.com",

      
        151
        151
         			expectedCode: http.StatusBadRequest,

      
        152
        
        -			expectedMsg:  models.ErrUserWrongCredentials.Error(),

      
        
        152
        +			expectedMsg:  models.ErrUserNotFound.Error(),

      
        153
        153
         		},

      
        154
        154
         	}

      
        155
        155
         

      ···
        157
        157
         		httpResp := e.httpRequest(

      
        158
        158
         			http.MethodPost,

      
        159
        159
         			"/api/v1/auth/resend-verification-email",

      
        160
        
        -			e.jsonify(apiv1AuthSignInRequest{

      
        161
        
        -				Email:    t.email,

      
        162
        
        -				Password: t.password,

      
        
        160
        +			e.jsonify(apiv1AuthResendVerificationEmailRequest{

      
        
        161
        +				Email: t.email,

      
        163
        162
         			}))

      
        164
        163
         

      
        165
        164
         		e.Equal(httpResp.Code, t.expectedCode)

      
M internal/dtos/user.go
···
        16
        16
         	Password string

      
        17
        17
         }

      
        18
        18
         

      
        
        19
        +type ResendVerificationEmail struct {

      
        
        20
        +	Email string

      
        
        21
        +}

      
        
        22
        +

      
        19
        23
         type ChangeUserPassword struct {

      
        20
        24
         	CurrentPassword string

      
        21
        25
         	NewPassword     string

      
M internal/service/usersrv/usersrv.go
···
        37
        37
         	HandleOAuthLogin(ctx context.Context, providerName, code string) (dtos.Tokens, error)

      
        38
        38
         

      
        39
        39
         	Verify(ctx context.Context, verificationKey string) error

      
        40
        
        -	ResendVerificationEmail(ctx context.Context, credentials dtos.SignIn) error

      
        
        40
        +	ResendVerificationEmail(ctx context.Context, inp dtos.ResendVerificationEmail) error

      
        41
        41
         

      
        42
        42
         	ParseJWTToken(token string) (jwtutil.Payload, error)

      
        43
        43
         

      ···
        297
        297
         	return u.userstore.MarkUserAsActivated(ctx, uid)

      
        298
        298
         }

      
        299
        299
         

      
        300
        
        -func (u *UserSrv) ResendVerificationEmail(ctx context.Context, inp dtos.SignIn) error {

      
        
        300
        +func (u *UserSrv) ResendVerificationEmail(

      
        
        301
        +	ctx context.Context,

      
        
        302
        +	inp dtos.ResendVerificationEmail,

      
        
        303
        +) error {

      
        301
        304
         	user, err := u.userstore.GetByEmail(ctx, inp.Email)

      
        302
        305
         	if err != nil {

      
        303
        306
         		return err

      
        304
        
        -	}

      
        305
        
        -

      
        306
        
        -	if err = u.hasher.Compare(user.Password, inp.Password); err != nil {

      
        307
        
        -		return models.ErrUserWrongCredentials

      
        308
        307
         	}

      
        309
        308
         

      
        310
        309
         	if user.Activated {

      
M internal/transport/http/apiv1/auth.go
···
        97
        97
         	c.String(http.StatusOK, "email verified")

      
        98
        98
         }

      
        99
        99
         

      
        
        100
        +type resendVerificationEmailRequest struct {

      
        
        101
        +	Email string `json:"email"`

      
        
        102
        +}

      
        
        103
        +

      
        100
        104
         func (a *APIV1) resendVerificationEmailHandler(c *gin.Context) {

      
        101
        
        -	var req signInRequest

      
        
        105
        +	var req resendVerificationEmailRequest

      
        102
        106
         	if err := c.ShouldBindJSON(&req); err != nil {

      
        103
        107
         		newError(c, http.StatusBadRequest, "invalid request")

      
        104
        108
         		return

      ···
        106
        110
         

      
        107
        111
         	if err := a.usersrv.ResendVerificationEmail(

      
        108
        112
         		c.Request.Context(),

      
        109
        
        -		dtos.SignIn{

      
        110
        
        -			Email:    req.Email,

      
        111
        
        -			Password: req.Password,

      
        
        113
        +		dtos.ResendVerificationEmail{

      
        
        114
        +			Email: req.Email,

      
        112
        115
         		}); err != nil {

      
        113
        116
         		errorResponse(c, err)

      
        114
        117
         		return

      
M web/src/Api/Auth.elm
···
        75
        75
                 }

      
        76
        76
         

      
        77
        77
         

      
        78
        
        -resendVerificationEmail :

      
        79
        
        -    { onResponse : Result Api.Error () -> msg

      
        80
        
        -    , email : String

      
        81
        
        -    , password : String

      
        82
        
        -    }

      
        83
        
        -    -> Effect msg

      
        
        78
        +resendVerificationEmail : { onResponse : Result Api.Error () -> msg, email : String } -> Effect msg

      
        84
        79
         resendVerificationEmail options =

      
        85
        80
             let

      
        86
        
        -        body : Encode.Value

      
        87
        81
                 body =

      
        88
        
        -            Encode.object

      
        89
        
        -                [ ( "email", Encode.string options.email )

      
        90
        
        -                , ( "password", Encode.string options.password )

      
        91
        
        -                ]

      
        
        82
        +            Encode.object [ ( "email", Encode.string options.email ) ]

      
        92
        83
             in

      
        93
        84
             Effect.sendApiRequest

      
        94
        85
                 { endpoint = "/api/v1/auth/resend-verification-email"

      
M web/src/Pages/Auth.elm
···
        124
        124
                     , Api.Auth.resendVerificationEmail

      
        125
        125
                         { onResponse = ApiResendVerificationEmail

      
        126
        126
                         , email = model.email

      
        127
        
        -                , password = model.password

      
        128
        127
                         }

      
        129
        128
                     )

      
        130
        129