From 8c432bb834841f6fcf8eafebf6114a3eb11787ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Fri, 19 Sep 2025 13:33:45 +0200 Subject: [PATCH] Allow executing without local-fallback --- app/application.go | 18 ++++++++++++++--- app/config.go | 6 +++--- app/sync.go | 50 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/app/application.go b/app/application.go index c2e803e..7e392a2 100644 --- a/app/application.go +++ b/app/application.go @@ -1,6 +1,7 @@ package app import ( + "errors" "fmt" "os" "os/signal" @@ -11,6 +12,7 @@ import ( "fyne.io/systray" "git.blackforestbytes.com/BlackForestBytes/goext/dataext" + "git.blackforestbytes.com/BlackForestBytes/goext/langext" "git.blackforestbytes.com/BlackForestBytes/goext/syncext" "git.blackforestbytes.com/BlackForestBytes/goext/termext" "git.blackforestbytes.com/BlackForestBytes/goext/timeext" @@ -89,7 +91,7 @@ func (app *Application) Run() { app.LogDebug(fmt.Sprintf("WebDAVURL := '%s'", app.config.WebDAVURL)) app.LogDebug(fmt.Sprintf("WebDAVUser := '%s'", app.config.WebDAVUser)) app.LogDebug(fmt.Sprintf("WebDAVPass := '%s'", app.config.WebDAVPass)) - app.LogDebug(fmt.Sprintf("LocalFallback := '%s'", app.config.LocalFallback)) + app.LogDebug(fmt.Sprintf("LocalFallback := '%s'", langext.Coalesce(app.config.LocalFallback, ""))) app.LogDebug(fmt.Sprintf("WorkDir := '%s'", app.config.WorkDir)) app.LogDebug(fmt.Sprintf("Debounce := %d ms", app.config.Debounce)) app.LogDebug(fmt.Sprintf("ForceColors := %v", app.config.ForceColors)) @@ -108,6 +110,16 @@ func (app *Application) Run() { go func() { app.initTray() }() + if app.config.LocalFallback != nil { + if _, err := os.Stat(*app.config.LocalFallback); errors.Is(err, os.ErrNotExist) { + app.config.LocalFallback = nil + + app.LogError(fmt.Sprintf("Configured local-fallback '%s' not found - disabling.", *app.config.LocalFallback), nil) + + app.showErrorNotification("Local fallback database not found", fmt.Sprintf("Configured local-fallback '%s' not found - fallback option won't be available.", *app.config.LocalFallback)) + } + } + go func() { app.syncLoopRunning.Set(true) defer app.syncLoopRunning.Set(false) @@ -140,10 +152,10 @@ func (app *Application) Run() { return } - } else if isr == InitSyncResponseFallback { + } else if isr == InitSyncResponseFallback && app.config.LocalFallback != nil { app.LogInfo(fmt.Sprintf("Starting KeepassXC with local fallback database (without sync loop!)")) - app.LogDebug(fmt.Sprintf("DB-Path := '%s'", app.config.LocalFallback)) + app.LogDebug(fmt.Sprintf("DB-Path := '%s'", *app.config.LocalFallback)) go func() { app.keepassRunning.Set(true) diff --git a/app/config.go b/app/config.go index 4d35e73..518d513 100644 --- a/app/config.go +++ b/app/config.go @@ -16,7 +16,7 @@ type Config struct { WebDAVUser string `json:"webdav_user"` WebDAVPass string `json:"webdav_pass"` - LocalFallback string `json:"local_fallback"` + LocalFallback *string `json:"local_fallback"` WorkDir string `json:"work_dir"` @@ -85,7 +85,7 @@ func (app *Application) loadConfig() (Config, string) { WebDAVURL: "https://your-nextcloud-domain.example/remote.php/dav/files/keepass.kdbx", WebDAVUser: "", WebDAVPass: "", - LocalFallback: "", + LocalFallback: nil, WorkDir: "/tmp/kpsync", Debounce: 3500, ForceColors: false, @@ -114,7 +114,7 @@ func (app *Application) loadConfig() (Config, string) { cfg.WebDAVPass = webdavPass } if localFallback != "" { - cfg.LocalFallback = localFallback + cfg.LocalFallback = &localFallback } if workDir != "" { cfg.WorkDir = workDir diff --git a/app/sync.go b/app/sync.go index d1a173a..e4997b8 100644 --- a/app/sync.go +++ b/app/sync.go @@ -30,7 +30,18 @@ func (app *Application) initSync() (InitSyncResponse, error) { return "", exerr.Wrap(err, "").Build() } - app.dbFile = path.Join(app.config.WorkDir, path.Base(app.config.LocalFallback)) + fn := "" + if app.config.LocalFallback != nil { + fn = path.Base(*app.config.LocalFallback) + } + if fn == "" || fn == "." || fn == "/" || fn == "\\" { + fn = path.Base(app.config.WebDAVURL) + } + if fn == "" || fn == "." || fn == "/" || fn == "\\" { + fn = "database.kdbx" + } + + app.dbFile = path.Join(app.config.WorkDir, fn) app.stateFile = path.Join(app.config.WorkDir, "kpsync.state") if app.isKeepassRunning() { @@ -102,18 +113,27 @@ func (app *Application) initSync() (InitSyncResponse, error) { }() if err != nil { - r, err := app.showChoiceNotification("KeePassSync", "Failed to download remote database.\nUse local fallback?", map[string]string{"y": "Yes", "n": "Abort"}) - if err != nil { - app.LogError("Failed to show choice notification", err) - return "", exerr.Wrap(err, "Failed to show choice notification").Build() - } + if app.config.LocalFallback != nil { + + r, err := app.showChoiceNotification("KeePassSync", "Failed to download remote database.\nUse local fallback?", map[string]string{"y": "Yes", "n": "Abort"}) + if err != nil { + app.LogError("Failed to show choice notification", err) + return "", exerr.Wrap(err, "Failed to show choice notification").Build() + } + + if r == "y" { + return InitSyncResponseFallback, nil + } else if r == "n" { + return InitSyncResponseAbort, nil + } else { + return "", exerr.Wrap(err, "").Build() + } - if r == "y" { - return InitSyncResponseFallback, nil - } else if r == "n" { - return InitSyncResponseAbort, nil } else { - return "", exerr.Wrap(err, "").Build() + + app.showErrorNotification("KeePassSync", "Failed to download remote database.") + return InitSyncResponseAbort, nil + } } @@ -133,7 +153,13 @@ func (app *Application) runKeepass(fallback bool) { filePath := app.dbFile if fallback { - filePath = app.config.LocalFallback + if app.config.LocalFallback == nil { + app.LogError("No local fallback database configured", nil) + app.sigErrChan <- exerr.New(exerr.TypeInternal, "No local fallback database configured").Build() + return + } + + filePath = *app.config.LocalFallback } cmd := exec.Command("keepassxc", filePath)