diff --git a/agent/actions/login.go b/agent/actions/login.go index ad709e0..21ca8fd 100644 --- a/agent/actions/login.go +++ b/agent/actions/login.go @@ -96,7 +96,7 @@ func handleLogin(msg ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, cal } return } - err = bitwarden.SyncToVault(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, cfg, &protectedUserSymetricKey) + err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, cfg, &protectedUserSymetricKey, false) response, err = ipc.IPCMessageFromPayload(ipc.ActionResponse{ Success: true, diff --git a/agent/actions/vault.go b/agent/actions/vault.go index c3fe7c6..e05d4c1 100644 --- a/agent/actions/vault.go +++ b/agent/actions/vault.go @@ -57,7 +57,7 @@ func handleUnlockVault(request ipc.IPCMessage, cfg *config.Config, vault *vault. ctx := context.Background() bitwarden.RefreshToken(ctx, cfg) token, err := cfg.GetToken() - err = bitwarden.SyncToVault(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, cfg, nil) + err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, cfg, nil, true) if err != nil { fmt.Println(err) } diff --git a/agent/agent.go b/agent/agent.go index 6efc1d4..579a1c4 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -125,7 +125,7 @@ func StartUnixAgent(path string) error { } protectedUserSymetricKey, err := crypto.SymmetricEncryptionKeyFromBytes(userSymmetricKey) - err = bitwarden.SyncToVault(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymetricKey) + err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymetricKey, true) if err != nil { fmt.Println(err) } @@ -150,7 +150,7 @@ func StartUnixAgent(path string) error { } protectedUserSymetricKey, err := crypto.SymmetricEncryptionKeyFromBytes(userSymmetricKey) - err = bitwarden.SyncToVault(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymetricKey) + err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymetricKey, true) if err != nil { fmt.Println(err) } @@ -181,7 +181,7 @@ func StartUnixAgent(path string) error { continue } - bitwarden.SyncToVault(context.WithValue(ctx, bitwarden.AuthToken{}, token), vault, &cfg, nil) + bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token), vault, &cfg, nil, false) } } }() diff --git a/agent/bitwarden/sync.go b/agent/bitwarden/sync.go index 118f7d1..03c6a52 100644 --- a/agent/bitwarden/sync.go +++ b/agent/bitwarden/sync.go @@ -2,7 +2,9 @@ package bitwarden import ( "context" + "encoding/json" "fmt" + "os" "github.com/LlamaNite/llamalog" "github.com/quexten/goldwarden/agent/bitwarden/crypto" @@ -13,20 +15,30 @@ import ( var log = llamalog.NewLogger("Goldwarden", "Bitwarden API") +const path = "/.cache/goldwarden-vault.json" + func Sync(ctx context.Context, config *config.Config) (models.SyncData, error) { var sync models.SyncData if err := authenticatedHTTPGet(ctx, config.ConfigFile.ApiUrl+"/sync", &sync); err != nil { return models.SyncData{}, fmt.Errorf("could not sync: %v", err) } + + home, _ := os.UserHomeDir() + WriteVault(sync, home+path) return sync, nil } -func SyncToVault(ctx context.Context, vault *vault.Vault, config *config.Config, userSymmetricKey *crypto.SymmetricEncryptionKey) error { +func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config, userSymmetricKey *crypto.SymmetricEncryptionKey, allowCache bool) error { log.Info("Performing full sync...") sync, err := Sync(ctx, config) if err != nil { - return err + if allowCache { + home, _ := os.UserHomeDir() + sync, err = ReadVault(home + path) + } else { + return err + } } if userSymmetricKey != nil { @@ -52,3 +64,41 @@ func SyncToVault(ctx context.Context, vault *vault.Vault, config *config.Config, return nil } + +func WriteVault(data models.SyncData, path string) error { + dataJson, err := json.Marshal(data) + if err != nil { + return err + } + + // write to disk + os.Remove(path) + file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0600) + if err != nil { + return err + } + + defer file.Close() + + _, err = file.Write(dataJson) + if err != nil { + return err + } + return nil +} + +func ReadVault(path string) (models.SyncData, error) { + file, err := os.Open(path) + if err != nil { + return models.SyncData{}, err + } + defer file.Close() + + decoder := json.NewDecoder(file) + data := models.SyncData{} + err = decoder.Decode(&data) + if err != nil { + return models.SyncData{}, err + } + return data, nil +} diff --git a/agent/bitwarden/websocket.go b/agent/bitwarden/websocket.go index 62e0d00..56561d0 100644 --- a/agent/bitwarden/websocket.go +++ b/agent/bitwarden/websocket.go @@ -107,7 +107,7 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con websocketLog.Error("Error getting token %s", err) break } - SyncToVault(context.WithValue(ctx, AuthToken{}, token.AccessToken), vault, cfg, nil) + DoFullSync(context.WithValue(ctx, AuthToken{}, token.AccessToken), vault, cfg, nil, false) break case SyncCipherDelete: websocketLog.Warn("Delete requested for cipher " + cipherid)