From e4007eb15aea2e0687a5e0ba8bee103ff9eff9e9 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Sun, 5 Jul 2026 02:57:56 +0700 Subject: [PATCH] save refresh token in login route --- .vscode/settings.json | 5 +++ cmd/evening_detective_server/main.go | 4 +- internal/repos/refresh_tokens_repo/repo.go | 43 +++++++++++++++++++ internal/services/users_service/service.go | 13 +++++- .../20260704192907_refresh_tokens_table.sql | 11 +++++ 5 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 internal/repos/refresh_tokens_repo/repo.go create mode 100644 migrations/20260704192907_refresh_tokens_table.sql diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2869530 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "pgxpool" + ] +} \ No newline at end of file diff --git a/cmd/evening_detective_server/main.go b/cmd/evening_detective_server/main.go index 02bf352..b60b769 100644 --- a/cmd/evening_detective_server/main.go +++ b/cmd/evening_detective_server/main.go @@ -7,6 +7,7 @@ import ( "evening_detective_server/internal/modules/email_sender" "evening_detective_server/internal/modules/password_generator" "evening_detective_server/internal/modules/processor_jwt" + "evening_detective_server/internal/repos/refresh_tokens_repo" "evening_detective_server/internal/repos/users_repo" "evening_detective_server/internal/services/users_service" proto "evening_detective_server/proto" @@ -51,7 +52,8 @@ func main() { smtpPassword := os.Getenv("SMTP_PASSWORD") emailSender := email_sender.NewSender(smtpHost, smtpPort, smtpUser, smtpPassword) processorJWT := processor_jwt.NewProcessor(os.Getenv("SECRET")) - usersService := users_service.NewUsersService(usersRepo, passwordGenerator, emailSender, processorJWT) + refreshTokensRepo := refresh_tokens_repo.NewRefreshTokensRepo(dbpool) + usersService := users_service.NewUsersService(usersRepo, passwordGenerator, emailSender, processorJWT, refreshTokensRepo) // Create a listener on TCP port lis, err := net.Listen("tcp", ":8080") diff --git a/internal/repos/refresh_tokens_repo/repo.go b/internal/repos/refresh_tokens_repo/repo.go new file mode 100644 index 0000000..3b0959c --- /dev/null +++ b/internal/repos/refresh_tokens_repo/repo.go @@ -0,0 +1,43 @@ +package refresh_tokens_repo + +import ( + "context" + + "github.com/jackc/pgx/v5/pgxpool" +) + +type RefreshTokensRepo struct { + pool *pgxpool.Pool +} + +func NewRefreshTokensRepo(pool *pgxpool.Pool) *RefreshTokensRepo { + return &RefreshTokensRepo{ + pool: pool, + } +} + +func (s *RefreshTokensRepo) AddRefreshToken( + ctx context.Context, + userId int, + refreshToken string, +) error { + _, err := s.pool.Exec( + ctx, + `INSERT INTO refresh_tokens (user_id, refresh_token) VALUES ($1, $2)`, + userId, + refreshToken, + ) + return err +} + +func (s *RefreshTokensRepo) DeleteRefreshTokensByUserId( + ctx context.Context, + userId int, +) error { + _, err := s.pool.Exec( + ctx, + `DELETE FROM refresh_tokens WHERE user_id = $1`, + userId, + ) + return err +} diff --git a/internal/services/users_service/service.go b/internal/services/users_service/service.go index add440e..9c5fc1b 100644 --- a/internal/services/users_service/service.go +++ b/internal/services/users_service/service.go @@ -6,6 +6,7 @@ import ( "evening_detective_server/internal/modules/email_sender" "evening_detective_server/internal/modules/password_generator" "evening_detective_server/internal/modules/processor_jwt" + "evening_detective_server/internal/repos/refresh_tokens_repo" "evening_detective_server/internal/repos/users_repo" "fmt" "strings" @@ -18,6 +19,7 @@ type UsersService struct { passwordGenerator password_generator.IPasswordGenerator emailSender email_sender.IEmailSender processorJWT processor_jwt.IProcessorJWT + refreshTokensRepo *refresh_tokens_repo.RefreshTokensRepo } func NewUsersService( @@ -25,12 +27,14 @@ func NewUsersService( passwordGenerator password_generator.IPasswordGenerator, emailSender email_sender.IEmailSender, processorJWT processor_jwt.IProcessorJWT, + refreshTokensRepo *refresh_tokens_repo.RefreshTokensRepo, ) *UsersService { return &UsersService{ usersRepo: usersRepo, passwordGenerator: passwordGenerator, emailSender: emailSender, processorJWT: processorJWT, + refreshTokensRepo: refreshTokensRepo, } } @@ -130,8 +134,13 @@ func (s *UsersService) Login( fmt.Println(accessToken, refreshToken) - // delete refresh tokens - // save new refresh token + if err := s.refreshTokensRepo.DeleteRefreshTokensByUserId(ctx, user.ID); err != nil { + return "", "", err + } + + if err := s.refreshTokensRepo.AddRefreshToken(ctx, user.ID, refreshToken); err != nil { + return "", "", err + } return accessToken, refreshToken, nil } diff --git a/migrations/20260704192907_refresh_tokens_table.sql b/migrations/20260704192907_refresh_tokens_table.sql new file mode 100644 index 0000000..4e6ec7a --- /dev/null +++ b/migrations/20260704192907_refresh_tokens_table.sql @@ -0,0 +1,11 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS refresh_tokens ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id INT NOT NULL, + refresh_token TEXT NOT NULL, + + CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE +); + +-- +goose Down +DROP TABLE IF EXISTS refresh_tokens;