From 5b1432de0567fb7c2afdc56b0d845d932a261c87 Mon Sep 17 00:00:00 2001 From: Antonio Mika Date: Mon, 7 Oct 2024 21:47:09 -0400 Subject: [PATCH] Refactor --- auth/api.go | 11 +- cmd/scripts/analytics/analytics.go | 4 +- cmd/scripts/clean-object-store/clean.go | 5 +- cmd/scripts/shasum/shasum.go | 3 +- db/postgres/storage.go | 4 +- docker-compose.prod.yml | 2 +- feeds/config.go | 21 +- feeds/scp_hooks.go | 7 +- feeds/ssh.go | 16 +- filehandlers/assets/handler.go | 27 +- filehandlers/imgs/handler.go | 21 +- filehandlers/imgs/img.go | 9 +- filehandlers/post_handler.go | 19 +- filehandlers/router_handler.go | 2 +- filehandlers/util/pubkey_auth.go | 6 +- go.mod | 91 +++--- go.sum | 192 ++++++------ imgs/api.go | 3 +- imgs/cli.go | 14 +- imgs/config.go | 19 +- imgs/ssh.go | 15 +- pastes/api.go | 3 +- pastes/config.go | 19 +- pastes/scp_hooks.go | 5 +- pastes/ssh.go | 16 +- pgs/calc_route.go | 2 +- pgs/cli.go | 11 +- pgs/config.go | 23 +- pgs/ssh.go | 15 +- pgs/tunnel.go | 9 +- pgs/wish.go | 12 +- pico/cli.go | 22 +- pico/config.go | 3 +- pico/file_handler.go | 29 +- pico/ssh.go | 15 +- prose/api.go | 13 +- prose/cli.go | 14 +- prose/config.go | 25 +- prose/scp_hooks.go | 7 +- prose/ssh.go | 16 +- pubsub/cli.go | 4 +- pubsub/config.go | 9 +- pubsub/ssh.go | 10 +- shared/api.go | 3 +- shared/bucket.go | 2 +- shared/cmd.go | 37 --- shared/config.go | 14 +- shared/io.go | 35 --- shared/sendlog.go | 386 ------------------------ shared/util.go | 169 ----------- tui/createaccount/create.go | 9 +- tui/createkey/create.go | 8 +- tui/logs/logs.go | 29 +- tui/settings/settings.go | 4 +- tui/util.go | 12 +- ui/api.go | 15 +- 56 files changed, 456 insertions(+), 1040 deletions(-) delete mode 100644 shared/cmd.go delete mode 100644 shared/io.go delete mode 100644 shared/sendlog.go delete mode 100644 shared/util.go diff --git a/auth/api.go b/auth/api.go index 637c9fd5..0b4a0d6e 100644 --- a/auth/api.go +++ b/auth/api.go @@ -18,6 +18,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/db/postgres" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) type Client struct { @@ -647,13 +648,13 @@ type AuthCfg struct { } func StartApiServer() { - debug := shared.GetEnv("AUTH_DEBUG", "0") + debug := utils.GetEnv("AUTH_DEBUG", "0") cfg := &AuthCfg{ - DbURL: shared.GetEnv("DATABASE_URL", ""), + DbURL: utils.GetEnv("DATABASE_URL", ""), Debug: debug == "1", - Issuer: shared.GetEnv("AUTH_ISSUER", "pico.sh"), - Domain: shared.GetEnv("AUTH_DOMAIN", "http://0.0.0.0:3000"), - Port: shared.GetEnv("AUTH_WEB_PORT", "3000"), + Issuer: utils.GetEnv("AUTH_ISSUER", "pico.sh"), + Domain: utils.GetEnv("AUTH_DOMAIN", "http://0.0.0.0:3000"), + Port: utils.GetEnv("AUTH_WEB_PORT", "3000"), } logger := shared.CreateLogger("auth") diff --git a/cmd/scripts/analytics/analytics.go b/cmd/scripts/analytics/analytics.go index 9ad6634f..11c2fbb0 100644 --- a/cmd/scripts/analytics/analytics.go +++ b/cmd/scripts/analytics/analytics.go @@ -6,7 +6,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/db/postgres" - "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func main() { @@ -23,7 +23,7 @@ func main() { // By: "post_id", By: "user_id", Interval: "day", - Origin: shared.StartOfMonth(), + Origin: utils.StartOfMonth(), // Where: "AND (post_id IS NOT NULL OR (post_id IS NULL AND project_id IS NULL))", }, ) diff --git a/cmd/scripts/clean-object-store/clean.go b/cmd/scripts/clean-object-store/clean.go index a024e65f..5329506a 100644 --- a/cmd/scripts/clean-object-store/clean.go +++ b/cmd/scripts/clean-object-store/clean.go @@ -10,6 +10,7 @@ import ( "github.com/picosh/pico/pgs" "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" + "github.com/picosh/utils" ) func bail(err error) { @@ -27,7 +28,7 @@ type RmProject struct { // have a corresponding project inside our database. func main() { // to actually commit changes, set to true - writeEnv := shared.GetEnv("WRITE", "0") + writeEnv := utils.GetEnv("WRITE", "0") write := false if writeEnv == "1" { write = true @@ -102,7 +103,7 @@ func main() { } } - session := &shared.CmdSessionLogger{ + session := &utils.CmdSessionLogger{ Log: logger, } diff --git a/cmd/scripts/shasum/shasum.go b/cmd/scripts/shasum/shasum.go index d5df80e2..f691ae0c 100644 --- a/cmd/scripts/shasum/shasum.go +++ b/cmd/scripts/shasum/shasum.go @@ -6,6 +6,7 @@ import ( "github.com/picosh/pico/db/postgres" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func main() { @@ -24,7 +25,7 @@ func main() { empty := 0 diff := 0 for _, post := range posts { - nextShasum := shared.Shasum([]byte(post.Text)) + nextShasum := utils.Shasum([]byte(post.Text)) if post.Shasum == "" { empty += 1 } else if post.Shasum != nextShasum { diff --git a/db/postgres/storage.go b/db/postgres/storage.go index 3496d4a4..e982c320 100644 --- a/db/postgres/storage.go +++ b/db/postgres/storage.go @@ -14,7 +14,7 @@ import ( _ "github.com/lib/pq" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) var PAGER_SIZE = 15 @@ -1552,7 +1552,7 @@ func (me *PsqlDB) FindFeedItemsByPostID(postID string) ([]*db.FeedItem, error) { } func (me *PsqlDB) InsertProject(userID, name, projectDir string) (string, error) { - if !shared.IsValidSubdomain(name) { + if !utils.IsValidSubdomain(name) { return "", fmt.Errorf("'%s' is not a valid project name, must match /^[a-z0-9-]+$/", name) } diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 07015f34..2b6133a6 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -96,7 +96,7 @@ services: env_file: - .env.prod environment: - APP_DOMAIN: ${PUBSUB_DOMAIN:-send.pico.sh} + APP_DOMAIN: ${PUBSUB_DOMAIN:-pipe.pico.sh} APP_EMAIL: ${PUBSUB_EMAIL:-hello@pico.sh} volumes: - ${PUBSUB_CADDYFILE}:/etc/caddy/Caddyfile diff --git a/feeds/config.go b/feeds/config.go index 369b1d8e..8e8d7e6a 100644 --- a/feeds/config.go +++ b/feeds/config.go @@ -2,19 +2,20 @@ package feeds import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func NewConfigSite() *shared.ConfigSite { - debug := shared.GetEnv("FEEDS_DEBUG", "0") - domain := shared.GetEnv("FEEDS_DOMAIN", "feeds.pico.sh") - port := shared.GetEnv("FEEDS_WEB_PORT", "3000") - protocol := shared.GetEnv("FEEDS_PROTOCOL", "https") - storageDir := shared.GetEnv("IMGS_STORAGE_DIR", ".storage") - minioURL := shared.GetEnv("MINIO_URL", "") - minioUser := shared.GetEnv("MINIO_ROOT_USER", "") - minioPass := shared.GetEnv("MINIO_ROOT_PASSWORD", "") - dbURL := shared.GetEnv("DATABASE_URL", "") - sendgridKey := shared.GetEnv("SENDGRID_API_KEY", "") + debug := utils.GetEnv("FEEDS_DEBUG", "0") + domain := utils.GetEnv("FEEDS_DOMAIN", "feeds.pico.sh") + port := utils.GetEnv("FEEDS_WEB_PORT", "3000") + protocol := utils.GetEnv("FEEDS_PROTOCOL", "https") + storageDir := utils.GetEnv("IMGS_STORAGE_DIR", ".storage") + minioURL := utils.GetEnv("MINIO_URL", "") + minioUser := utils.GetEnv("MINIO_ROOT_USER", "") + minioPass := utils.GetEnv("MINIO_ROOT_PASSWORD", "") + dbURL := utils.GetEnv("DATABASE_URL", "") + sendgridKey := utils.GetEnv("SENDGRID_API_KEY", "") return &shared.ConfigSite{ Debug: debug == "1", diff --git a/feeds/scp_hooks.go b/feeds/scp_hooks.go index a01846f9..785bfd5b 100644 --- a/feeds/scp_hooks.go +++ b/feeds/scp_hooks.go @@ -11,6 +11,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/filehandlers" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) type FeedHooks struct { @@ -19,7 +20,7 @@ type FeedHooks struct { } func (p *FeedHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) { - if !shared.IsTextFile(string(data.Text)) { + if !utils.IsTextFile(string(data.Text)) { err := fmt.Errorf( "WARNING: (%s) invalid file must be plain text (utf-8), skipping", data.Filename, @@ -27,7 +28,7 @@ func (p *FeedHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) return false, err } - if !shared.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) { + if !utils.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) { extStr := strings.Join(p.Cfg.AllowedExt, ",") err := fmt.Errorf( "WARNING: (%s) invalid file, format must be (%s), skipping", @@ -44,7 +45,7 @@ func (p *FeedHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) err parsedText := shared.ListParseText(string(data.Text)) if parsedText.Title == "" { - data.Title = shared.ToUpper(data.Slug) + data.Title = utils.ToUpper(data.Slug) } else { data.Title = parsedText.Title } diff --git a/feeds/ssh.go b/feeds/ssh.go index 6ade5685..16f9755b 100644 --- a/feeds/ssh.go +++ b/feeds/ssh.go @@ -14,16 +14,16 @@ import ( "github.com/picosh/pico/db/postgres" "github.com/picosh/pico/filehandlers" "github.com/picosh/pico/filehandlers/util" - "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" wsh "github.com/picosh/pico/wish" + "github.com/picosh/send/auth" "github.com/picosh/send/list" "github.com/picosh/send/pipe" + wishrsync "github.com/picosh/send/protocols/rsync" + "github.com/picosh/send/protocols/scp" + "github.com/picosh/send/protocols/sftp" "github.com/picosh/send/proxy" - "github.com/picosh/send/send/auth" - wishrsync "github.com/picosh/send/send/rsync" - "github.com/picosh/send/send/scp" - "github.com/picosh/send/send/sftp" + "github.com/picosh/utils" ) func createRouter(handler *filehandlers.FileHandlerRouter) proxy.Router { @@ -52,9 +52,9 @@ func withProxy(handler *filehandlers.FileHandlerRouter, otherMiddleware ...wish. } func StartSshServer() { - host := shared.GetEnv("LISTS_HOST", "0.0.0.0") - port := shared.GetEnv("LISTS_SSH_PORT", "2222") - promPort := shared.GetEnv("LISTS_PROM_PORT", "9222") + host := utils.GetEnv("LISTS_HOST", "0.0.0.0") + port := utils.GetEnv("LISTS_SSH_PORT", "2222") + promPort := utils.GetEnv("LISTS_PROM_PORT", "9222") cfg := NewConfigSite() logger := cfg.Logger dbh := postgres.NewDB(cfg.DbURL, cfg.Logger) diff --git a/filehandlers/assets/handler.go b/filehandlers/assets/handler.go index 402b1851..d40caf30 100644 --- a/filehandlers/assets/handler.go +++ b/filehandlers/assets/handler.go @@ -22,7 +22,8 @@ import ( "github.com/picosh/pico/shared/storage" "github.com/picosh/pobj" sst "github.com/picosh/pobj/storage" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ignore "github.com/sabhiram/go-gitignore" ) @@ -91,7 +92,7 @@ func shouldIgnoreFile(fp, ignoreStr string) bool { } type FileData struct { - *utils.FileEntry + *sendutils.FileEntry User *db.User Bucket sst.Bucket Project *db.Project @@ -116,13 +117,13 @@ func (h *UploadAssetHandler) GetLogger() *slog.Logger { return h.Cfg.Logger } -func (h *UploadAssetHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileInfo, utils.ReaderAtCloser, error) { +func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) { user, err := futil.GetUser(s.Context()) if err != nil { return nil, nil, err } - fileInfo := &utils.VirtualFile{ + fileInfo := &sendutils.VirtualFile{ FName: filepath.Base(entry.Filepath), FIsDir: false, FSize: entry.Size, @@ -170,7 +171,7 @@ func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recur name = "/" } - info := &utils.VirtualFile{ + info := &sendutils.VirtualFile{ FName: name, FIsDir: true, } @@ -243,7 +244,7 @@ func (h *UploadAssetHandler) findDenylist(bucket sst.Bucket, project *db.Project return str, nil } -func (h *UploadAssetHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, error) { +func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) { user, err := futil.GetUser(s.Context()) if err != nil { h.Cfg.Logger.Error("user not found in ctx", "err", err.Error()) @@ -365,7 +366,7 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *utils.FileEntry) (strin ) fsize, err := h.writeAsset( - shared.NewMaxBytesReader(data.Reader, int64(sizeRemaining)), + utils.NewMaxBytesReader(data.Reader, int64(sizeRemaining)), data, ) if err != nil { @@ -373,9 +374,9 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *utils.FileEntry) (strin cerr := fmt.Errorf( "%s: storage size %.2fmb, storage max %.2fmb, file max %.2fmb", err, - shared.BytesToMB(int(curStorageSize)), - shared.BytesToMB(int(storageMax)), - shared.BytesToMB(int(fileMax)), + utils.BytesToMB(int(curStorageSize)), + utils.BytesToMB(int(storageMax)), + utils.BytesToMB(int(fileMax)), ) return "", cerr } @@ -393,15 +394,15 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *utils.FileEntry) (strin str := fmt.Sprintf( "%s (space: %.2f/%.2fGB, %.2f%%)", url, - shared.BytesToGB(int(nextStorageSize)), - shared.BytesToGB(maxSize), + utils.BytesToGB(int(nextStorageSize)), + utils.BytesToGB(maxSize), (float32(nextStorageSize)/float32(maxSize))*100, ) return str, nil } -func (h *UploadAssetHandler) Delete(s ssh.Session, entry *utils.FileEntry) error { +func (h *UploadAssetHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error { user, err := futil.GetUser(s.Context()) if err != nil { h.Cfg.Logger.Error("user not found in ctx", "err", err.Error()) diff --git a/filehandlers/imgs/handler.go b/filehandlers/imgs/handler.go index 9ef71b38..04ad2c6b 100644 --- a/filehandlers/imgs/handler.go +++ b/filehandlers/imgs/handler.go @@ -18,7 +18,8 @@ import ( "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" "github.com/picosh/pobj" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ) var Space = "imgs" @@ -29,7 +30,7 @@ type PostMetaData struct { Cur *db.Post Tags []string User *db.User - *utils.FileEntry + *sendutils.FileEntry FeatureFlag *db.FeatureFlag } @@ -47,7 +48,7 @@ func NewUploadImgHandler(dbpool db.DB, cfg *shared.ConfigSite, storage storage.S } } -func (h *UploadImgHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileInfo, utils.ReaderAtCloser, error) { +func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) { user, err := util.GetUser(s.Context()) if err != nil { return nil, nil, err @@ -64,7 +65,7 @@ func (h *UploadImgHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileI return nil, nil, err } - fileInfo := &utils.VirtualFile{ + fileInfo := &sendutils.VirtualFile{ FName: post.Filename, FIsDir: false, FSize: int64(post.FileSize), @@ -86,7 +87,7 @@ func (h *UploadImgHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileI return fileInfo, reader, nil } -func (h *UploadImgHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, error) { +func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) { logger := h.Cfg.Logger user, err := util.GetUser(s.Context()) if err != nil { @@ -123,8 +124,8 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, now := time.Now() fileSize := binary.Size(text) - shasum := shared.Shasum(text) - slug := shared.SanitizeFileExt(filename) + shasum := utils.Shasum(text) + slug := utils.SanitizeFileExt(filename) nextPost := db.Post{ Filename: filename, @@ -184,14 +185,14 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, str := fmt.Sprintf( "%s (space: %.2f/%.2fGB, %.2f%%)", url, - shared.BytesToGB(totalFileSize), - shared.BytesToGB(maxSize), + utils.BytesToGB(totalFileSize), + utils.BytesToGB(maxSize), (float32(totalFileSize)/float32(maxSize))*100, ) return str, nil } -func (h *UploadImgHandler) Delete(s ssh.Session, entry *utils.FileEntry) error { +func (h *UploadImgHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error { user, err := util.GetUser(s.Context()) if err != nil { return err diff --git a/filehandlers/imgs/img.go b/filehandlers/imgs/img.go index f49b1602..730441b2 100644 --- a/filehandlers/imgs/img.go +++ b/filehandlers/imgs/img.go @@ -10,7 +10,8 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/filehandlers/util" "github.com/picosh/pico/shared" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ) func (h *UploadImgHandler) validateImg(data *PostMetaData) (bool, error) { @@ -29,7 +30,7 @@ func (h *UploadImgHandler) validateImg(data *PostMetaData) (bool, error) { return false, fmt.Errorf("ERROR: user (%s) has exceeded (%d bytes) max (%d bytes)", data.User.Name, totalFileSize, storageMax) } - if !shared.IsExtAllowed(data.Filepath, h.Cfg.AllowedExt) { + if !utils.IsExtAllowed(data.Filepath, h.Cfg.AllowedExt) { extStr := strings.Join(h.Cfg.AllowedExt, ",") err := fmt.Errorf( "ERROR: (%s) invalid file, format must be (%s), skipping", @@ -59,8 +60,8 @@ func (h *UploadImgHandler) metaImg(data *PostMetaData) error { fname, _, err := h.Storage.PutObject( bucket, data.Filename, - utils.NopReaderAtCloser(reader), - &utils.FileEntry{}, + sendutils.NopReaderAtCloser(reader), + &sendutils.FileEntry{}, ) if err != nil { return err diff --git a/filehandlers/post_handler.go b/filehandlers/post_handler.go index 90941698..390f0e5f 100644 --- a/filehandlers/post_handler.go +++ b/filehandlers/post_handler.go @@ -15,7 +15,8 @@ import ( "github.com/picosh/pico/filehandlers/util" "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ) type PostMetaData struct { @@ -23,7 +24,7 @@ type PostMetaData struct { Cur *db.Post Tags []string User *db.User - FileEntry *utils.FileEntry + FileEntry *sendutils.FileEntry Aliases []string } @@ -46,7 +47,7 @@ func NewScpPostHandler(dbpool db.DB, cfg *shared.ConfigSite, hooks ScpFileHooks, } } -func (h *ScpUploadHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileInfo, utils.ReaderAtCloser, error) { +func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) { user, err := util.GetUser(s.Context()) if err != nil { return nil, nil, err @@ -62,19 +63,19 @@ func (h *ScpUploadHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileI return nil, nil, err } - fileInfo := &utils.VirtualFile{ + fileInfo := &sendutils.VirtualFile{ FName: post.Filename, FIsDir: false, FSize: int64(post.FileSize), FModTime: *post.UpdatedAt, } - reader := utils.NopReaderAtCloser(strings.NewReader(post.Text)) + reader := sendutils.NopReaderAtCloser(strings.NewReader(post.Text)) return fileInfo, reader, nil } -func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, error) { +func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) { logger := h.Cfg.Logger user, err := util.GetUser(s.Context()) if err != nil { @@ -106,9 +107,9 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, } now := time.Now() - slug := shared.SanitizeFileExt(filename) + slug := utils.SanitizeFileExt(filename) fileSize := binary.Size(origText) - shasum := shared.Shasum(origText) + shasum := utils.Shasum(origText) nextPost := db.Post{ Filename: filename, @@ -261,7 +262,7 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, return h.Cfg.FullPostURL(curl, user.Name, metadata.Slug), nil } -func (h *ScpUploadHandler) Delete(s ssh.Session, entry *utils.FileEntry) error { +func (h *ScpUploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error { logger := h.Cfg.Logger user, err := util.GetUser(s.Context()) if err != nil { diff --git a/filehandlers/router_handler.go b/filehandlers/router_handler.go index 46c84881..76dbbf85 100644 --- a/filehandlers/router_handler.go +++ b/filehandlers/router_handler.go @@ -12,7 +12,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/filehandlers/util" "github.com/picosh/pico/shared" - "github.com/picosh/send/send/utils" + "github.com/picosh/send/utils" ) type ReadWriteHandler interface { diff --git a/filehandlers/util/pubkey_auth.go b/filehandlers/util/pubkey_auth.go index 540d003e..aa9850fd 100644 --- a/filehandlers/util/pubkey_auth.go +++ b/filehandlers/util/pubkey_auth.go @@ -6,6 +6,7 @@ import ( "github.com/charmbracelet/ssh" "github.com/picosh/pico/db" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) type SshAuthHandler struct { @@ -25,10 +26,7 @@ func NewSshAuthHandler(dbpool db.DB, logger *slog.Logger, cfg *shared.ConfigSite func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool { shared.SetPublicKeyCtx(ctx, key) - pubkey, err := shared.KeyForKeyText(key) - if err != nil { - return false - } + pubkey := utils.KeyForKeyText(key) user, err := r.DBPool.FindUserForKey(ctx.User(), pubkey) if err != nil { diff --git a/go.mod b/go.mod index 1ccb9a87..d5ea40b7 100644 --- a/go.mod +++ b/go.mod @@ -30,15 +30,16 @@ require ( github.com/gorilla/feeds v1.1.2 github.com/lib/pq v1.10.9 github.com/microcosm-cc/bluemonday v1.0.26 - github.com/minio/minio-go/v7 v7.0.70 + github.com/minio/minio-go/v7 v7.0.77 github.com/mmcdole/gofeed v1.3.0 github.com/muesli/reflow v0.3.0 - github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5 + github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257 github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577 - github.com/picosh/pobj v0.0.0-20241005185823-c92bd8ee07f8 - github.com/picosh/pubsub v0.0.0-20241003170126-d92d74f10efe - github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc + github.com/picosh/pobj v0.0.0-20241008013754-bbbfc341e2cf + github.com/picosh/pubsub v0.0.0-20241008010300-a63fd95dc8ed + github.com/picosh/send v0.0.0-20241008013240-6fdbff00f848 github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e + github.com/picosh/utils v0.0.0-20241008004349-f48b50af554b github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 github.com/sendgrid/sendgrid-go v3.14.0+incompatible github.com/simplesurance/go-ip-anonymizer v0.0.0-20200429124537-35a880f8e87d @@ -49,7 +50,7 @@ require ( go.abhg.dev/goldmark/anchor v0.1.1 go.abhg.dev/goldmark/hashtag v0.3.1 go.abhg.dev/goldmark/toc v0.10.0 - golang.org/x/crypto v0.27.0 + golang.org/x/crypto v0.28.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -61,25 +62,25 @@ require ( github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/antoniomika/syncmap v1.0.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect - github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.11 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect + github.com/aws/aws-sdk-go-v2 v1.32.1 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.42 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.40 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.16 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.29 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.20 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.20 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.59.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect - github.com/aws/smithy-go v1.20.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.20 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.1 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.65.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.32.1 // indirect + github.com/aws/smithy-go v1.22.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -88,7 +89,7 @@ require ( github.com/charmbracelet/log v0.4.0 // indirect github.com/charmbracelet/x/ansi v0.3.2 // indirect github.com/charmbracelet/x/conpty v0.1.0 // indirect - github.com/charmbracelet/x/errors v0.0.0-20240919170804-a4978c8e603a // indirect + github.com/charmbracelet/x/errors v0.0.0-20241007193646-7cc13b2883e3 // indirect github.com/charmbracelet/x/input v0.2.0 // indirect github.com/charmbracelet/x/term v0.2.0 // indirect github.com/charmbracelet/x/termios v0.1.0 // indirect @@ -109,6 +110,7 @@ require ( github.com/gdamore/encoding v1.0.1 // indirect github.com/gdamore/tcell/v2 v2.7.4 // indirect github.com/go-errors/errors v1.5.1 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect @@ -120,16 +122,16 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/fs v0.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect + github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/minio/madmin-go/v3 v3.0.54 // indirect + github.com/minio/madmin-go/v3 v3.0.70 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/mmcdole/goxpp v1.1.1 // indirect github.com/mmcloughlin/md4 v0.1.2 // indirect @@ -137,39 +139,40 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/neurosnap/go-jpeg-image-structure v0.0.0-20221010133817-70b1c1ff679e // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/philhofer/fwd v1.1.2 // indirect + github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc // indirect github.com/pkg/sftp v1.13.6 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prom2json v1.3.3 // indirect + github.com/prometheus/prom2json v1.4.1 // indirect + github.com/prometheus/prometheus v0.54.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/rs/xid v1.5.0 // indirect - github.com/safchain/ethtool v0.3.0 // indirect + github.com/rs/xid v1.6.0 // indirect + github.com/safchain/ethtool v0.4.1 // indirect github.com/secure-io/sio-go v0.3.1 // indirect github.com/sendgrid/rest v2.6.9+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.5 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/tinylib/msgp v1.1.9 // indirect + github.com/tinylib/msgp v1.2.2 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.8.0 // indirect + github.com/tklauser/numcpus v0.9.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yuin/goldmark-emoji v1.0.2 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.6.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect + google.golang.org/protobuf v1.35.1 // indirect mvdan.cc/xurls/v2 v2.5.0 // indirect ) diff --git a/go.sum b/go.sum index b19b7262..bbaf8b6a 100644 --- a/go.sum +++ b/go.sum @@ -23,44 +23,44 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= -github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw= -github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= -github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.11 h1:FEDZD/Axt5tKSkPAs967KZ++MkvYdBqr0a+cetRbjLM= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.11/go.mod h1:dvlsbA32KfvCzqwTiX7maABgFek2RyUuYEJ3kyn/PmQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= +github.com/aws/aws-sdk-go-v2 v1.32.1 h1:8WuZ43ytA+TV6QEPT/R23mr7pWyI7bSSiEHdt9BS2Pw= +github.com/aws/aws-sdk-go-v2 v1.32.1/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= +github.com/aws/aws-sdk-go-v2/config v1.27.42 h1:Zsy9coUPuOsCWkjTvHpl2/DB9bptXtv7WeNPxvFr87s= +github.com/aws/aws-sdk-go-v2/config v1.27.42/go.mod h1:FGASs+PuJM2EY+8rt8qyQKLPbbX/S5oY+6WzJ/KE7ko= +github.com/aws/aws-sdk-go-v2/credentials v1.17.40 h1:RjnlA7t0p/IamxAM7FUJ5uS13Vszh4sjVGvsx91tGro= +github.com/aws/aws-sdk-go-v2/credentials v1.17.40/go.mod h1:dgpdnSs1Bp/atS6vLlW83h9xZPP+uSPB/27dFSgC1BM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.16 h1:fwrer1pJeaiia0CcOfWVbZxvj9Adc7rsuaMTwPR0DIA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.16/go.mod h1:XyEwwp8XI4zMar7MTnJ0Sk7qY/9aN8Hp929XhuX5SF8= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.29 h1:eyeHfJ9FAb7sd5ODTkjrfot3gS0Ln4vn/18l7zZMCik= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.29/go.mod h1:JpzRPe12SjlOmuqgi+/5RmgfbsWzDYdfxe3Abrk2kW8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.20 h1:OErdlGnt+hg3tTwGYAlKvFkKVUo/TXkoHcxDxuhYYU8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.20/go.mod h1:HsPfuL5gs+407ByRXBMgpYoyrV1sgMrzd18yMXQHJpo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.20 h1:822cE1CYSwY/EZnErlF46pyynuxvf1p+VydHRQW+XNs= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.20/go.mod h1:79/Tn7H7hYC5Gjz6fbnOV4OeBpkao7E8Tv95RO72pMM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 h1:mimdLQkIX1zr8GIPY1ZtALdBQGxcASiBd2MOp8m/dMc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16/go.mod h1:YHk6owoSwrIsok+cAH9PENCOGoH5PU2EllX4vLtSrsY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 h1:GckUnpm4EJOAio1c8o25a+b3lVfwVzC9gnSBqiiNmZM= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18/go.mod h1:Br6+bxfG33Dk3ynmkhsW2Z/t9D4+lRqdLDNCKi85w0U= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.59.0 h1:Cso4Ev/XauMVsbwdhYEoxg8rxZWw43CFqqaPB5w3W2c= -github.com/aws/aws-sdk-go-v2/service/s3 v1.59.0/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= -github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= -github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.20 h1:HO5UCCkLmeWkJZHLvLDfylKv8ca28XLAX3HojZz2shI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.20/go.mod h1:IO0HUM6Ouk/s7Rx3hiLtFU3mc+9OJFFygjsaxFBhAbk= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.1 h1:UeW3Ul28hkKvB3beWImBvO7U62tSmapxaqk8sX9SMCU= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.1/go.mod h1:TER/1DuTxSN6RFQpk3xfD9hK4A1gQ7ainfkwHV3LPtU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.1 h1:5vBMBTakOvtd8aNaicswcrr9qqCYUlasuzyoU6/0g8I= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.1/go.mod h1:WSUbDa5qdg05Q558KXx2Scb+EDvOPXT9gfET0fyrJSk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.1 h1:T6oOYbNQ+iqdtG1/mTJvMBg/YFyHR8Z8URyG3qK+Anc= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.1/go.mod h1:25CEM6c1e2vyLcr3fPritPsdsoMwNAOc9//M1QAwtDk= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.1 h1:HQR79P0F0C2YQOaS2Z+90YK9DH22z9D6Neplaj0yuy4= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.1/go.mod h1:xYVl5BX9Ws7+ZM58b3w0kq36TR1Dgw2OMkjSr6YTWXg= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.1 h1:aAIr0WhAgvKrxZtkBqne87Gjmd7/lJVTFkR2l2yuhL8= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.1/go.mod h1:8XhxGMWUfikJuginPQl5SGZ0LSJuNX3TCEQmFWZwHTM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.1 h1:J6kIsIkgFOaU6aKjigXJoue1XEHtKIIrpSh4vKdmRTs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.1/go.mod h1:2V2JLP7tXOmUbL3Hd1ojq+774t2KUAEQ35//shoNEL0= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.1 h1:q76Ig4OaJzVJGNUSGO3wjSTBS94g+EhHIbpY9rPvkxs= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.1/go.mod h1:664dajZ7uS7JMUMUG0R5bWbtN97KECNCVdFDdQ6Ipu8= +github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= +github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -91,8 +91,8 @@ github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyf github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U= github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ= -github.com/charmbracelet/x/errors v0.0.0-20240919170804-a4978c8e603a h1:IlWNrDYRP6lyttqsFHDhmo8NXggMwBuhvvCP+Wmb2a8= -github.com/charmbracelet/x/errors v0.0.0-20240919170804-a4978c8e603a/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0= +github.com/charmbracelet/x/errors v0.0.0-20241007193646-7cc13b2883e3 h1:nsBhzPXBqeXEGZ9ztveSIPdf790BcDikbaEH3vMglH4= +github.com/charmbracelet/x/errors v0.0.0-20241007193646-7cc13b2883e3/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0= github.com/charmbracelet/x/input v0.2.0 h1:1Sv+y/flcqUfUH2PXNIDKDIdT2G8smOnGOgawqhwy8A= github.com/charmbracelet/x/input v0.2.0/go.mod h1:KUSFIS6uQymtnr5lHVSOK9j8RvwTD4YHnWnzJUYnd/M= github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= @@ -102,8 +102,9 @@ github.com/charmbracelet/x/termios v0.1.0/go.mod h1:H/EVv/KRnrYjz+fCYa9bsKdqF3S8 github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/delthas/go-libnp v0.0.0-20221222161248-0e45ece1f878 h1:v8W8eW7eb2bHFXBA80UKcoe0TvEu46NlTHSDRvgAbMU= github.com/delthas/go-libnp v0.0.0-20221222161248-0e45ece1f878/go.mod h1:aGVXnhWpDlt5U4SphG97o1gszctZKvBTXy320E8Buw4= github.com/delthas/go-localeinfo v0.0.0-20221116001557-686a1e185118 h1:Xzf9ra1QRJXD62gwudjI2iBq7x9CusvHd83Dg2OnUmE= @@ -152,6 +153,8 @@ github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWE github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -189,23 +192,25 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI= -github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= +github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= +github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -223,12 +228,12 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= -github.com/minio/madmin-go/v3 v3.0.54 h1:Mwp6JYSY9GxbrUoMMij2rTzSBaCps575dlsuKO8D3yk= -github.com/minio/madmin-go/v3 v3.0.54/go.mod h1:IFAwr0XMrdsLovxAdCcuq/eoL4nRuMVQQv0iubJANQw= +github.com/minio/madmin-go/v3 v3.0.70 h1:zrFCXLcV6PR74JC0yytK4Dk2qsaCV8kXQoPTvcusR2k= +github.com/minio/madmin-go/v3 v3.0.70/go.mod h1:TOTc96ZkMknNhl+ReO/V68bQfgRGfH+8iy7YaDzHdXA= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g= -github.com/minio/minio-go/v7 v7.0.70/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo= +github.com/minio/minio-go/v7 v7.0.77 h1:GaGghJRg9nwDVlNbwYjSDJT1rqltQkBFDsypWX1v3Bw= +github.com/minio/minio-go/v7 v7.0.77/go.mod h1:AVM3IUN6WwKzmwBxVdjzhH8xq+f57JSbbvzqvUzR6eg= github.com/mmcdole/gofeed v1.3.0 h1:5yn+HeqlcvjMeAI4gu6T+crm7d0anY85+M+v6fIFNG4= github.com/mmcdole/gofeed v1.3.0/go.mod h1:9TGv2LcJhdXePDzxiuMnukhV2/zb6VtnZt1mS+SjkLE= github.com/mmcdole/goxpp v1.1.1 h1:RGIX+D6iQRIunGHrKqnA2+700XMCnNv0bAOOv5MUhx8= @@ -246,32 +251,32 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5 h1:NiONcKK0EV5gUZcnCiPMORaZA0eBDc+Fgepl9xl4lZ8= -github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= +github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257 h1:RNw/zu+CJemcRlDFPjElZUbY2UlI/MA2B3I6PM3Isiw= +github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577 h1:hVmVNttSLNloGsbFKVXAUHonXTd8KKrv30U/8UkloKI= github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577/go.mod h1:G3Cu1AW+dmRLDFpOi8eUAfc3cGoRHUjTkGjeRcndgl4= github.com/neurosnap/go-jpeg-image-structure v0.0.0-20221010133817-70b1c1ff679e h1:76Dng5ms0fR+26doKZAvNqhi2UPfnLxGfPIDEr+BBlM= github.com/neurosnap/go-jpeg-image-structure v0.0.0-20221010133817-70b1c1ff679e/go.mod h1:nZBDA7+RD63GDJwjZmxhxac65MJqiCIHUUUvdYOsFkk= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= -github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= +github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= +github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc h1:bvcsoOvaNHPquFnRkdraEo7+8t6bW7nWEhlALnwZPdI= github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc/go.mod h1:i0iR3W4GSm1PuvVxB9OH32E5jP+CYkVb2NQSe0JCtlo= -github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a h1:Cr1xODiyd/SjjBRtYA9VX6Do3D+w+DansQzkb4NGeyA= -github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a/go.mod h1:VIkR1MZBvxSK2OO47jikxikAO/sKb/vTmXX5ZuYTIvo= -github.com/picosh/pobj v0.0.0-20241005184424-366421c762d7 h1:QiKWMuxqhNKfOacqfZl0fJn7Oc53hIoB1WH7eluOqs0= -github.com/picosh/pobj v0.0.0-20241005184424-366421c762d7/go.mod h1:tPv/ydMnuXlGVpWUMvBlcWlyn/xu9PsVPdncYibweWY= -github.com/picosh/pobj v0.0.0-20241005185823-c92bd8ee07f8 h1:M6GjB28u/sThE3gyKx4V2iqrokdMJAr1pQ41Q3mK04I= -github.com/picosh/pobj v0.0.0-20241005185823-c92bd8ee07f8/go.mod h1:tPv/ydMnuXlGVpWUMvBlcWlyn/xu9PsVPdncYibweWY= -github.com/picosh/pubsub v0.0.0-20241003170126-d92d74f10efe h1:NQA2eXxqFPjVr/8DX073Vap5kMnJk3/AAAgt/jz8cyc= -github.com/picosh/pubsub v0.0.0-20241003170126-d92d74f10efe/go.mod h1:gWhwrStKWJNzp9i44Bc3YQmnC+pIKvI5dYWm1GRHJac= -github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc h1:IIsJuAFG2ju3cygKVKTIsYYZf21q5S3Dr1H4fGbfgJg= -github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM= +github.com/picosh/pobj v0.0.0-20241008013754-bbbfc341e2cf h1:Ul+LuTVXRimpIneOHez05k7VOV/lDVw37I18rceEplw= +github.com/picosh/pobj v0.0.0-20241008013754-bbbfc341e2cf/go.mod h1:cF+eAl4G1vU+WOD8cYCKaxokHo6MWmbR8J4/SJnvESg= +github.com/picosh/pubsub v0.0.0-20241008010300-a63fd95dc8ed h1:aBJeQoLvq/V3hX6bgWjuuTmGzgbPNYuuwaCWU4aSJcU= +github.com/picosh/pubsub v0.0.0-20241008010300-a63fd95dc8ed/go.mod h1:ajolgob5MxlHdp5HllF7u3rTlCgER4InqfP7M/xl6HQ= +github.com/picosh/send v0.0.0-20241008013240-6fdbff00f848 h1:VWbjNNOqpJ8AB3zdw+M5+XC/SINooWLGi6WCozKwt1o= +github.com/picosh/send v0.0.0-20241008013240-6fdbff00f848/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM= github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0 h1:pBRIbiCj7K6rGELijb//dYhyCo8A3fvxW5dijrJVtjs= github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0/go.mod h1:QaBDtybFC5gz7EG/9c3bgzuyW7W5W2rYLFZxWNuWk3Q= github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e h1:3rNSjBJ6VlvngWF58V/z0fPLH7WyzKpSboC6YznECgw= github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e/go.mod h1:UrDH/VCIc1wg/L6iY2zSYt4TiGw+25GsKSnkVkU40Dw= +github.com/picosh/utils v0.0.0-20241008004349-f48b50af554b h1:PvWk8Y7JhC1bK4Ns7FUFfcvi+BGZ+K07wTA2VDTmfDQ= +github.com/picosh/utils v0.0.0-20241008004349-f48b50af554b/go.mod h1:ftrp1FjbKK/mFnBAYGymA1QEtPlkA0+lWkPI5h0HKt4= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -279,16 +284,18 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prom2json v1.3.3 h1:IYfSMiZ7sSOfliBoo89PcufjWO4eAR0gznGcETyaUgo= -github.com/prometheus/prom2json v1.3.3/go.mod h1:Pv4yIPktEkK7btWsrUTWDDDrnpUrAELaOCj+oFwlgmc= +github.com/prometheus/prom2json v1.4.1 h1:7McxdrHgPEOtMwWjkKtd0v5AhpR2Q6QAnlHKVxq0+tQ= +github.com/prometheus/prom2json v1.4.1/go.mod h1:CzOQykSKFxXuC7ELUZHOHQvwKesQ3eN0p2PWLhFitQM= +github.com/prometheus/prometheus v0.54.1 h1:vKuwQNjnYN2/mDoWfHXDhAsz/68q/dQDb+YbcEqU7MQ= +github.com/prometheus/prometheus v0.54.1/go.mod h1:xlLByHhk2g3ycakQGrMaU8K7OySZx98BzeCR99991NY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -297,12 +304,12 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 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.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= -github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= -github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= +github.com/safchain/ethtool v0.4.1 h1:S6mEleTADqgynileXoiapt/nKnatyR6bmIHoF+h2ADo= +github.com/safchain/ethtool v0.4.1/go.mod h1:XLLnZmy4OCRTkksP/UiMjij96YmIsBfmBQcs7H6tA48= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc= github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs= @@ -327,12 +334,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU= -github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k= +github.com/tinylib/msgp v1.2.2 h1:iHiBE1tJQwFI740SPEPkGE8cfhNfrqOYRlH450BnC/4= +github.com/tinylib/msgp v1.2.2/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= +github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= github.com/x-way/crawlerdetect v0.2.21 h1:LORs0nEy+MWUsC3XvKf00hXyO7drB5w/hlGB8bztXbI= github.com/x-way/crawlerdetect v0.2.21/go.mod h1:DVupfue81iupuoUmFjIyDUqPqGaJhtZfYQDWoP1ZUR4= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= @@ -361,10 +368,10 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw= +golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -382,8 +389,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -407,8 +414,9 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -416,8 +424,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -425,8 +433,8 @@ golang.org/x/text v0.4.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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= @@ -435,13 +443,11 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 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= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.7/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= diff --git a/imgs/api.go b/imgs/api.go index 627d4413..35876cb2 100644 --- a/imgs/api.go +++ b/imgs/api.go @@ -17,6 +17,7 @@ import ( "github.com/picosh/pico/pgs" "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" + "github.com/picosh/utils" ) type PostPageData struct { @@ -219,7 +220,7 @@ func ImgRequest(w http.ResponseWriter, r *http.Request) { if ext == fext { // users might add the file extension when requesting an image // but we want to remove that - slug = shared.SanitizeFileExt(slug) + slug = utils.SanitizeFileExt(slug) break } } diff --git a/imgs/cli.go b/imgs/cli.go index 9a71e8f5..57529c8d 100644 --- a/imgs/cli.go +++ b/imgs/cli.go @@ -14,21 +14,21 @@ import ( "github.com/charmbracelet/wish" "github.com/google/uuid" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" "github.com/picosh/pico/tui/common" sst "github.com/picosh/pobj/storage" psub "github.com/picosh/pubsub" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ) func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { - var err error - key, err := shared.KeyText(s) - if err != nil { + if s.PublicKey() == nil { return nil, fmt.Errorf("key not found") } + key := utils.KeyForKeyText(s.PublicKey()) + user, err := dbpool.FindUserForKey(s.User(), key) if err != nil { return nil, err @@ -60,7 +60,7 @@ func flagCheck(cmd *flag.FlagSet, posArg string, cmdArgs []string) bool { type Cmd struct { User *db.User - Session shared.CmdSession + Session utils.CmdSession Log *slog.Logger Dbpool db.DB Write bool @@ -201,7 +201,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware { return func(sesh ssh.Session) { user, err := getUser(sesh, dbpool) if err != nil { - utils.ErrorHandler(sesh, err) + sendutils.ErrorHandler(sesh, err) return } diff --git a/imgs/config.go b/imgs/config.go index 7db2b0a7..e1af2889 100644 --- a/imgs/config.go +++ b/imgs/config.go @@ -2,18 +2,19 @@ package imgs import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func NewConfigSite() *shared.ConfigSite { - debug := shared.GetEnv("IMGS_DEBUG", "0") - domain := shared.GetEnv("IMGS_DOMAIN", "prose.sh") - port := shared.GetEnv("IMGS_WEB_PORT", "3000") - protocol := shared.GetEnv("IMGS_PROTOCOL", "https") - storageDir := shared.GetEnv("IMGS_STORAGE_DIR", ".storage") - minioURL := shared.GetEnv("MINIO_URL", "") - minioUser := shared.GetEnv("MINIO_ROOT_USER", "") - minioPass := shared.GetEnv("MINIO_ROOT_PASSWORD", "") - dbURL := shared.GetEnv("DATABASE_URL", "") + debug := utils.GetEnv("IMGS_DEBUG", "0") + domain := utils.GetEnv("IMGS_DOMAIN", "prose.sh") + port := utils.GetEnv("IMGS_WEB_PORT", "3000") + protocol := utils.GetEnv("IMGS_PROTOCOL", "https") + storageDir := utils.GetEnv("IMGS_STORAGE_DIR", ".storage") + minioURL := utils.GetEnv("MINIO_URL", "") + minioUser := utils.GetEnv("MINIO_ROOT_USER", "") + minioPass := utils.GetEnv("MINIO_ROOT_PASSWORD", "") + dbURL := utils.GetEnv("DATABASE_URL", "") cfg := shared.ConfigSite{ Debug: debug == "1", diff --git a/imgs/ssh.go b/imgs/ssh.go index 6a406053..7565cfd5 100644 --- a/imgs/ssh.go +++ b/imgs/ssh.go @@ -27,6 +27,7 @@ import ( "github.com/picosh/pico/shared/storage" psub "github.com/picosh/pubsub" "github.com/picosh/tunkit" + "github.com/picosh/utils" ) type ctxUserKey struct{} @@ -44,11 +45,7 @@ func setUserCtx(ctx ssh.Context, user *db.User) { func AuthHandler(dbh db.DB, log *slog.Logger) func(ssh.Context, ssh.PublicKey) bool { return func(ctx ssh.Context, key ssh.PublicKey) bool { - kk, err := shared.KeyForKeyText(key) - if err != nil { - log.Error("cannot get pubkey", "err", err) - return false - } + kk := utils.KeyForKeyText(key) user, err := dbh.FindUserForKey("", kk) if err != nil { @@ -263,10 +260,10 @@ func StartSshServer() { port = "2222" } dbUrl := os.Getenv("DATABASE_URL") - registryUrl := shared.GetEnv("REGISTRY_URL", "0.0.0.0:5000") - minioUrl := shared.GetEnv("MINIO_URL", "http://0.0.0.0:9000") - minioUser := shared.GetEnv("MINIO_ROOT_USER", "") - minioPass := shared.GetEnv("MINIO_ROOT_PASSWORD", "") + registryUrl := utils.GetEnv("REGISTRY_URL", "0.0.0.0:5000") + minioUrl := utils.GetEnv("MINIO_URL", "http://0.0.0.0:9000") + minioUser := utils.GetEnv("MINIO_ROOT_USER", "") + minioPass := utils.GetEnv("MINIO_ROOT_PASSWORD", "") logger := shared.CreateLogger("imgs") logger.Info("bootup", "registry", registryUrl, "minio", minioUrl) diff --git a/pastes/api.go b/pastes/api.go index 9771f6c6..86a230ca 100644 --- a/pastes/api.go +++ b/pastes/api.go @@ -12,6 +12,7 @@ import ( "github.com/picosh/pico/db/postgres" "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" + "github.com/picosh/utils" ) type PageData struct { @@ -123,7 +124,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) { Title: post.Filename, PublishAt: post.PublishAt.Format(time.DateOnly), PublishAtISO: post.PublishAt.Format(time.RFC3339), - UpdatedTimeAgo: shared.TimeAgo(post.UpdatedAt), + UpdatedTimeAgo: utils.TimeAgo(post.UpdatedAt), UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339), } postCollection = append(postCollection, p) diff --git a/pastes/config.go b/pastes/config.go index ca85c6be..2aa59a0b 100644 --- a/pastes/config.go +++ b/pastes/config.go @@ -2,18 +2,19 @@ package pastes import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func NewConfigSite() *shared.ConfigSite { - debug := shared.GetEnv("PASTES_DEBUG", "0") - domain := shared.GetEnv("PASTES_DOMAIN", "pastes.sh") - port := shared.GetEnv("PASTES_WEB_PORT", "3000") - dbURL := shared.GetEnv("DATABASE_URL", "") - protocol := shared.GetEnv("PASTES_PROTOCOL", "https") - storageDir := shared.GetEnv("IMGS_STORAGE_DIR", ".storage") - minioURL := shared.GetEnv("MINIO_URL", "") - minioUser := shared.GetEnv("MINIO_ROOT_USER", "") - minioPass := shared.GetEnv("MINIO_ROOT_PASSWORD", "") + debug := utils.GetEnv("PASTES_DEBUG", "0") + domain := utils.GetEnv("PASTES_DOMAIN", "pastes.sh") + port := utils.GetEnv("PASTES_WEB_PORT", "3000") + dbURL := utils.GetEnv("DATABASE_URL", "") + protocol := utils.GetEnv("PASTES_PROTOCOL", "https") + storageDir := utils.GetEnv("IMGS_STORAGE_DIR", ".storage") + minioURL := utils.GetEnv("MINIO_URL", "") + minioUser := utils.GetEnv("MINIO_ROOT_USER", "") + minioPass := utils.GetEnv("MINIO_ROOT_PASSWORD", "") return &shared.ConfigSite{ Debug: debug == "1", diff --git a/pastes/scp_hooks.go b/pastes/scp_hooks.go index adceb600..b053dd51 100644 --- a/pastes/scp_hooks.go +++ b/pastes/scp_hooks.go @@ -11,6 +11,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/filehandlers" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) var DEFAULT_EXPIRES_AT = 90 @@ -21,7 +22,7 @@ type FileHooks struct { } func (p *FileHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) { - if !shared.IsTextFile(string(data.Text)) { + if !utils.IsTextFile(string(data.Text)) { err := fmt.Errorf( "WARNING: (%s) invalid file must be plain text (utf-8), skipping", data.Filename, @@ -33,7 +34,7 @@ func (p *FileHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) } func (p *FileHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) error { - data.Title = shared.ToUpper(data.Slug) + data.Title = utils.ToUpper(data.Slug) // we want the slug to be the filename for pastes data.Slug = data.Filename diff --git a/pastes/ssh.go b/pastes/ssh.go index c8195a36..0e7795e6 100644 --- a/pastes/ssh.go +++ b/pastes/ssh.go @@ -14,16 +14,16 @@ import ( "github.com/picosh/pico/db/postgres" "github.com/picosh/pico/filehandlers" "github.com/picosh/pico/filehandlers/util" - "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" wsh "github.com/picosh/pico/wish" + "github.com/picosh/send/auth" "github.com/picosh/send/list" "github.com/picosh/send/pipe" + wishrsync "github.com/picosh/send/protocols/rsync" + "github.com/picosh/send/protocols/scp" + "github.com/picosh/send/protocols/sftp" "github.com/picosh/send/proxy" - "github.com/picosh/send/send/auth" - wishrsync "github.com/picosh/send/send/rsync" - "github.com/picosh/send/send/scp" - "github.com/picosh/send/send/sftp" + "github.com/picosh/utils" ) func createRouter(handler *filehandlers.FileHandlerRouter) proxy.Router { @@ -52,9 +52,9 @@ func withProxy(handler *filehandlers.FileHandlerRouter, otherMiddleware ...wish. } func StartSshServer() { - host := shared.GetEnv("PASTES_HOST", "0.0.0.0") - port := shared.GetEnv("PASTES_SSH_PORT", "2222") - promPort := shared.GetEnv("PASTES_PROM_PORT", "9222") + host := utils.GetEnv("PASTES_HOST", "0.0.0.0") + port := utils.GetEnv("PASTES_SSH_PORT", "2222") + promPort := utils.GetEnv("PASTES_PROM_PORT", "9222") cfg := NewConfigSite() logger := cfg.Logger dbh := postgres.NewDB(cfg.DbURL, cfg.Logger) diff --git a/pgs/calc_route.go b/pgs/calc_route.go index f8e2e911..8fae5fbf 100644 --- a/pgs/calc_route.go +++ b/pgs/calc_route.go @@ -10,7 +10,7 @@ import ( "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" - "github.com/picosh/send/send/utils" + "github.com/picosh/send/utils" ) type HttpReply struct { diff --git a/pgs/cli.go b/pgs/cli.go index faeef451..12582659 100644 --- a/pgs/cli.go +++ b/pgs/cli.go @@ -15,6 +15,7 @@ import ( "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" "github.com/picosh/pico/tui/common" + "github.com/picosh/utils" ) func projectTable(styles common.Styles, projects []*db.Project, width int) *table.Table { @@ -117,7 +118,7 @@ func getHelpText(styles common.Styles, userName string, width int) string { type Cmd struct { User *db.User - Session shared.CmdSession + Session utils.CmdSession Log *slog.Logger Store storage.StorageServe Dbpool db.DB @@ -209,7 +210,7 @@ func (c *Cmd) statsByProject(projectName string) error { FkID: project.ID, By: "project_id", Interval: "day", - Origin: shared.StartOfMonth(), + Origin: utils.StartOfMonth(), } summary, err := c.Dbpool.VisitSummary(opts) @@ -237,7 +238,7 @@ func (c *Cmd) statsSites() error { FkID: c.User.ID, By: "user_id", Interval: "day", - Origin: shared.StartOfMonth(), + Origin: utils.StartOfMonth(), } summary, err := c.Dbpool.VisitSummary(opts) @@ -325,8 +326,8 @@ func (c *Cmd) stats(cfgMaxSize uint64) error { headers := []string{"Used (GB)", "Quota (GB)", "Used (%)", "Projects (#)"} data := []string{ - fmt.Sprintf("%.4f", shared.BytesToGB(int(totalFileSize))), - fmt.Sprintf("%.4f", shared.BytesToGB(int(storageMax))), + fmt.Sprintf("%.4f", utils.BytesToGB(int(totalFileSize))), + fmt.Sprintf("%.4f", utils.BytesToGB(int(storageMax))), fmt.Sprintf("%.4f", (float32(totalFileSize)/float32(storageMax))*100), fmt.Sprintf("%d", len(projects)), } diff --git a/pgs/config.go b/pgs/config.go index 8795652a..ceb66ba4 100644 --- a/pgs/config.go +++ b/pgs/config.go @@ -2,21 +2,22 @@ package pgs import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) -var maxSize = uint64(25 * shared.MB) -var maxAssetSize = int64(10 * shared.MB) +var maxSize = uint64(25 * utils.MB) +var maxAssetSize = int64(10 * utils.MB) func NewConfigSite() *shared.ConfigSite { - domain := shared.GetEnv("PGS_DOMAIN", "pgs.sh") - port := shared.GetEnv("PGS_WEB_PORT", "3000") - protocol := shared.GetEnv("PGS_PROTOCOL", "https") - storageDir := shared.GetEnv("PGS_STORAGE_DIR", ".storage") - minioURL := shared.GetEnv("MINIO_URL", "") - minioUser := shared.GetEnv("MINIO_ROOT_USER", "") - minioPass := shared.GetEnv("MINIO_ROOT_PASSWORD", "") - dbURL := shared.GetEnv("DATABASE_URL", "") - secret := shared.GetEnv("PICO_SECRET", "") + domain := utils.GetEnv("PGS_DOMAIN", "pgs.sh") + port := utils.GetEnv("PGS_WEB_PORT", "3000") + protocol := utils.GetEnv("PGS_PROTOCOL", "https") + storageDir := utils.GetEnv("PGS_STORAGE_DIR", ".storage") + minioURL := utils.GetEnv("MINIO_URL", "") + minioUser := utils.GetEnv("MINIO_ROOT_USER", "") + minioPass := utils.GetEnv("MINIO_ROOT_PASSWORD", "") + dbURL := utils.GetEnv("DATABASE_URL", "") + secret := utils.GetEnv("PICO_SECRET", "") if secret == "" { panic("must provide PICO_SECRET environment variable") } diff --git a/pgs/ssh.go b/pgs/ssh.go index 600249c5..b6b142df 100644 --- a/pgs/ssh.go +++ b/pgs/ssh.go @@ -18,14 +18,15 @@ import ( "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" wsh "github.com/picosh/pico/wish" + "github.com/picosh/send/auth" "github.com/picosh/send/list" "github.com/picosh/send/pipe" + wishrsync "github.com/picosh/send/protocols/rsync" + "github.com/picosh/send/protocols/scp" + "github.com/picosh/send/protocols/sftp" "github.com/picosh/send/proxy" - "github.com/picosh/send/send/auth" - wishrsync "github.com/picosh/send/send/rsync" - "github.com/picosh/send/send/scp" - "github.com/picosh/send/send/sftp" "github.com/picosh/tunkit" + "github.com/picosh/utils" ) func createRouter(cfg *shared.ConfigSite, handler *uploadassets.UploadAssetHandler) proxy.Router { @@ -55,9 +56,9 @@ func withProxy(cfg *shared.ConfigSite, handler *uploadassets.UploadAssetHandler, } func StartSshServer() { - host := shared.GetEnv("PGS_HOST", "0.0.0.0") - port := shared.GetEnv("PGS_SSH_PORT", "2222") - promPort := shared.GetEnv("PGS_PROM_PORT", "9222") + host := utils.GetEnv("PGS_HOST", "0.0.0.0") + port := utils.GetEnv("PGS_SSH_PORT", "2222") + promPort := utils.GetEnv("PGS_PROM_PORT", "9222") cfg := NewConfigSite() logger := cfg.Logger dbpool := postgres.NewDB(cfg.DbURL, cfg.Logger) diff --git a/pgs/tunnel.go b/pgs/tunnel.go index e9bf24a6..037783b0 100644 --- a/pgs/tunnel.go +++ b/pgs/tunnel.go @@ -10,6 +10,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/shared" "github.com/picosh/pico/ui" + "github.com/picosh/utils" ) func allowPerm(proj *db.Project) bool { @@ -42,11 +43,9 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge { log.Error(err.Error(), "subdomain", subdomain) return http.HandlerFunc(shared.UnauthorizedHandler) } - pubkeyStr, err := shared.KeyForKeyText(pubkey) - if err != nil { - log.Error(err.Error()) - return http.HandlerFunc(shared.UnauthorizedHandler) - } + + pubkeyStr := utils.KeyForKeyText(pubkey) + log = log.With( "pubkey", pubkeyStr, ) diff --git a/pgs/wish.go b/pgs/wish.go index c32f6aec..b55b9bf4 100644 --- a/pgs/wish.go +++ b/pgs/wish.go @@ -11,18 +11,18 @@ import ( bm "github.com/charmbracelet/wish/bubbletea" "github.com/picosh/pico/db" uploadassets "github.com/picosh/pico/filehandlers/assets" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ) func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { - var err error - key, err := shared.KeyText(s) - if err != nil { + if s.PublicKey() == nil { return nil, fmt.Errorf("key not found") } + key := utils.KeyForKeyText(s.PublicKey()) + user, err := dbpool.FindUserForKey(s.User(), key) if err != nil { return nil, err @@ -88,7 +88,7 @@ func WishMiddleware(handler *uploadassets.UploadAssetHandler) wish.Middleware { user, err := getUser(sesh, dbpool) if err != nil { - utils.ErrorHandler(sesh, err) + sendutils.ErrorHandler(sesh, err) return } diff --git a/pico/cli.go b/pico/cli.go index 33a6ae05..e64f0e4e 100644 --- a/pico/cli.go +++ b/pico/cli.go @@ -15,15 +15,18 @@ import ( "github.com/picosh/pico/tui/common" "github.com/picosh/pico/tui/notifications" "github.com/picosh/pico/tui/plus" + "github.com/picosh/utils" + + pipeLogger "github.com/picosh/pubsub/log" ) func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { - var err error - key, err := shared.KeyText(s) - if err != nil { + if s.PublicKey() == nil { return nil, fmt.Errorf("key not found") } + key := utils.KeyForKeyText(s.PublicKey()) + user, err := dbpool.FindUserForKey(s.User(), key) if err != nil { return nil, err @@ -39,7 +42,7 @@ func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { type Cmd struct { User *db.User SshSession ssh.Session - Session shared.CmdSession + Session utils.CmdSession Log *slog.Logger Dbpool db.DB Write bool @@ -67,7 +70,14 @@ func (c *Cmd) notifications() error { } func (c *Cmd) logs(ctx context.Context) error { - stdoutPipe, err := shared.ConnectToLogs(ctx) + stdoutPipe, err := pipeLogger.ConnectToLogs(ctx, &pipeLogger.PubSubConnectionInfo{ + RemoteHost: utils.GetEnv("PICO_PIPE_ENDPOINT", "pipe.pico.sh:22"), + KeyLocation: utils.GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"), + KeyPassphrase: utils.GetEnv("PICO_PIPE_PASSPHRASE", ""), + RemoteHostname: utils.GetEnv("PICO_PIPE_REMOTE_HOST", "pipe.pico.sh"), + RemoteUser: utils.GetEnv("PICO_PIPE_USER", "pico"), + }) + if err != nil { return err } @@ -83,7 +93,7 @@ func (c *Cmd) logs(ctx context.Context) error { continue } - user := shared.AnyToStr(parsedData, "user") + user := utils.AnyToStr(parsedData, "user") if user == c.User.Name { wish.Println(c.SshSession, line) } diff --git a/pico/config.go b/pico/config.go index 0d2ff5fd..6af018bc 100644 --- a/pico/config.go +++ b/pico/config.go @@ -2,10 +2,11 @@ package pico import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func NewConfigSite() *shared.ConfigSite { - dbURL := shared.GetEnv("DATABASE_URL", "") + dbURL := utils.GetEnv("DATABASE_URL", "") return &shared.ConfigSite{ DbURL: dbURL, diff --git a/pico/file_handler.go b/pico/file_handler.go index 94e30ae8..f56578f6 100644 --- a/pico/file_handler.go +++ b/pico/file_handler.go @@ -16,7 +16,8 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/filehandlers/util" "github.com/picosh/pico/shared" - "github.com/picosh/send/send/utils" + sendutils "github.com/picosh/send/utils" + "github.com/picosh/utils" ) type UploadHandler struct { @@ -31,7 +32,7 @@ func NewUploadHandler(dbpool db.DB, cfg *shared.ConfigSite) *UploadHandler { } } -func (h *UploadHandler) getAuthorizedKeyFile(user *db.User) (*utils.VirtualFile, string, error) { +func (h *UploadHandler) getAuthorizedKeyFile(user *db.User) (*sendutils.VirtualFile, string, error) { keys, err := h.DBPool.FindKeysForUser(user) text := "" var modTime time.Time @@ -42,7 +43,7 @@ func (h *UploadHandler) getAuthorizedKeyFile(user *db.User) (*utils.VirtualFile, if err != nil { return nil, "", err } - fileInfo := &utils.VirtualFile{ + fileInfo := &sendutils.VirtualFile{ FName: "authorized_keys", FIsDir: false, FSize: int64(len(text)), @@ -51,11 +52,11 @@ func (h *UploadHandler) getAuthorizedKeyFile(user *db.User) (*utils.VirtualFile, return fileInfo, text, nil } -func (h *UploadHandler) Delete(s ssh.Session, entry *utils.FileEntry) error { +func (h *UploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error { return errors.New("unsupported") } -func (h *UploadHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileInfo, utils.ReaderAtCloser, error) { +func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) { user, err := util.GetUser(s.Context()) if err != nil { return nil, nil, err @@ -71,7 +72,7 @@ func (h *UploadHandler) Read(s ssh.Session, entry *utils.FileEntry) (os.FileInfo if err != nil { return nil, nil, err } - reader := utils.NopReaderAtCloser(strings.NewReader(text)) + reader := sendutils.NopReaderAtCloser(strings.NewReader(text)) return fileInfo, reader, nil } @@ -92,7 +93,7 @@ func (h *UploadHandler) List(s ssh.Session, fpath string, isDir bool, recursive name = "/" } - fileList = append(fileList, &utils.VirtualFile{ + fileList = append(fileList, &sendutils.VirtualFile{ FName: name, FIsDir: true, }) @@ -121,7 +122,7 @@ func (h *UploadHandler) GetLogger() *slog.Logger { func (h *UploadHandler) Validate(s ssh.Session) error { var err error - key, err := utils.KeyText(s) + key, err := sendutils.KeyText(s) if err != nil { return fmt.Errorf("key not found") } @@ -231,10 +232,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger, diff := authorizedKeysDiff(s.PublicKey(), curKeys, nextKeys) for _, pk := range diff.Add { - key, err := shared.KeyForKeyText(pk.Pk) - if err != nil { - continue - } + key := utils.KeyForKeyText(pk.Pk) wish.Errorf(s, "adding pubkey (%s)\n", key) logger.Info("adding pubkey", "pubkey", key) @@ -247,10 +245,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger, } for _, pk := range diff.Update { - key, err := shared.KeyForKeyText(pk.Pk) - if err != nil { - continue - } + key := utils.KeyForKeyText(pk.Pk) wish.Errorf(s, "updating pubkey with comment: %s (%s)\n", pk.Comment, key) logger.Info( @@ -280,7 +275,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger, return nil } -func (h *UploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string, error) { +func (h *UploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) { logger := h.Cfg.Logger user, err := util.GetUser(s.Context()) if err != nil { diff --git a/pico/ssh.go b/pico/ssh.go index cef0a3f6..cd6864ee 100644 --- a/pico/ssh.go +++ b/pico/ssh.go @@ -17,13 +17,14 @@ import ( "github.com/picosh/pico/shared" "github.com/picosh/pico/tui" wsh "github.com/picosh/pico/wish" + "github.com/picosh/send/auth" "github.com/picosh/send/list" "github.com/picosh/send/pipe" + wishrsync "github.com/picosh/send/protocols/rsync" + "github.com/picosh/send/protocols/scp" + "github.com/picosh/send/protocols/sftp" "github.com/picosh/send/proxy" - "github.com/picosh/send/send/auth" - wishrsync "github.com/picosh/send/send/rsync" - "github.com/picosh/send/send/scp" - "github.com/picosh/send/send/sftp" + "github.com/picosh/utils" ) func authHandler(ctx ssh.Context, key ssh.PublicKey) bool { @@ -58,9 +59,9 @@ func withProxy(cfg *shared.ConfigSite, handler *UploadHandler, cliHandler *CliHa } func StartSshServer() { - host := shared.GetEnv("PICO_HOST", "0.0.0.0") - port := shared.GetEnv("PICO_SSH_PORT", "2222") - promPort := shared.GetEnv("PICO_PROM_PORT", "9222") + host := utils.GetEnv("PICO_HOST", "0.0.0.0") + port := utils.GetEnv("PICO_SSH_PORT", "2222") + promPort := utils.GetEnv("PICO_PROM_PORT", "9222") cfg := NewConfigSite() logger := cfg.Logger dbpool := postgres.NewDB(cfg.DbURL, cfg.Logger) diff --git a/prose/api.go b/prose/api.go index 7a4a6434..d98e36f1 100644 --- a/prose/api.go +++ b/prose/api.go @@ -20,6 +20,7 @@ import ( "github.com/picosh/pico/imgs" "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" + "github.com/picosh/utils" ) type PageData struct { @@ -260,10 +261,10 @@ func blogHandler(w http.ResponseWriter, r *http.Request) { p := PostItemData{ URL: template.URL(cfg.FullPostURL(curl, post.Username, post.Slug)), BlogURL: template.URL(cfg.FullBlogURL(curl, post.Username)), - Title: shared.FilenameToTitle(post.Filename, post.Title), + Title: utils.FilenameToTitle(post.Filename, post.Title), PublishAt: post.PublishAt.Format(time.DateOnly), PublishAtISO: post.PublishAt.Format(time.RFC3339), - UpdatedTimeAgo: shared.TimeAgo(post.UpdatedAt), + UpdatedTimeAgo: utils.TimeAgo(post.UpdatedAt), UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339), } postCollection = append(postCollection, p) @@ -446,7 +447,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) { URL: template.URL(cfg.FullPostURL(curl, post.Username, post.Slug)), BlogURL: template.URL(cfg.FullBlogURL(curl, username)), Description: post.Description, - Title: shared.FilenameToTitle(post.Filename, post.Title), + Title: utils.FilenameToTitle(post.Filename, post.Title), Slug: post.Slug, PublishAt: post.PublishAt.Format(time.DateOnly), PublishAtISO: post.PublishAt.Format(time.RFC3339), @@ -595,12 +596,12 @@ func readHandler(w http.ResponseWriter, r *http.Request) { item := PostItemData{ URL: template.URL(cfg.FullPostURL(curl, post.Username, post.Slug)), BlogURL: template.URL(cfg.FullBlogURL(curl, post.Username)), - Title: shared.FilenameToTitle(post.Filename, post.Title), + Title: utils.FilenameToTitle(post.Filename, post.Title), Description: post.Description, Username: post.Username, PublishAt: post.PublishAt.Format(time.DateOnly), PublishAtISO: post.PublishAt.Format(time.RFC3339), - UpdatedTimeAgo: shared.TimeAgo(post.UpdatedAt), + UpdatedTimeAgo: utils.TimeAgo(post.UpdatedAt), UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339), } data.Posts = append(data.Posts, item) @@ -725,7 +726,7 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) { item := &feeds.Item{ Id: feedId, - Title: shared.FilenameToTitle(post.Filename, post.Title), + Title: utils.FilenameToTitle(post.Filename, post.Title), Link: &feeds.Link{Href: realUrl}, Content: tpl.String(), Updated: *post.UpdatedAt, diff --git a/prose/cli.go b/prose/cli.go index 7a98a7bb..e603d615 100644 --- a/prose/cli.go +++ b/prose/cli.go @@ -10,17 +10,17 @@ import ( "github.com/charmbracelet/wish" bm "github.com/charmbracelet/wish/bubbletea" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" + "github.com/picosh/utils" ) func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { - var err error - key, err := shared.KeyText(s) - if err != nil { + if s.PublicKey() == nil { return nil, fmt.Errorf("key not found") } + key := utils.KeyForKeyText(s.PublicKey()) + user, err := dbpool.FindUserForKey(s.User(), key) if err != nil { return nil, err @@ -35,7 +35,7 @@ func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { type Cmd struct { User *db.User - Session shared.CmdSession + Session utils.CmdSession Log *slog.Logger Dbpool db.DB Styles common.Styles @@ -62,7 +62,7 @@ func (c *Cmd) statsByPost(postSlug string) error { FkID: post.ID, By: "post_id", Interval: "day", - Origin: shared.StartOfMonth(), + Origin: utils.StartOfMonth(), } summary, err := c.Dbpool.VisitSummary(opts) @@ -90,7 +90,7 @@ func (c *Cmd) stats() error { FkID: c.User.ID, By: "user_id", Interval: "day", - Origin: shared.StartOfMonth(), + Origin: utils.StartOfMonth(), Where: "AND (post_id IS NOT NULL OR (post_id IS NULL AND project_id IS NULL))", } diff --git a/prose/config.go b/prose/config.go index 46e837a5..878eb9b6 100644 --- a/prose/config.go +++ b/prose/config.go @@ -2,21 +2,22 @@ package prose import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func NewConfigSite() *shared.ConfigSite { - debug := shared.GetEnv("PROSE_DEBUG", "0") - domain := shared.GetEnv("PROSE_DOMAIN", "prose.sh") - port := shared.GetEnv("PROSE_WEB_PORT", "3000") - protocol := shared.GetEnv("PROSE_PROTOCOL", "https") - storageDir := shared.GetEnv("IMGS_STORAGE_DIR", ".storage") - minioURL := shared.GetEnv("MINIO_URL", "") - minioUser := shared.GetEnv("MINIO_ROOT_USER", "") - minioPass := shared.GetEnv("MINIO_ROOT_PASSWORD", "") - dbURL := shared.GetEnv("DATABASE_URL", "") - maxSize := uint64(500 * shared.MB) - maxImgSize := int64(10 * shared.MB) - secret := shared.GetEnv("PICO_SECRET", "") + debug := utils.GetEnv("PROSE_DEBUG", "0") + domain := utils.GetEnv("PROSE_DOMAIN", "prose.sh") + port := utils.GetEnv("PROSE_WEB_PORT", "3000") + protocol := utils.GetEnv("PROSE_PROTOCOL", "https") + storageDir := utils.GetEnv("IMGS_STORAGE_DIR", ".storage") + minioURL := utils.GetEnv("MINIO_URL", "") + minioUser := utils.GetEnv("MINIO_ROOT_USER", "") + minioPass := utils.GetEnv("MINIO_ROOT_PASSWORD", "") + dbURL := utils.GetEnv("DATABASE_URL", "") + maxSize := uint64(500 * utils.MB) + maxImgSize := int64(10 * utils.MB) + secret := utils.GetEnv("PICO_SECRET", "") if secret == "" { panic("must provide PICO_SECRET environment variable") } diff --git a/prose/scp_hooks.go b/prose/scp_hooks.go index 577790c9..b2b38d21 100644 --- a/prose/scp_hooks.go +++ b/prose/scp_hooks.go @@ -10,6 +10,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/filehandlers" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) type MarkdownHooks struct { @@ -18,7 +19,7 @@ type MarkdownHooks struct { } func (p *MarkdownHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) { - if !shared.IsTextFile(data.Text) { + if !utils.IsTextFile(data.Text) { err := fmt.Errorf( "WARNING: (%s) invalid file must be plain text (utf-8), skipping", data.Filename, @@ -33,7 +34,7 @@ func (p *MarkdownHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaD return true, nil } - if !shared.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) { + if !utils.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) { extStr := strings.Join(p.Cfg.AllowedExt, ",") err := fmt.Errorf( "WARNING: (%s) invalid file, format must be (%s), skipping", @@ -53,7 +54,7 @@ func (p *MarkdownHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) } if parsedText.Title == "" { - data.Title = shared.ToUpper(data.Slug) + data.Title = utils.ToUpper(data.Slug) } else { data.Title = parsedText.Title } diff --git a/prose/ssh.go b/prose/ssh.go index 47f296cc..3e57c16c 100644 --- a/prose/ssh.go +++ b/prose/ssh.go @@ -15,16 +15,16 @@ import ( "github.com/picosh/pico/filehandlers" uploadimgs "github.com/picosh/pico/filehandlers/imgs" "github.com/picosh/pico/filehandlers/util" - "github.com/picosh/pico/shared" "github.com/picosh/pico/shared/storage" wsh "github.com/picosh/pico/wish" + "github.com/picosh/send/auth" "github.com/picosh/send/list" "github.com/picosh/send/pipe" + wishrsync "github.com/picosh/send/protocols/rsync" + "github.com/picosh/send/protocols/scp" + "github.com/picosh/send/protocols/sftp" "github.com/picosh/send/proxy" - "github.com/picosh/send/send/auth" - wishrsync "github.com/picosh/send/send/rsync" - "github.com/picosh/send/send/scp" - "github.com/picosh/send/send/sftp" + "github.com/picosh/utils" ) func createRouter(handler *filehandlers.FileHandlerRouter, cliHandler *CliHandler) proxy.Router { @@ -54,9 +54,9 @@ func withProxy(handler *filehandlers.FileHandlerRouter, cliHandler *CliHandler, } func StartSshServer() { - host := shared.GetEnv("PROSE_HOST", "0.0.0.0") - port := shared.GetEnv("PROSE_SSH_PORT", "2222") - promPort := shared.GetEnv("PROSE_PROM_PORT", "9222") + host := utils.GetEnv("PROSE_HOST", "0.0.0.0") + port := utils.GetEnv("PROSE_SSH_PORT", "2222") + promPort := utils.GetEnv("PROSE_PROM_PORT", "9222") cfg := NewConfigSite() logger := cfg.Logger dbh := postgres.NewDB(cfg.DbURL, cfg.Logger) diff --git a/pubsub/cli.go b/pubsub/cli.go index cb1e11df..ba2423b4 100644 --- a/pubsub/cli.go +++ b/pubsub/cli.go @@ -17,7 +17,7 @@ import ( "github.com/picosh/pico/db" "github.com/picosh/pico/shared" psub "github.com/picosh/pubsub" - "github.com/picosh/send/send/utils" + "github.com/picosh/send/utils" ) func flagSet(cmdName string, sesh ssh.Session) *flag.FlagSet { @@ -48,7 +48,7 @@ func NewTabWriter(out io.Writer) *tabwriter.Writer { func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { var err error - key, err := shared.KeyText(s) + key, err := utils.KeyText(s) if err != nil { return nil, fmt.Errorf("key not found") } diff --git a/pubsub/config.go b/pubsub/config.go index 2290116e..dfbbe865 100644 --- a/pubsub/config.go +++ b/pubsub/config.go @@ -2,13 +2,14 @@ package pubsub import ( "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) func NewConfigSite() *shared.ConfigSite { - domain := shared.GetEnv("PUBSUB_DOMAIN", "send.pico.sh") - port := shared.GetEnv("PUBSUB_WEB_PORT", "3000") - dbURL := shared.GetEnv("DATABASE_URL", "") - protocol := shared.GetEnv("PUBSUB_PROTOCOL", "https") + domain := utils.GetEnv("PUBSUB_DOMAIN", "pipe.pico.sh") + port := utils.GetEnv("PUBSUB_WEB_PORT", "3000") + dbURL := utils.GetEnv("DATABASE_URL", "") + protocol := utils.GetEnv("PUBSUB_PROTOCOL", "https") return &shared.ConfigSite{ Domain: domain, diff --git a/pubsub/ssh.go b/pubsub/ssh.go index 3b61b6ef..3d55c4f3 100644 --- a/pubsub/ssh.go +++ b/pubsub/ssh.go @@ -12,16 +12,16 @@ import ( "github.com/charmbracelet/wish" "github.com/picosh/pico/db/postgres" "github.com/picosh/pico/filehandlers/util" - "github.com/picosh/pico/shared" wsh "github.com/picosh/pico/wish" psub "github.com/picosh/pubsub" + "github.com/picosh/utils" ) func StartSshServer() { - host := shared.GetEnv("PUBSUB_HOST", "0.0.0.0") - port := shared.GetEnv("PUBSUB_SSH_PORT", "2222") - portOverride := shared.GetEnv("PUBSUB_SSH_PORT_OVERRIDE", port) - promPort := shared.GetEnv("PUBSUB_PROM_PORT", "9222") + host := utils.GetEnv("PUBSUB_HOST", "0.0.0.0") + port := utils.GetEnv("PUBSUB_SSH_PORT", "2222") + portOverride := utils.GetEnv("PUBSUB_SSH_PORT_OVERRIDE", port) + promPort := utils.GetEnv("PUBSUB_PROM_PORT", "9222") cfg := NewConfigSite() logger := cfg.Logger dbh := postgres.NewDB(cfg.DbURL, cfg.Logger) diff --git a/shared/api.go b/shared/api.go index b555560e..96a4e68d 100644 --- a/shared/api.go +++ b/shared/api.go @@ -10,6 +10,7 @@ import ( "github.com/charmbracelet/ssh" "github.com/picosh/pico/db" + "github.com/picosh/utils" ) func CorsHeaders(headers http.Header) { @@ -43,7 +44,7 @@ type UserApi struct { func NewUserApi(user *db.User, pubkey ssh.PublicKey) *UserApi { return &UserApi{ User: user, - Fingerprint: KeyForSha256(pubkey), + Fingerprint: utils.KeyForSha256(pubkey), } } diff --git a/shared/bucket.go b/shared/bucket.go index 1257b551..99a9c263 100644 --- a/shared/bucket.go +++ b/shared/bucket.go @@ -6,7 +6,7 @@ import ( "path/filepath" "strings" - "github.com/picosh/send/send/utils" + "github.com/picosh/send/utils" ) func GetImgsBucketName(userID string) string { diff --git a/shared/cmd.go b/shared/cmd.go deleted file mode 100644 index 0969e0c5..00000000 --- a/shared/cmd.go +++ /dev/null @@ -1,37 +0,0 @@ -package shared - -import ( - "fmt" - "io" - "log/slog" - "os" -) - -type CmdSessionLogger struct { - Log *slog.Logger -} - -func (c *CmdSessionLogger) Write(out []byte) (int, error) { - c.Log.Info(string(out)) - return 0, nil -} - -func (c *CmdSessionLogger) Exit(code int) error { - os.Exit(code) - return fmt.Errorf("panic %d", code) -} - -func (c *CmdSessionLogger) Close() error { - return fmt.Errorf("closing") -} - -func (c *CmdSessionLogger) Stderr() io.ReadWriter { - return nil -} - -type CmdSession interface { - Write([]byte) (int, error) - Exit(code int) error - Close() error - Stderr() io.ReadWriter -} diff --git a/shared/config.go b/shared/config.go index 868a88c4..61dabb05 100644 --- a/shared/config.go +++ b/shared/config.go @@ -11,6 +11,9 @@ import ( "strings" "github.com/picosh/pico/db" + "github.com/picosh/utils" + + pipeLogger "github.com/picosh/pubsub/log" ) var DefaultEmail = "hello@pico.sh" @@ -274,8 +277,15 @@ func CreateLogger(space string) *slog.Logger { newLogger := log - if strings.ToLower(GetEnv("PICO_SENDLOG_ENABLED", "true")) == "true" { - newLog, err := SendLogRegister(log, 100) + if strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true" { + newLog, err := pipeLogger.SendLogRegister(log, &pipeLogger.PubSubConnectionInfo{ + RemoteHost: utils.GetEnv("PICO_PIPE_ENDPOINT", "pipe.pico.sh:22"), + KeyLocation: utils.GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"), + KeyPassphrase: utils.GetEnv("PICO_PIPE_PASSPHRASE", ""), + RemoteHostname: utils.GetEnv("PICO_PIPE_REMOTE_HOST", "pipe.pico.sh"), + RemoteUser: utils.GetEnv("PICO_PIPE_USER", "pico"), + }, 100) + if err == nil { newLogger = newLog } else { diff --git a/shared/io.go b/shared/io.go deleted file mode 100644 index 84bf5a59..00000000 --- a/shared/io.go +++ /dev/null @@ -1,35 +0,0 @@ -package shared - -import ( - "errors" - "fmt" - "io" -) - -// Throws an error if the reader is bigger than limit. -var ErrSizeExceeded = errors.New("stream size exceeded") - -type MaxBytesReader struct { - io.Reader // reader object - Limit int64 - N int64 // max bytes remaining. -} - -func NewMaxBytesReader(r io.Reader, limit int64) *MaxBytesReader { - return &MaxBytesReader{r, limit, limit} -} - -func (b *MaxBytesReader) Read(p []byte) (n int, err error) { - if b.N <= 0 { - err := fmt.Errorf("%w: %.2fmb", ErrSizeExceeded, BytesToMB(int(b.Limit))) - return 0, err - } - - if int64(len(p)) > b.N { - p = p[0:b.N] - } - - n, err = b.Reader.Read(p) - b.N -= int64(n) - return -} diff --git a/shared/sendlog.go b/shared/sendlog.go deleted file mode 100644 index bd032dfb..00000000 --- a/shared/sendlog.go +++ /dev/null @@ -1,386 +0,0 @@ -package shared - -import ( - "context" - "errors" - "fmt" - "io" - "log/slog" - "net" - "os" - "path/filepath" - "slices" - "strings" - "sync" - "time" - - "golang.org/x/crypto/ssh" -) - -type MultiHandler struct { - Handlers []slog.Handler - mu sync.Mutex -} - -func (m *MultiHandler) Enabled(ctx context.Context, l slog.Level) bool { - m.mu.Lock() - defer m.mu.Unlock() - - for _, h := range m.Handlers { - if h.Enabled(ctx, l) { - return true - } - } - - return false -} - -func (m *MultiHandler) Handle(ctx context.Context, r slog.Record) error { - m.mu.Lock() - defer m.mu.Unlock() - - var errs []error - for _, h := range m.Handlers { - if h.Enabled(ctx, r.Level) { - errs = append(errs, h.Handle(ctx, r.Clone())) - } - } - - return errors.Join(errs...) -} - -func (m *MultiHandler) WithAttrs(attrs []slog.Attr) slog.Handler { - m.mu.Lock() - defer m.mu.Unlock() - - var handlers []slog.Handler - - for _, h := range m.Handlers { - handlers = append(handlers, h.WithAttrs(slices.Clone(attrs))) - } - - return &MultiHandler{ - Handlers: handlers, - } -} - -func (m *MultiHandler) WithGroup(name string) slog.Handler { - if name == "" { - return m - } - - m.mu.Lock() - defer m.mu.Unlock() - - var handlers []slog.Handler - - for _, h := range m.Handlers { - handlers = append(handlers, h.WithGroup(name)) - } - - return &MultiHandler{ - Handlers: handlers, - } -} - -type SendLogWriter struct { - SSHClient *ssh.Client - Session *ssh.Session - StdinPipe io.WriteCloser - Done chan struct{} - Messages chan []byte - Timeout time.Duration - BufferSize int - closeOnce sync.Once - closeMessageOnce sync.Once - startOnce sync.Once - connecMu sync.Mutex -} - -func (c *SendLogWriter) Close() error { - c.connecMu.Lock() - defer c.connecMu.Unlock() - - if c.Done != nil { - c.closeOnce.Do(func() { - close(c.Done) - }) - } - - if c.Messages != nil { - c.closeMessageOnce.Do(func() { - close(c.Messages) - }) - } - - var errs []error - - if c.StdinPipe != nil { - errs = append(errs, c.StdinPipe.Close()) - } - - if c.Session != nil { - errs = append(errs, c.Session.Close()) - } - - if c.SSHClient != nil { - errs = append(errs, c.SSHClient.Close()) - } - - return errors.Join(errs...) -} - -func (c *SendLogWriter) Open() error { - c.Close() - - c.connecMu.Lock() - - c.Done = make(chan struct{}) - c.Messages = make(chan []byte, c.BufferSize) - - sshClient, err := CreateSSHClient( - GetEnv("PICO_SENDLOG_ENDPOINT", "send.pico.sh:22"), - GetEnv("PICO_SENDLOG_KEY", "ssh_data/term_info_ed25519"), - GetEnv("PICO_SENDLOG_PASSPHRASE", ""), - GetEnv("PICO_SENDLOG_REMOTE_HOST", "send.pico.sh"), - GetEnv("PICO_SENDLOG_USER", "pico"), - ) - if err != nil { - c.connecMu.Unlock() - return err - } - - session, err := sshClient.NewSession() - if err != nil { - c.connecMu.Unlock() - return err - } - - stdinPipe, err := session.StdinPipe() - if err != nil { - c.connecMu.Unlock() - return err - } - - err = session.Start("pub log-drain -b=false") - if err != nil { - c.connecMu.Unlock() - return err - } - - c.SSHClient = sshClient - c.Session = session - c.StdinPipe = stdinPipe - - c.closeOnce = sync.Once{} - c.startOnce = sync.Once{} - - c.connecMu.Unlock() - - c.Start() - - return nil -} - -func (c *SendLogWriter) Start() { - c.startOnce.Do(func() { - go func() { - defer c.Reconnect() - - for { - select { - case data, ok := <-c.Messages: - _, err := c.StdinPipe.Write(data) - if !ok || err != nil { - slog.Error("received error on write, reopening logger", "error", err) - return - } - case <-c.Done: - return - } - } - }() - }) -} - -func (c *SendLogWriter) Write(data []byte) (int, error) { - var ( - n int - err error - ) - - ok := c.connecMu.TryLock() - - if !ok { - return n, fmt.Errorf("unable to acquire lock to write") - } - - defer c.connecMu.Unlock() - - if c.Messages == nil || c.Done == nil { - return n, fmt.Errorf("logger not viable") - } - - select { - case c.Messages <- slices.Clone(data): - n = len(data) - case <-time.After(c.Timeout): - err = fmt.Errorf("unable to send data within timeout") - case <-c.Done: - break - } - - return n, err -} - -func (c *SendLogWriter) Reconnect() { - go func() { - for { - err := c.Open() - if err != nil { - slog.Error("unable to open send logger. retrying in 10 seconds", "error", err) - } else { - return - } - - <-time.After(10 * time.Second) - } - }() -} - -func CreateSSHClient(remoteHost string, keyLocation string, keyPassphrase string, remoteHostname string, remoteUser string) (*ssh.Client, error) { - if !strings.Contains(remoteHost, ":") { - remoteHost += ":22" - } - - rawConn, err := net.Dial("tcp", remoteHost) - if err != nil { - return nil, err - } - - keyPath, err := filepath.Abs(keyLocation) - if err != nil { - return nil, err - } - - f, err := os.Open(keyPath) - if err != nil { - return nil, err - } - defer f.Close() - - data, err := io.ReadAll(f) - if err != nil { - return nil, err - } - - var signer ssh.Signer - - if keyPassphrase != "" { - signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(keyPassphrase)) - } else { - signer, err = ssh.ParsePrivateKey(data) - } - - if err != nil { - return nil, err - } - - sshConn, chans, reqs, err := ssh.NewClientConn(rawConn, remoteHostname, &ssh.ClientConfig{ - Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), - User: remoteUser, - }) - - if err != nil { - return nil, err - } - - sshClient := ssh.NewClient(sshConn, chans, reqs) - - return sshClient, nil -} - -func SendLogRegister(logger *slog.Logger, buffer int) (*slog.Logger, error) { - if buffer < 0 { - buffer = 0 - } - - currentHandler := logger.Handler() - - logWriter := &SendLogWriter{ - Timeout: 10 * time.Millisecond, - BufferSize: buffer, - } - - logWriter.Reconnect() - - return slog.New( - &MultiHandler{ - Handlers: []slog.Handler{ - currentHandler, - slog.NewJSONHandler(logWriter, &slog.HandlerOptions{ - AddSource: true, - Level: slog.LevelDebug, - }), - }, - }, - ), nil -} - -var _ io.Writer = (*SendLogWriter)(nil) -var _ slog.Handler = (*MultiHandler)(nil) - -func AnyToStr(mp map[string]any, key string) string { - if value, ok := mp[key]; ok { - if value, ok := value.(string); ok { - return value - } - } - return "" -} - -func AnyToFloat(mp map[string]any, key string) float64 { - if value, ok := mp[key]; ok { - if value, ok := value.(float64); ok { - return value - } - } - return 0 -} - -func ConnectToLogs(ctx context.Context) (io.Reader, error) { - sshClient, err := CreateSSHClient( - GetEnv("PICO_SENDLOG_ENDPOINT", "send.pico.sh:22"), - GetEnv("PICO_SENDLOG_KEY", "ssh_data/term_info_ed25519"), - GetEnv("PICO_SENDLOG_PASSPHRASE", ""), - GetEnv("PICO_SENDLOG_REMOTE_HOST", "send.pico.sh"), - GetEnv("PICO_SENDLOG_USER", "pico"), - ) - if err != nil { - return nil, err - } - - session, err := sshClient.NewSession() - if err != nil { - return nil, err - } - - stdoutPipe, err := session.StdoutPipe() - if err != nil { - return nil, err - } - - err = session.Start("sub log-drain -k") - if err != nil { - return nil, err - } - - go func() { - <-ctx.Done() - session.Close() - sshClient.Close() - }() - - return stdoutPipe, nil -} diff --git a/shared/util.go b/shared/util.go deleted file mode 100644 index d37b7864..00000000 --- a/shared/util.go +++ /dev/null @@ -1,169 +0,0 @@ -package shared - -import ( - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "fmt" - "math" - "os" - pathpkg "path" - "path/filepath" - "regexp" - "strings" - "time" - "unicode" - "unicode/utf8" - - "slices" - - "github.com/charmbracelet/ssh" - gossh "golang.org/x/crypto/ssh" -) - -var fnameRe = regexp.MustCompile(`[-_]+`) -var subdomainRe = regexp.MustCompile(`^[a-z0-9-]+$`) - -var KB = 1000 -var MB = KB * 1000 - -func IsValidSubdomain(subd string) bool { - return subdomainRe.MatchString(subd) -} - -func FilenameToTitle(filename string, title string) string { - if filename != title { - return title - } - - return ToUpper(title) -} - -func ToUpper(str string) string { - pre := fnameRe.ReplaceAllString(str, " ") - - r := []rune(pre) - if len(r) > 0 { - r[0] = unicode.ToUpper(r[0]) - } - - return string(r) -} - -func SanitizeFileExt(fname string) string { - return strings.TrimSuffix(fname, filepath.Ext(fname)) -} - -func KeyText(s ssh.Session) (string, error) { - if s.PublicKey() == nil { - return "", fmt.Errorf("Session doesn't have public key") - } - return KeyForKeyText(s.PublicKey()) -} - -func KeyForKeyText(pk ssh.PublicKey) (string, error) { - kb := base64.StdEncoding.EncodeToString(pk.Marshal()) - return fmt.Sprintf("%s %s", pk.Type(), kb), nil -} - -func KeyForSha256(pk ssh.PublicKey) string { - return gossh.FingerprintSHA256(pk) -} - -func GetEnv(key string, defaultVal string) string { - if value, exists := os.LookupEnv(key); exists { - return value - } - - return defaultVal -} - -// IsText reports whether a significant prefix of s looks like correct UTF-8; -// that is, if it is likely that s is human-readable text. -func IsText(s string) bool { - const max = 1024 // at least utf8.UTFMax - if len(s) > max { - s = s[0:max] - } - for i, c := range s { - if i+utf8.UTFMax > len(s) { - // last char may be incomplete - ignore - break - } - if c == 0xFFFD || c < ' ' && c != '\n' && c != '\t' && c != '\f' && c != '\r' { - // decoding error or control character - not a text file - return false - } - } - return true -} - -func IsExtAllowed(filename string, allowedExt []string) bool { - ext := pathpkg.Ext(filename) - return slices.Contains(allowedExt, ext) -} - -// IsTextFile reports whether the file has a known extension indicating -// a text file, or if a significant chunk of the specified file looks like -// correct UTF-8; that is, if it is likely that the file contains human- -// readable text. -func IsTextFile(text string) bool { - num := math.Min(float64(len(text)), 1024) - return IsText(text[0:int(num)]) -} - -const solarYearSecs = 31556926 - -func TimeAgo(t *time.Time) string { - d := time.Since(*t) - var metric string - var amount int - if d.Seconds() < 60 { - amount = int(d.Seconds()) - metric = "second" - } else if d.Minutes() < 60 { - amount = int(d.Minutes()) - metric = "minute" - } else if d.Hours() < 24 { - amount = int(d.Hours()) - metric = "hour" - } else if d.Seconds() < solarYearSecs { - amount = int(d.Hours()) / 24 - metric = "day" - } else { - amount = int(d.Seconds()) / solarYearSecs - metric = "year" - } - if amount == 1 { - return fmt.Sprintf("%d %s ago", amount, metric) - } else { - return fmt.Sprintf("%d %ss ago", amount, metric) - } -} - -func Shasum(data []byte) string { - h := sha256.New() - h.Write(data) - bs := h.Sum(nil) - return hex.EncodeToString(bs) -} - -func BytesToMB(size int) float32 { - return ((float32(size) / 1000) / 1000) -} - -func BytesToGB(size int) float32 { - return BytesToMB(size) / 1000 -} - -// https://stackoverflow.com/a/46964105 -func StartOfMonth() time.Time { - now := time.Now() - firstday := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC) - return firstday -} - -func StartOfYear() time.Time { - now := time.Now() - return now.AddDate(-1, 0, 0) -} diff --git a/tui/createaccount/create.go b/tui/createaccount/create.go index 6dfe4f82..3359cbba 100644 --- a/tui/createaccount/create.go +++ b/tui/createaccount/create.go @@ -8,8 +8,8 @@ import ( input "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" + "github.com/picosh/utils" ) type state int @@ -200,7 +200,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // View renders current view from the model. func (m Model) View() string { s := common.LogoView() + "\n\n" - pubkey := fmt.Sprintf("pubkey: %s", shared.KeyForSha256(m.shared.Session.PublicKey())) + pubkey := fmt.Sprintf("pubkey: %s", utils.KeyForSha256(m.shared.Session.PublicKey())) s += m.shared.Styles.Label.SetString(pubkey).String() s += "\n\n" + m.input.View() + "\n\n" @@ -228,10 +228,7 @@ func (m *Model) createAccount() tea.Cmd { return NameInvalidMsg{} } - key, err := shared.KeyForKeyText(m.shared.Session.PublicKey()) - if err != nil { - return errMsg{err} - } + key := utils.KeyForKeyText(m.shared.Session.PublicKey()) user, err := m.shared.Dbpool.RegisterUser(m.newName, key, "") if err != nil { diff --git a/tui/createkey/create.go b/tui/createkey/create.go index 693692b6..04fa8e65 100644 --- a/tui/createkey/create.go +++ b/tui/createkey/create.go @@ -7,9 +7,9 @@ import ( input "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" "github.com/picosh/pico/tui/pages" + "github.com/picosh/utils" "golang.org/x/crypto/ssh" ) @@ -239,10 +239,8 @@ func (m *Model) addPublicKey() tea.Cmd { return KeyInvalidMsg{} } - key, err := shared.KeyForKeyText(pk) - if err != nil { - return KeyInvalidMsg{} - } + key := utils.KeyForKeyText(pk) + err = m.shared.Dbpool.InsertPublicKey(m.shared.User.ID, key, comment, nil) if err != nil { if errors.Is(err, db.ErrPublicKeyTaken) { diff --git a/tui/logs/logs.go b/tui/logs/logs.go index c2ef9f03..d2f2891d 100644 --- a/tui/logs/logs.go +++ b/tui/logs/logs.go @@ -11,9 +11,11 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" "github.com/picosh/pico/tui/pages" + "github.com/picosh/utils" + + pipeLogger "github.com/picosh/pubsub/log" ) type state int @@ -168,7 +170,14 @@ func (m Model) waitForActivity(sub chan map[string]any) tea.Cmd { func (m Model) connectLogs(sub chan map[string]any) tea.Cmd { return func() tea.Msg { - stdoutPipe, err := shared.ConnectToLogs(m.ctx) + stdoutPipe, err := pipeLogger.ConnectToLogs(m.ctx, &pipeLogger.PubSubConnectionInfo{ + RemoteHost: utils.GetEnv("PICO_PIPE_ENDPOINT", "pipe.pico.sh:22"), + KeyLocation: utils.GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"), + KeyPassphrase: utils.GetEnv("PICO_PIPE_PASSPHRASE", ""), + RemoteHostname: utils.GetEnv("PICO_PIPE_REMOTE_HOST", "pipe.pico.sh"), + RemoteUser: utils.GetEnv("PICO_PIPE_USER", "pico"), + }) + if err != nil { return errMsg(err) } @@ -184,7 +193,7 @@ func (m Model) connectLogs(sub chan map[string]any) tea.Cmd { continue } - user := shared.AnyToStr(parsedData, "user") + user := utils.AnyToStr(parsedData, "user") if user == m.shared.User.Name { sub <- parsedData } @@ -201,13 +210,13 @@ func matched(str, match string) bool { } func logToStr(styles common.Styles, data map[string]any, match string) string { - time := shared.AnyToStr(data, "time") - service := shared.AnyToStr(data, "service") - level := shared.AnyToStr(data, "level") - msg := shared.AnyToStr(data, "msg") - errMsg := shared.AnyToStr(data, "err") - status := shared.AnyToFloat(data, "status") - url := shared.AnyToStr(data, "url") + time := utils.AnyToStr(data, "time") + service := utils.AnyToStr(data, "service") + level := utils.AnyToStr(data, "level") + msg := utils.AnyToStr(data, "msg") + errMsg := utils.AnyToStr(data, "err") + status := utils.AnyToFloat(data, "status") + url := utils.AnyToStr(data, "url") if match != "" { lvlMatch := matched(level, match) diff --git a/tui/settings/settings.go b/tui/settings/settings.go index c35e4112..106cb0f3 100644 --- a/tui/settings/settings.go +++ b/tui/settings/settings.go @@ -8,9 +8,9 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" "github.com/picosh/pico/tui/pages" + "github.com/picosh/utils" ) var maxWidth = 50 @@ -125,7 +125,7 @@ func (m Model) featuresView() string { data := [][]string{} for _, feature := range m.features { - storeMax := shared.BytesToGB(int(feature.FindStorageMax(0))) + storeMax := utils.BytesToGB(int(feature.FindStorageMax(0))) row := []string{ feature.Name, fmt.Sprintf("%.2f", storeMax), diff --git a/tui/util.go b/tui/util.go index 0293a4a6..8fcfde11 100644 --- a/tui/util.go +++ b/tui/util.go @@ -2,10 +2,11 @@ package tui import ( "errors" + "fmt" "github.com/picosh/pico/db" - "github.com/picosh/pico/shared" "github.com/picosh/pico/tui/common" + "github.com/picosh/utils" ) func findUser(shrd common.SharedModel) (*db.User, error) { @@ -13,12 +14,13 @@ func findUser(shrd common.SharedModel) (*db.User, error) { var user *db.User usr := shrd.Session.User() - key, err := shared.KeyForKeyText(shrd.Session.PublicKey()) - if err != nil { - return nil, err + if shrd.Session.PublicKey() == nil { + return nil, fmt.Errorf("unable to find public key") } - user, err = shrd.Dbpool.FindUserForKey(usr, key) + key := utils.KeyForKeyText(shrd.Session.PublicKey()) + + user, err := shrd.Dbpool.FindUserForKey(usr, key) if err != nil { logger.Error("no user found for public key", "err", err.Error()) // we only want to throw an error for specific cases diff --git a/ui/api.go b/ui/api.go index 16cfd71c..2df5b866 100644 --- a/ui/api.go +++ b/ui/api.go @@ -12,6 +12,7 @@ import ( "github.com/charmbracelet/ssh" "github.com/picosh/pico/db" "github.com/picosh/pico/shared" + "github.com/picosh/utils" ) type registerPayload struct { @@ -35,13 +36,7 @@ func registerUser(apiConfig *shared.ApiConfig, ctx ssh.Context, pubkey ssh.Publi body, _ := io.ReadAll(r.Body) _ = json.Unmarshal(body, &payload) - pubkeyStr, err := shared.KeyForKeyText(pubkey) - if err != nil { - errMsg := fmt.Sprintf("could not get pubkey text: %s", err.Error()) - logger.Error("could not get pubkey text", "err", err.Error()) - shared.JSONError(w, errMsg, http.StatusUnprocessableEntity) - return - } + pubkeyStr := utils.KeyForKeyText(pubkey) user, err := dbpool.RegisterUser(payload.Name, pubkeyStr, "") if err != nil { @@ -130,7 +125,7 @@ func toFingerprint(pubkey string) (string, error) { if err != nil { return "", err } - return shared.KeyForSha256(kk), nil + return utils.KeyForSha256(kk), nil } func getPublicKeys(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc { @@ -636,8 +631,8 @@ func getAnalytics(apiConfig *shared.ApiConfig, ctx ssh.Context, sumtype, bytype, by = "post_id" } - year := &db.SummaryOpts{FkID: fkID, By: by, Interval: "month", Origin: shared.StartOfYear(), Where: where} - month := &db.SummaryOpts{FkID: fkID, By: by, Interval: "day", Origin: shared.StartOfMonth(), Where: where} + year := &db.SummaryOpts{FkID: fkID, By: by, Interval: "month", Origin: utils.StartOfYear(), Where: where} + month := &db.SummaryOpts{FkID: fkID, By: by, Interval: "day", Origin: utils.StartOfMonth(), Where: where} opts := year if sumtype == "month" {