diff --git a/app/app.go b/app/app.go index 2bc3978..b881853 100644 --- a/app/app.go +++ b/app/app.go @@ -1,243 +1,243 @@ package app -import ( - "context" - "errors" - "fmt" - "github.com/go-redis/redis/v8" - "heruvym/dal/minio" - "heruvym/dal/mongo" - "heruvym/internal/utils/middleware" - "heruvym/router" - "heruvym/service" - "heruvym/tools" - "net/http" - "time" - - "github.com/skeris/appInit" - tb "gopkg.in/tucnak/telebot.v2" - - "github.com/themakers/hlog" - "go.uber.org/zap" -) - -type App struct { - err chan error - logger *zap.Logger -} - -const ( - ENV = "env" - DEFAULT = "default" -) - -type Options struct { - MongoURI string `env:"BB_MONGO_URI" default:"mongodb://localhost:27017"` - NumberPortLocal string `env:"BB_PORT" default:"1488"` - AccountAddress string `env:"BB_AccountAddress" default:":8931"` - LoggerDevMode bool `env:"BB_IS_PROD" default:"false"` - MinioEndpoint string `env:"BB_MINIO_EP" default:"minio:9001"` - MinioAccessKey string `env:"BB_MINIO_AK" default:"minio"` - MinioSecretKey string `env:"BB_MINIO_SK" default:"miniostorage"` - MinioRegion string `env:"S3_REGION" default:""` - MinioToken string `env:"BB_MINIO_TOKEN" default:""` - MongoDbTable string `env:"DATABASE_TABLE" default:"profile"` - MongoCollections string `env:"COLLECTION_NAME" default:"profile,role"` - TgToken string `env:"TELEGRAM_TOKEN" default:"5851043588:AAGXhigZAaNV1--n-jfS8eBgM7iZ2IDm668"` - RedisHost string `env:"REDIS_HOST" default:"localhost:6379"` - RedisPassword string `env:"REDIS_PASSWORD" default:""` - RedisDB uint64 `env:"REDIS_DB" default:"0"` - TgChatID uint64 `env:"TELEGRAM_CHAT_ID" default:"1001344671794"` -} - -var ( - errInvalidOptions = errors.New("invalid options") -) - -var _ appInit.CommonApp = (*App)(nil) - -type InfoSvcStarted struct{} -type InfoSvcReady struct{} -type InfoSvcShutdown struct { - Signal string -} -type ErrorStoring struct { - Err error - Uri string -} -type ErrorCanNotServe struct { - Err error -} - -var zapOptions = []zap.Option{ - zap.AddCaller(), - zap.AddCallerSkip(2), - zap.AddStacktrace(zap.ErrorLevel), -} - -func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { - - var ( - err error - zapLogger *zap.Logger - errChan = make(chan error) - options Options - ok bool - ) - if options, ok = opts.(Options); !ok { - return App{}, errInvalidOptions - } - - if options.LoggerDevMode { - zapLogger, err = zap.NewProduction(zapOptions...) - if err != nil { - return nil, err - } - } else { - zapLogger, err = zap.NewDevelopment(zapOptions...) - if err != nil { - return nil, err - } - } - - zapLogger = zapLogger.With( - zap.String("SvcCommit", ver.Commit), - zap.String("SvcVersion", ver.Release), - zap.String("SvcBuildTime", ver.BuildTime), - ) - - logger := hlog.New(zapLogger) - logger.Emit(InfoSvcStarted{}) - - database, err := mongo.New( - ctx, - options.MongoURI, - "support", - logger, - ) - if err != nil { - return nil, err - } - - miniostore, err := minio.New(ctx, logger, options.MinioEndpoint, options.MinioAccessKey, options.MinioSecretKey, options.MinioToken, options.MinioRegion, false) - if err != nil { - fmt.Println(err) - return nil, err - } - - redisClient := redis.NewClient(&redis.Options{ - Addr: options.RedisHost, - Password: options.RedisPassword, - DB: int(options.RedisDB), - }) - - var newBot *tb.Bot - newBot, err = tb.NewBot(tb.Settings{ - Token: options.TgToken, - Verbose: false, - ParseMode: tb.ModeHTML, - Poller: &tb.LongPoller{ - Timeout: time.Second, - }, - }) - if err != nil { - //logger.Emit(json.Token(err)) - return nil, err - } - - heruvym := service.New(miniostore, database, logger, newBot, -int64(options.TgChatID), redisClient) - - mux := router.NewRouter(map[string]http.HandlerFunc{ - "/create": heruvym.CreateTicket, - "/subscribe": tools.SseWrapper(heruvym.GetList), - "/ticket": tools.SseWrapper(heruvym.Subscribe), - "/send": tools.HandlerWrapper(heruvym.PutMessage), - "/requestScreenshot": tools.HandlerWrapper(heruvym.RequestScreenshot), - "/sendFiles": heruvym.PutFile, - "/sendSC": heruvym.PutSC, - "/getTickets": tools.HandlerWrapper(heruvym.GetTickets), - "/getMessages": tools.HandlerWrapper(heruvym.GetMessages), - "/pick": tools.HandlerWrapper(heruvym.Pick), - "/delegate": tools.HandlerWrapper(heruvym.Delegate), - "/vote": tools.HandlerWrapper(heruvym.Vote), - "/close": tools.HandlerWrapper(heruvym.CloseTicket), - "/shown": tools.HandlerWrapper(heruvym.SetShown), - }) - - mw := middleware.NewMiddleware( - logger, - "*", - nil, - ) - - mux.Use( - func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // w.Header().Set("Access-Control-Allow-Origin", r.Header["Origin"][0]) - // w.Header().Set("Access-Control-Allow-Credentials", "true") - // w.Header().Set("Access-Control-Allow-Headers", "content-type") - // w.Header().Set("Access-Control-Expose-Headers", "*") - if r.Method == http.MethodOptions { - return - } - handler.ServeHTTP(w, r) - }) - }, - mw.MiddlewareLogger, - //mw.MiddlewareOriginAccess, - mw.MiddlewareRecovery, - mw.MiddlewareJwt, - mw.MiddlewareGetJwt, - //mw.MiddlewareJwtPlug, - //mw.MiddlewareRoleAccess, - mw.ExtractHostMiddleware, - ) - fmt.Println("mux") - server := &http.Server{ - Handler: mux, - Addr: fmt.Sprintf(":%s", options.NumberPortLocal), - } - - go func() { - defer func() { - if err := server.Shutdown(ctx); err != nil { - errChan <- err - } - }() - - logger.Emit(InfoSvcStarted{}) - tmplKey := "%s.key" - tmplCrt := "%s.crt" - - tmplCrt = fmt.Sprintf(tmplCrt, "prod") - tmplKey = fmt.Sprintf(tmplKey, "prod") - - fmt.Println("ISPROd", options.LoggerDevMode) - if options.LoggerDevMode { - if err := server.ListenAndServeTLS(tmplCrt, tmplKey); err != nil { - logger.Emit(ErrorCanNotServe{ - Err: err, - }) - errChan <- err - } - } else { - fmt.Println("startserver" + options.NumberPortLocal) - if err := server.ListenAndServe(); err != nil { - errChan <- err - } - } - }() - - return &App{ - logger: zapLogger, - err: errChan, - }, nil -} - -func (a App) GetLogger() *zap.Logger { - return a.logger -} - -func (a App) GetErr() chan error { - return a.err -} +//import ( +// "context" +// "errors" +// "fmt" +// "github.com/go-redis/redis/v8" +// "heruvym/dal/minio" +// "heruvym/dal/mongo" +// "heruvym/internal/tools" +// "heruvym/internal/utils/middleware" +// "heruvym/router" +// "heruvym/service" +// "net/http" +// "time" +// +// "github.com/skeris/appInit" +// tb "gopkg.in/tucnak/telebot.v2" +// +// "github.com/themakers/hlog" +// "go.uber.org/zap" +//) +// +//type App struct { +// err chan error +// logger *zap.Logger +//} +// +//const ( +// ENV = "env" +// DEFAULT = "default" +//) +// +//type Options struct { +// MongoURI string `env:"BB_MONGO_URI" default:"mongodb://localhost:27017"` +// NumberPortLocal string `env:"BB_PORT" default:"1488"` +// AccountAddress string `env:"BB_AccountAddress" default:":8931"` +// LoggerDevMode bool `env:"BB_IS_PROD" default:"false"` +// MinioEndpoint string `env:"BB_MINIO_EP" default:"minio:9001"` +// MinioAccessKey string `env:"BB_MINIO_AK" default:"minio"` +// MinioSecretKey string `env:"BB_MINIO_SK" default:"miniostorage"` +// MinioRegion string `env:"S3_REGION" default:""` +// MinioToken string `env:"BB_MINIO_TOKEN" default:""` +// MongoDbTable string `env:"DATABASE_TABLE" default:"profile"` +// MongoCollections string `env:"COLLECTION_NAME" default:"profile,role"` +// TgToken string `env:"TELEGRAM_TOKEN" default:"5851043588:AAGXhigZAaNV1--n-jfS8eBgM7iZ2IDm668"` +// RedisHost string `env:"REDIS_HOST" default:"localhost:6379"` +// RedisPassword string `env:"REDIS_PASSWORD" default:""` +// RedisDB uint64 `env:"REDIS_DB" default:"0"` +// TgChatID uint64 `env:"TELEGRAM_CHAT_ID" default:"1001344671794"` +//} +// +//var ( +// errInvalidOptions = errors.New("invalid options") +//) +// +//var _ appInit.CommonApp = (*App)(nil) +// +//type InfoSvcStarted struct{} +//type InfoSvcReady struct{} +//type InfoSvcShutdown struct { +// Signal string +//} +//type ErrorStoring struct { +// Err error +// Uri string +//} +//type ErrorCanNotServe struct { +// Err error +//} +// +//var zapOptions = []zap.Option{ +// zap.AddCaller(), +// zap.AddCallerSkip(2), +// zap.AddStacktrace(zap.ErrorLevel), +//} +// +//func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { +// +// var ( +// err error +// zapLogger *zap.Logger +// errChan = make(chan error) +// options Options +// ok bool +// ) +// if options, ok = opts.(Options); !ok { +// return App{}, errInvalidOptions +// } +// +// if options.LoggerDevMode { +// zapLogger, err = zap.NewProduction(zapOptions...) +// if err != nil { +// return nil, err +// } +// } else { +// zapLogger, err = zap.NewDevelopment(zapOptions...) +// if err != nil { +// return nil, err +// } +// } +// +// zapLogger = zapLogger.With( +// zap.String("SvcCommit", ver.Commit), +// zap.String("SvcVersion", ver.Release), +// zap.String("SvcBuildTime", ver.BuildTime), +// ) +// +// logger := hlog.New(zapLogger) +// logger.Emit(InfoSvcStarted{}) +// +// database, err := mongo.New( +// ctx, +// options.MongoURI, +// "support", +// logger, +// ) +// if err != nil { +// return nil, err +// } +// +// miniostore, err := minio.New(ctx, logger, options.MinioEndpoint, options.MinioAccessKey, options.MinioSecretKey, options.MinioToken, options.MinioRegion, false) +// if err != nil { +// fmt.Println(err) +// return nil, err +// } +// +// redisClient := redis.NewClient(&redis.Options{ +// Addr: options.RedisHost, +// Password: options.RedisPassword, +// DB: int(options.RedisDB), +// }) +// +// var newBot *tb.Bot +// newBot, err = tb.NewBot(tb.Settings{ +// Token: options.TgToken, +// Verbose: false, +// ParseMode: tb.ModeHTML, +// Poller: &tb.LongPoller{ +// Timeout: time.Second, +// }, +// }) +// if err != nil { +// //logger.Emit(json.Token(err)) +// return nil, err +// } +// +// heruvym := service.New(miniostore, database, logger, newBot, -int64(options.TgChatID), redisClient) +// +// mux := router.NewRouter(map[string]http.HandlerFunc{ +// "/create": heruvym.CreateTicket, +// "/subscribe": tools.SseWrapper(heruvym.GetList), +// "/ticket": tools.SseWrapper(heruvym.Subscribe), +// "/send": tools.HandlerWrapper(heruvym.PutMessage), +// "/requestScreenshot": tools.HandlerWrapper(heruvym.RequestScreenshot), +// "/sendFiles": heruvym.PutFile, +// "/sendSC": heruvym.PutSC, +// "/getTickets": tools.HandlerWrapper(heruvym.GetTickets), +// "/getMessages": tools.HandlerWrapper(heruvym.GetMessages), +// "/pick": tools.HandlerWrapper(heruvym.Pick), +// "/delegate": tools.HandlerWrapper(heruvym.Delegate), +// "/vote": tools.HandlerWrapper(heruvym.Vote), +// "/close": tools.HandlerWrapper(heruvym.CloseTicket), +// "/shown": tools.HandlerWrapper(heruvym.SetShown), +// }) +// +// mw := middleware.NewMiddleware( +// logger, +// "*", +// nil, +// ) +// +// mux.Use( +// func(handler http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// // w.Header().Set("Access-Control-Allow-Origin", r.Header["Origin"][0]) +// // w.Header().Set("Access-Control-Allow-Credentials", "true") +// // w.Header().Set("Access-Control-Allow-Headers", "content-type") +// // w.Header().Set("Access-Control-Expose-Headers", "*") +// if r.Method == http.MethodOptions { +// return +// } +// handler.ServeHTTP(w, r) +// }) +// }, +// mw.MiddlewareLogger, +// //mw.MiddlewareOriginAccess, +// mw.MiddlewareRecovery, +// mw.MiddlewareJwt, +// mw.MiddlewareGetJwt, +// //mw.MiddlewareJwtPlug, +// //mw.MiddlewareRoleAccess, +// mw.ExtractHostMiddleware, +// ) +// fmt.Println("mux") +// server := &http.Server{ +// Handler: mux, +// Addr: fmt.Sprintf(":%s", options.NumberPortLocal), +// } +// +// go func() { +// defer func() { +// if err := server.Shutdown(ctx); err != nil { +// errChan <- err +// } +// }() +// +// logger.Emit(InfoSvcStarted{}) +// tmplKey := "%s.key" +// tmplCrt := "%s.crt" +// +// tmplCrt = fmt.Sprintf(tmplCrt, "prod") +// tmplKey = fmt.Sprintf(tmplKey, "prod") +// +// fmt.Println("ISPROd", options.LoggerDevMode) +// if options.LoggerDevMode { +// if err := server.ListenAndServeTLS(tmplCrt, tmplKey); err != nil { +// logger.Emit(ErrorCanNotServe{ +// Err: err, +// }) +// errChan <- err +// } +// } else { +// fmt.Println("startserver" + options.NumberPortLocal) +// if err := server.ListenAndServe(); err != nil { +// errChan <- err +// } +// } +// }() +// +// return &App{ +// logger: zapLogger, +// err: errChan, +// }, nil +//} +// +//func (a App) GetLogger() *zap.Logger { +// return a.logger +//} +// +//func (a App) GetErr() chan error { +// return a.err +//} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..3a54b90 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "context" + "fmt" + "heruvym/internal/app" + "heruvym/internal/initialize" + "log" + "os" + "os/signal" + "syscall" + "time" +) + +var ( + commit string = os.Getenv("COMMIT") + buildTime string = os.Getenv("BUILD_TIME") + version string = os.Getenv("VERSION") +) + +// $env:COMMIT=$(git rev-parse --short HEAD); $env:BUILD_TIME=$(Get-Date -UFormat "%Y-%m-%dT%H:%M:%SZ"); $env:VERSION=$(git describe --tags); go run cmd/main.go + +func main() { + + ptime, err := time.Parse(time.RFC3339, buildTime) + if err != nil { + fmt.Println("Error parsing build time:") + ptime = time.Now() + } + + config, err := initialize.LoadConfig() + if err != nil { + log.Fatal("Failed loaded config:", err) + } + + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer stop() + + if err = app.Run(ctx, *config, app.Build{ + Commit: commit, + Version: version, + BuildTime: ptime.Unix(), + }); err != nil { + log.Fatal("App exited with error:", err.Error()) + } +} diff --git a/go.mod b/go.mod index efbd921..c1ef414 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,17 @@ module heruvym -go 1.21 +go 1.22.0 toolchain go1.23.1 require ( + github.com/caarlos0/env/v8 v8.0.0 github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/go-playground/validator/v10 v10.13.0 - github.com/gofiber/contrib/fiberzap v1.0.2 + github.com/go-redis/redis/v8 v8.11.5 github.com/gofiber/fiber/v2 v2.51.0 github.com/gorilla/mux v1.8.0 + github.com/joho/godotenv v1.5.1 github.com/minio/minio-go/v7 v7.0.43 - github.com/pkg/errors v0.9.1 github.com/rs/xid v1.4.0 github.com/skeris/appInit v1.0.2 github.com/stretchr/testify v1.8.4 @@ -19,47 +19,26 @@ require ( github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf go.mongodb.org/mongo-driver v1.13.1 go.uber.org/zap v1.27.0 + gopkg.in/telebot.v3 v3.3.8 gopkg.in/tucnak/telebot.v2 v2.5.0 + penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240804072029-436a9f848461 ) require ( - github.com/BurntSushi/toml v0.3.1 // indirect + github.com/ClickHouse/clickhouse-go v1.5.4 // indirect github.com/andybalholm/brotli v1.0.5 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect - github.com/caarlos0/env/v8 v8.0.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/chzyer/logex v1.1.10 // indirect - github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect - github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect - github.com/creack/pty v1.1.9 // indirect + github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/go-playground/assert/v2 v2.2.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/go-cmp v0.5.8 // indirect - github.com/google/gofuzz v1.0.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect - github.com/google/renameio v0.1.0 // indirect github.com/google/uuid v1.4.0 // indirect - github.com/hpcloud/tail v1.0.0 // indirect - github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect - github.com/joho/godotenv v1.5.1 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/kisielk/gotool v1.0.0 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.1.2 // indirect - github.com/kr/pretty v0.3.0 // indirect - github.com/kr/pty v1.1.1 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/leodido/go-urn v1.2.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect @@ -68,20 +47,10 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/montanaflynn/stats v0.6.6 // indirect - github.com/nxadm/tail v1.4.8 // indirect - github.com/onsi/ginkgo v1.16.5 // indirect - github.com/onsi/ginkgo/v2 v2.0.0 // indirect - github.com/onsi/gomega v1.18.1 // indirect - github.com/philhofer/fwd v1.1.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.3 // indirect - github.com/rogpeppe/go-internal v1.6.1 // indirect - github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect - github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect github.com/sirupsen/logrus v1.9.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/tidwall/pretty v1.0.0 // indirect - github.com/tinylib/msgp v1.1.8 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.50.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect @@ -89,30 +58,18 @@ require ( github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect - github.com/yuin/goldmark v1.4.13 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/goleak v1.3.0 // indirect + go.etcd.io/bbolt v1.3.6 // indirect go.uber.org/multierr v1.10.0 // indirect - go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect golang.org/x/crypto v0.7.0 // indirect - golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.8.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.14.0 // indirect - golang.org/x/term v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.6.0 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect + google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f // indirect + google.golang.org/grpc v1.47.0 // indirect google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect - gopkg.in/errgo.v2 v2.1.0 // indirect - gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/telebot.v3 v3.3.8 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.0.1-2020.1.4 // indirect - penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240804072029-436a9f848461 // indirect + penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240827173819-1561c532e463 // indirect + penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240915070307-5111f41445b3 // indirect ) diff --git a/go.sum b/go.sum index 9d7ef99..0ac1a7b 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= +github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -63,7 +65,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -72,13 +73,11 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0= github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -92,6 +91,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= +github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -125,13 +126,11 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -144,28 +143,16 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ= -github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofiber/contrib/fiberzap v1.0.2 h1:EQwhggtszVfIdBeXxN9Xrmld71es34Ufs+ef8VMqZxc= -github.com/gofiber/contrib/fiberzap v1.0.2/go.mod h1:jGO8BHU4gRI9U0JtM6zj2CIhYfgVmW5JxziN8NTgVwE= -github.com/gofiber/fiber/v2 v2.42.0/go.mod h1:3+SGNjqMh5VQH5Vz2Wdi43zTIV16ktlFd3x3R6O1Zlc= -github.com/gofiber/fiber/v2 v2.45.0 h1:p4RpkJT9GAW6parBSbcNFH2ApnAuW3OzaQzbOCoDu+s= -github.com/gofiber/fiber/v2 v2.45.0/go.mod h1:DNl0/c37WLe0g92U6lx1VMQuxGUQY5V7EIaVoEsUffc= +github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ= github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -199,6 +186,7 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -213,13 +201,13 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -238,14 +226,12 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -287,9 +273,9 @@ github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -306,32 +292,26 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.1.2 h1:XhdX4fqAJUA0yj+kUwMavO0hHrSPAecYdYf1ZmxHvak= github.com/klauspost/cpuid/v2 v2.1.2/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= -github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -348,13 +328,11 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -383,24 +361,17 @@ github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v6 github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= -github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -433,16 +404,12 @@ github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= -github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= -github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= -github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= -github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk= -github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -460,7 +427,6 @@ github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+z github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -470,35 +436,25 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfaoLTYvXmdeyUUxsJKdPUVsjSmiA= github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E= github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf h1:TJJm6KcBssmbWzplF5lzixXl1RBAi/ViPs1GaSOkhwo= github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf/go.mod h1:1FsorU3vnXO9xS9SrhUp8fRb/6H/Zfll0rPt1i4GWaA= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= -github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= -github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.44.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= -github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c= -github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= @@ -509,12 +465,13 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.mongodb.org/mongo-driver v1.10.3 h1:XDQEvmh6z1EUsXuIkXE9TaVeqHw6SwS1uf93jFs0HBA= -go.mongodb.org/mongo-driver v1.10.3/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8= +go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -526,22 +483,16 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -554,10 +505,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -596,11 +545,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -624,7 +570,6 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -639,7 +584,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -649,9 +593,6 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -692,7 +633,6 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -704,14 +644,11 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -733,11 +670,11 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -775,20 +712,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -799,7 +728,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -851,11 +779,9 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -866,15 +792,11 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1000,6 +922,8 @@ google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f h1:hJ/Y5SqPXbarffmAsApliUlcvMU+wScNGfyop4bZm8o= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1030,6 +954,8 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1044,19 +970,19 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/telebot.v3 v3.3.8 h1:uVDGjak9l824FN9YARWUHMsiNZnlohAVwUycw21k6t8= gopkg.in/telebot.v3 v3.3.8/go.mod h1:1mlbqcLTVSfK9dx7fdp+Nb5HZsy4LLPtpZTKmwhwtzM= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tucnak/telebot.v2 v2.5.0 h1:i+NynLo443Vp+Zn3Gv9JBjh3Z/PaiKAQwcnhNI7y6Po= gopkg.in/tucnak/telebot.v2 v2.5.0/go.mod h1:BgaIIx50PSRS9pG59JH+geT82cfvoJU/IaI5TJdN3v8= @@ -1067,6 +993,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -1081,6 +1008,12 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240804072029-436a9f848461 h1:Qfgv2eitRRtbM4/THFi1ZopdkurTItYpE/j/IEL1/ws= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240804072029-436a9f848461/go.mod h1:+bPxq2wfW5S1gd+83vZYmHm33AE7nEBfznWS8AM1TKE= +penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240827173819-1561c532e463 h1:Pz86cnhDTWNd+4nICjGtbNnIRjIIGnyOxn5iRx0qVKY= +penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240827173819-1561c532e463/go.mod h1:i7M72RIpkSjcQtHID6KKj9RT/EYZ1rxS6tIPKWa/BSY= +penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387 h1:G+GIhkkvUsM9No2rf2D4kvQ2ExTw9KxlA8vsSnC0ywU= +penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387/go.mod h1:30nezjpGpZuNThbQOCULIfa79RoJ5sray593jhfVP/Q= +penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240915070307-5111f41445b3 h1:ORXNLpt4WerSOPkgDcpXisexEkKHjOA3PJ2ojQOZyyQ= +penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240915070307-5111f41445b3/go.mod h1:30nezjpGpZuNThbQOCULIfa79RoJ5sray593jhfVP/Q= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/internal/app/app.go b/internal/app/app.go index 711840a..6d0eace 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -5,10 +5,11 @@ import ( "errors" "github.com/themakers/hlog" "go.uber.org/zap" - "heruvym/app" "heruvym/internal/initialize" "heruvym/internal/server/http" + "heruvym/internal/utils/middleware" "heruvym/pkg/closer" + "penahub.gitlab.yandexcloud.net/external/trashlog/app" "strconv" "time" ) @@ -61,6 +62,12 @@ func Run(ctx context.Context, cfg initialize.Config, build Build) error { shutdownGroup := closer.NewCloserGroup() + mw := middleware.NewMiddleware( + hlogger, + "*", + nil, + ) + mdb, err := initialize.MongoDB(ctx, cfg) if err != nil { logger.Error("Error initializing MongoDB", zap.Error(err)) @@ -109,7 +116,7 @@ func Run(ctx context.Context, cfg initialize.Config, build Build) error { Logger: logger, Controllers: []http.Controller{controllers.Tickets, controllers.Other}, Hlogger: hlogger, - //JWT: jwtUtil, + MW: mw, }) go func() { diff --git a/internal/controllers/other/other.go b/internal/controllers/other/other.go index 3dcf7a3..4e74c78 100644 --- a/internal/controllers/other/other.go +++ b/internal/controllers/other/other.go @@ -12,9 +12,9 @@ import ( tb "gopkg.in/tucnak/telebot.v2" "heruvym/internal/repository/minio" "heruvym/internal/repository/mongo" + "heruvym/internal/utils/helpers" "heruvym/internal/utils/jwt_adapter" "heruvym/internal/utils/middleware" - "heruvym/utils" "io" "strings" "sync" @@ -117,7 +117,7 @@ func (o *OtherController) PutFile(ctx *fiber.Ctx) error { for _, fileHeaders := range files { for _, fileHeader := range fileHeaders { fileSize := fileHeader.Size - fileType := utils.GetFileType(fileHeader.Filename) + fileType := helpers.GetFileType(fileHeader.Filename) if limit, ok := fileTypeLimits[fileType]; ok { if fileSize > limit { diff --git a/internal/controllers/tickets/route.go b/internal/controllers/tickets/route.go index b557df5..46f3463 100644 --- a/internal/controllers/tickets/route.go +++ b/internal/controllers/tickets/route.go @@ -2,7 +2,7 @@ package tickets import ( "github.com/gofiber/fiber/v2" - "heruvym/tools" + "heruvym/internal/tools" ) func (t *TicketController) Register(router fiber.Router) { diff --git a/internal/controllers/tickets/tickets.go b/internal/controllers/tickets/tickets.go index 4aae7ea..e830f26 100644 --- a/internal/controllers/tickets/tickets.go +++ b/internal/controllers/tickets/tickets.go @@ -12,9 +12,9 @@ import ( our_errors "heruvym/internal/controllers/errors" "heruvym/internal/model" "heruvym/internal/repository/mongo" + "heruvym/internal/tools" "heruvym/internal/utils/jwt_adapter" "heruvym/internal/utils/middleware" - "heruvym/tools" ) type Deps struct { diff --git a/internal/initialize/config.go b/internal/initialize/config.go index 26fe272..4352f0b 100644 --- a/internal/initialize/config.go +++ b/internal/initialize/config.go @@ -7,13 +7,7 @@ import ( ) type Config struct { - //MongoURI string `env:"BB_MONGO_URI" envDefault:"mongodb://localhost:27017"` - MongoHost string `env:"MONGO_HOST" envDefault:"127.0.0.1"` - MongoPort string `env:"MONGO_PORT" envDefault:"27020"` - MongoUser string `env:"MONGO_USER" envDefault:"test"` - MongoPassword string `env:"MONGO_PASSWORD" envDefault:"test"` - MongoDatabase string `env:"MONGO_DB" envDefault:"admin"` - MongoAuth string `env:"MONGO_AUTH" envDefault:"admin"` + MongoURI string `env:"BB_MONGO_URI" envDefault:"mongodb://localhost:27017"` NumberPortLocal string `env:"BB_PORT" envDefault:"1488"` AccountAddress string `env:"BB_AccountAddress" envDefault:":8931"` LoggerDevMode bool `env:"BB_IS_PROD" envDefault:"false"` diff --git a/internal/initialize/mongo.go b/internal/initialize/mongo.go index 76df7b6..f14b189 100644 --- a/internal/initialize/mongo.go +++ b/internal/initialize/mongo.go @@ -2,38 +2,24 @@ package initialize import ( "context" + "fmt" "go.mongodb.org/mongo-driver/mongo" - mdb "penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo" + "go.mongodb.org/mongo-driver/mongo/options" "time" ) func MongoDB(ctx context.Context, cfg Config) (*mongo.Database, error) { - dbConfig := &mdb.Configuration{ - Host: cfg.MongoHost, - Port: cfg.MongoPort, - User: cfg.MongoUser, - Password: cfg.MongoPassword, - DatabaseName: cfg.MongoDatabase, - Auth: cfg.MongoAuth, - } - newCtx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - - mongoDeps := &mdb.ConnectDeps{ - Configuration: dbConfig, - Timeout: 10 * time.Second, - } - - db, err := mdb.Connect(newCtx, mongoDeps) + clientOptions := options.Client().ApplyURI(cfg.MongoURI) + client, err := mongo.Connect(newCtx, clientOptions) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to connect to MongoDB: %w", err) } - - err = db.Client().Ping(newCtx, nil) + err = client.Ping(newCtx, nil) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to ping MongoDB: %w", err) } - + db := client.Database(cfg.MongoDbTable) return db, nil } diff --git a/internal/server/http/http_server.go b/internal/server/http/http_server.go index 202a27c..f5836ee 100644 --- a/internal/server/http/http_server.go +++ b/internal/server/http/http_server.go @@ -13,7 +13,7 @@ type ServerConfig struct { Logger *zap.Logger Controllers []Controller Hlogger hlog.Logger - JWT *middleware.Middleware + MW *middleware.Middleware } type Server struct { @@ -24,6 +24,9 @@ type Server struct { func NewServer(config ServerConfig) *Server { app := fiber.New() + + app.Use(config.MW.ExtractHostMiddleware, config.MW.MiddlewareLogger, config.MW.MiddlewareJwt, config.MW.MiddlewareRecovery, config.MW.MiddlewareGetJwt, config.MW.MiddlewareOriginAccess) + s := &Server{ Logger: config.Logger, Controllers: config.Controllers, diff --git a/tools/tools.go b/internal/tools/tools.go similarity index 54% rename from tools/tools.go rename to internal/tools/tools.go index 05e4ef3..9f0456e 100644 --- a/tools/tools.go +++ b/internal/tools/tools.go @@ -1,9 +1,11 @@ package tools import ( + "bufio" "context" "encoding/json" "fmt" + "github.com/gofiber/fiber/v2" "net/http" "reflect" "time" @@ -13,8 +15,8 @@ type DataEmitter func(ctx context.Context) chan interface{} const ContextURLKey = "url" -func SseWrapper(emitter DataEmitter) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { +func SseWrapper(emitter DataEmitter) fiber.Handler { + return func(ctx *fiber.Ctx) error { defer func() { if v := recover(); v != nil { fmt.Println("sse her err", v) @@ -23,80 +25,56 @@ func SseWrapper(emitter DataEmitter) http.HandlerFunc { // Отправляем header event-stream fmt.Println("SseWrapper") - w.Header().Set("Content-Type", "text/event-stream") - w.Header().Set("Cache-Control", "no-cache") - w.Header().Set("Connection", "keep-alive") + ctx.Set("Content-Type", "text/event-stream") + ctx.Set("Cache-Control", "no-cache") + ctx.Set("Connection", "keep-alive") - flusher, ok := w.(http.Flusher) - if !ok { - fmt.Println("!ok") - http.Error( - w, - "flushing is not allowed", - http.StatusFailedDependency, - ) - return - } - fmt.Println("SseWrapper") - ctx := context.WithValue( - r.Context(), - ContextURLKey, - r.URL.Query().Get("ticket"), - ) - - dE := emitter(ctx) + ctxValue := context.WithValue(ctx.Context(), ContextURLKey, ctx.Query("ticket")) + ctxCancel, cancel := context.WithCancel(ctxValue) + dE := emitter(ctxCancel) if dE == nil { fmt.Println("dE") - http.Error(w, "no token", http.StatusUnauthorized) - return + cancel() + return ctx.Status(fiber.StatusUnauthorized).SendString("no token") } - defer close(dE) - for { - select { - case <-r.Context().Done(): - return - case <-time.After(time.Second * 10): - SSEPing(w) - case m := <-dE: - fmt.Println("datatatata", m) - if m == nil { - continue - } - if err, ok := m.(error); ok { - if _, err := w.Write( - []byte( - fmt.Sprintf( - "data: %s\n\n", - err.Error(), - ), - ), - ); err != nil { - panic(err) + ctx.Status(fiber.StatusOK).Context().SetBodyStreamWriter(func(w *bufio.Writer) { + pingTicker := time.NewTicker(5 * time.Second) + defer pingTicker.Stop() + defer close(dE) + for { + select { + case <-pingTicker.C: + fmt.Fprintf(w, "data: %s\n\n", `{"event": "ping"}`) + if err := w.Flush(); err != nil { + fmt.Println("sse, close connection") + cancel() + return + } + case m := <-dE: + fmt.Println("datatatata", m) + if m == nil { + continue + } + if err, ok := m.(error); ok { + fmt.Fprintf(w, "data: %s\n\n", err.Error()) + if err := w.Flush(); err != nil { + fmt.Println("error flushing err ") + cancel() + return + } + } + fmt.Fprintf(w, "data: %s\n\n", m) + if err := w.Flush(); err != nil { + fmt.Println("error flushing data") + cancel() + return } - - flusher.Flush() } - line, err := json.Marshal(m) - if err != nil { - panic(err) - } - - if _, err := w.Write( - []byte( - fmt.Sprintf( - "data: %s\n\n", - string(line), - ), - ), - ); err != nil { - panic(err) - } - - flusher.Flush() } - } + }) + return nil } } diff --git a/utils/utils.go b/internal/utils/helpers/fileType.go similarity index 95% rename from utils/utils.go rename to internal/utils/helpers/fileType.go index f028daf..1abdb10 100644 --- a/utils/utils.go +++ b/internal/utils/helpers/fileType.go @@ -1,4 +1,4 @@ -package utils +package helpers import ( "path/filepath" diff --git a/service/service.go b/service/service.go index 2a5f101..33d9bbb 100644 --- a/service/service.go +++ b/service/service.go @@ -1,1137 +1,1137 @@ package service -import ( - "context" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "github.com/go-redis/redis/v8" - "heruvym/dal/minio" - "heruvym/dal/mongo" - "heruvym/internal/model" - "heruvym/internal/utils/jwt_adapter" - "heruvym/internal/utils/middleware" - "heruvym/tools" - "heruvym/utils" - "io" - "net/http" - "strings" - "sync" - "time" - - "github.com/rs/xid" - "github.com/themakers/hlog" - tb "gopkg.in/tucnak/telebot.v2" -) - -type Heruvym struct { - logger hlog.Logger - dal *mongo.DAL - bs *minio.BlobStore - - notifier *tb.Bot - tgChatID int64 -} - -func New( - blobs *minio.BlobStore, - dataAccessLayer *mongo.DAL, - log hlog.Logger, - notifier *tb.Bot, - tgChatID int64, redisClient *redis.Client) *Heruvym { - return &Heruvym{ - logger: log.Module("Service"), - dal: dataAccessLayer, - bs: blobs, - notifier: notifier, - tgChatID: tgChatID, - redisClient: redisClient, - } -} - -func (h Heruvym) Register(m *http.ServeMux) *http.ServeMux { - - //"/requestScreenshot": tools.HandlerWrapper(heruvym.RequestScreenshot), ???? - //"/sendFiles": heruvym.PutFile, ???? - //"/sendSC": heruvym.PutSC, ???? - //"/shown": tools.HandlerWrapper(heruvym.SetShown), ???? - - m.HandleFunc("/create", h.CreateTicket) - m.HandleFunc("/subscribe", tools.SseWrapper(h.GetList)) - m.HandleFunc("/ticket", tools.SseWrapper(h.Subscribe)) - m.HandleFunc("/send", tools.HandlerWrapper(h.PutMessage)) - m.HandleFunc("/getTickets", tools.HandlerWrapper(h.GetTickets)) - m.HandleFunc("/getMessages", tools.HandlerWrapper(h.GetMessages)) - m.HandleFunc("/pick", tools.HandlerWrapper(h.Pick)) - m.HandleFunc("/delegate", tools.HandlerWrapper(h.Delegate)) - m.HandleFunc("/vote", tools.HandlerWrapper(h.Vote)) - m.HandleFunc("/close", tools.HandlerWrapper(h.CloseTicket)) - - return m -} - -type CreateTicketReq struct { - Title string `json:"Title"` - Message string `json:"Message"` -} - -type CreateTicketResp struct { - Ticket string `json:"Ticket"` - Sess string `json:"sess"` -} - -func (h *Heruvym) CreateTicket(w http.ResponseWriter, r *http.Request) { - defer func() { - if err := r.Body.Close(); err != nil { - h.logger.Emit(ErrorClose{ - Err: err, - }) - } - }() - - var ( - err error - request CreateTicketReq - ) - - if err := json.NewDecoder(r.Body).Decode(&request); err != nil { - http.Error(w, "Invalid json", http.StatusBadRequest) - return - } - - if request.Title == "" { - http.Error(w, "No Title", http.StatusBadRequest) - return - } - - if request.Message == "" { - http.Error(w, "No Message", http.StatusBadRequest) - return - } - - ctx := r.Context() - - session := jwt_adapter.Get(ctx) - - if session == nil { - http.Error(w, "No session", http.StatusUnauthorized) - return - } - - var ( - ticketID string - tickets []model.Ticket - role = jwt_adapter.GetRole(ctx) - ) - if role == "" { - tickets, _, err = h.dal.GetTickets4Sess(ctx, session.Id) - } - - if err != nil || len(tickets) == 0 { - - ticketID, err = h.dal.CreateTicket( - ctx, - session.Id, - session.Id, - r.Header["Origin"][0], - request.Title, - request.Message, - []string{}, - ) - if err != nil { - http.Error(w, "CannotCreateTicket", http.StatusInternalServerError) - return - } - - if _, err := h.dal.PutMessage(ctx, - request.Message, - session.Id, - session.Id, - ticketID, - []string{}, - ); err != nil { - http.Error(w, "CannotCreateMessage", http.StatusInternalServerError) - return - } - - domain := ctx.Value(middleware.HostKey).(string) - if domain == "" { - fmt.Println("domain is nil err") - } - - go func() { - if session.Id != "" && role != "admin" { - if err == nil && h.notifier != nil { - var userLink, supportLink string - if session.StandardClaims.Issuer != "" { - fmt.Println("MABNAT", domain) - if domain[0] == 's' { - userLink = fmt.Sprintf("https://sadmin.pena/users/%s", session.Id) - supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID) - } else { - userLink = fmt.Sprintf("https://admin.pena/users/%s", session.Id) - supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID) - } - } else { - if domain[0] == 's' { - supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID) - } else { - supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID) - } - userLink = "незарегистрированного пользователя" - } - - message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s", - userLink, domain, supportLink) - - if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil { - fmt.Println("CAN NOT NOTIFY", err) - } - return - } - } - }() - - } else { - ticketID = tickets[0].ID - } - - response, err := json.Marshal(CreateTicketResp{Ticket: ticketID, Sess: session.Id}) - if err != nil { - h.logger.Emit(ErrorMarshal{ - Err: err, - }) - http.Error(w, "CannotMarshalMessage", http.StatusInternalServerError) - return - } - - if _, err := w.Write(response); err != nil { - h.logger.Emit(ErrorMarshal{ - Err: err, - }) - return - } -} - -var _ tools.DataEmitter = (&Heruvym{}).GetList - -func (h *Heruvym) GetList(ctx context.Context) chan interface{} { - fmt.Println("GetList") - defer func() { - if rec := recover(); rec != nil { - fmt.Println(rec) - } - }() - sess := jwt_adapter.Get(ctx) - fmt.Println("sess", sess) - if sess == nil { - return nil - } - - output := make(chan interface{}) - - if sess.Id == "" { - go h.unauthorizedTickets(ctx, sess.Id, output) - } else { - role := jwt_adapter.GetRole(ctx) - - fmt.Println("ALL TICKETS Sess ", sess.Id, role) - if role == "admin" || role == "manager" { - go h.allTickets(ctx, output) - } else { - go h.userTickets(ctx, sess.Id, output) - } - } - - return output -} - -func (h *Heruvym) allTickets(ctx context.Context, output chan interface{}) { - defer func() { - if v := recover(); v != nil { - fmt.Println("AllTicketsRec", v) - } - }() - - //data, count, err := h.dal.YieldTickets(ctx, 20) - // - //if err != nil { - // output <- errors.New("cannot get tickets:" + err.Error()) - // return - //} - // - //if data != nil { - // output <- GetTicketsResp{data, count} - //} - - if err := h.dal.WatchAllTickets(ctx, func(ticket model.Ticket) error { - output <- ticket - return nil - }); err != nil { - output <- errors.New("cannot watch all tickets" + err.Error()) - } -} - -func (h *Heruvym) userTickets(ctx context.Context, userID string, output chan interface{}) { - - defer func() { - if v := recover(); v != nil { - fmt.Println("USERTICKS", v) - } - }() - - data, count, err := h.dal.YieldUserTickets(ctx, userID, 20, 0) - - if err != nil { - output <- errors.New("cannot get tickets:" + err.Error()) - return - } - - if data != nil { - output <- GetTicketsResp{data, count} - } - - if err := h.dal.WatchTickets(ctx, userID, func(ticket model.Ticket) error { - output <- ticket - return nil - }); err != nil { - output <- errors.New("cannot watch tickets") - return - } -} - -func (h *Heruvym) hasNoRole(output chan interface{}) { - output <- errors.New("no role in profile") -} - -func (h *Heruvym) unauthorizedTickets(ctx context.Context, sess string, output chan interface{}) { - //defer close(output) - - tickets, count, err := h.dal.GetTickets4Sess(ctx, sess) - - if err != nil { - output <- errors.New("no tickets for session") - return - } - - if tickets != nil { - output <- GetTicketsResp{tickets, count} - } -} - -type ReqPutMessage struct { - Message string `json:"message"` - TicketID string `json:"ticket"` - Files []string `json:"files"` - Lang string `json:"lang"` -} - -func (h *Heruvym) PutMessage( - ctx context.Context, - request ReqPutMessage, -) (interface{}, int) { - sess := jwt_adapter.Get(ctx) - fmt.Println("PUTMES", sess) - - request.Files = []string{} - - domain := ctx.Value(middleware.HostKey).(string) - if domain == "" { - fmt.Println("domain is nil err") - return errors.New("domain is nil"), http.StatusBadRequest - } - - message, err := h.dal.PutMessage( - ctx, - request.Message, - sess.Id, - sess.Id, - request.TicketID, - []string{}, - ) - fmt.Println("PUTMES00", err) - if err != nil { - fmt.Println("PUTMES1", err) - return errors.New("can not put message"), http.StatusInternalServerError - } - - role := jwt_adapter.GetRole(ctx) - go func() { - if sess.Id != "" && role != "admin" { - if err == nil && h.notifier != nil { - var userLink, supportLink string - if sess.StandardClaims.Issuer != "" { - fmt.Println("MABNAT", domain) - if domain[0] == 's' { - userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id) - supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID) - } else { - userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id) - supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID) - } - } else { - if domain[0] == 's' { - supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID) - } else { - supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID) - } - userLink = "незарегистрированного пользователя" - } - - message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ссылка на чат - %s", - userLink, domain, supportLink) - - if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil { - fmt.Println("CAN NOT NOTIFY", err) - } - return - } - } - }() - - if err := h.dal.UpdateTopMessage(ctx, request.TicketID, message); err != nil { - fmt.Println("PUTMES01", err, request.TicketID, message) - //return errors.New("can not update ticket"), http.StatusInternalServerError - } - - fmt.Println("PUTMES03") - return nil, http.StatusOK -} - -type ReqScreenshot struct { - TicketID string `json:"ticket"` - Lang string `json:"lang"` -} - -func (h *Heruvym) RequestScreenshot( - ctx context.Context, - request ReqScreenshot, -) (interface{}, int) { - sess := jwt_adapter.Get(ctx) - - _, err := h.dal.PutSCRequest( - ctx, - sess.Id, - sess.Id, - request.TicketID, - ) - if err != nil { - return errors.New("can not put message"), http.StatusInternalServerError - } - - return nil, http.StatusOK -} - -var _ tools.DataEmitter = (&Heruvym{}).Subscribe - -func (h *Heruvym) Subscribe(ctx context.Context) chan interface{} { - sess := jwt_adapter.Get(ctx) - fmt.Println("SESS Subsc", sess) - - ticketID := ctx.Value(tools.ContextURLKey).(string) - - output := make(chan interface{}) - if sess.Id == "" { - go func() { - ticket, err := h.dal.GetTicket4Sess(ctx, ticketID, sess.Id) - if err != nil || ticket == nil { - output <- errors.New("no tickets 4 session") - return - } - - /*if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error { - output <- message - fmt.Println("OOOOOOLd") - - //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { - // - // output <- errors.New("cannot show message " + err.Error()) - // return err - //} - - return nil - }); err != nil { - output <- errors.New("cannot read messages " + err.Error()) - }*/ - - if err := h.dal.WatchMessages(ctx, ticketID, - func(message model.Message) error { - output <- message - - //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { - // fmt.Println("3", err) - // output <- errors.New("cannot show watch message " + err.Error()) - // return err - //} - - return nil - }); err != nil { - fmt.Println("4", err) - output <- errors.New("cannot watch messages " + err.Error()) - } - }() - } else { - role := jwt_adapter.GetRole(ctx) - - if role == "admin" || role == "manager" { - go func() { - - if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error { - output <- message - - //if err := h.dal.SetShown(ctx, message.ID, sess.User); err != nil { - // fmt.Println("2", err) - // output <- errors.New("cannot show message " + err.Error()) - // return err - //} - - return nil - }); err != nil { - fmt.Println("1", err) - output <- errors.New("cannot read messages " + err.Error()) - } - - if err := h.dal.WatchMessages(ctx, ticketID, - func(message model.Message) error { - output <- message - - //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { - // fmt.Println("3", err) - // output <- errors.New("cannot show watch message " + err.Error()) - // return err - //} - - return nil - }); err != nil { - fmt.Println("4", err) - output <- errors.New("cannot watch messages " + err.Error()) - } - }() - } else { - go func() { - defer func() { - if v := recover(); v != nil { - fmt.Println("heryvym panic", v) - } - }() - ticket, err := h.dal.GetTicket4User(ctx, ticketID, sess.Id) - if err != nil || ticket == nil { - output <- errors.New("no tickets 4 user") - } - - /*if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error { - output <- message - - //if err := h.dal.SetShown(ctx, message.ID, sess.User); err != nil { - // fmt.Println("2", err) - // output <- errors.New("cannot show message " + err.Error()) - // return err - //} - - return nil - }); err != nil { - fmt.Println("1", err) - output <- errors.New("cannot read messages " + err.Error()) - }*/ - - if err := h.dal.WatchMessages(ctx, ticketID, - func(message model.Message) error { - output <- message - - //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { - // fmt.Println("3", err) - // output <- errors.New("cannot show watch message " + err.Error()) - // return err - //} - - return nil - }); err != nil { - fmt.Println("4", err) - output <- errors.New("cannot watch messages " + err.Error()) - } - }() - } - } - - return output -} - -func (h *Heruvym) handleOwnMessages(output chan interface{}) { - defer close(output) -} - -type GetTicketsReq struct { - Amount int64 `json:"amt"` - Page int64 `json:"page"` - Search string `json:"srch"` - Status string `json:"status"` -} -type GetTicketsResp struct { - Data []model.Ticket `json:"data"` - Count int64 `json:"count"` -} - -func (h *Heruvym) GetTickets( - ctx context.Context, - request GetTicketsReq) (GetTicketsResp, int) { - - role := jwt_adapter.GetRole(ctx) - - if role == "admin" { - result, count, err := h.dal.GetTicketPage(ctx, - request.Status, - request.Search, - request.Amount, - request.Page, - ) - if err != nil { - return GetTicketsResp{}, http.StatusNoContent - } - - return GetTicketsResp{ - Data: *result, - Count: count, - }, http.StatusOK - } else { - - sess := jwt_adapter.Get(ctx) - - result, count, err := h.dal.YieldUserTickets(ctx, sess.Id, request.Amount, request.Page*request.Amount) - if err != nil { - return GetTicketsResp{}, http.StatusNoContent - } - - return GetTicketsResp{ - Data: result, - Count: count, - }, http.StatusOK - } -} - -type GetMessagesReq struct { - Amount int64 `json:"amt"` - Page int64 `json:"page"` - Search string `json:"srch"` - TicketID string `json:"ticket"` -} - -func (h *Heruvym) GetMessages( - ctx context.Context, - request GetMessagesReq) ([]model.Message, int) { - result, err := h.dal.GetMessagesPage(ctx, - request.Search, - request.TicketID, - request.Amount, - request.Page, - ) - if err != nil { - return nil, http.StatusNoContent - } - - return result, http.StatusOK -} - -type CloseTicketReq struct { - TicketID string `json:"ticket"` -} -type CloseTicketResp struct { - TicketID string `json:"ticket"` -} - -func (h *Heruvym) CloseTicket(ctx context.Context, req CloseTicketReq) (*CloseTicketResp, int) { - if err := h.dal.SetTicketStatus(ctx, req.TicketID, model.StateClose); err != nil { - return nil, http.StatusBadRequest - } - - if _, err := h.dal.PutMessage(ctx, "close", "close", "close", req.TicketID, []string{}); err != nil { - return nil, http.StatusBadRequest - } - - return &CloseTicketResp{ - TicketID: req.TicketID, - }, http.StatusOK -} - -type VoteReq struct { - TicketID string `json:"ticket"` - Rate int `json:"rate"` -} - -func (h *Heruvym) Vote(ctx context.Context, req VoteReq) (error, int) { - if err := h.dal.SetRate(ctx, req.TicketID, req.Rate); err != nil { - return err, http.StatusBadRequest - } - - return nil, http.StatusOK -} - -type PickReq struct { - TicketID string `json:"ticket"` -} - -func (h *Heruvym) Pick(ctx context.Context, req PickReq) (error, int) { - sess := jwt_adapter.Get(ctx) - if err := h.dal.SetAnswerer(ctx, req.TicketID, sess.Id); err != nil { - return err, http.StatusBadRequest - } - - return nil, http.StatusOK -} - -type DelegateReq struct { - TicketID string `json:"ticket"` - AnswererID string `json:"answerer"` -} - -func (h *Heruvym) Delegate(ctx context.Context, req DelegateReq) (error, int) { - if err := h.dal.SetAnswerer(ctx, req.TicketID, req.AnswererID); err != nil { - return err, http.StatusBadRequest - } - - return nil, http.StatusOK -} - -// MB Size constants -const ( - MB = 1 << 20 -) - -var fileTypeLimits = map[string]int64{ - "image": 5 * MB, - "video": 50 * MB, - "document": 10 * MB, -} - -type PutFileReq struct { - Ticket string `json:"ticket"` -} - -type PutFileResp struct { - Message string `json:"message"` -} - -func (h *Heruvym) PutFile(w http.ResponseWriter, r *http.Request) { - defer r.Body.Close() - - sess := jwt_adapter.Get(r.Context()) - if sess == nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("not authorized")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - TimeKey := fmt.Sprintf("sendLockHeruvym:%s", sess.Id) - isNewKey, err := h.redisClient.SetNX(r.Context(), TimeKey, time.Now().Unix(), 30*time.Second).Result() - if err != nil { - fmt.Println("failed check last upload time in Redis:", err) - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("internal server error")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if !isNewKey { - w.WriteHeader(http.StatusTooManyRequests) - if _, err := w.Write([]byte("file upload limit exceeded")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if err := r.ParseMultipartForm(10 * MB); err != nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("can not parse multipart " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if r.MultipartForm == nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("no multipart")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if r.MultipartForm.File == nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("no file")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - for _, files := range r.MultipartForm.File { - for _, fileHeader := range files { - fileSize := fileHeader.Size - fileType := utils.GetFileType(fileHeader.Filename) - - if limit, ok := fileTypeLimits[fileType]; ok { - if fileSize > limit { - w.WriteHeader(http.StatusRequestEntityTooLarge) - if _, err := w.Write([]byte(fileType + " file size exceeds the limit")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - } else { - w.WriteHeader(http.StatusNotAcceptable) - if _, err := w.Write([]byte("Unsupported file type")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - } - } - - filesCount := len(r.MultipartForm.File) - - if filesCount == 0 { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("no files")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - var req PutFileReq - req.Ticket = r.MultipartForm.Value["ticket"][0] - - var ( - fileIDs, filenames []string - errFile error - ) - wg := new(sync.WaitGroup) - m := new(sync.Mutex) - - wg.Add(filesCount) - for name, file := range r.MultipartForm.File { - file := file - name := name - go func() { - defer wg.Done() - - freader, err := file[0].Open() - if err != nil { - fmt.Println("can not open ", err.Error()) - } - - hash := sha256.New() - if _, err := io.Copy(hash, freader); err != nil { - fmt.Println("error calculating file hash: ", err) - errFile = err - } - - _, err = freader.Seek(0, 0) - if err != nil { - fmt.Println("error seeking back to the beginning of the file: ", err) - errFile = err - } - - hashInBytes := hash.Sum(nil) - fileHash := hex.EncodeToString(hashInBytes) - splitted := strings.Split(name, ".") - filename := fmt.Sprintf("%s_%s.%s", fileHash, sess.Id, splitted[len(splitted)-1]) - - defer func() { - if err := freader.Close(); err != nil { - errFile = err - } - }() - - exists, err := h.bs.FileExists(r.Context(), filename) - if err != nil { - errFile = err - return - } - - if exists { - response := struct { - File string `json:"file"` - }{ - File: filename, - } - - resp, err := json.Marshal(response) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("error marshaling response: " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - w.WriteHeader(http.StatusAlreadyReported) - if _, err := w.Write(resp); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - m.Lock() - defer m.Unlock() - fileIDs = append(fileIDs, filename) - filenames = append(filenames, name) - return - } - - if err := h.bs.PutFile( - r.Context(), - filename, - freader, - file[0].Size); err != nil { - errFile = err - } - - m.Lock() - defer m.Unlock() - fileIDs = append(fileIDs, filename) - filenames = append(filenames, name) - }() - } - wg.Wait() - - if len(fileIDs) == 0 { - return - } - - if errFile != nil { - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("can not store files " + errFile.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - message, err := h.dal.PutMessage( - r.Context(), - strings.Join(filenames, ", "), - sess.Id, - sess.Id, - req.Ticket, - fileIDs, - ) - - if err != nil { - for _, filename := range filenames { - if err := h.bs.DeleteFile(r.Context(), filename); err != nil { - fmt.Println("can not delete", err) - } - } - - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("can not store message " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - resp, err := json.Marshal(&PutFileResp{Message: message.ID}) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("can not marshal resp " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - ctx := r.Context() - domain := ctx.Value(middleware.HostKey).(string) - if domain == "" { - fmt.Println("domain is nil err") - } - role := jwt_adapter.GetRole(ctx) - go func() { - if sess.Id != "" && role != "admin" { - if err == nil && h.notifier != nil { - var userLink, supportLink string - if sess.StandardClaims.Issuer != "" { - fmt.Println("MABNAT", domain) - if domain[0] == 's' { - userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id) - supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", req.Ticket) - } else { - userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id) - supportLink = fmt.Sprintf("https://admin.pena/support/%s", req.Ticket) - } - } else { - if domain[0] == 's' { - supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", req.Ticket) - } else { - supportLink = fmt.Sprintf("https://admin.pena/support/%s", req.Ticket) - } - userLink = "незарегистрированного пользователя" - } - - message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s", - userLink, domain, supportLink) - - if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil { - fmt.Println("CAN NOT NOTIFY", err) - } - return - } - } - }() - - if _, err := w.Write(resp); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - w.WriteHeader(http.StatusOK) // Необязательно, т.к. w.Write сам вызывает w.WriteHeader(http.StatusOK) перед выполнением -} - -type PutSCReq struct { - Ticket string `json:"ticket"` -} - -type PutSCResp struct { - Message string `json:"message"` -} - -func (h *Heruvym) PutSC(w http.ResponseWriter, r *http.Request) { - defer r.Body.Close() - - if err := r.ParseMultipartForm(10 * MB); err != nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("can not parse multipart " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if r.MultipartForm == nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("no multipart")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if r.MultipartForm.File == nil { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("no file")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - filesCount := len(r.MultipartForm.File) - - if filesCount == 0 { - w.WriteHeader(http.StatusBadRequest) - if _, err := w.Write([]byte("no files")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - sess := jwt_adapter.Get(r.Context()) - if sess == nil { - w.WriteHeader(http.StatusUnauthorized) - if _, err := w.Write([]byte("not authorized")); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - var req PutFileReq - - req.Ticket = r.MultipartForm.Value["ticket"][0] - var ( - fileIDs, filenames []string - errFile error - ) - wg := new(sync.WaitGroup) - m := new(sync.Mutex) - - wg.Add(filesCount) - for name, file := range r.MultipartForm.File { - file := file - name := name - go func() { - defer wg.Done() - - freader, err := file[0].Open() - if err != nil { - fmt.Println("can not open ", err.Error()) - } - - defer func() { - if err := freader.Close(); err != nil { - errFile = err - } - }() - - splitted := strings.Split(name, ".") - filename := fmt.Sprintf("%s.%s", xid.New().String(), splitted[len(splitted)-1]) - - if err := h.bs.PutFile( - r.Context(), - filename, - freader, - file[0].Size); err != nil { - errFile = err - } - - m.Lock() - defer m.Unlock() - fileIDs = append(fileIDs, filename) - filenames = append(filenames, name) - }() - } - wg.Wait() - - if errFile != nil { - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("can not store files " + errFile.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - message, err := h.dal.PutSCResponse( - r.Context(), - strings.Join(filenames, ", "), - sess.Id, - sess.Id, - req.Ticket, - fileIDs, - ) - - if err != nil { - for _, filename := range filenames { - if err := h.bs.DeleteFile(r.Context(), filename); err != nil { - fmt.Println("can not delete", err) - } - } - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("can not store message " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - resp, err := json.Marshal(&PutFileResp{Message: message.ID}) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte("can not marshal resp " + err.Error())); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - return - } - - if _, err := w.Write(resp); err != nil { - fmt.Println("CAN NOT WRITE", err) - } - w.WriteHeader(http.StatusOK) -} - -type ShownReq struct { - ID string `json:"id"` -} - -func (h *Heruvym) SetShown(ctx context.Context, req ShownReq) (error, int) { - return h.dal.SetShown(ctx, req.ID, "me"), http.StatusOK -} +//import ( +// "context" +// "crypto/sha256" +// "encoding/hex" +// "encoding/json" +// "errors" +// "fmt" +// "github.com/go-redis/redis/v8" +// "heruvym/dal/minio" +// "heruvym/dal/mongo" +// "heruvym/internal/model" +// "heruvym/internal/tools" +// "heruvym/internal/utils/jwt_adapter" +// "heruvym/internal/utils/middleware" +// "heruvym/utils" +// "io" +// "net/http" +// "strings" +// "sync" +// "time" +// +// "github.com/rs/xid" +// "github.com/themakers/hlog" +// tb "gopkg.in/tucnak/telebot.v2" +//) +// +//type Heruvym struct { +// logger hlog.Logger +// dal *mongo.DAL +// bs *minio.BlobStore +// +// notifier *tb.Bot +// tgChatID int64 +//} +// +//func New( +// blobs *minio.BlobStore, +// dataAccessLayer *mongo.DAL, +// log hlog.Logger, +// notifier *tb.Bot, +// tgChatID int64, redisClient *redis.Client) *Heruvym { +// return &Heruvym{ +// logger: log.Module("Service"), +// dal: dataAccessLayer, +// bs: blobs, +// notifier: notifier, +// tgChatID: tgChatID, +// redisClient: redisClient, +// } +//} +// +//func (h Heruvym) Register(m *http.ServeMux) *http.ServeMux { +// +// //"/requestScreenshot": tools.HandlerWrapper(heruvym.RequestScreenshot), ???? +// //"/sendFiles": heruvym.PutFile, ???? +// //"/sendSC": heruvym.PutSC, ???? +// //"/shown": tools.HandlerWrapper(heruvym.SetShown), ???? +// +// m.HandleFunc("/create", h.CreateTicket) +// m.HandleFunc("/subscribe", tools.SseWrapper(h.GetList)) +// m.HandleFunc("/ticket", tools.SseWrapper(h.Subscribe)) +// m.HandleFunc("/send", tools.HandlerWrapper(h.PutMessage)) +// m.HandleFunc("/getTickets", tools.HandlerWrapper(h.GetTickets)) +// m.HandleFunc("/getMessages", tools.HandlerWrapper(h.GetMessages)) +// m.HandleFunc("/pick", tools.HandlerWrapper(h.Pick)) +// m.HandleFunc("/delegate", tools.HandlerWrapper(h.Delegate)) +// m.HandleFunc("/vote", tools.HandlerWrapper(h.Vote)) +// m.HandleFunc("/close", tools.HandlerWrapper(h.CloseTicket)) +// +// return m +//} +// +//type CreateTicketReq struct { +// Title string `json:"Title"` +// Message string `json:"Message"` +//} +// +//type CreateTicketResp struct { +// Ticket string `json:"Ticket"` +// Sess string `json:"sess"` +//} +// +//func (h *Heruvym) CreateTicket(w http.ResponseWriter, r *http.Request) { +// defer func() { +// if err := r.Body.Close(); err != nil { +// h.logger.Emit(ErrorClose{ +// Err: err, +// }) +// } +// }() +// +// var ( +// err error +// request CreateTicketReq +// ) +// +// if err := json.NewDecoder(r.Body).Decode(&request); err != nil { +// http.Error(w, "Invalid json", http.StatusBadRequest) +// return +// } +// +// if request.Title == "" { +// http.Error(w, "No Title", http.StatusBadRequest) +// return +// } +// +// if request.Message == "" { +// http.Error(w, "No Message", http.StatusBadRequest) +// return +// } +// +// ctx := r.Context() +// +// session := jwt_adapter.Get(ctx) +// +// if session == nil { +// http.Error(w, "No session", http.StatusUnauthorized) +// return +// } +// +// var ( +// ticketID string +// tickets []model.Ticket +// role = jwt_adapter.GetRole(ctx) +// ) +// if role == "" { +// tickets, _, err = h.dal.GetTickets4Sess(ctx, session.Id) +// } +// +// if err != nil || len(tickets) == 0 { +// +// ticketID, err = h.dal.CreateTicket( +// ctx, +// session.Id, +// session.Id, +// r.Header["Origin"][0], +// request.Title, +// request.Message, +// []string{}, +// ) +// if err != nil { +// http.Error(w, "CannotCreateTicket", http.StatusInternalServerError) +// return +// } +// +// if _, err := h.dal.PutMessage(ctx, +// request.Message, +// session.Id, +// session.Id, +// ticketID, +// []string{}, +// ); err != nil { +// http.Error(w, "CannotCreateMessage", http.StatusInternalServerError) +// return +// } +// +// domain := ctx.Value(middleware.HostKey).(string) +// if domain == "" { +// fmt.Println("domain is nil err") +// } +// +// go func() { +// if session.Id != "" && role != "admin" { +// if err == nil && h.notifier != nil { +// var userLink, supportLink string +// if session.StandardClaims.Issuer != "" { +// fmt.Println("MABNAT", domain) +// if domain[0] == 's' { +// userLink = fmt.Sprintf("https://sadmin.pena/users/%s", session.Id) +// supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID) +// } else { +// userLink = fmt.Sprintf("https://admin.pena/users/%s", session.Id) +// supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID) +// } +// } else { +// if domain[0] == 's' { +// supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID) +// } else { +// supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID) +// } +// userLink = "незарегистрированного пользователя" +// } +// +// message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s", +// userLink, domain, supportLink) +// +// if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil { +// fmt.Println("CAN NOT NOTIFY", err) +// } +// return +// } +// } +// }() +// +// } else { +// ticketID = tickets[0].ID +// } +// +// response, err := json.Marshal(CreateTicketResp{Ticket: ticketID, Sess: session.Id}) +// if err != nil { +// h.logger.Emit(ErrorMarshal{ +// Err: err, +// }) +// http.Error(w, "CannotMarshalMessage", http.StatusInternalServerError) +// return +// } +// +// if _, err := w.Write(response); err != nil { +// h.logger.Emit(ErrorMarshal{ +// Err: err, +// }) +// return +// } +//} +// +//var _ tools.DataEmitter = (&Heruvym{}).GetList +// +//func (h *Heruvym) GetList(ctx context.Context) chan interface{} { +// fmt.Println("GetList") +// defer func() { +// if rec := recover(); rec != nil { +// fmt.Println(rec) +// } +// }() +// sess := jwt_adapter.Get(ctx) +// fmt.Println("sess", sess) +// if sess == nil { +// return nil +// } +// +// output := make(chan interface{}) +// +// if sess.Id == "" { +// go h.unauthorizedTickets(ctx, sess.Id, output) +// } else { +// role := jwt_adapter.GetRole(ctx) +// +// fmt.Println("ALL TICKETS Sess ", sess.Id, role) +// if role == "admin" || role == "manager" { +// go h.allTickets(ctx, output) +// } else { +// go h.userTickets(ctx, sess.Id, output) +// } +// } +// +// return output +//} +// +//func (h *Heruvym) allTickets(ctx context.Context, output chan interface{}) { +// defer func() { +// if v := recover(); v != nil { +// fmt.Println("AllTicketsRec", v) +// } +// }() +// +// //data, count, err := h.dal.YieldTickets(ctx, 20) +// // +// //if err != nil { +// // output <- errors.New("cannot get tickets:" + err.Error()) +// // return +// //} +// // +// //if data != nil { +// // output <- GetTicketsResp{data, count} +// //} +// +// if err := h.dal.WatchAllTickets(ctx, func(ticket model.Ticket) error { +// output <- ticket +// return nil +// }); err != nil { +// output <- errors.New("cannot watch all tickets" + err.Error()) +// } +//} +// +//func (h *Heruvym) userTickets(ctx context.Context, userID string, output chan interface{}) { +// +// defer func() { +// if v := recover(); v != nil { +// fmt.Println("USERTICKS", v) +// } +// }() +// +// data, count, err := h.dal.YieldUserTickets(ctx, userID, 20, 0) +// +// if err != nil { +// output <- errors.New("cannot get tickets:" + err.Error()) +// return +// } +// +// if data != nil { +// output <- GetTicketsResp{data, count} +// } +// +// if err := h.dal.WatchTickets(ctx, userID, func(ticket model.Ticket) error { +// output <- ticket +// return nil +// }); err != nil { +// output <- errors.New("cannot watch tickets") +// return +// } +//} +// +//func (h *Heruvym) hasNoRole(output chan interface{}) { +// output <- errors.New("no role in profile") +//} +// +//func (h *Heruvym) unauthorizedTickets(ctx context.Context, sess string, output chan interface{}) { +// //defer close(output) +// +// tickets, count, err := h.dal.GetTickets4Sess(ctx, sess) +// +// if err != nil { +// output <- errors.New("no tickets for session") +// return +// } +// +// if tickets != nil { +// output <- GetTicketsResp{tickets, count} +// } +//} +// +//type ReqPutMessage struct { +// Message string `json:"message"` +// TicketID string `json:"ticket"` +// Files []string `json:"files"` +// Lang string `json:"lang"` +//} +// +//func (h *Heruvym) PutMessage( +// ctx context.Context, +// request ReqPutMessage, +//) (interface{}, int) { +// sess := jwt_adapter.Get(ctx) +// fmt.Println("PUTMES", sess) +// +// request.Files = []string{} +// +// domain := ctx.Value(middleware.HostKey).(string) +// if domain == "" { +// fmt.Println("domain is nil err") +// return errors.New("domain is nil"), http.StatusBadRequest +// } +// +// message, err := h.dal.PutMessage( +// ctx, +// request.Message, +// sess.Id, +// sess.Id, +// request.TicketID, +// []string{}, +// ) +// fmt.Println("PUTMES00", err) +// if err != nil { +// fmt.Println("PUTMES1", err) +// return errors.New("can not put message"), http.StatusInternalServerError +// } +// +// role := jwt_adapter.GetRole(ctx) +// go func() { +// if sess.Id != "" && role != "admin" { +// if err == nil && h.notifier != nil { +// var userLink, supportLink string +// if sess.StandardClaims.Issuer != "" { +// fmt.Println("MABNAT", domain) +// if domain[0] == 's' { +// userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id) +// supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID) +// } else { +// userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id) +// supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID) +// } +// } else { +// if domain[0] == 's' { +// supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID) +// } else { +// supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID) +// } +// userLink = "незарегистрированного пользователя" +// } +// +// message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ссылка на чат - %s", +// userLink, domain, supportLink) +// +// if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil { +// fmt.Println("CAN NOT NOTIFY", err) +// } +// return +// } +// } +// }() +// +// if err := h.dal.UpdateTopMessage(ctx, request.TicketID, message); err != nil { +// fmt.Println("PUTMES01", err, request.TicketID, message) +// //return errors.New("can not update ticket"), http.StatusInternalServerError +// } +// +// fmt.Println("PUTMES03") +// return nil, http.StatusOK +//} +// +//type ReqScreenshot struct { +// TicketID string `json:"ticket"` +// Lang string `json:"lang"` +//} +// +//func (h *Heruvym) RequestScreenshot( +// ctx context.Context, +// request ReqScreenshot, +//) (interface{}, int) { +// sess := jwt_adapter.Get(ctx) +// +// _, err := h.dal.PutSCRequest( +// ctx, +// sess.Id, +// sess.Id, +// request.TicketID, +// ) +// if err != nil { +// return errors.New("can not put message"), http.StatusInternalServerError +// } +// +// return nil, http.StatusOK +//} +// +//var _ tools.DataEmitter = (&Heruvym{}).Subscribe +// +//func (h *Heruvym) Subscribe(ctx context.Context) chan interface{} { +// sess := jwt_adapter.Get(ctx) +// fmt.Println("SESS Subsc", sess) +// +// ticketID := ctx.Value(tools.ContextURLKey).(string) +// +// output := make(chan interface{}) +// if sess.Id == "" { +// go func() { +// ticket, err := h.dal.GetTicket4Sess(ctx, ticketID, sess.Id) +// if err != nil || ticket == nil { +// output <- errors.New("no tickets 4 session") +// return +// } +// +// /*if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error { +// output <- message +// fmt.Println("OOOOOOLd") +// +// //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { +// // +// // output <- errors.New("cannot show message " + err.Error()) +// // return err +// //} +// +// return nil +// }); err != nil { +// output <- errors.New("cannot read messages " + err.Error()) +// }*/ +// +// if err := h.dal.WatchMessages(ctx, ticketID, +// func(message model.Message) error { +// output <- message +// +// //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { +// // fmt.Println("3", err) +// // output <- errors.New("cannot show watch message " + err.Error()) +// // return err +// //} +// +// return nil +// }); err != nil { +// fmt.Println("4", err) +// output <- errors.New("cannot watch messages " + err.Error()) +// } +// }() +// } else { +// role := jwt_adapter.GetRole(ctx) +// +// if role == "admin" || role == "manager" { +// go func() { +// +// if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error { +// output <- message +// +// //if err := h.dal.SetShown(ctx, message.ID, sess.User); err != nil { +// // fmt.Println("2", err) +// // output <- errors.New("cannot show message " + err.Error()) +// // return err +// //} +// +// return nil +// }); err != nil { +// fmt.Println("1", err) +// output <- errors.New("cannot read messages " + err.Error()) +// } +// +// if err := h.dal.WatchMessages(ctx, ticketID, +// func(message model.Message) error { +// output <- message +// +// //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { +// // fmt.Println("3", err) +// // output <- errors.New("cannot show watch message " + err.Error()) +// // return err +// //} +// +// return nil +// }); err != nil { +// fmt.Println("4", err) +// output <- errors.New("cannot watch messages " + err.Error()) +// } +// }() +// } else { +// go func() { +// defer func() { +// if v := recover(); v != nil { +// fmt.Println("heryvym panic", v) +// } +// }() +// ticket, err := h.dal.GetTicket4User(ctx, ticketID, sess.Id) +// if err != nil || ticket == nil { +// output <- errors.New("no tickets 4 user") +// } +// +// /*if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error { +// output <- message +// +// //if err := h.dal.SetShown(ctx, message.ID, sess.User); err != nil { +// // fmt.Println("2", err) +// // output <- errors.New("cannot show message " + err.Error()) +// // return err +// //} +// +// return nil +// }); err != nil { +// fmt.Println("1", err) +// output <- errors.New("cannot read messages " + err.Error()) +// }*/ +// +// if err := h.dal.WatchMessages(ctx, ticketID, +// func(message model.Message) error { +// output <- message +// +// //if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil { +// // fmt.Println("3", err) +// // output <- errors.New("cannot show watch message " + err.Error()) +// // return err +// //} +// +// return nil +// }); err != nil { +// fmt.Println("4", err) +// output <- errors.New("cannot watch messages " + err.Error()) +// } +// }() +// } +// } +// +// return output +//} +// +//func (h *Heruvym) handleOwnMessages(output chan interface{}) { +// defer close(output) +//} +// +//type GetTicketsReq struct { +// Amount int64 `json:"amt"` +// Page int64 `json:"page"` +// Search string `json:"srch"` +// Status string `json:"status"` +//} +//type GetTicketsResp struct { +// Data []model.Ticket `json:"data"` +// Count int64 `json:"count"` +//} +// +//func (h *Heruvym) GetTickets( +// ctx context.Context, +// request GetTicketsReq) (GetTicketsResp, int) { +// +// role := jwt_adapter.GetRole(ctx) +// +// if role == "admin" { +// result, count, err := h.dal.GetTicketPage(ctx, +// request.Status, +// request.Search, +// request.Amount, +// request.Page, +// ) +// if err != nil { +// return GetTicketsResp{}, http.StatusNoContent +// } +// +// return GetTicketsResp{ +// Data: *result, +// Count: count, +// }, http.StatusOK +// } else { +// +// sess := jwt_adapter.Get(ctx) +// +// result, count, err := h.dal.YieldUserTickets(ctx, sess.Id, request.Amount, request.Page*request.Amount) +// if err != nil { +// return GetTicketsResp{}, http.StatusNoContent +// } +// +// return GetTicketsResp{ +// Data: result, +// Count: count, +// }, http.StatusOK +// } +//} +// +//type GetMessagesReq struct { +// Amount int64 `json:"amt"` +// Page int64 `json:"page"` +// Search string `json:"srch"` +// TicketID string `json:"ticket"` +//} +// +//func (h *Heruvym) GetMessages( +// ctx context.Context, +// request GetMessagesReq) ([]model.Message, int) { +// result, err := h.dal.GetMessagesPage(ctx, +// request.Search, +// request.TicketID, +// request.Amount, +// request.Page, +// ) +// if err != nil { +// return nil, http.StatusNoContent +// } +// +// return result, http.StatusOK +//} +// +//type CloseTicketReq struct { +// TicketID string `json:"ticket"` +//} +//type CloseTicketResp struct { +// TicketID string `json:"ticket"` +//} +// +//func (h *Heruvym) CloseTicket(ctx context.Context, req CloseTicketReq) (*CloseTicketResp, int) { +// if err := h.dal.SetTicketStatus(ctx, req.TicketID, model.StateClose); err != nil { +// return nil, http.StatusBadRequest +// } +// +// if _, err := h.dal.PutMessage(ctx, "close", "close", "close", req.TicketID, []string{}); err != nil { +// return nil, http.StatusBadRequest +// } +// +// return &CloseTicketResp{ +// TicketID: req.TicketID, +// }, http.StatusOK +//} +// +//type VoteReq struct { +// TicketID string `json:"ticket"` +// Rate int `json:"rate"` +//} +// +//func (h *Heruvym) Vote(ctx context.Context, req VoteReq) (error, int) { +// if err := h.dal.SetRate(ctx, req.TicketID, req.Rate); err != nil { +// return err, http.StatusBadRequest +// } +// +// return nil, http.StatusOK +//} +// +//type PickReq struct { +// TicketID string `json:"ticket"` +//} +// +//func (h *Heruvym) Pick(ctx context.Context, req PickReq) (error, int) { +// sess := jwt_adapter.Get(ctx) +// if err := h.dal.SetAnswerer(ctx, req.TicketID, sess.Id); err != nil { +// return err, http.StatusBadRequest +// } +// +// return nil, http.StatusOK +//} +// +//type DelegateReq struct { +// TicketID string `json:"ticket"` +// AnswererID string `json:"answerer"` +//} +// +//func (h *Heruvym) Delegate(ctx context.Context, req DelegateReq) (error, int) { +// if err := h.dal.SetAnswerer(ctx, req.TicketID, req.AnswererID); err != nil { +// return err, http.StatusBadRequest +// } +// +// return nil, http.StatusOK +//} +// +//// MB Size constants +//const ( +// MB = 1 << 20 +//) +// +//var fileTypeLimits = map[string]int64{ +// "image": 5 * MB, +// "video": 50 * MB, +// "document": 10 * MB, +//} +// +//type PutFileReq struct { +// Ticket string `json:"ticket"` +//} +// +//type PutFileResp struct { +// Message string `json:"message"` +//} +// +//func (h *Heruvym) PutFile(w http.ResponseWriter, r *http.Request) { +// defer r.Body.Close() +// +// sess := jwt_adapter.Get(r.Context()) +// if sess == nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("not authorized")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// TimeKey := fmt.Sprintf("sendLockHeruvym:%s", sess.Id) +// isNewKey, err := h.redisClient.SetNX(r.Context(), TimeKey, time.Now().Unix(), 30*time.Second).Result() +// if err != nil { +// fmt.Println("failed check last upload time in Redis:", err) +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("internal server error")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if !isNewKey { +// w.WriteHeader(http.StatusTooManyRequests) +// if _, err := w.Write([]byte("file upload limit exceeded")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if err := r.ParseMultipartForm(10 * MB); err != nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("can not parse multipart " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if r.MultipartForm == nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("no multipart")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if r.MultipartForm.File == nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("no file")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// for _, files := range r.MultipartForm.File { +// for _, fileHeader := range files { +// fileSize := fileHeader.Size +// fileType := utils.GetFileType(fileHeader.Filename) +// +// if limit, ok := fileTypeLimits[fileType]; ok { +// if fileSize > limit { +// w.WriteHeader(http.StatusRequestEntityTooLarge) +// if _, err := w.Write([]byte(fileType + " file size exceeds the limit")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// } else { +// w.WriteHeader(http.StatusNotAcceptable) +// if _, err := w.Write([]byte("Unsupported file type")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// } +// } +// +// filesCount := len(r.MultipartForm.File) +// +// if filesCount == 0 { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("no files")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// var req PutFileReq +// req.Ticket = r.MultipartForm.Value["ticket"][0] +// +// var ( +// fileIDs, filenames []string +// errFile error +// ) +// wg := new(sync.WaitGroup) +// m := new(sync.Mutex) +// +// wg.Add(filesCount) +// for name, file := range r.MultipartForm.File { +// file := file +// name := name +// go func() { +// defer wg.Done() +// +// freader, err := file[0].Open() +// if err != nil { +// fmt.Println("can not open ", err.Error()) +// } +// +// hash := sha256.New() +// if _, err := io.Copy(hash, freader); err != nil { +// fmt.Println("error calculating file hash: ", err) +// errFile = err +// } +// +// _, err = freader.Seek(0, 0) +// if err != nil { +// fmt.Println("error seeking back to the beginning of the file: ", err) +// errFile = err +// } +// +// hashInBytes := hash.Sum(nil) +// fileHash := hex.EncodeToString(hashInBytes) +// splitted := strings.Split(name, ".") +// filename := fmt.Sprintf("%s_%s.%s", fileHash, sess.Id, splitted[len(splitted)-1]) +// +// defer func() { +// if err := freader.Close(); err != nil { +// errFile = err +// } +// }() +// +// exists, err := h.bs.FileExists(r.Context(), filename) +// if err != nil { +// errFile = err +// return +// } +// +// if exists { +// response := struct { +// File string `json:"file"` +// }{ +// File: filename, +// } +// +// resp, err := json.Marshal(response) +// if err != nil { +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("error marshaling response: " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// w.WriteHeader(http.StatusAlreadyReported) +// if _, err := w.Write(resp); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// m.Lock() +// defer m.Unlock() +// fileIDs = append(fileIDs, filename) +// filenames = append(filenames, name) +// return +// } +// +// if err := h.bs.PutFile( +// r.Context(), +// filename, +// freader, +// file[0].Size); err != nil { +// errFile = err +// } +// +// m.Lock() +// defer m.Unlock() +// fileIDs = append(fileIDs, filename) +// filenames = append(filenames, name) +// }() +// } +// wg.Wait() +// +// if len(fileIDs) == 0 { +// return +// } +// +// if errFile != nil { +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("can not store files " + errFile.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// message, err := h.dal.PutMessage( +// r.Context(), +// strings.Join(filenames, ", "), +// sess.Id, +// sess.Id, +// req.Ticket, +// fileIDs, +// ) +// +// if err != nil { +// for _, filename := range filenames { +// if err := h.bs.DeleteFile(r.Context(), filename); err != nil { +// fmt.Println("can not delete", err) +// } +// } +// +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("can not store message " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// resp, err := json.Marshal(&PutFileResp{Message: message.ID}) +// if err != nil { +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("can not marshal resp " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// ctx := r.Context() +// domain := ctx.Value(middleware.HostKey).(string) +// if domain == "" { +// fmt.Println("domain is nil err") +// } +// role := jwt_adapter.GetRole(ctx) +// go func() { +// if sess.Id != "" && role != "admin" { +// if err == nil && h.notifier != nil { +// var userLink, supportLink string +// if sess.StandardClaims.Issuer != "" { +// fmt.Println("MABNAT", domain) +// if domain[0] == 's' { +// userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id) +// supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", req.Ticket) +// } else { +// userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id) +// supportLink = fmt.Sprintf("https://admin.pena/support/%s", req.Ticket) +// } +// } else { +// if domain[0] == 's' { +// supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", req.Ticket) +// } else { +// supportLink = fmt.Sprintf("https://admin.pena/support/%s", req.Ticket) +// } +// userLink = "незарегистрированного пользователя" +// } +// +// message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s", +// userLink, domain, supportLink) +// +// if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil { +// fmt.Println("CAN NOT NOTIFY", err) +// } +// return +// } +// } +// }() +// +// if _, err := w.Write(resp); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// w.WriteHeader(http.StatusOK) // Необязательно, т.к. w.Write сам вызывает w.WriteHeader(http.StatusOK) перед выполнением +//} +// +//type PutSCReq struct { +// Ticket string `json:"ticket"` +//} +// +//type PutSCResp struct { +// Message string `json:"message"` +//} +// +//func (h *Heruvym) PutSC(w http.ResponseWriter, r *http.Request) { +// defer r.Body.Close() +// +// if err := r.ParseMultipartForm(10 * MB); err != nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("can not parse multipart " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if r.MultipartForm == nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("no multipart")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if r.MultipartForm.File == nil { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("no file")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// filesCount := len(r.MultipartForm.File) +// +// if filesCount == 0 { +// w.WriteHeader(http.StatusBadRequest) +// if _, err := w.Write([]byte("no files")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// sess := jwt_adapter.Get(r.Context()) +// if sess == nil { +// w.WriteHeader(http.StatusUnauthorized) +// if _, err := w.Write([]byte("not authorized")); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// var req PutFileReq +// +// req.Ticket = r.MultipartForm.Value["ticket"][0] +// var ( +// fileIDs, filenames []string +// errFile error +// ) +// wg := new(sync.WaitGroup) +// m := new(sync.Mutex) +// +// wg.Add(filesCount) +// for name, file := range r.MultipartForm.File { +// file := file +// name := name +// go func() { +// defer wg.Done() +// +// freader, err := file[0].Open() +// if err != nil { +// fmt.Println("can not open ", err.Error()) +// } +// +// defer func() { +// if err := freader.Close(); err != nil { +// errFile = err +// } +// }() +// +// splitted := strings.Split(name, ".") +// filename := fmt.Sprintf("%s.%s", xid.New().String(), splitted[len(splitted)-1]) +// +// if err := h.bs.PutFile( +// r.Context(), +// filename, +// freader, +// file[0].Size); err != nil { +// errFile = err +// } +// +// m.Lock() +// defer m.Unlock() +// fileIDs = append(fileIDs, filename) +// filenames = append(filenames, name) +// }() +// } +// wg.Wait() +// +// if errFile != nil { +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("can not store files " + errFile.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// message, err := h.dal.PutSCResponse( +// r.Context(), +// strings.Join(filenames, ", "), +// sess.Id, +// sess.Id, +// req.Ticket, +// fileIDs, +// ) +// +// if err != nil { +// for _, filename := range filenames { +// if err := h.bs.DeleteFile(r.Context(), filename); err != nil { +// fmt.Println("can not delete", err) +// } +// } +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("can not store message " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// resp, err := json.Marshal(&PutFileResp{Message: message.ID}) +// if err != nil { +// w.WriteHeader(http.StatusInternalServerError) +// if _, err := w.Write([]byte("can not marshal resp " + err.Error())); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// return +// } +// +// if _, err := w.Write(resp); err != nil { +// fmt.Println("CAN NOT WRITE", err) +// } +// w.WriteHeader(http.StatusOK) +//} +// +//type ShownReq struct { +// ID string `json:"id"` +//} +// +//func (h *Heruvym) SetShown(ctx context.Context, req ShownReq) (error, int) { +// return h.dal.SetShown(ctx, req.ID, "me"), http.StatusOK +//}