all repos

onasty @ 40bb8b9396a7ed0f5c599dcbe7ccec4febc9ed8f

a one-time notes service
5 files changed, 59 insertions(+), 0 deletions(-)
feat: /me (#132)

* feat: add /me route

* test: test /me
Author: Smirnov Oleksandr ss2316544@gmail.com
Committed by: GitHub noreply@github.com
Committed at: 2025-06-09 18:12:42 +0300
Parent: e6c5d1c
M e2e/apiv1_auth_test.go

@@ -2,6 +2,7 @@ package e2e_test

import ( "net/http" + "time" "github.com/gofrs/uuid/v5" "github.com/olexsmir/onasty/internal/hasher"

@@ -435,6 +436,26 @@ }),

) e.Equal(httpResp.Code, http.StatusBadRequest) +} + +type getMeResponse struct { + Email string `json:"email"` + CreatedAt time.Time `json:"created_at"` +} + +func (e *AppTestSuite) TestApiV1_getMe() { + email := e.uuid() + "@test.com" + _, toks := e.createAndSingIn(email, "password") + + httpResp := e.httpRequest(http.MethodGet, "/api/v1/me", nil, toks.AccessToken) + + e.Equal(httpResp.Code, http.StatusOK) + + var body getMeResponse + e.readBodyAndUnjsonify(httpResp.Body, &body) + + e.Equal(email, body.Email) + e.NotZero(body.CreatedAt) } // createAndSingIn creates an activated user, logs them in,
M internal/dtos/user.go

@@ -39,3 +39,8 @@ type Tokens struct {

Access string Refresh string } + +type UserInfo struct { + Email string + CreatedAt time.Time +}
M internal/service/usersrv/usersrv.go

@@ -26,6 +26,7 @@ SignIn(ctx context.Context, inp dtos.SignIn) (dtos.Tokens, error)

RefreshTokens(ctx context.Context, refreshToken string) (dtos.Tokens, error) Logout(ctx context.Context, userID uuid.UUID, refreshToken string) error LogoutAll(ctx context.Context, userID uuid.UUID) error + GetUserInfo(ctx context.Context, userID uuid.UUID) (dtos.UserInfo, error) ChangePassword(ctx context.Context, userID uuid.UUID, inp dtos.ChangeUserPassword) error RequestPasswordReset(ctx context.Context, inp dtos.RequestResetPassword) error

@@ -165,6 +166,18 @@ }

func (u *UserSrv) LogoutAll(ctx context.Context, userID uuid.UUID) error { return u.sessionstore.DeleteAllByUserID(ctx, userID) +} + +func (u *UserSrv) GetUserInfo(ctx context.Context, userID uuid.UUID) (dtos.UserInfo, error) { + user, err := u.userstore.GetByID(ctx, userID) + if err != nil { + return dtos.UserInfo{}, err + } + + return dtos.UserInfo{ + Email: user.Email, + CreatedAt: user.CreatedAt, + }, nil } func (u *UserSrv) RefreshTokens(ctx context.Context, rtoken string) (dtos.Tokens, error) {
M internal/transport/http/apiv1/apiv1.go

@@ -54,6 +54,8 @@ authorized.POST("/change-password", a.changePasswordHandler)

} } + r.GET("/me", a.authorizedMiddleware, a.getMeHandler) + note := r.Group("/note") { note.GET("/:slug", a.getNoteBySlugHandler)
M internal/transport/http/apiv1/auth.go

@@ -262,3 +262,21 @@ AccessToken: tokens.Access,

RefreshToken: tokens.Refresh, }) } + +type getMeResponse struct { + Email string `json:"email"` + CreatedAt time.Time `json:"created_at"` +} + +func (a *APIV1) getMeHandler(c *gin.Context) { + uinfo, err := a.usersrv.GetUserInfo(c.Request.Context(), a.getUserID(c)) + if err != nil { + errorResponse(c, err) + return + } + + c.JSON(http.StatusOK, getMeResponse{ + Email: uinfo.Email, + CreatedAt: uinfo.CreatedAt, + }) +}