diff --git a/app/delivery/web/api/restricted/jwtCookies.go b/app/delivery/web/api/restricted/jwtCookies.go new file mode 100644 index 0000000..9666647 --- /dev/null +++ b/app/delivery/web/api/restricted/jwtCookies.go @@ -0,0 +1,57 @@ +package restricted + +import ( + "git.ma-al.com/goc_daniel/b2b/app/service/jwtService" + "git.ma-al.com/goc_daniel/b2b/app/utils/i18n" + "git.ma-al.com/goc_daniel/b2b/app/utils/nullable" + "git.ma-al.com/goc_daniel/b2b/app/utils/response" + "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" + "github.com/gofiber/fiber/v3" +) + +// JWTCookiesHandler for updating JWT cookies. +type JWTCookiesHandler struct { + jwtService *jwtService.JWTService +} + +// NewJWTCookiesHandler creates a new JWTCookiesHandler instance +func NewJWTCookiesHandler() *JWTCookiesHandler { + jwtService := jwtService.New() + return &JWTCookiesHandler{ + jwtService: jwtService, + } +} + +func JWTCookiesHandlerRoutes(r fiber.Router) fiber.Router { + handler := NewJWTCookiesHandler() + + r.Get("/get-languages", handler.GetLanguages) + r.Get("/get-countries", handler.GetCountries) + r.Get("/update-choice", handler.UpdateChoice) + + return r +} + +func (h *JWTCookiesHandler) GetLanguages(c fiber.Ctx) error { + languages, err := h.jwtService.GetLanguages() + if err != nil { + return c.Status(responseErrors.GetErrorStatus(err)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) + } + + return c.JSON(response.Make(&languages, 0, i18n.T_(c, response.Message_OK))) +} + +func (h *JWTCookiesHandler) GetCountries(c fiber.Ctx) error { + countries, err := h.jwtService.GetCountriesAndCurrencies() + if err != nil { + return c.Status(responseErrors.GetErrorStatus(err)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) + } + + return c.JSON(response.Make(&countries, 0, i18n.T_(c, response.Message_OK))) +} + +func (h *JWTCookiesHandler) UpdateChoice(c fiber.Ctx) error { + return nil +} diff --git a/app/delivery/web/init.go b/app/delivery/web/init.go index dfcec34..efcc9a3 100644 --- a/app/delivery/web/init.go +++ b/app/delivery/web/init.go @@ -97,6 +97,11 @@ func (s *Server) Setup() error { listProducts := s.restricted.Group("/list-products") restricted.ListProductsHandlerRoutes(listProducts) + // changing the JWT cookies routes (restricted) + // in reality it just handles changing user's country and language + jwtUpdates := s.restricted.Group("/jwt-updates") + restricted.JWTCookiesHandlerRoutes(jwtUpdates) + // // Restricted routes example // restricted := s.api.Group("/restricted") // restricted.Use(middleware.AuthMiddleware()) diff --git a/app/model/countries.go b/app/model/countries.go new file mode 100644 index 0000000..61972d2 --- /dev/null +++ b/app/model/countries.go @@ -0,0 +1,11 @@ +package model + +// Represents a country together with its associated currency +type Country struct { + ID uint `gorm:"primaryKey;column:id" json:"id"` + Name string `gorm:"column:name" json:"name"` + Flag string `gorm:"size:16;not null;column:flag" json:"flag"` + CurrencyID uint `gorm:"column:id_currency" json:"currency_id"` + CurrencyISOCode string `gorm:"column:iso_code" json:"currency_iso_code"` + CurrencyName string `gorm:"column:name" json:"currency_name"` +} diff --git a/app/service/authService/auth.go b/app/service/authService/auth.go index d6c070c..089c3be 100644 --- a/app/service/authService/auth.go +++ b/app/service/authService/auth.go @@ -27,8 +27,8 @@ type JWTClaims struct { Email string `json:"email"` Username string `json:"username"` Role model.CustomerRole `json:"customer_role"` - FirstName string `json:"first_name"` - LastName string `json:"last_name"` + CartsIDs []uint `json:"carts_ids"` + CountryID uint `json:"country_id"` jwt.RegisteredClaims } @@ -476,8 +476,8 @@ func (s *AuthService) generateAccessToken(user *model.Customer) (string, error) Email: user.Email, Username: user.Email, Role: user.Role, - FirstName: user.FirstName, - LastName: user.LastName, + CartsIDs: []uint{}, + CountryID: 1, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(s.config.JWTExpiration) * time.Second)), IssuedAt: jwt.NewNumericDate(time.Now()), diff --git a/app/service/jwtService/jwtService.go b/app/service/jwtService/jwtService.go new file mode 100644 index 0000000..fd5ee2d --- /dev/null +++ b/app/service/jwtService/jwtService.go @@ -0,0 +1,28 @@ +package jwtService + +import ( + "git.ma-al.com/goc_daniel/b2b/app/model" + "git.ma-al.com/goc_daniel/b2b/repository/jwtFieldsRepo" +) + +// jwtService handles updating JWT cookies +type JWTService struct { + repo jwtFieldsRepo.JWTFieldsRepo +} + +// NewJWTService creates a new JWT service +func New() *JWTService { + return &JWTService{} +} + +func (s *JWTService) GetLanguages() ([]model.Language, error) { + return s.repo.GetLanguages() +} + +func (s *JWTService) GetCountriesAndCurrencies() ([]model.Country, error) { + return s.repo.GetCountriesAndCurrencies() +} + +func (s *JWTService) UpdateChoice() error { + return nil +} diff --git a/i18n/migrations/20260302163122_create_tables.sql b/i18n/migrations/20260302163122_create_tables.sql index e335d0f..721b18e 100644 --- a/i18n/migrations/20260302163122_create_tables.sql +++ b/i18n/migrations/20260302163122_create_tables.sql @@ -24,7 +24,7 @@ INSERT IGNORE INTO b2b_language VALUES (1, '2022-09-16 17:10:02.837', '2026-03-02 21:24:36.779730', NULL, 'Polski', 'pl', 'pl', '__-__-____', '__-__', 0, 0, 1, '🇵🇱'), (2, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'English', 'en', 'en', '__-__-____', '__-__', 0, 1, 1, '🇬🇧'), - (3, '2022-09-16 17:10:02.865', '2026-03-02 21:24:36.779730', NULL, 'Čeština', 'cs', 'cs', '__-__-____', '__-__', 0, 0, 1, '🇨🇿'), + (3, '2022-09-16 17:10:02.865', '2026-03-02 21:24:36.779730', NULL, 'Čeština', 'cs', 'cs', '__-__-____', '__-__', 0, 0, 0, '🇨🇿'), (4, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'Deutsch', 'de', 'de', '__-__-____', '__-__', 0, 0, 1, '🇩🇪'); CREATE TABLE IF NOT EXISTS b2b_components ( @@ -119,8 +119,26 @@ VALUES (1, 'admin@ma-al.com', '$2a$10$Owy9DjrS0l3Fz4XoOvh5pulgmOMqdwXmb7hYE9BovnSuWS2plGr82', 'Super', 'Admin', 'admin', 'local', '', '', 1, 1, NULL, NULL, '', NULL, NULL, NULL, 'pl', '2026-03-02 16:55:10.252740', '2026-03-02 16:55:10.252740', NULL); ALTER TABLE b2b_customers AUTO_INCREMENT = 1; +-- countries +CREATE TABLE IF NOT EXISTS b2b_countries ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(128) NOT NULL, + currency INT UNSIGNED NOT NULL, + flag VARCHAR(16) NOT NULL, + CONSTRAINT fk_countries_currency FOREIGN KEY (currency) REFERENCES ps_currency(id_currency) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT IGNORE INTO b2b_countries + (id, name, currency, flag) +VALUES + (1, 'Polska', 1, '🇵🇱'), + (2, 'England', 2, '🇬🇧'), + (3, 'Čeština', 2, '🇨🇿'), + (4, 'Deutschland', 2, '🇩🇪'); + -- +goose Down +DROP TABLE IF EXISTS b2b_countries; DROP TABLE IF EXISTS b2b_language; DROP TABLE IF EXISTS b2b_components; DROP TABLE IF EXISTS b2b_scopes; diff --git a/repository/jwtFieldsRepo/jwtFieldsRepo.go b/repository/jwtFieldsRepo/jwtFieldsRepo.go new file mode 100644 index 0000000..b112ef0 --- /dev/null +++ b/repository/jwtFieldsRepo/jwtFieldsRepo.go @@ -0,0 +1,36 @@ +package jwtFieldsRepo + +import ( + "git.ma-al.com/goc_daniel/b2b/app/db" + "git.ma-al.com/goc_daniel/b2b/app/model" +) + +type UIJWTFieldsRepo interface { + GetLanguages() ([]model.Language, error) + GetCountriesAndCurrencies() ([]model.Country, error) +} + +type JWTFieldsRepo struct{} + +func New() UIJWTFieldsRepo { + return &JWTFieldsRepo{} +} + +func (repo *JWTFieldsRepo) GetLanguages() ([]model.Language, error) { + var languages []model.Language + + err := db.DB.Table("b2b_language").Scan(&languages).Error + + return languages, err +} + +func (repo *JWTFieldsRepo) GetCountriesAndCurrencies() ([]model.Country, error) { + var countries []model.Country + + err := db.DB.Table("b2b_countries"). + Select("b2b_countries.id, b2b_countries.name, b2b_countries.flag, ps_currency.id as id_currency, ps_currency.name as currency_name, ps_currency.iso_code as currency_iso_code"). + Joins("JOIN ps_currency ON ps_currency.id = b2b_countries.currency"). + Scan(&countries).Error + + return countries, err +}