Compare commits
5 Commits
1bab7f642f
...
user_telep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0c53c97ba | ||
| 09a77c14c9 | |||
|
|
c7533a8deb | ||
|
|
03f04b2f53 | ||
|
|
55da953f32 |
4
.env
4
.env
@@ -48,10 +48,6 @@ EMAIL_FROM=test@ma-al.com
|
|||||||
EMAIL_FROM_NAME=Gitea Manager
|
EMAIL_FROM_NAME=Gitea Manager
|
||||||
EMAIL_ADMIN=goc_marek@ma-al.pl
|
EMAIL_ADMIN=goc_marek@ma-al.pl
|
||||||
|
|
||||||
# STORAGE
|
|
||||||
STORAGE_ROOT=./storage
|
|
||||||
|
|
||||||
|
|
||||||
I18N_LANGS=en,pl,cs
|
I18N_LANGS=en,pl,cs
|
||||||
|
|
||||||
PDF_SERVER_URL=http://localhost:8000
|
PDF_SERVER_URL=http://localhost:8000
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,6 +5,4 @@ bin/
|
|||||||
i18n/*.json
|
i18n/*.json
|
||||||
*_templ.go
|
*_templ.go
|
||||||
tmp/main
|
tmp/main
|
||||||
test.go
|
test.go
|
||||||
storage/*
|
|
||||||
!storage/.gitkeep
|
|
||||||
@@ -2,10 +2,8 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -26,8 +24,7 @@ type Config struct {
|
|||||||
GoogleTranslate GoogleTranslateConfig
|
GoogleTranslate GoogleTranslateConfig
|
||||||
Image ImageConfig
|
Image ImageConfig
|
||||||
Cors CorsConfig
|
Cors CorsConfig
|
||||||
MeiliSearch MeiliSearchConfig
|
MailiSearch MeiliSearchConfig
|
||||||
Storage StorageConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type I18n struct {
|
type I18n struct {
|
||||||
@@ -98,10 +95,6 @@ type EmailConfig struct {
|
|||||||
Enabled bool `env:"EMAIL_ENABLED,false"`
|
Enabled bool `env:"EMAIL_ENABLED,false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorageConfig struct {
|
|
||||||
RootFolder string `env:"STORAGE_ROOT"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PdfPrinter struct {
|
type PdfPrinter struct {
|
||||||
ServerUrl string `env:"PDF_SERVER_URL,http://localhost:8000"`
|
ServerUrl string `env:"PDF_SERVER_URL,http://localhost:8000"`
|
||||||
}
|
}
|
||||||
@@ -162,7 +155,7 @@ func load() *Config {
|
|||||||
|
|
||||||
err = loadEnv(&cfg.OAuth.Google)
|
err = loadEnv(&cfg.OAuth.Google)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("not possible to load env variables for oauth google : ", err.Error(), "")
|
slog.Error("not possible to load env variables for outh google : ", err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loadEnv(&cfg.App)
|
err = loadEnv(&cfg.App)
|
||||||
@@ -177,12 +170,12 @@ func load() *Config {
|
|||||||
|
|
||||||
err = loadEnv(&cfg.I18n)
|
err = loadEnv(&cfg.I18n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("not possible to load env variables for i18n : ", err.Error(), "")
|
slog.Error("not possible to load env variables for email : ", err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loadEnv(&cfg.Pdf)
|
err = loadEnv(&cfg.Pdf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("not possible to load env variables for pdf : ", err.Error(), "")
|
slog.Error("not possible to load env variables for email : ", err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loadEnv(&cfg.GoogleTranslate)
|
err = loadEnv(&cfg.GoogleTranslate)
|
||||||
@@ -192,25 +185,19 @@ func load() *Config {
|
|||||||
|
|
||||||
err = loadEnv(&cfg.Image)
|
err = loadEnv(&cfg.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("not possible to load env variables for image : ", err.Error(), "")
|
slog.Error("not possible to load env variables for google translate : ", err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loadEnv(&cfg.Cors)
|
err = loadEnv(&cfg.Cors)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("not possible to load env variables for cors : ", err.Error(), "")
|
slog.Error("not possible to load env variables for google translate : ", err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loadEnv(&cfg.MeiliSearch)
|
err = loadEnv(&cfg.MailiSearch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("not possible to load env variables for meili search : ", err.Error(), "")
|
slog.Error("not possible to load env variables for google translate : ", err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loadEnv(&cfg.Storage)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("not possible to load env variables for storage : ", err.Error(), "")
|
|
||||||
}
|
|
||||||
cfg.Storage.RootFolder = ResolveRelativePath(cfg.Storage.RootFolder)
|
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,22 +308,6 @@ func setValue(field reflect.Value, val string, key string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveRelativePath(relativePath string) string {
|
|
||||||
// get working directory (where program was started)
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert to absolute path
|
|
||||||
absPath := relativePath
|
|
||||||
if !filepath.IsAbs(absPath) {
|
|
||||||
absPath = filepath.Join(wd, absPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Clean(absPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseEnvTag(tag string) (key string, def *string) {
|
func parseEnvTag(tag string) (key string, def *string) {
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||||
@@ -60,9 +61,52 @@ func AuthMiddleware() fiber.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set user in context
|
// Create locale. LangID is overwritten by auth Token
|
||||||
c.Locals(constdata.USER_LOCALES_NAME, user.ToSession())
|
var userLocale model.UserLocale
|
||||||
c.Locals(constdata.USER_LOCALES_ID, user.ID)
|
userLocale.OriginalUser = user
|
||||||
|
|
||||||
|
// Check if target user is present
|
||||||
|
targetUserIDAttribute := c.Query("target_user_id")
|
||||||
|
|
||||||
|
if targetUserIDAttribute == "" {
|
||||||
|
userLocale.User = user
|
||||||
|
c.Locals(constdata.USER_LOCALE, &userLocale)
|
||||||
|
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now populate the target user
|
||||||
|
if user.Role != model.RoleAdmin {
|
||||||
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
||||||
|
"error": "admin access required",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
targetUserID, err := strconv.Atoi(targetUserIDAttribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
|
"error": "invalid target user id attribute",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// to verify target user, we use the same functionality as for verifying original user
|
||||||
|
// Get target user from database
|
||||||
|
user, err = authService.GetUserByID(uint(targetUserID))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||||
|
"error": "target user not found",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if target user is active
|
||||||
|
if !user.IsActive {
|
||||||
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
||||||
|
"error": "target user account is inactive",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
userLocale.User = user
|
||||||
|
c.Locals(constdata.USER_LOCALE, &userLocale)
|
||||||
|
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
@@ -95,24 +139,6 @@ func RequireAdmin() fiber.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserID extracts user ID from context
|
|
||||||
func GetUserID(c fiber.Ctx) uint {
|
|
||||||
userID, ok := c.Locals("userID").(uint)
|
|
||||||
if !ok {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return userID
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUser extracts user from context
|
|
||||||
func GetUser(c fiber.Ctx) *model.UserSession {
|
|
||||||
user, ok := c.Locals("user").(*model.UserSession)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return user
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetConfig returns the app config
|
// GetConfig returns the app config
|
||||||
func GetConfig() *config.Config {
|
func GetConfig() *config.Config {
|
||||||
return config.Get()
|
return config.Get()
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
|
||||||
|
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,12 +24,8 @@ func LanguageMiddleware() fiber.Handler {
|
|||||||
if id, err := strconv.ParseUint(langIDStr, 10, 32); err == nil {
|
if id, err := strconv.ParseUint(langIDStr, 10, 32); err == nil {
|
||||||
langID = uint(id)
|
langID = uint(id)
|
||||||
if langID > 0 {
|
if langID > 0 {
|
||||||
lang, err := langService.GetLanguageById(langID)
|
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
|
||||||
if err == nil {
|
return c.Next()
|
||||||
c.Locals("langID", langID)
|
|
||||||
c.Locals("lang", lang)
|
|
||||||
return c.Next()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,12 +36,8 @@ func LanguageMiddleware() fiber.Handler {
|
|||||||
if id, err := strconv.ParseUint(cookieLang, 10, 32); err == nil {
|
if id, err := strconv.ParseUint(cookieLang, 10, 32); err == nil {
|
||||||
langID = uint(id)
|
langID = uint(id)
|
||||||
if langID > 0 {
|
if langID > 0 {
|
||||||
lang, err := langService.GetLanguageById(langID)
|
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
|
||||||
if err == nil {
|
return c.Next()
|
||||||
c.Locals("langID", langID)
|
|
||||||
c.Locals("lang", lang)
|
|
||||||
return c.Next()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,8 +51,7 @@ func LanguageMiddleware() fiber.Handler {
|
|||||||
lang, err := langService.GetLanguageByISOCode(isoCode)
|
lang, err := langService.GetLanguageByISOCode(isoCode)
|
||||||
if err == nil && lang != nil {
|
if err == nil && lang != nil {
|
||||||
langID = uint(lang.ID)
|
langID = uint(lang.ID)
|
||||||
c.Locals("langID", langID)
|
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
|
||||||
c.Locals("lang", lang)
|
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,8 +61,7 @@ func LanguageMiddleware() fiber.Handler {
|
|||||||
defaultLang, err := langService.GetDefaultLanguage()
|
defaultLang, err := langService.GetDefaultLanguage()
|
||||||
if err == nil && defaultLang != nil {
|
if err == nil && defaultLang != nil {
|
||||||
langID = uint(defaultLang.ID)
|
langID = uint(defaultLang.ID)
|
||||||
c.Locals("langID", langID)
|
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
|
||||||
c.Locals("lang", defaultLang)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Next()
|
return c.Next()
|
||||||
@@ -104,11 +96,9 @@ func parseAcceptLanguage(header string) string {
|
|||||||
return strings.ToLower(first)
|
return strings.ToLower(first)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLanguageID extracts language ID from context
|
func returnNewLocale(lang_id uint) *model.UserLocale {
|
||||||
func GetLanguageID(c fiber.Ctx) uint {
|
newLocale := model.UserLocale{}
|
||||||
langID, ok := c.Locals("langID").(uint)
|
newLocale.OriginalUser = &model.Customer{}
|
||||||
if !ok {
|
newLocale.OriginalUser.LangID = lang_id
|
||||||
return 0
|
return &newLocale
|
||||||
}
|
|
||||||
return langID
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,15 +268,15 @@ func (h *AuthHandler) RefreshToken(c fiber.Ctx) error {
|
|||||||
|
|
||||||
// Me returns the current user info
|
// Me returns the current user info
|
||||||
func (h *AuthHandler) Me(c fiber.Ctx) error {
|
func (h *AuthHandler) Me(c fiber.Ctx) error {
|
||||||
user := c.Locals("user")
|
userLocale := c.Locals(constdata.USER_LOCALE).(*model.UserLocale)
|
||||||
if user == nil {
|
if userLocale.OriginalUser == nil {
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||||
"error": responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated),
|
"error": responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
"user": user,
|
"user": *userLocale.OriginalUser,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,21 +351,12 @@ func (h *AuthHandler) CompleteRegistration(c fiber.Ctx) error {
|
|||||||
|
|
||||||
// Updates JWT Tokens. Requires authentication and updates access token only
|
// Updates JWT Tokens. Requires authentication and updates access token only
|
||||||
func (h *AuthHandler) UpdateJWTToken(c fiber.Ctx) error {
|
func (h *AuthHandler) UpdateJWTToken(c fiber.Ctx) error {
|
||||||
userLocals, ok := c.Locals(constdata.USER_LOCALES_NAME).(*model.UserSession)
|
userLocale, ok := c.Locals(constdata.USER_LOCALE).(*model.UserLocale)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(fiber.StatusUnauthorized).
|
return c.Status(fiber.StatusUnauthorized).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated)))
|
||||||
}
|
}
|
||||||
|
|
||||||
user := model.Customer{
|
|
||||||
ID: userLocals.UserID,
|
|
||||||
Email: userLocals.Email,
|
|
||||||
Role: userLocals.Role,
|
|
||||||
LangID: userLocals.LangID,
|
|
||||||
CountryID: userLocals.CountryID,
|
|
||||||
IsActive: userLocals.IsActive,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse language and country_id from query params
|
// Parse language and country_id from query params
|
||||||
langIDStr := c.Query("lang_id")
|
langIDStr := c.Query("lang_id")
|
||||||
|
|
||||||
@@ -375,7 +366,7 @@ func (h *AuthHandler) UpdateJWTToken(c fiber.Ctx) error {
|
|||||||
return c.Status(fiber.StatusBadRequest).
|
return c.Status(fiber.StatusBadRequest).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadLangID)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadLangID)))
|
||||||
}
|
}
|
||||||
user.LangID = uint(parsedID)
|
userLocale.OriginalUser.LangID = uint(parsedID)
|
||||||
}
|
}
|
||||||
|
|
||||||
countryIDStr := c.Query("country_id")
|
countryIDStr := c.Query("country_id")
|
||||||
@@ -386,10 +377,10 @@ func (h *AuthHandler) UpdateJWTToken(c fiber.Ctx) error {
|
|||||||
return c.Status(fiber.StatusBadRequest).
|
return c.Status(fiber.StatusBadRequest).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadCountryID)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadCountryID)))
|
||||||
}
|
}
|
||||||
user.CountryID = uint(parsedID)
|
userLocale.OriginalUser.CountryID = uint(parsedID)
|
||||||
}
|
}
|
||||||
|
|
||||||
newAccessToken, err := h.authService.UpdateJWTToken(&user)
|
newAccessToken, err := h.authService.UpdateJWTToken(userLocale.OriginalUser)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
|
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package public
|
|||||||
import (
|
import (
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"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/response"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
@@ -30,7 +31,7 @@ func RoutingHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *RoutingHandler) GetRouting(c fiber.Ctx) error {
|
func (h *RoutingHandler) GetRouting(c fiber.Ctx) error {
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
lang_id, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/cartsService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/cartsService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"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/response"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
@@ -37,7 +38,7 @@ func CartsHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
|
func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
@@ -53,7 +54,7 @@ func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
@@ -78,7 +79,7 @@ func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) RetrieveCartsInfo(c fiber.Ctx) error {
|
func (h *CartsHandler) RetrieveCartsInfo(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
@@ -94,7 +95,7 @@ func (h *CartsHandler) RetrieveCartsInfo(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
@@ -117,7 +118,7 @@ func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/listService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/listService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||||
@@ -43,19 +44,19 @@ func (h *ListHandler) ListProducts(c fiber.Ctx) error {
|
|||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
id_lang, ok := c.Locals("langID").(uint)
|
id_lang, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
}
|
}
|
||||||
|
|
||||||
listing, err := h.listService.ListProducts(id_lang, paging, filters)
|
list, err := h.listService.ListProducts(id_lang, paging, filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(&list.Items, int(list.Count), i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
var columnMappingListProducts map[string]string = map[string]string{
|
var columnMappingListProducts map[string]string = map[string]string{
|
||||||
@@ -74,19 +75,19 @@ func (h *ListHandler) ListUsers(c fiber.Ctx) error {
|
|||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
id_lang, ok := c.Locals("langID").(uint)
|
id_lang, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
}
|
}
|
||||||
|
|
||||||
listing, err := h.listService.ListUsers(id_lang, paging, filters)
|
list, err := h.listService.ListUsers(id_lang, paging, filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(&list.Items, int(list.Count), i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
var columnMappingListUsers map[string]string = map[string]string{
|
var columnMappingListUsers map[string]string = map[string]string{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"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/response"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
@@ -33,7 +34,7 @@ func MenuHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MenuHandler) GetCategoryTree(c fiber.Ctx) error {
|
func (h *MenuHandler) GetCategoryTree(c fiber.Ctx) error {
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
lang_id, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
@@ -56,7 +57,7 @@ func (h *MenuHandler) GetCategoryTree(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
|
func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
lang_id, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
@@ -86,7 +87,7 @@ func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
|
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
lang_id, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/productTranslationService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/productTranslationService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"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/response"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
@@ -41,7 +42,7 @@ func ProductTranslationHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
|
|
||||||
// GetProductDescription returns the product description for a given product ID
|
// GetProductDescription returns the product description for a given product ID
|
||||||
func (h *ProductTranslationHandler) GetProductDescription(c fiber.Ctx) error {
|
func (h *ProductTranslationHandler) GetProductDescription(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
@@ -72,7 +73,7 @@ func (h *ProductTranslationHandler) GetProductDescription(c fiber.Ctx) error {
|
|||||||
|
|
||||||
// SaveProductDescription saves the description for a given product ID, in given language
|
// SaveProductDescription saves the description for a given product ID, in given language
|
||||||
func (h *ProductTranslationHandler) SaveProductDescription(c fiber.Ctx) error {
|
func (h *ProductTranslationHandler) SaveProductDescription(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
@@ -109,7 +110,7 @@ func (h *ProductTranslationHandler) SaveProductDescription(c fiber.Ctx) error {
|
|||||||
|
|
||||||
// TranslateProductDescription returns translated product description
|
// TranslateProductDescription returns translated product description
|
||||||
func (h *ProductTranslationHandler) TranslateProductDescription(c fiber.Ctx) error {
|
func (h *ProductTranslationHandler) TranslateProductDescription(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"git.ma-al.com/goc_daniel/b2b/app/service/meiliService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/meiliService"
|
||||||
searchservice "git.ma-al.com/goc_daniel/b2b/app/service/searchService"
|
searchservice "git.ma-al.com/goc_daniel/b2b/app/service/searchService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"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/response"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
@@ -36,7 +37,7 @@ func MeiliSearchHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
||||||
id_lang, ok := c.Locals("langID").(uint)
|
id_lang, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
@@ -49,12 +50,11 @@ func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
|||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
nothing := ""
|
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
||||||
return c.JSON(response.Make(¬hing, 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
|
func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
|
||||||
id_lang, ok := c.Locals("langID").(uint)
|
id_lang, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
@@ -88,7 +88,7 @@ func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MeiliSearchHandler) GetSettings(c fiber.Ctx) error {
|
func (h *MeiliSearchHandler) GetSettings(c fiber.Ctx) error {
|
||||||
id_lang, ok := c.Locals("langID").(uint)
|
id_lang, ok := localeExtractor.GetLangID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
package restricted
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/storageService"
|
|
||||||
"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"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StorageHandler struct {
|
|
||||||
storageService *storageService.StorageService
|
|
||||||
config *config.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStorageHandler() *StorageHandler {
|
|
||||||
return &StorageHandler{
|
|
||||||
storageService: storageService.New(),
|
|
||||||
config: config.Get(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func StorageHandlerRoutes(r fiber.Router) fiber.Router {
|
|
||||||
handler := NewStorageHandler()
|
|
||||||
|
|
||||||
r.Get("/list-content/*", handler.ListContent)
|
|
||||||
r.Get("/download-file/*", handler.DownloadFile)
|
|
||||||
|
|
||||||
r.Get("/move/*", handler.Move)
|
|
||||||
r.Get("/copy/*", handler.Copy)
|
|
||||||
r.Post("/upload-file/*", handler.UploadFile)
|
|
||||||
r.Get("/create-folder/*", handler.CreateFolder)
|
|
||||||
r.Delete("/delete-file/*", handler.DeleteFile)
|
|
||||||
r.Delete("/delete-folder/*", handler.DeleteFolder)
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) Move(c fiber.Ctx) error {
|
|
||||||
src_abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
dest_abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Query("dest_path"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.storageService.Move(src_abs_path, dest_abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) Copy(c fiber.Ctx) error {
|
|
||||||
src_abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
dest_abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Query("dest_path"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.storageService.Copy(src_abs_path, dest_abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// accepted path looks like e.g. "/folder1/" or "folder1"
|
|
||||||
func (h *StorageHandler) ListContent(c fiber.Ctx) error {
|
|
||||||
// relative path defaults to root directory
|
|
||||||
abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
entries_in_list, err := h.storageService.ListContent(abs_path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(entries_in_list, 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) DownloadFile(c fiber.Ctx) error {
|
|
||||||
abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
f, filename, filesize, err := h.storageService.DownloadFilePrep(abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Attachment(filename)
|
|
||||||
c.Set("Content-Length", strconv.FormatInt(filesize, 10))
|
|
||||||
c.Set("Content-Type", "application/octet-stream")
|
|
||||||
return c.SendStream(f, int(filesize))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) UploadFile(c fiber.Ctx) error {
|
|
||||||
abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := c.FormFile("document")
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrMissingFileFieldDocument)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrMissingFileFieldDocument)))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.storageService.UploadFile(c, abs_path, f)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) CreateFolder(c fiber.Ctx) error {
|
|
||||||
abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.storageService.CreateFolder(abs_path, c.Query("name"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) DeleteFile(c fiber.Ctx) error {
|
|
||||||
abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.storageService.DeleteFile(abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StorageHandler) DeleteFolder(c fiber.Ctx) error {
|
|
||||||
abs_path, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.storageService.DeleteFolder(abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
@@ -115,10 +115,6 @@ func (s *Server) Setup() error {
|
|||||||
carts := s.restricted.Group("/carts")
|
carts := s.restricted.Group("/carts")
|
||||||
restricted.CartsHandlerRoutes(carts)
|
restricted.CartsHandlerRoutes(carts)
|
||||||
|
|
||||||
// storage (restricted)
|
|
||||||
storage := s.restricted.Group("/storage")
|
|
||||||
restricted.StorageHandlerRoutes(storage)
|
|
||||||
|
|
||||||
s.api.All("*", func(c fiber.Ctx) error {
|
s.api.All("*", func(c fiber.Ctx) error {
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -82,6 +82,15 @@ type UserSession struct {
|
|||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserLocale struct {
|
||||||
|
// User is the Target user if present, otherwise same as Original.
|
||||||
|
// User ought to be used in applications
|
||||||
|
User *Customer
|
||||||
|
// Original user is the one associated with auth token
|
||||||
|
OriginalUser *Customer
|
||||||
|
// Importantly, lang_id used in application is stored as OriginalUser.LangID
|
||||||
|
}
|
||||||
|
|
||||||
// ToSession converts User to UserSession
|
// ToSession converts User to UserSession
|
||||||
func (u *Customer) ToSession() *UserSession {
|
func (u *Customer) ToSession() *UserSession {
|
||||||
return &UserSession{
|
return &UserSession{
|
||||||
@@ -98,6 +107,7 @@ func (u *Customer) ToSession() *UserSession {
|
|||||||
type LoginRequest struct {
|
type LoginRequest struct {
|
||||||
Email string `json:"email" form:"email"`
|
Email string `json:"email" form:"email"`
|
||||||
Password string `json:"password" form:"password"`
|
Password string `json:"password" form:"password"`
|
||||||
|
LangID *uint `json:"lang_id" form:"lang_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterRequest represents the initial registration form data
|
// RegisterRequest represents the initial registration form data
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type EntryInList struct {
|
|
||||||
Name string
|
|
||||||
IsFolder bool
|
|
||||||
}
|
|
||||||
@@ -18,9 +18,10 @@ type ProductDescription struct {
|
|||||||
AvailableLater string `gorm:"column:available_later;type:varchar(255)" json:"available_later" form:"available_later"`
|
AvailableLater string `gorm:"column:available_later;type:varchar(255)" json:"available_later" form:"available_later"`
|
||||||
DeliveryInStock string `gorm:"column:delivery_in_stock;type:varchar(255)" json:"delivery_in_stock" form:"delivery_in_stock"`
|
DeliveryInStock string `gorm:"column:delivery_in_stock;type:varchar(255)" json:"delivery_in_stock" form:"delivery_in_stock"`
|
||||||
DeliveryOutStock string `gorm:"column:delivery_out_stock;type:varchar(255)" json:"delivery_out_stock" form:"delivery_out_stock"`
|
DeliveryOutStock string `gorm:"column:delivery_out_stock;type:varchar(255)" json:"delivery_out_stock" form:"delivery_out_stock"`
|
||||||
Usage string `gorm:"column:usage;type:text" json:"usage" form:"usage"`
|
Usage string `gorm:"column:_usage_;type:text" json:"usage" form:"usage"`
|
||||||
|
|
||||||
ExistsInDatabase bool `gorm:"-" json:"exists_in_database"`
|
ImageLink string `gorm:"column:image_link" json:"image_link"`
|
||||||
|
ExistsInDatabase bool `gorm:"-" json:"exists_in_database"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductRow struct {
|
type ProductRow struct {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/db"
|
"git.ma-al.com/goc_daniel/b2b/app/db"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model/dbmodel"
|
"git.ma-al.com/goc_daniel/b2b/app/model/dbmodel"
|
||||||
@@ -36,6 +37,27 @@ func (r *ProductDescriptionRepo) GetProductDescription(productID uint, productid
|
|||||||
IDShop: int32(constdata.SHOP_ID),
|
IDShop: int32(constdata.SHOP_ID),
|
||||||
IDLang: int32(productid_lang),
|
IDLang: int32(productid_lang),
|
||||||
}).
|
}).
|
||||||
|
Select(`
|
||||||
|
`+dbmodel.PsProductLangCols.IDProduct.TabCol()+` AS id_product,
|
||||||
|
`+dbmodel.PsProductLangCols.IDShop.TabCol()+` AS id_shop,
|
||||||
|
`+dbmodel.PsProductLangCols.IDLang.TabCol()+` AS id_lang,
|
||||||
|
`+dbmodel.PsProductLangCols.Description.TabCol()+` AS description,
|
||||||
|
`+dbmodel.PsProductLangCols.DescriptionShort.TabCol()+` AS description_short,
|
||||||
|
`+dbmodel.PsProductLangCols.LinkRewrite.TabCol()+` AS link_rewrite,
|
||||||
|
`+dbmodel.PsProductLangCols.MetaDescription.TabCol()+` AS meta_description,
|
||||||
|
`+dbmodel.PsProductLangCols.MetaKeywords.TabCol()+` AS meta_keywords,
|
||||||
|
`+dbmodel.PsProductLangCols.MetaTitle.TabCol()+` AS meta_title,
|
||||||
|
`+dbmodel.PsProductLangCols.Name.TabCol()+` AS name,
|
||||||
|
`+dbmodel.PsProductLangCols.AvailableNow.TabCol()+` AS available_now,
|
||||||
|
`+dbmodel.PsProductLangCols.AvailableLater.TabCol()+` AS available_later,
|
||||||
|
`+dbmodel.PsProductLangCols.DeliveryInStock.TabCol()+` AS delivery_in_stock,
|
||||||
|
`+dbmodel.PsProductLangCols.DeliveryOutStock.TabCol()+` AS delivery_out_stock,
|
||||||
|
`+dbmodel.PsProductLangCols.Usage.TabCol()+` AS _usage_,
|
||||||
|
CONCAT(?, '/', `+dbmodel.PsImageShopCols.IDImage.TabCol()+`, '-large_default/', `+dbmodel.PsProductLangCols.LinkRewrite.TabCol()+`, '.webp') AS image_link
|
||||||
|
`, config.Get().Image.ImagePrefix).
|
||||||
|
Joins("JOIN " + dbmodel.TableNamePsImageShop +
|
||||||
|
" ON " + dbmodel.PsImageShopCols.IDProduct.TabCol() + "=" + dbmodel.PsProductLangCols.IDProduct.TabCol() +
|
||||||
|
" AND " + dbmodel.PsImageShopCols.Cover.TabCol() + " = 1").
|
||||||
First(&ProductDescription).Error
|
First(&ProductDescription).Error
|
||||||
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ func New() UISearchRepo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *SearchRepo) Search(index string, body []byte) (*SearchProxyResponse, error) {
|
func (r *SearchRepo) Search(index string, body []byte) (*SearchProxyResponse, error) {
|
||||||
url := fmt.Sprintf("%s/indexes/%s/search", r.cfg.MeiliSearch.ServerURL, index)
|
url := fmt.Sprintf("%s/indexes/%s/search", r.cfg.MailiSearch.ServerURL, index)
|
||||||
return r.doRequest(http.MethodPost, url, body)
|
return r.doRequest(http.MethodPost, url, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SearchRepo) GetIndexSettings(index string) (*SearchProxyResponse, error) {
|
func (r *SearchRepo) GetIndexSettings(index string) (*SearchProxyResponse, error) {
|
||||||
url := fmt.Sprintf("%s/indexes/%s/settings", r.cfg.MeiliSearch.ServerURL, index)
|
url := fmt.Sprintf("%s/indexes/%s/settings", r.cfg.MailiSearch.ServerURL, index)
|
||||||
return r.doRequest(http.MethodGet, url, nil)
|
return r.doRequest(http.MethodGet, url, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,8 +55,8 @@ func (r *SearchRepo) doRequest(method, url string, body []byte) (*SearchProxyRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
if r.cfg.MeiliSearch.ApiKey != "" {
|
if r.cfg.MailiSearch.ApiKey != "" {
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", r.cfg.MeiliSearch.ApiKey))
|
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", r.cfg.MailiSearch.ApiKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
package storageRepo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"mime/multipart"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
|
||||||
"github.com/gofiber/fiber/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UIStorageRepo interface {
|
|
||||||
EntryInfo(abs_path string) (os.FileInfo, error)
|
|
||||||
ListContent(abs_path string) (*[]model.EntryInList, error)
|
|
||||||
Move(src_abs_path string, dest_abs_path string) error
|
|
||||||
Copy(src_abs_path string, dest_abs_path string) error
|
|
||||||
OpenFile(abs_path string) (*os.File, error)
|
|
||||||
UploadFile(c fiber.Ctx, abs_path string, f *multipart.FileHeader) error
|
|
||||||
CreateFolder(abs_path string) error
|
|
||||||
DeleteFile(abs_path string) error
|
|
||||||
DeleteFolder(abs_path string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type StorageRepo struct{}
|
|
||||||
|
|
||||||
func New() UIStorageRepo {
|
|
||||||
return &StorageRepo{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) EntryInfo(abs_path string) (os.FileInfo, error) {
|
|
||||||
return os.Stat(abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) ListContent(abs_path string) (*[]model.EntryInList, error) {
|
|
||||||
entries, err := os.ReadDir(abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var entries_in_list []model.EntryInList
|
|
||||||
|
|
||||||
for _, entry := range entries {
|
|
||||||
var next_entry_in_list model.EntryInList
|
|
||||||
next_entry_in_list.Name = entry.Name()
|
|
||||||
next_entry_in_list.IsFolder = entry.IsDir()
|
|
||||||
|
|
||||||
entries_in_list = append(entries_in_list, next_entry_in_list)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &entries_in_list, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) Move(src_abs_path string, dest_abs_path string) error {
|
|
||||||
return os.Rename(src_abs_path, dest_abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) Copy(src_abs_path string, dest_abs_path string) error {
|
|
||||||
in, err := os.Open(src_abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer in.Close()
|
|
||||||
|
|
||||||
info, err := in.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := os.OpenFile(dest_abs_path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, info.Mode())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer out.Close()
|
|
||||||
|
|
||||||
if _, err := io.Copy(out, in); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return out.Sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) OpenFile(abs_path string) (*os.File, error) {
|
|
||||||
return os.Open(abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) UploadFile(c fiber.Ctx, abs_path string, f *multipart.FileHeader) error {
|
|
||||||
return c.SaveFile(f, abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) CreateFolder(abs_path string) error {
|
|
||||||
return os.Mkdir(abs_path, 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) DeleteFile(abs_path string) error {
|
|
||||||
return os.Remove(abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StorageRepo) DeleteFolder(abs_path string) error {
|
|
||||||
return os.RemoveAll(abs_path)
|
|
||||||
}
|
|
||||||
@@ -83,6 +83,15 @@ func (s *AuthService) Login(req *model.LoginRequest) (*model.AuthResponse, strin
|
|||||||
// Update last login time
|
// Update last login time
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
user.LastLoginAt = &now
|
user.LastLoginAt = &now
|
||||||
|
|
||||||
|
if req.LangID != nil {
|
||||||
|
_, err := s.GetLangISOCode(*req.LangID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", responseErrors.ErrBadLangID
|
||||||
|
}
|
||||||
|
user.LangID = *req.LangID
|
||||||
|
}
|
||||||
|
|
||||||
s.db.Save(&user)
|
s.db.Save(&user)
|
||||||
|
|
||||||
// Generate access token (JWT)
|
// Generate access token (JWT)
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ type MeiliService struct {
|
|||||||
func New() *MeiliService {
|
func New() *MeiliService {
|
||||||
|
|
||||||
client := meilisearch.New(
|
client := meilisearch.New(
|
||||||
config.Get().MeiliSearch.ServerURL,
|
config.Get().MailiSearch.ServerURL,
|
||||||
meilisearch.WithAPIKey(config.Get().MeiliSearch.ApiKey),
|
meilisearch.WithAPIKey(config.Get().MailiSearch.ApiKey),
|
||||||
)
|
)
|
||||||
|
|
||||||
return &MeiliService{
|
return &MeiliService{
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
package storageService
|
|
||||||
|
|
||||||
import (
|
|
||||||
"mime/multipart"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/repos/storageRepo"
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
|
||||||
"github.com/gofiber/fiber/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StorageService struct {
|
|
||||||
storageRepo storageRepo.UIStorageRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *StorageService {
|
|
||||||
return &StorageService{
|
|
||||||
storageRepo: storageRepo.New(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) ListContent(abs_path string) (*[]model.EntryInList, error) {
|
|
||||||
info, err := s.storageRepo.EntryInfo(abs_path)
|
|
||||||
if err != nil || !info.IsDir() {
|
|
||||||
return nil, responseErrors.ErrFolderDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
entries_in_list, err := s.storageRepo.ListContent(abs_path)
|
|
||||||
return entries_in_list, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) DownloadFilePrep(abs_path string) (*os.File, string, int64, error) {
|
|
||||||
info, err := s.storageRepo.EntryInfo(abs_path)
|
|
||||||
if err != nil || info.IsDir() {
|
|
||||||
return nil, "", 0, responseErrors.ErrFileDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := s.storageRepo.OpenFile(abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return f, filepath.Base(abs_path), info.Size(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) Move(src_abs_path string, dest_abs_path string) error {
|
|
||||||
_, err := s.storageRepo.EntryInfo(src_abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return responseErrors.ErrFileDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = s.storageRepo.EntryInfo(dest_abs_path)
|
|
||||||
if err == nil {
|
|
||||||
return responseErrors.ErrNameTaken
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
return s.storageRepo.Move(src_abs_path, dest_abs_path)
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (s *StorageService) Copy(src_abs_path string, dest_abs_path string) error {
|
|
||||||
_, err := s.storageRepo.EntryInfo(src_abs_path)
|
|
||||||
if err != nil {
|
|
||||||
return responseErrors.ErrFileDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = s.storageRepo.EntryInfo(dest_abs_path)
|
|
||||||
if err == nil {
|
|
||||||
return responseErrors.ErrNameTaken
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
return s.storageRepo.Copy(src_abs_path, dest_abs_path)
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) UploadFile(c fiber.Ctx, abs_path string, f *multipart.FileHeader) error {
|
|
||||||
info, err := s.storageRepo.EntryInfo(abs_path)
|
|
||||||
if err != nil || !info.IsDir() {
|
|
||||||
return responseErrors.ErrFolderDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
name := f.Filename
|
|
||||||
if name == "" || name == "." || name == ".." || filepath.Base(name) != name {
|
|
||||||
return responseErrors.ErrBadAttribute
|
|
||||||
}
|
|
||||||
abs_file_path, err := s.AbsPath(abs_path, name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if abs_file_path == abs_path {
|
|
||||||
return responseErrors.ErrBadAttribute
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err = s.storageRepo.EntryInfo(abs_file_path)
|
|
||||||
if err == nil {
|
|
||||||
return responseErrors.ErrNameTaken
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
return s.storageRepo.UploadFile(c, abs_file_path, f)
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) CreateFolder(abs_path string, name string) error {
|
|
||||||
info, err := s.storageRepo.EntryInfo(abs_path)
|
|
||||||
if err != nil || !info.IsDir() {
|
|
||||||
return responseErrors.ErrFolderDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "" || name == "." || name == ".." || filepath.Base(name) != name {
|
|
||||||
return responseErrors.ErrBadAttribute
|
|
||||||
}
|
|
||||||
abs_folder_path, err := s.AbsPath(abs_path, name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if abs_folder_path == abs_path {
|
|
||||||
return responseErrors.ErrBadAttribute
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err = s.storageRepo.EntryInfo(abs_folder_path)
|
|
||||||
if err == nil {
|
|
||||||
return responseErrors.ErrNameTaken
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
return s.storageRepo.CreateFolder(abs_folder_path)
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) DeleteFile(abs_path string) error {
|
|
||||||
info, err := s.storageRepo.EntryInfo(abs_path)
|
|
||||||
if err != nil || info.IsDir() {
|
|
||||||
return responseErrors.ErrFileDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.storageRepo.DeleteFile(abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StorageService) DeleteFolder(abs_path string) error {
|
|
||||||
info, err := s.storageRepo.EntryInfo(abs_path)
|
|
||||||
if err != nil || !info.IsDir() {
|
|
||||||
return responseErrors.ErrFolderDoesNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.storageRepo.DeleteFolder(abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AbsPath extracts an absolute path and validates it
|
|
||||||
func (s *StorageService) AbsPath(root string, relativePath string) (string, error) {
|
|
||||||
clean_name := filepath.Clean(relativePath)
|
|
||||||
full_path := filepath.Join(root, clean_name)
|
|
||||||
|
|
||||||
if full_path != root && !strings.HasPrefix(full_path, root+string(os.PathSeparator)) {
|
|
||||||
return "", responseErrors.ErrAccessDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
return full_path, nil
|
|
||||||
}
|
|
||||||
@@ -11,5 +11,4 @@ const CATEGORY_TREE_ROOT_ID = 2
|
|||||||
const MAX_AMOUNT_OF_CARTS_PER_USER = 10
|
const MAX_AMOUNT_OF_CARTS_PER_USER = 10
|
||||||
const DEFAULT_NEW_CART_NAME = "new cart"
|
const DEFAULT_NEW_CART_NAME = "new cart"
|
||||||
|
|
||||||
const USER_LOCALES_NAME = "user"
|
const USER_LOCALE = "user"
|
||||||
const USER_LOCALES_ID = "userID"
|
|
||||||
|
|||||||
23
app/utils/localeExtractor/localeExtractor.go
Normal file
23
app/utils/localeExtractor/localeExtractor.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package localeExtractor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
|
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetLangID(c fiber.Ctx) (uint, bool) {
|
||||||
|
user_locale, ok := c.Locals(constdata.USER_LOCALE).(*model.UserLocale)
|
||||||
|
if !ok || user_locale.OriginalUser == nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return user_locale.OriginalUser.LangID, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserID(c fiber.Ctx) (uint, bool) {
|
||||||
|
user_locale, ok := c.Locals(constdata.USER_LOCALE).(*model.UserLocale)
|
||||||
|
if !ok || user_locale.User == nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return user_locale.User.ID, true
|
||||||
|
}
|
||||||
@@ -59,13 +59,6 @@ var (
|
|||||||
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
||||||
ErrUserHasNoSuchCart = errors.New("user does not have cart with given id")
|
ErrUserHasNoSuchCart = errors.New("user does not have cart with given id")
|
||||||
ErrProductOrItsVariationDoesNotExist = errors.New("product or its variation with given ids does not exist")
|
ErrProductOrItsVariationDoesNotExist = errors.New("product or its variation with given ids does not exist")
|
||||||
|
|
||||||
// Typed errors for storage
|
|
||||||
ErrAccessDenied = errors.New("access denied!")
|
|
||||||
ErrFolderDoesNotExist = errors.New("folder does not exist")
|
|
||||||
ErrFileDoesNotExist = errors.New("file does not exist")
|
|
||||||
ErrNameTaken = errors.New("name taken")
|
|
||||||
ErrMissingFileFieldDocument = errors.New("missing file field 'document'")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error represents an error with HTTP status code
|
// Error represents an error with HTTP status code
|
||||||
@@ -169,17 +162,6 @@ func GetErrorCode(c fiber.Ctx, err error) string {
|
|||||||
case errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
case errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||||
return i18n.T_(c, "error.product_or_its_variation_does_not_exist")
|
return i18n.T_(c, "error.product_or_its_variation_does_not_exist")
|
||||||
|
|
||||||
case errors.Is(err, ErrAccessDenied):
|
|
||||||
return i18n.T_(c, "error.access_denied")
|
|
||||||
case errors.Is(err, ErrFolderDoesNotExist):
|
|
||||||
return i18n.T_(c, "error.folder_does_not_exist")
|
|
||||||
case errors.Is(err, ErrFileDoesNotExist):
|
|
||||||
return i18n.T_(c, "error.file_does_not_exist")
|
|
||||||
case errors.Is(err, ErrNameTaken):
|
|
||||||
return i18n.T_(c, "error.name_taken")
|
|
||||||
case errors.Is(err, ErrMissingFileFieldDocument):
|
|
||||||
return i18n.T_(c, "error.missing_file_field_document")
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return i18n.T_(c, "error.err_internal_server_error")
|
return i18n.T_(c, "error.err_internal_server_error")
|
||||||
}
|
}
|
||||||
@@ -221,12 +203,7 @@ func GetErrorStatus(err error) int {
|
|||||||
errors.Is(err, ErrRootNeverReached),
|
errors.Is(err, ErrRootNeverReached),
|
||||||
errors.Is(err, ErrMaxAmtOfCartsReached),
|
errors.Is(err, ErrMaxAmtOfCartsReached),
|
||||||
errors.Is(err, ErrUserHasNoSuchCart),
|
errors.Is(err, ErrUserHasNoSuchCart),
|
||||||
errors.Is(err, ErrProductOrItsVariationDoesNotExist),
|
errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||||
errors.Is(err, ErrAccessDenied),
|
|
||||||
errors.Is(err, ErrFolderDoesNotExist),
|
|
||||||
errors.Is(err, ErrFileDoesNotExist),
|
|
||||||
errors.Is(err, ErrNameTaken),
|
|
||||||
errors.Is(err, ErrMissingFileFieldDocument):
|
|
||||||
return fiber.StatusBadRequest
|
return fiber.StatusBadRequest
|
||||||
case errors.Is(err, ErrEmailExists):
|
case errors.Is(err, ErrEmailExists):
|
||||||
return fiber.StatusConflict
|
return fiber.StatusConflict
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: add-new-cart
|
name: add-new-cart
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 11
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: add-product-to-cart (1)
|
name: add-product-to-cart (1)
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 16
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: add-product-to-cart
|
name: add-product-to-cart
|
||||||
type: http
|
type: http
|
||||||
seq: 14
|
seq: 15
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: change-cart-name
|
name: change-cart-name
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 12
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
info:
|
info:
|
||||||
name: create-index
|
name: create-index
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 7
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/search/create-index
|
url: http://localhost:3000/api/v1/restricted/meili-search/create-index
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: get-breadcrumb
|
name: get-breadcrumb
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 18
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: get-category-tree
|
name: get-category-tree
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 5
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: get-indexes
|
name: get-indexes
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 9
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: get-product-description
|
name: get-product-description
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 17
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: get_countries
|
name: get_countries
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 4
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -5,7 +5,7 @@ info:
|
|||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/list/list-products?p=1&elems=10
|
url: http://localhost:3000/api/v1/restricted/list/list-products?p=1&elems=10&target_user_id=2
|
||||||
params:
|
params:
|
||||||
- name: p
|
- name: p
|
||||||
value: "1"
|
value: "1"
|
||||||
@@ -13,6 +13,9 @@ http:
|
|||||||
- name: elems
|
- name: elems
|
||||||
value: "10"
|
value: "10"
|
||||||
type: query
|
type: query
|
||||||
|
- name: target_user_id
|
||||||
|
value: "2"
|
||||||
|
type: query
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
encodeUrl: true
|
encodeUrl: true
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: list-users
|
name: list-users
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 2
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: remove-index
|
name: remove-index
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 8
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: DELETE
|
method: DELETE
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: retrieve-cart
|
name: retrieve-cart
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 14
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: retrieve-carts-info
|
name: retrieve-carts-info
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 13
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
info:
|
|
||||||
name: save-product-description
|
|
||||||
type: http
|
|
||||||
seq: 19
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: POST
|
|
||||||
url: http://localhost:3000/api/v1/restricted/product-translation/save-product-description?productID=1&productLangID=3
|
|
||||||
params:
|
|
||||||
- name: productID
|
|
||||||
value: "1"
|
|
||||||
type: query
|
|
||||||
- name: productLangID
|
|
||||||
value: "3"
|
|
||||||
type: query
|
|
||||||
body:
|
|
||||||
type: json
|
|
||||||
data: |-
|
|
||||||
{
|
|
||||||
"description": "<p>Der Einsatz von Rehabilitationsrollen in verschiedenen Übungen und Behandlungen wirkt sich positiv auf die Reduzierung von Verletzungen und die Genesungschancen aus. Sie werden in der Rehabilitation, bei Korrekturgymnastik sowie in der traditionellen und Sportmassage eingesetzt, da sie ideal zum Anheben und Spreizen von Gliedmaßen geeignet sind. Zudem können sie zur Unterstützung von Knien, Füßen, Armen und Schultern verwendet werden. Auch für Kinder sind Rehabilitationsrollen empfehlenswert; ihre spielerische Anwendung fördert die Entwicklung der Grobmotorik.</p><p> Dank der großen Auswahl an Farben und Größen lässt sich ein Übungsset zusammenstellen, das in jeder Physiotherapiepraxis, jedem Massageraum, jeder Schule oder jedem Kindergarten benötigt wird.</p><p> Die Rehabilitationsrolle ist ein Medizinprodukt, das den grundlegenden Anforderungen an Medizinprodukte und den Bestimmungen des Medizinproduktegesetzes entspricht, im Register für Medizinprodukte des Amtes für die Registrierung von Arzneimitteln, Medizinprodukten und Biozidprodukten eingetragen ist, mit der Konformitätserklärung des Herstellers versehen ist und das CE-Zeichen trägt. </p><p></p><p><img src=\"https://www.naluconcept.com/img/cms/Logotypy/images.jpg\" alt=\"Medizinprodukt\" style=\"margin-left:auto;margin-right:auto;\" width=\"253\" height=\"86\" /></p><h4> <strong>Empfohlene Verwendung:</strong></h4><ul style=\"list-style-type:circle;\"><li> in der Rehabilitation</li><li> während Massagen (traditionell, Sport)</li><li> in der Korrekturgymnastik (insbesondere für Kinder)</li><li> zur Linderung von Verletzungen einzelner Körperteile</li><li> Zur Unterstützung von: Knien, Knöcheln, Kopf des Patienten</li><li> bei Übungen zur Entwicklung der motorischen Fähigkeiten von Kindern</li><li> in Schönheitssalons</li><li> in Kinderspielzimmern</li></ul><p></p><h4> <strong>Materialspezifikationen:</strong></h4><p> <strong>Abdeckung:</strong> PVC-beschichtetes Material, das für medizinische Geräte vorgesehen ist und daher sehr leicht zu reinigen und zu desinfizieren ist:</p><ul style=\"list-style-type:circle;\"><li> Material gemäß REACH-Verordnung, zertifiziert mit dem STANDARD 100 Zertifikat von OEKO-TEX®.</li><li> Enthält keine Phthalate</li><li> feuerfest</li><li> resistent gegenüber physiologischen Flüssigkeiten (Blut, Urin, Schweiß) und Alkohol</li><li> UV-beständig, daher auch für den Einsatz im Freien geeignet.</li><li> kratzfest</li><li> ölbeständig </li></ul><p><img src=\"https://www.naluconcept.com/img/cms/Logotypy/reach.jpg\" alt=\"ERREICHEN\" width=\"115\" height=\"115\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/oeko-tex.jpg\" alt=\"Öko-Tex Standard 100 Zertifikat\" width=\"116\" height=\"114\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/phthalate-free.jpg\" alt=\"Enthält keine Phthalate\" width=\"112\" height=\"111\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/fireresistant.jpg\" alt=\"Feuerfest\" width=\"114\" height=\"113\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/odporny-na-alkohol.jpg\" alt=\"Alkoholbeständig\" width=\"114\" height=\"114\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/odporny-na-uv.jpg\" alt=\"UV-beständig\" width=\"117\" height=\"116\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/outdoor.jpg\" alt=\"Für den Einsatz im Freien konzipiert\" width=\"116\" height=\"116\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/odporny-na-zadrapania.jpg\" alt=\"Kratzfest\" width=\"97\" height=\"96\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/olejoodporny.jpg\" alt=\"Ölbeständig\" width=\"99\" height=\"98\" /></p><p> <strong>Füllung:</strong> mittelharter Polyurethanschaum mit erhöhter Verformungsbeständigkeit:</p><ul style=\"list-style-type:circle;\"><li> besitzt ein Hygienezertifikat, ausgestellt vom Institut für Maritime und Tropenmedizin in Gdynia</li><li> zertifiziert mit dem STANDARD 100 by OEKO-TEX® Zertifikat – Produktklasse I, ausgestellt vom Textilforschungsinstitut in Łódź</li><li> Hergestellt aus hochwertigen Rohstoffen, die die Ozonschicht nicht schädigen. </li></ul><p><img src=\"https://www.naluconcept.com/img/cms/Logotypy/oeko-tex.jpg\" alt=\"Öko-Tex Standard 100 Zertifikat\" width=\"95\" height=\"95\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/Logo_GUMed_kolor-180x180.jpg\" alt=\"Hygienezertifikat\" width=\"94\" height=\"94\" /><img src=\"https://www.naluconcept.com/img/cms/Logotypy/atest_higieniczny_kolor.jpg\" alt=\"Hygienezertifikat\" width=\"79\" height=\"94\" /></p><p></p><p></p>"
|
|
||||||
}
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
info:
|
info:
|
||||||
name: search
|
name: search
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 10
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/search/search?query=w&limit=4&id_category=0&price_lower_bound=60.0&price_upper_bound=70.0
|
url: http://localhost:3000/api/v1/restricted/meili-search/search?query=w&limit=4&id_category=0&price_lower_bound=60.0&price_upper_bound=70.0
|
||||||
params:
|
params:
|
||||||
- name: query
|
- name: query
|
||||||
value: w
|
value: w
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
info:
|
info:
|
||||||
name: test
|
name: test
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 6
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/search/test
|
url: http://localhost:3000/api/v1/restricted/meili-search/test
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
info:
|
|
||||||
name: translate-product-description
|
|
||||||
type: http
|
|
||||||
seq: 21
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/product-translation/translate-product-description?productID=51&productFromLangID=1&productToLangID=3&model=Google
|
|
||||||
params:
|
|
||||||
- name: productID
|
|
||||||
value: "51"
|
|
||||||
type: query
|
|
||||||
- name: productFromLangID
|
|
||||||
value: "1"
|
|
||||||
type: query
|
|
||||||
- name: productToLangID
|
|
||||||
value: "3"
|
|
||||||
type: query
|
|
||||||
- name: model
|
|
||||||
value: Google
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: update-choice
|
name: update-choice
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 3
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: POST
|
method: POST
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: auth
|
|
||||||
type: folder
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: carts
|
|
||||||
type: folder
|
|
||||||
seq: 7
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: langs-and-countries
|
|
||||||
type: folder
|
|
||||||
seq: 4
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: list
|
|
||||||
type: folder
|
|
||||||
seq: 3
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: menu
|
|
||||||
type: folder
|
|
||||||
seq: 5
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: product-translation
|
|
||||||
type: folder
|
|
||||||
seq: 2
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,28 +0,0 @@
|
|||||||
info:
|
|
||||||
name: translate-product-description
|
|
||||||
type: http
|
|
||||||
seq: 24
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/product-translation/translate-product-description?productID=51&productFromLangID=2&productToLangID=3&model=Google
|
|
||||||
params:
|
|
||||||
- name: productID
|
|
||||||
value: "51"
|
|
||||||
type: query
|
|
||||||
- name: productFromLangID
|
|
||||||
value: "2"
|
|
||||||
type: query
|
|
||||||
- name: productToLangID
|
|
||||||
value: "3"
|
|
||||||
type: query
|
|
||||||
- name: model
|
|
||||||
value: Google
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: search
|
|
||||||
type: folder
|
|
||||||
seq: 6
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: copy
|
|
||||||
type: http
|
|
||||||
seq: 7
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/copy/folder1/test.txt?dest_path=/folder/a.txt
|
|
||||||
params:
|
|
||||||
- name: dest_path
|
|
||||||
value: /folder/a.txt
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: create-folder
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/create-folder?name=folder
|
|
||||||
params:
|
|
||||||
- name: name
|
|
||||||
value: folder
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
info:
|
|
||||||
name: delete-file
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: DELETE
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/delete-file/folder1/TODO.txt
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
info:
|
|
||||||
name: delete-folder
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: DELETE
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/delete-folder/folder/
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
info:
|
|
||||||
name: download-file
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/download-file/folder1/test.xlsx
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: storage
|
|
||||||
type: folder
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
info:
|
|
||||||
name: list-content
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/list-content/folder1
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: move
|
|
||||||
type: http
|
|
||||||
seq: 8
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/move/folder?dest_path=/folder1/test.txt
|
|
||||||
params:
|
|
||||||
- name: dest_path
|
|
||||||
value: /folder1/test.txt
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
info:
|
|
||||||
name: upload-file
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: POST
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/upload-file/folder1/
|
|
||||||
body:
|
|
||||||
type: multipart-form
|
|
||||||
data:
|
|
||||||
- name: document
|
|
||||||
type: file
|
|
||||||
value:
|
|
||||||
- /home/daniel/TODO.txt
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
This is a test.
|
|
||||||
Reference in New Issue
Block a user