diff --git a/.vscode/auth.go b/.vscode/auth.go new file mode 100644 index 0000000..93a441e --- /dev/null +++ b/.vscode/auth.go @@ -0,0 +1,34 @@ +package routes + +import ( + "net/http" + + "github.com/divyam234/teldrive-go/services" + + "github.com/gin-gonic/gin" +) + +func addAuthRoutes(rg *gin.RouterGroup) { + + r := rg.Group("/auth") + + authService := services.AuthService{SessionCookieName: "__Secure-user-session", SessionMaxAge: 30 * 24 * 60 * 60} + + r.POST("/login", func(c *gin.Context) { + + err := authService.SignIn(c) + + if err != nil { + c.AbortWithError(err.Code, err.Error) + return + } + }) + + r.GET("/session", func(c *gin.Context) { + + session := authService.GetSession(c) + + c.JSON(http.StatusOK, session) + }) + +} diff --git a/.vscode/file.routes.go b/.vscode/file.routes.go new file mode 100644 index 0000000..f1478bb --- /dev/null +++ b/.vscode/file.routes.go @@ -0,0 +1,74 @@ +package routes + +import ( + "context" + "net/http" + "os" + "strconv" + + "github.com/divyam234/teldrive-go/database" + "github.com/divyam234/teldrive-go/services" + + "github.com/gin-gonic/gin" +) + +func addFileRoutes(rg *gin.RouterGroup) { + + r := rg.Group("/files") + r.Use(Authmiddleware) + channelID, _ := strconv.ParseInt(os.Getenv("CHANNEL_ID"), 10, 64) + fileService := services.FileService{Db: database.DB, ChannelID: channelID} + + r.GET("/", func(c *gin.Context) { + res, err := fileService.ListFiles(c) + + if err != nil { + c.AbortWithError(err.Code, err.Error) + return + } + + c.JSON(http.StatusOK, res) + }) + + r.POST("/", func(c *gin.Context) { + + res, err := fileService.CreateFile(c) + + if err != nil { + c.AbortWithError(err.Code, err.Error) + return + } + + c.JSON(http.StatusOK, res) + }) + + r.GET("/:fileID", func(c *gin.Context) { + + res, err := fileService.GetFileByID(c) + + if err != nil { + c.AbortWithError(http.StatusNotFound, err) + return + } + + c.JSON(http.StatusOK, res) + }) + + r.PATCH("/:fileID", func(c *gin.Context) { + + res, err := fileService.UpdateFile(c) + + if err != nil { + c.AbortWithError(err.Code, err.Error) + return + } + + c.JSON(http.StatusOK, res) + }) + + r.GET("/:fileID/:fileName", func(c *gin.Context) { + + fileService.GetFileStream(context.Background())(c) + }) + +} diff --git a/database/database.go b/database/database.go index 61a620a..12c2ca4 100644 --- a/database/database.go +++ b/database/database.go @@ -1,11 +1,14 @@ package database import ( + "log" "os" "time" + "github.com/divyam234/teldrive-go/utils" "gorm.io/driver/postgres" "gorm.io/gorm" + "gorm.io/gorm/logger" "gorm.io/gorm/schema" ) @@ -15,7 +18,18 @@ func InitDB() { var err error - DB, err = gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{ + newLogger := logger.New( + log.New(os.Stdout, "\r\n", log.LstdFlags), + logger.Config{ + SlowThreshold: time.Second, + LogLevel: logger.Silent, + IgnoreRecordNotFoundError: true, + ParameterizedQueries: true, + Colorful: false, + }, + ) + + DB, err = gorm.Open(postgres.Open(utils.GetConfig().DatabaseUrl), &gorm.Config{ NamingStrategy: schema.NamingStrategy{ TablePrefix: "teldrive.", SingularTable: false, @@ -24,6 +38,7 @@ func InitDB() { NowFunc: func() time.Time { return time.Now().UTC() }, + Logger: newLogger, }) if err != nil { panic(err) diff --git a/go.mod b/go.mod index 3f2cbb1..0f2abd1 100644 --- a/go.mod +++ b/go.mod @@ -1,29 +1,32 @@ module github.com/divyam234/teldrive-go -go 1.20 +go 1.21 + +toolchain go1.21.0 require ( github.com/allegro/bigcache/v3 v3.1.0 + github.com/divyam234/cors v1.4.2 github.com/gin-gonic/gin v1.9.1 - github.com/jackc/pgx/v4 v4.18.1 + github.com/go-jose/go-jose/v3 v3.0.0 + github.com/gotd/contrib v0.19.0 + github.com/gotd/td v0.84.0 + github.com/jackc/pgtype v1.14.0 + github.com/joho/godotenv v1.5.1 github.com/mitchellh/mapstructure v1.5.0 - golang.org/x/time v0.3.0 + github.com/pkg/errors v0.9.1 + github.com/quantumsheep/range-parser v1.1.0 + go.uber.org/zap v1.25.0 + golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb + gorm.io/driver/postgres v1.5.2 gorm.io/gorm v1.25.2 -) - -require ( - github.com/PeteProgrammer/go-automapper v0.0.0-20200419053654-7c63d5bb0eb4 // indirect - github.com/jackc/pgx/v5 v5.3.1 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/lib/pq v1.10.2 // indirect + github.com/kelseyhightower/envconfig v1.4.0 ) require ( github.com/bytedance/sonic v1.9.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/devfeel/mapper v0.7.13 github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-faster/errors v0.6.1 // indirect @@ -33,49 +36,38 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/gotd/contrib v0.19.0 github.com/gotd/ige v0.2.2 // indirect github.com/gotd/neo v0.1.5 // indirect - github.com/gotd/td v0.84.0 - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.0 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.2 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgtype v1.14.0 - github.com/jinzhu/gorm v1.9.16 - github.com/joho/godotenv v1.5.1 + github.com/jackc/pgx/v5 v5.3.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect - github.com/lynchborg/automapper v0.0.0-20230411105854-fb8a35df335a github.com/mattn/go-isatty v0.0.19 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pkg/errors v0.9.1 - github.com/quantumsheep/range-parser v1.1.0 github.com/segmentio/asm v1.2.0 // indirect - github.com/sirupsen/logrus v1.9.3 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect go.opentelemetry.io/otel v1.16.0 // indirect go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b golang.org/x/net v0.12.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gorm.io/driver/postgres v1.5.2 nhooyr.io/websocket v1.8.7 // indirect rsc.io/qr v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index f4cee68..951ffa8 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/PeteProgrammer/go-automapper v0.0.0-20200419053654-7c63d5bb0eb4 h1:S+0ODzOh5zBv4dlixiY+a6ZcwlbSkRXtkK8cJm+aKJo= -github.com/PeteProgrammer/go-automapper v0.0.0-20200419053654-7c63d5bb0eb4/go.mod h1:gzkRbKGjRtfeCc53wW2SyIPPx9wU5oM6bzr6qF/kWuI= -github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk= github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I= -github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +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/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -19,11 +17,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/devfeel/mapper v0.7.13 h1:IE6ZITgrMH8W/xhUvJ6PInjVV8QW29idDJAUZPc9bbw= -github.com/devfeel/mapper v0.7.13/go.mod h1:foz4u16jrssGoDfnWYQGFcthjlU6uBV5UV8uYJfKneA= -github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/divyam234/cors v1.4.1 h1:NexEerR+urDaMAAhvg+J6Dx5wqC/X56TKpv8R8eelUg= +github.com/divyam234/cors v1.4.1/go.mod h1:JrxBJAqTU7jtPItodwf2mzxbbZm0Qq0NFkK8jo9UUDk= +github.com/divyam234/cors v1.4.2 h1:moAxStmYpvG9/SkPz+Wld02iutgo3JcUvrez6Kit/D8= +github.com/divyam234/cors v1.4.2/go.mod h1:JrxBJAqTU7jtPItodwf2mzxbbZm0Qq0NFkK8jo9UUDk= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -38,9 +37,13 @@ github.com/go-faster/jx v1.0.1/go.mod h1:vKDNikrKoyUmpzaJ0OkIkRQClNHFX/nF3dnTJZb github.com/go-faster/xor v0.3.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ= github.com/go-faster/xor v1.0.0 h1:2o8vTOgErSGHP3/7XwA5ib1FTtUsNtwCoLLBjl31X38= github.com/go-faster/xor v1.0.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ= +github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= +github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 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= @@ -50,22 +53,29 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.4.0/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gotd/contrib v0.19.0 h1:O6GvMrRVeFslIHLUcpaHVzcl9/5PcgR2jQTIIeTyds0= github.com/gotd/contrib v0.19.0/go.mod h1:LzPxzRF0FvtpBt/WyODWQnPpk0tm/G9z6RHUoPqMakU= @@ -85,9 +95,8 @@ github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530 h1:dUJ578zuPEsXjtzOfEF0q9zDAfljJ9oFnTHcQaNkccw= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= -github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -102,9 +111,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= -github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= @@ -117,20 +125,15 @@ github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76 github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c h1:Dznn52SgVIVst9UyOT9brctYUgxs+CvVfPaC3jKrA50= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= -github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= -github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= @@ -138,6 +141,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= @@ -148,20 +153,21 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t 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.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 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.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lynchborg/automapper v0.0.0-20230411105854-fb8a35df335a h1:3aE6b7HFuFpFklAhZG77EFUY0XM5gWfo4+dH52EYlN8= -github.com/lynchborg/automapper v0.0.0-20230411105854-fb8a35df335a/go.mod h1:3Wk1b4pHcmQr6bICtYkRr3ymaQ4OvlxVIPFfEFIgu1g= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -169,7 +175,6 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -183,10 +188,13 @@ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNc github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/quantumsheep/range-parser v1.1.0 h1:k4f1F58f8FF54FBYc9dYBRM+8JkAxFo11gC3IeMH4rU= github.com/quantumsheep/range-parser v1.1.0/go.mod h1:acv4Vt2PvpGvRsvGju7Gk2ahKluZJsIUNR69W53J22I= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -197,8 +205,6 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -208,19 +214,21 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= @@ -232,6 +240,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -241,53 +251,37 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -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.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI= -golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA= +golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -300,32 +294,19 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -338,9 +319,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -352,6 +331,8 @@ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cn google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -361,8 +342,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= -gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= -gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho= gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/main.go b/main.go index 1062a36..05ffcd4 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,14 @@ package main import ( + "time" + "github.com/divyam234/teldrive-go/cache" "github.com/divyam234/teldrive-go/database" "github.com/divyam234/teldrive-go/routes" "github.com/divyam234/teldrive-go/utils" + "github.com/divyam234/cors" "github.com/gin-gonic/gin" "github.com/joho/godotenv" ) @@ -18,16 +21,29 @@ func main() { godotenv.Load() + utils.InitConfig() + + utils.InitializeLogger() + database.InitDB() cache.CacheInit() - utils.StartClients() + utils.StartBotTgClients() + + router.Use(cors.New(cors.Config{ + AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"}, + AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"}, + AllowCredentials: true, + AllowOriginFunc: func(origin string) bool { + return true + }, + MaxAge: 12 * time.Hour, + })) router.Use(gin.ErrorLogger()) routes.GetRoutes(router) router.Run(":8080") - } diff --git a/routes/auth.go b/routes/auth.go new file mode 100644 index 0000000..2ea9efd --- /dev/null +++ b/routes/auth.go @@ -0,0 +1,34 @@ +package routes + +import ( + "net/http" + + "github.com/divyam234/teldrive-go/services" + + "github.com/gin-gonic/gin" +) + +func addAuthRoutes(rg *gin.RouterGroup) { + + r := rg.Group("/auth") + + authService := services.AuthService{SessionMaxAge: 30 * 24 * 60 * 60} + + r.POST("/login", func(c *gin.Context) { + + err := authService.SignIn(c) + + if err != nil { + c.AbortWithError(err.Code, err.Error) + return + } + }) + + r.GET("/session", func(c *gin.Context) { + + session := authService.GetSession(c) + + c.JSON(http.StatusOK, session) + }) + +} diff --git a/routes/file.routes.go b/routes/file.routes.go index d7c8d18..b95593d 100644 --- a/routes/file.routes.go +++ b/routes/file.routes.go @@ -3,11 +3,10 @@ package routes import ( "context" "net/http" - "os" - "strconv" "github.com/divyam234/teldrive-go/database" "github.com/divyam234/teldrive-go/services" + "github.com/divyam234/teldrive-go/utils" "github.com/gin-gonic/gin" ) @@ -15,10 +14,10 @@ import ( func addFileRoutes(rg *gin.RouterGroup) { r := rg.Group("/files") - channelID, _ := strconv.ParseInt(os.Getenv("CHANNEL_ID"), 10, 64) - fileService := services.FileService{Db: database.DB, ChannelID: channelID} + r.Use(Authmiddleware) + fileService := services.FileService{Db: database.DB, ChannelID: utils.GetConfig().ChannelID} - r.GET("/", func(c *gin.Context) { + r.GET("", func(c *gin.Context) { res, err := fileService.ListFiles(c) if err != nil { @@ -29,7 +28,7 @@ func addFileRoutes(rg *gin.RouterGroup) { c.JSON(http.StatusOK, res) }) - r.POST("/", func(c *gin.Context) { + r.POST("", func(c *gin.Context) { res, err := fileService.CreateFile(c) diff --git a/routes/main.go b/routes/main.go index 8a739a2..d311dc6 100644 --- a/routes/main.go +++ b/routes/main.go @@ -4,5 +4,6 @@ import "github.com/gin-gonic/gin" func GetRoutes(router *gin.Engine) { api := router.Group("/api") + addAuthRoutes(api) addFileRoutes(api) } diff --git a/routes/middleware.go b/routes/middleware.go new file mode 100644 index 0000000..e1627a1 --- /dev/null +++ b/routes/middleware.go @@ -0,0 +1,36 @@ +package routes + +import ( + "net/http" + "time" + + "github.com/divyam234/teldrive-go/services" + "github.com/divyam234/teldrive-go/utils/auth" + "github.com/gin-gonic/gin" + "github.com/go-jose/go-jose/v3/jwt" +) + +func Authmiddleware(c *gin.Context) { + cookie, err := c.Request.Cookie(services.GetUserSessionCookieName(c)) + + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "missing session cookie"}) + } + + now := time.Now().UTC() + + jwePayload, err := auth.Decode(cookie.Value) + + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) + } + + if *jwePayload.Expiry < *jwt.NewNumericDate(now) { + c.JSON(http.StatusUnauthorized, gin.H{"error": "token expired"}) + } + + c.Set("jwtUser", jwePayload) + + c.Next() + +} diff --git a/services/auth.service.go b/services/auth.service.go new file mode 100644 index 0000000..20feeb5 --- /dev/null +++ b/services/auth.service.go @@ -0,0 +1,133 @@ +package services + +import ( + "bytes" + "encoding/base64" + "encoding/binary" + "encoding/hex" + "errors" + "math/big" + "net" + "net/http" + "time" + + "github.com/divyam234/teldrive-go/types" + "github.com/divyam234/teldrive-go/utils/auth" + "github.com/gin-gonic/gin" + "github.com/go-jose/go-jose/v3/jwt" +) + +type AuthService struct { + SessionMaxAge int +} + +func IP4toInt(IPv4Address net.IP) int64 { + IPv4Int := big.NewInt(0) + IPv4Int.SetBytes(IPv4Address.To4()) + return IPv4Int.Int64() +} + +func Pack32BinaryIP4(ip4Address string) []byte { + ipv4Decimal := IP4toInt(net.ParseIP(ip4Address)) + + buf := new(bytes.Buffer) + binary.Write(buf, binary.BigEndian, uint32(ipv4Decimal)) + return buf.Bytes() +} + +func generateSessionKey(dcID int, serverAddress string, authKey []byte, port int) string { + + dcIDByte := byte(dcID) + serverAddressBytes := Pack32BinaryIP4(serverAddress) + portByte := make([]byte, 2) + binary.BigEndian.PutUint16(portByte, uint16(port)) + + packet := make([]byte, 0) + packet = append(packet, dcIDByte) + packet = append(packet, serverAddressBytes...) + packet = append(packet, portByte...) + packet = append(packet, authKey...) + + base64Encoded := base64.URLEncoding.EncodeToString(packet) + return "1" + base64Encoded +} + +func GetUserSessionCookieName(c *gin.Context) string { + + isHttps := c.Request.URL.Scheme == "https" + var cookieName string + if isHttps { + cookieName = "__Secure-user-session" + } else { + cookieName = "user-session" + } + + return cookieName +} + +func (as *AuthService) SignIn(c *gin.Context) *types.AppError { + dcMaps := map[int]string{ + 1: "149.154.175.53", + 2: "149.154.167.51", + 3: "149.154.175.100", + 4: "149.154.167.91", + 5: "91.108.56.130", + } + var session types.TgSession + if err := c.ShouldBindJSON(&session); err != nil { + return &types.AppError{Error: errors.New("invalid request payload"), Code: http.StatusBadRequest} + } + + now := time.Now().UTC() + + authBytes, _ := hex.DecodeString(session.AuthKey) + + sessionData := generateSessionKey(session.DcID, dcMaps[session.DcID], authBytes, 443) + + jwtClaims := &types.JWTClaims{Claims: jwt.Claims{ + Subject: session.UserID, + IssuedAt: jwt.NewNumericDate(now), + Expiry: jwt.NewNumericDate(now.Add(time.Duration(as.SessionMaxAge) * time.Second)), + }, TgSession: sessionData, Name: session.Name, UserName: session.UserName, Bot: session.Bot, IsPremium: session.IsPremium} + + jweToken, err := auth.Encode(jwtClaims) + + if err != nil { + return &types.AppError{Error: err, Code: http.StatusBadRequest} + } + c.SetCookie(GetUserSessionCookieName(c), jweToken, as.SessionMaxAge, "/", c.Request.Host, false, false) + return nil +} + +func (as *AuthService) GetSession(c *gin.Context) *types.Session { + + cookie, err := c.Request.Cookie(GetUserSessionCookieName(c)) + + if err != nil { + return nil + } + + jwePayload, err := auth.Decode(cookie.Value) + + if err != nil { + return nil + } + + now := time.Now().UTC() + + newExpires := now.Add(time.Duration(as.SessionMaxAge) * time.Second) + + session := &types.Session{Name: jwePayload.Name, UserName: jwePayload.UserName, Expires: newExpires.Format(time.RFC3339)} + + jwePayload.IssuedAt = jwt.NewNumericDate(now) + + jwePayload.Expiry = jwt.NewNumericDate(newExpires) + + jweToken, err := auth.Encode(jwePayload) + + if err != nil { + return nil + } + c.SetCookie(GetUserSessionCookieName(c), jweToken, as.SessionMaxAge, "/", c.Request.Host, false, false) + return session +} diff --git a/services/file.service.go b/services/file.service.go index f2524f8..30af4f7 100644 --- a/services/file.service.go +++ b/services/file.service.go @@ -230,14 +230,29 @@ func (fs *FileService) GetFileStream(ctx context.Context) gin.HandlerFunc { return func(c *gin.Context) { - fileID := c.Param("fileID") - - tgClient := utils.GetTgClient() - - tgClient.Workload++ - w := c.Writer r := c.Request + config := utils.GetConfig() + + fileID := c.Param("fileID") + + var tgClient *utils.Client + + var err error + if config.MultiClient { + tgClient = utils.GetBotClient() + tgClient.Workload++ + + } else { + val, _ := c.Get("jwtUser") + jwtUser := val.(*types.JWTClaims) + userId, _ := strconv.Atoi(jwtUser.Subject) + tgClient, err = utils.GetAuthClient(jwtUser.TgSession, userId) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } res, err := cache.CachedFunction(fs.GetFileByID, fmt.Sprintf("files:%s", fileID))(c) @@ -302,7 +317,9 @@ func (fs *FileService) GetFileStream(ctx context.Context) gin.HandlerFunc { } defer func() { - tgClient.Workload-- + if config.MultiClient { + tgClient.Workload-- + } }() } } diff --git a/types/main.go b/types/main.go index 2a724ba..6e2f0d8 100644 --- a/types/main.go +++ b/types/main.go @@ -1,6 +1,9 @@ package types -import "github.com/gotd/td/tg" +import ( + "github.com/go-jose/go-jose/v3/jwt" + "github.com/gotd/td/tg" +) type AppError struct { Error error @@ -13,3 +16,29 @@ type Part struct { Start int64 End int64 } + +type JWTClaims struct { + jwt.Claims + TgSession string `json:"tgSession"` + Name string `json:"name"` + UserName string `json:"userName"` + Bot bool `json:"bot"` + IsPremium bool `json:"isPremium"` +} + +type TgSession struct { + DcID int `json:"dcId"` + AuthKey string `json:"authKey"` + UserID string `json:"userId"` + Bot bool `json:"bot"` + UserName string `json:"userName"` + Name string `json:"name"` + IsPremium bool `json:"isPremium"` +} + +type Session struct { + Name string `json:"name"` + UserName string `json:"userName"` + IsPremium bool `json:"isPremium"` + Expires string `json:"expires"` +} diff --git a/utils/auth/jwe.go b/utils/auth/jwe.go new file mode 100644 index 0000000..6286167 --- /dev/null +++ b/utils/auth/jwe.go @@ -0,0 +1,62 @@ +package auth + +import ( + "encoding/json" + "os" + + "github.com/divyam234/teldrive-go/types" + "github.com/go-jose/go-jose/v3" +) + +func Encode(payload *types.JWTClaims) (string, error) { + + rcpt := jose.Recipient{ + Algorithm: jose.PBES2_HS256_A128KW, + Key: os.Getenv("JWT_SECRET"), + } + + enc, err := jose.NewEncrypter(jose.A128CBC_HS256, rcpt, nil) + + if err != nil { + return "", err + } + + jwt, _ := json.Marshal(payload) + + jweObject, err := enc.Encrypt(jwt) + + if err != nil { + return "", err + } + + jweToken, err := jweObject.CompactSerialize() + + if err != nil { + return "", err + } + return jweToken, nil +} + +func Decode(token string) (*types.JWTClaims, error) { + jwe, err := jose.ParseEncrypted(token) + if err != nil { + return nil, err + } + + decryptedData, err := jwe.Decrypt(os.Getenv("JWT_SECRET")) + + if err != nil { + return nil, err + } + + jwtToken := &types.JWTClaims{} + + err = json.Unmarshal(decryptedData, jwtToken) + + if err != nil { + return nil, err + } + + return jwtToken, nil + +} diff --git a/utils/config.go b/utils/config.go new file mode 100644 index 0000000..86adbc2 --- /dev/null +++ b/utils/config.go @@ -0,0 +1,29 @@ +package utils + +import ( + "github.com/kelseyhightower/envconfig" +) + +type MultiToken string + +type Config struct { + AppId int `envconfig:"APP_ID" required:"true"` + AppHash string `envconfig:"APP_HASH" required:"true"` + ChannelID int64 `envconfig:"CHANNEL_ID" required:"true"` + JwtSecret string `envconfig:"JWT_SECRET" required:"true"` + MultiClient bool `envconfig:"MULTI_CLIENT" default:"false"` + DatabaseUrl string `envconfig:"DATABASE_URL" required:"true"` +} + +var config Config + +func InitConfig() { + err := envconfig.Process("", &config) + if err != nil { + panic(err) + } +} + +func GetConfig() *Config { + return &config +} diff --git a/utils/logger.go b/utils/logger.go new file mode 100644 index 0000000..c7584e4 --- /dev/null +++ b/utils/logger.go @@ -0,0 +1,19 @@ +package utils + +import ( + "os" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var Logger *zap.Logger + +func InitializeLogger() { + config := zap.NewProductionEncoderConfig() + config.EncodeTime = zapcore.ISO8601TimeEncoder + consoleEncoder := zapcore.NewConsoleEncoder(config) + defaultLogLevel := zapcore.DebugLevel + core := zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), defaultLogLevel) + Logger = zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel)) +} diff --git a/utils/tgclient.go b/utils/tgclient.go index 193b871..948fc93 100644 --- a/utils/tgclient.go +++ b/utils/tgclient.go @@ -6,16 +6,15 @@ import ( "os" "path/filepath" "sort" - "strconv" "strings" "time" "github.com/gotd/contrib/bg" "github.com/gotd/contrib/middleware/ratelimit" + "github.com/gotd/td/session" "github.com/gotd/td/telegram" "github.com/pkg/errors" "go.uber.org/zap" - "go.uber.org/zap/zapcore" "golang.org/x/time/rate" ) @@ -27,17 +26,17 @@ type Client struct { var clients map[int]*Client -func initClient(appID int, appHash, clientName, sessionDir string) *telegram.Client { +func getBotClient(appID int, appHash, clientName, sessionDir string) *telegram.Client { sessionStorage := &telegram.FileSessionStorage{ Path: filepath.Join(sessionDir, clientName+".json"), } - options := telegram.Options{ SessionStorage: sessionStorage, Middlewares: []telegram.Middleware{ ratelimit.New(rate.Every(time.Millisecond*100), 5), }, + NoUpdates: true, } client := telegram.NewClient(appID, appHash, options) @@ -46,7 +45,7 @@ func initClient(appID int, appHash, clientName, sessionDir string) *telegram.Cli } -func startClient(ctx context.Context, client *Client, lg *zap.Logger) (bg.StopFunc, error) { +func startClient(ctx context.Context, client *Client) (bg.StopFunc, error) { stop, err := bg.Connect(client.Tg) @@ -64,60 +63,100 @@ func startClient(ctx context.Context, client *Client, lg *zap.Logger) (bg.StopFu tguser, _ = client.Tg.Self(ctx) } - lg.Info("started Client", zap.String("user", tguser.Username)) + Logger.Info("started Client", zap.String("user", tguser.Username)) return stop, nil } -func StartClients() { - - appID, err := strconv.Atoi(os.Getenv("APP_ID")) - - if err != nil { - return - } - - appHash := os.Getenv("APP_HASH") - - if appHash == "" { - return - } - - sessionDir := "sessions" - - if err := os.MkdirAll(sessionDir, 0700); err != nil { - return - } - - lg, _ := zap.NewDevelopment(zap.IncreaseLevel(zapcore.InfoLevel), zap.AddStacktrace(zapcore.FatalLevel)) - - var keysToSort []string - - for _, e := range os.Environ() { - if strings.HasPrefix(e, "MULTI_TOKEN") { - if i := strings.Index(e, "="); i >= 0 { - keysToSort = append(keysToSort, e[:i]) - } - } - } - - sort.Strings(keysToSort) +func StartBotTgClients() { clients = make(map[int]*Client) - for idx, key := range keysToSort { - client := initClient(appID, appHash, fmt.Sprintf("client%d", idx), sessionDir) - clients[idx] = &Client{Tg: client, Token: os.Getenv(key)} + if config.MultiClient { + sessionDir := "sessions" + + if err := os.MkdirAll(sessionDir, 0700); err != nil { + return + } + + var keysToSort []string + + for _, e := range os.Environ() { + if strings.HasPrefix(e, "MULTI_TOKEN") { + if i := strings.Index(e, "="); i >= 0 { + keysToSort = append(keysToSort, e[:i]) + } + } + } + + sort.Strings(keysToSort) + + for idx, key := range keysToSort { + client := getBotClient(config.AppId, config.AppHash, fmt.Sprintf("client%d", idx), sessionDir) + clients[idx] = &Client{Tg: client, Token: os.Getenv(key)} + } + + ctx := context.Background() + + for _, client := range clients { + go startClient(ctx, client) + } + } + +} + +func GetAuthClient(sessionStr string, userId int) (*Client, error) { + + if client, ok := clients[userId]; ok { + return client, nil } ctx := context.Background() - for _, client := range clients { - go startClient(ctx, client, lg) + data, err := session.TelethonSession(sessionStr) + + if err != nil { + return nil, err } + var ( + storage = new(session.StorageMemory) + loader = session.Loader{Storage: storage} + ) + + if err := loader.Save(ctx, data); err != nil { + return nil, err + } + + client := telegram.NewClient(config.AppId, config.AppHash, telegram.Options{ + SessionStorage: storage, + Middlewares: []telegram.Middleware{ + ratelimit.New(rate.Every(time.Millisecond*100), 5), + }, + NoUpdates: true, + }) + + _, err = bg.Connect(client) + + if err != nil { + return nil, err + } + + tguser, err := client.Self(ctx) + + if err != nil { + return nil, err + } + + Logger.Info("started Client", zap.String("user", tguser.Username)) + + tgClient := &Client{Tg: client} + + clients[int(tguser.GetID())] = tgClient + + return tgClient, nil } -func GetTgClient() *Client { +func GetBotClient() *Client { smallest := clients[0] for _, client := range clients { if client.Workload < smallest.Workload {