Compare commits
1 Commits
9c7eb5ee4e
...
add_image_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7533a8deb |
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
|
||||||
|
|||||||
@@ -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,146 +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.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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.Query("path"))
|
|
||||||
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.Query("path"))
|
|
||||||
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))
|
|
||||||
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.Query("path"))
|
|
||||||
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.Query("path"))
|
|
||||||
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.Query("path"))
|
|
||||||
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.Query("path"))
|
|
||||||
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)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type EntryInList struct {
|
|
||||||
Name string
|
|
||||||
IsFolder bool
|
|
||||||
}
|
|
||||||
@@ -18,8 +18,9 @@ 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"`
|
||||||
|
|
||||||
|
ImageLink string `gorm:"column:image_link" json:"image_link"`
|
||||||
ExistsInDatabase bool `gorm:"-" json:"exists_in_database"`
|
ExistsInDatabase bool `gorm:"-" json:"exists_in_database"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,68 +0,0 @@
|
|||||||
package storageRepo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"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)
|
|
||||||
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) 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)
|
|
||||||
}
|
|
||||||
@@ -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,132 +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) 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
|
|
||||||
}
|
|
||||||
@@ -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: 14
|
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: 19
|
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: 18
|
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: 15
|
seq: 12
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
info:
|
|
||||||
name: create-folder
|
|
||||||
type: http
|
|
||||||
seq: 24
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/create-folder?path=&name=folder
|
|
||||||
params:
|
|
||||||
- name: path
|
|
||||||
value: ""
|
|
||||||
type: query
|
|
||||||
- name: name
|
|
||||||
value: folder
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: create-index
|
name: create-index
|
||||||
type: http
|
type: http
|
||||||
seq: 10
|
seq: 7
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: delete-file
|
|
||||||
type: http
|
|
||||||
seq: 25
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: DELETE
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/delete-file?path=/folder/test.txt
|
|
||||||
params:
|
|
||||||
- name: path
|
|
||||||
value: /folder/test.txt
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: delete-folder
|
|
||||||
type: http
|
|
||||||
seq: 26
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: DELETE
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/delete-folder?path=/folder/
|
|
||||||
params:
|
|
||||||
- name: path
|
|
||||||
value: /folder/
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: download-file
|
|
||||||
type: http
|
|
||||||
seq: 22
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/download-file?path=/folder1/test.txt
|
|
||||||
params:
|
|
||||||
- name: path
|
|
||||||
value: /folder1/test.txt
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: get-breadcrumb
|
name: get-breadcrumb
|
||||||
type: http
|
type: http
|
||||||
seq: 20
|
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: 8
|
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: 12
|
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: 7
|
seq: 4
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
info:
|
|
||||||
name: list-content
|
|
||||||
type: http
|
|
||||||
seq: 21
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/list-content?path=/folder1
|
|
||||||
params:
|
|
||||||
- name: path
|
|
||||||
value: /folder1
|
|
||||||
type: query
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: list-products
|
name: list-products
|
||||||
type: http
|
type: http
|
||||||
seq: 4
|
seq: 1
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: list-users
|
name: list-users
|
||||||
type: http
|
type: http
|
||||||
seq: 5
|
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: 11
|
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: 17
|
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: 16
|
seq: 13
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: search
|
name: search
|
||||||
type: http
|
type: http
|
||||||
seq: 13
|
seq: 10
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: test
|
name: test
|
||||||
type: http
|
type: http
|
||||||
seq: 9
|
seq: 6
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
info:
|
|
||||||
name: translate-product-description
|
|
||||||
type: http
|
|
||||||
seq: 2
|
|
||||||
|
|
||||||
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 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: update-choice
|
name: update-choice
|
||||||
type: http
|
type: http
|
||||||
seq: 6
|
seq: 3
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: POST
|
method: POST
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
info:
|
|
||||||
name: upload-file
|
|
||||||
type: http
|
|
||||||
seq: 23
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: POST
|
|
||||||
url: http://localhost:3000/api/v1/restricted/storage/upload-file?path=folder/
|
|
||||||
params:
|
|
||||||
- name: path
|
|
||||||
value: folder/
|
|
||||||
type: query
|
|
||||||
body:
|
|
||||||
type: multipart-form
|
|
||||||
data:
|
|
||||||
- name: document
|
|
||||||
type: file
|
|
||||||
value:
|
|
||||||
- /home/daniel/coding/work/b2b/storage/folder1/test.txt
|
|
||||||
auth: inherit
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
This is a test.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
This is a test.
|
|
||||||
Reference in New Issue
Block a user